CC312: Fork CC312 runtime library inside tf-m

Files from https://github.com/ARM-software/cryptocell-312-runtime, on
commit a31f19d6fa2173c53f5181a90af100866a78c314

Change-Id: Idd00e58a5bb694de978207823e7553ec051a67ed
Signed-off-by: Raef Coles <raef.coles@arm.com>
diff --git a/lib/ext/cryptocell-312-runtime/BSD-3-Clause.txt b/lib/ext/cryptocell-312-runtime/BSD-3-Clause.txt
new file mode 100755
index 0000000..c9804e2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/BSD-3-Clause.txt
@@ -0,0 +1,28 @@
+/****************************************************************************************
+*   Copyright (c) 2001-2019, Arm Limited and Contributors.                              *
+*       All rights reserved.                                                            *
+*                                                                                       *
+* Redistribution and use in source and binary forms, with or without modification,      *
+* are permitted provided that the following conditions are met:                         *
+*                                                                                       *
+* 1.  Redistributions of source code must retain the above copyright notice, this       *
+*    list of conditions and the following disclaimer.                                   *
+* 2.  Redistributions in binary form must reproduce the above copyright notice, this    *
+*    list of conditions and the following disclaimer in the documentation and/or        *
+*    other materials provided with the distribution.                                    *
+* 3.  Neither the name of ARM nor the names of its contributors may be used to          *
+*    endorse or promote products derived from this software without specific prior      *
+*    written permission.                                                                *
+*                                                                                       *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND       *
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED         *
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE                *
+* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR      *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        *
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;          *
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON        *
+* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT               *
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS         *
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                          *
+****************************************************************************************/
+
diff --git a/lib/ext/cryptocell-312-runtime/README.md b/lib/ext/cryptocell-312-runtime/README.md
new file mode 100644
index 0000000..282ed4b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/README.md
@@ -0,0 +1,14 @@
+# cryptocell-312-runtime
+
+Refer to docs/cc312_cryptocell_runtime_software_developers_manual*.pdf for APIs documentation.
+
+Refer to docs/cc312_r1_oss_rt_sw-*_ReleaseNote.pdf for additional information ( contents, build commands and more).
+# cryptocell-312-runtime
+
+Refer to docs/cc312_cryptocell_runtime_software_developers_manual*.pdf for APIs documentation.
+
+Refer to docs/cc312_r1_oss_rt_sw-*_ReleaseNote.pdf for additional information ( contents, build commands and more).
+
+--------------
+
+Copyright (c) 2001-2019, Arm Limited. All rights reserved.
diff --git a/lib/ext/cryptocell-312-runtime/build.props b/lib/ext/cryptocell-312-runtime/build.props
new file mode 100644
index 0000000..7950056
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/build.props
@@ -0,0 +1,7 @@
+PROJ_NAME = cc312
+PROJ_VER = 1.3.0
+BUILD_MACHINE = Linux 4.4.0-127-generic x86_64
+BUILD_TIME = Mon Jul 8 09:23:14 UTC 2019
+TARGET_HOST_ARCH = arm
+GIT_BRANCH = refs/tags/cc312r1-1.3.0-rel-rc10-20190708-1221
+GIT_REV = 6227ff8
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_aes_ext_dma.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_aes_ext_dma.c
new file mode 100644
index 0000000..0f71d5c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_aes_ext_dma.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "aes.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "aes_driver.h"
+#include "cc_aes_defs.h"
+#include "mbedtls_ext_dma_error.h"
+#include "aes_driver.h"
+#include "driver_defs.h"
+#include "cc_sym_error.h"
+#include "cc_pal_perf.h"
+#include "cc_pal_compiler.h"
+#include "mbedtls_aes_ext_dma.h"
+#include "aes_driver_ext_dma.h"
+
+
+static aesMode_t CC2DriverAesMode(CCAesOperationMode_t operationMode)
+{
+    aesMode_t result;
+
+    switch (operationMode) {
+    case CC_AES_MODE_ECB:
+        result = CIPHER_ECB;
+        break;
+    case CC_AES_MODE_CBC:
+        result = CIPHER_CBC;
+        break;
+    case CC_AES_MODE_CTR:
+        result = CIPHER_CTR;
+        break;
+    case CC_AES_MODE_CBC_MAC:
+        result = CIPHER_CBC_MAC;
+        break;
+    case CC_AES_MODE_CMAC:
+        result = CIPHER_CMAC;
+        break;
+    case CC_AES_MODE_OFB:
+        result = CIPHER_OFB;
+        break;
+    default:
+        result = CIPHER_NULL_MODE;
+    }
+
+    return result;
+}
+
+
+
+int mbedtls_aes_ext_dma_init(
+    unsigned int keybits,
+    int   encryptDecryptFlag,
+    CCAesOperationMode_t operationMode)
+{
+    drvError_t drvRc = AES_DRV_OK;
+    aesMode_t         mode;
+    keySizeId_t       keySizeId;
+
+    /* check if the operation mode is legal */
+    if ( (operationMode != CC_AES_MODE_ECB) &&
+         (operationMode != CC_AES_MODE_CBC) &&
+         (operationMode != CC_AES_MODE_CTR) &&
+         (operationMode != CC_AES_MODE_CBC_MAC) &&
+         (operationMode != CC_AES_MODE_CMAC)  &&
+         (operationMode != CC_AES_MODE_OFB)) {
+        return EXT_DMA_AES_ILLEGAL_OPERATION_MODE_ERROR;
+    }
+
+    if (CC_AES_DECRYPT != encryptDecryptFlag && CC_AES_ENCRYPT != encryptDecryptFlag) {
+        return EXT_DMA_AES_INVALID_ENCRYPT_MODE_ERROR;
+    }
+
+    /* in MAC,XCBC,CMAC modes enable only encrypt mode  */
+    if ( ((operationMode == CC_AES_MODE_CBC_MAC) ||
+          (operationMode == CC_AES_MODE_CMAC)) &&
+         (encryptDecryptFlag != CC_AES_ENCRYPT) ) {
+        return EXT_DMA_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE;
+    }
+
+    /* check key size validity */
+    switch (keybits)
+    {
+    case 128:
+        keySizeId =  KEY_SIZE_128_BIT;
+        break;
+    case 192:
+        keySizeId =  KEY_SIZE_192_BIT;
+        break;
+    case 256:
+        keySizeId =  KEY_SIZE_256_BIT;
+        break;
+    default:
+        return EXT_DMA_AES_ILLEGAL_KEY_SIZE_ERROR;
+    }
+
+    mode = CC2DriverAesMode(operationMode);
+    /* In case of failure, the resources will be freed within the driver */
+    drvRc = AesExtDmaInit((cryptoDirection_t)encryptDecryptFlag, mode, keySizeId);
+    // "add driver to CC conversion"
+    return drvRc;
+}
+
+int  mbedtls_aes_ext_dma_set_key(
+        CCAesOperationMode_t operationMode,
+        const unsigned char *key,
+        unsigned int keybits )
+{
+    drvError_t drvRc = AES_DRV_OK;
+    drvError_t rc = AES_DRV_OK;
+    keySizeId_t keySizeId;
+    uint32_t  keyBuffer[CC_AES_KEY_MAX_SIZE_IN_WORDS];
+    aesMode_t         mode;
+
+    /* check the validity of the key data pointer */
+    if (key == NULL) {
+        drvRc = EXT_DMA_AES_ILLEGAL_KEY_SIZE_ERROR;
+        goto end;
+    }
+
+    /* check if the operation mode is legal */
+    if ( (operationMode != CC_AES_MODE_ECB) &&
+         (operationMode != CC_AES_MODE_CBC) &&
+         (operationMode != CC_AES_MODE_CTR) &&
+         (operationMode != CC_AES_MODE_CBC_MAC) &&
+         (operationMode != CC_AES_MODE_CMAC)  &&
+         (operationMode != CC_AES_MODE_OFB)) {
+        drvRc = EXT_DMA_AES_ILLEGAL_OPERATION_MODE_ERROR;
+        goto end;
+    }
+
+    /* check key size validity */
+    switch (keybits)
+    {
+    case 128:
+        keySizeId =  KEY_SIZE_128_BIT;
+        break;
+    case 192:
+        keySizeId =  KEY_SIZE_192_BIT;
+        break;
+    case 256:
+        keySizeId =  KEY_SIZE_256_BIT;
+        break;
+    default:
+        drvRc =  EXT_DMA_AES_ILLEGAL_KEY_SIZE_ERROR;
+        goto end;
+    }
+
+    mode = CC2DriverAesMode(operationMode);
+    CC_PalMemCopy(keyBuffer, key, keybits/8);
+    drvRc = AesExtDmaSetKey(mode, keyBuffer, keySizeId);
+    if (drvRc != AES_DRV_OK)
+    {
+        goto end;
+    }
+    return AES_DRV_OK;
+
+end:
+    rc = terminateAesExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateAesExtDma \n");
+    }
+    return drvRc;
+}
+
+int mbedtls_aes_ext_dma_set_data_size(uint32_t dataSize, CCAesOperationMode_t operationMode)
+{
+    drvError_t drvRc = AES_DRV_OK;
+    drvError_t rc = AES_DRV_OK;
+
+    /* check if the operation mode is legal */
+    if ( (operationMode != CC_AES_MODE_ECB) &&
+         (operationMode != CC_AES_MODE_CBC) &&
+         (operationMode != CC_AES_MODE_CTR) &&
+         (operationMode != CC_AES_MODE_CBC_MAC) &&
+         (operationMode != CC_AES_MODE_CMAC)  &&
+         (operationMode != CC_AES_MODE_OFB)) {
+        drvRc = EXT_DMA_AES_ILLEGAL_OPERATION_MODE_ERROR;
+        goto end;
+    }
+    /* Check the dataSize */
+    if ( (dataSize == 0) || (dataSize > CPU_DIN_MAX_SIZE) ){
+        drvRc = EXT_DMA_ILLEGAL_INPUT_SIZE_ERROR;
+        goto end;
+    }
+    if ( ( (operationMode == CC_AES_MODE_ECB) ||
+            (operationMode == CC_AES_MODE_CBC) ||
+            (operationMode == CC_AES_MODE_CBC_MAC) ) &&
+            (dataSize % AES_BLOCK_SIZE != 0)  ){
+        drvRc = EXT_DMA_ILLEGAL_INPUT_SIZE_ERROR;
+        goto end;
+    }
+
+    /* Set data size */
+    AesExtDmaSetDataSize(dataSize);
+    return drvRc;
+
+end:
+    rc = terminateAesExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateAesExtDma \n");
+    }
+    return drvRc;
+}
+
+
+int mbedtls_aes_ext_dma_set_iv(
+    CCAesOperationMode_t operationMode,
+    unsigned char       * iv,
+    unsigned int          iv_size)
+{
+
+    drvError_t drvRc = AES_DRV_OK;
+    int rc;
+    aesMode_t  mode;
+    uint32_t   ivBuff[CC_AES_IV_SIZE_IN_WORDS];
+
+    /* check if the operation mode is legal */
+    if ( (operationMode != CC_AES_MODE_ECB) &&
+         (operationMode != CC_AES_MODE_CBC) &&
+         (operationMode != CC_AES_MODE_CTR) &&
+         (operationMode != CC_AES_MODE_CBC_MAC) &&
+         (operationMode != CC_AES_MODE_CMAC)  &&
+         (operationMode != CC_AES_MODE_OFB)) {
+        drvRc = EXT_DMA_AES_ILLEGAL_OPERATION_MODE_ERROR;
+        goto end;
+    }
+
+    if (iv == NULL || iv_size != CC_AES_IV_SIZE_IN_BYTES) {
+        drvRc = EXT_DMA_AES_INVALID_IV_OR_TWEAK_PTR_ERROR;
+        goto end;
+    }
+    mode = CC2DriverAesMode(operationMode);
+    CC_PalMemCopy((uint8_t *)ivBuff, iv, CC_AES_IV_SIZE_IN_BYTES);
+
+    drvRc = AesExtDmaSetIv(mode, ivBuff);
+    if (drvRc != AES_DRV_OK)
+    {
+        goto end;
+    }
+    return AES_DRV_OK;
+end:
+    rc = terminateAesExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateAesExtDma \n");
+    }
+    return drvRc;
+}
+
+
+int mbedtls_aes_ext_dma_finish(
+    CCAesOperationMode_t operationMode,
+    unsigned char       *iv,
+    unsigned int         iv_size )
+{
+
+    drvError_t      drvRc = AES_DRV_OK;
+    drvError_t      rc = AES_DRV_OK;
+    aesMode_t       mode;
+    uint32_t        ivBuff[CC_AES_IV_SIZE_IN_WORDS];
+
+    /* check if the operation mode is legal */
+    if ( (operationMode != CC_AES_MODE_ECB) &&
+         (operationMode != CC_AES_MODE_CBC) &&
+         (operationMode != CC_AES_MODE_CTR) &&
+         (operationMode != CC_AES_MODE_CBC_MAC) &&
+         (operationMode != CC_AES_MODE_CMAC)  &&
+         (operationMode != CC_AES_MODE_OFB)) {
+        drvRc = EXT_DMA_AES_ILLEGAL_OPERATION_MODE_ERROR;
+        goto end;
+    }
+
+    if ((operationMode == CC_AES_MODE_CBC_MAC || operationMode==CC_AES_MODE_CMAC) &&
+        (iv == NULL || iv_size != CC_AES_IV_SIZE_IN_BYTES) ) {
+        drvRc = EXT_DMA_AES_INVALID_IV_OR_TWEAK_PTR_ERROR;
+        goto end;
+    }
+    mode = CC2DriverAesMode(operationMode);
+
+    drvRc = finalizeAesExtDma(mode, ivBuff);
+
+    if ((operationMode == CC_AES_MODE_CBC_MAC || operationMode==CC_AES_MODE_CMAC) && (drvRc == AES_DRV_OK)) {
+        CC_PalMemCopy(iv, (uint8_t *)ivBuff, CC_AES_IV_SIZE_IN_BYTES);
+    }
+
+end:
+    rc = terminateAesExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateAesExtDma \n");
+    }
+    return drvRc;
+
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_chacha.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_chacha.c
new file mode 100644
index 0000000..f020247
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_chacha.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "chacha_driver.h"
+#include "mbedtls_cc_chacha.h"
+#include "mbedtls_cc_chacha_error.h"
+#include "driver_defs.h"
+#include "cc_sym_error.h"
+
+static CCError_t Driver2CCChachaErr(drvError_t drvRc)
+{
+        switch (drvRc) {
+        case CHACHA_DRV_OK:
+                return CC_OK;
+        case CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR:
+                return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
+        case CHACHA_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR:
+                return CC_CHACHA_INVALID_ENCRYPT_MODE_ERROR;
+        case CHACHA_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR:
+                return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
+        case CHACHA_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR:
+                return CC_CHACHA_DATA_OUT_POINTER_INVALID_ERROR;
+        case CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR:
+                return CC_CHACHA_INVALID_NONCE_ERROR;
+        default:
+                return CC_FATAL_ERROR;
+        }
+}
+
+static CCError_t ChachaBlock(mbedtls_chacha_user_context    *pContextID,
+        uint8_t                     *pDataIn,
+        size_t                      dataInSize,
+        uint8_t                     *pDataOut)
+{
+        drvError_t drvRc = CHACHA_DRV_OK;
+        ChachaContext_t *chachaCtx = NULL;
+        uintptr_t upDataOut = 0;
+        uintptr_t upDataIn = 0;
+        CCBuffInfo_t inBuffInfo;
+        CCBuffInfo_t outBuffInfo;
+
+        /* if the users context ID pointer is NULL return an error */
+        if (pContextID == NULL) {
+                return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* if the users Data In pointer is illegal return an error */
+        if (pDataIn == NULL) {
+                return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
+        }
+
+        /* Size zero is not a valid block operation */
+        if (dataInSize == 0) {
+                return CC_CHACHA_DATA_IN_SIZE_ILLEGAL;
+        }
+
+        /* if the users Data Out pointer is illegal return an error */
+        if (pDataOut == NULL) {
+                return CC_CHACHA_DATA_OUT_POINTER_INVALID_ERROR;
+        }
+
+        upDataOut = (uintptr_t)pDataOut;
+        upDataIn = (uintptr_t)pDataIn;
+        if ((((upDataOut > upDataIn) && (upDataOut - upDataIn < dataInSize))) ||
+                (((upDataIn > upDataOut) && (upDataIn - upDataOut < dataInSize)))) {
+                return CC_CHACHA_DATA_OUT_POINTER_INVALID_ERROR;
+        }
+
+        chachaCtx = (ChachaContext_t *)pContextID;
+
+        /* set data buffers structures */
+        drvRc = SetDataBuffersInfo(pDataIn, dataInSize, &inBuffInfo,
+                                   pDataOut, dataInSize, &outBuffInfo);
+        if (drvRc != 0) {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
+        }
+
+        drvRc = ProcessChacha(chachaCtx, &inBuffInfo, &outBuffInfo, dataInSize);
+
+        return Driver2CCChachaErr(drvRc);
+}
+
+CIMPORT_C CCError_t  mbedtls_chacha_init(mbedtls_chacha_user_context    *pContextID,
+        mbedtls_chacha_nonce     pNonce,
+                                               mbedtls_chacha_nonce_size_t        nonceSize,
+                                               mbedtls_chacha_key           pKey,
+                                               uint32_t                    initialCounter,
+                                               mbedtls_chacha_encrypt_mode_t   EncryptDecryptFlag)
+{
+        ChachaContext_t *chachaCtx = NULL;
+
+        /* Chacha key size bytes */
+        uint32_t keySizeBytes = CC_CHACHA_KEY_MAX_SIZE_IN_BYTES;
+        /* Chacha nonce size bytes */
+        uint32_t nonceSizeBytes = 0;
+
+        /* FUNCTION LOGIC */
+
+        /* ............... local initializations .............................. */
+        /* -------------------------------------------------------------------- */
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* if the users context ID pointer is NULL return an error */
+        if (pContextID == NULL) {
+                return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        if (sizeof(mbedtls_chacha_user_context) != sizeof(ChachaContext_t)) {
+                return CC_CHACHA_CTX_SIZES_ERROR;
+        }
+
+        /* if the pNonce is NULL return an error */
+        if (pNonce == NULL) {
+                return CC_CHACHA_INVALID_NONCE_PTR_ERROR;
+        }
+
+        /* check the nonce size */
+        if (nonceSize == CC_CHACHA_Nonce64BitSize) {
+        nonceSizeBytes = 8;
+    } else if (nonceSize == CC_CHACHA_Nonce96BitSize) {
+        nonceSizeBytes = CC_CHACHA_NONCE_MAX_SIZE_IN_BYTES;
+    } else {
+                return  CC_CHACHA_INVALID_NONCE_ERROR;
+        }
+
+        /* check the Encrypt / Decrypt flag validity */
+        if (EncryptDecryptFlag >= CC_CHACHA_EncryptNumOfOptions) {
+                return  CC_CHACHA_INVALID_ENCRYPT_MODE_ERROR;
+        }
+
+        /*  check the validity of the key pointer */
+        if (pKey == NULL) {
+                return  CC_CHACHA_INVALID_KEY_POINTER_ERROR;
+        }
+
+        chachaCtx = (ChachaContext_t *)pContextID;
+        chachaCtx->dir = (enum cryptoDirection)EncryptDecryptFlag;
+        chachaCtx->nonceSize = (chachaNonceSize_t)nonceSize;
+        chachaCtx->inputDataAddrType = DLLI_ADDR;
+        chachaCtx->outputDataAddrType = DLLI_ADDR;
+
+        /* Copy the key to the context */
+        CC_PalMemCopy(chachaCtx->keyBuf, pKey, keySizeBytes);
+
+        /* Copy the nonce to the context */
+        CC_PalMemCopy(chachaCtx->nonceBuf, pNonce, nonceSizeBytes);
+
+        /* init the block counter */
+        chachaCtx->blockCounterLsb = initialCounter;
+        chachaCtx->blockCounterMsb = 0;
+
+        return CC_OK;
+}
+
+CIMPORT_C CCError_t  mbedtls_chacha_block(mbedtls_chacha_user_context    *pContextID,
+                                         uint8_t                     *pDataIn,
+                                         size_t                      dataInSize,
+                                         uint8_t                     *pDataOut )
+{
+        if ((dataInSize % CHACHA_BLOCK_SIZE_BYTES) != 0) {
+                return CC_CHACHA_DATA_IN_SIZE_ILLEGAL;
+        }
+        if (dataInSize == 0) {
+                return CC_OK;
+        }
+
+        return ChachaBlock(pContextID, pDataIn, dataInSize, pDataOut);
+}
+
+CIMPORT_C CCError_t  mbedtls_chacha_finish(mbedtls_chacha_user_context    *pContextID,
+        uint8_t                     *pDataIn,
+        size_t                      dataInSize,
+        uint8_t                     *pDataOut)
+{
+        if (dataInSize == 0) {
+                return CC_OK;
+        }
+
+        return ChachaBlock(pContextID, pDataIn, dataInSize, pDataOut);
+}
+
+CIMPORT_C CCError_t  mbedtls_chacha_free(mbedtls_chacha_user_context *pContextID)
+{
+        ChachaContext_t *chachaCtx = (ChachaContext_t*)pContextID;
+
+        if (pContextID == NULL) {
+                return CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* Zero the context */
+        CC_PalMemSetZero(chachaCtx, sizeof(ChachaContext_t));
+
+        return CC_OK;
+}
+
+CIMPORT_C CCError_t  mbedtls_chacha(mbedtls_chacha_nonce       pNonce,
+                                   mbedtls_chacha_nonce_size_t          nonceSize,
+                                   mbedtls_chacha_key             pKey,
+                                   uint32_t                      initialCounter,
+                                   mbedtls_chacha_encrypt_mode_t     encryptDecryptFlag,
+                                   uint8_t                       *pDataIn,
+                                   size_t                        dataInSize,
+                                   uint8_t                       *pDataOut )
+{
+    mbedtls_chacha_user_context UserContext;
+    CCError_t Error = CC_OK;
+
+
+    /* if the users Data In pointer is illegal return an error */
+    if ( (pDataIn == NULL) ^ (dataInSize == 0) ) {
+        return CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR;
+    }
+
+    /* limit the input size. in IoT no reason for such a big size */
+    if ( dataInSize > CC_MAX_UINT32_VAL ) {
+        return CC_CHACHA_DATA_IN_SIZE_ILLEGAL;
+    }
+
+    /* Size zero is valid - do nothing and return with CC_OK */
+    if (dataInSize == 0) {
+        return CC_OK;
+    }
+
+    Error = mbedtls_chacha_init(&UserContext, pNonce, nonceSize, pKey, initialCounter, encryptDecryptFlag);
+    if (Error != CC_OK) {
+        goto end;
+    }
+
+    Error = mbedtls_chacha_finish(&UserContext, pDataIn, dataInSize, pDataOut);
+    if (Error != CC_OK) {
+            goto end;
+    }
+
+    Error = mbedtls_chacha_free(&UserContext);
+    if (Error != CC_OK) {
+            goto end;
+    }
+
+end:
+    return Error;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_chacha_poly.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_chacha_poly.c
new file mode 100644
index 0000000..6d3a18c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_chacha_poly.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "mbedtls_cc_chacha.h"
+#include "mbedtls_cc_poly.h"
+#include "poly.h"
+#include "mbedtls_cc_chacha_poly_error.h"
+
+
+CIMPORT_C CCError_t  mbedtls_chacha_poly(
+        mbedtls_chacha_nonce         pNonce,
+        mbedtls_chacha_key            pKey,
+        mbedtls_chacha_encrypt_mode_t    encryptDecryptFlag,
+        uint8_t          *pAddData,
+        size_t           addDataSize,
+        uint8_t                     *pDataIn,
+        size_t                       dataInSize,
+        uint8_t                     *pDataOut,
+        mbedtls_poly_mac         macRes)
+
+{
+    CCError_t rc;
+    uint8_t chachaInState[CC_CHACHA_BLOCK_SIZE_IN_BYTES] = {0};
+    uint8_t chachaOutState[CC_CHACHA_BLOCK_SIZE_IN_BYTES] = {0};
+    mbedtls_poly_key polyKey = {0};
+    mbedtls_poly_mac polyMac = {0};
+    uint8_t *pCipherData = NULL;
+
+
+    // Verify inputs
+    if ((pAddData == NULL) ^ (addDataSize == 0)) {
+        return CC_CHACHA_POLY_ADATA_INVALID_ERROR;
+    }
+    if ((pDataIn == NULL) ^ (dataInSize == 0)) {
+        return CC_CHACHA_POLY_DATA_INVALID_ERROR;
+    }
+    if (((pDataOut == NULL) ^ (pDataIn == NULL))||
+        (macRes == NULL) ||
+        (pNonce == NULL) ||
+        (pKey == NULL) ||
+        (dataInSize > CC_MAX_UINT32_VAL) ||
+        (addDataSize > CC_MAX_UINT32_VAL))
+        return CC_CHACHA_POLY_DATA_INVALID_ERROR;
+
+
+    if (encryptDecryptFlag == CC_CHACHA_Encrypt) {
+        pCipherData = pDataOut;
+    } else if (encryptDecryptFlag == CC_CHACHA_Decrypt) {
+        pCipherData = pDataIn;
+    } else {
+        return CC_CHACHA_POLY_ENC_MODE_INVALID_ERROR;
+    }
+
+    // 1. Generate poly key
+    // Calling mbedtls_chacha with data=0 is like performing the chacha block function without the encryption
+    rc = mbedtls_chacha(pNonce, CC_CHACHA_Nonce96BitSize, pKey, 0, CC_CHACHA_Encrypt, chachaInState, sizeof(chachaInState), chachaOutState);
+    if (rc != CC_OK) {
+        rc = CC_CHACHA_POLY_GEN_KEY_ERROR;
+        goto end_with_error;
+    }
+    // poly key defined as the first 32 bytes of chacha output.
+    CC_PalMemCopy(polyKey, chachaOutState, sizeof(polyKey));
+
+    // 2. Encryption pDataIn
+    if (encryptDecryptFlag == CC_CHACHA_Encrypt) {
+        rc = mbedtls_chacha(pNonce, CC_CHACHA_Nonce96BitSize, pKey, 1, encryptDecryptFlag, (uint8_t *)pDataIn,  dataInSize, (uint8_t *)pDataOut);
+        if (rc != CC_OK) {
+            rc = CC_CHACHA_POLY_ENCRYPTION_ERROR;
+            goto end_with_error;
+        }
+    }
+
+    // 3. Authentication
+    rc = PolyMacCalc(polyKey, pAddData, addDataSize, pCipherData, dataInSize, polyMac, true);
+    if (rc != CC_OK) {
+        rc = CC_CHACHA_POLY_AUTH_ERROR;
+        goto end_with_error;
+    }
+    // 3.1. If encrypt, Calculate mac
+    if (encryptDecryptFlag == CC_CHACHA_Encrypt) {
+        CC_PalMemCopy(macRes, polyMac, sizeof(polyMac));
+        return CC_OK;
+    }
+
+    // 3.2. If decrypt, first Verify the expected macRes with polyMac, than decrypt the msg
+    if (CC_PalMemCmp(macRes, polyMac, sizeof(polyMac)) != 0) {
+        rc = CC_CHACHA_POLY_MAC_ERROR;
+        goto end_with_error;
+    }
+    rc = mbedtls_chacha(pNonce, CC_CHACHA_Nonce96BitSize, pKey, 1, encryptDecryptFlag, (uint8_t *)pDataIn,  dataInSize, (uint8_t *)pDataOut);
+    if (rc != CC_OK) {
+        rc = CC_CHACHA_POLY_ENCRYPTION_ERROR;
+        goto end_with_error;
+    }
+    return CC_OK;
+
+    end_with_error:
+    if (pDataOut != NULL) {
+        CC_PalMemSetZero(pDataOut, dataInSize);
+    }
+    return rc;
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_ecies.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_ecies.c
new file mode 100644
index 0000000..f1b16f7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_ecies.c
@@ -0,0 +1,598 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include "mbedtls_cc_ecies.h"
+
+#include "cc_pal_mem.h"
+#include "cc_pal_log.h"
+#include "cc_pal_types.h"
+
+#include "cc_ecpki_build.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_domain.h"
+#include "cc_rnd_common.h"
+#include "cc_ecpki_kg.h"
+#include "ecp_common.h"
+#include "ec_wrst.h"
+#include "cc_kdf.h"
+#include "mbedtls_cc_hkdf.h"
+#include "mbedtls_common.h"
+
+#include "mbedtls/platform.h"
+
+/************************ Defines *************************************/
+
+/************************ Enums ***************************************/
+
+/************************ Typedefs ************************************/
+
+/************************ Global Data *********************************/
+
+/************* Private function prototype *****************************/
+static CCKdfHashOpMode_t ecies_convert_mbed_to_cc_hkdf_hash_mode(mbedtls_hkdf_hashmode_t mode)
+{
+    switch (mode)
+    {
+        case CC_HKDF_HASH_SHA1_mode:
+            return CC_KDF_HASH_SHA1_mode;
+        case CC_HKDF_HASH_SHA224_mode:
+            return CC_KDF_HASH_SHA224_mode;
+        case CC_HKDF_HASH_SHA256_mode:
+            return CC_KDF_HASH_SHA256_mode;
+        case CC_HKDF_HASH_SHA384_mode:
+            return CC_KDF_HASH_SHA384_mode;
+        case CC_HKDF_HASH_SHA512_mode:
+            return CC_KDF_HASH_SHA512_mode;
+        default:
+            return CC_KDF_HASH_OpModeLast;
+    }
+}
+
+static int ecies_convert_mbed_to_cc_public_key(const mbedtls_ecp_group *pGrp, /*in*/
+                                               const CCEcpkiDomain_t *pDomain,
+                                               mbedtls_ecp_point *pPubKey, /*in*/
+                                               CCEcpkiUserPublKey_t *pUserPublKey, /*out*/
+                                               CCEciesTempData_t *tempBuff /*in*/)
+
+{
+    int error = 0;
+    size_t keylen = 0;
+    uint8_t *pBuf = NULL;
+    CCEcpkiBuildTempData_t *pTempBuildBuff = NULL;
+    size_t bufSize = 0;
+
+    if (tempBuff == NULL)
+    {
+        CC_PAL_LOG_ERR("Error - tempBuff is NULL\n");
+        error = CC_ECIES_INVALID_PTR;
+        goto EXIT_ON_ERROR;
+    }
+
+    pTempBuildBuff = &tempBuff->tmp.buildTempbuff;
+    pBuf = (uint8_t*)&tempBuff->ConvPublKey;
+    bufSize = sizeof(tempBuff->ConvPublKey);
+
+    /* write mpi to buf */
+    if ((error = mbedtls_ecp_point_write_binary(pGrp,
+                                                pPubKey,
+                                                MBEDTLS_ECP_PF_UNCOMPRESSED,
+                                                &keylen,
+                                                pBuf,
+                                                bufSize)) != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to write mpi\n");
+        goto EXIT_ON_ERROR;
+    }
+
+    if ((error = CC_EcpkiPublKeyBuildAndCheck(pDomain,
+                                              pBuf,
+                                              keylen,
+                                              ECpublKeyFullCheck,
+                                              pUserPublKey,
+                                              pTempBuildBuff)) != CC_OK)
+    {
+        CC_PAL_LOG_ERR("Error - failed CC_EcpkiPublKeyBuildAndCheck\n");
+        goto EXIT_ON_ERROR;
+    }
+
+EXIT_ON_ERROR:
+    return error;
+
+}
+
+static int ecies_convert_mbed_to_cc_private_key(const CCEcpkiDomain_t *pDomain,
+                                                mbedtls_mpi *pPrivKey, /*in*/
+                                                CCEcpkiUserPrivKey_t *pUserPrivKey /*out*/,
+                                                CCEciesTempData_t *tempBuff)
+{
+    int error = 0;
+    size_t n = 0;
+    CCEcpkiBuildTempData_t *pTempBuildBuff = NULL;
+    if (tempBuff == NULL)
+    {
+        CC_PAL_LOG_ERR("Error - tempBuff is NULL\n");
+        error = CC_ECIES_INVALID_PTR;
+        goto EXIT_ON_ERROR;
+    }
+
+    pTempBuildBuff = &tempBuff->tmp.buildTempbuff;
+    n = mbedtls_mpi_size( pPrivKey );
+
+    if (n > sizeof(*pTempBuildBuff))
+    {
+        CC_PAL_LOG_ERR("Error - n[%u] latger pTempBuildBuff struct[%u]\n", n, sizeof(*pTempBuildBuff));
+        error = CC_ECIES_INVALID_TEMP_DATA_SIZE_ERROR;
+        goto EXIT_ON_ERROR;
+    }
+    /* write mpi to buf */
+    if ((error = mbedtls_mpi_write_binary(pPrivKey, (uint8_t*)pTempBuildBuff, n)) != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to write mpi\n");
+        goto EXIT_ON_ERROR;
+    }
+
+    if ((error = CC_EcpkiPrivKeyBuild(pDomain, (uint8_t*)pTempBuildBuff, n, pUserPrivKey)) != CC_OK)
+    {
+        CC_PAL_LOG_ERR("Error - failed to CC_EcpkiPrivKeyBuild n[%u]\n", n);
+        goto EXIT_ON_ERROR;
+    }
+
+EXIT_ON_ERROR:
+    return error;
+
+}
+
+static void ecies_free_keys(CCEcpkiUserPrivKey_t *a, CCEcpkiUserPublKey_t *b)
+{
+    if (a != NULL)
+    {
+        CC_PalMemSetZero(a, sizeof(*a));
+        mbedtls_free(a);
+    }
+
+    if (b != NULL)
+    {
+        CC_PalMemSetZero(b, sizeof(*b));
+        mbedtls_free(b);
+    }
+}
+
+/************************ Public Functions ****************************/
+CCError_t mbedtls_ecies_kem_encrypt_full(mbedtls_ecp_group *pGrp,
+                                         mbedtls_ecp_point *pRecipUzPublKey,
+                                         CCKdfDerivFuncMode_t kdfDerivMode,
+                                         mbedtls_hkdf_hashmode_t kdfHashMode,
+                                         uint32_t isSingleHashMode,
+                                         mbedtls_ecp_point *pExtEphUzPublicKey,
+                                         mbedtls_mpi *pExtEphUzPrivateKey,
+                                         uint8_t *pSecrKey,
+                                         size_t secrKeySize,
+                                         uint8_t *pCipherData,
+                                         size_t *pCipherDataSize,
+                                         void *pBuff,
+                                         size_t buffLen,
+                                         int (*f_rng)(void *, unsigned char *, size_t),
+                                         void *p_rng)
+{
+
+    /* LOCAL DECLARATIONS */
+    CCError_t error = CC_OK;
+
+    /*  pointer to EC domain  */
+    const CCEcpkiDomain_t *pDomain;
+    CCEcpkiDomainID_t domain_id;
+
+    uint32_t modSizeInBytes, kdfDataSize;
+    uint8_t *pKdfData;
+
+
+    /* pointers to ephemeral key pair, which should be used */
+    CCEcpkiUserPublKey_t *pCcReciptUzPublKey = NULL;
+    CCEcpkiUserPrivKey_t *pEphUzPrivKey = NULL;
+    CCEcpkiUserPublKey_t *pEphUzPublKey = NULL;
+    CCEcpkiPublKey_t *pRecipPublKey = NULL;
+    CCEcpkiPrivKey_t *pEphPrivKey = NULL;
+
+    CCEciesTempData_t *pTempBuff = NULL;
+    CCRndContext_t *pRndContext = NULL;
+
+    /* Initialize Error */
+    error = CC_OK;
+
+    /* .........    checking the validity of input parameters  .......... */
+    /* Note: pRndContext and pFipsCtx will be checked in called functions */
+    /* ------------------------------------------------------------------- */
+
+    /* check the validity of the user static private key */
+    if (pRecipUzPublKey == NULL)
+        return CC_ECIES_INVALID_PUBL_KEY_PTR_ERROR;
+
+    /* check KDF and HASH modes */
+    if (kdfDerivMode != CC_KDF_ISO18033_KDF1_DerivMode && kdfDerivMode != CC_KDF_ISO18033_KDF2_DerivMode)
+        return CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR;
+
+    /* check HASH mode */
+    if (kdfHashMode >= CC_HKDF_HASH_NumOfModes)
+        return CC_ECIES_INVALID_KDF_HASH_MODE_ERROR;
+
+    /* check the pointer to the buffer for secret key output */
+    if (pSecrKey == NULL)
+        return CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR;
+
+    /* check the size of secret key to be generated */
+    if (secrKeySize == 0)
+        return CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR;
+
+    /* checking the buffer for cipher text output */
+    if (pCipherData == NULL)
+        return CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR;
+
+    if (pCipherDataSize == NULL)
+        return CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR;
+
+    if ((pExtEphUzPublicKey != NULL) ^ (pExtEphUzPrivateKey != NULL))
+        return CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR;
+
+    /* checking the temp buffer pointer  */
+    if (pBuff == NULL)
+        return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
+
+    if (buffLen < sizeof(CCEciesTempData_t))
+        return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
+
+
+    /* ..  initializtions  and other checking   .... */
+    /* --------------------------------------------- */
+
+    /* convert grp_id to domain ID */
+    if ((error = ecp_grp_id_to_domain_id(pGrp->id, &domain_id)) != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to ecp_grp_id_to_domain_id grpId[%u]. error[0x%08x]\n", pGrp->id, error);
+        error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+        goto End;
+    }
+
+    /* check EC Domain ID */
+    if (domain_id >= CC_ECPKI_DomainID_OffMode)
+    {
+        CC_PAL_LOG_ERR("Error - domain_id[%u] larger than CC_ECPKI_DomainID_OffMode[%u]\n", domain_id, CC_ECPKI_DomainID_OffMode);
+        error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+        goto End;
+    }
+
+    /* get domain from id */
+    pDomain = CC_EcpkiGetEcDomain(domain_id);
+    if (pDomain == NULL)
+    {
+        CC_PAL_LOG_ERR("Error - failed to get pDomain by id[%u]\n", domain_id);
+        error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+        goto End;
+    }
+
+    /* convert mbedtls keys to cc structs */
+    pTempBuff = (CCEciesTempData_t *)pBuff;
+
+    pCcReciptUzPublKey = mbedtls_calloc(1, sizeof(*pCcReciptUzPublKey));
+    if (pCcReciptUzPublKey == NULL)
+    {
+        CC_PAL_LOG_ERR("Error - pCcReciptUzPublKey failed to allocate\n");
+        error = CC_ECIES_INVALID_PTR;
+        goto End;
+    }
+
+    if ((error = ecies_convert_mbed_to_cc_public_key(pGrp, pDomain, pRecipUzPublKey, pCcReciptUzPublKey, pTempBuff)) != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to ecp_convert_mbed_to_cc_public_key receipt public key. error[0x%08x]\n", error);
+        goto End;
+    }
+
+     /* derive and check domainID from recipient Public Key */
+    pRecipPublKey = (CCEcpkiPublKey_t*) &pCcReciptUzPublKey->PublKeyDbBuff;
+
+    /* modulus size */
+    modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
+
+    /* check cipher output buffer size */
+    if (*pCipherDataSize < 2 * modSizeInBytes + 1)
+    {
+        CC_PAL_LOG_ERR("Error - size mismatch dataSize[%u] keyDataSize[%u]\n", *pCipherDataSize, 2 * modSizeInBytes + 1);
+        error = CC_ECIES_INVALID_CIPHER_DATA_SIZE_ERROR;
+        goto End;
+    }
+
+    if (pExtEphUzPublicKey == NULL && pExtEphUzPrivateKey == NULL)
+    {
+        pRndContext = mbedtls_calloc(1, sizeof(CCRndContext_t));
+        if (pRndContext == NULL)
+        {
+            CC_PAL_LOG_ERR("Error - failed to allocate CCRndContext_t\n");
+            error = CC_ECIES_INVALID_PTR;
+            goto End;
+        }
+
+        if (f_rng == NULL)
+        {
+            CC_PAL_LOG_ERR("Error - f_rng is NULL\n");
+            error = CC_ECIES_INVALID_PTR;
+            goto End;
+        }
+
+        pRndContext->rndGenerateVectFunc = (CCRndGenerateVectWorkFunc_t)f_rng;
+        pRndContext->rndState = p_rng;
+
+        /* use internal genrated ephemeral Key Pair */
+        error = CC_EcpkiKeyPairGenerate(pRndContext, /*in/out*/
+                                        pDomain,
+                                        &pTempBuff->PrivKey,
+                                        &pTempBuff->PublKey,
+                                        &pTempBuff->tmp.KgTempBuff,
+                                        NULL);
+
+        CC_PalMemSetZero(pRndContext, sizeof(*pRndContext));
+        mbedtls_free(pRndContext);
+
+        if (error != CC_OK)
+            goto End;
+
+        pEphUzPrivKey = &pTempBuff->PrivKey;    // r
+        pEphUzPublKey = &pTempBuff->PublKey;    // g~ = r*G
+    }
+    else
+    {
+        pEphUzPrivKey = &pTempBuff->PrivKey;
+        pEphUzPublKey = &pTempBuff->PublKey;
+
+        /* use external ephemeral Key Pair */
+        if ((error = ecies_convert_mbed_to_cc_private_key(pDomain, pExtEphUzPrivateKey, pEphUzPrivKey, pTempBuff)) != 0)
+        {
+            CC_PAL_LOG_ERR("Error - failed to ecies_convert_mbed_to_cc_private_key. error[0x%08x]\n", error);
+            ecies_free_keys(pEphUzPrivKey, pEphUzPublKey);
+            goto End;
+        }
+
+        if ((error = ecies_convert_mbed_to_cc_public_key(pGrp, pDomain, pExtEphUzPublicKey, pEphUzPublKey, pTempBuff)) != 0)
+        {
+            CC_PAL_LOG_ERR("Error - failed to ecies_convert_mbed_to_cc_public_key. error[0x%08x]\n", error);
+            ecies_free_keys(pEphUzPrivKey, pEphUzPublKey);
+            goto End;
+        }
+    }
+
+    /* convert ephemeral public key to standard form */
+    error = CC_EcpkiPubKeyExport(pEphUzPublKey, /*in*/
+                                 CC_EC_PointUncompressed, /*in*/
+                                 (uint8_t*) &pTempBuff->zz, /*out*/
+                                 pCipherDataSize); /*in/out*//* Number of Bytes that were copied to zz*/
+    if (error != CC_OK)
+    {
+        CC_PAL_LOG_ERR("Error - failed to CC_EcpkiPubKeyExport. error[0x%08x]\n", error);
+        goto End;
+    }
+
+    /* call  EcWrstDhDeriveSharedSecret function to calculate the Secret Value */
+    /* --------------------------------------------------------------- */        // h~ = r*h
+    pEphPrivKey = (CCEcpkiPrivKey_t*) &pEphUzPrivKey->PrivKeyDbBuff;
+    error = EcWrstDhDeriveSharedSecret(pRecipPublKey, /*in*/
+                                       (CCEcpkiPrivKey_t *) (pEphPrivKey->PrivKey), /*in*/
+                                       &((uint8_t*) &pTempBuff->zz)[*pCipherDataSize], /*out*//* Next available space in zz where the (SV X coordinate of multiplication) will be stored*/
+                                       &pTempBuff->tmp.DhTempBuff); /*in*/
+    if (error != CC_OK)
+    {
+        CC_PAL_LOG_ERR("Error - failed to EcWrstDhDeriveSharedSecret. error[0x%08x]\n", error);
+        goto End;
+    }
+
+    /* derive the Keying Data from the Secret Value by calling the KDF function    */
+    /* --------------------------------------------------------------------------- */
+
+    /* set pointer  and size of input data for KDF function */
+    if (isSingleHashMode == CC_TRUE)
+    { /* z = X */
+        pKdfData = &((uint8_t*) &pTempBuff->zz)[*pCipherDataSize];
+        kdfDataSize = modSizeInBytes;
+    }
+    else
+    { /*z = C0 || X*/
+        pKdfData = (uint8_t*) &pTempBuff->zz;
+        kdfDataSize = *pCipherDataSize + modSizeInBytes;
+    }
+
+    /*derive the Keying Data */
+    error = CC_KdfKeyDerivFunc(pKdfData/*ZZSecret*/,
+                               kdfDataSize/*ZZSecretSize*/,
+                               NULL/*&otherInfo*/,
+                               ecies_convert_mbed_to_cc_hkdf_hash_mode(kdfHashMode),
+                               kdfDerivMode,
+                               pSecrKey,
+                               secrKeySize);
+    if (error != CC_OK)
+    {
+        CC_PAL_LOG_ERR("Error - failed to CC_KdfKeyDerivFunc. error[0x%08x]\n", error);
+        goto End;
+    }
+
+    /* Output of the Cipher Data (C0) = Ephemeral Public Key */
+    CC_PalMemCopy(pCipherData, pTempBuff->zz, *pCipherDataSize);
+
+End:
+
+    if (error != CC_OK)
+    {
+        *pCipherDataSize = 0;
+    }
+
+    ecies_free_keys(NULL, pCcReciptUzPublKey);
+
+    /* clean temp buffers */
+    CC_PalMemSetZero(pBuff, buffLen);
+
+    return error;
+
+}/* END OF CC_EciesKemEncrypt */
+
+CCError_t mbedtls_ecies_kem_decrypt(mbedtls_ecp_group *pGrp,
+                                    mbedtls_mpi *pRecipUzPrivKey,
+                                    CCKdfDerivFuncMode_t kdfDerivMode,
+                                    mbedtls_hkdf_hashmode_t kdfHashMode,
+                                    uint32_t isSingleHashMode,
+                                    uint8_t *pCipherData,
+                                    size_t cipherDataSize,
+                                    uint8_t *pSecrKey,
+                                    size_t secrKeySize,
+                                    void *pBuff,
+                                    size_t buffLen)
+{
+
+    /* LOCAL DECLARATIONS */
+
+    CCError_t error = CC_OK;
+
+    /*  pointer to EC domain  */
+    const CCEcpkiDomain_t *pDomain;
+    CCEcpkiDomainID_t domain_id;
+
+    uint32_t modSizeInBytes, kdfDataSize;
+    uint8_t *pKdfData;
+
+    CCEcpkiPrivKey_t *pRecipPrivKey = NULL;
+    CCEcpkiUserPrivKey_t *pRecipUserPrivKey;
+
+    CCEciesTempData_t *pTempBuff = NULL;
+
+    /* ................. checking the validity of input parameters  .......... */
+    /* ----------------------------------------------------------------------- */
+
+    /* check the validity of the recipient's private key */
+    if (pRecipUzPrivKey == NULL)
+        return CC_ECIES_INVALID_PRIV_KEY_PTR_ERROR;
+
+    /*check KDF and HASH modes */
+    if (kdfDerivMode != CC_KDF_ISO18033_KDF1_DerivMode && kdfDerivMode != CC_KDF_ISO18033_KDF2_DerivMode)
+        return CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR;
+
+    if (kdfHashMode >= CC_HKDF_HASH_NumOfModes) {
+        return CC_ECIES_INVALID_KDF_HASH_MODE_ERROR;
+    }
+
+    /* check the pointer to the buffer for secret key output */
+    if (pSecrKey == NULL)
+        return CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR;
+
+    /* checking the size of secret key to be generated */
+    if (secrKeySize == 0)
+        return CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR;
+
+    /* check the buffer for cipher text output */
+    if (pCipherData == NULL)
+        return CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR;
+
+    /* checking the temp buffer pointer  */
+    if (pBuff == NULL)
+        return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
+
+    /* check the buffer is bug enough */
+    if (buffLen < MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES)
+    {
+        CC_PAL_LOG_ERR("Error - buffLen[%u] < MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES[%u]\n", buffLen, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
+        return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
+    }
+
+    /* ..  initializations  and other checking   .... */
+    /* ---------------------------------------------- */
+
+    /* convert grp_id to domain ID */
+    if ((error = ecp_grp_id_to_domain_id(pGrp->id, &domain_id)) != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to ecp_grp_id_to_domain_id grpId[%u]. error[0x%08x]\n", pGrp->id, error);
+        error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+        goto End;
+    }
+
+    /* check EC Domain ID */
+    if (domain_id >= CC_ECPKI_DomainID_OffMode)
+    {
+        CC_PAL_LOG_ERR("Error - domain_id[%u] larger than CC_ECPKI_DomainID_OffMode[%u]\n", domain_id, CC_ECPKI_DomainID_OffMode);
+        error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+        goto End;
+    }
+
+    /* get domain from id */
+    pDomain = CC_EcpkiGetEcDomain(domain_id);
+    if (pDomain == NULL)
+    {
+        CC_PAL_LOG_ERR("Error - failed to get pDomain by id[%u]\n", domain_id);
+        error = CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+        goto End;
+    }
+
+    /* convert mbedtls keys to cc structs */
+    pTempBuff = (CCEciesTempData_t *)pBuff;
+    pRecipUserPrivKey = &pTempBuff->PrivKey;
+
+    if ((error = ecies_convert_mbed_to_cc_private_key(pDomain, pRecipUzPrivKey, pRecipUserPrivKey, pTempBuff)) != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to ecp_convert_mbed_to_cc_public_key reciept public key. error[0x%08x]\n", error);
+        goto End;
+    }
+
+    /* derive domainID from recipient Private Key */
+    pRecipPrivKey = (CCEcpkiPrivKey_t*) &(pRecipUserPrivKey->PrivKeyDbBuff);
+
+    /* modulus size */
+    modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
+
+    /* partially check the cipher data C0 (ephemeral public key)
+     and initialize appropriate CC Key structure */
+    error = CC_EcpkiPublKeyBuildAndCheck(pDomain, /*in*/
+                                         pCipherData, /*in - ephem. publ.key data*/
+                                         cipherDataSize, /*in*/
+                                         ECpublKeyPartlyCheck, /*in*/
+                                         &pTempBuff->PublKey, /*out*/
+                                         &pTempBuff->tmp.buildTempbuff); /*in*/
+    if (error != CC_OK)
+        goto End;
+
+    /* call  EcWrstDhDeriveSharedSecret function to calculate the Secret Value SV */
+    /* ----------------------------------------------------------------- */
+    error = EcWrstDhDeriveSharedSecret((CCEcpkiPublKey_t*) &pTempBuff->PublKey.PublKeyDbBuff, /*in*/
+                                       (CCEcpkiPrivKey_t *) pRecipPrivKey->PrivKey, /*in*/
+                                       &((uint8_t*) &pTempBuff->zz)[cipherDataSize], /*out*/
+                                       &pTempBuff->tmp.DhTempBuff); /*in*/
+
+    if (error != CC_OK)
+        goto End;
+
+    /* set pointer  and size of input data for KDF function */
+    if (isSingleHashMode == CC_TRUE)
+    { /* zz = SV */
+        pKdfData = &((uint8_t*) &pTempBuff->zz)[cipherDataSize];
+        kdfDataSize = modSizeInBytes;
+    }
+    else
+    { /* zz = C0 || SV */
+        pKdfData = (uint8_t*) &pTempBuff->zz;
+        kdfDataSize = cipherDataSize + modSizeInBytes;
+        /* set cipherData  C0 in the temp buffer zz */
+        CC_PalMemCopy((uint8_t* )&pTempBuff->zz, pCipherData, cipherDataSize);
+    }
+
+    /* derive the Keying Data from the ZZ Value by calling the KDF function */
+    /* -----------------------------------------------------------------  - */
+    error = CC_KdfKeyDerivFunc(pKdfData/*ZZSecret*/,
+                               kdfDataSize/*ZZSecretSize*/,
+                               NULL/*&otherInfo*/,
+                               ecies_convert_mbed_to_cc_hkdf_hash_mode(kdfHashMode),
+                               kdfDerivMode,
+                               pSecrKey,
+                               secrKeySize);
+End:
+    /* clean temp buffers */
+    CC_PalMemSetZero(pBuff, buffLen);
+
+    return error;
+
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_poly.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_poly.c
new file mode 100644
index 0000000..a61c1ac
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_poly.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "mbedtls_cc_poly.h"
+#include "poly.h"
+#include "mbedtls_cc_poly_error.h"
+
+
+CIMPORT_C CCError_t  mbedtls_poly(
+        mbedtls_poly_key         pKey,
+        uint8_t                *pDataIn,
+        size_t                  dataInSize,
+        mbedtls_poly_mac        macRes)
+
+{
+    CCError_t rc;
+
+    // Verify inputs
+    if (pKey == NULL) {
+        return CC_POLY_KEY_INVALID_ERROR;
+    }
+    if ((macRes == NULL) ||
+        ((pDataIn == NULL) ^ (dataInSize == 0)) ||
+        (dataInSize > CC_MAX_UINT32_VAL)) {
+        return CC_POLY_DATA_INVALID_ERROR;
+    }
+
+    // calculate teh MAC using PKA
+    rc = PolyMacCalc(pKey, NULL, 0, pDataIn, dataInSize, macRes, false);
+    if (rc != CC_OK) {
+        return CC_POLY_RESOURCES_ERROR;
+    }
+
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_sha512_t.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_sha512_t.c
new file mode 100644
index 0000000..bf835bb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_sha512_t.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_pal_abort.h"
+#include "mbedtls_cc_sha512_t.h"
+#include "sha512.h"
+#include "cc_pal_mem.h"
+
+#if defined(MBEDTLS_SHA512_C)
+
+#include "mbedtls/sha512.h"
+
+#if defined(_MSC_VER) || defined(__WATCOMC__)
+  #define UL64(x) x##ui64
+#else
+  #define UL64(x) x##ULL
+#endif
+
+#include <string.h>
+
+
+#define MBEDTLS_SHA512_T_224_DIGEST_SIZE_BYTES 28
+#define MBEDTLS_SHA512_T_256_DIGEST_SIZE_BYTES 32
+
+void mbedtls_sha512_t_init( mbedtls_sha512_context *ctx )
+{
+    if (ctx == NULL) {
+        CC_PalAbort("mbedtls_sha512_context cannot be NULL");
+    }
+    mbedtls_sha512_init(ctx);
+}
+
+void mbedtls_sha512_t_free( mbedtls_sha512_context *ctx )
+{
+    if (ctx != NULL) {
+        mbedtls_sha512_free(ctx);
+    }
+}
+
+/*
+ * SHA-512_t context setup
+ */
+void mbedtls_sha512_t_starts( mbedtls_sha512_context *ctx, int is224 )
+{
+    if (ctx == NULL) {
+        CC_PalAbort("mbedtls_sha512_context cannot be NULL");
+    }
+
+    if (is224 != 0 && is224 != 1 ) {
+        CC_PalAbort("mbedtls_sha512_starts: is224 must be 0 or 1");
+    }
+
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    if( is224 == 1 ) {
+        /* SHA-512/224 */
+        ctx->state[0] = UL64(0x8C3D37C819544DA2);
+        ctx->state[1] = UL64(0x73E1996689DCD4D6);
+        ctx->state[2] = UL64(0x1DFAB7AE32FF9C82);
+        ctx->state[3] = UL64(0x679DD514582F9FCF);
+        ctx->state[4] = UL64(0x0F6D2B697BD44DA8);
+        ctx->state[5] = UL64(0x77E36F7304C48942);
+        ctx->state[6] = UL64(0x3F9D85A86A1D36C8);
+        ctx->state[7] = UL64(0x1112E6AD91D692A1);
+    }
+    else {
+        /* SHA-512/256 */
+        ctx->state[0] = UL64(0x22312194FC2BF72C);
+        ctx->state[1] = UL64(0x9F555FA3C84C64C2);
+        ctx->state[2] = UL64(0x2393B86B6F53B151);
+        ctx->state[3] = UL64(0x963877195940EABD);
+        ctx->state[4] = UL64(0x96283EE2A88EFFE3);
+        ctx->state[5] = UL64(0xBE5E1E2553863992);
+        ctx->state[6] = UL64(0x2B0199FC2C85B8AA);
+        ctx->state[7] = UL64(0x0EB72DDC81C52CA2);
+    }
+
+    ctx->is384 = 0;
+}
+
+
+void mbedtls_sha512_t_process( mbedtls_sha512_context *ctx, const unsigned char data[128] )
+{
+    if (ctx == NULL || data == NULL) {
+        CC_PalAbort("mbedtls_sha512_context and data buffer cannot be NULL");
+    }
+    mbedtls_sha512_process(ctx, data);
+}
+
+/*
+ * SHA-512 process buffer
+ */
+void mbedtls_sha512_t_update( mbedtls_sha512_context *ctx, const unsigned char *input,
+                    size_t ilen )
+{
+    if (ctx == NULL || input == NULL) {
+        CC_PalAbort("mbedtls_sha512_context and input buffer cannot be NULL");
+    }
+    mbedtls_sha512_update(ctx,input,ilen);
+}
+
+/*
+ * SHA-512 final digest
+ */
+void mbedtls_sha512_t_finish( mbedtls_sha512_context *ctx, unsigned char output[32], int is224 )
+{
+    unsigned char output512[64] = {0};
+
+    if (ctx == NULL || output == NULL) {
+        CC_PalAbort("mbedtls_sha512_context and output buffer cannot be NULL");
+    }
+    if (is224 != 0 && is224 != 1 ) {
+        CC_PalAbort("mbedtls_sha512_t_finish: is224 must be 0 or 1");
+    }
+
+    mbedtls_sha512_finish(ctx, output512);
+    if (is224) {
+        CC_PalMemCopy(output, output512, MBEDTLS_SHA512_T_224_DIGEST_SIZE_BYTES);
+    }
+    else {
+        CC_PalMemCopy(output, output512, MBEDTLS_SHA512_T_256_DIGEST_SIZE_BYTES);
+    }
+}
+
+#endif /* !MBEDTLS_SHA512_ALT */
+
+/*
+ * output = SHA-512( input buffer )
+ */
+void mbedtls_sha512_t( const unsigned char *input, size_t ilen,
+             unsigned char output[32], int is224 )
+{
+    mbedtls_sha512_context ctx;
+
+    if (input == NULL || output == NULL) {
+        CC_PalAbort("input and output buffers cannot be NULL");
+    }
+
+    mbedtls_sha512_t_init( &ctx );
+    mbedtls_sha512_t_starts( &ctx, is224 );
+    mbedtls_sha512_t_update( &ctx, input, ilen );
+    mbedtls_sha512_t_finish( &ctx, output, is224 );
+    mbedtls_sha512_t_free( &ctx );
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_srp.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_srp.c
new file mode 100644
index 0000000..1164f66
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_cc_srp.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_bitops.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_common.h"
+#include "mbedtls_cc_srp.h"
+#include "srp_driver.h"
+#include "srp.h"
+#include "mbedtls_cc_srp_error.h"
+
+
+/************************ private Functions **********************/
+bool isSrpVerValid(mbedtls_srp_version_t    srpVer)
+{
+    if ((srpVer != CC_SRP_VER_3) &&
+        (srpVer != CC_SRP_VER_6) &&
+        (srpVer != CC_SRP_VER_6A) &&
+        (srpVer != CC_SRP_VER_HK)) {
+        return false;
+    }
+    return true;
+}
+
+bool isSrpModulusSizeValid(size_t modSizeInBits)
+{
+    if ((modSizeInBits != CC_SRP_MODULUS_SIZE_1024_BITS) &&
+        (modSizeInBits != CC_SRP_MODULUS_SIZE_1536_BITS) &&
+        (modSizeInBits != CC_SRP_MODULUS_SIZE_2048_BITS) &&
+        (modSizeInBits != CC_SRP_MODULUS_SIZE_3072_BITS)) {
+        return false;
+    }
+    return true;
+}
+
+uint32_t getHashDigestSize(CCHashOperationMode_t  hashMode)
+{
+    switch(hashMode) {
+    case CC_HASH_SHA1_mode:
+        return CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+    case CC_HASH_SHA224_mode:
+        return CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+    case CC_HASH_SHA256_mode:
+        return CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+    case CC_HASH_SHA384_mode:
+        return CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+    case CC_HASH_SHA512_mode:
+        return CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+    case CC_HASH_MD5_mode:
+        return CC_HASH_MD5_DIGEST_SIZE_IN_BYTES;
+    default:
+        return 0;
+    }
+}
+
+/************************ SRP common Functions **********************/
+CIMPORT_C CCError_t  mbedtls_srp_init(
+                mbedtls_srp_entity_t    srpType,
+                mbedtls_srp_version_t   srpVer,
+                mbedtls_srp_modulus srpModulus,
+                uint8_t         srpGen,
+                size_t          modSizeInBits,
+                CCHashOperationMode_t   hashMode,
+                uint8_t         *pUserName,
+                size_t                  userNameSize,
+                uint8_t         *pPwd,
+                size_t                  pwdSize,
+                CCRndContext_t  *pRndCtx,
+                mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    uint32_t    hashDigestSize = 0;
+
+    // Verify inputs
+    hashDigestSize = getHashDigestSize(hashMode);
+    if (((srpType != CC_SRP_HOST) && (srpType != CC_SRP_USER)) ||
+        (isSrpVerValid(srpVer) == false) ||
+        (srpModulus == NULL) ||
+        (isSrpModulusSizeValid(modSizeInBits) == false) ||
+        (pUserName == NULL) || (userNameSize == 0) ||
+        ((srpType == CC_SRP_USER) && ((pPwd == NULL) || (pwdSize == 0))) ||
+        (pRndCtx == NULL) ||
+        (pCtx == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    // clear SRP ctx
+    CC_PalMemSetZero(pCtx, sizeof(*pCtx));
+
+    // Keep inputs in context
+    pCtx->srpType = srpType;
+    pCtx->srpVer = srpVer;
+    pCtx->groupParam.gen = srpGen;
+    pCtx->groupParam.modSizeInBits = modSizeInBits;
+    CC_PalMemCopy(pCtx->groupParam.modulus, srpModulus, CALC_FULL_BYTES(modSizeInBits));
+    pCtx->hashMode = hashMode;
+    pCtx->hashDigestSize = hashDigestSize;
+    pCtx->pRndCtx = pRndCtx;
+
+    //calculate multiplier k and keep it in SRP context
+    rc = SRP_InitAndkMultiplierCalc(pCtx);
+    if (rc != 0) {
+                rc = CC_SRP_INTERNAL_ERROR;
+                goto end_with_error;
+    }
+
+    //calculate user credential Digest, if exists, and keep it in SRP context
+    if ((pPwd != NULL) && (pwdSize != 0)) {
+        rc = SRP_UserCredDigCalc(pUserName, userNameSize,
+                pPwd, pwdSize,
+                pCtx);
+        if (rc != 0) {
+            goto end_with_error;
+        }
+    }
+
+    // start calculating the proof with existing values
+    rc = SRP_UserNameDigCalc(pUserName,
+            userNameSize,
+            pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    return CC_OK;
+
+end_with_error:
+    CC_PalMemSetZero(pCtx, sizeof(*pCtx));
+    return rc;
+
+}
+
+
+CIMPORT_C CCError_t  mbedtls_srp_pwd_ver_create(
+                size_t                  saltSize,
+                uint8_t         *pSalt,
+                mbedtls_srp_modulus         pwdVerifier,
+                mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    mbedtls_srp_digest  xBuff;
+    CCRndContext_t *pRndCtx;
+
+    // verify input
+    if ((saltSize < CC_SRP_MIN_SALT_SIZE) || (saltSize > CC_SRP_MAX_SALT_SIZE) ||
+        (pSalt == NULL) ||
+        (pwdVerifier == NULL) ||
+        (pCtx == NULL) || (pCtx->pRndCtx->rndGenerateVectFunc == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    pRndCtx = pCtx->pRndCtx;
+
+    // generate random pSalt
+    rc = pRndCtx->rndGenerateVectFunc(pRndCtx->rndState, (unsigned char *)pSalt, saltSize);
+    if (rc != CC_OK) {
+        goto end_with_error;
+    }
+    // calc x = SHA(pSalt | pCtx->credDigest)
+    rc = SRP_xBuffCalc(pSalt,
+        saltSize,
+        xBuff,
+        pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    // Use PKA to calculate v=g^x%N
+    rc = SrpPwdVerifierCalc(xBuff, pwdVerifier, pCtx);
+    if (rc != 0) {
+                rc = CC_SRP_INTERNAL_ERROR;
+                goto end_with_error;
+    }
+    return CC_OK;
+
+end_with_error:
+    CC_PalMemSetZero(pSalt, saltSize);
+    CC_PalMemSetZero(pwdVerifier, sizeof(mbedtls_srp_modulus));
+    CC_PalMemSetZero(pCtx, sizeof(mbedtls_srp_context));
+    return rc;
+}
+
+
+CIMPORT_C CCError_t  mbedtls_srp_clear(
+        mbedtls_srp_context *pCtx)
+{
+    if (pCtx == NULL) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    CC_PalMemSetZero(pCtx, sizeof(*pCtx));
+    return CC_OK;
+}
+
+
+/************************ SRP Host Functions **********************/
+CIMPORT_C CCError_t  mbedtls_srp_host_pub_key_create(
+                size_t                  ephemPrivSize,
+                mbedtls_srp_modulus         pwdVerifier,
+                mbedtls_srp_modulus         hostPubKeyB,
+                mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    CCRndContext_t *pRndCtx;
+
+    // verify input
+    if ((ephemPrivSize < CC_SRP_PRIV_NUM_MIN_SIZE) ||
+        (ephemPrivSize > CC_SRP_PRIV_NUM_MAX_SIZE) ||
+        (ephemPrivSize % CC_32BIT_WORD_SIZE) ||
+        (pwdVerifier == NULL) ||
+        (hostPubKeyB == NULL) ||
+        (pCtx == NULL) || (pCtx->pRndCtx->rndGenerateVectFunc == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    pRndCtx = pCtx->pRndCtx;
+    // generate ephemeral private key b
+    rc = pRndCtx->rndGenerateVectFunc(pRndCtx->rndState, (unsigned char *)pCtx->ephemPriv, ephemPrivSize);
+    if (rc != CC_OK) {
+        goto end_with_error;
+    }
+    pCtx->ephemPrivSize = ephemPrivSize;
+
+    // Use PKA to calculate B=(k*v+g^b)%N
+    rc = SrpHostPublicKeyCalc(pwdVerifier, hostPubKeyB, pCtx);
+    if (rc != 0) {
+                rc = CC_SRP_INTERNAL_ERROR;
+                goto end_with_error;
+    }
+    return CC_OK;
+
+end_with_error:
+    CC_PalMemSetZero(hostPubKeyB, sizeof(mbedtls_srp_modulus));
+    CC_PalMemSetZero(pCtx, sizeof(mbedtls_srp_context));
+    return rc;
+}
+
+
+CIMPORT_C CCError_t  mbedtls_srp_host_proof_verify_and_calc(
+                size_t                  saltSize,
+                uint8_t         *pSalt,
+                mbedtls_srp_modulus         pwdVerifier,
+                mbedtls_srp_modulus         userPubKeyA,
+                mbedtls_srp_modulus         hostPubKeyB,
+                mbedtls_srp_digest  userProof,
+                mbedtls_srp_digest  hostProof,
+                mbedtls_srp_sessionKey  sessionKey,
+                mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    mbedtls_srp_digest  digBuff; // used for uScramble and expected user proof
+    mbedtls_srp_modulus         sharedSecret;
+
+    // Verify input
+    if ((saltSize < CC_SRP_MIN_SALT_SIZE) || (saltSize > CC_SRP_MAX_SALT_SIZE) ||
+        (pSalt == NULL) ||
+        (pwdVerifier == NULL) ||
+        (userPubKeyA == NULL) ||
+        (hostPubKeyB == NULL) ||
+        (userProof == NULL) ||
+        (hostProof == NULL) ||
+        (sessionKey == NULL) ||
+        (pCtx == NULL) ) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    // Generate u
+    rc = SRP_uScrambleCalc(userPubKeyA,
+            hostPubKeyB,
+            digBuff,
+            pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    // Use PKA to calculate shared secret S=(((A*v^u)^b)%N
+    rc = SrpHostSharedSecretCalc(userPubKeyA,
+                pwdVerifier,
+                digBuff,
+                sharedSecret,
+                pCtx);
+    if (rc != 0) {
+                rc = CC_SRP_INTERNAL_ERROR;
+                goto end_with_error;
+    }
+
+    // Generate session key K
+    rc = SRP_SessionKeyCalc((uint8_t *)sharedSecret,
+                CALC_FULL_BYTES(pCtx->groupParam.modSizeInBits),
+                sessionKey, pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    CC_PalMemSetZero(digBuff, sizeof(digBuff));
+    // generate the expected user proof
+    rc = SRP_UserProofCalc2(pSalt, saltSize,
+        userPubKeyA, hostPubKeyB,
+        sessionKey,
+        digBuff,
+        pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+    rc = SRP_SecureMemCmp(digBuff, userProof, pCtx->hashDigestSize);
+    if (rc != 0) {
+        rc = CC_SRP_RESULT_ERROR;
+        goto end_with_error;
+    }
+
+    // generate the host proof
+    rc = SRP_HostProofCalc(userPubKeyA,
+        userProof,
+        sessionKey,
+        hostProof,
+        pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+    return CC_OK;
+
+end_with_error:
+    CC_PalMemSetZero(hostProof, sizeof(mbedtls_srp_digest));
+    CC_PalMemSetZero(sessionKey, sizeof(mbedtls_srp_sessionKey));
+    CC_PalMemSetZero(pCtx, sizeof(mbedtls_srp_context));
+    return rc;
+}
+
+
+/************************ SRP User Functions **********************/
+CIMPORT_C CCError_t  mbedtls_srp_user_pub_key_create(
+                size_t                  ephemPrivSize,
+                mbedtls_srp_modulus         userPubKeyA,
+                mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    CCRndContext_t *pRndCtx;
+
+    // verify input
+    if ((ephemPrivSize < CC_SRP_PRIV_NUM_MIN_SIZE) ||
+        (ephemPrivSize > CC_SRP_PRIV_NUM_MAX_SIZE) ||
+        (ephemPrivSize % CC_32BIT_WORD_SIZE) ||
+        (userPubKeyA == NULL) ||
+        (pCtx == NULL) || (pCtx->pRndCtx->rndGenerateVectFunc == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    pRndCtx = pCtx->pRndCtx;
+    // generate ephemeral private key a
+    rc = pRndCtx->rndGenerateVectFunc(pRndCtx->rndState, (unsigned char *)pCtx->ephemPriv, ephemPrivSize);
+    if (rc != CC_OK) {
+        goto end_with_error;
+    }
+    pCtx->ephemPrivSize = ephemPrivSize;
+
+    // Use PKA to calculate A=(g^a)%N
+    rc = SrpUserPublicKeyCalc(userPubKeyA, pCtx);
+    if (rc != 0) {
+                rc = CC_SRP_INTERNAL_ERROR;
+                goto end_with_error;
+    }
+    return CC_OK;
+
+end_with_error:
+    CC_PalMemSetZero(userPubKeyA, sizeof(mbedtls_srp_modulus));
+    CC_PalMemSetZero(pCtx, sizeof(mbedtls_srp_context));
+    return rc;
+}
+
+
+CIMPORT_C CCError_t  mbedtls_srp_user_proof_calc(
+                size_t                  saltSize,
+                uint8_t         *pSalt,
+                mbedtls_srp_modulus userPubKeyA,
+                mbedtls_srp_modulus hostPubKeyB,
+                mbedtls_srp_digest  userProof,
+                mbedtls_srp_sessionKey  sessionKey,
+                mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    mbedtls_srp_digest  uScramble;
+    mbedtls_srp_modulus         sharedSecret;
+    mbedtls_srp_digest      xBuff;
+
+    // Verify input
+    if ((saltSize < CC_SRP_MIN_SALT_SIZE) || (saltSize > CC_SRP_MAX_SALT_SIZE) ||
+        (pSalt == NULL) ||
+        (userPubKeyA == NULL) ||
+        (hostPubKeyB == NULL) ||
+        (userProof == NULL) ||
+        (sessionKey == NULL) ||
+        (pCtx == NULL) ) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    // Generate u
+    rc = SRP_uScrambleCalc(userPubKeyA,
+            hostPubKeyB,
+            uScramble,
+            pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    // calc x = SHA(pSalt | pCtx->credDigest)
+    rc = SRP_xBuffCalc(pSalt, saltSize, xBuff, pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    // Use PKA to calculate S=((B-k*g^x)^(a+u*x))%N
+    rc = SrpUserSharedSecretCalc(hostPubKeyB,
+                xBuff,
+                uScramble,
+                sharedSecret,
+                pCtx);
+    if (rc != 0) {
+                rc = CC_SRP_INTERNAL_ERROR;
+                goto end_with_error;
+    }
+
+    // generate shared secret K
+    rc = SRP_SessionKeyCalc((uint8_t *)sharedSecret,
+                CALC_FULL_BYTES(pCtx->groupParam.modSizeInBits),
+                sessionKey,
+                pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    // generate the expected user proof
+    rc = SRP_UserProofCalc2(pSalt, saltSize,
+        userPubKeyA, hostPubKeyB,
+        sessionKey,
+        userProof,
+        pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+    return CC_OK;
+
+end_with_error:
+    CC_PalMemSetZero(userProof, sizeof(mbedtls_srp_digest));
+    CC_PalMemSetZero(sessionKey, sizeof(mbedtls_srp_sessionKey));
+    CC_PalMemSetZero(pCtx, sizeof(mbedtls_srp_context));
+    return rc;
+}
+
+
+CIMPORT_C CCError_t  mbedtls_srp_user_proof_verify(
+                mbedtls_srp_sessionKey  sessionKey,
+                mbedtls_srp_modulus userPubKeyA,
+                mbedtls_srp_digest  userProof,
+                mbedtls_srp_digest  hostProof,
+                mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    mbedtls_srp_digest  expHostProof = {0};
+
+    // verify input
+    if ((sessionKey == NULL) ||
+        (userPubKeyA == NULL) ||
+        (userProof == NULL) ||
+        (hostProof == NULL) ||
+        (pCtx == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    // generate the expected proof
+    rc = SRP_HostProofCalc(userPubKeyA,
+        userProof,
+        sessionKey,
+        expHostProof,
+        pCtx);
+    if (rc != 0) {
+        goto end_with_error;
+    }
+
+    // compare the expected proof to the actual one
+    rc = SRP_SecureMemCmp(expHostProof, hostProof, pCtx->hashDigestSize);
+    if (rc != 0) {
+        rc = CC_SRP_RESULT_ERROR;
+        goto end_with_error;
+    }
+    return CC_OK;
+
+end_with_error:
+    CC_PalMemSetZero(pCtx, sizeof(mbedtls_srp_context));
+    return rc;
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_ccm_internal.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_ccm_internal.c
new file mode 100644
index 0000000..c9707f6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_ccm_internal.c
@@ -0,0 +1,719 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "aesccm_driver.h"
+#include "cc_common.h"
+#include "mbedtls_ccm_internal.h"
+#include "mbedtls_ccm_common.h"
+#include "mbedtls_common.h"
+#include "cc_aesccm_error.h"
+
+/************************ Type definitions **********************/
+
+/* AES-CCM* Security levels (ieee-802.15.4-2011, Table 58) */
+#define AESCCM_STAR_SECURITY_LEVEL_ENC          4
+#define AESCCM_STAR_SECURITY_LEVEL_ENC_MIC_32   5
+#define AESCCM_STAR_SECURITY_LEVEL_ENC_MIC_64   6
+#define AESCCM_STAR_SECURITY_LEVEL_ENC_MIC_128  7
+
+/************************ Type definitions **********************/
+
+
+/************************ static functions **********************/
+static int ccm_init(mbedtls_ccm_context *ctx,
+                    cryptoDirection_t encryptDecryptFlag,
+                    size_t assocDataSize,
+                    size_t textDataSize,
+                    const uint8_t *pNonce,
+                    uint8_t sizeOfN,
+                    uint8_t sizeOfT,
+                    uint32_t ccmMode)
+{
+
+    AesCcmContext_t *pAesCcmCtx = NULL;
+    uint8_t ctrStateBuf[CC_AES_BLOCK_SIZE_IN_BYTES] = { 0 };
+    uint8_t qFieldSize = 15 - sizeOfN;
+    uint8_t *tempBuff;
+    drvError_t rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+    uint8_t securityLevelField = 0;
+
+    /* check the Encrypt / Decrypt flag validity */
+    if (encryptDecryptFlag >= CRYPTO_DIRECTION_NUM_OF_ENC_MODES)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* check Nonce pointer */
+    if (pNonce == NULL)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if (ccmMode == MBEDTLS_AESCCM_MODE_CCM) {
+        /* check CCM MAC size: [4,6,8,10,12,14,16] */
+        if ((sizeOfT < 4) || (sizeOfT > 16) || ((sizeOfT & 1) != 0)) {
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
+        }
+    }
+    else if (ccmMode == MBEDTLS_AESCCM_MODE_STAR) {
+        /* check CCM STAR MAC size */
+        if (mbedtls_ccm_get_security_level(sizeOfT, &securityLevelField) != CC_OK) {
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
+        }
+
+        /* check CCM STAR Nonce size. sizeOfN == 13 */
+        if (sizeOfN != MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES) {
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
+        }
+
+        /* check CCM STAR Security level field */
+        if (pNonce[MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES - 1] != securityLevelField) {
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
+        }
+    }
+    else {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* check the Q field size: according to our implementation qFieldSize <= 4*/
+    if ((qFieldSize < 2) || (qFieldSize > 8))
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* check, that actual size of TextData is not great, than its control field size */
+    if ((qFieldSize < 4) && ((textDataSize >> (qFieldSize * 8)) > 0))
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* check Nonce size. */
+    if (sizeOfN < 7 || sizeOfN >= CC_AES_BLOCK_SIZE_IN_BYTES)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* set pointer to user context */
+    pAesCcmCtx = (AesCcmContext_t *) ctx;
+
+    /* set current AES operation mode for AES_MAC operation on first block B0 and next blocks */
+    pAesCcmCtx->mode = CIPHER_CBC_MAC;
+    pAesCcmCtx->sizeOfN = sizeOfN;
+    pAesCcmCtx->sizeOfT = sizeOfT;
+    pAesCcmCtx->dir = encryptDecryptFlag;
+
+    /* clear initial vector */
+    mbedtls_zeroize_internal(pAesCcmCtx->ivBuf, sizeof(pAesCcmCtx->ivBuf));
+
+    /*clear intenal buffers*/
+    mbedtls_zeroize_internal(pAesCcmCtx->ctrStateBuf, sizeof(pAesCcmCtx->ctrStateBuf));
+    mbedtls_zeroize_internal(pAesCcmCtx->tempBuff, sizeof(pAesCcmCtx->tempBuff));
+
+    /* formatting the first block of CCM input B0, and encrypt with CBC-MAC */
+    tempBuff = pAesCcmCtx->tempBuff;
+
+    /* set Adata flag (bit 6 for big endian form) */
+    if (assocDataSize > 0)
+    {
+        tempBuff[0] = 1 << 6;
+    }
+
+    /* next flag bits: (t-2)/2 concatenated with (q-1) */
+    tempBuff[0] |= ((sizeOfT - 2) / 2) << 3; /* bits 3 - 5 */
+    tempBuff[0] |= (qFieldSize - 1); /* bits 0 - 2 */
+
+    /* set N and Q (in big endian form) into B0 */
+    CC_PalMemCopy(tempBuff + 1, pNonce, sizeOfN);
+    CC_CommonReverseMemcpy(tempBuff + 16 - min(qFieldSize, 4), (uint8_t*) &textDataSize, min(qFieldSize, 4));
+
+    /* set data buffers structures */
+    rc = SetDataBuffersInfo(tempBuff, CC_AES_BLOCK_SIZE_IN_BYTES, &inBuffInfo,
+    NULL,
+                            0, &outBuffInfo);
+    if (rc != 0)
+    {
+        CC_PAL_LOG_ERR("illegal data buffers\n");
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    /* calculating MAC */
+    rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, CC_AES_BLOCK_SIZE_IN_BYTES);
+    if (rc != AES_DRV_OK)
+    {
+        CC_PAL_LOG_ERR("calculating MAC failed with error code %d\n", rc);
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    /* set initial Counter value into ctrStateBuf buffer for AES CTR operations on text data */
+
+    /* Flags byte = (qFieldSize - 1) */
+    ctrStateBuf[0] = qFieldSize - 1;
+    /* copy Nonce into bytes 1...(15-qFieldSize) in big endian form */
+    CC_PalMemCopy(ctrStateBuf + 1, pNonce, sizeOfN);
+    /* set counter i = 1 (in byte 15) */
+    ctrStateBuf[15] = 1; /* Note: value i = 0 reserved for encoding MAC value */
+    CC_PalMemCopy((uint8_t * )pAesCcmCtx->ctrStateBuf, ctrStateBuf, CC_AES_BLOCK_SIZE_IN_BYTES);
+
+    return (0);
+}
+
+static int ccm_ass_data(mbedtls_ccm_context *ctx, const uint8_t *pAssocData, size_t assocDataSize)
+{
+
+    AesCcmContext_t *pAesCcmCtx;
+    uint32_t firstBlockRemSize = 0;
+    uint8_t Asize = 0;
+    drvError_t rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if (pAssocData == NULL)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* set pointer to user context */
+    pAesCcmCtx = (AesCcmContext_t *) ctx;
+
+    /* formatting ASize and setting it into AES tempBuff buffer */
+    /* clean working tempBuff */
+    mbedtls_zeroize_internal(pAesCcmCtx->tempBuff, CC_AES_BLOCK_SIZE_IN_BYTES);
+
+    /* set formatted ASize into temp buffer.
+     Note: case ASize > 2^32 is not allowed by implementation */
+    if (assocDataSize > 0xFFFFFFFF)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* if ASize > 2^16-2^8, then set 6 bytes = 0xff||0xfe||ASize */
+    if (assocDataSize >= 0xff00)
+    { /* if ASize >= 2^16 - 2^8, then set 0xff||0xfe||ASize */
+        pAesCcmCtx->tempBuff[0] = 0xff;
+        pAesCcmCtx->tempBuff[1] = 0xfe;
+        /* reverse copy 4 bytes */
+        CC_CommonReverseMemcpy(pAesCcmCtx->tempBuff + 6 - 4, (uint8_t*) &assocDataSize, 4);
+        Asize = 6;
+    }
+    else if (assocDataSize > 0)
+    { /* else if 0 < ASize < 2^16 - 2^8, then set 2 bytes = ASize */
+        /* reverse copy 2 bytes */
+        CC_CommonReverseMemcpy(pAesCcmCtx->tempBuff + 2 - 2, (uint8_t*) &assocDataSize, 2);
+        Asize = 2;
+    }
+    else
+    { /* no Adata */
+        Asize = 0;
+    }
+
+    firstBlockRemSize = CC_AES_BLOCK_SIZE_IN_BYTES - Asize;
+
+    if (assocDataSize < firstBlockRemSize)
+    {
+        firstBlockRemSize = assocDataSize;
+    }
+
+    CC_PalMemCopy(pAesCcmCtx->tempBuff + Asize, pAssocData, firstBlockRemSize);
+
+    assocDataSize -= firstBlockRemSize;
+    pAssocData += firstBlockRemSize;
+    pAesCcmCtx->mode = CIPHER_CBC_MAC;
+
+    /* set data buffers structures */
+    rc = SetDataBuffersInfo(pAesCcmCtx->tempBuff, CC_AES_BLOCK_SIZE_IN_BYTES, &inBuffInfo,
+    NULL,
+                            0, &outBuffInfo);
+    if (rc != 0)
+    {
+        CC_PAL_LOG_ERR("illegal data buffers\n");
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    /* encrypt a0 concatenated with the beginning of Associated data */
+    rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, CC_AES_BLOCK_SIZE_IN_BYTES);
+    if (rc != AES_DRV_OK)
+    {
+        CC_PAL_LOG_ERR("encrypt a0 concatenated with the beginning of Associated data failed with error code %d\n", rc);
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    if (assocDataSize)
+    {
+        /* set data buffers structures */
+        rc = SetDataBuffersInfo(pAssocData, assocDataSize, &inBuffInfo,
+        NULL,
+                                0, &outBuffInfo);
+        if (rc != 0)
+        {
+            CC_PAL_LOG_ERR("illegal data buffers\n");
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+
+        /* encrypt remaining Associated data */
+        rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, assocDataSize);
+        if (rc != AES_DRV_OK)
+        {
+            CC_PAL_LOG_ERR("encrypt remaining Associated data failed with error code %d\n", rc);
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+    }
+
+    return (0);
+}
+
+static int ccm_text_data(mbedtls_ccm_context *ctx, const uint8_t *pTextDataIn, size_t textDataSize, uint8_t *pTextDataOut)
+{
+
+    AesCcmContext_t *pAesCcmCtx = NULL;
+    drvError_t rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* if the users Data In pointer is illegal return an error */
+    if ((pTextDataIn == NULL) && (textDataSize != 0))
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if (textDataSize > 0xFFFFFFFF)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* if the users Data Out pointer is illegal return an error */
+    if ((pTextDataOut == NULL) && (textDataSize != 0))
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* check overlapping of input-output buffers:
+     1. in-placement operation is permitted, i.e. pTextDataIn = pTextDataOut
+     2. If pTextDataIn > pTextDataOut, operation is valid since HW reads the block,
+           perform operation and write the result to output which will not overwrite the next input operation block.
+           And the tag/mac result is written to another temporary buffer see in ccm_finish()
+     3. BUT,  pTextDataIn < pTextDataOut, operation is NOT valid since the output result will  overwrite the next input block,
+           or expected tag/mac */
+    if ((pTextDataIn < pTextDataOut) &&
+        (pTextDataIn + textDataSize > pTextDataOut))
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* set pointer to user context */
+    pAesCcmCtx = (AesCcmContext_t *) ctx;
+
+    /* set data buffers structures */
+    rc = SetDataBuffersInfo(pTextDataIn, textDataSize, &inBuffInfo, pTextDataOut, textDataSize, &outBuffInfo);
+    if (rc != 0)
+    {
+        CC_PAL_LOG_ERR("illegal data buffers\n");
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+#ifndef AES_NO_TUNNEL
+
+    /* use HW tunnel to process CCMPE/PD on text data */
+
+    if (pAesCcmCtx->dir == CRYPTO_DIRECTION_DECRYPT)
+    {
+        pAesCcmCtx->mode = CIPHER_CCMPD;
+    }
+    else
+    {
+        pAesCcmCtx->mode = CIPHER_CCMPE;
+    }
+
+    rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, textDataSize);
+    if (rc != AES_DRV_OK)
+    {
+        CC_PAL_LOG_ERR("HW tunnel processing CCMPE/PD on text data failed with error code %d\n", rc);
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+#else
+
+    /* invoke two separate operations in case of no tunneling is supported by HW */
+
+    if (pAesCcmCtx->dir == CRYPTO_DIRECTION_ENCRYPT)
+    {
+        /* set operation mode to CBC_MAC */
+        pAesCcmCtx->mode = CIPHER_CBC_MAC;
+
+        rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, buffAttr, textDataSize);
+        if ( rc != AES_DRV_OK )
+        {
+            CC_PAL_LOG_ERR("CBC_MAC on text data failed with error code %d\n", rc);
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+    }
+
+    /* Encrypt(decrypt) text data by AES-CTR, starting from CTR = CTR0+1 */
+    pAesCcmCtx->mode = CIPHER_CTR;
+    rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, textDataSize);
+    if ( rc != AES_DRV_OK)
+    {
+        CC_PAL_LOG_ERR("AES-CTR on text data failed with error code %d\n", rc);
+        return MBEDTLS_ERR_CCM_AUTH_FAILED;
+    }
+
+    if (pAesCcmCtx->dir == CRYPTO_DIRECTION_DECRYPT)
+    {
+        /* execute the AES-MAC on decrypt mode */
+        pAesCcmCtx->mode = CIPHER_CBC_MAC;
+
+        /* set data buffers structures */
+        rc = SetDataBuffersInfo(pTextDataOut, textDataSize, &inBuffInfo,
+                        NULL, 0, &outBuffInfo);
+        if (rc != 0)
+        {
+            CC_PAL_LOG_ERR("illegal data buffers\n");
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+
+        if (ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, textDataSize) != AES_DRV_OK )
+        {
+            CC_PAL_LOG_ERR("AES-MAC on decrypt data failed with error code %d\n", rc);
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+    }
+
+#endif
+
+    return (0);
+}
+
+static int ccm_finish(mbedtls_ccm_context *ctx, unsigned char * macBuf, size_t *sizeOfT)
+{
+
+    AesCcmContext_t *pAesCcmCtx;
+    uint8_t *tempBuff;
+    uint8_t qFieldSize;
+    drvError_t rc;
+    /* important to define different buffer for mac to support CCM with TextData in-place
+     * and pTextDataIn > pTextDataOut overlapping addresses, see comment in ccm_text_data()*/
+    uint8_t localMacBuf[CC_AES_BLOCK_SIZE_IN_BYTES];
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if (sizeOfT == NULL)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* if the users Data In pointer is illegal return an error */
+    if (macBuf == NULL)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* set pointer to user context */
+    pAesCcmCtx = (AesCcmContext_t *) ctx;
+
+    qFieldSize = 15 - pAesCcmCtx->sizeOfN;
+
+    /* encrypt (decrypt) the CCM-MAC value */
+    /* ------------------------------------------------------------------------- */
+
+    /* set operation to CTR mode */
+    pAesCcmCtx->mode = CIPHER_CTR;
+
+    /* set CTR value = CTR0 for encrypt(decrypt) CCM-MAC */
+    mbedtls_zeroize_internal((uint8_t*) pAesCcmCtx->ctrStateBuf + CC_AES_BLOCK_SIZE_IN_BYTES - qFieldSize, qFieldSize);
+
+    /* on CCM encrypt mode*/
+    if (pAesCcmCtx->dir == CRYPTO_DIRECTION_ENCRYPT)
+    {
+        /* set data buffers structures */
+        rc = SetDataBuffersInfo((uint8_t*) pAesCcmCtx->ivBuf, CC_AES_BLOCK_SIZE_IN_BYTES, &inBuffInfo, localMacBuf, CC_AES_BLOCK_SIZE_IN_BYTES, &outBuffInfo);
+        if (rc != 0)
+        {
+            CC_PAL_LOG_ERR("illegal data buffers\n");
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+
+        rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, CC_AES_BLOCK_SIZE_IN_BYTES);
+        if (rc != AES_DRV_OK)
+        {
+            CC_PAL_LOG_ERR("encryption of IV buf failed with error code %d\n", rc);
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+
+        CC_PalMemCopy(macBuf, localMacBuf, pAesCcmCtx->sizeOfT);
+
+    }
+    else
+    {/* on CCM decrypt mode*/
+        tempBuff = pAesCcmCtx->tempBuff;
+        mbedtls_zeroize_internal(tempBuff, sizeof(pAesCcmCtx->tempBuff));
+
+        /* copy encrypted CCM-MAC from input to temp buff padded with zeros */
+        CC_PalMemCopy(tempBuff, macBuf, pAesCcmCtx->sizeOfT);
+
+        /* set data buffers structures */
+        rc = SetDataBuffersInfo(tempBuff, CC_AES_BLOCK_SIZE_IN_BYTES, &inBuffInfo, tempBuff, CC_AES_BLOCK_SIZE_IN_BYTES, &outBuffInfo);
+        if (rc != 0)
+        {
+            CC_PAL_LOG_ERR("illegal data buffers\n");
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+
+        /* decrypt the MAC value and save it in the pAesCcmCtx->temp buffer */
+        rc = ProcessAesCcmDrv(pAesCcmCtx, &inBuffInfo, &outBuffInfo, CC_AES_BLOCK_SIZE_IN_BYTES);
+        if (rc != AES_DRV_OK)
+        {
+            CC_PAL_LOG_ERR("decryption of MAC buf failed with error code %d\n", rc);
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+        /* compare calculated and decrypted MAC results */
+        if (CC_PalMemCmp(pAesCcmCtx->ivBuf, tempBuff, pAesCcmCtx-> sizeOfT ) != 0)
+        {
+            /* if MAC results are different, return an Error */
+            CC_PAL_LOG_ERR("calculated and decrypted MAC results are different \n");
+            return MBEDTLS_ERR_CCM_AUTH_FAILED;
+        }
+    }
+
+    *sizeOfT = pAesCcmCtx->sizeOfT;
+
+    return (0);
+}
+
+static int ccm_auth_crypt(mbedtls_ccm_context *ctx,
+                          size_t length,
+                          const unsigned char *iv,
+                          size_t iv_len,
+                          const unsigned char *add,
+                          size_t add_len,
+                          const unsigned char *input,
+                          unsigned char *output,
+                          unsigned char *tag,
+                          size_t tag_len,
+                          cryptoDirection_t dir,
+                          uint32_t ccmMode)
+{
+    int rc;
+
+    /* check for  user context */
+    if (ctx == NULL)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    rc = ccm_init(ctx, dir, add_len, length, iv, iv_len, tag_len, ccmMode);
+    if (rc != 0)
+    {
+        return rc;
+    }
+
+    /* if there's no associated data, skip a0 encryption */
+    if (add_len != 0)
+    {
+        rc = ccm_ass_data(ctx, add, add_len);
+        if (rc != 0)
+        {
+            return rc;
+        }
+    }
+
+    /* if there's no payload data, skip to authentication */
+    if (length != 0)
+    {
+        rc = ccm_text_data(ctx, input, length, output);
+        if (rc != 0)
+        {
+            return rc;
+        }
+    }
+
+    rc = ccm_finish(ctx, tag, &tag_len);
+    if (0 != rc)
+    {
+        mbedtls_zeroize_internal(output, length);
+    }
+
+    return rc;
+}
+
+/****************************** PUBLIC **************************/
+int mbedtls_ccm_get_security_level(uint8_t sizeOfT, uint8_t *pSecurityLevel)
+{
+    if (pSecurityLevel == NULL)
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /*
+     The security level field for AES-CCM* as defined in ieee-802.15.4-2011, Table 58.
+     System spec requirement CCM*-3: The CCM* shall support only the security levels that include encryption (1XX values).
+     */
+    switch (sizeOfT)
+    {
+        case 0:
+            *pSecurityLevel = AESCCM_STAR_SECURITY_LEVEL_ENC;
+            break;
+        case 4:
+            *pSecurityLevel = AESCCM_STAR_SECURITY_LEVEL_ENC_MIC_32;
+            break;
+        case 8:
+            *pSecurityLevel = AESCCM_STAR_SECURITY_LEVEL_ENC_MIC_64;
+            break;
+        case 16:
+            *pSecurityLevel = AESCCM_STAR_SECURITY_LEVEL_ENC_MIC_128;
+            break;
+        default:
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    return CC_OK;
+}
+
+void mbedtls_ccm_init_int(mbedtls_ccm_context *ctx)
+{
+    if (ctx == NULL)
+    {
+        CC_PalAbort("!!!!CCM context is NULL!!!\n");
+    }
+    /* check size of structs match , memory allocated must be at least the size of AesCcmContext_t*/
+    if (sizeof(mbedtls_ccm_context) < sizeof(AesCcmContext_t))
+    {
+        CC_PalAbort("!!!!CCM context sizes mismatch!!!\n");
+    }
+    mbedtls_zeroize_internal(ctx, sizeof(mbedtls_ccm_context));
+
+}
+
+int mbedtls_ccm_setkey_int(mbedtls_ccm_context *ctx, mbedtls_cipher_id_t cipher, const unsigned char *key, unsigned int keybits)
+{
+
+    AesCcmContext_t *aes_ccm_ctx;
+
+    if (ctx == NULL || key == NULL)
+    {
+        CC_PAL_LOG_ERR("Null pointer, ctx or key are NULL\n");
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if (cipher != MBEDTLS_CIPHER_ID_AES)
+    {
+        /* No real use case for CCM other then AES*/
+        CC_PAL_LOG_ERR("Only AES cipher id is supported\n");
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+    aes_ccm_ctx = (AesCcmContext_t *) ctx;
+    switch (keybits)
+    {
+        case 128:
+
+            aes_ccm_ctx->keySizeId = KEY_SIZE_128_BIT;
+            break;
+
+        case 192:
+
+            aes_ccm_ctx->keySizeId = KEY_SIZE_192_BIT;
+            break;
+
+        case 256:
+
+            aes_ccm_ctx->keySizeId = KEY_SIZE_256_BIT;
+            break;
+
+        default:
+            return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    /* Copy user key to context */
+    CC_PalMemCopy(aes_ccm_ctx->keyBuf, key, keybits / 8);
+
+    return (0);
+}
+
+void mbedtls_ccm_free_int(mbedtls_ccm_context *ctx)
+{
+    if (ctx != NULL)
+    {
+        mbedtls_zeroize_internal(ctx, sizeof(mbedtls_ccm_context));
+    }
+}
+
+int mbedtls_ccm_encrypt_and_tag_int(mbedtls_ccm_context *ctx,
+                                    size_t length,
+                                    const unsigned char *iv,
+                                    size_t iv_len,
+                                    const unsigned char *add,
+                                    size_t add_len,
+                                    const unsigned char *input,
+                                    unsigned char *output,
+                                    unsigned char *tag,
+                                    size_t tag_len,
+                                    uint32_t ccmMode)
+{
+    return ccm_auth_crypt(ctx, length, iv, iv_len, add, add_len, input, output, tag, tag_len, CRYPTO_DIRECTION_ENCRYPT, ccmMode);
+}
+
+int mbedtls_ccm_auth_decrypt_int(mbedtls_ccm_context *ctx,
+                                 size_t length,
+                                 const unsigned char *iv,
+                                 size_t iv_len,
+                                 const unsigned char *add,
+                                 size_t add_len,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 const unsigned char *tag,
+                                 size_t tag_len,
+                                 uint32_t ccmMode)
+{
+
+    uint8_t localMacBuf[CC_AES_BLOCK_SIZE_IN_BYTES];
+
+    if (tag_len > CC_AES_BLOCK_SIZE_IN_BYTES)
+    {
+        CC_PAL_LOG_ERR("parameter tag_len is bigger then %d\n", CC_AES_BLOCK_SIZE_IN_BYTES);
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+    if (tag == NULL)
+    {
+        CC_PAL_LOG_ERR("\ntag NULL pointer\n");
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    CC_PalMemCopy(localMacBuf, tag, tag_len);
+    return ccm_auth_crypt(ctx, length, iv, iv_len, add, add_len, input, output, localMacBuf, tag_len, CRYPTO_DIRECTION_DECRYPT, ccmMode);
+}
+
+
+int mbedtls_ccm_star_nonce_generate(unsigned char * src_addr, uint32_t frame_counter, uint8_t size_of_t, unsigned char * nonce_buf)
+{
+    int rc = 0;
+    uint8_t securityLevelField = 0;
+
+    if ((src_addr == NULL) || (nonce_buf == NULL))
+    {
+        return MBEDTLS_ERR_CCM_BAD_INPUT;
+    }
+
+    if ((rc = mbedtls_ccm_get_security_level(size_of_t, &securityLevelField)) != 0)
+    {
+        return rc;
+    }
+
+    /*
+     The nonce structure for AES-CCM* is defined in ieee-802.15.4-2011, Figure 61:
+     Source address (8) | Frame counter (4) | Security lvel (1)
+     */
+
+    CC_PalMemCopy(nonce_buf, src_addr, MBEDTLS_AESCCM_STAR_SOURCE_ADDRESS_SIZE_BYTES);
+    CC_PalMemCopy(nonce_buf + MBEDTLS_AESCCM_STAR_SOURCE_ADDRESS_SIZE_BYTES, &frame_counter, sizeof(uint32_t));
+    nonce_buf[MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES - 1] = securityLevelField;
+
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_ccm_internal.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_ccm_internal.h
new file mode 100644
index 0000000..e15950c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_ccm_internal.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _MBEDTLS_CCM_INTERNAL_H
+#define _MBEDTLS_CCM_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "ccm.h"
+
+int mbedtls_ccm_get_security_level(uint8_t sizeOfT, uint8_t *pSecurityLevel);
+
+void mbedtls_ccm_init_int(mbedtls_ccm_context *ctx);
+
+int mbedtls_ccm_setkey_int(mbedtls_ccm_context *ctx, mbedtls_cipher_id_t cipher, const unsigned char *key, unsigned int keybits);
+
+void mbedtls_ccm_free_int(mbedtls_ccm_context *ctx);
+
+int mbedtls_ccm_encrypt_and_tag_int(mbedtls_ccm_context *ctx,
+                                    size_t length,
+                                    const unsigned char *iv,
+                                    size_t iv_len,
+                                    const unsigned char *add,
+                                    size_t add_len,
+                                    const unsigned char *input,
+                                    unsigned char *output,
+                                    unsigned char *tag,
+                                    size_t tag_len,
+                                    uint32_t ccmMode);
+
+int mbedtls_ccm_auth_decrypt_int(mbedtls_ccm_context *ctx,
+                                 size_t length,
+                                 const unsigned char *iv,
+                                 size_t iv_len,
+                                 const unsigned char *add,
+                                 size_t add_len,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 const unsigned char *tag,
+                                 size_t tag_len,
+                                 uint32_t ccmMode);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MBEDTLS_CCM_INTERNAL_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_chacha_ext_dma.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_chacha_ext_dma.c
new file mode 100644
index 0000000..7007ffd
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_chacha_ext_dma.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "mbedtls_cc_chacha.h"
+#include "mbedtls_cc_chacha_error.h"
+#include "driver_defs.h"
+#include "cc_sym_error.h"
+#include "chacha_driver_ext_dma.h"
+#include "mbedtls_ext_dma_error.h"
+
+
+static CCError_t Driver2ExtDMAChachaErr(drvError_t drvRc)
+{
+    switch (drvRc) {
+    case CHACHA_DRV_OK:
+        return CC_OK;
+    case CHACHA_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR:
+        return EXT_DMA_CHACHA_INVALID_ENCRYPT_MODE_ERROR;
+    case CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR:
+        return EXT_DMA_CHACHA_INVALID_NONCE_ERROR;
+    default:
+        return CC_FATAL_ERROR;
+    }
+}
+
+
+int mbedtls_ext_dma_chacha_init(uint8_t *  pNonce,
+                                mbedtls_chacha_nonce_size_t   nonceSizeFlag,
+                                uint8_t *  pKey,
+                                uint32_t    keySizeBytes,
+                                uint32_t    initialCounter,
+                                mbedtls_chacha_encrypt_mode_t  EncryptDecryptFlag,
+                                uint32_t    dataSize)
+{
+    drvError_t drvRc = CHACHA_DRV_OK;
+    uint32_t keyBufferWords[CC_CHACHA_KEY_MAX_SIZE_IN_WORDS];
+    uint32_t nonceBuffer[CC_CHACHA_NONCE_MAX_SIZE_IN_WORDS];
+    uint32_t nonceSizeBytes=0;
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+    /* if dataSize is 0 return an error */
+    if ((dataSize == 0) || (dataSize > CPU_DIN_MAX_SIZE)){
+        return EXT_DMA_CHACHA_ILLEGAL_INPUT_SIZE_ERROR;
+    }
+    /* if the pNonce is NULL return an error */
+    if (pNonce == NULL) {
+       return EXT_DMA_CHACHA_INVALID_NONCE_PTR_ERROR;
+    }
+
+    /* check the Encrypt / Decrypt flag validity */
+    if (EncryptDecryptFlag >= CC_CHACHA_EncryptNumOfOptions) {
+        return  EXT_DMA_CHACHA_INVALID_ENCRYPT_MODE_ERROR;
+    }
+
+    /*  check the validity of the key pointer */
+    if (pKey == NULL) {
+        return  EXT_DMA_CHACHA_INVALID_KEY_POINTER_ERROR;
+    }
+    if (keySizeBytes != CC_CHACHA_KEY_MAX_SIZE_IN_BYTES) {
+        return  EXT_DMA_CHACHA_ILLEGAL_KEY_SIZE_ERROR;
+
+    }
+
+    switch (nonceSizeFlag) {
+    case CC_CHACHA_Nonce64BitSize:
+        nonceSizeBytes = 8;
+        break;
+    case CC_CHACHA_Nonce96BitSize:
+        nonceSizeBytes = 12;
+        break;
+    default:
+        return  EXT_DMA_CHACHA_INVALID_NONCE_ERROR;
+    }
+
+    CC_PalMemCopy((uint8_t *)keyBufferWords, pKey, CC_CHACHA_KEY_MAX_SIZE_IN_BYTES);
+    CC_PalMemCopy((uint8_t *)nonceBuffer, pNonce, nonceSizeBytes);
+
+    drvRc = InitChachaExtDma(nonceBuffer, (chachaNonceSize_t)nonceSizeFlag, keyBufferWords, initialCounter, dataSize);
+
+    return Driver2ExtDMAChachaErr(drvRc);
+}
+
+
+int mbedtls_chacha_ext_dma_finish(void)
+{
+    drvError_t drvRc = CHACHA_DRV_OK;
+
+    drvRc = terminateChachaExtDma();
+
+    return Driver2ExtDMAChachaErr(drvRc);
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_hash_ext_dma.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_hash_ext_dma.c
new file mode 100644
index 0000000..4c4be90
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/api/mbedtls_hash_ext_dma.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_hash_defs.h"
+#include "hash_driver_ext_dma.h"
+#include "mbedtls_hash_ext_dma.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_sym_error.h"
+#include "cc_pal_perf.h"
+#include "cc_pal_compiler.h"
+#include "mbedtls_ext_dma_error.h"
+
+static int Driver2ExtDmaHashErr(drvError_t drvRc)
+{
+    switch (drvRc) {
+    case HASH_DRV_OK:
+        return 0;
+    case HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR:
+        return EXT_DMA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+    default:
+        return CC_FATAL_ERROR;
+    }
+}
+
+
+int mbedtls_hash_ext_dma_init(CCHashOperationMode_t  operationMode, uint32_t dataSize)
+{
+    drvError_t drvRc = HASH_DRV_OK;
+    int error = CC_OK;
+    hashMode_t mode;
+
+    /* check Hash mode */
+    switch (operationMode) {
+    case CC_HASH_SHA1_mode:
+        mode = HASH_SHA1;
+        break;
+    case CC_HASH_SHA224_mode:
+        mode = HASH_SHA224;
+        break;
+    case CC_HASH_SHA256_mode:
+        mode = HASH_SHA256;
+        break;
+    default:
+        error = EXT_DMA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        goto endInit;
+    }
+
+    if (dataSize > CPU_DIN_MAX_SIZE){
+        error = EXT_DMA_ILLEGAL_INPUT_SIZE_ERROR;
+        goto endInit;
+    }
+    drvRc = InitHashExtDma(mode, dataSize);
+    error = Driver2ExtDmaHashErr(drvRc);
+
+endInit:
+    return error;
+}
+
+
+
+int mbedtls_hash_ext_dma_finish(CCHashOperationMode_t  operationMode, uint32_t digestBufferSize, uint32_t *digestBuffer)
+{
+    CCError_t error = CC_OK;
+    drvError_t rc = HASH_DRV_OK;
+    hashMode_t mode;
+
+    if ( digestBuffer == NULL ) {
+        error = EXT_DMA_HASH_INVALID_RESULT_BUFFER_POINTER_ERROR;
+        goto endFinish;
+    }
+    if (digestBufferSize != CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES &&
+        digestBufferSize != CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES &&
+        digestBufferSize != CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES) {
+        error = EXT_DMA_HASH_ILLEGAL_PARAMS_ERROR;
+        goto endFinish;
+    }
+    /* check Hash mode */
+    switch (operationMode) {
+    case CC_HASH_SHA1_mode:
+        mode = HASH_SHA1;
+        break;
+    case CC_HASH_SHA224_mode:
+        mode = HASH_SHA224;
+        break;
+    case CC_HASH_SHA256_mode:
+        mode = HASH_SHA256;
+        break;
+    default:
+        error = EXT_DMA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        goto endFinish;
+    }
+
+    error = FinishHashExtDma(mode, digestBuffer);
+    error = Driver2ExtDmaHashErr(error);
+    return error;
+
+endFinish:
+    rc = terminateHashExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateAesExtDma \n");
+    }
+    return error;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver.c
new file mode 100644
index 0000000..3e3e722
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver.c
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "aes_driver.h"
+#include "driver_defs.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_sram_map.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "dx_nvm.h"
+#include "cc_otp_defs.h"
+#include "mbedtls_cc_mng_int.h"
+#include "cc_util_pm.h"
+#include "cc_int_general_defs.h"
+
+#define SET_ZEROS(buff, size) {\
+    uint32_t i = 0;\
+    for (i = 0; i< size; i++) {\
+        buff[i] = 0x0;\
+    }\
+}
+
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+
+/******************************************************************************
+*               PRIVATE FUNCTIONS
+******************************************************************************/
+
+/* Note: InitAes is private function and it is called only by the driver! */
+static drvError_t InitAes(AesContext_t *aesCtx)
+{
+        uint32_t aesCtrl = 0;
+        uint32_t irrVal = 0;
+        cryptoDirection_t dir;
+
+        /* verify user context pointer */
+        if ( aesCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* verify aes valid mode */
+        switch (aesCtx->mode) {
+        case CIPHER_ECB:
+        case CIPHER_CBC:
+        case CIPHER_CTR:
+        case CIPHER_CBC_MAC:
+    case CIPHER_CMAC:
+        case CIPHER_OFB:
+                break;
+        default:
+                return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+
+        /* verify aes valid dir */
+        if ( (aesCtx->dir != CRYPTO_DIRECTION_ENCRYPT) &&
+             (aesCtx->dir != CRYPTO_DIRECTION_DECRYPT) ) {
+                return AES_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR;
+        }
+
+        /* verify aes valid input addr type */
+        if ( (aesCtx->inputDataAddrType != SRAM_ADDR) &&
+             (aesCtx->inputDataAddrType != DLLI_ADDR) ) {
+                return AES_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR;
+        }
+
+        /* verify aes valid output addr type for ecb, cbc, ctr */
+        if ( (aesCtx->outputDataAddrType != SRAM_ADDR) &&
+             (aesCtx->outputDataAddrType != DLLI_ADDR) ) {
+                return AES_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR;
+        }
+
+        /* make sure sym engines are ready to use */
+        CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+        /* clear all interrupts before starting the engine */
+        CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+        /* mask dma interrupts which are not required */
+        irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
+        CC_HalMaskInterrupt(irrVal);
+
+        /* configure DIN-AES-DOUT */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_DIN_AES_DOUT_VAL);
+
+    /* Zero AES_REMAINING_BYTES */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES) ,0);
+
+    /* configure AES direction (in case of CMAC - force only encrypt) */
+    if ((aesCtx->mode == CIPHER_CBC_MAC) || (aesCtx->mode == CIPHER_CMAC))
+        dir = CRYPTO_DIRECTION_ENCRYPT;
+    else
+        dir = aesCtx->dir;
+    CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesCtrl, dir);
+
+    /* configure AES mode */
+    CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesCtrl, aesCtx->mode);
+    switch (aesCtx->keySizeId) {
+        case KEY_SIZE_128_BIT:
+        case KEY_SIZE_192_BIT:
+        case KEY_SIZE_256_BIT:
+                /* NK_KEY0 and NK_KEY1 are configured, only NK_KEY0 is in use (no tunneling in cc3x)*/
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesCtrl, aesCtx->keySizeId);
+                break;
+        default:
+                return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
+        }
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL) ,aesCtrl);
+
+        /* initiate CMAC sub-keys calculation */
+        if (aesCtx->mode == CIPHER_CMAC) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CMAC_INIT) ,0x1);
+        }
+
+        return AES_DRV_OK;
+}
+
+static drvError_t LoadAesKey(AesContext_t *aesCtx)
+{
+        uint32_t   error = 0;
+        uint32_t   isKeyInUse = 0;
+
+        /* verify user context pointer */
+        if ( aesCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        switch (aesCtx->cryptoKey) {
+        case USER_KEY:
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_0) ,aesCtx->keyBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_1) ,aesCtx->keyBuf[1]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_2) ,aesCtx->keyBuf[2]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_3) ,aesCtx->keyBuf[3]);
+                if (aesCtx->keySizeId == KEY_SIZE_192_BIT || aesCtx->keySizeId == KEY_SIZE_256_BIT) {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_4) ,aesCtx->keyBuf[4]);
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_5) ,aesCtx->keyBuf[5]);
+                }
+                if (aesCtx->keySizeId == KEY_SIZE_256_BIT)
+                {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_6) ,aesCtx->keyBuf[6]);
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_7) ,aesCtx->keyBuf[7]);
+                }
+                break;
+        case RKEK_KEY:
+        /* Verify no integrity error */
+        CC_IS_KEY_ERROR(KDR, error);
+        if (error == CC_TRUE) {
+            return AES_DRV_ILLEGAL_KEY_INTEGRITY_ERROR;
+        }
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_CRYPTOKEY_SEL) ,aesCtx->cryptoKey);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_SK), 0x1);
+                break;
+        case KCP_KEY:
+        /* Verify key is in use */
+        CC_IS_OTP_KEY_IN_USE(OEM, KCP, error, isKeyInUse);
+        if ( (error != CC_OK) || (isKeyInUse != CC_TRUE) ) {
+            return AES_DRV_ILLEGAL_KEY_USE_ERROR;
+        }
+
+        /* Verify key is not locked */
+        CC_IS_KEY_LOCKED(KCP, error);
+        if (error == CC_TRUE) {
+            return AES_DRV_ILLEGAL_KEY_LOCK_ERROR;
+        }
+
+        /* Verify no integrity error */
+        CC_IS_KEY_ERROR(PROV, error);
+        if (error == CC_TRUE) {
+            return AES_DRV_ILLEGAL_KEY_INTEGRITY_ERROR;
+        }
+
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_CRYPTOKEY_SEL) ,aesCtx->cryptoKey);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_SK), 0x1);
+                break;
+        case KPICV_KEY:
+        /* Verify key is in use */
+        CC_IS_OTP_KEY_IN_USE(MANUFACTURE, KPICV, error, isKeyInUse);
+        if ( (error != CC_OK) || (isKeyInUse != CC_TRUE) ) {
+            return AES_DRV_ILLEGAL_KEY_USE_ERROR;
+        }
+
+        /* Verify key is not locked */
+        CC_IS_KEY_LOCKED(KPICV, error);
+        if (error == CC_TRUE) {
+            return AES_DRV_ILLEGAL_KEY_LOCK_ERROR;
+        }
+
+        /* Verify no integrity error */
+        CC_IS_KEY_ERROR(KPICV, error);
+        if (error == CC_TRUE) {
+            return AES_DRV_ILLEGAL_KEY_INTEGRITY_ERROR;
+        }
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_CRYPTOKEY_SEL) ,aesCtx->cryptoKey);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_SK), 0x1);
+                break;
+        case RTL_KEY:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_CRYPTOKEY_SEL) ,1);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_SK), 0x1);
+        break;
+        default:
+                return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+
+       }
+
+       /* For all HW keys, check if fatal error bit is set to ON */
+       if (aesCtx->cryptoKey != USER_KEY) {
+               CC_IS_FATAL_ERR_ON(error);
+               if (error == CC_TRUE) {
+                   return AES_DRV_ILLEGAL_FATAL_ERR_BIT_ERROR;
+               }
+       }
+       return AES_DRV_OK;
+}
+
+static drvError_t LoadIVState(AesContext_t *aesCtx)
+{
+        /* verify user context pointer */
+        if ( aesCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* write the initial counter value according to mode */
+        switch (aesCtx->mode) {
+    case(CIPHER_CTR):
+    case(CIPHER_OFB):
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0) ,aesCtx->ivBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1) ,aesCtx->ivBuf[1]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2) ,aesCtx->ivBuf[2]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3) ,aesCtx->ivBuf[3]);
+                break;
+        case(CIPHER_CMAC):
+        case(CIPHER_CBC):
+    case(CIPHER_CBC_MAC):
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0) ,aesCtx->ivBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1) ,aesCtx->ivBuf[1]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2) ,aesCtx->ivBuf[2]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3) ,aesCtx->ivBuf[3]);
+        case(CIPHER_ECB):
+                break;
+        default:
+                return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+
+        return AES_DRV_OK;
+}
+
+static drvError_t StoreIVState(AesContext_t *aesCtx)
+{
+        /* verify user context pointer */
+        if ( aesCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* write the initial counter value according to mode */
+        switch (aesCtx->mode) {
+    case(CIPHER_CTR):
+    case(CIPHER_OFB):
+                aesCtx->ivBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0));
+                aesCtx->ivBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1));
+                aesCtx->ivBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2));
+                aesCtx->ivBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3));
+                break;
+        case(CIPHER_CMAC):
+        case(CIPHER_CBC):
+    case(CIPHER_CBC_MAC):
+                aesCtx->ivBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0));
+                aesCtx->ivBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1));
+                aesCtx->ivBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2));
+                aesCtx->ivBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3));
+        case(CIPHER_ECB):
+                break;
+        default:
+                return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+
+        return AES_DRV_OK;
+
+}
+
+static drvError_t finalizeCmac(AesContext_t *aesCtx, CCBuffInfo_t *pInputBuffInfo, uint32_t blockSize)
+{
+        drvError_t drvRc = AES_DRV_OK;
+        uint32_t irrVal = 0;
+        uint32_t regVal = 0;
+        uint32_t inputDataAddr;
+
+        /* check input parameters */
+        if (pInputBuffInfo == NULL) {
+             return AES_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+        }
+
+
+    if (((aesCtx->inputDataAddrType == SRAM_ADDR) && (blockSize >= CC_SRAM_MAX_SIZE)) ||
+        ((aesCtx->inputDataAddrType == DLLI_ADDR) && (blockSize >= DLLI_MAX_BUFF_SIZE))) {
+                return AES_DRV_ILLEGAL_MEM_SIZE_ERROR;
+    }
+
+    // In ARM CryptoCell 3xx we can't have last block == 0, since as NIST 800-38B says:
+    // "the final block in the partition is replaced with the exclusive-OR of the final block with the first subkey"
+    // In ARM CryptoCell 3xx we enable/disable the AES clock for every block, so HW doesn't keep the first key and nither does the driver.
+    // so we dont have the first key and we cant xor with it.
+        if ((blockSize == 0) && (aesCtx->dataBlockType != FIRST_BLOCK)) {
+                return AES_DRV_ILLEGAL_MEM_SIZE_ERROR;
+        }
+
+        /* lock mutex for more aes hw operation */
+        drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        drvRc = CC_IS_WAKE;
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* enable clock */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+        drvRc = InitAes(aesCtx);
+        if (drvRc != AES_DRV_OK) {
+                goto FinishExit;
+        }
+
+        /* load AES key and iv length and digest */
+        drvRc = LoadAesKey(aesCtx);
+        if (drvRc != 0){
+            goto FinishExit;
+        }
+
+        drvRc = LoadIVState(aesCtx);
+        if (drvRc != 0){
+            goto FinishExit;
+        }
+
+        /* initiate CMAC sub-keys calculation */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CMAC_INIT) ,0x1);
+        /* set the remaining bytes */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES) ,blockSize);
+
+        inputDataAddr = pInputBuffInfo->dataBuffAddr;
+
+        /* configure the HW with the correct data buffer attributes (secure/non-secure) */
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
+
+
+        if (blockSize == 0) {
+                if (aesCtx->dataBlockType == FIRST_BLOCK) {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CMAC_SIZE0_KICK) ,0x1);
+                }
+        } else {
+                /* configure source address and size, set the relevant IRR bit */
+                if (aesCtx->inputDataAddrType == DLLI_ADDR) {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,blockSize);
+                } else {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_SRC_ADDR) ,inputDataAddr);
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_SRAM_BYTES_LEN) ,blockSize);
+                }
+                /* set dma completion bit in irr */
+                CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+                drvRc = CC_HalWaitInterrupt(irrVal);
+                if (drvRc != 0){
+                    goto FinishExit;
+                }
+        }
+
+        /* get machine state */
+        StoreIVState(aesCtx);
+        /* Note: the upper layer should copy the mac result to outputDataAddr using PAL */
+
+FinishExit:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+        /* decrease CC counter at the end of each operation */
+        if (CC_IS_IDLE != 0) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+        }
+
+        /* release mutex */
+        if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+            CC_PalAbort("Fail to release mutex\n");
+        }
+
+        return drvRc;
+}
+
+
+
+/******************************************************************************
+*       PUBLIC FUNCTIONS
+******************************************************************************/
+
+drvError_t ProcessAesDrv(AesContext_t *aesCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize)
+{
+        uint32_t irrVal = 0;
+        drvError_t drvRc = AES_DRV_OK;
+        uint32_t regVal = 0;
+        uint32_t inputDataAddr, outputDataAddr;
+
+        /* check input parameters */
+        if ( (pInputBuffInfo == NULL) || (pOutputBuffInfo == NULL)) {
+             return AES_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+        }
+
+        /* verify user context pointer */
+        if ( aesCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+        if (((aesCtx->inputDataAddrType == SRAM_ADDR) && (blockSize >= CC_SRAM_MAX_SIZE)) ||
+            ((aesCtx->inputDataAddrType == DLLI_ADDR) && (blockSize >= DLLI_MAX_BUFF_SIZE))) {
+                    return AES_DRV_ILLEGAL_MEM_SIZE_ERROR;
+        }
+
+        /* lock mutex for more aes hw operation */
+        drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        drvRc = CC_IS_WAKE;
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* enable clock */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+        drvRc = InitAes(aesCtx);
+        if (drvRc != AES_DRV_OK) {
+                goto ProcessExit;
+        }
+
+        drvRc = LoadAesKey(aesCtx);
+        if (drvRc != AES_DRV_OK){
+            goto ProcessExit;
+        }
+
+        drvRc = LoadIVState(aesCtx);
+        if (drvRc != AES_DRV_OK) {
+            goto ProcessExit;
+        }
+
+        inputDataAddr = pInputBuffInfo->dataBuffAddr;
+        outputDataAddr = pOutputBuffInfo->dataBuffAddr;
+
+        /* configure the HW with the correct data buffer attributes (secure/non-secure) */
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, pOutputBuffInfo->dataBuffNs);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
+
+        if ((aesCtx->mode != CIPHER_CBC_MAC) && (aesCtx->mode != CIPHER_CMAC)) {
+                /* configure destination address and size in case of ecb or cbc or ctr */
+                /* and set dout bit in irr */
+                if (aesCtx->outputDataAddrType == DLLI_ADDR) {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD0) ,outputDataAddr);
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD1) ,blockSize);
+                } else {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_DEST_ADDR) ,outputDataAddr);
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DOUT_SRAM_BYTES_LEN) ,blockSize);
+                }
+        }
+
+        /* configure source address and size */
+        if (aesCtx->inputDataAddrType == DLLI_ADDR) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,blockSize);
+        } else {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_SRC_ADDR) ,inputDataAddr);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_SRAM_BYTES_LEN) ,blockSize);
+        }
+
+        /* set dma completion bit in irr */
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+    drvRc = CC_HalWaitInterrupt(irrVal);
+    if (drvRc != 0){
+        goto ProcessExit;
+    }
+
+        /* get machine state */
+        StoreIVState(aesCtx);
+
+        /* at least one block of data processed */
+        aesCtx->dataBlockType =  MIDDLE_BLOCK;
+
+        ProcessExit:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+        /* decrease CC counter at the end of each operation */
+        if (CC_IS_IDLE != 0) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+        }
+
+        /* release mutex */
+        if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+            CC_PalAbort("Fail to release mutex\n");
+        }
+
+        return drvRc;
+}
+
+
+drvError_t FinishAesDrv(AesContext_t *aesCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize)
+{
+        drvError_t drvRc = AES_DRV_OK;
+
+        /* check input parameters */
+        if ( (pInputBuffInfo == NULL) || (pOutputBuffInfo == NULL)) {
+             return AES_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+        }
+
+        /* verify user context pointer */
+        if ( aesCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        switch (aesCtx->mode) {
+        case CIPHER_CMAC:
+                drvRc = finalizeCmac(aesCtx, pInputBuffInfo, blockSize);
+                break;
+        default:
+                if (blockSize == 0) {
+                        if ((aesCtx->mode == CIPHER_CBC_MAC) && (aesCtx->dataBlockType == FIRST_BLOCK)) { // according to ISO/IEC 9797-1 sec 6.1.3
+                                blockSize = sizeof(aesCtx->tempBuff);
+                                SET_ZEROS(aesCtx->tempBuff, blockSize);
+                                pInputBuffInfo->dataBuffAddr = (uint32_t)aesCtx->tempBuff;
+                        } else
+                                return AES_DRV_OK;
+                }
+                drvRc = ProcessAesDrv(aesCtx, pInputBuffInfo, pOutputBuffInfo, blockSize);
+        }
+
+        return drvRc;
+}
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver.h
new file mode 100644
index 0000000..f631c73
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _AES_DRIVER_H
+#define  _AES_DRIVER_H
+
+#include "driver_defs.h"
+
+/******************************************************************************
+*               TYPE DEFINITIONS
+******************************************************************************/
+
+/* The context data-base used by the AES functions on the low level */
+typedef struct AesContext {
+        /* IV buffer contains: on CTR mode - Counter, on other modes - IV */
+        uint32_t    ivBuf[AES_IV_SIZE_WORDS];
+        /* AES Key: fixed size is 128 bit = 512/2*/
+        uint32_t    keyBuf[AES_256_BIT_KEY_SIZE_WORDS];
+        /* keySize: 128, 192, 256 */
+        keySizeId_t   keySizeId;
+        /* mode: ECB, CBC, CTR, CBC-MAC, CMAC */
+        aesMode_t mode;
+        /* Decrypt / Encrypt */
+        cryptoDirection_t dir;
+        /* key type: user or hw(RKEK/PROV) */
+        cryptoKeyType_t cryptoKey;
+        /* padding type */
+        cryptoPaddingType_t padType;
+        /* first/middel/last */
+        DataBlockType_t dataBlockType;
+        /* data input addr type */
+        dataAddrType_t inputDataAddrType;
+        /* data output addr type */
+        dataAddrType_t outputDataAddrType;
+        uint8_t     tempBuff[AES_BLOCK_SIZE];
+} AesContext_t;
+
+
+/******************************************************************************
+*               FUNCTION PROTOTYPES
+******************************************************************************/
+
+/*!
+ * This function is used to process block(s) of data using the AES machine.
+ *
+ * \param aesCtx A pointer to the AES context buffer.
+ * \param pInputBuffInfo A structure which represents the data input buffer.
+ * \param pOutputBuffInfo A structure which represents the data output buffer.
+ * \param blockSize - number of bytes to copy.
+ *
+ * \return drvError_t defined in driver_defs.h.
+ */
+drvError_t ProcessAesDrv(AesContext_t *aesCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize);
+
+/*!
+ * This function is used as finish operation of AES on XCBC, CMAC, CBC
+ * and other modes besides XTS mode.
+ * The function may either be called after "InitCipher" or "ProcessCipher".
+ *
+ * \param aesCtx A pointer to the AES context buffer.
+ * \param pInputBuffInfo A structure which represents the data input buffer.
+ * \param pOutputBuffInfo A structure which represents the data output buffer.
+ * \param blockSize - number of bytes to copy.
+ *
+ * \return drvError_t defined in driver_defs.h.
+ */
+drvError_t FinishAesDrv(AesContext_t *aesCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize);
+
+
+#endif /* _AES_DRIVER_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver_ext_dma.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver_ext_dma.c
new file mode 100644
index 0000000..af5fccf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver_ext_dma.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "aes_driver.h"
+#include "driver_defs.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "aes_driver_ext_dma.h"
+#include "cc_util_pm.h"
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+
+
+
+/******************************************************************************
+*       PUBLIC FUNCTIONS
+******************************************************************************/
+drvError_t AesExtDmaInit(cryptoDirection_t   encryptDecryptFlag,
+        aesMode_t operationMode,
+        keySizeId_t          keySizeId)
+{
+        uint32_t aesCtrl = 0;
+        uint32_t irrVal = 0;
+        cryptoDirection_t dir;
+        drvError_t rc = AES_DRV_OK;
+        uint32_t pIv[AES_BLOCK_SIZE_WORDS] = {0};
+
+        /* verify aes valid mode */
+        switch (operationMode) {
+        case CIPHER_ECB:
+        case CIPHER_CBC:
+        case CIPHER_CTR:
+        case CIPHER_CBC_MAC:
+        case CIPHER_CMAC:
+        case CIPHER_OFB:
+                break;
+        default:
+                return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+
+        /* verify aes valid dir */
+        if ( (encryptDecryptFlag != CRYPTO_DIRECTION_ENCRYPT) &&
+             (encryptDecryptFlag != CRYPTO_DIRECTION_DECRYPT) ) {
+                return AES_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR;
+        }
+
+
+        /* lock mutex for more aes hw operation */
+        rc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+        if (rc != 0) {
+            CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        rc = CC_IS_WAKE;
+        if (rc != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* enable clock */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+        /* make sure sym engines are ready to use */
+        CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+        /* clear all interrupts before starting the engine */
+        CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+        /* mask dma interrupts which are not required */
+        irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 1);
+        CC_HalMaskInterrupt(irrVal);
+
+        /* configure DIN-AES-DOUT */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_DIN_AES_DOUT_VAL);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), 0);
+
+        /* configure AES direction (in case of CMAC - force only encrypt) */
+        if ((operationMode == CIPHER_CBC_MAC) || (operationMode == CIPHER_CMAC)){
+            dir = CRYPTO_DIRECTION_ENCRYPT;
+        }
+        else {
+            dir = encryptDecryptFlag;
+        }
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesCtrl, dir);
+
+        /* configure AES mode */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesCtrl, operationMode);
+        switch (keySizeId) {
+        case KEY_SIZE_128_BIT:
+        case KEY_SIZE_192_BIT:
+        case KEY_SIZE_256_BIT:
+            /* NK_KEY0 and NK_KEY1 are configured, only NK_KEY0 is in use (no tunneling in cc3x)*/
+            CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesCtrl, keySizeId);
+            break;
+        default:
+            goto end;
+        }
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL) ,aesCtrl);
+
+        /* zeroize IV in CMAC */
+        if (operationMode == CIPHER_CMAC) {
+            rc = AesExtDmaSetIv(operationMode, pIv);
+            if (rc != 0) {
+                goto end;
+            }
+        }
+
+        return AES_DRV_OK;
+
+end:
+        rc = terminateAesExtDma();
+        if (rc != 0) {
+            CC_PalAbort("Failed to terminateAesExtDma \n");
+        }
+        return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
+}
+
+
+void AesExtDmaSetDataSize(uint32_t dataSize)
+{
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), dataSize);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_CPU_DATA_SIZE) , dataSize);
+}
+
+drvError_t AesExtDmaSetIv(aesMode_t mode, uint32_t *pIv)
+{
+    drvError_t rc = AES_DRV_OK;
+    /* write the initial counter value according to mode */
+    switch (mode) {
+    case(CIPHER_CTR):
+    case(CIPHER_OFB):
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0) ,pIv[0]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1) ,pIv[1]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2) ,pIv[2]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3) ,pIv[3]);
+        break;
+    case(CIPHER_CMAC):
+    case(CIPHER_CBC):
+    case(CIPHER_CBC_MAC):
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0) ,pIv[0]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1) ,pIv[1]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2) ,pIv[2]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3) ,pIv[3]);
+        break;
+    case(CIPHER_ECB):
+        break;
+    default:
+        rc = AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+    }
+
+    return rc;
+}
+
+
+drvError_t AesExtDmaStoreIv(aesMode_t mode, uint32_t *pIv)
+{
+    drvError_t rc = AES_DRV_OK;
+    /* write the initial counter value according to mode */
+    switch (mode) {
+
+    case(CIPHER_CMAC):
+    case(CIPHER_CBC_MAC):
+        pIv[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0));
+        pIv[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1));
+        pIv[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2));
+        pIv[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3));
+        break;
+    default:
+        rc = AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+    }
+    return rc;
+}
+
+
+
+drvError_t AesExtDmaSetKey(aesMode_t mode, uint32_t *keyBuf, keySizeId_t keySizeId)
+{
+    /* verify user context pointer */
+    if ( keyBuf == NULL ) {
+        return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
+    }
+    if ((keySizeId != KEY_SIZE_256_BIT) && (keySizeId != KEY_SIZE_192_BIT) && (keySizeId != KEY_SIZE_128_BIT)) {
+        return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
+    }
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_0) ,keyBuf[0]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_1) ,keyBuf[1]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_2) ,keyBuf[2]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_3) ,keyBuf[3]);
+
+    if (keySizeId == KEY_SIZE_192_BIT || keySizeId == KEY_SIZE_256_BIT) {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_4) ,keyBuf[4]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_5) ,keyBuf[5]);
+    }
+    if (keySizeId == KEY_SIZE_256_BIT) {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_6) ,keyBuf[6]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_7) ,keyBuf[7]);
+    }
+
+    /* initiate CMAC sub-keys calculation */
+    if (mode == CIPHER_CMAC) {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CMAC_INIT) ,0x1);
+    }
+
+    return AES_DRV_OK;
+}
+
+
+drvError_t finalizeAesExtDma(aesMode_t mode, uint32_t *pIv)
+{
+        drvError_t drvRc = AES_DRV_OK;
+
+        if (mode == CIPHER_CMAC || mode== CIPHER_CBC_MAC)
+        {
+            drvRc = AesExtDmaStoreIv(mode, pIv);
+        }
+
+        return drvRc;
+}
+
+drvError_t terminateAesExtDma(void)
+{
+        drvError_t rc = AES_DRV_OK;
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+        /* decrease CC counter at the end of each operation */
+        rc = CC_IS_IDLE;
+        if (rc != 0) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+        }
+
+        /* unlock mutex for more aes hw operation */
+        rc = CC_PalMutexUnlock(&CCSymCryptoMutex);
+        if (rc != 0) {
+            CC_PalAbort("Fail to unlock mutex\n");
+        }
+        return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver_ext_dma.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver_ext_dma.h
new file mode 100644
index 0000000..6a5e046
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aes_driver_ext_dma.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _AES_DRIVER_EXT_DMA_H
+#define  _AES_DRIVER_EXT_DMA_H
+
+#include "driver_defs.h"
+#include "aes_driver.h"
+
+
+
+
+
+drvError_t finalizeAesExtDma(aesMode_t mode, uint32_t *pIv);
+drvError_t terminateAesExtDma(void);
+
+
+drvError_t AesExtDmaSetIv(aesMode_t mode, uint32_t *pIv);
+
+
+drvError_t AesExtDmaSetKey(aesMode_t mode, uint32_t *keyBuf, keySizeId_t keySizeId);
+
+
+void       AesExtDmaSetDataSize(uint32_t dataSize);
+
+
+drvError_t AesExtDmaInit(cryptoDirection_t encryptDecryptFlag,
+        aesMode_t operationMode,
+        keySizeId_t keySizeId);
+
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesccm_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesccm_driver.c
new file mode 100644
index 0000000..d29594f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesccm_driver.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stddef.h>
+
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "driver_defs.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_sram_map.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "aesccm_driver.h"
+#include "cc_util_pm.h"
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+
+/******************************************************************************
+*               PRIVATE FUNCTIONS
+******************************************************************************/
+
+static drvError_t InitAesCcm(AesCcmContext_t   *pAesCcmCtx)
+{
+        uint32_t aesControl = 0;
+        uint32_t irrVal = 0;
+
+        /* verify user context pointer */
+        if ( pAesCcmCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* verify valid dir */
+        if ( (pAesCcmCtx->dir != CRYPTO_DIRECTION_ENCRYPT) &&
+             (pAesCcmCtx->dir != CRYPTO_DIRECTION_DECRYPT) ) {
+                return AES_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR;
+        }
+
+        /* veriy mode and set aes control */
+        switch (pAesCcmCtx->mode) {
+        case CIPHER_CBC_MAC:
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, CRYPTO_DIRECTION_ENCRYPT);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CBC_MAC);
+                break;
+        case CIPHER_CTR:
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, pAesCcmCtx->dir);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CTR);
+                break;
+        case CIPHER_CCMPE:
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, pAesCcmCtx->dir);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CTR);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY1, aesControl, CIPHER_CBC_MAC);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL_IS_ON, aesControl, 1);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUN_B1_USES_PADDED_DATA_IN, aesControl, 1);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL0_ENCRYPT, aesControl, 1);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_OUTPUT_MID_TUNNEL_DATA, aesControl, 1);
+                break;
+        case CIPHER_CCMPD:
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesControl, pAesCcmCtx->dir);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesControl, CIPHER_CTR);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY1, aesControl, CIPHER_CBC_MAC);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL_IS_ON, aesControl, 1);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_OUTPUT_MID_TUNNEL_DATA, aesControl, 1);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, AES_TUNNEL_B1_PAD_EN, aesControl, 1);
+                break;
+        default:
+                return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+
+        /* verify keySizeID */
+        switch (pAesCcmCtx->keySizeId) {
+        case KEY_SIZE_128_BIT:
+        case KEY_SIZE_192_BIT:
+        case KEY_SIZE_256_BIT:
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesControl, pAesCcmCtx->keySizeId);
+                CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY1, aesControl, pAesCcmCtx->keySizeId);
+                break;
+        default:
+                return AES_DRV_ILLEGAL_KEY_SIZE_ERROR;
+        }
+
+        /* make sure sym engines are ready to use */
+        CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+        /* clear all interrupts before starting the engine */
+        CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+        /* mask dma interrupts which are not required */
+        irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
+        CC_HalMaskInterrupt(irrVal);
+
+        /* configure DIN-AES-DOUT */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_DIN_AES_DOUT_VAL);
+
+    /* Zero AES_REMAINING_BYTES */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES) ,0);
+
+    /* configure AES control */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL) ,aesControl);
+
+        return AES_DRV_OK;
+}
+
+static void LoadAesCcmdKey(AesCcmContext_t   *pAesCcmCtx)
+{
+        /* load key0 [127:0]*/
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_0) ,pAesCcmCtx->keyBuf[0]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_1) ,pAesCcmCtx->keyBuf[1]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_2) ,pAesCcmCtx->keyBuf[2]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_3) ,pAesCcmCtx->keyBuf[3]);
+
+        /* load key1 [127:0]*/
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_0) ,pAesCcmCtx->keyBuf[0]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_1) ,pAesCcmCtx->keyBuf[1]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_2) ,pAesCcmCtx->keyBuf[2]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_3) ,pAesCcmCtx->keyBuf[3]);
+
+        if (pAesCcmCtx->keySizeId >= KEY_SIZE_192_BIT) {
+                /* load key0 [191:128]*/
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_4) ,pAesCcmCtx->keyBuf[4]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_5) ,pAesCcmCtx->keyBuf[5]);
+                /* load key1 [191:128]*/
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_4) ,pAesCcmCtx->keyBuf[4]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_5) ,pAesCcmCtx->keyBuf[5]);
+        }
+
+        if (pAesCcmCtx->keySizeId == KEY_SIZE_256_BIT) {
+                /* load key0 [255:191]*/
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_6) ,pAesCcmCtx->keyBuf[6]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_7) ,pAesCcmCtx->keyBuf[7]);
+                /* load key1 [255:191]*/
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_6) ,pAesCcmCtx->keyBuf[6]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_1_7) ,pAesCcmCtx->keyBuf[7]);
+        }
+
+        return;
+}
+
+static void LoadAesCcmIvState(AesCcmContext_t   *pAesCcmCtx)
+{
+        if (pAesCcmCtx->mode == CIPHER_CBC_MAC) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0) ,pAesCcmCtx->ivBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1) ,pAesCcmCtx->ivBuf[1]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2) ,pAesCcmCtx->ivBuf[2]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3) ,pAesCcmCtx->ivBuf[3]);
+        } else {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_0) ,pAesCcmCtx->ivBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_1) ,pAesCcmCtx->ivBuf[1]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_2) ,pAesCcmCtx->ivBuf[2]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_3) ,pAesCcmCtx->ivBuf[3]);
+        }
+
+        return;
+}
+
+static void LoadAesCcmCtrState(AesCcmContext_t   *pAesCcmCtx)
+{
+        /* write the initial counter value according to mode */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0) ,pAesCcmCtx->ctrStateBuf[0]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1) ,pAesCcmCtx->ctrStateBuf[1]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2) ,pAesCcmCtx->ctrStateBuf[2]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3) ,pAesCcmCtx->ctrStateBuf[3]);
+
+        return;
+}
+
+
+static void StoreAesCcmIvState(AesCcmContext_t   *pAesCcmCtx)
+{
+        if (pAesCcmCtx->mode == CIPHER_CBC_MAC) {
+                pAesCcmCtx->ivBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_0));
+                pAesCcmCtx->ivBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_1));
+                pAesCcmCtx->ivBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_2));
+                pAesCcmCtx->ivBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_0_3));
+        } else {
+                pAesCcmCtx->ivBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_0));
+                pAesCcmCtx->ivBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_1));
+                pAesCcmCtx->ivBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_2));
+                pAesCcmCtx->ivBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_IV_1_3));
+        }
+
+        return;
+}
+
+
+static void StoreAesCcmCtrState(AesCcmContext_t   *pAesCcmCtx)
+{
+        /* write the initial counter value according to mode */
+        pAesCcmCtx->ctrStateBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0));
+        pAesCcmCtx->ctrStateBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1));
+        pAesCcmCtx->ctrStateBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2));
+        pAesCcmCtx->ctrStateBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3));
+
+        return;
+}
+
+
+/******************************************************************************
+*               PUBLIC FUNCTIONS
+******************************************************************************/
+
+drvError_t ProcessAesCcmDrv(AesCcmContext_t   *pAesCcmCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize)
+{
+        uint32_t irrVal = 0;
+        drvError_t drvRc = AES_DRV_OK;
+        uint32_t regVal = 0;
+        uint32_t inputDataAddr, outputDataAddr;
+
+        /* check input parameters */
+        if ( (pInputBuffInfo == NULL) || (pOutputBuffInfo == NULL)) {
+             return AES_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+        }
+
+        /* verify user context pointer */
+        if ( pAesCcmCtx == NULL ) {
+                return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* verify valid block size */
+    if (blockSize >= DLLI_MAX_BUFF_SIZE) {
+                return AES_DRV_ILLEGAL_MEM_SIZE_ERROR;
+    }
+
+        /* lock mutex for more aes hw operation */
+        drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        drvRc = CC_IS_WAKE;
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* enable clock */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+        drvRc = InitAesCcm(pAesCcmCtx);
+        if (drvRc != AES_DRV_OK) {
+                goto ProcessExit;
+        }
+
+        /* load key0 and key1 */
+        LoadAesCcmdKey(pAesCcmCtx);
+
+        inputDataAddr = pInputBuffInfo->dataBuffAddr;
+        outputDataAddr = pOutputBuffInfo->dataBuffAddr;
+
+        /* configure the HW with the correct data buffer attributes (secure/non-secure) */
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, pOutputBuffInfo->dataBuffNs);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
+
+        /* load CTR in case of CTR / CCMPE / CCMPD */
+        if (pAesCcmCtx->mode != CIPHER_CBC_MAC) {
+        /* write the initial counter value according to mode */
+                LoadAesCcmCtrState(pAesCcmCtx);
+
+                /* configure destination address and size in case of ctr */
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD0) ,outputDataAddr);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD1) ,blockSize);
+        }
+
+        /* load IV in case of CBC_MAC / CCMPE / CCMPD */
+        if (pAesCcmCtx->mode != CIPHER_CTR) {
+        /* write the initial counter value according to mode */
+                LoadAesCcmIvState(pAesCcmCtx);
+
+        /* initiate CMAC sub-keys calculation */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CMAC_INIT) ,0x1);
+        /* set the remaining bytes */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES) ,blockSize);
+
+        }
+
+        /* configure source address and size */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,blockSize);
+
+        /* set dma completion bit in irr */
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+        drvRc = CC_HalWaitInterrupt(irrVal);
+        if (drvRc != AES_DRV_OK) {
+            goto ProcessExit;
+        }
+
+        /* get CTR state in case of CTR / CCMPE / CCMPD */
+        if (pAesCcmCtx->mode != CIPHER_CBC_MAC) {
+                StoreAesCcmCtrState(pAesCcmCtx);
+        }
+
+        /* get IV state in case of CBC_MAC / CCMPE / CCMPD */
+        if (pAesCcmCtx->mode != CIPHER_CTR) {
+                StoreAesCcmIvState(pAesCcmCtx);
+        }
+
+ProcessExit:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+        /* decrease CC counter at the end of each operation */
+        if (CC_IS_IDLE != 0) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+        }
+
+        /* release mutex */
+        if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+            CC_PalAbort("Fail to release mutex\n");
+        }
+
+        return drvRc;
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesccm_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesccm_driver.h
new file mode 100644
index 0000000..07e39ae
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesccm_driver.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _AESCCM_DRIVER_H
+#define _AESCCM_DRIVER_H
+
+/*
+ * All the includes that are needed for code using this file to
+ * compile correctly should be #included here.
+ */
+#include "driver_defs.h"
+#include "cc_aes_defs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/*  NOTE: make sure struct size equals to CC_AESCCM_USER_CTX_SIZE_IN_WORDS */
+typedef struct  AesCcmContext_t {
+    /* IV buffer */
+    uint32_t ivBuf[AES_IV_SIZE_WORDS];
+    /* AES max key size supported is 256 bit */
+    uint32_t keyBuf[AES_256_BIT_KEY_SIZE_WORDS];
+    /* AES counter for CTR mode */
+    uint32_t ctrStateBuf[AES_IV_SIZE_WORDS];
+    /* scratch buffer for internal use */
+    uint8_t tempBuff[CC_AES_BLOCK_SIZE_IN_BYTES];
+    /* mode: CBC_MAC, CTR, CCMAPD, CCMAPE */
+    aesMode_t mode;
+    /* keySize: 128, 192, 256 */
+    keySizeId_t keySizeId;
+    /* Decrypt / Encrypt */
+    cryptoDirection_t dir;
+    /* nonce size */
+    uint8_t sizeOfN;
+    /* T mac size */
+    uint8_t sizeOfT;
+}AesCcmContext_t;
+
+
+/******************************************************************************
+*               FUNCTION PROTOTYPES
+******************************************************************************/
+
+/*!
+ * This function is used to process block of data using the AES machine.
+ * It is optimized to support only CBC_MAC, CTR, CCMPE, CCMPD.
+ *
+ * \param pAesCcmCtx A pointer to the AEAD context buffer
+ * \param pInputBuffInfo A structure which represents the data input buffer.
+ * \param pOutputBuffInfo A structure which represents the data output buffer.
+ * \param blockSize - number of bytes to copy
+ *
+ * \return drvError_t defined in driver_defs.h
+ */
+drvError_t ProcessAesCcmDrv(AesCcmContext_t   *pAesCcmCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesgcm_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesgcm_driver.c
new file mode 100644
index 0000000..d0b6ef3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesgcm_driver.c
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "cc_pal_mem.h"
+#include "cc_hal.h"
+#include "aesgcm_driver.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mutex.h"
+#include "cc_util_pm.h"
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+/******************************************************************************
+*               PRIVATE FUNCTIONS
+******************************************************************************/
+
+void loadAesGcmGhashSubkey(AesGcmContext_t *pAesGcmCtx)
+{
+    /* Set H as the GHASH Key */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_SUBKEY_0_0), pAesGcmCtx->H[0]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_SUBKEY_0_1), pAesGcmCtx->H[1]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_SUBKEY_0_2), pAesGcmCtx->H[2]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_SUBKEY_0_3), pAesGcmCtx->H[3]);
+
+    return;
+}
+void loadAesGcmKey(AesGcmContext_t *pAesGcmCtx)
+{
+    /* load key0 [127:0]*/
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_0) ,pAesGcmCtx->keyBuf[0]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_1) ,pAesGcmCtx->keyBuf[1]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_2) ,pAesGcmCtx->keyBuf[2]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_3) ,pAesGcmCtx->keyBuf[3]);
+
+    if (pAesGcmCtx->keySizeId > KEY_SIZE_128_BIT) {
+        /* load key0 [191:128]*/
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_4) ,pAesGcmCtx->keyBuf[4]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_5) ,pAesGcmCtx->keyBuf[5]);
+    }
+
+    if (pAesGcmCtx->keySizeId > KEY_SIZE_192_BIT) {
+        /* load key0 [255:191]*/
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_6) ,pAesGcmCtx->keyBuf[6]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_KEY_0_7) ,pAesGcmCtx->keyBuf[7]);
+    }
+
+    return;
+}
+
+void inc32AesGcmJ0(AesGcmContext_t *pAesGcmCtx)
+{
+    uint32_t tmpWord = SWAP_ENDIAN(pAesGcmCtx->J0[3]);
+    /* --- Inc32 LSW --- */
+    /* Check overlap and inc. by 1 */
+    if (BITMASK(CC_BITS_IN_32BIT_WORD) != tmpWord) {
+        tmpWord++;
+    }
+    else {
+        tmpWord = 0;
+    }
+
+    CC_PalMemCopy(pAesGcmCtx->aesCntrBuf, pAesGcmCtx->J0, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+    pAesGcmCtx->aesCntrBuf[3] = SWAP_ENDIAN(tmpWord);
+
+    return;
+}
+
+void loadAesGcmCntr(AesGcmContext_t *pAesGcmCtx)
+{
+    /* Write the initial counter value */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0), pAesGcmCtx->aesCntrBuf[0]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1), pAesGcmCtx->aesCntrBuf[1]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2), pAesGcmCtx->aesCntrBuf[2]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3), pAesGcmCtx->aesCntrBuf[3]);
+
+    return;
+}
+
+void storeAesGcmCntr(AesGcmContext_t *pAesGcmCtx)
+{
+    /* Read the AES counter value */
+    pAesGcmCtx->aesCntrBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_0));
+    pAesGcmCtx->aesCntrBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_1));
+    pAesGcmCtx->aesCntrBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_2));
+    pAesGcmCtx->aesCntrBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CTR_0_3));
+
+    return;
+}
+
+void loadAesGcmGhashIV(AesGcmContext_t *pAesGcmCtx)
+{
+    /* Write the initial counter value according to mode */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_0), pAesGcmCtx->ghashResBuf[0]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_1), pAesGcmCtx->ghashResBuf[1]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_2), pAesGcmCtx->ghashResBuf[2]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_3), pAesGcmCtx->ghashResBuf[3]);
+
+    return;
+}
+
+void storeAesGcmGhashIV(AesGcmContext_t *pAesGcmCtx, CCBool storeInJ0)
+{
+    /* Write the result in GHASH Result Buffer */
+    pAesGcmCtx->ghashResBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_0));
+    pAesGcmCtx->ghashResBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_1));
+    pAesGcmCtx->ghashResBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_2));
+    pAesGcmCtx->ghashResBuf[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_IV_0_3));
+
+    if(CC_TRUE == storeInJ0) {
+        /* Write the result in J0 */
+        CC_PalMemCopy(pAesGcmCtx->J0, pAesGcmCtx->ghashResBuf, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+    }
+
+    return;
+}
+
+drvError_t initAesGcm(AesGcmContext_t* pAesGcmCtx)
+{
+    uint32_t auxReg = 0;
+    uint32_t irrVal = 0;
+
+    /* Verify user context pointer */
+    if (NULL == pAesGcmCtx) {
+            return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /* verify valid dir */
+    if ( (pAesGcmCtx->dir != CRYPTO_DIRECTION_ENCRYPT) &&
+         (pAesGcmCtx->dir != CRYPTO_DIRECTION_DECRYPT) ) {
+            return AES_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR;
+    }
+
+    /* Set to 0x00 */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), 0x00);
+
+    /* Configure cores according to the process mode */
+    switch (pAesGcmCtx->processMode) {
+    case DRV_AESGCM_Process_CalcH:
+        /* Set cryptographic flow to AES */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_DIN_AES_DOUT_VAL);
+        /********************************************************************************/
+        /***                      AES Configurations                                  ***/
+        /********************************************************************************/
+        /* Set Direction: Enc */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, auxReg, CRYPTO_DIRECTION_ENCRYPT);
+        /* Set AES Mode to ECB */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, auxReg, CIPHER_ECB);
+        /* Set AES Key length */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, auxReg, pAesGcmCtx->keySizeId);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL), auxReg);
+
+        /* Load Key */
+        loadAesGcmKey(pAesGcmCtx);
+
+        /* Set to 0x10 */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), AES_BLOCK_SIZE);
+
+        break;
+    case DRV_AESGCM_Process_CalcJ0_FirstPhase:
+    case DRV_AESGCM_Process_A:
+        /* Set the GHASH Engine to be ready to a new GHASH operation */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, GHASH_INIT), GHASH_INIT_SET_VAL);
+        /* Falls through. */
+    case DRV_AESGCM_Process_CalcJ0_SecondPhase:
+        /* Set cryptographic flow to HASH */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_HASH_MODE_VAL);
+        /********************************************************************************/
+        /***                    GHASH Configurations                                  ***/
+        /********************************************************************************/
+        /* Set H as the GHASH Key */
+        loadAesGcmGhashSubkey(pAesGcmCtx);
+
+        /* Set '0' as the GHASH IV */
+        loadAesGcmGhashIV(pAesGcmCtx);
+
+        /* Set Hash select module */
+        CC_REG_FLD_SET(HOST_RGF, HASH_SEL_AES_MAC, HASH_SEL_AES_MAC, auxReg, HASH_SEL_HASH_MOD);
+        /* Set Ghash select module */
+        CC_REG_FLD_SET(HOST_RGF, HASH_SEL_AES_MAC, GHASH_SEL, auxReg, GHASH_SEL_GHASH_MOD);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), auxReg);
+
+        /* Set '0' as the GHASH IV */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_XOR_DIN), HASH_XOR_DATA_VAL);
+
+        break;
+    case DRV_AESGCM_Process_DataIn:
+        /* Set cryptographic flow according to crypto direction */
+        if (CRYPTO_DIRECTION_ENCRYPT == pAesGcmCtx->dir) {
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_AES_TO_HASH_AND_DOUT_VAL);
+        } else {
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_DIN_AES_AND_HASH_VAL);
+        }
+        /********************************************************************************/
+        /***                      AES Configurations                                  ***/
+        /********************************************************************************/
+        /* Set Direction: Enc */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, auxReg, CRYPTO_DIRECTION_ENCRYPT);
+        /* Set AES Mode to CTR */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, auxReg, CIPHER_CTR);
+        /* Set AES Key length */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, auxReg, pAesGcmCtx->keySizeId);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL), auxReg);
+
+        if(CC_FALSE == pAesGcmCtx->J0Inc32DoneFlg) {
+            inc32AesGcmJ0(pAesGcmCtx);
+            pAesGcmCtx->J0Inc32DoneFlg = CC_TRUE;
+        }
+
+        /* Load Counter */
+        loadAesGcmCntr(pAesGcmCtx);
+
+        /* Load Key */
+        loadAesGcmKey(pAesGcmCtx);
+
+        /* Set to data size */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), pAesGcmCtx->dataSize);
+
+        /********************************************************************************/
+        /***                    GHASH Configurations                                  ***/
+        /********************************************************************************/
+        /* Set H as the GHASH Key */
+        loadAesGcmGhashSubkey(pAesGcmCtx);
+        /* Set former GHASH result as the new GHASH_IV value */
+        loadAesGcmGhashIV(pAesGcmCtx);
+
+        /* Set Hash select module */
+        CC_REG_FLD_SET(HOST_RGF, HASH_SEL_AES_MAC, HASH_SEL_AES_MAC, auxReg, HASH_SEL_HASH_MOD);
+        /* Set Ghash select module */
+        CC_REG_FLD_SET(HOST_RGF, HASH_SEL_AES_MAC, GHASH_SEL, auxReg, GHASH_SEL_GHASH_MOD);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), auxReg);
+
+        /* Set '0' as the GHASH IV */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_XOR_DIN), HASH_XOR_DATA_VAL);
+        break;
+    case DRV_AESGCM_Process_LenA_LenC:
+        /* Set cryptographic flow to HASH */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_HASH_MODE_VAL);
+        /********************************************************************************/
+        /***                    GHASH Configurations                                  ***/
+        /********************************************************************************/
+        /* Set H as the GHASH Key */
+        loadAesGcmGhashSubkey(pAesGcmCtx);
+        /* Set former GHASH result as the new GHASH_IV value */
+        loadAesGcmGhashIV(pAesGcmCtx);
+
+        /* Set Hash select module */
+        CC_REG_FLD_SET(HOST_RGF, HASH_SEL_AES_MAC, HASH_SEL_AES_MAC, auxReg, HASH_SEL_HASH_MOD);
+        /* Set Ghash select module */
+        CC_REG_FLD_SET(HOST_RGF, HASH_SEL_AES_MAC, GHASH_SEL, auxReg, GHASH_SEL_GHASH_MOD);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), auxReg);
+
+        /* Set '0' as the GHASH IV */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_XOR_DIN), HASH_XOR_DATA_VAL);
+        break;
+    case DRV_AESGCM_Process_GctrFinal:
+        /* Set cryptographic flow to AES */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL), CONFIG_DIN_AES_DOUT_VAL);
+        /********************************************************************************/
+        /***                      AES Configurations                                  ***/
+        /********************************************************************************/
+        /* Set Direction: Enc */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, auxReg, CRYPTO_DIRECTION_ENCRYPT);
+        /* Set AES Mode to CTR */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, auxReg, CIPHER_CTR);
+        /* Set AES Key length */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, auxReg, pAesGcmCtx->keySizeId);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CONTROL), auxReg);
+
+        /* Load Counter */
+        CC_PalMemCopy(pAesGcmCtx->aesCntrBuf, pAesGcmCtx->J0, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+        loadAesGcmCntr(pAesGcmCtx);
+
+        /* Load Key */
+        loadAesGcmKey(pAesGcmCtx);
+
+        /* Copy GHASH result to the Input address */
+        CC_PalMemCopy(pAesGcmCtx->tempBuf, pAesGcmCtx->ghashResBuf, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+
+        /* Set to GHASH Output size */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_REMAINING_BYTES), CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+        break;
+    default:
+        return AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+    }
+
+    /* make sure sym engines are ready to use */
+    CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+    /* clear all interrupts before starting the engine */
+    CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+    /* mask dma interrupts which are not required */
+    irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
+    CC_HalMaskInterrupt(irrVal);
+
+    return AES_DRV_OK;
+}
+
+
+/******************************************************************************
+*               PUBLIC FUNCTIONS
+******************************************************************************/
+
+drvError_t ProcessAesGcm(AesGcmContext_t *pAesGcmCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize)
+{
+    drvError_t drvRc  = AES_DRV_OK;
+    uint32_t   irrVal = 0;
+    uint32_t regVal = 0;
+    uint32_t inputDataAddr, outputDataAddr;
+
+    /* check input parameters */
+    if ( (pInputBuffInfo == NULL) || (pOutputBuffInfo == NULL)) {
+         return AES_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+    }
+
+    /* Verify user context pointer */
+    if (NULL == pAesGcmCtx) {
+        return AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /* Verify valid block size */
+    if (blockSize >= DLLI_MAX_BUFF_SIZE) {
+        return AES_DRV_ILLEGAL_MEM_SIZE_ERROR;
+    }
+
+    /* Lock mutex for all hw operation */
+    if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+        /* increase CC counter at the beginning of each operation */
+        drvRc = CC_IS_WAKE;
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+    /********************************************************************************/
+    /***                       Enable Clocks                                      ***/
+    /********************************************************************************/
+    /* Enable AES clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE),  SET_CLOCK_ENABLE);
+    /* Enable Hash clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE), SET_CLOCK_ENABLE);
+    /* Enable DMA clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE),  SET_CLOCK_ENABLE);
+
+    /* Registers initializations */
+    drvRc = initAesGcm(pAesGcmCtx);
+    if (drvRc != AES_DRV_OK) {
+            goto ProcessExit;
+    }
+
+    inputDataAddr = pInputBuffInfo->dataBuffAddr;
+    outputDataAddr = pOutputBuffInfo->dataBuffAddr;
+
+    /* configure the HW with the correct data buffer attributes (secure/non-secure) */
+    CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
+    CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, pOutputBuffInfo->dataBuffNs);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
+
+    /* For AES operations only */
+    if((DRV_AESGCM_Process_CalcH     == pAesGcmCtx->processMode) ||
+       (DRV_AESGCM_Process_DataIn    == pAesGcmCtx->processMode) ||
+       (DRV_AESGCM_Process_GctrFinal == pAesGcmCtx->processMode)) {
+        /* Configure destination address and size */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD0) ,outputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD1) ,blockSize);
+    }
+
+    /* Configure source address and size */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,blockSize); // Kick operation
+
+    /* Set DMA completion bit in IRR */
+    CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+
+    /* Wait for completion */
+        drvRc = CC_HalWaitInterrupt(irrVal);
+        if (drvRc != AES_DRV_OK) {
+            goto ProcessExit_Err;
+        }
+    /* Post-processing */
+    switch (pAesGcmCtx->processMode) {
+        case DRV_AESGCM_Process_CalcH:
+            break;
+        case DRV_AESGCM_Process_CalcJ0_FirstPhase:
+            storeAesGcmGhashIV(pAesGcmCtx, CC_FALSE);
+            break;
+        case DRV_AESGCM_Process_CalcJ0_SecondPhase:
+            storeAesGcmGhashIV(pAesGcmCtx, CC_TRUE);
+            break;
+        case DRV_AESGCM_Process_A:
+            storeAesGcmGhashIV(pAesGcmCtx, CC_FALSE);
+            break;
+        case DRV_AESGCM_Process_DataIn:
+            storeAesGcmCntr(pAesGcmCtx);
+            storeAesGcmGhashIV(pAesGcmCtx, CC_FALSE);
+            break;
+        case DRV_AESGCM_Process_LenA_LenC:
+            storeAesGcmGhashIV(pAesGcmCtx, CC_FALSE);
+            break;
+        case DRV_AESGCM_Process_GctrFinal:
+            break;
+        default:
+            drvRc = AES_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+            break;
+        }
+
+ProcessExit:
+
+    /********************************************************************************/
+    /***        Reset to default values in case of operation completion           ***/
+    /********************************************************************************/
+    if((DRV_AESGCM_Process_CalcH     != pAesGcmCtx->processMode) &&
+       (DRV_AESGCM_Process_GctrFinal != pAesGcmCtx->processMode)) {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,0);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,0);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), 0);
+    }
+
+ProcessExit_Err:
+    /********************************************************************************/
+    /***                      Disable Clocks                                      ***/
+    /********************************************************************************/
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE),  SET_CLOCK_DISABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE), SET_CLOCK_DISABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE),  SET_CLOCK_DISABLE);
+
+        /* decrease CC counter at the end of each operation */
+        if (CC_IS_IDLE != 0) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+        }
+
+        /* Release mutex */
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return drvRc;
+}
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesgcm_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesgcm_driver.h
new file mode 100644
index 0000000..d663f7d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/aesgcm_driver.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _AESGCM_DRIVER_H
+#define _AESGCM_DRIVER_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+
+/*
+ * All the includes that are needed for code using this file to
+ * compile correctly should be #included here.
+ */
+#include "driver_defs.h"
+#include "cc_aes_defs.h"
+#include "cc_pal_types.h"
+#include "cc_bitops.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/* 128 bits */
+#define CC_AESGCM_GHASH_DIGEST_SIZE_BYTES           16
+#define CC_AESGCM_GHASH_DIGEST_SIZE_WORDS           CC_AESGCM_GHASH_DIGEST_SIZE_BYTES>>2
+
+/************************ Enums ********************************/
+
+/*! AES GCM driver process modes. */
+typedef enum {
+    /*! Calculate H. */
+    DRV_AESGCM_Process_CalcH                = 0,
+    /*! Calculate J0 - First phase. */
+    DRV_AESGCM_Process_CalcJ0_FirstPhase    = 1,
+    /*! Calculate J0 - Second phase. */
+    DRV_AESGCM_Process_CalcJ0_SecondPhase   = 2,
+    /*! GHASH AAD. */
+    DRV_AESGCM_Process_A                    = 3,
+    /*! GCTR and GHASH Data In. */
+    DRV_AESGCM_Process_DataIn               = 4,
+    /*! GHASH Len(A) || Len(C). */
+    DRV_AESGCM_Process_LenA_LenC            = 5,
+    /*! GCTR Final. */
+    DRV_AESGCM_Process_GctrFinal            = 6,
+
+    /*! Number of optional key sizes. */
+    DRV_AESGCM_ProcessesTotal,
+    /*! Reserved. */
+    DRV_AESGCM_ProcessLast    = 0x7FFFFFFF,
+}drvAesGcmProcessModes_t;
+
+
+/************************ Typedefs  ****************************/
+
+/*  NOTE: make sure that structure size equals to CC_AESGCM_USER_CTX_SIZE_IN_WORDS */
+typedef struct  AesGcmContext_t {
+    /* AES max key size supported is 256 bit */
+    uint32_t keyBuf[AES_256_BIT_KEY_SIZE_WORDS];
+    /* H buffer size is 128 bit */
+    uint32_t H[AES_128_BIT_KEY_SIZE_WORDS];
+    /* J0 buffer size is 128 bit */
+    uint32_t J0[CC_AESGCM_GHASH_DIGEST_SIZE_WORDS];
+    /* Temp. buffer size is 128 bit */
+    uint32_t tempBuf[CC_AESGCM_GHASH_DIGEST_SIZE_WORDS];
+    /* AES Counter buffer size is 128 bit */
+    uint32_t aesCntrBuf[CC_AESGCM_GHASH_DIGEST_SIZE_WORDS];
+    /* GHASH Result buffer size is 128 bit */
+    uint32_t ghashResBuf[CC_AESGCM_GHASH_DIGEST_SIZE_WORDS];
+    /* Pre-Tag buffer size is 128 bit */
+    uint8_t preTagBuf[CC_AESGCM_GHASH_DIGEST_SIZE_BYTES];
+    /* J0 Inc32 flag */
+    CCBool J0Inc32DoneFlg;
+    /* keySize: 128, 192, 256 */
+    keySizeId_t keySizeId;
+    /* Encrypt / Decrypt */
+    cryptoDirection_t dir;
+    /* Tag size */
+    uint8_t tagSize;
+    /* Alignment */
+    uint8_t RFU[3];
+    /* Driver process mode */
+    drvAesGcmProcessModes_t processMode;
+    /* Data size (Plain/Cipher text) */
+    uint32_t dataSize;
+    /* IV size */
+    uint32_t ivSize;
+    /* AAD size */
+    uint32_t aadSize;
+}AesGcmContext_t;
+
+
+/******************************************************************************
+*               FUNCTION PROTOTYPES
+******************************************************************************/
+
+/*!
+ * This function is used to process block of data using the AES and / or Hash machines.
+ *
+ * \param pAesGcmCtx A pointer to the AES-GCM context buffer.
+ * \param pInputBuffInfo A structure which represents the data input buffer.
+ * \param pOutputBuffInfo A structure which represents the data output buffer.
+ * \param blockSize - number of bytes to copy.
+ *
+ * \return drvError_t defined in driver_defs.h.
+ */
+drvError_t ProcessAesGcm(AesGcmContext_t *pAesGcmCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t blockSize);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif //  MBEDTLS_GCM_C
+#endif // _AESGCM_DRIVER_H
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/bypass_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/bypass_driver.c
new file mode 100644
index 0000000..51d73d6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/bypass_driver.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_SYM_DRIVER
+
+#include "cc_pal_mem.h"
+#include "cc_pal_log.h"
+#include "bypass_driver.h"
+#include "driver_defs.h"
+#include "cc_sym_error.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+
+
+/******************************************************************************
+*               PRIVATE FUNCTIONS
+******************************************************************************/
+
+drvError_t ProcessBypass(CCBuffInfo_t *pInputBuffInfo, dataAddrType_t inputDataAddrType,
+                         CCBuffInfo_t *pOutputBuffInfo, dataAddrType_t outputDataAddrType,
+                         uint32_t blockSize)
+{
+    drvError_t drvRc = BYPASS_DRV_OK;
+    uint32_t irrVal = 0;
+    uint32_t regVal = 0;
+    uint32_t inputDataAddr, outputDataAddr;
+
+    /* check input parameters */
+    if ( (pInputBuffInfo == NULL) || (pOutputBuffInfo == NULL)) {
+         return BYPASS_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+    }
+
+    /* verify min block size */
+    if (blockSize == 0)
+        return BYPASS_DRV_ILLEGAL_BLOCK_SIZE_ERROR;
+
+    /* verify aes valid input addr type */
+    if( (inputDataAddrType != SRAM_ADDR) &&
+        (inputDataAddrType != DLLI_ADDR) ) {
+        return BYPASS_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR;
+    }
+
+    /* verify aes valid output addr type for ecb, cbc, ctr */
+    if( (outputDataAddrType != SRAM_ADDR) &&
+        (outputDataAddrType != DLLI_ADDR) ) {
+        return BYPASS_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR;
+    }
+
+        /* make sure sym engines are ready to use */
+        CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+        /* clear all interrupts before starting the engine */
+        CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+        /* mask dma interrupts which are not required */
+        irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
+        CC_HalMaskInterrupt(irrVal);
+
+    /* configure DIN-BYPASS-DOUT */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_DIN_BYPASS_DOUT_VAL);
+
+        /* enable clock */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+        inputDataAddr = pInputBuffInfo->dataBuffAddr;
+        outputDataAddr = pOutputBuffInfo->dataBuffAddr;
+
+        /* configure the HW with the correct data buffer attributes (secure/non-secure) */
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, pOutputBuffInfo->dataBuffNs);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
+
+    /* configure destination address and size; set dout bit in irr */
+    if (outputDataAddrType == DLLI_ADDR){
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD0) ,outputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD1) ,blockSize);
+    } else {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_DEST_ADDR) ,outputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DOUT_SRAM_BYTES_LEN) ,blockSize);
+    }
+
+    /* configure source address and size */
+    if (inputDataAddrType == DLLI_ADDR){
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,blockSize);
+    } else {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_SRC_ADDR) ,inputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_SRAM_BYTES_LEN) ,blockSize);
+    }
+
+        /* set dma completion bit in irr */
+        irrVal = 0;
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+        drvRc = CC_HalWaitInterrupt(irrVal);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+    return drvRc;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/bypass_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/bypass_driver.h
new file mode 100644
index 0000000..d04d78b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/bypass_driver.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _BYPASS_DRIVER_H
+#define  _BYPASS_DRIVER_H
+
+#include "driver_defs.h"
+
+/******************************************************************************
+*               FUNCTION PROTOTYPES
+******************************************************************************/
+/****************************************************************************************************/
+/**
+ * @brief This function is used to perform the BYPASS operation in one integrated process.
+ *
+ *
+ * @param[in] pInputBuffInfo A structure which represents the data input buffer.
+ * @param[in] inputDataAddrType - the memory address input type: SRAM_ADDR or DLLI_ADDR.
+ * @param[in] pOutputBuffInfo A structure which represents the data output buffer.
+ * @param[in] outputDataAddrType - the memory address input type: SRAM_ADDR or DLLI_ADDR.
+ * @param[in] blockSize - number of bytes to copy.
+ *
+ * @return drvError_t - On success BYPASS_DRV_OK is returned, on failure a value defined in driver_defs.h
+ *
+ */
+drvError_t ProcessBypass(CCBuffInfo_t *pInputBuffInf, dataAddrType_t inputDataAddrType,
+                         CCBuffInfo_t *pOutputBuffInfo, dataAddrType_t outputDataAddrType,
+                         uint32_t blockSize);
+
+#endif /* _BYPASS_DRIVER_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver.c
new file mode 100644
index 0000000..388ac76
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stddef.h>
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "chacha_driver.h"
+#include "driver_defs.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_sram_map.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "cc_util_pm.h"
+
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+/* chacha mode, poly1305 disabled, 256 bit key, 20 rounds, 64 bit iv, do not reset the block counter (overwritten by the context) */
+#define CHACHA_CONTROL_REG_VAL        (1 << DX_CHACHA_CONTROL_REG_INIT_FROM_HOST_BIT_SHIFT)
+#define CHACHA_CONTROL_REG_USE_IV_96  (1 << DX_CHACHA_CONTROL_REG_USE_IV_96BIT_BIT_SHIFT)
+
+/******************************************************************************
+*               PRIVATE FUNCTIONS
+******************************************************************************/
+
+static drvError_t InitChacha(ChachaContext_t *chachaCtx)
+{
+    uint32_t irrVal = 0;
+
+    /* verify user context pointer */
+    if ( chachaCtx == NULL ) {
+        return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /* verify chacha valid input addr type */
+    if ( (chachaCtx->inputDataAddrType != SRAM_ADDR) &&
+         (chachaCtx->inputDataAddrType != DLLI_ADDR) ) {
+        return CHACHA_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR;
+    }
+
+    /* verify chacha valid output addr type */
+    if ( (chachaCtx->outputDataAddrType != SRAM_ADDR) &&
+         (chachaCtx->outputDataAddrType != DLLI_ADDR) ) {
+        return CHACHA_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR;
+    }
+
+    /* make sure sym engines are ready to use */
+    CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+    /* clear all interrupts before starting the engine */
+    CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+    /* mask dma interrupts which are not required */
+    irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
+    CC_HalMaskInterrupt(irrVal);
+
+    /* configure DIN-CHACHA-DOUT */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_DIN_CHACHA_DOUT_VAL);
+
+    return CHACHA_DRV_OK;
+}
+
+static drvError_t LoadChachaState(ChachaContext_t *chachaCtx)
+{
+        /* verify user context pointer */
+        if (chachaCtx == NULL) {
+                return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* write the initial counter value according to mode */
+        if (chachaCtx->nonceSize == NONCE_SIZE_64) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB), chachaCtx->blockCounterMsb);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0), chachaCtx->nonceBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1), chachaCtx->nonceBuf[1]);
+        }
+        else if (chachaCtx->nonceSize == NONCE_SIZE_96) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB), chachaCtx->nonceBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0), chachaCtx->nonceBuf[1]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1), chachaCtx->nonceBuf[2]);
+        }
+        else {
+                return CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR;
+        }
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_LSB), chachaCtx->blockCounterLsb);
+
+        return CHACHA_DRV_OK;
+}
+
+
+static drvError_t StoreChachaState(ChachaContext_t *chachaCtx)
+{
+        /* verify user context pointer */
+        if (chachaCtx == NULL) {
+                return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* read the initial counter value according to mode */
+        if (chachaCtx->nonceSize == NONCE_SIZE_64) {
+                chachaCtx->blockCounterMsb = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB));
+                chachaCtx->nonceBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0));
+                chachaCtx->nonceBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1));
+        }
+        else if (chachaCtx->nonceSize == NONCE_SIZE_96) {
+                chachaCtx->nonceBuf[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB));
+                chachaCtx->nonceBuf[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0));
+                chachaCtx->nonceBuf[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1));
+        }
+        else {
+                return CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR;
+        }
+        chachaCtx->blockCounterLsb = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_LSB));
+
+        return CHACHA_DRV_OK;
+}
+
+static drvError_t LoadChachaKey(ChachaContext_t *chachaCtx)
+{
+        int enrtyNum = 0;
+
+        /* verify user context pointer */
+        if (chachaCtx == NULL) {
+                return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        for (enrtyNum = 0; enrtyNum < CHACHA_256_BIT_KEY_SIZE_WORDS; ++enrtyNum) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_KEY0) + (sizeof(uint32_t) * enrtyNum), chachaCtx->keyBuf[enrtyNum]);
+        }
+
+        return CHACHA_DRV_OK;
+}
+
+/******************************************************************************
+*               PUBLIC FUNCTIONS
+******************************************************************************/
+drvError_t ProcessChacha(ChachaContext_t *chachaCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t inDataSize)
+{
+    uint32_t irrVal = 0;
+    uint32_t chachaCtrl = CHACHA_CONTROL_REG_VAL;
+    drvError_t drvRc = CHACHA_DRV_OK;
+    uint32_t regVal = 0;
+    uint32_t inputDataAddr, outputDataAddr;
+
+    /* check input parameters */
+    if ( (pInputBuffInfo == NULL) || (pOutputBuffInfo == NULL)) {
+         return CHACHA_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+    }
+
+    /* verify user context pointer */
+    if ( chachaCtx == NULL ) {
+        return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+    if (((chachaCtx->inputDataAddrType == SRAM_ADDR) && (inDataSize >= CC_SRAM_MAX_SIZE)) ||
+        ((chachaCtx->inputDataAddrType == DLLI_ADDR) && (inDataSize >= DLLI_MAX_BUFF_SIZE))) {
+        return CHACHA_DRV_ILLEGAL_MEM_SIZE_ERROR;
+    }
+
+    /* lock mutex for more chacha hw operation */
+    drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+    if (drvRc != 0) {
+        CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* increase CC counter at the beginning of each operation */
+    drvRc = CC_IS_WAKE;
+    if (drvRc != 0) {
+        CC_PalAbort("Fail to increase PM counter\n");
+    }
+
+    /* enable clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+    drvRc = InitChacha(chachaCtx);
+    if (drvRc != CHACHA_DRV_OK) {
+            goto ProcessExit;
+    }
+
+    /* write the initial counter value */
+    drvRc = LoadChachaState(chachaCtx);
+    if (drvRc != CHACHA_DRV_OK) {
+            goto ProcessExit;
+    }
+
+    /* load key */
+    drvRc = LoadChachaKey(chachaCtx);
+    if (drvRc != CHACHA_DRV_OK) {
+            goto ProcessExit;
+    }
+
+    /* configure the CHACHA mode */
+    if (chachaCtx->nonceSize == NONCE_SIZE_96) {
+        chachaCtrl |= CHACHA_CONTROL_REG_USE_IV_96;
+    }
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CONTROL_REG), chachaCtrl);
+
+    inputDataAddr = pInputBuffInfo->dataBuffAddr;
+    outputDataAddr = pOutputBuffInfo->dataBuffAddr;
+
+    /* configure the HW with the correct data buffer attributes (secure/non-secure) */
+    CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
+    CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, pOutputBuffInfo->dataBuffNs);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
+
+    /* configure destination address and size */
+    /* and set dout bit in irr */
+    if (chachaCtx->outputDataAddrType == DLLI_ADDR) {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD0) ,outputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DST_LLI_WORD1) ,inDataSize);
+    } else {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_DEST_ADDR) ,outputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DOUT_SRAM_BYTES_LEN) ,inDataSize);
+    }
+
+    /* configure source address and size */
+    if (chachaCtx->inputDataAddrType == DLLI_ADDR) {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,inDataSize);
+    } else {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_SRC_ADDR) ,inputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_SRAM_BYTES_LEN) ,inDataSize);
+    }
+
+    /* set dma completion bit in irr */
+    CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+    drvRc = CC_HalWaitInterrupt(irrVal);
+    if (drvRc != CHACHA_DRV_OK) {
+        goto ProcessExit;
+    }
+    /* get machine state */
+    drvRc = StoreChachaState(chachaCtx);
+    if (drvRc != CHACHA_DRV_OK) {
+            goto ProcessExit;
+    }
+
+    ProcessExit:
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+    /* decrease CC counter at the end of each operation */
+    if (CC_IS_IDLE != 0) {
+        CC_PalAbort("Fail to decrease PM counter\n");
+    }
+
+    /* release mutex */
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return drvRc;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver.h
new file mode 100644
index 0000000..8390343
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CHACHA_DRIVER_H
+#define  _CHACHA_DRIVER_H
+
+#include "driver_defs.h"
+
+/******************************************************************************
+*               TYPE DEFINITIONS
+******************************************************************************/
+
+/* The context data-base used by the CHACHA functions on the low level */
+typedef struct ChachaContext {
+    /* IV buffer */
+    uint32_t    nonceBuf[CHACHA_IV_96_SIZE_WORDS];
+    /* CHACHA block counter */
+    uint32_t    blockCounterLsb;
+    uint32_t    blockCounterMsb;
+    /* CHACHA Key: fixed size is 256 bit */
+    uint32_t    keyBuf[CHACHA_256_BIT_KEY_SIZE_WORDS];
+    /* Decrypt / Encrypt */
+    cryptoDirection_t dir;
+    /* data input addr type */
+    dataAddrType_t inputDataAddrType;
+    /* data output addr type */
+    dataAddrType_t outputDataAddrType;
+    /* CHACHA iv size */
+    chachaNonceSize_t nonceSize;
+} ChachaContext_t;
+
+
+/******************************************************************************
+*               FUNCTION PROTOTYPES
+******************************************************************************/
+/*!
+ * This function is used to process block(s) of data using the CHACHA machine.
+ *
+ * \param chachaCtx - A pointer to the CHACHA context buffer.
+ * \param pInputBuffInfo A structure which represents the data input buffer.
+ * \param pOutputBuffInfo A structure which represents the data output buffer.
+ * \param inDataSize - number of bytes to process.
+ *
+ * \return drvError_t defined in driver_defs.h.
+ */
+drvError_t ProcessChacha(ChachaContext_t *chachaCtx, CCBuffInfo_t *pInputBuffInfo, CCBuffInfo_t *pOutputBuffInfo, uint32_t inDataSize);
+
+
+#endif /* _CHACHA_DRIVER_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver_ext_dma.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver_ext_dma.c
new file mode 100644
index 0000000..dad5bbc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver_ext_dma.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "chacha_driver.h"
+#include "chacha_driver_ext_dma.h"
+#include "driver_defs.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "cc_util_pm.h"
+
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+/* chacha mode, poly1305 disabled, 256 bit key, 20 rounds, 64 bit iv, do not reset the block counter (overwritten by the context) */
+#define CHACHA_CONTROL_REG_VAL        (1 << DX_CHACHA_CONTROL_REG_INIT_FROM_HOST_BIT_SHIFT)
+#define CHACHA_CONTROL_REG_USE_IV_96  (1 << DX_CHACHA_CONTROL_REG_USE_IV_96BIT_BIT_SHIFT)
+
+/******************************************************************************
+*               PRIVATE FUNCTIONS
+******************************************************************************/
+
+static drvError_t LoadChachaExtDmaState(uint32_t *pNonceBuf, chachaNonceSize_t nonceSizeFlag, uint32_t blockCounterLsb)
+{
+        /* verify user context pointer */
+        if (pNonceBuf == NULL) {
+                return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        /* write the initial counter value according to mode */
+        if (nonceSizeFlag == NONCE_SIZE_64) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB), 0);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0), pNonceBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1), pNonceBuf[1]);
+        }
+        else if (nonceSizeFlag == NONCE_SIZE_96) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_MSB), pNonceBuf[0]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_0), pNonceBuf[1]);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_IV_1), pNonceBuf[2]);
+        }
+        else {
+                return CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR;
+        }
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_BLOCK_CNT_LSB), blockCounterLsb);
+
+        return CHACHA_DRV_OK;
+}
+
+static drvError_t LoadChachaKeyExtDma(uint32_t *pKey)
+{
+        int enrtyNum = 0;
+
+        /* verify user context pointer */
+        if (pKey == NULL) {
+            return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+
+        for (enrtyNum = 0; enrtyNum < CHACHA_256_BIT_KEY_SIZE_WORDS; ++enrtyNum) {
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_KEY0) + (sizeof(uint32_t) * enrtyNum), pKey[enrtyNum]);
+        }
+
+        return CHACHA_DRV_OK;
+}
+
+/******************************************************************************
+*               PUBLIC FUNCTIONS
+******************************************************************************/
+drvError_t InitChachaExtDma(uint32_t *pNonceBuf, chachaNonceSize_t nonceSizeFlag, uint32_t *keyBuf, uint32_t initialCounter, uint32_t dataLen)
+{
+    uint32_t irrVal = 0;
+    uint32_t chachaCtrl = CHACHA_CONTROL_REG_VAL;
+    drvError_t drvRc = CHACHA_DRV_OK;
+    drvError_t rc = AES_DRV_OK;
+
+    if (pNonceBuf == NULL || keyBuf == NULL) {
+        return CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+    /* lock mutex for more chacha hw operation */
+    drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+    if (drvRc != 0) {
+        CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* increase CC counter at the beginning of each operation */
+    drvRc = CC_IS_WAKE;
+    if (drvRc != 0) {
+        CC_PalAbort("Fail to increase PM counter\n");
+    }
+
+    /* enable clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+    /* make sure sym engines are ready to use */
+    CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+    /* clear all interrupts before starting the engine */
+    CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+    /* mask dma interrupts which are not required */
+    irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 1);
+    CC_HalMaskInterrupt(irrVal);
+
+    /* configure DIN-CHACHA-DOUT */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_DIN_CHACHA_DOUT_VAL);
+
+    /* write the initial counter value */
+    drvRc = LoadChachaExtDmaState(pNonceBuf, nonceSizeFlag, initialCounter);
+    if (drvRc != CHACHA_DRV_OK) {
+            goto InitExit;
+    }
+
+    /* load key */
+    drvRc = LoadChachaKeyExtDma(keyBuf);
+    if (drvRc != CHACHA_DRV_OK) {
+            goto InitExit;
+    }
+
+    /* configure the CHACHA mode */
+    if (nonceSizeFlag == NONCE_SIZE_96) {
+        chachaCtrl |= CHACHA_CONTROL_REG_USE_IV_96;
+    }
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CONTROL_REG), chachaCtrl);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_CPU_DATA_SIZE) , dataLen);
+
+    return CHACHA_DRV_OK;
+
+InitExit:
+
+    rc = terminateChachaExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateAesExtDma \n");
+    }
+    return drvRc;
+}
+
+drvError_t terminateChachaExtDma(void)
+{
+    drvError_t rc = AES_DRV_OK;
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CHACHA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+    /* decrease CC counter at the end of each operation */
+    rc = CC_IS_IDLE;
+    if (rc != 0) {
+        CC_PalAbort("Fail to decrease PM counter\n");
+    }
+
+    /* unlock mutex for more aes hw operation */
+    rc = CC_PalMutexUnlock(&CCSymCryptoMutex);
+    if (rc != 0) {
+        CC_PalAbort("Fail to unlock mutex\n");
+    }
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver_ext_dma.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver_ext_dma.h
new file mode 100644
index 0000000..f1ae0d7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/chacha_driver_ext_dma.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef  _CHACHA_DRIVER_EXT_DMA_H
+#define  _CHACHA_DRIVER_EXT_DMA_H
+
+#include "driver_defs.h"
+
+
+
+
+drvError_t FinishChachaExtDma(hashMode_t mode, uint32_t * digest);
+drvError_t InitChachaExtDma(uint32_t *nonceBuf, chachaNonceSize_t nonceSizeFlag, uint32_t *keyBuf, uint32_t initialCounter, uint32_t dataLen);
+drvError_t terminateChachaExtDma(void);
+
+
+
+
+#endif // #_CHACHA_DRIVER_EXT_DMA_H
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/driver_common.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/driver_common.c
new file mode 100644
index 0000000..67f6071
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/driver_common.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "driver_defs.h"
+#include "cc_pal_buff_attr.h"
+#include "cc_pal_abort.h"
+#include "cc_error.h"
+
+/******************************************************************************
+*       PUBLIC FUNCTIONS
+******************************************************************************/
+
+
+drvError_t SetDataBuffersInfo(const uint8_t *pDataIn, size_t dataInSize, CCBuffInfo_t *pInputBuffInfo,
+                              const uint8_t *pDataOut, size_t dataOutSize, CCBuffInfo_t *pOutputBuffInfo)
+{
+    drvError_t drvRet = CC_OK;
+    uint8_t  buffNs = 0;
+
+    drvRet = CC_PalDataBufferAttrGet(pDataIn, dataInSize, INPUT_DATA_BUFFER, &buffNs);
+    if (drvRet != CC_OK){
+        CC_PAL_LOG_ERR("input buffer memory is illegal\n");
+        return CC_FATAL_ERROR;
+    }
+    pInputBuffInfo->dataBuffAddr = (uint32_t)pDataIn;
+    pInputBuffInfo->dataBuffNs = buffNs;
+
+    if (pOutputBuffInfo != NULL) {
+        if (pDataOut != NULL) {
+            drvRet = CC_PalDataBufferAttrGet(pDataOut, dataOutSize, OUTPUT_DATA_BUFFER, &buffNs);
+            if (drvRet != CC_OK){
+                CC_PAL_LOG_ERR("output buffer memory is illegal\n");
+                return CC_FATAL_ERROR;
+            }
+        }
+        pOutputBuffInfo->dataBuffAddr = (uint32_t)pDataOut;
+        pOutputBuffInfo->dataBuffNs = buffNs;
+    }
+
+    return drvRet;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/driver_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/driver_defs.h
new file mode 100644
index 0000000..0eca804
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/driver_defs.h
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _DRIVER_DEFS_H_
+#define _DRIVER_DEFS_H_
+
+#include "cc_pal_types.h"
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#define INT32_MAX 0x7FFFFFFFL
+#else
+#include <stdint.h>
+#endif
+
+#ifndef min
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define CPU_DIN_MAX_SIZE    0xFFFFUL
+/******************************************************************************
+*               TYPE DEFINITIONS
+******************************************************************************/
+typedef uint32_t drvError_t;
+
+typedef enum aesMode {
+    CIPHER_NULL_MODE = -1,
+    CIPHER_ECB = 0,
+    CIPHER_CBC = 1,
+    CIPHER_CTR = 2,
+    CIPHER_CBC_MAC = 3,
+    CIPHER_OFB = 6,
+    CIPHER_CMAC = 7,
+    CIPHER_CCMA = 8,
+    CIPHER_CCMPE = 9,
+    CIPHER_CCMPD = 10,
+    CIPHER_RESERVE32B = INT32_MAX
+}aesMode_t;
+
+typedef enum hashMode {
+    HASH_NULL_MODE = -1,
+    HASH_SHA1 = 0,
+    HASH_SHA256 = 1,
+    HASH_SHA224 = 2,
+    HASH_SHA512 = 3,
+    HASH_SHA384 = 4,
+    HASH_RESERVE32B = INT32_MAX
+}hashMode_t;
+
+typedef enum DataBlockType {
+    FIRST_BLOCK,
+    MIDDLE_BLOCK,
+    LAST_BLOCK,
+    RESERVE32B_BLOCK = INT32_MAX
+}DataBlockType_t;
+
+typedef enum dataAddrType {
+    SRAM_ADDR = 0,
+    DLLI_ADDR = 1,
+    ADDR_RESERVE32B = INT32_MAX
+}dataAddrType_t;
+
+typedef enum cryptoDirection {
+    CRYPTO_DIRECTION_ENCRYPT = 0,
+    CRYPTO_DIRECTION_DECRYPT = 1,
+    CRYPTO_DIRECTION_NUM_OF_ENC_MODES,
+    CRYPTO_DIRECTION_RESERVE32B = INT32_MAX
+}cryptoDirection_t;
+
+typedef enum keySizeId {
+    KEY_SIZE_128_BIT = 0,
+    KEY_SIZE_192_BIT = 1,
+    KEY_SIZE_256_BIT = 2,
+    KEY_SIZE_ID_RESERVE32B = INT32_MAX,
+}keySizeId_t;
+
+typedef enum cryptoKeyType {
+    RKEK_KEY = 0,
+    USER_KEY = 1,
+    KCP_KEY = 2,
+    KCE_KEY = 3,
+    KPICV_KEY = 4,
+    KCEICV_KEY = 5,
+    RTL_KEY,
+    END_OF_KEYS = INT32_MAX,
+}cryptoKeyType_t;
+
+typedef enum cryptoPaddingType {
+    CRYPTO_PADDING_NONE = 0,
+    CRYPTO_PADDING_PKCS7 = 1,
+    CRYPTO_PADDING_RESERVE32B = INT32_MAX
+}cryptoPaddingType_t;
+
+typedef enum chachaNonceSize {
+        NONCE_SIZE_64 = 0,
+        NONCE_SIZE_96 = 1,
+        NONCE_SIZE_RESERVE32B = INT32_MAX
+}chachaNonceSize_t;
+
+typedef enum hashSelAesMacModule {
+    HASH_SEL_HASH_MOD    = 0,
+    HASH_SEL_AES_MAC_MOD = 1,
+    HASH_SEL_RESERVE32B  = INT32_MAX
+}hashSelAesMacModule_t;
+
+typedef enum ghashSelModule {
+    GHASH_SEL_HASH_MOD   = 0,
+    GHASH_SEL_GHASH_MOD  = 1,
+    GHASH_SEL_RESERVE32B = INT32_MAX
+}ghashSelModule_t;
+
+/******************************************************************************
+*               Buffer Information
+******************************************************************************/
+/*! User buffer type (input for read / output for write). */
+#define INPUT_DATA_BUFFER     1
+#define OUTPUT_DATA_BUFFER    0
+
+
+/*! User buffer buffer information. */
+typedef struct {
+    uint32_t dataBuffAddr;       /*!< Address of data buffer.*/
+    uint8_t  dataBuffNs;         /*!< HNONSEC buffer attribute (0 for secure, 1 for non-secure) */
+}CCBuffInfo_t;
+
+/******************************************************************************
+*               Driver's Errors base address
+******************************************************************************/
+#define DRV_MODULE_ERROR_BASE               0x00F00000
+#define AES_DRV_MODULE_ERROR_BASE           (DRV_MODULE_ERROR_BASE + 0x10000UL)
+#define AEAD_DRV_MODULE_ERROR_BASE          (DRV_MODULE_ERROR_BASE + 0x20000UL)
+#define HASH_DRV_MODULE_ERROR_BASE          (DRV_MODULE_ERROR_BASE + 0x30000UL)
+#define HMAC_DRV_MODULE_ERROR_BASE          (DRV_MODULE_ERROR_BASE + 0x40000UL)
+#define BYPASS_DRV_MODULE_ERROR_BASE        (DRV_MODULE_ERROR_BASE + 0x50000UL)
+#define CHACHA_DRV_MODULE_ERROR_BASE        (DRV_MODULE_ERROR_BASE + 0x60000UL)
+
+/******************************************************************************
+*               CRYPTOGRAPHIC FLOW DEFINITIONS
+******************************************************************************/
+#define CONFIG_DIN_AES_DOUT_VAL             0x1UL
+#define CONFIG_DIN_AES_AND_HASH_VAL         0x3UL
+#define CONFIG_HASH_MODE_VAL                0x7UL
+#define CONFIG_AES_TO_HASH_AND_DOUT_VAL     0xAUL
+
+/******************************************************************************
+*              Data Buffer Attributes for secure/non-secure
+******************************************************************************/
+#define OUTPUT_BUFFER_HNONSEC_BIT_SHIFT     0x0UL
+#define OUTPUT_BUFFER_HNONSEC_BIT_SIZE      0x1UL
+#define INPUT_BUFFER_HNONSEC_BIT_SHIFT      0x1UL
+#define INPUT_BUFFER_HNONSEC_BIT_SIZE       0x1UL
+
+/******************************************************************************
+*               AES DEFINITIONS
+******************************************************************************/
+
+#define AES_BLOCK_SIZE                  16
+#define AES_BLOCK_SIZE_WORDS            (AES_BLOCK_SIZE >> 2)
+#define AES_IV_SIZE                     16
+#define AES_IV_SIZE_WORDS               (AES_IV_SIZE >> 2)
+#define AES_128_BIT_KEY_SIZE            16
+#define AES_128_BIT_KEY_SIZE_WORDS      (AES_128_BIT_KEY_SIZE >> 2)
+#define AES_192_BIT_KEY_SIZE            24
+#define AES_192_BIT_KEY_SIZE_WORDS      (AES_192_BIT_KEY_SIZE >> 2)
+#define AES_256_BIT_KEY_SIZE            32
+#define AES_256_BIT_KEY_SIZE_WORDS      (AES_256_BIT_KEY_SIZE >> 2)
+
+
+#define SET_CLOCK_ENABLE                0x1UL
+#define SET_CLOCK_DISABLE               0x0UL
+
+/* The CC AES file errors */
+#define AES_DRV_OK                                      0
+#define AES_DRV_INVALID_USER_CONTEXT_POINTER_ERROR      (AES_DRV_MODULE_ERROR_BASE + 0x00UL)
+#define AES_DRV_ILLEGAL_OPERATION_MODE_ERROR            (AES_DRV_MODULE_ERROR_BASE + 0x01UL)
+#define AES_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR       (AES_DRV_MODULE_ERROR_BASE + 0x02UL)
+#define AES_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR            (AES_DRV_MODULE_ERROR_BASE + 0x03UL)
+#define AES_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR           (AES_DRV_MODULE_ERROR_BASE + 0x04UL)
+#define AES_DRV_ILLEGAL_MEM_SIZE_ERROR                  (AES_DRV_MODULE_ERROR_BASE + 0x05UL)
+#define AES_DRV_ILLEGAL_KEY_SIZE_ERROR                  (AES_DRV_MODULE_ERROR_BASE + 0x06UL)
+#define AES_DRV_ILLEGAL_KEY_LOCK_ERROR                  (AES_DRV_MODULE_ERROR_BASE + 0x07UL)
+#define AES_DRV_ILLEGAL_KEY_INTEGRITY_ERROR             (AES_DRV_MODULE_ERROR_BASE + 0x08UL)
+#define AES_DRV_ILLEGAL_KEY_USE_ERROR                   (AES_DRV_MODULE_ERROR_BASE + 0x09UL)
+#define AES_DRV_ILLEGAL_FATAL_ERR_BIT_ERROR             (AES_DRV_MODULE_ERROR_BASE + 0x0AUL)
+#define AES_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR    (AES_DRV_MODULE_ERROR_BASE + 0x0BUL)
+
+
+/******************************************************************************
+*               GHASH DEFINITIONS
+******************************************************************************/
+#define GHASH_INIT_SET_VAL                              0x1UL
+
+/******************************************************************************
+*               HASH & HMAC DEFINITIONS
+******************************************************************************/
+
+/************************ Typedefs  ****************************/
+typedef drvError_t (*llf_hash_init_operation_func)(void *);
+typedef drvError_t (*llf_hash_update_operation_func)(void *, CCBuffInfo_t *pInputBuffInfo, uint32_t dataInSize);
+typedef drvError_t (*llf_hash_finish_operation_func)(void *);
+
+
+/* The SHA-1 digest result size */
+#define SHA1_DIGEST_SIZE_IN_WORDS 5
+#define SHA1_DIGEST_SIZE_IN_BYTES (SHA1_DIGEST_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* The SHA-256 digest result size*/
+#define SHA224_DIGEST_SIZE_IN_WORDS 7
+#define SHA224_DIGEST_SIZE_IN_BYTES (SHA224_DIGEST_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* The SHA-256 digest result size */
+#define SHA256_DIGEST_SIZE_IN_WORDS 8
+#define SHA256_DIGEST_SIZE_IN_BYTES (SHA256_DIGEST_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* The SHA-384 digest result size*/
+#define SHA384_DIGEST_SIZE_IN_WORDS 12
+#define SHA384_DIGEST_SIZE_IN_BYTES (SHA384_DIGEST_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* The SHA-512 digest result size in bytes */
+#define SHA512_DIGEST_SIZE_IN_WORDS 16
+#define SHA512_DIGEST_SIZE_IN_BYTES (SHA512_DIGEST_SIZE_IN_WORDS * sizeof(uint32_t))
+
+
+#define MAX_DIGEST_SIZE_WORDS       SHA512_DIGEST_SIZE_IN_WORDS
+
+#define HW_HASH_CTL_SHA1_VAL            0x0001UL
+#define HW_HASH_CTL_SHA256_VAL          0x0002UL
+#define HW_HASH_LE_MODE_VAL         0x0001UL
+#define HW_HASH_PAD_EN_VAL          0x1UL
+
+/* The SHA1 hash block size in words */
+#define HASH_BLOCK_SIZE_IN_WORDS 16
+#define HASH_BLOCK_SIZE_IN_BYTES (HASH_BLOCK_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* The SHA2 hash block size in words */
+#define HASH_SHA512_BLOCK_SIZE_IN_WORDS 32
+#define HASH_SHA512_BLOCK_SIZE_IN_BYTES (HASH_SHA512_BLOCK_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* the MAC key IPAD and OPAD bytes */
+#define MAC_KEY_IPAD_BYTE 0x36
+#define MAC_KEY_OPAD_BYTE 0x5C
+
+#define HMAC_CONTEXT_VALIDATION_TAG 0x23456789
+
+/* The CC HASH file errors */
+#define HASH_DRV_OK                     0
+#define HASH_DRV_INVALID_USER_CONTEXT_POINTER_ERROR     (HASH_DRV_MODULE_ERROR_BASE + 0x00UL)
+#define HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR           (HASH_DRV_MODULE_ERROR_BASE + 0x01UL)
+#define HASH_DRV_USER_CONTEXT_CORRUPTED_ERROR           (HASH_DRV_MODULE_ERROR_BASE + 0x02UL)
+#define HASH_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR   (HASH_DRV_MODULE_ERROR_BASE + 0x03UL)
+
+/* The CC HMAC file errors */
+#define HMAC_DRV_OK                     0
+#define HMAC_DRV_INVALID_USER_CONTEXT_POINTER_ERROR         (HMAC_DRV_MODULE_ERROR_BASE + 0x00UL)
+
+
+/* SHA512 soft driver */
+
+/* The first padding byte */
+#define LLF_HASH_FIRST_PADDING_BYTE 0x80
+/* The size at the end of the padding for SHA384 and SHA512 */
+#define LLF_HASH_SHA2_COUNTER_SIZE_ON_END_OF_PADDING_IN_BYTES (4 * sizeof(uint32_t))
+#define LLF_HASH_SHA2_COUNTER_SIZE_ON_END_OF_PADDING_IN_WORDS 4
+
+/* the HASH user context validity TAG */
+#define HASH_CONTEXT_VALIDATION_TAG 0x12345678
+
+/* the HASH XOR data value */
+#define HASH_XOR_DATA_VAL               0x0UL
+
+/******************************************************************************
+*               BYPASS DEFINITIONS
+******************************************************************************/
+
+#define CONFIG_DIN_BYPASS_DOUT_VAL                      0
+
+/* The CC BYPASS file errors */
+#define BYPASS_DRV_OK                       0
+#define BYPASS_DRV_ILLEGAL_BLOCK_SIZE_ERROR             (BYPASS_DRV_MODULE_ERROR_BASE + 0x01UL)
+#define BYPASS_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR         (BYPASS_DRV_MODULE_ERROR_BASE + 0x02UL)
+#define BYPASS_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR        (BYPASS_DRV_MODULE_ERROR_BASE + 0x03UL)
+#define BYPASS_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR (BYPASS_DRV_MODULE_ERROR_BASE + 0x04UL)
+
+/******************************************************************************
+*               CHACHA DEFINITIONS
+******************************************************************************/
+
+#define CHACHA_BLOCK_SIZE_BYTES            64
+#define CHACHA_BLOCK_SIZE_WORDS            (CHACHA_BLOCK_SIZE_BYTES >> 2)
+#define CHACHA_IV_64_SIZE_BYTES            8
+#define CHACHA_IV_64_SIZE_WORDS            (CHACHA_IV_64_SIZE_BYTES >> 2)
+#define CHACHA_IV_96_SIZE_BYTES            12
+#define CHACHA_IV_96_SIZE_WORDS            (CHACHA_IV_96_SIZE_BYTES >> 2)
+#define CHACHA_256_BIT_KEY_SIZE            32
+#define CHACHA_256_BIT_KEY_SIZE_WORDS       (CHACHA_256_BIT_KEY_SIZE >> 2)
+
+#define ENABLE_CHACHA_CLOCK     0x1UL
+#define DISABLE_CHACHA_CLOCK        0x0UL
+
+#define CONFIG_DIN_CHACHA_DOUT_VAL          0x10UL
+
+/* The CC CHACHA file errors */
+#define CHACHA_DRV_OK                       0
+#define CHACHA_DRV_INVALID_USER_CONTEXT_POINTER_ERROR   (CHACHA_DRV_MODULE_ERROR_BASE + 0x00UL)
+#define CHACHA_DRV_ILLEGAL_OPERATION_DIRECTION_ERROR    (CHACHA_DRV_MODULE_ERROR_BASE + 0x01UL)
+#define CHACHA_DRV_ILLEGAL_INPUT_ADDR_MEM_ERROR         (CHACHA_DRV_MODULE_ERROR_BASE + 0x02UL)
+#define CHACHA_DRV_ILLEGAL_OUTPUT_ADDR_MEM_ERROR        (CHACHA_DRV_MODULE_ERROR_BASE + 0x03UL)
+#define CHACHA_DRV_ILLEGAL_MEM_SIZE_ERROR               (CHACHA_DRV_MODULE_ERROR_BASE + 0x04UL)
+#define CHACHA_DRV_ILLEGAL_NONCE_SIZE_ERROR             (CHACHA_DRV_MODULE_ERROR_BASE + 0x05UL)
+#define CHACHA_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR (CHACHA_DRV_MODULE_ERROR_BASE + 0x06UL)
+
+
+/******************************************************************************
+*               MACROS
+******************************************************************************/
+/* This MACRO purpose is to switch from CryptoCell definitions to crypto driver definitions, the MACRO assumes that the value is legal (encrypt or decrypt only) */
+#define CC_2_DRIVER_DIRECTION(ssiDirection) ((ssiDirection == CC_AES_ENCRYPT) ? (CRYPTO_DIRECTION_ENCRYPT) : (CRYPTO_DIRECTION_DECRYPT))
+/* This MACRO purpose is to switch from MBEDTLS definitions to crypto driver definitions, the MACRO assumes that the value is legal (encrypt or decrypt only) */
+#define MBEDTLS_2_DRIVER_DIRECTION(mbedtlsDir) ((mbedtlsDir == 1) ? (CRYPTO_DIRECTION_ENCRYPT) : (CRYPTO_DIRECTION_DECRYPT))
+
+
+/* Poll on the crypto busy till it is = 0 */
+#define CC_HAL_WAIT_ON_CRYPTO_BUSY()\
+    do {\
+        uint32_t regVal=1;\
+        do {\
+            regVal = CC_HAL_READ_REGISTER( CC_REG_OFFSET(HOST_RGF, CRYPTO_BUSY));\
+                }while( regVal );\
+        }while(0)
+
+
+
+/* check HUK, Kcp, Kce, Kpicv, Kceicv error bit in LCS register */
+#define CC_IS_KEY_ERROR(keyType, rc)\
+    do {\
+                uint32_t regVal = 0; \
+        regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, LCS_REG));\
+            rc = CC_REG_FLD_GET(0, LCS_REG, ERROR_## keyType ##_ZERO_CNT, regVal);\
+                rc = (rc == 1)?CC_TRUE:CC_FALSE;\
+    }while(0)
+
+
+/* check if key is locked for Kpicv, Kceicv, Kcp, Kce */
+#define CC_IS_KEY_LOCKED(keyType, rc)\
+    do {\
+            uint32_t regVal = 0;\
+        regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));\
+                rc = CC_REG_FLD_GET(0, HOST_AO_LOCK_BITS, HOST_## keyType ##_LOCK, regVal);\
+                rc = (rc == 1)?CC_TRUE:CC_FALSE;\
+    }while(0)
+
+/* Verifies if one of teh keys: Kpicv, Kceicv, HBK0, Kcp or Kce is in use */
+#define CC_IS_OTP_KEY_IN_USE(owner, keyType, rc, isKeyInUse)\
+    do {\
+            uint32_t otpVal = 0;\
+            uint32_t notInUse = 0;\
+            rc = mbedtls_mng_otpWordRead(CC_OTP_## owner ##_FLAG_OFFSET, &otpVal);\
+            if (rc == CC_OK) {\
+                        notInUse = BITFIELD_GET(otpVal,  CC_OTP_## owner ##_FLAG_## keyType ##_NOT_IN_USE_BIT_SHIFT,\
+                                                           CC_OTP_## owner ##_FLAG_## keyType ##_NOT_IN_USE_BIT_SIZE);\
+            isKeyInUse = (notInUse ==0)?CC_TRUE:CC_FALSE;\
+            }\
+    }while(0)
+
+/*!
+ * This function is used to wrap the input and output data buffers to 2 info structs.
+ * The function call a PAL function to verify each buffer validity memory.
+ * It also get the buffer attribute (secure / non-secure) from the PAL function.
+ *
+ * \param pDataIn A pointer to the input data buffer.
+ * \param dataInSize - number bytes of input data buffer.
+ * \param pInputBuffInfo A structure which represents the data input buffer.
+ * \param pDataOut A pointer to the output data buffer.
+ * \param dataOutSize - number bytes of output data buffer.
+ * \param pOutputBuffInfo A structure which represents the data output buffer.
+ *
+ * \return drvError_t defined in cc_error.h.
+ */
+drvError_t SetDataBuffersInfo(const uint8_t *pDataIn, size_t dataInSize, CCBuffInfo_t *pInputBuffInfo,
+                              const uint8_t *pDataOut, size_t dataOutSize, CCBuffInfo_t *pOutputBuffInfo);
+
+#endif /* _DRIVER_DEFS_H_ */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver.c
new file mode 100644
index 0000000..012eaf5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "hash_driver.h"
+#include "driver_defs.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_sram_map.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+
+#include "cc_common.h"
+#include "cc_common_math.h"
+
+#include "cc_util_pm.h"
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+/**********************************************************************************************/
+/************************ Private Functions ***************************************************/
+/**********************************************************************************************/
+
+static void UpdateHashFinish(HashContext_t  *hashCtx)
+{
+    /* read and store the hash data registers */
+    switch(hashCtx->mode) {
+    case HASH_SHA224:
+    case HASH_SHA256:
+        hashCtx->digest[7] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7));
+        hashCtx->digest[6] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6));
+        hashCtx->digest[5] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5));
+                /* Fall-through. */
+    case HASH_SHA1:
+        hashCtx->digest[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4));
+        hashCtx->digest[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3));
+        hashCtx->digest[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2));
+        hashCtx->digest[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1));
+        hashCtx->digest[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0));
+    default:
+        break;
+    }
+
+    /* read and store the current length of message that was processed */
+    hashCtx->totalDataSizeProcessed[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_0));
+    hashCtx->totalDataSizeProcessed[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_1));
+
+    return;
+}
+
+/* initial HASH values */
+static const uint32_t HASH_LARVAL_SHA1[] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
+static const uint32_t HASH_LARVAL_SHA224[] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
+static const uint32_t HASH_LARVAL_SHA256[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
+
+
+/**********************************************************************************************/
+/************************              Public Functions          ******************************/
+/**********************************************************************************************/
+
+drvError_t InitHashDrv(void  *pCtx)
+{
+    HashContext_t  *hashCtx;
+
+        /* verify user context pointer */
+        if ( pCtx == NULL ) {
+                return HASH_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+    hashCtx = (HashContext_t  *)pCtx;
+
+        /* verify hash valid mode */
+        switch (hashCtx->mode) {
+    case HASH_SHA1:
+        CC_PalMemCopy((uint8_t *)&hashCtx->digest, (uint8_t *)&HASH_LARVAL_SHA1, SHA1_DIGEST_SIZE_IN_BYTES );
+        break;
+    case HASH_SHA224:
+        CC_PalMemCopy((uint8_t *)&hashCtx->digest, (uint8_t *)&HASH_LARVAL_SHA224, SHA256_DIGEST_SIZE_IN_BYTES );
+        break;
+    case HASH_SHA256:
+        CC_PalMemCopy((uint8_t *)&hashCtx->digest, (uint8_t *)&HASH_LARVAL_SHA256, SHA256_DIGEST_SIZE_IN_BYTES );
+                break;
+        default:
+                return HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+
+    return HASH_DRV_OK;
+}
+
+
+drvError_t ProcessHashDrv( void         *pCtx,
+                        CCBuffInfo_t *pInputBuffInfo,
+                        uint32_t    dataInSize)
+{
+    uint32_t irrVal = 0;
+    drvError_t drvRc = HASH_DRV_OK;
+    uint32_t hashCtrl = 0;
+    HashContext_t  *hashCtx;
+    uint32_t regVal = 0;
+    uint32_t inputDataAddr;
+
+    /* check input parameters */
+    if (pInputBuffInfo == NULL) {
+         return HASH_DRV_INVALID_USER_DATA_BUFF_POINTER_ERROR;
+    }
+
+    /* verify user context pointer */
+    if ( pCtx == NULL ) {
+        return HASH_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+    hashCtx = (HashContext_t  *)pCtx;
+
+    /* verify hash valid mode */
+    switch(hashCtx->mode) {
+    case HASH_SHA1:
+        hashCtrl |= HW_HASH_CTL_SHA1_VAL;
+        break;
+    case HASH_SHA224:
+    case HASH_SHA256:
+        hashCtrl |= HW_HASH_CTL_SHA256_VAL;
+        break;
+    default:
+        return HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+    }
+
+    /* lock mutex for more aes hw operation */
+    drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+    if (drvRc != 0) {
+        CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+        /* increase CC counter at the beginning of each operation */
+        drvRc = CC_IS_WAKE;
+        if (drvRc != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+    /* make sure sym engines are ready to use */
+    CC_HAL_WAIT_ON_CRYPTO_BUSY();
+
+    /* clear all interrupts before starting the engine */
+    CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+    /* mask dma interrupts which are not required */
+    irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 0);
+    CC_HalMaskInterrupt(irrVal);
+
+    /* enable clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+    /* configure CC to hash */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_HASH_MODE_VAL);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), 0);
+
+    /* load the current length of message being processed */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_0), hashCtx->totalDataSizeProcessed[0]);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_1), hashCtx->totalDataSizeProcessed[1]);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CONTROL) ,hashCtrl);
+
+    /* initializing the init HASH values from context */
+    switch(hashCtx->mode) {
+    case HASH_SHA224:
+    case HASH_SHA256:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7) ,hashCtx->digest[7]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6) ,hashCtx->digest[6]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5) ,hashCtx->digest[5]);
+        /* Fall-through. */
+    case HASH_SHA1:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4) ,hashCtx->digest[4]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3) ,hashCtx->digest[3]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2) ,hashCtx->digest[2]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1) ,hashCtx->digest[1]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0) ,hashCtx->digest[0]);
+    default:
+        break;
+    }
+
+    if (dataInSize == 0) {
+        /* use DO_PAD to complete padding of previous operation */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,4);
+
+    } else {
+        /* use HW padding (NA for zero bytes) for last block */
+        if (hashCtx->isLastBlockProcessed == 1){
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,1);
+        }
+
+        inputDataAddr = pInputBuffInfo->dataBuffAddr;
+
+        /* configure the HW with the correct data buffer attributes (secure/non-secure) */
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, pInputBuffInfo->dataBuffNs);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AHBM_HNONSEC) ,regVal);
+
+        /* configure source address and size */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD0) ,inputDataAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, SRC_LLI_WORD1) ,dataInSize);
+
+        /* set dma completion bit in irr */
+        irrVal = 0;
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+        drvRc = CC_HalWaitInterrupt(irrVal);
+        /* Note: Hash operation should be completed also in case of error! */
+        /* drvRc will be tested later, and hash results will be cleared */
+    }
+
+    /* finishing the update operation */
+    UpdateHashFinish(hashCtx);
+
+    /* reset to default values in case of operation completion */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,0);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,0);
+
+    /* disable the HASH clock in the end of the process */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+    if (drvRc != HASH_DRV_OK) {
+        /* Clear buffer results in case of error */
+        CC_PalMemSetZero((uint8_t*)hashCtx->digest, MAX_DIGEST_SIZE_WORDS);
+    }
+
+    /* decrease CC counter at the end of each operation */
+    if (CC_IS_IDLE != 0) {
+        CC_PalAbort("Fail to decrease PM counter\n");
+    }
+
+    /* release mutex */
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+    CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return drvRc;
+}
+
+
+drvError_t FinishHashDrv(void  *pCtx)
+{
+
+    HashContext_t  *hashCtx;
+    int i;
+
+        /* verify user context pointer */
+        if ( pCtx == NULL ) {
+                return HASH_DRV_INVALID_USER_CONTEXT_POINTER_ERROR;
+        }
+    hashCtx = (HashContext_t  *)pCtx;
+
+    /* reverse the bytes */
+    for ( i = 0 ; i < MAX_DIGEST_SIZE_WORDS ; i++ )
+        hashCtx->digest[i] = CC_COMMON_REVERSE32(hashCtx->digest[i]);
+
+    return HASH_DRV_OK;
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver.h
new file mode 100644
index 0000000..d85da35
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _HASH_DRIVER_H
+#define  _HASH_DRIVER_H
+
+#include "driver_defs.h"
+
+/******************************************************************************
+*               TYPE DEFINITIONS
+******************************************************************************/
+
+/* The context data-base used by the Hash functions on the low level */
+typedef struct HashContext {
+    /* mode: SHA1, SHA224, SHA256 */
+    hashMode_t mode;
+
+    /* last block ack */
+    uint32_t isLastBlockProcessed;
+
+    /* hash data */
+    uint32_t digest[MAX_DIGEST_SIZE_WORDS];
+
+    /* The buffer that contains the size of so far digested message in the hardware.
+       For SHA1, sha-224 and SHA-256 it is 64 bits,
+       For SHA-384 and SHA-512 it is 128 bits */
+    uint32_t totalDataSizeProcessed[4];
+
+/* the follwing ia used only by soft sha512 */
+
+    uint32_t valid_tag;
+
+    /* the size of the Block size in bytes according to the currently running SHA algorithm (64 or 108) */
+    uint32_t blockSizeInBytes;
+
+    /* The number of bytes in the previous update */
+    uint32_t prevDataInSize;
+
+    /* A block buffer used for all cases where the update data size
+    is not aligned to a block size - we cannot perform the block,
+    therefore the first block is always loaded from this buffer  */
+    uint32_t prevDataIn[HASH_SHA512_BLOCK_SIZE_IN_WORDS];
+
+    /* function pointers for llf hash operations */
+    llf_hash_init_operation_func  llfHashInitFuncP;
+    llf_hash_update_operation_func  llfHashUpdateFuncP;
+    llf_hash_finish_operation_func  llfHashFinishFuncP;
+
+} HashContext_t;
+
+
+/* HW hash for sha1, sha224 and sha256 */
+drvError_t InitHashDrv(void  *pCtx);
+drvError_t ProcessHashDrv(void *pCtx, CCBuffInfo_t *pInputBuffInfo, uint32_t dataInSize);
+drvError_t FinishHashDrv(void  *pCtx);
+
+/* soft hash for sha384 and sha512 */
+drvError_t InitSwHash512(void  *pCtx);
+drvError_t ProcessSwHash512(void  *pCtx, CCBuffInfo_t *pInputBuffInfo, uint32_t dataInSize );
+drvError_t FinishSwHash512(void  *pCtx);
+
+#endif /* _HASH_DRIVER_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver_ext_dma.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver_ext_dma.c
new file mode 100644
index 0000000..b90367d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver_ext_dma.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "hash_driver.h"
+#include "driver_defs.h"
+#include "cc_hal.h"
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "hash_driver_ext_dma.h"
+#include "cc_util_pm.h"
+
+extern CC_PalMutex CCSymCryptoMutex;
+
+
+/* initial HASH values */
+static const uint32_t HASH_LARVAL_SHA1[] = {0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0};
+static const uint32_t HASH_LARVAL_SHA224[] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4};
+static const uint32_t HASH_LARVAL_SHA256[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
+
+
+/**********************************************************************************************/
+/************************ Private Functions ***************************************************/
+/**********************************************************************************************/
+
+static void UpdateHashFinishExtDma(hashMode_t mode, uint32_t *digest)
+{
+    /* read and store the hash data registers */
+    switch(mode) {
+    case HASH_SHA224:
+    case HASH_SHA256:
+        digest[7] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7));
+        digest[6] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6));
+        digest[5] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5));
+        /* fall-thru */
+    case HASH_SHA1:
+        digest[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4));
+        digest[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3));
+        digest[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2));
+        digest[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1));
+        digest[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0));
+    default:
+        break;
+    }
+}
+
+/**********************************************************************************************/
+/************************              Public Functions          ******************************/
+/**********************************************************************************************/
+
+drvError_t InitHashExtDma(hashMode_t mode, uint32_t dataSize)
+{
+    uint32_t hashCtrl = 0;
+    uint32_t digest[MAX_DIGEST_SIZE_WORDS] = {0};
+    drvError_t drvRc = HASH_DRV_OK;
+    int rc;
+    uint32_t irrVal = 0;
+
+    /* lock mutex for more aes hw operation */
+    drvRc = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+    if (drvRc != 0) {
+        CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* increase CC counter at the beginning of each operation */
+    drvRc = CC_IS_WAKE;
+    if (drvRc != 0) {
+        CC_PalAbort("Fail to increase PM counter\n");
+    }
+
+    /* make sure sym engines are ready to use */
+    CC_HAL_WAIT_ON_CRYPTO_BUSY();
+    /* verify hash valid mode */
+    switch(mode) {
+    case HASH_SHA1:
+        hashCtrl |= HW_HASH_CTL_SHA1_VAL;
+        CC_PalMemCopy((uint8_t *)digest, (uint8_t *)&HASH_LARVAL_SHA1, SHA1_DIGEST_SIZE_IN_BYTES );
+        break;
+    case HASH_SHA224:
+        hashCtrl |= HW_HASH_CTL_SHA256_VAL;
+        CC_PalMemCopy((uint8_t *)digest, (uint8_t *)&HASH_LARVAL_SHA224, SHA256_DIGEST_SIZE_IN_BYTES );
+        break;
+    case HASH_SHA256:
+        hashCtrl |= HW_HASH_CTL_SHA256_VAL;
+        CC_PalMemCopy((uint8_t *)digest, (uint8_t *)&HASH_LARVAL_SHA256, SHA256_DIGEST_SIZE_IN_BYTES );
+        break;
+    default:
+        drvRc = HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        goto end;
+    }
+
+
+    /* clear all interrupts before starting the engine */
+    CC_HalClearInterruptBit(0xFFFFFFFFUL);
+
+    /* mask dma interrupts which are not required */
+    irrVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, irrVal, 1);
+    CC_HalMaskInterrupt(irrVal);
+
+    /* enable clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_ENABLE);
+
+    /* configure CC to hash */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_CTL) ,CONFIG_HASH_MODE_VAL);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_SEL_AES_MAC), 0);
+
+    /* load the current length of message being processed */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_0), 0);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CUR_LEN_1), 0);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CONTROL) ,hashCtrl);
+
+    /* initializing the init HASH values from context */
+    switch(mode) {
+    case HASH_SHA224:
+    case HASH_SHA256:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H7) ,digest[7]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H6) ,digest[6]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H5) ,digest[5]);
+        /* fall-thru */
+    case HASH_SHA1:
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H4) ,digest[4]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H3) ,digest[3]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H2) ,digest[2]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H1) ,digest[1]);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_H0) ,digest[0]);
+        break;
+    default:
+        drvRc = HASH_DRV_ILLEGAL_OPERATION_MODE_ERROR;
+        goto end;
+    }
+    if (dataSize == 0) {
+        /* use DO_PAD to complete padding of previous operation */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,4);
+
+    } else {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,1);
+    }
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_CPU_DATA_SIZE) , dataSize);
+
+
+    return HASH_DRV_OK;
+end:
+    rc = terminateHashExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateHashExtDma \n");
+    }
+
+    return drvRc;
+}
+
+
+drvError_t FinishHashExtDma(hashMode_t mode, uint32_t * digest)
+{
+
+    int i;
+    drvError_t rc = AES_DRV_OK;
+
+    UpdateHashFinishExtDma(mode, digest);
+    /* reverse the bytes */
+    for ( i = 0 ; i < MAX_DIGEST_SIZE_WORDS ; i++ ) {
+        digest[i] = CC_COMMON_REVERSE32(digest[i]);
+    }
+
+    /* reset to default values */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_EN) ,1);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AUTO_HW_PADDING) ,0);
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_PAD_CFG) ,0);
+
+
+    rc = terminateHashExtDma();
+    if (rc != 0) {
+        CC_PalAbort("Failed to terminateHashExtDma \n");
+    }
+
+    return HASH_DRV_OK;
+}
+
+drvError_t terminateHashExtDma(void)
+{
+    drvError_t rc = AES_DRV_OK;
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HASH_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DMA_CLK_ENABLE) ,SET_CLOCK_DISABLE);
+
+    /* decrease CC counter at the end of each operation */
+    rc = CC_IS_IDLE;
+    if (rc != 0) {
+        CC_PalAbort("Fail to decrease PM counter\n");
+    }
+
+    /* unlock mutex for more aes hw operation */
+    rc = CC_PalMutexUnlock(&CCSymCryptoMutex);
+    if (rc != 0) {
+        CC_PalAbort("Fail to unlock mutex\n");
+    }
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver_ext_dma.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver_ext_dma.h
new file mode 100644
index 0000000..e82af6a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hash_driver_ext_dma.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef  _HASH_DRIVER_EXT_DMA_H
+#define  _HASH_DRIVER_EXT_DMA_H
+
+#include "driver_defs.h"
+
+
+
+
+drvError_t FinishHashExtDma(hashMode_t mode, uint32_t * digest);
+drvError_t InitHashExtDma(hashMode_t mode, uint32_t dataSize);
+drvError_t terminateHashExtDma(void);
+
+
+
+
+#endif // #_HASH_DRIVER_EXT_DMA_H
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hmac_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hmac_driver.h
new file mode 100644
index 0000000..c919139
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/hmac_driver.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _HMAC_DRIVER_H
+#define  _HMAC_DRIVER_H
+
+#include "driver_defs.h"
+
+/******************************************************************************
+*               TYPE DEFINITIONS
+******************************************************************************/
+
+/* The context data-base used by the Hmac functions on the low level */
+typedef struct HmacContext {
+    uint32_t valid_tag;
+    /* Key XOR opad result */
+    uint8_t KeyXorOpadBuff[CC_HMAC_SHA2_1024BIT_KEY_SIZE_IN_BYTES];
+    /* The operation mode */
+    CCHashOperationMode_t mode;
+    /* The user HASH context - required for operating the HASH described below */
+    CCHashUserContext_t HashUserContext;
+} HmacContext_t;
+
+
+#endif /* _HMAC_DRIVER_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/srp_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/srp_driver.c
new file mode 100644
index 0000000..3cbfaa2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/srp_driver.c
@@ -0,0 +1,726 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "mbedtls_cc_srp.h"
+#include "cc_hash_defs.h"
+#include "hash_driver.h"
+#include "mbedtls_cc_srp_error.h"
+#include "cc_general_defs.h"
+#include "md.h"
+#include "cc_bitops.h"
+
+
+#define  REMOVE_LEADING_BYTE_ZEROS(origPubKey, origSize, pPubKey, pubKeySize) {\
+    size_t i; \
+    for (i = 0; i < origSize; i++) { \
+        if (((uint8_t *)origPubKey)[i] != 0) { \
+            break;\
+        } \
+    }\
+    pubKeySize = origSize-i; \
+    pPubKey = &(((uint8_t *)origPubKey)[i]); \
+}
+
+
+
+CCHashResultBuf_t zeroBuff = {0};
+
+
+static uint32_t  SRP_kMultiplierCalc(mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+     size_t          modSize;
+    CCHashResultBuf_t      hashResultBuff;
+    const mbedtls_md_info_t *md_info=NULL;
+    mbedtls_md_context_t hash_ctx;
+
+    modSize = CALC_FULL_BYTES(pCtx->groupParam.modSizeInBits);
+
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+    if (NULL == md_info) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    mbedtls_md_init(&hash_ctx);
+    rc = mbedtls_md_setup(&hash_ctx, md_info, 0); // 0 = HASH, not HMAC
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_starts(&hash_ctx);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, pCtx->groupParam.modulus, modSize);
+    if (rc != 0) {
+        goto End;
+    }
+    // use ephemPriv as tempopary buffer with paded zeros
+    CC_PalMemSetZero(pCtx->ephemPriv, sizeof(mbedtls_srp_modulus));
+    pCtx->ephemPriv[modSize-1] =  pCtx->groupParam.gen;
+    rc = mbedtls_md_update(&hash_ctx, (uint8_t *)pCtx->ephemPriv, modSize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_finish(&hash_ctx, (unsigned char *)hashResultBuff);
+    if (rc != 0) {
+        goto End;
+    }
+    // verify k != 0
+    if (CC_PalMemCmp((uint8_t *)zeroBuff, (uint8_t *)hashResultBuff, pCtx->hashDigestSize) == 0) {
+        rc = CC_SRP_RESULT_ERROR;
+        goto End;
+    }
+    // copy the result to the user
+    CC_PalMemCopy(pCtx->kMult, (uint8_t *)hashResultBuff, pCtx->hashDigestSize);
+
+End:
+    if (NULL != md_info) {
+        mbedtls_md_free(&hash_ctx);
+    }
+    return rc;
+}
+
+// Sha_interleave - from RFC 2945 : Interleaved SHA
+static uint32_t SRP_shaInterleave(uint8_t        *pInBuff,       /* in buff to hash*/
+                         size_t       inBuffSize, /* in buffer size */
+                         mbedtls_srp_sessionKey   sessionKey,   /* out hash interleave buff - shared secret */
+                         mbedtls_srp_context  *pCtx)
+{
+    uint32_t rc = CC_OK;
+    uint32_t i = 0;
+    uint32_t j = 0;
+    const mbedtls_md_info_t *md_info=NULL;
+    uint8_t buffEF[CC_SRP_MAX_MODULUS/2] = {0};
+    uint8_t buffG[CC_SRP_MAX_DIGEST] = {0};
+    uint8_t buffH[CC_SRP_MAX_DIGEST] = {0};
+
+    // Remove all leading zero bytes from the input.
+    while ((pInBuff[i] == 0) &&
+           (inBuffSize > 0)) {
+        inBuffSize--;
+        i++;
+    }
+    if (inBuffSize == 0) {
+        /* meaning pInBuff, which is the shared secret is 0 --
+         * not reasonable, since that the think about SRP */
+        return CC_SRP_INTERNAL_ERROR;
+    }
+    // If the length of the resulting string is odd, also remove the first byte
+    if (inBuffSize % 2) {
+        inBuffSize--;
+        i++;
+    }
+    if (inBuffSize == 0) {
+        /* meaning pInBuff, which is the shared secret is 0 --
+          * not reasonable, since that the think about SRP */
+         return CC_SRP_INTERNAL_ERROR;
+    }
+
+
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+    if (NULL == md_info) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    // E = T[0] | T[2] | T[4] | ...
+    for (j = 0; j < (inBuffSize/2); j++) {
+        buffEF[j] = pInBuff[i+j*2];
+    }
+    //G = SHA(E)
+    rc = mbedtls_md(md_info,
+                    buffEF,
+                    inBuffSize/2,
+                    (unsigned char *)buffG);
+    if (rc != 0) {
+        return rc;
+    }
+
+    // F = T[1] | T[3] | T[5] | ...
+    for (j = 0; j < (inBuffSize/2); j++) {
+        buffEF[j] = pInBuff[i+j*2+1];
+    }
+    //H = SHA(F)
+    rc = mbedtls_md(md_info,
+                    buffEF,
+                    inBuffSize/2,
+                    (unsigned char *)buffH);
+    if (rc != 0) {
+        return rc;
+    }
+
+    // result = G[0] | H[0] | G[1] | H[1] | ... | G[19] | H[19]
+    for (i = 0; (i < pCtx->hashDigestSize) && (2*i+1 < pCtx->sessionKeySize); i++) {
+        sessionKey[2*i] = buffG[i];
+        sessionKey[2*i+1] = buffH[i];
+
+    }
+    return CC_OK;
+}
+
+static uint32_t SRP_shaInterleaveHK(uint8_t        *pInBuff,       /* in buff to hash*/
+                         size_t       inBuffSize, /* in buffer size */
+                         mbedtls_srp_sessionKey   sessionKey,   /* out hash interleave buff - shared secret */
+                         mbedtls_srp_context  *pCtx)
+{
+    uint32_t rc = CC_OK;
+    const mbedtls_md_info_t *md_info=NULL;
+
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+    if (NULL == md_info) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    rc = mbedtls_md(md_info,
+                    pInBuff,
+                    inBuffSize,
+                    (unsigned char *)sessionKey);
+    if (rc != 0) {
+        return rc;
+    }
+    return CC_OK;
+}
+
+uint32_t  SRP_InitAndkMultiplierCalc(mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    size_t          hashDigestSize;
+
+    // verify input
+    if (pCtx == NULL) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    hashDigestSize = pCtx->hashDigestSize;
+
+    CC_PalMemSetZero(pCtx->kMult, sizeof(mbedtls_srp_digest));
+    switch(pCtx->srpVer) {
+    case CC_SRP_VER_3:
+        pCtx->sessionKeySize = 2*hashDigestSize;
+        pCtx->kMult[hashDigestSize-1] = 0x1;
+        break;
+    case CC_SRP_VER_6:
+        pCtx->sessionKeySize = 2*hashDigestSize;
+        pCtx->kMult[hashDigestSize-1] = 0x3;
+        break;
+    case CC_SRP_VER_6A:
+        /* Does 6A requires sha-interleave or just sha?
+         * we assume sha-interleave is required, therefore the size of the session key is digest*2
+         * see details in Cerberus confluence */
+        pCtx->sessionKeySize = 2*hashDigestSize;
+        rc = SRP_kMultiplierCalc(pCtx);
+        break;
+    case CC_SRP_VER_HK:
+        pCtx->sessionKeySize = hashDigestSize;
+        rc = SRP_kMultiplierCalc(pCtx);
+        break;
+    default:  // should not reach here
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    return rc;
+}
+
+uint32_t  SRP_uScrambleCalc(
+        mbedtls_srp_modulus ephemPubA,
+        mbedtls_srp_modulus ephemPubB,
+        mbedtls_srp_digest  uScramble,
+        mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    CCHashResultBuf_t      hashResultBuff;
+    size_t  modSize;
+    uint32_t    bytesToCopy = 0;
+    mbedtls_md_context_t hash_ctx;
+
+    const mbedtls_md_info_t *md_info=NULL;
+    mbedtls_md_context_t *md_ctx=NULL;
+
+    // verify input
+    if ((ephemPubA == NULL) ||
+            (ephemPubB == NULL) ||
+            (uScramble == NULL) ||
+            (pCtx == NULL)) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+
+    modSize = CALC_FULL_BYTES(pCtx->groupParam.modSizeInBits);
+
+    CC_PalMemSetZero(uScramble, sizeof(mbedtls_srp_digest));
+    switch(pCtx->srpVer) {
+    case CC_SRP_VER_3:
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+        if (NULL == md_info) {
+            rc = CC_SRP_PARAM_INVALID_ERROR;
+            goto End;
+        }
+        rc = mbedtls_md(md_info,
+                        (uint8_t *)ephemPubB,
+                        modSize,
+                        (unsigned char *)hashResultBuff);
+        if (rc != 0) {
+            goto End;
+        }
+        // The parameter u is a 32-bit unsigned integer which takes its value
+        // from the first 32 bits of the SHA1 hash of B, MSB first.
+        bytesToCopy = CC_32BIT_WORD_SIZE;
+        break;
+    case CC_SRP_VER_6:
+    case CC_SRP_VER_6A:
+    case CC_SRP_VER_HK:
+        md_ctx = &hash_ctx;
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+        if (NULL == md_info) {
+            rc = CC_SRP_PARAM_INVALID_ERROR;
+            goto End;
+        }
+        mbedtls_md_init(md_ctx);
+        rc = mbedtls_md_setup(md_ctx, md_info, 0); // 0 = HASH, not HMAC
+        if (rc != 0) {
+            goto End;
+        }
+        rc = mbedtls_md_starts(md_ctx);
+        if (rc != 0) {
+            goto End;
+        }
+        rc = mbedtls_md_update(md_ctx, ephemPubA, modSize);
+        if (rc != 0) {
+            goto End;
+        }
+        rc = mbedtls_md_update(md_ctx, ephemPubB, modSize);
+        if (rc != 0) {
+            goto End;
+        }
+
+        rc = mbedtls_md_finish(md_ctx, (unsigned char *)hashResultBuff);
+        if (rc != 0) {
+            goto End;
+        }
+        bytesToCopy = pCtx->hashDigestSize;
+        break;
+    default:  // should not reach here
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    // verify u != 0
+    if (CC_PalMemCmp((uint8_t *)zeroBuff, (uint8_t *)hashResultBuff, bytesToCopy) == 0) {
+        rc = CC_SRP_RESULT_ERROR;
+        goto End;
+    }
+    // copy uScramble
+    CC_PalMemCopy(uScramble, (uint8_t *)hashResultBuff, bytesToCopy);
+
+    End:
+    if((md_info!=NULL) && (md_ctx!=NULL)) {
+        mbedtls_md_free(md_ctx);
+    }
+
+    return rc;
+}
+
+
+// credDigest = SHA(U|:|P)
+uint32_t  SRP_UserCredDigCalc(uint8_t   *pUserName,
+                              size_t        userNameSize,
+                              uint8_t   *pPwd,
+                              size_t        pwdSize,
+                              mbedtls_srp_context *pCtx)
+{
+    CCError_t   rc = 0;
+    char  colonChar = ':';
+    CCHashResultBuf_t      hashResultBuff;
+    const mbedtls_md_info_t *md_info=NULL;
+    mbedtls_md_context_t hash_ctx;
+
+    // verify input
+    if ((pUserName == NULL) || (userNameSize == 0) ||
+            (pPwd == NULL) || (pwdSize == 0) ||
+            (pCtx == NULL)) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+
+    CC_PalMemSetZero(pCtx->credDigest, sizeof(mbedtls_srp_digest));
+
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+    if (NULL == md_info) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    mbedtls_md_init(&hash_ctx);
+    rc = mbedtls_md_setup(&hash_ctx, md_info, 0); // 0 = HASH, not HMAC
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_starts(&hash_ctx);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, pUserName, userNameSize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, (uint8_t *)&colonChar, sizeof(colonChar));
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, pPwd, pwdSize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_finish(&hash_ctx, (unsigned char *)hashResultBuff);
+    if (rc != 0) {
+        goto End;
+    }
+    CC_PalMemCopy(pCtx->credDigest, (uint8_t *)hashResultBuff, pCtx->hashDigestSize);
+
+    End:
+    if (NULL != md_info) {
+        mbedtls_md_free(&hash_ctx);
+    }
+
+    return rc;
+}
+
+// calc x = SHA(pSalt | pCtx->credDigest)
+uint32_t  SRP_xBuffCalc(uint8_t             *pSalt,
+                        size_t          saltSize,
+                        mbedtls_srp_digest  xBuff,  // out
+                        mbedtls_srp_context     *pCtx)
+{
+    CCError_t   rc = 0;
+    CCHashResultBuf_t      hashResultBuff;
+    const mbedtls_md_info_t *md_info=NULL;
+    mbedtls_md_context_t hash_ctx;
+
+    // verify input
+    if ((pSalt == NULL) ||
+            (saltSize < CC_SRP_MIN_SALT_SIZE) || (saltSize > CC_SRP_MAX_SALT_SIZE) ||
+            (xBuff == NULL) ||
+            (pCtx == NULL)) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+    if (NULL == md_info) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    mbedtls_md_init(&hash_ctx);
+    rc = mbedtls_md_setup(&hash_ctx, md_info, 0); // 0 = HASH, not HMAC
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_starts(&hash_ctx);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, pSalt, saltSize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, pCtx->credDigest, pCtx->hashDigestSize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_finish(&hash_ctx, (unsigned char *)hashResultBuff);
+    if (rc != 0) {
+        goto End;
+    }
+    CC_PalMemCopy(xBuff, (uint8_t *)hashResultBuff, pCtx->hashDigestSize);
+
+    End:
+    if (NULL != md_info) {
+        mbedtls_md_free(&hash_ctx);
+    }
+
+    return rc;
+}
+
+
+//SHA(U)
+uint32_t  SRP_UserNameDigCalc(uint8_t   *pUserName,
+                              size_t        userNameSize,
+                              mbedtls_srp_context   *pCtx)
+{
+    CCError_t   rc = 0;
+    CCHashResultBuf_t      hashResultBuff;
+    const mbedtls_md_info_t *md_info=NULL;
+
+    // verify input
+    if ((pUserName == NULL) || (userNameSize == 0) ||
+            (pCtx == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    if (pCtx->hashDigestSize > sizeof(CCHashResultBuf_t)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    // SHA(U)
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+    if (NULL == md_info) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    rc = mbedtls_md(md_info,
+                    pUserName,
+                    userNameSize,
+                    (unsigned char *)hashResultBuff);
+    if (rc != 0) {
+        return rc;
+    }
+    CC_PalMemCopy(pCtx->userNameDigest, (uint8_t *)hashResultBuff, pCtx->hashDigestSize);
+
+    return rc;
+}
+
+// SHA((SHA(N) XOR SHA(g))|SHA(U)|s|A|B|K)
+uint32_t  SRP_UserProofCalc2(uint8_t        *pSalt,
+                             size_t                 saltSize,
+                             mbedtls_srp_modulus        userPubKeyA,
+                             mbedtls_srp_modulus        hostPubKeyB,
+                             mbedtls_srp_sessionKey sessionKey,
+                             mbedtls_srp_digest userProof, // out
+                             mbedtls_srp_context    *pCtx)
+{
+    CCError_t   rc = 0;
+    CCHashResultBuf_t      hashResultBuff;
+    size_t          hashDigestSize;
+    size_t          modSize;
+    uint32_t        i = 0;
+    uint8_t         *pPubKey;
+    size_t          pubKeySize;
+    CCHashResultBuf_t   buff1 = {0};
+    CCHashResultBuf_t   buff2 = {0};
+    CCHashOperationMode_t   hashMode;
+    mbedtls_md_context_t hash_ctx;
+
+    const mbedtls_md_info_t *md_info=NULL;
+    mbedtls_md_context_t *md_ctx=NULL;
+
+    // verify input
+    if ((pSalt == NULL) ||
+            (saltSize < CC_SRP_MIN_SALT_SIZE) || (saltSize > CC_SRP_MAX_SALT_SIZE) ||
+            (userPubKeyA == NULL) ||
+            (hostPubKeyB == NULL) ||
+            (sessionKey == NULL) ||
+            (userProof == NULL) ||
+            (pCtx == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    hashDigestSize = pCtx->hashDigestSize;
+    modSize = CALC_FULL_BYTES(pCtx->groupParam.modSizeInBits);
+    hashMode = pCtx->hashMode;
+
+    CC_PalMemSetZero(userProof, sizeof(mbedtls_srp_digest));
+
+    // SHA(N)
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+    if (NULL == md_info) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    rc = mbedtls_md(md_info,
+                    pCtx->groupParam.modulus,
+                    CALC_FULL_BYTES(pCtx->groupParam.modSizeInBits),
+                    (unsigned char *)buff1);
+    if (rc != 0) {
+        goto End;
+    }
+
+    // SHA(g)
+    rc = mbedtls_md(md_info,
+                    &pCtx->groupParam.gen,
+                    sizeof(pCtx->groupParam.gen),
+                    (unsigned char *)buff2);
+    if (rc != 0) {
+        goto End;
+    }
+    // XOR SHA(N)^=SHA(g)
+    for (i = 0; i < CALC_32BIT_WORDS_FROM_BYTES(hashDigestSize); i++) {
+        buff1[i] ^= buff2[i];
+    }
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+    if (NULL == md_info) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    md_ctx = &hash_ctx;
+    mbedtls_md_init(md_ctx);
+    rc = mbedtls_md_setup(md_ctx, md_info, 0); // 0 = HASH, not HMAC
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_starts(md_ctx);
+    if (rc != 0) {
+        goto End;
+    }
+    // Update(SHA(N)^=SHA(g))
+    rc = mbedtls_md_update(md_ctx, (uint8_t *)buff1, hashDigestSize);
+    if (rc != 0) {
+        goto End;
+    }
+    // Update(SHA(U))
+    rc = mbedtls_md_update(md_ctx, pCtx->userNameDigest, hashDigestSize);
+    if (rc != 0) {
+        goto End;
+    }
+    //Update(salt)
+    rc = mbedtls_md_update(md_ctx, pSalt, saltSize);
+    if (rc != 0) {
+        goto End;
+    }
+    //Update(A)
+    REMOVE_LEADING_BYTE_ZEROS((uint8_t *)userPubKeyA, modSize, pPubKey, pubKeySize);
+    rc = mbedtls_md_update(md_ctx, (uint8_t *)pPubKey, pubKeySize);
+    if (rc != 0) {
+        goto End;
+    }
+    //Update(B)
+    REMOVE_LEADING_BYTE_ZEROS((uint8_t *)hostPubKeyB, modSize, pPubKey, pubKeySize);
+    rc = mbedtls_md_update(md_ctx, (uint8_t *)pPubKey, pubKeySize);
+    if (rc != 0) {
+        goto End;
+    }
+    //Update(K)
+    rc = mbedtls_md_update(md_ctx, (uint8_t *)sessionKey, pCtx->sessionKeySize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_finish(md_ctx, (unsigned char *)hashResultBuff);
+    if (rc != 0) {
+        goto End;
+    }
+    CC_PalMemCopy(userProof, (uint8_t *)hashResultBuff, hashDigestSize);
+
+    End:
+    if((md_info!=NULL) && (md_ctx!=NULL)) {
+        mbedtls_md_free(md_ctx);
+    }
+
+    return rc;
+}
+
+
+
+// SHA(A|M1|K)
+uint32_t  SRP_HostProofCalc(mbedtls_srp_modulus  userPubKeyA,
+                            mbedtls_srp_digest  userProof,
+                            mbedtls_srp_sessionKey  sessionKey,
+                            mbedtls_srp_digest  hostProof,  // out
+                            mbedtls_srp_context     *pCtx)
+{
+    CCError_t   rc = 0;
+    size_t      hashDigestSize;
+    CCHashResultBuf_t      hashResultBuff;
+    const mbedtls_md_info_t *md_info=NULL;
+    mbedtls_md_context_t hash_ctx;
+    uint8_t  *pPubKey;
+    size_t          pubKeySize;
+
+    // verify input
+    if ((userPubKeyA == NULL) ||
+            (userProof == NULL) ||
+            (sessionKey == NULL) ||
+            (hostProof == NULL) ||
+            (pCtx == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    hashDigestSize = pCtx->hashDigestSize;
+
+    CC_PalMemSetZero(hostProof, sizeof(mbedtls_srp_digest));
+
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[pCtx->hashMode] );
+    if (NULL == md_info) {
+        rc = CC_SRP_PARAM_INVALID_ERROR;
+        goto End;
+    }
+    mbedtls_md_init(&hash_ctx);
+    rc = mbedtls_md_setup(&hash_ctx, md_info, 0); // 0 = HASH, not HMAC
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_starts(&hash_ctx);
+    if (rc != 0) {
+        goto End;
+    }
+    REMOVE_LEADING_BYTE_ZEROS((uint8_t *)userPubKeyA, CALC_FULL_BYTES(pCtx->groupParam.modSizeInBits), pPubKey, pubKeySize);
+    rc = mbedtls_md_update(&hash_ctx, (uint8_t *)pPubKey, pubKeySize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, (uint8_t *)userProof, hashDigestSize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_update(&hash_ctx, (uint8_t *)sessionKey, pCtx->sessionKeySize);
+    if (rc != 0) {
+        goto End;
+    }
+    rc = mbedtls_md_finish(&hash_ctx, (unsigned char *)hashResultBuff);
+    if (rc != 0) {
+        goto End;
+    }
+    CC_PalMemCopy(hostProof, (uint8_t *)hashResultBuff, hashDigestSize);
+
+    End:
+    if (NULL != md_info) {
+        mbedtls_md_free(&hash_ctx);
+    }
+
+    return rc;
+}
+
+uint32_t  SRP_SessionKeyCalc(uint8_t        *pInBuff,       /* in buff to hash*/
+                               size_t       inBuffSize, /* in buffer size */
+                               mbedtls_srp_sessionKey   sessionKey, /* out hash interleave buff - shared secret */
+                               mbedtls_srp_context  *pCtx)
+{
+    CCError_t   rc = 0;
+
+    //Verify inputs
+    if ((pInBuff == NULL) ||
+            (inBuffSize == 0) || (inBuffSize > CC_SRP_MAX_MODULUS) ||
+            (sessionKey == NULL) ||
+            (pCtx == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    CC_PalMemSetZero(sessionKey, sizeof(mbedtls_srp_sessionKey));
+
+    switch(pCtx->srpVer) {
+    case CC_SRP_VER_HK:
+        rc = SRP_shaInterleaveHK(pInBuff, inBuffSize, sessionKey, pCtx);
+       break;
+    case CC_SRP_VER_3:
+    case CC_SRP_VER_6:
+        /* Does 6A requires sha-interleave or just sha?
+         * see details in Cerberus confluence */
+    case CC_SRP_VER_6A:
+        rc = SRP_shaInterleave(pInBuff, inBuffSize, sessionKey, pCtx);
+        break;
+    default:  // should not reach here
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    return rc;
+}
+
+
+uint32_t SRP_SecureMemCmp( const uint8_t* aTarget, /*!< [in] The target buffer to compare. */
+                           const uint8_t* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */)
+{
+    uint32_t i;
+    uint32_t stat = 0;
+
+    for( i = 0; i < aSize; i++ ) {
+        stat |= (aTarget[i] ^ aSource[i]);
+    }
+
+    return stat;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/srp_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/srp_driver.h
new file mode 100644
index 0000000..81ccfce
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/srp_driver.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "mbedtls_cc_srp.h"
+
+
+uint32_t  SRP_InitAndkMultiplierCalc(mbedtls_srp_context *pSrpCtx);
+
+uint32_t  SRP_uScrambleCalc(mbedtls_srp_modulus ephemPubA,
+        mbedtls_srp_modulus ephemPubB,
+        mbedtls_srp_digest  uScramble,
+        mbedtls_srp_context *pCtx);
+
+// credDigest = SHA(U|:|P)
+uint32_t  SRP_UserCredDigCalc(uint8_t   *pUserName,
+              size_t        userNameSize,
+              uint8_t   *pPwd,
+              size_t        pwdSize,
+              mbedtls_srp_context *pCtx);
+
+
+// calc x = SHA(pSalt | pCtx->credDigest)
+uint32_t  SRP_xBuffCalc(uint8_t             *pSalt,
+            size_t          saltSize,
+            mbedtls_srp_digest  xBuff,  // out
+            mbedtls_srp_context     *pCtx);
+
+//SHA(U)
+uint32_t  SRP_UserNameDigCalc(uint8_t   *pUserName,
+        size_t        userNameSize,
+        mbedtls_srp_context     *pCtx);
+
+// SHA(SHA(N)^=SHA(g) | SHA(U)|s|A|B|K)
+uint32_t  SRP_UserProofCalc2(uint8_t            *pSalt,
+            size_t                  saltSize,
+            mbedtls_srp_modulus         userPubKeyA,
+            mbedtls_srp_modulus         hostPubKeyB,
+            mbedtls_srp_sessionKey  sessionKey,
+            mbedtls_srp_digest  userProof,
+            mbedtls_srp_context     *pCtx);
+
+// SHA(A|M1|K)
+uint32_t  SRP_HostProofCalc(mbedtls_srp_modulus  userPubKeyA,
+        mbedtls_srp_digest  userProof,
+        mbedtls_srp_sessionKey  sessionKey,
+            mbedtls_srp_digest  hostProof,  // out
+            mbedtls_srp_context     *pCtx);
+
+
+// Sha_interleave
+uint32_t  SRP_SessionKeyCalc(uint8_t        *pInBuff,       /* in buff to hash*/
+               size_t       inBuffSize, /* in buffer size */
+               mbedtls_srp_sessionKey   sessionKey,
+               mbedtls_srp_context  *pCtx);
+
+
+// Secure mem compare comes to prevent timing attacks on pwd comparison.
+uint32_t SRP_SecureMemCmp( const uint8_t* aTarget, /*!< [in] The target buffer to compare. */
+                           const uint8_t* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */);
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/sw_hash_common.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/sw_hash_common.c
new file mode 100644
index 0000000..3784fe6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/cc3x_sym/driver/sw_hash_common.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/********************** Include Files **********************************/
+#include "cc_common_error.h"
+#include "cc_common_math.h"
+
+/************************ Defines **************************************/
+
+/************************ Enums ****************************************/
+
+/************************ Typedefs *************************************/
+
+/************************ Global Data **********************************/
+
+/************* Private function prototype ******************************/
+
+/************************ Public Functions *****************************/
+
+
+/********************************************************************************
+ * @brief This function adds a value to a large counter presented in a buffer.
+ *        The MSB of the counter is stored in the first cell in the array.
+ *
+ *        for example:
+ *
+ *        a counter of 64 bit : the value is :
+ *
+ *        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]
+ *
+ * @param[in] CounterBuff_ptr - The buffer containing the counter.
+ * @param[in] Val             - this value to add.
+ * @param[in] CounterSize      - the counter size in 32bit words.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+
+void HASH_COMMON_IncMsbUnsignedCounter( uint32_t     *CounterBuff_ptr ,
+                    uint32_t      Val,
+                    uint32_t       CounterSize )
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* a value for storing the current counter word value */
+    uint32_t curretCounterWordVal;
+
+    /* loop variable */
+    uint32_t i;
+
+    /* FUNCTION LOGIC */
+    /* .. inversing the counters bytes to a word in little endian format. */
+    /* ------------------------------------------------------------------ */
+    for (i = 0 ; i < CounterSize ; i++)
+        CounterBuff_ptr[i] = CC_COMMON_REVERSE32( CounterBuff_ptr[i] );
+
+    /* .................... initialize local variables .................. */
+    /* ------------------------------------------------------------------ */
+
+    /* initialize the current local counter value to the first word */
+    curretCounterWordVal = CounterBuff_ptr[CounterSize-1];
+
+    /* .................... adding the value to the LSW ................. */
+    /* ------------------------------------------------------------------ */
+
+    /* adding the value to the word */
+    CounterBuff_ptr[CounterSize-1] += Val;
+
+    /* .................... adding the carry to the higher words ........ */
+    /* ------------------------------------------------------------------ */
+
+    /* if there is overflow on the word then handle the upper words */
+    if (curretCounterWordVal > CounterBuff_ptr[CounterSize-1]) {
+        /* adding the carry to the counter loop */
+        i = CounterSize - 2;
+        while (1) {
+            /* set the current word value */
+            curretCounterWordVal = CounterBuff_ptr[i];
+
+            /* adding the carry to the current word */
+            CounterBuff_ptr[i]++;
+
+            /* if there is no overflow on the current word after adding the value
+               exit the loop */
+            if ((curretCounterWordVal < CounterBuff_ptr[i]) || (i == 0)) {
+                break;
+            }
+            i--;
+
+        }/* end of adding the carry loop */
+
+    }/* end of setting the carrier on the upper words */
+
+    /* .. restore the counters bytes order */
+    /* ----------------------------------- */
+
+    for (i = 0 ; i < CounterSize ; i++)
+        CounterBuff_ptr[i] = CC_COMMON_REVERSE32( CounterBuff_ptr[i] );
+
+
+    return;
+
+}/* END OF HASH_COMMON_IncMsbUnsignedCounter */
+
+/********************************************************************************
+ * @brief This function adds a value to a large counter presented in a buffer.
+ *        The LSB of the counter is stored in the first cell in the array.
+ *
+ *        for example:
+ *
+ *        a counter of 64 bit : the value is :
+ *
+ *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
+ *
+ * @param[in] CounterBuff_ptr - The buffer containing the counter.
+ * @param[in] Val             - this value to add.
+ * @param[in] CounterSize      - the counter size in 32bit words.
+ *
+ * @return carry bit from MS word if carry occur
+ *
+ */
+
+uint32_t HASH_COMMON_IncLsbUnsignedCounter(
+                      uint32_t     *CounterBuff_ptr ,
+                      uint32_t      Val,
+                      uint32_t       CounterSize )
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* a value for storing the current counter word value */
+    uint32_t curretCounterWordVal;
+
+    /* loop variable */
+    uint32_t i;
+
+    /* carry bit */
+    uint32_t  carry = 0;
+
+    /* FUNCTION LOGIC */
+
+    /* .................... initialize local variables .................. */
+    /* ------------------------------------------------------------------ */
+
+    /* initialize the current local counter value to the first word */
+    curretCounterWordVal = CounterBuff_ptr[0];
+
+    /* .................... adding the value to the LSW ................. */
+    /* ------------------------------------------------------------------ */
+
+    /* adding the value to the word */
+    CounterBuff_ptr[0] += Val;
+
+    /* .................... adding the carry to the higher words ........ */
+    /* ------------------------------------------------------------------ */
+
+    /* if there is overflow on the word then handle the upper words */
+    if (curretCounterWordVal > CounterBuff_ptr[0]) {
+        /* adding the carry to the counter loop */
+        for (i = 1 ; i < CounterSize ; i++) {
+            /* set the current word value */
+            curretCounterWordVal = CounterBuff_ptr[i];
+
+            /* adding the carry to the current word */
+            CounterBuff_ptr[i]++;
+
+            /* if there is no overflow on the current word after adding the value
+               exit the loop */
+            if (curretCounterWordVal < CounterBuff_ptr[i]) {
+                carry = 0;
+                break;
+            } else
+                carry = 1;
+
+        }/* end of adding the carry loop */
+
+    }/* end of setting the carrier on the upper words */
+
+    return carry;
+
+}/* END OF HASH_COMMON_IncLsbUnsignedCounter */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common.h
new file mode 100644
index 0000000..5cd03d6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_COMMON_H
+#define _CC_COMMON_H
+
+#include "cc_common_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+
+
+/***********************************************************************
+ **
+ * @brief This function executes a reverse bytes copying from one buffer to another buffer.
+ *
+ *        Overlapping of buffers is not allowed, excluding the case, when destination and source
+ *        buffers are the same.
+ *        Example of a 5 byte buffer:
+ *
+ *        dst_ptr[4] = src_ptr[0]
+ *        dst_ptr[3] = src_ptr[1]
+ *        dst_ptr[2] = src_ptr[2]
+ *        dst_ptr[1] = src_ptr[3]
+ *        dst_ptr[0] = src_ptr[4]
+ *
+ * @param[in] dst_ptr - The pointer to destination buffer.
+ * @param[in] src_ptr - The pointer to source buffer.
+ * @param[in] size    - The size in bytes.
+ *
+ */
+ CCError_t CC_CommonReverseMemcpy( uint8_t *dst_ptr , uint8_t *src_ptr , uint32_t size );
+
+
+/***********************************************************************
+ **
+ * @brief This function converts aligned words array to bytes array/
+ *
+ *            1. Assumed, that input buffer is aligned to 4-bytes word and
+ *               bytes order is set according to machine endianness.
+ *            2. Output buffer receives data as bytes stream from LSB to MSB.
+ *               For increasing performance on small buffers, the output data is given
+ *               by rounded down pointer and alignment.
+ *            3. This implementation is given for both Big and Little endian machines.
+ *
+ *
+ * @param[in] in32_ptr - The pointer to aligned input buffer.
+ * @param[in] out32_ptr - The 32-bits pointer to output buffer (rounded down to 4 bytes) .
+ * @param[in] outAlignBits - The actual output data alignment;
+ * @param[in] sizeWords - The size in words (sizeWords >= 1).
+ *
+ *  return - no return value.
+ */
+ void CC_CommonAlignedWordsArrayToBytes( uint32_t *in32_ptr , uint32_t *out32_ptr ,
+                                            uint32_t outAlignBits, uint32_t sizeWords );
+
+/***********************************************************************/
+ /**
+  * @brief This function converts in place words byffer to bytes buffer with
+  *        reversed endianity of output array.
+  *
+  *        The function can convert:
+  *           - big endian bytes array to words array with little endian order
+  *             of words and backward.
+  *
+  *      Note:
+  *      1. Endianness of each word in words buffer should be set allways
+  *      according to processor used.
+  *      2. Implementation is given for both big and little endianness of
+  *      processor.
+  *
+  * @param[in]  buf_ptr - The 32-bits pointer to input/output buffer.
+  * @param[in]  sizeWords - The size in words (sizeWords > 0).
+  *
+  * @return - no return value.
+  */
+void CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(
+                    uint32_t *buf_ptr,
+                    uint32_t  sizeWords);
+
+
+/***********************************************************************/
+  /**
+  * @brief This function converts big endianness bytes array to aligned words
+  *        array with words order according to little endian.
+  *
+  *            1. Assumed, that input bytes order is set according
+  *           to big endianness: MS Byte is most left, i.e. order is from
+  *           Msb to Lsb.
+  *            2. Output words array should set according to
+  *           little endianness words order: LSWord is most left, i.e. order
+  *           is from Lsw to Msw. Order bytes in each word - according to
+  *           processor endianness.
+  *            3. Owerlapping of buffers is not allowed, besides in
+  *           place operation and size aligned to full words.
+  *            4. Implementation is given for both big and little
+  *           endianness of processor.
+  *
+  * @param[out] out32_ptr - The 32-bits pointer to output buffer.
+  * @param[in] sizeOutBuffBytes - The size in bytes of output buffer, must be
+  *            aligned to 4 bytes and not less than inpSizeInBytes.
+  * @param[in] in8_ptr - The pointer to input buffer.
+  * @param[in] inpSizeInBytes - The size in bytes of input data, where
+  *                  0 < inpSizeInBytes < UINT32_MAX - CC_32BIT_WORD_SIZE.
+  *
+  * @return CCError_t - On success CC_OK is returned, on failure a
+  *                        value MODULE_* as defined in .
+  */
+CCError_t CC_CommonConvertMsbLsbBytesToLswMswWords(
+                    uint32_t *out32_ptr,
+                    uint32_t  sizeOutBuffBytes,
+                    const uint8_t  *in8_ptr,
+                    uint32_t  inpSizeInBytes);
+
+
+/***********************************************************************/
+  /**
+  * @brief This function converts LE 32bit-words array to BE bytes array.
+  *
+  *            1. Assumed, that output bytes order is according
+  *           to big endianness: MS Byte is most left, i.e. order is from
+  *           Msb to Lsb.
+  *            2. Input words array should be set according to
+  *           little endianness words order: LSWord is most left, i.e. order
+  *           is from Lsw to Msw. Bytes order in each word - according to
+  *           processor endianness.
+  *            3. Owerlapping of buffers is not allowed, besides in
+  *           place operation and size aligned to full words.
+  *            4. Implementation is given for both big and little
+  *           endianness of processor.
+  *
+  * @param[in] out32_ptr - The 32-bits pointer to output buffer.
+  * @param[in] sizeOutBuffBytes - The size in bytes of output buffer, must be
+  *       not less than sizeInBytes.
+  * @param[out] in8_ptr - The pointer to input buffer.
+  * @param[in] sizeInBytes - The size in bytes. The size must be not 0 and
+  *       aligned to 4 bytes word.
+  *
+  * @return CCError_t - On success CC_OK is returned, on failure a
+  *                        value MODULE_* as defined in .
+  */
+CCError_t CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                    uint8_t  *out8_ptr,
+                    size_t    sizeOutBuffBytes,
+                    uint32_t *in32_ptr,
+                    uint32_t  sizeInBytes);
+
+
+/***********************************************************************/
+/**
+ * @brief VOS_GetGlobalData get the global random key hidden inside the function
+ *  the global data implemented for now are random key buffer and AES secret key buffer
+ *
+ * When no_rtos is declared then we allow a global data. The random key/AES secret key are hidden as static inside the function
+ *
+ *
+ * @param[in] Globalid     select the buffer
+ * @param[in] GlobalDataSizeWords      - the global data buffer size needed in words - this value must be a predetermined value
+ * @param[out] GlobalData_ptr - Pointer to the global buffer returned. The buffer must be at least GlobalDataSizeWords size
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure an Error as defined in VOS_error
+ */
+CCError_t CC_CommonGetGlobalData(uint16_t Globalid, uint32_t *GlobalData_ptr, uint16_t GlobalDataSizeWords);
+
+
+/***********************************************************************/
+/**
+* @brief CC_CommonStoreGlobalData store the global random key into the global buffer hidden inside the function
+*   the global data implemented for now are random key buffer and AES secret key buffer
+*
+*
+* @param[in] Globalid      - random key / AES secret key
+* @param[in] GlobalDataSizeWords       - the global data buffer size needed in words - this value must be a predetermined value
+* @param[in] GlobalData_ptr - Pointer to the global buffer to be saved. The buffer must be at least GlobalDataSizeWords size
+*
+*   Return Value:
+*/
+CCError_t CC_CommonStoreGlobalData(uint16_t Globalid, uint32_t *GlobalData_ptr, uint16_t GlobalDataSizeWords);
+
+
+/***********************************************************************/
+/**
+ * @brief The CC_CommonCutAndSaveEndOfLliData() function saves the data from end of source
+ *        memory, pointed by LLI table, to destination memory, and decreases the LLI table accordingly.
+ *
+ *        The function executes the following major steps:
+ *
+ *        1. Starts copy bytes from last byte of last chunk of source LLI table into
+ *           last byte of destination memory.
+ *        2. Continues copy bytes in reverse order while not completes copying of all amount of data.
+ *        3. If last chunk of source or destination data is not enough, the function crosses
+ *           to next chunk of LLI table.
+ *        4. Decreases the Data size of last updated LLI entry and sets the LAST bit.
+ *        5. Exits with the OK code.
+ *
+ *
+ * @param[in] SrcLliTab_ptr - The pointer to the LLI table, containing pointers and sizes of
+ *                            chunks of source data. The table need to be aligned and placed
+ *                            in SEP SRAM.
+ * @param[in] SrcLliTabSize_ptr -   The pointer to buffer, containing th size of the LLI table in words.
+ * @param[in] Dest_ptr  -  The destination address for copying the data.
+ * @param[in] DataSize  -  The count of bytes to copy.
+ *
+ * @return CCError_t - On success CC_OK is returned,
+ *                     - CC_COMMON_ERROR_IN_SAVING_LLI_DATA_ERROR
+ *
+ * NOTE: 1. Because the function is intended for internal using, it is presumed that all input parameters
+ *          are valid.
+ *       2. Assumed, that copied source not may to take more than two last chunks of source memory.
+ */
+ CCError_t  CC_CommonCutAndSaveEndOfLliData(
+                                         uint32_t   *SrcLliTab_ptr,
+                                         uint32_t   *SrcLliTabSize_ptr,
+                                         uint8_t    *Dst_ptr,
+                                         uint32_t    DataSize);
+
+/***********************************************************************/
+/**
+ * @brief The CC_CommonCutAndSaveBeginOfLliData() function saves the data from beginning of source
+ *        memory, pointed by LLI table, to destination memory, and decreases the LLI table accordingly.
+ *
+ *        The function executes the following major steps:
+ *
+ *        1. Starts copy bytes from first byte of first chunk of source LLI table into
+ *           destination memory.
+ *        2. If first chunk of source is not enough, the function crosses
+ *           to next chunk of LLI table.
+ *        3. Updates LLI table pointer and size according to copied amount of data.
+ *        5. Exits with the OK code.
+ *
+ * @param[in/out] SrcLliTab_ptr_ptr - The pointer to pointer to the LLI table, containing pointers and
+ *                            sizes of the chunks of source data. The table need to be aligned and
+ *                            placed in SRAM.
+ * @param[in/out] SrcLliTabSize_ptr -   The pointer to buffer, containing th size of the LLI table in words.
+ * @param[in] Dest_ptr  -  The destination address for copying the data.
+ * @param[in] DataSize  -  The count of bytes to copy.
+ *
+ * @return - no return value.
+ *
+ * NOTE: 1. Because the function is intended for internal using, it is presumed that all input parameters
+ *          are valid.
+ *       2. Assumed, that copied source not may to take more than two first chunks of source memory.
+ */
+ void  CC_CommonCutAndSaveBeginOfLliData(
+                                         uint32_t  **SrcLliTab_ptr_ptr,
+                                         uint32_t   *SrcLliTabSize_ptr,
+                                         uint8_t    *Dst_ptr,
+                                         uint32_t    DataSize);
+
+/***********************************************************************/
+  /**
+  * @brief This function converts 32-bit words array with little endian
+  *        order of words to bytes array with little endian (LE) order of bytes.
+  *
+  *    Assuming: no buffers overlapping, in/out pointers and sizes not equall to NULL,
+                 the buffer size must be not less, than input data size.
+  *
+  * @param[out] out8Le - The bytes pointer to output buffer.
+  * @param[in] in32Le - The pointer to input 32-bit words buffer.
+  * @param[in] sizeInWords - The size in words of input data (sizeWords >= 0).
+  *
+  * @return CCError_t - On success CC_OK is returned, on failure a
+  *                        value MODULE_* as defined in .
+  */
+void CC_CommonConvertLswMswWordsToLsbMsbBytes(
+                    uint8_t  *out8Le,
+                    const uint32_t *in32Le,
+                    size_t  sizeInWords);
+
+
+/***********************************************************************/
+/**
+ * @brief This function converts bytes array with little endian (LE) order of
+ *        bytes to 32-bit words array with little endian order of words and bytes.
+ *
+ *   Assuming:  No owerlapping of buffers; in/out pointers and sizes are not equall to NULL.
+ *              If is in-place conversion, then the size must be multiple of 4 bytes.
+ * @param[out] out32Le - The 32-bits pointer to output buffer. The buffer size must be
+ *                       not less, than input data size.
+ * @param[in] in8Le - The pointer to input buffer.
+ * @param[in] sizeInBytes - The size in bytes of input data(sizeBytes > 0).
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in .
+ */
+void CC_CommonConvertLsbMsbBytesToLswMswWords(
+                    uint32_t *out32Le,
+                    const uint8_t  *in8Le,
+                    size_t  sizeInBytes);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_conv_endian.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_conv_endian.c
new file mode 100644
index 0000000..d9ef961
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_conv_endian.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_common_error.h"
+#include "cc_pal_mem.h"
+#include "cc_bitops.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ********************************/
+
+/************************ Typedefs *****************************/
+
+/************************ Global Data **************************/
+
+/************* Private function prototype **********************/
+
+/************************ Public Functions *********************/
+
+/***********************************************************************
+ **
+ * @brief This function executes a reverse bytes copying from one buffer to another buffer.
+ *
+ *        Overlapping of buffers is not allowed, excluding the case, when destination and source
+ *        buffers are the same.
+ *        Example of a 5 byte buffer:
+ *
+ *        dst_ptr[4] = src_ptr[0]
+ *        dst_ptr[3] = src_ptr[1]
+ *        dst_ptr[2] = src_ptr[2]
+ *        dst_ptr[1] = src_ptr[3]
+ *        dst_ptr[0] = src_ptr[4]
+ *
+ * @param[in] dst_ptr - The pointer to destination buffer.
+ * @param[in] src_ptr - The pointer to source buffer.
+ * @param[in] size    - The size in bytes.
+ *
+ */
+CCError_t CC_CommonReverseMemcpy( uint8_t *dst_ptr , uint8_t *src_ptr , uint32_t size )
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* loop variable */
+        uint32_t i;
+
+        /* FUNCTION LOGIC */
+
+        /* check overlapping */
+        if ((dst_ptr > src_ptr && dst_ptr < (src_ptr + size)) ||
+            (dst_ptr < src_ptr && (dst_ptr + size) >= src_ptr)) {
+                return CC_COMMON_DATA_OUT_DATA_IN_OVERLAP_ERROR;
+        }
+
+
+        /* execute the reverse copy in case of different buffers */
+        if (dst_ptr != src_ptr) {
+                for (i = 0 ; i < size ; i++)
+                        dst_ptr[i] = src_ptr[size - 1 - i];
+        }
+
+        /* execute the reverse copy in the same place */
+        else {
+                uint8_t  temp;
+
+                for (i = 0; i < size / 2; i++) {
+                        temp = src_ptr[i];
+                        src_ptr[i] = src_ptr[size - 1 - i];
+                        src_ptr[size - 1 - i] = temp;
+                }
+        }
+
+        return CC_OK;
+
+}/* END OF CC_CommonReverseMemcpy */
+
+
+#ifndef DX_OEM_FW
+
+/***********************************************************************/
+/**
+ * @brief This function converts in place words byffer to bytes buffer with
+ *        reversed endianity of output array.
+ *
+ *        The function can convert:
+ *           - big endian bytes array to words array with little endian order
+ *             of words and backward.
+ *
+ *      Note:
+ *      1. Endianness of each word in words buffer should be set allways
+ *      according to processor used.
+ *      2. Implementation is given for both big and little endianness of
+ *      processor.
+ *
+ * @param[in]  buf_ptr - The 32-bits pointer to input/output buffer.
+ * @param[in]  sizeWords - The size in words (sizeWords > 0).
+ *
+ * @return - no return value.
+ */
+void CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(
+                                                        uint32_t *buf_ptr,
+                                                        uint32_t  sizeWords)
+{
+        /* FUNCTION DECLARATIONS */
+
+        uint32_t i, tmp;
+
+        /* FUNCTION logic */
+
+#ifndef BIG__ENDIAN
+        /* If sizeWords is odd revert middle word */
+        if (sizeWords & 1UL) {
+                buf_ptr[sizeWords/2] = CC_COMMON_REVERSE32(buf_ptr[sizeWords/2]);
+        }
+#endif
+
+                /* Reverse order of words and order of bytes in each word.    *
+                *  Note: Condition (sizeWords >= 2) inserted inside for() to  *
+                *        prevent wrong false positive warnings.               *
+                *                                                             */
+                for (i = 0; ((i < sizeWords/2) && (sizeWords >= 2)); i++) {
+#ifndef BIG__ENDIAN
+                        tmp = CC_COMMON_REVERSE32(buf_ptr[i]);
+                        buf_ptr[i] = CC_COMMON_REVERSE32(buf_ptr[sizeWords-i-1]);
+#else
+                        tmp = buf_ptr[i];
+                        buf_ptr[i] = buf_ptr[sizeWords-i-1];
+#endif
+                        buf_ptr[sizeWords-i-1] = tmp;
+                }
+
+        return;
+
+}/* End of CC_CommonInPlaceConvertBytesWordsAndArrayEndianness */
+
+
+/***********************************************************************/
+/**
+* @brief This function converts big endianness bytes array to aligned words
+*        array with words order according to little endian.
+*
+*            1. Assumed, that input bytes order is set according
+*         to big endianness: MS Byte is most left, i.e. order is from
+*         Msb to Lsb.
+*            2. Output words array should set according to
+*         little endianness words order: LSWord is most left, i.e. order
+*         is from Lsw to Msw. Order bytes in each word - according to
+*         processor endianness.
+*            3. Owerlapping of buffers is not allowed, besides in
+*         place operation and size aligned to full words.
+*            4. Implementation is given for both big and little
+*         endianness of processor.
+*
+* @param[out] out32_ptr - The 32-bits pointer to output buffer.
+* @param[in] sizeOutBuffBytes - The size in bytes of output buffer, must be
+*            aligned to 4 bytes and not less than inpSizeInBytes.
+* @param[in] in8_ptr - The pointer to input buffer.
+* @param[in] inpSizeInBytes - The size in bytes of input data, where
+*                  0 < inpSizeInBytes < UINT32_MAX - CC_32BIT_WORD_SIZE.
+*
+* @return CCError_t - On success CC_OK is returned, on failure a
+*                        value MODULE_* as defined in .
+*/
+CCError_t CC_CommonConvertMsbLsbBytesToLswMswWords(
+                                                  uint32_t *out32_ptr,
+                                                  uint32_t  sizeOutBuffBytes,
+                                                  const uint8_t  *in8_ptr,
+                                                  uint32_t  inpSizeInBytes)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* the rounded up size of the input data in bytes */
+        uint32_t roundedInpSizeInBytes;
+
+        /* FUNCTION LOGIC */
+
+        /* Check pointers and size */
+        if ((in8_ptr == NULL) || (out32_ptr == NULL))
+                return CC_COMMON_DATA_IN_POINTER_INVALID_ERROR;
+
+        /*  Check the size and in place operation:       *
+        *   the size must be > 0 and aligned to words    */
+        if ((inpSizeInBytes == 0) || (inpSizeInBytes >= UINT32_MAX - CC_32BIT_WORD_SIZE) ||
+            (sizeOutBuffBytes & 3) || (inpSizeInBytes > sizeOutBuffBytes)) {
+                return CC_COMMON_DATA_SIZE_ILLEGAL;
+        }
+
+        /* Size of input data in words rounded up */
+        roundedInpSizeInBytes = ROUNDUP_BYTES_TO_32BIT_WORD(inpSizeInBytes);
+
+        if (roundedInpSizeInBytes > sizeOutBuffBytes)
+                return CC_COMMON_OUTPUT_BUFF_SIZE_ILLEGAL;
+
+        /*  If the conversion is not "in place" or data size not aligned to
+            words, then copy the data into output buffer and zeroe leading bytes */
+        if (((CCVirtAddr_t)out32_ptr != (CCVirtAddr_t)in8_ptr) || (inpSizeInBytes & 3)) {
+                CC_PalMemMove((uint8_t*)out32_ptr + roundedInpSizeInBytes - inpSizeInBytes, in8_ptr, inpSizeInBytes);
+                /* set leading zeros in output buffer */
+                if (roundedInpSizeInBytes > inpSizeInBytes)
+                        CC_PalMemSetZero((uint8_t*)out32_ptr, roundedInpSizeInBytes - inpSizeInBytes); /*leading zeros*/
+        }
+
+        /* set tailing zeros in output buffer */
+        CC_PalMemSetZero((uint8_t*)out32_ptr + roundedInpSizeInBytes,
+                         sizeOutBuffBytes - roundedInpSizeInBytes); /*tailing zeros*/
+
+        /* Reverse words order and set endianness of each word */
+        CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(out32_ptr, CALC_32BIT_WORDS_FROM_BYTES(inpSizeInBytes));
+
+        return CC_OK;
+}
+
+
+/***********************************************************************/
+/**
+* @brief This function converts LE 32bit-words array to BE bytes array.
+*
+*            1. Assumed, that output bytes order is according
+*         to big endianness: MS Byte is most left, i.e. order is from
+*         Msb to Lsb.
+*            2. Input words array should be set according to
+*         little endianness words order: LSWord is most left, i.e. order
+*         is from Lsw to Msw. Bytes order in each word - according to
+*         processor endianness.
+*            3. Owerlapping of buffers is not allowed, besides in
+*         place operation and size aligned to full words.
+*            4. Implementation is given for both big and little
+*         endianness of processor.
+*
+* @param[in] out32_ptr - The 32-bits pointer to output buffer.
+* @param[in] sizeOutBuffBytes - The size in bytes of output buffer, must be
+*       not less than inpSizeInBytes.
+* @param[out] in8_ptr - The pointer to input buffer.
+* @param[in] sizeInBytes - The size in bytes. The size must be not 0 and
+*       aligned to 4 bytes word.
+*
+* @return CCError_t - On success CC_OK is returned, on failure a
+*                        value MODULE_* as defined in .
+*/
+CCError_t CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                  uint8_t  *out8_ptr,
+                                                  size_t   sizeOutBuffBytes,
+                                                  uint32_t *in32_ptr,
+                                                  uint32_t  sizeInBytes)
+{
+        /* FUNCTION DECLARATIONS */
+
+        uint32_t sizeInWords;
+
+        /* FUNCTION LOGIC */
+
+        /* Check pointers and size */
+        if ((in32_ptr == NULL) || (out8_ptr == NULL))
+                return CC_COMMON_DATA_IN_POINTER_INVALID_ERROR;
+
+        /* Size in words rounded up */
+        sizeInWords = (sizeInBytes + 3) / 4;
+
+        if ((sizeInBytes == 0) || (sizeOutBuffBytes < sizeInBytes))
+                return CC_COMMON_DATA_SIZE_ILLEGAL;
+
+        /* Check in place operation: the size must be aligned to word */
+        if (((CCVirtAddr_t)in32_ptr == (CCVirtAddr_t)out8_ptr) && (sizeInBytes & 3UL))
+                return CC_COMMON_DATA_SIZE_ILLEGAL;
+
+        /* Reverse words order and bytes according to endianness of CPU */
+        CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(in32_ptr, sizeInWords);
+
+        /* Copy output buffer */
+        if ((CCVirtAddr_t)out8_ptr != (CCVirtAddr_t)in32_ptr) {
+
+                /* Check overlapping */
+                if (((CCVirtAddr_t)out8_ptr > (CCVirtAddr_t)in32_ptr && (CCVirtAddr_t)out8_ptr < ((CCVirtAddr_t)in32_ptr + sizeInBytes)) ||
+                    ((CCVirtAddr_t)out8_ptr < (CCVirtAddr_t)in32_ptr && ((CCVirtAddr_t)out8_ptr + sizeInBytes) > (CCVirtAddr_t)in32_ptr))
+                        return CC_COMMON_DATA_OUT_DATA_IN_OVERLAP_ERROR;
+
+                CC_PalMemCopy(out8_ptr, (uint8_t *)in32_ptr + ((4 - (sizeInBytes & 3UL)) & 3UL), sizeInBytes);
+                /* Revert the input buffer to previous state */
+                CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(in32_ptr, sizeInWords);
+        }
+
+        return CC_OK;
+}
+
+
+/***********************************************************************/
+/**
+ * @brief This function converts bytes array with little endian (LE) order of
+ *        bytes to 32-bit words array with little endian order of words and bytes.
+ *
+ *   Assuming:  No owerlapping of buffers; in/out pointers and sizes are not equall to NULL.
+ *              If is in-place conversion, then the size must be multiple of 4 bytes.
+ * @param[out] out32Le - The 32-bits pointer to output buffer. The buffer size must be
+ *                       not less, than input data size.
+ * @param[in] in8Le - The pointer to input buffer.
+ * @param[in] sizeInBytes - The size in bytes of input data(sizeBytes > 0).
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in .
+ */
+void CC_CommonConvertLsbMsbBytesToLswMswWords(
+                                             uint32_t *out32Le,
+                                             const uint8_t  *in8Le,
+                                             size_t  sizeInBytes)
+{
+
+        uint32_t sizeInWords;
+
+        /* Size in words rounded up */
+        sizeInWords = (sizeInBytes + 3)/4;
+
+        /* if not in place, then zero empty bytes of MS word and copy data */
+        if ((uint8_t*)out32Le != in8Le) {
+                out32Le[sizeInWords-1] = 0;
+                CC_PalMemCopy((uint8_t*)out32Le, in8Le, sizeInBytes);
+        }
+
+#ifdef BIG__ENDIAN
+        /* Reverse endianness of each word */
+        {
+                uint32_t i;
+                for (i = 0; i < sizeInWords; i++) {
+                        CC_COMMON_REVERSE32(out32Le[i]);
+                }
+        }
+#endif
+        return;
+}
+
+/***********************************************************************/
+/**
+* @brief This function converts 32-bit words array with little endian
+*        order of words to bytes array with little endian (LE) order of bytes.
+*
+*    Assuming: no buffers overlapping, in/out pointers and sizes not equall to NULL,
+               the buffer size must be not less, than input data size.
+*
+* @param[out] out8Le - The bytes pointer to output buffer.
+* @param[in] in32Le - The pointer to input 32-bit words buffer.
+* @param[in] sizeInWords - The size in words of input data (sizeWords >= 0).
+*
+* @return CCError_t - On success CC_OK is returned, on failure a
+*                        value MODULE_* as defined in .
+*/
+void CC_CommonConvertLswMswWordsToLsbMsbBytes(
+                                             uint8_t *out8Le,
+                                             const uint32_t  *in32Le,
+                                             size_t  sizeInWords)
+{
+        /* FUNCTION LOGIC */
+
+#ifndef BIG__ENDIAN
+        if (out8Le != (uint8_t*)in32Le) {
+                CC_PalMemCopy(out8Le, (uint8_t*)in32Le, sizeInWords*sizeof(uint32_t));
+        }
+#else
+        /* Reverse endianness of each word and copy it to output */
+        size_t i;
+
+        for (i = 0; i < sizeInWords; i++) {
+                if (out8Le != (uint8_t*)in32Le) {
+                        uint32_t tmp;
+                        tmp = in32Le[i / sizeof(uint32_t)];
+                        CC_COMMON_REVERSE32(tmp);
+                        out8Le[i*sizeof(uint32_t) + 0] = tmp & 0xFF;
+                        out8Le[i*sizeof(uint32_t) + 1] = (tmp >>  8) & 0xFF;
+                        out8Le[i*sizeof(uint32_t) + 2] = (tmp >> 16) & 0xFF;
+                        out8Le[i*sizeof(uint32_t) + 3] = (tmp >> 24) & 0xFF;
+                } else {
+                        CC_COMMON_REVERSE32(in32Le[i]);
+                }
+        }
+
+#endif
+        return;
+}
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_error.h
new file mode 100644
index 0000000..b5d4f0c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_error.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_COMMON_ERROR_H
+#define _CC_COMMON_ERROR_H
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* CC COMMON module errors. Base address - 0x00F00D00 */
+
+#define CC_COMMON_INIT_HW_SEM_CREATION_FAILURE    (CC_COMMON_MODULE_ERROR_BASE + 0x0UL)
+#define CC_COMMON_DATA_IN_POINTER_INVALID_ERROR   (CC_COMMON_MODULE_ERROR_BASE + 0x4UL)
+#define CC_COMMON_DATA_SIZE_ILLEGAL         (CC_COMMON_MODULE_ERROR_BASE + 0x5UL)
+#define CC_COMMON_DATA_OUT_DATA_IN_OVERLAP_ERROR  (CC_COMMON_MODULE_ERROR_BASE + 0x6UL)
+#define CC_COMMON_DATA_OUT_POINTER_INVALID_ERROR  (CC_COMMON_MODULE_ERROR_BASE + 0x7UL)
+#define CC_COMMON_OUTPUT_BUFF_SIZE_ILLEGAL      (CC_COMMON_MODULE_ERROR_BASE + 0x9UL)
+
+#define CC_COMMON_TST_UTIL_CHUNK_SIZE_SMALL_ERROR (CC_COMMON_MODULE_ERROR_BASE + 0x10UL)
+#define CC_COMMON_ERROR_IN_SAVING_LLI_DATA_ERROR  (CC_COMMON_MODULE_ERROR_BASE + 0x11UL)
+
+
+#define CC_COMMON_TST_UTIL_LLI_ENTRY_SIZE_TOO_SMALL_ERROR   (CC_COMMON_MODULE_ERROR_BASE + 0x12UL)
+#define CC_COMMON_TST_CSI_DATA_SIZE_EXCEED_ERROR            (CC_COMMON_MODULE_ERROR_BASE + 0x13UL)
+#define CC_COMMON_TST_CSI_MODULE_ID_OUT_OF_RANGE            (CC_COMMON_MODULE_ERROR_BASE + 0x14UL)
+#define CC_COMMON_TST_CSI_MEMORY_MAPPING_ERROR              (CC_COMMON_MODULE_ERROR_BASE + 0x15UL)
+
+#define CC_COMMON_TERM_HW_SEM_DELETE_FAILURE                (CC_COMMON_MODULE_ERROR_BASE + 0x16UL)
+
+#define CC_COMMON_TST_UTIL_NOT_INTEGER_CHAR_ERROR           (CC_COMMON_MODULE_ERROR_BASE + 0x17UL)
+#define CC_COMMON_TST_UTIL_BUFFER_IS_SMALL_ERROR            (CC_COMMON_MODULE_ERROR_BASE + 0x18UL)
+#define CC_COMMON_POINTER_NOT_ALIGNED_ERROR                 (CC_COMMON_MODULE_ERROR_BASE + 0x19UL)
+
+
+/************************ Enums ********************************/
+
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+
+
+/************************ Public Variables **********************/
+
+
+/************************ Public Functions **********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_math.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_math.c
new file mode 100644
index 0000000..8dd761a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_math.c
@@ -0,0 +1,1025 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/********************** Include Files **********************************/
+
+#include "cc_common_math.h"
+#include "cc_common_error.h"
+
+/************************ Defines **************************************/
+
+/************************ Enums ****************************************/
+
+/************************ Typedefs *************************************/
+
+/************************ Global Data **********************************/
+
+/************* Private function prototype ******************************/
+
+/************************ Public Functions *****************************/
+
+#ifndef DX_OEM_FW
+/********************************************************************************
+ * @brief This function adds a value to a large counter presented in a buffer.
+ *        The MSB of the counter is stored in the first cell in the array.
+ *
+ *        for example:
+ *
+ *        a counter of 64 bit : the value is :
+ *
+ *        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]
+ *
+ * @param[in] CounterBuff_ptr - The buffer containing the counter.
+ * @param[in] Val             - this value to add.
+ * @param[in] CounterSize      - the counter size in 32bit words.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+
+void CC_CommonIncMsbUnsignedCounter( uint32_t     *CounterBuff_ptr ,
+                    uint32_t      Val,
+                    uint32_t      CounterSize )
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* a value for storing the current counter word value */
+    uint32_t curretCounterWordVal;
+
+    /* loop variable */
+    uint32_t i;
+
+    /* FUNCTION LOGIC */
+
+    /* .. inversing the counters bytes to a word in little endian format. */
+    /* ------------------------------------------------------------------ */
+    for (i = 0 ; i < CounterSize ; i++)
+        CounterBuff_ptr[i] = CC_COMMON_REVERSE32( CounterBuff_ptr[i] );
+
+    /* .................... initialize local variables .................. */
+    /* ------------------------------------------------------------------ */
+
+    /* initialize the current local counter value to the first word */
+    curretCounterWordVal = CounterBuff_ptr[CounterSize-1];
+
+    /* .................... adding the value to the LSW ................. */
+    /* ------------------------------------------------------------------ */
+
+    /* adding the value to the word */
+    CounterBuff_ptr[CounterSize-1] += Val;
+
+    /* .................... adding the carry to the higher words ........ */
+    /* ------------------------------------------------------------------ */
+
+    /* if there is overflow on the word then handle the upper words */
+    if (curretCounterWordVal > CounterBuff_ptr[CounterSize-1]) {
+        /* adding the carry to the counter loop */
+        i = CounterSize - 2;
+        while (1) {
+            /* set the current word value */
+            curretCounterWordVal = CounterBuff_ptr[i];
+
+            /* adding the carry to the current word */
+            CounterBuff_ptr[i]++;
+
+            /* if there is no overflow on the current word after adding the value
+               exit the loop */
+            if ((curretCounterWordVal < CounterBuff_ptr[i]) || (i == 0)){
+                break;
+            }
+            i--;
+
+        }/* end of adding the carry loop */
+
+    }/* end of setting the carrier on the upper words */
+
+    /* .. restore the counters bytes order */
+    /* ----------------------------------- */
+
+    for (i = 0 ; i < CounterSize ; i++)
+        CounterBuff_ptr[i] = CC_COMMON_REVERSE32( CounterBuff_ptr[i] );
+
+
+    return;
+
+}/* END OF CC_CommonIncMsbUnsignedCounter */
+
+/********************************************************************************
+ * @brief This function adds a value to a large counter presented in a buffer.
+ *        The LS word of the counter is stored in the first cell in the array.
+ *
+ *        for example: a counter of 64 bit : the value is :
+ *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
+ *
+ * @param[in] pCounterBuff - The buffer containing the counter.
+ * @param[in] val          - this value to add.
+ * @param[in] counterSize  - the counter size in 32bit words.
+ *
+ * @return Carry from MS word if occurs
+ *
+ */
+uint32_t CC_CommonIncLsbUnsignedCounter(
+                      uint32_t     *pCounterBuff,
+                      uint32_t      val,
+                      uint32_t      counterSize )
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    /* a value for storing the current counter word value */
+    uint32_t currCounterVal;
+    /* loop variable */
+    uint32_t i;
+
+    for (i = 0; i < counterSize; i++) {
+        currCounterVal = pCounterBuff[i];
+        pCounterBuff[i] += val;
+        val = (currCounterVal > pCounterBuff[i]) ? 1 : 0;
+    }
+
+    return val;
+
+}/* END OF CC_CommonIncLsbUnsignedCounter */
+
+
+/********************************************************************************
+ * @brief This function subtracts a value from a large counter presented in a first
+ *        buffer and sets result in a second buffer. The first and the second
+ *        buffers may be the same.
+ *        The LSB of the counter is stored in the first cell in the array,
+ *
+ * @param[in]  CounterBuff_ptr - the buffer containing the counter.
+ * @param[in]  Val             - the value to subtract.
+ * @param[in]  CounterSize      - the counter size in 32bit words.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+
+void CC_CommonDecrLsbUnsignedCounter( uint32_t     *CounterBuff_ptr,
+                     uint32_t      Val,
+                     uint32_t      CounterSizeInWords )
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* borrow and temp word */
+    uint32_t borrow, temp;
+
+    /* loop variable */
+    uint32_t i;
+
+    /* FUNCTION LOGIC */
+
+    /* .................... initialize local variables .................. */
+    /* ------------------------------------------------------------------ */
+
+    /* initialize the borrow to Val */
+    borrow = Val;
+
+    /* Subtracting loop */
+    for (i = 0 ; i < CounterSizeInWords ; i++) {
+        temp = CounterBuff_ptr[i];
+
+        CounterBuff_ptr[i] = CounterBuff_ptr[i] - borrow;
+
+        if (CounterBuff_ptr[i] > temp)
+            borrow = 1;
+        else
+            break;
+    }
+
+    return;
+
+}/* END OF CC_CommonDecrLsbUnsignedCounter */
+
+
+/********************************************************************************
+ * @brief This function compares a value of 2 large counters presented in a byte buffer.
+ *        The MSB of the counter is stored in the first cell in the array.
+ *
+ *        for example:
+ *
+ *        a counter of 64 bit : the value is :
+ *
+ *        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]
+ *
+ *
+ * @param[in] CounterBuff1_ptr - The first counter buffer.
+ * @param[in] Counter1Size     - the first counter size in bytes.
+ * @param[in] CounterBuff2_ptr - The second counter buffer.
+ * @param[in] Counter2Size     - the second counter size in bytes.
+ * @param[in] SizeUnit         - the size units. 0 - bits , 1 - bytes
+ *
+ * @return result - an enum with the compare result:
+ *                                0 - both counters are identical
+ *                                1 - counter 1 is larger.
+ *                                2 - counter 2 is larger.
+ * @note This code executes in constant time, regardless of the arguments.
+ */
+
+CCCommonCmpCounter_t CC_CommonCmpMsbUnsignedCounters( const uint8_t  *CounterBuff1_ptr,
+                                 uint32_t  Counter1Size,
+                                 const uint8_t  *CounterBuff2_ptr,
+                                 uint32_t Counter2Size )
+{
+
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* loop variable */
+    int32_t StartInd1,StartInd2;
+    uint32_t i;
+
+    /* the result after comparing the bytes */
+    CCCommonCmpCounter_t Result;
+
+    /* the final result */
+    CCCommonCmpCounter_t FinalResult;
+
+    /* FUNCTION LOGIC */
+
+    /* ........ initialize local variables ............................................ */
+    /* -------------------------------------------------------------------------------- */
+
+    /* the default is that the result is the same */
+    Result = CC_COMMON_CmpCounter1AndCounter2AreIdentical;
+    FinalResult = CC_COMMON_CmpCounter1AndCounter2AreIdentical; /* just to avoid compilers warnings */
+
+    /* ........ calculate the effective size ( decrementing the zeros at the MS bytes ) */
+    /* -------------------------------------------------------------------------------- */
+
+    StartInd1=0,StartInd2=0;
+    /* a loop for adjusting the counter 1 size by neglecting the zeros */
+    while (Counter1Size && (CounterBuff1_ptr[StartInd1] == 0)) {
+        StartInd1++;
+        Counter1Size--;
+    }
+    /* a loop for adjusting the counter 2 size by neglecting the zeros */
+    while (Counter2Size && (CounterBuff2_ptr[StartInd2] == 0)) {
+        StartInd2++;
+        Counter2Size--;
+    }
+
+    /* ....... step 1 : comparing the counters assuming the effective counter size is the same .......... */
+    /* -------------------------------------------------------------------------------------------------- */
+
+    /* for security reasons we shall execute this loop as the minimum between the counter sizes
+       the result will be neglected in steps 2,3 if the actual size is different */
+
+    /* we shall compare all of the bytes from the MSB , the first one that is different
+       will determine which counter is larger , if all of the bytes are equal then the counters are equal */
+
+    /* loop for checking all of the bytes */
+    for (i=0 ; i < CC_MIN(Counter1Size, Counter2Size) ; i++) {
+        /* if the counter 1 byte is grater then counter 2 byte - return counter 1 is bigger */
+        if ((CounterBuff1_ptr[StartInd1 + i] > CounterBuff2_ptr[StartInd2 + i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
+
+            Result = CC_COMMON_CmpCounter1GreaterThenCounter2;
+
+        /* if the counter 2 byte is grater then counter 1 byte - return counter 2 is bigger */
+        if ((CounterBuff2_ptr[StartInd2 + i] > CounterBuff1_ptr[StartInd1 + i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
+
+            Result = CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    }/* end of searching all of the bytes loop */
+
+    /* ....... STEP 2 : the counter 1 effective size is bigger then counter 2 effective size */
+    /* ------------------------------------------------------------------------------------- */
+
+    /* on this case the final result is then counter 1 is larger then counter 2 - neglecting the
+       result calculated in step 1 */
+    if (Counter1Size > Counter2Size)
+
+        FinalResult = CC_COMMON_CmpCounter1GreaterThenCounter2;
+
+    /* ....... STEP 3 : the counter 2 effective size is bigger then counter 1 effective size */
+    /* ------------------------------------------------------------------------------------- */
+
+    /* on this case the final result is then counter 2 is larger then counter 1 - neglecting the
+      result calculated in step 1 */
+    if (Counter2Size > Counter1Size)
+
+        FinalResult = CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    /* ....... STEP 4 : the counter 1 effective size is the same as the counter 2 effective size */
+    /* ----------------------------------------------------------------------------------------- */
+
+    /* on this case the final result is the one calculated in STEP 1 */
+    if (Counter2Size == Counter1Size)
+
+        FinalResult = Result;
+
+    /* return the final result */
+
+    return FinalResult;
+
+} /* end CC_CommonCmpMsbUnsignedCounters */
+
+
+#endif
+
+
+/********************************************************************************
+ * @brief This function compares a value of 2 large counter presented in a byte buffer.
+ *        The LSB of the counter is stored in the first cell in the array.
+ *
+ *        for example:
+ *
+ *        a counter of 64 bit : the value is :
+ *
+ *        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
+ *
+ * @param[in] CounterBuff1_ptr - The first counter buffer.
+ * @param[in] Counter1Size     - the first counter size in bytes.
+ * @param[in] CounterBuff2_ptr - The second counter buffer.
+ * @param[in] Counter2Size     - the second counter size in bytes.
+ *
+ * @return result - an enum with the compare result:
+ *                                0 - both counters are identical
+ *                                1 - counter 1 is larger.
+ *                                2 - counter 2 is larger.
+ */
+
+CCCommonCmpCounter_t CC_CommonCmpLsbUnsignedCounters( const uint8_t  *CounterBuff1_ptr,
+                                 size_t  Counter1Size,
+                                 const uint8_t  *CounterBuff2_ptr,
+                                 size_t Counter2Size )
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* loop variable */
+    int32_t i;
+
+    /* the result after comparing the bytes */
+    CCCommonCmpCounter_t Result;
+
+    /* the final result */
+    CCCommonCmpCounter_t FinalResult;
+
+    /* FUNCTION LOGIC */
+
+    /* ........ initialize local variables ............................................ */
+    /* -------------------------------------------------------------------------------- */
+
+    /* the default is that the result is the same */
+    Result = CC_COMMON_CmpCounter1AndCounter2AreIdentical;
+    FinalResult = CC_COMMON_CmpCounter1AndCounter2AreIdentical; /* just to avoid compilers warnings */
+
+    /* STEP 1 : calculate the effective size (decrementing the zeros at the MS bytes) */
+    /* ------------------------------------------------------------------------------ */
+
+    /* a loop for adjusting the counter 1 size by neglecting the zeros */
+    while (Counter1Size != 0) {
+        if (CounterBuff1_ptr[Counter1Size - 1] == 0)
+            Counter1Size--;
+        else
+            break;
+    }
+
+
+    /* a loop for adjusting the counter 2 size by neglecting the zeros */
+    while (Counter2Size != 0) {
+        if (CounterBuff2_ptr[Counter2Size - 1] == 0)
+            Counter2Size--;
+        else
+            break;
+    }
+
+    /* check the sizes */
+    if (Counter1Size == 0 && Counter2Size == 0)
+        return CC_COMMON_CmpCounter1AndCounter2AreIdentical;
+    else if (Counter1Size > Counter2Size)
+        return CC_COMMON_CmpCounter1GreaterThenCounter2;
+    else if (Counter2Size > Counter1Size)
+        return CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    /* step 2 : comparing the counters assuming the effective counter size is the same */
+    /* ------------------------------------------------------------------------------- */
+
+    /* for security reasons we shall execute this loop as the minimum between the counter sizes
+      the result will be neglected in steps 2,3 if the actual size is different */
+
+    /* we shall compare all of the bytes from the MSB , the first one that is different
+       will determine which counter is larger , if all of the bytes are equal then the counters are equal */
+
+    /* loop for checking all of the bytes */
+    for (i = CC_MIN(Counter1Size - 1,Counter2Size - 1) ; i >= 0 ; i--) {
+        /* if the counter 1 byte is grater then counter 2 byte - return counter 1 is bigger */
+        if ((CounterBuff1_ptr[i] > CounterBuff2_ptr[i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
+            Result = CC_COMMON_CmpCounter1GreaterThenCounter2;
+
+        /* if the counter 2 byte is grater then counter 1 byte - return counter 2 is bigger */
+        if ((CounterBuff2_ptr[i] > CounterBuff1_ptr[i]) && Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
+            Result = CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    }/* end of searching all of the bytes loop */
+
+    /* STEP 3 : the counter 1 effective size is bigger then counter 2 effective size */
+    /* ----------------------------------------------------------------------------- */
+
+    /* on this case the final result is then counter 1 is larger then counter 2 - neglecting the
+       result calculated in step 1 */
+    if (Counter1Size > Counter2Size)
+        FinalResult = CC_COMMON_CmpCounter1GreaterThenCounter2;
+
+    /* STEP 4 : the counter 2 effective size is bigger then counter 1 effective size */
+    /* ----------------------------------------------------------------------------- */
+
+    /* on this case the final result is then counter 2 is larger then counter 1 - neglecting the
+      result calculated in step 1 */
+    if (Counter2Size > Counter1Size)
+        FinalResult = CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    /* ....... STEP 4 : the counter 1 effective size is the same as the counter 2 effective size */
+    /* ----------------------------------------------------------------------------------------- */
+
+    /* on this case the final result is the one calculated in STEP 1 */
+    if (Counter2Size == Counter1Size)
+        FinalResult = Result;
+
+    /* return the final result */
+    return FinalResult;
+
+}/* END OF CC_CommonCmpLsbUnsignedCounters */
+
+
+
+/**************************************************************************
+ *           CC_CommonCmpLsWordsUnsignedCounters function         *
+ **************************************************************************/
+/**
+ * @brief This function compares a value of 2 large counter presented in a word buffer.
+ *        The LSWord of the counters is stored in the first cell in the array.
+ *
+ *
+ * @param[in] CounterBuff1_ptr - The first counter buffer.
+ * @param[in] Counter1SizeWords     - the first counter size in Words.
+ * @param[in] CounterBuff2_ptr - The second counter buffer.
+ * @param[in] Counter2SizeWords     - the second counter size in Words.
+ *
+ * @return result - an enum with the compare result:
+ *                                0 - both counters are identical
+ *                                1 - counter 1 is larger.
+ *                                2 - counter 2 is larger.
+ */
+CCCommonCmpCounter_t CC_CommonCmpLsWordsUnsignedCounters(const uint32_t  *CounterBuff1_ptr,
+                                uint32_t   Counter1SizeWords,
+                                const uint32_t  *CounterBuff2_ptr,
+                                uint32_t   Counter2SizeWords)
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    /* loop variable */
+    int32_t i;
+
+    /* the result after comparing the bytes */
+    CCCommonCmpCounter_t Result;
+
+    /* the final result */
+    CCCommonCmpCounter_t FinalResult;
+
+    /* FUNCTION LOGIC */
+
+    /* ........ initialize local variables ............................................ */
+    /* -------------------------------------------------------------------------------- */
+
+    /* the default is that the result is the same */
+    Result = CC_COMMON_CmpCounter1AndCounter2AreIdentical;
+    FinalResult = CC_COMMON_CmpCounter1AndCounter2AreIdentical; /* just to avoid compilers warnings */
+
+    /* ........ calculate the effective size ( decrementing the zeros at the MS bytes ) */
+    /* -------------------------------------------------------------------------------- */
+
+    /* a loop for adjusting the counter 1 size by neglecting the zeros */
+    while (Counter1SizeWords != 0) {
+        if (CounterBuff1_ptr[Counter1SizeWords - 1] == 0)
+            Counter1SizeWords--;
+        else
+            break;
+    }
+
+    /* a loop for adjusting the counter 2 size by neglecting the zeros */
+    while (Counter2SizeWords != 0) {
+        if (CounterBuff2_ptr[Counter2SizeWords - 1] == 0)
+            Counter2SizeWords--;
+        else
+            break;
+    }
+
+    /* check the sizes */
+    if (Counter1SizeWords == 0 && Counter2SizeWords == 0)
+        return CC_COMMON_CmpCounter1AndCounter2AreIdentical;
+    else if (Counter1SizeWords > Counter2SizeWords)
+        return CC_COMMON_CmpCounter1GreaterThenCounter2;
+    else if (Counter2SizeWords > Counter1SizeWords)
+        return CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    /* ....... step 1 : comparing the counters assuming the effective counter size is the same .......... */
+    /* -------------------------------------------------------------------------------------------------- */
+
+    /* for security reasons we shall execute this loop as the minimum between the counter sizes
+       the result will be neglected in steps 2,3 if the actual size is different */
+
+    /* we shall compare all of the bytes from the MSB , the first one that is different
+       will determine which counter is larger , if all of the bytes are equal then the counters are equal */
+
+    /* loop for checking all of the bytes */
+    for (i = CC_MIN(Counter1SizeWords - 1, Counter2SizeWords - 1) ; i >= 0 ; i--) {
+        /* if the counter 1 byte is grater then counter 2 byte - return counter 1 is bigger */
+        if ((CounterBuff1_ptr[i] > CounterBuff2_ptr[i]) && (Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical))
+            Result = CC_COMMON_CmpCounter1GreaterThenCounter2;
+
+        /* if the counter 2 byte is grater then counter 1 byte - return counter 2 is bigger */
+        if ((CounterBuff2_ptr[i] > CounterBuff1_ptr[i]) && (Result == CC_COMMON_CmpCounter1AndCounter2AreIdentical))
+            Result = CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    }/* end of searching all of the bytes loop */
+
+    /* ....... STEP 2 : the counter 1 effective size is bigger then counter 2 effective size */
+    /* ------------------------------------------------------------------------------------- */
+
+    /* on this case the final result is then counter 1 is larger then counter 2 - neglecting the
+       result calculated in step 1 */
+    if (Counter1SizeWords > Counter2SizeWords)
+        FinalResult = CC_COMMON_CmpCounter1GreaterThenCounter2;
+
+    /* ....... STEP 3 : the counter 2 effective size is bigger then counter 1 effective size */
+    /* ------------------------------------------------------------------------------------- */
+
+    /* on this case the final result is then counter 2 is larger then counter 1 - neglecting the
+      result calculated in step 1 */
+    if (Counter2SizeWords > Counter1SizeWords)
+        FinalResult = CC_COMMON_CmpCounter2GreaterThenCounter1;
+
+    /* ....... STEP 4 : the counter 1 effective size is the same as the counter 2 effective size */
+    /* ----------------------------------------------------------------------------------------- */
+
+    /* on this case the final result is the one calculated in STEP 1 */
+    if (Counter2SizeWords == Counter1SizeWords)
+        FinalResult = Result;
+
+    /* return the final result */
+    return FinalResult;
+
+}
+
+
+
+/*******************************************************************************
+ *             CC_CommonGetBytesCounterEffectiveSizeInBits                  *
+ *******************************************************************************
+ *
+ * @brief This function returns the effective number of bits in the byte stream counter
+ *        ( searching the highest '1' in the counter )
+ *
+ *        The function has one implementations: for little and big endian machines.
+ *
+ *        Assumed, that LSB of the counter is stored in the first cell in the array.
+ *         For example, the value of the 8-Bytes counter B is :
+ *             B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0] .
+ *
+ *
+ * @param[in] CounterBuff_ptr -  The counter buffer.
+ * @param[in] CounterSize     -  the counter size in bytes.
+ *
+ * @return result - The effective counters size in bits.
+ */
+
+uint32_t CC_CommonGetBytesCounterEffectiveSizeInBits( const uint8_t  *CounterBuff_ptr,
+                             uint32_t  CounterSize )
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* loop variable */
+    int32_t i;
+
+    /* the effective size in bits */
+    uint32_t CounterEffectiveSizeInBits;
+
+    /* the effective MS byte ( the one that is not zero ) */
+    uint8_t EffectiveMsByteVal;
+
+    /* FUNCTION LOGIC */
+
+    /* STEP1 : a loop for adjusting the counter size by neglecting the MSB zeros */
+    while (CounterSize != 0) {
+        if (CounterBuff_ptr[CounterSize - 1] == 0)
+            CounterSize--;
+        else
+            break;
+    }
+
+    /* STEP2 : if counter size is 0 - return 0 */
+    if (CounterSize == 0)
+        return 0;
+
+    /* set the effective MS byte */
+    EffectiveMsByteVal = CounterBuff_ptr[CounterSize - 1];
+
+    /* initialize the effective size as the counters size ( with MSB zeros ) */
+    CounterEffectiveSizeInBits = CounterSize * 8;
+
+    /* STEP 3 : adjusting the effective size in bits */
+    for (i = 0; i < 8 ; i++) {
+        if (EffectiveMsByteVal & 0x80)
+            break;
+
+        CounterEffectiveSizeInBits--;
+        EffectiveMsByteVal <<= 1;
+
+    }/* end of adjusting the effective size in bits loop */
+
+    return CounterEffectiveSizeInBits;
+
+}/* END OF CC_CommonGetBytesCounterEffectiveSizeInBits */
+
+
+#ifndef DX_OEM_FW
+
+/*******************************************************************************
+ *             CC_CommonGetWordsCounterEffectiveSizeInBits                  *
+ *******************************************************************************
+ *
+ * @brief This function returns the effective number of bits in the words array
+ *        ( searching the highest '1' in the counter )
+ *
+ *        The function may works on little and big endian machines.
+ *
+ *        Assumed, that the words in array are ordered from LS word to MS word.
+ *        For LITTLE Endian machines assumed, that LSB of the each word is stored in the first
+ *        cell in the word. For example, the value of the 8-Bytes (B) counter is :
+ *             B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0]
+ *
+ *        For BIG Endian machines assumed, that MS byte of each word is stored in the first
+ *        cell, LS byte is stored in the last place of the word.
+ *        For example, the value of the 64 bit counter is :
+ *         B[3] << 56 | B[2] << 48 B[1] << 8 | B[0],  B[7]<<56 | B[6]<<48 | B[5]<<8 | B[4]
+ *
+ *     NOTE !!: 1. For BIG Endian the counter buffer and its size must be aligned to 4-bytes word.
+ *
+ * @param[in] CounterBuff_ptr   -  The counter buffer.
+ * @param[in] CounterSizeWords  -  The counter size in words.
+ *
+ * @return result - The effective counters size in bits.
+ *
+ */
+uint32_t CC_CommonGetWordsCounterEffectiveSizeInBits( const uint32_t  *CounterBuff_ptr,
+                             uint32_t   CounterSizeWords)
+{
+
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    /* loop variable */
+    int32_t i;
+
+    /* the effective size in bits */
+    uint32_t CounterEffectiveSizeInBits = 0;
+
+    /* the  MS word ( the first, that is not zero ) */
+    uint32_t MsWordVal = 0;
+
+
+    /* FUNCTION LOGIC */
+
+    /* STEP1 : a loop for adjusting the counter size by neglecting the MSW zeros */
+    while (CounterSizeWords != 0) {
+        if (CounterBuff_ptr[CounterSizeWords - 1] == 0)
+            CounterSizeWords--;
+        else
+            break;
+    }
+
+    /* STEP2 : if counter size is 0 - return 0 */
+    if (CounterSizeWords == 0)
+        return 0;
+
+    /* set the effective MS word and bit-size */
+    MsWordVal = CounterBuff_ptr[CounterSizeWords - 1];
+    CounterEffectiveSizeInBits = 32*CounterSizeWords;
+
+    /* STEP 3 : adjusting the effective size in bits */
+    for (i = 0; i < 32 ; i++) {
+        if (MsWordVal & 0x80000000)
+            break;
+
+        CounterEffectiveSizeInBits--;
+        MsWordVal <<= 1;
+
+    }/* end of adjusting the effective size in bits loop */
+
+
+    return CounterEffectiveSizeInBits;
+
+}/* END OF CC_CommonGetWordsCounterEffectiveSizeInBits */
+
+
+/********************************************************************************
+ * @brief This function divides a vector by 2 - in a secured way
+ *
+ *        The LSB of the vector is stored in the first cell in the array.
+ *
+ *        for example:
+ *
+ *        a vector of 128 bit : the value is :
+ *
+ *        word[3] << 96 | word[2] << 64 ............ word[1] << 32 | word[0]
+ *
+ * @param[in] VecBuff_ptr     -  The vector buffer.
+ * @param[in] SizeInWords     -  the counter size in words.
+ *
+ * @return result - no return value.
+ */
+
+void CC_CommonDivideVectorBy2(uint32_t *VecBuff_ptr,uint32_t SizeInWords)
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    uint32_t i;
+    uint32_t Temp;
+
+    /* FUNCTION LOGIC */
+
+    /* for loop for dividing the vectors arrays by 2 */
+    for (i=0;i < (SizeInWords)-1 ;i++) {
+        VecBuff_ptr[i]=VecBuff_ptr[i] >> 1;
+        Temp=VecBuff_ptr[i+1]&1UL;
+        VecBuff_ptr[i]=VecBuff_ptr[i] | Temp<<(32-1);
+    }
+
+    /* dividing the MS word */
+    VecBuff_ptr[SizeInWords-1]=VecBuff_ptr[SizeInWords-1]>>1;
+
+    return;
+
+}/* END OF CC_CommonDivideVectorBy2 */
+
+
+/********************************************************************************
+ * @brief This function shifts left a big endian vector by Shift - bits (Shift < 8).
+ *
+ *        The MSB of the vector is stored in the first cell in the array,
+ *
+ *        For example, a vector of 128 bit is :
+ *
+ *        byte[n-1] | byte[n-2] ... byte[1] | byte[0]
+ *
+ * @param[in] VecBuff_ptr     -  The vector buffer.
+ * @param[in] SizeInBytes     -  The counter size in bytes.
+ * @param[in] Shift           -  The number of shift left bits, must be < 8.
+ * @return no return value.
+ */
+
+void CC_CommonShiftLeftBigEndVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift)
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    uint32_t i;
+    uint32_t Temp = 0;
+
+
+    /* FUNCTION LOGIC */
+
+    if (SizeInBytes == 0 || Shift == 0)
+        return;
+
+    /* loop for shifting the vector by Shift bits left */
+    for (i=0;i < SizeInBytes - 1 ;i++) {
+        VecBuff_ptr[i] = (uint8_t)(VecBuff_ptr[i] << Shift);
+        Temp = VecBuff_ptr[i+1] & 0xFF ;
+        VecBuff_ptr[i] = VecBuff_ptr[i] | (uint8_t)(Temp >> (8 - Shift));
+    }
+
+    /* shifting the LS byte */
+    VecBuff_ptr[SizeInBytes - 1] = (uint8_t)(VecBuff_ptr[SizeInBytes - 1] << Shift);
+
+    return;
+
+}/* END OF CC_CommonShiftLeftBigEndVector */
+
+
+/*******************************************************************************
+ *                      CC_CommonShiftRightVector                           *
+ *******************************************************************************
+ * @brief This function shifts right a vector by Shift - bits (Shift < 8).
+ *
+ *        The LSB of the vector is stored in the first cell in the array.
+ *        For example, a vector of 128 bit is :
+ *
+ *        byte[n-1] | byte[n-2] ... byte[1] | byte[0]
+ *
+ * @param[in] VecBuff_ptr     -  The vector buffer.
+ * @param[in] SizeInBytes     -  The counter size in bytes.
+ * @param[in] Shift           -  The number of shift left bits, must be < 8.
+ * @return no return value.
+ */
+void CC_CommonShiftRightVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift)
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    uint32_t i;
+    uint32_t Temp = 0;
+
+
+    /* FUNCTION LOGIC */
+
+    if (SizeInBytes == 0 || Shift == 0)
+        return;
+
+    /* loop for shifting the vector by Shift bits right */
+    for (i=0;i < SizeInBytes - 1 ;i++) {
+        VecBuff_ptr[i] = (uint8_t)(VecBuff_ptr[i] >> Shift);
+        Temp = VecBuff_ptr[i+1] & 0xFF ;
+        VecBuff_ptr[i] = VecBuff_ptr[i] | (uint8_t)(Temp << (8 - Shift));
+    }
+
+    /* shifting the MS byte */
+    VecBuff_ptr[SizeInBytes - 1] = (uint8_t)(VecBuff_ptr[SizeInBytes - 1] >> Shift);
+
+    return;
+
+}/* END OF CC_CommonShiftRightVector */
+
+
+/********************************************************************************
+ * @brief This function adds 2 vectors ( A+B).
+ *
+ * @param[in] A_ptr       -  input vector A.
+ * @param[in] B_ptr       -  input vector B.
+ * @param[in] SizeInWords - The size in words
+ * @param[in] Res_ptr     - The result pointer
+ *
+ * @return - Carry from high words addition.
+ */
+
+uint32_t CC_CommonAdd2vectors ( uint32_t *A_ptr, uint32_t *B_ptr,uint32_t SizeInWords, uint32_t *Res_ptr )
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    uint16_t  i;
+    uint32_t temp;
+    uint32_t Carry, PrevCarry=0;
+    uint32_t currentWordRes;
+
+    /* FUNCTION LOGIC */
+
+    for (i=0;i < SizeInWords;i++) {
+        /* execute the addition */
+        currentWordRes = A_ptr[i]+B_ptr[i];
+
+        /* check if carry */
+        Carry = ((currentWordRes < A_ptr[i]) || (currentWordRes < B_ptr[i]));
+
+        /* add previous carry */
+        Res_ptr[i] = currentWordRes + PrevCarry;
+
+        /*  Solve 4 problems: 1.if result > 32 bits ==> Carry to the next word.
+                              2.if the result=32 bits exactly ==> the result is = 0 but carry=1 to the next word.
+                          3.if the result=32 bit-1 and because of PrevCarry the result come to 0 ==> Carry to the next word.
+                          4.if the result=0 because the exercise is 0+0. */
+
+        /* a dummy initialization for temp */
+        temp = 2;
+
+        if (!(Res_ptr[i]))
+
+            temp = 1;
+
+        if (Res_ptr[i])
+
+            temp = 0;
+
+        PrevCarry = Carry | ( PrevCarry & temp & 0x1);
+
+    }/* end of adding the vectors */
+
+    return PrevCarry;
+
+}/* END OF CC_CommonAdd2vectors */
+
+
+
+/*******************************************************************************
+ *                      CC_CommonSubtractUintArrays                         *
+ *******************************************************************************
+
+ * @brief This function subtracts two little endian word arrays (length SizeInWords):
+ *        Res = (A - B) and returns borrow from subtracting of high words.
+ *
+ * @param[in] A_ptr       -  Pointer to input vector A.
+ * @param[in] B_ptr       -  Pointer to input vector B.
+ * @param[in] SizeInWords -  Size in words of each of vectors
+ * @param[in] Res_ptr     -  result pointer
+ *
+ * @return  Borrow from high words subtracting.
+ */
+
+uint32_t CC_CommonSubtractUintArrays(const uint32_t *A_ptr,
+                    uint32_t *B_ptr,
+                    uint32_t  SizeInWords,
+                    uint32_t *Res_ptr )
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    uint32_t temp, i;
+
+    uint32_t Borrow = 0;
+
+    /* FUNCTION LOGIC */
+
+    for (i=0; i < SizeInWords; i++) {
+        /* subtract previous borrow */
+        temp = A_ptr[i] - Borrow;
+
+        /* check if borrow */
+        if (temp > A_ptr[i])
+
+            Borrow = 1;
+
+        else Borrow = 0;
+
+        /* subtract B */
+        Res_ptr[i] = temp - B_ptr[i];
+
+        /* check if borrow */
+        if (Res_ptr[i] > temp)
+
+            Borrow ++;
+
+
+    }/* end of subtracting */
+
+    return Borrow;
+
+}/* END OF CC_CommonSubtractUintArrays */
+
+
+/*******************************************************************************
+ *                      CC_CommonSubtractMSBUint8Arrays                     *
+ *******************************************************************************
+
+ * @brief This function subtracts two big endian byte arrays.
+ *
+ *   Assuming:  SizeA >= SizeB.
+ *              Size of result buffer is not less, than sizeA.
+ *
+ * @param[in] A_ptr       -  Pointer to input vector A.
+ * @param[in] sizeA       -  Size in bytes of each of vector A.
+ * @param[in] B_ptr       -  Pointer to input vector B.
+ * @param[in] sizeB       -  Size in bytes of each of vector B.
+ * @param[in] Res_ptr     -  result pointer
+ *
+ * @return  Borrow from high byte of vector A.
+ */
+uint8_t CC_CommonSubtractMSBUint8Arrays(
+                      uint8_t  *A_ptr,
+                      uint32_t  sizeA,
+                      uint8_t  *B_ptr,
+                      uint32_t  sizeB,
+                      uint8_t  *Res_ptr )
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    uint8_t temp;
+
+    uint8_t Borrow = 0;
+
+    int32_t difSizes, i;
+
+
+    /* FUNCTION LOGIC */
+
+    difSizes = sizeA - sizeB;
+
+    for (i = sizeA - 1; i > 0; i--) {
+        /* subtract previous borrow */
+        temp = A_ptr[i] - Borrow;
+
+        /* check if borrow */
+        if (temp > A_ptr[i])
+
+            Borrow = 1;
+
+        else Borrow = 0;
+
+        /* subtract B */
+        if (i - difSizes >= 0)
+            Res_ptr[i] = temp - B_ptr[i - difSizes];
+        else
+            Res_ptr[i] = temp;
+
+        /* check if borrow */
+        if (Res_ptr[i] > temp)
+
+            Borrow ++;
+
+    }/* end of subtracting */
+
+    return Borrow;
+
+}/* END OF CC_CommonSubtractUintArrays */
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_math.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_math.h
new file mode 100644
index 0000000..756cc44
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/common/cc_common_math.h
@@ -0,0 +1,566 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_COMMON_MATH_H
+#define _CC_COMMON_MATH_H
+
+#include "cc_common_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/************************ Macros *******************************/
+#ifndef IS_ALIGNED
+#define IS_ALIGNED(val, align)      \
+(((CCVirtAddr_t)(val) & ((align) - 1)) == 0)
+#endif
+/* converts size given in bits to size in 32-bit words, rounded up */
+#define BIT_SIZE_UP_TO_32BIT_WORDS(x)  (((x)>>5UL) + (((x)&31)!=0))
+
+/* rotate right 32-bits word by n bits */
+#define CC_COMMON_ROTR32(x, n) ( ((x) >> (n)) | ((x) << ( 32 - (n) )) )
+/* rotate 32-bits word by 16 bits */
+#define CC_COMMON_ROT32(x) ( (x) >> 16 | (x) << 16 )
+
+/* inverse the bytes order in a word */
+#define CC_COMMON_REVERSE32(x)  ( ((CC_COMMON_ROT32((x)) & 0xff00ff00UL) >> 8) | ((CC_COMMON_ROT32((x)) & 0x00ff00ffUL) << 8) )
+
+#define SHIFT_LEFT(x, nBits)  ( (x) >> (nBits) )
+#define SHIFT_RIGHT(x, nBits)  ( (x) << (nBits) )
+#define CONVERT_LE_2_CPU_E(x)  (x)
+#define CONVERT_CPU_E_2_BE(x)  CC_COMMON_REVERSE32(x)
+
+/* inverse the bytes order in words of array */
+#define CC_COMMON_INVERSE_UINT32_IN_ARRAY( Array, SizeWords ) \
+{  \
+uint32_t ii2; \
+for( ii2 = 0; ii2 < (SizeWords); ii2++ ) \
+{ \
+    (Array)[ii2] = CC_COMMON_REVERSE32( (Array)[ii2] ); \
+} \
+}
+
+#ifndef BIG__ENDIAN
+/* define word endiannes*/
+#define  CC_SET_WORD_ENDIANESS
+#else
+#define  CC_SET_WORD_ENDIANESS(val) CC_COMMON_REVERSE32(val)
+#endif
+
+#ifdef BIG__ENDIAN
+#define CC_COMMON_CONVERT_TO_LE32(in32_ptr, out32_ptr, size_words) \
+{ \
+uint32_t i; \
+for (i = 0; i < size_words; i++) { \
+    (out32_ptr)[i] = CC_COMMON_REVERSE32((in32_ptr)[i]); \
+} \
+}
+#else
+#define CC_COMMON_CONVERT_TO_LE32(in32_ptr, out32_ptr, size_words) \
+{ \
+uint32_t i; \
+if((in32_ptr) != (out32_ptr)) { \
+    for (i = 0; i < size_words; i++) { \
+        (out32_ptr)[i] = (in32_ptr)[i]; \
+    } \
+} \
+}
+#endif
+
+/* get a bit val from a word array */
+#define CC_COMMON_GET_BIT_VAL_FROM_WORD_ARRAY( ptr , bit_pos ) \
+(((ptr)[(bit_pos)>>5] >> ((bit_pos) & 0x1FUL)) & 1UL)
+
+/* exchange a bit on a word array */
+#define CC_COMMON_EXCHANGE_BIT_ON_WORD_ARRAY(ptr,bit_pos) ((ptr)[(bit_pos)>>5] ^= (1UL << ((bit_pos) & 0x1FUL)))
+
+/* macros for copying 4 words to non aligned output according to macine endianness.
+Note: output is given by aligned down pointer and alignment of output data in bits,
+ input must be aligned to 4 bytes */
+#ifdef BIG__ENDIAN
+
+#define CC_COMMON_COPY_4WORDS_TO_BYTES( out32_ptr, outAlign, in32_ptr )  \
+if( outAlign != 0 ) \
+{  \
+  (out32_ptr)[0]  = ((out32_ptr)[0] & (0xFFFFFFFF << (32-(outAlign))))      | \
+              CC_COMMON_REVERSE32((in32_ptr)[0]) >> (outAlign);   \
+  (out32_ptr)[1]  = CC_COMMON_REVERSE32((in32_ptr)[0]) << (32-(outAlign)) | \
+              CC_COMMON_REVERSE32((in32_ptr)[1]) >> (outAlign);   \
+  (out32_ptr)[2]  = CC_COMMON_REVERSE32((in32_ptr)[1]) << (32-(outAlign)) | \
+              CC_COMMON_REVERSE32((in32_ptr)[2]) >> (outAlign);   \
+  (out32_ptr)[3]  = CC_COMMON_REVERSE32((in32_ptr)[2]) << (32-(outAlign)) | \
+              CC_COMMON_REVERSE32((in32_ptr)[3]) >> (outAlign);   \
+  (out32_ptr)[4]  = ((out32_ptr)[4] & (0xFFFFFFFF >> (outAlign)))           | \
+              CC_COMMON_REVERSE32((in32_ptr)[3]) << (32-(outAlign)); \
+} \
+else  \
+{ \
+  (out32_ptr)[0]  = CC_COMMON_REVERSE32((in32_ptr)[0]);   \
+  (out32_ptr)[1]  = CC_COMMON_REVERSE32((in32_ptr)[1]);   \
+  (out32_ptr)[2]  = CC_COMMON_REVERSE32((in32_ptr)[2]);   \
+  (out32_ptr)[3]  = CC_COMMON_REVERSE32((in32_ptr)[3]);   \
+}
+
+#else  /* LITTLE_ENDIAN */
+#define CC_COMMON_COPY_4WORDS_TO_BYTES( out32_ptr, outAlign, in32_ptr )  \
+if( outAlign != 0 ) \
+{  \
+  (out32_ptr)[0]  = ((out32_ptr)[0] & (0xFFFFFFFF  >> (32-(outAlign)))) | (in32_ptr)[0] << (outAlign); \
+  (out32_ptr)[1]  = (in32_ptr)[0] >> (32-(outAlign)) | (in32_ptr)[1] << (outAlign);                   \
+  (out32_ptr)[2]  = (in32_ptr)[1] >> (32-(outAlign)) | (in32_ptr)[2] << (outAlign);                   \
+  (out32_ptr)[3]  = (in32_ptr)[2] >> (32-(outAlign)) | (in32_ptr)[3] << (outAlign);                   \
+  (out32_ptr)[4]  = ((out32_ptr)[4] & (0xFFFFFFFF << (outAlign))) | (in32_ptr)[3] >> (32-(outAlign));   \
+} \
+else \
+{ \
+  (out32_ptr)[0]  = (in32_ptr)[0];   \
+  (out32_ptr)[1]  = (in32_ptr)[1];   \
+  (out32_ptr)[2]  = (in32_ptr)[2];   \
+  (out32_ptr)[3]  = (in32_ptr)[3];   \
+}
+#endif
+
+
+/* macros for copying 16 bytes from non aligned input into aligned output according to machine endianness.
+Note: input is given by aligned down pointer and alignment of input data in bits,
+ output must be aligned to 4 bytes */
+
+#ifdef BIG__ENDIAN
+
+#define CC_COMMON_COPY_16BYTES_TO_WORDS( in32_ptr, inAlign, out32_ptr )  \
+if( inAlign != 0 ) \
+{  \
+  (out32_ptr)[0]  = CC_COMMON_REVERSE32( (in32_ptr)[0] << (inAlign) | (in32_ptr)[1] >> (32-(inAlign)) );  \
+      (out32_ptr)[1]  = CC_COMMON_REVERSE32( (in32_ptr)[1] << (inAlign) | (in32_ptr)[2] >> (32-(inAlign)) );  \
+      (out32_ptr)[2]  = CC_COMMON_REVERSE32( (in32_ptr)[2] << (inAlign) | (in32_ptr)[3] >> (32-(inAlign)) );  \
+      (out32_ptr)[3]  = CC_COMMON_REVERSE32( (in32_ptr)[3] << (inAlign) | (in32_ptr)[4] >> (32-(inAlign)) );  \
+} \
+else  \
+{  \
+      (out32_ptr)[0]  = CC_COMMON_REVERSE32((in32_ptr)[0]); \
+      (out32_ptr)[1]  = CC_COMMON_REVERSE32((in32_ptr)[1]); \
+      (out32_ptr)[2]  = CC_COMMON_REVERSE32((in32_ptr)[2]); \
+      (out32_ptr)[3]  = CC_COMMON_REVERSE32((in32_ptr)[3]); \
+}
+
+#else  /* LITTLE_ENDIAN */
+
+#define  CC_COMMON_COPY_16BYTES_TO_WORDS( in32_ptr, inAlign, out32_ptr )  \
+if( inAlign != 0 ) \
+{  \
+      (out32_ptr)[0]  = (in32_ptr)[0] >> (inAlign) | (in32_ptr)[1] << (32-(inAlign));  \
+      (out32_ptr)[1]  = (in32_ptr)[1] >> (inAlign) | (in32_ptr)[2] << (32-(inAlign));  \
+      (out32_ptr)[2]  = (in32_ptr)[2] >> (inAlign) | (in32_ptr)[3] << (32-(inAlign));  \
+      (out32_ptr)[3]  = (in32_ptr)[3] >> (inAlign) | (in32_ptr)[4] << (32-(inAlign));  \
+}  \
+else  \
+{  \
+      (out32_ptr)[0]  = (in32_ptr)[0];  \
+      (out32_ptr)[1]  = (in32_ptr)[1];  \
+      (out32_ptr)[2]  = (in32_ptr)[2];  \
+      (out32_ptr)[3]  = (in32_ptr)[3];  \
+}
+#endif
+
+
+/************************ Enums ********************************/
+
+/* the counter comperation result enum */
+typedef enum {
+    CC_COMMON_CmpCounter1AndCounter2AreIdentical = 0,
+    CC_COMMON_CmpCounter1GreaterThenCounter2      = 1,
+    CC_COMMON_CmpCounter2GreaterThenCounter1      = 2,
+
+    CC_COMMON_CmpCounterLast                    = 0x7FFFFFFF,
+
+} CCCommonCmpCounter_t;
+
+
+/************************ Typedefs  *****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+/*****************************************************************
+* @brief This function adds a value to a large counter presented in a buffer.
+*        The MSB of the counter is stored in the first cell in the array.
+*
+*        for example:
+*
+*        a counter of 64 bit : the value is :
+*
+*        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]
+*
+* @param[in] CounterBuff_ptr - The buffer containing the counter.
+* @param[in] Val             - this value to add.
+* @param[in] CounterSize      - the counter size in 32bit words.
+*
+* @return CCError_t - On success CC_OK is returned, on failure a
+*                        value MODULE_* as defined in ...
+*/
+
+void CC_CommonIncMsbUnsignedCounter( uint32_t *CounterBuff_ptr ,
+                 uint32_t  Val,
+                 uint32_t  CounterSize);
+
+
+/********************************************************************************
+* @brief This function adds a value to a large counter presented in a buffer.
+*        The LSB of the counter is stored in the first cell in the array.
+*
+*        for example:
+*
+*        a counter of 64 bit : the value is :
+*
+*        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
+*
+* @param[in] CounterBuff_ptr - The buffer containing the counter.
+* @param[in] Val             - this value to add.
+* @param[in] CounterSize      - the counter size in 32bit words.
+*
+* @return carry bit from MS word if carry occur
+*
+*/
+
+uint32_t CC_CommonIncLsbUnsignedCounter(
+                 uint32_t     *CounterBuff_ptr ,
+                 uint32_t      Val,
+                 uint32_t      CounterSize);
+
+
+/********************************************************************************
+* @brief This function subtracts a value from a large counter presented in a buffer.
+*        The LSB of the counter is stored in the first cell in the array.
+*
+*        for example:
+*
+*        a counter of 64 bit : the value is :
+*
+*        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
+*
+* @param[in] CounterBuff_ptr - the buffer containing the counter.
+* @param[in] Val             - the value to subtract.
+* @param[in]  CounterSize      - the counter size in 32bit words.
+*
+* @return CCError_t - On success CC_OK is returned, on failure a
+*                        value MODULE_* as defined in ...
+*/
+
+void CC_CommonDecrLsbUnsignedCounter( uint32_t     *CounterBuff_ptr,
+                   uint32_t      Val,
+                   uint32_t      CounterSizeInWords);
+
+
+/**************************************************************
+* @brief This function compares a value of 2 large counter presented in a byte buffer.
+*        The MSB of the counter is stored in the first cell in the array.
+*
+*        for example:
+*
+*        a counter of 64 bit : the value is :
+*
+*        byte[0] << 56 | byte[1] << 48 ............ byte[6] << 8 | byte[7]
+*
+*
+* @param[in] CounterBuff1_ptr - The first counter buffer.
+* @param[in] Counter1Size     - the first counter size in bytes.
+* @param[in] CounterBuff2_ptr - The second counter buffer.
+* @param[in] Counter2Size     - the second counter size in bytes.
+* @param[in] SizeUnit         - the size units. 0 - bits , 1 - bytes
+*
+* @return result - an enum with the compare result:
+*                                0 - both counters are identical
+*                                1 - counter 1 is larger.
+*                                2 - counter 2 is larger.
+* @note This code executes in constant time, regardless of the arguments.
+*/
+
+CCCommonCmpCounter_t CC_CommonCmpMsbUnsignedCounters( const uint8_t  *CounterBuff1_ptr,
+                              uint32_t  Counter1Size,
+                              const uint8_t  *CounterBuff2_ptr,
+                              uint32_t Counter2Size );
+
+
+
+/**************************************************************
+* @brief This function compares a value of 2 large counter presented in a byte buffer.
+*        The LSB of the counter is stored in the first cell in the array.
+*
+*        for example:
+*
+*        a counter of 64 bit : the value is :
+*
+*        byte[7] << 56 | byte[6] << 48 ............ byte[1] << 8 | byte[0]
+*
+* @param[in] CounterBuff1_ptr - The first counter buffer.
+* @param[in] Counter1Size     - the first counter size in bytes.
+* @param[in] CounterBuff2_ptr - The second counter buffer.
+* @param[in] Counter2Size     - the second counter size in bytes.
+*
+* @return result - an enum with the compare result:
+*                                0 - both counters are identical
+*                                1 - counter 1 is larger.
+*                                2 - counter 2 is larger.
+*/
+
+CCCommonCmpCounter_t CC_CommonCmpLsbUnsignedCounters( const uint8_t  *CounterBuff1_ptr,
+                                 size_t  Counter1Size,
+                                 const uint8_t  *CounterBuff2_ptr,
+                                 size_t Counter2Size );
+
+
+
+/**************************************************************************
+*           CC_CommonCmpLsWordsUnsignedCounters function          *
+**************************************************************************/
+/**
+* @brief This function compares a value of 2 large counter presented in a word buffer.
+*        The LSWord of the counters is stored in the first cell in the array.
+*
+*
+* @param[in] CounterBuff1_ptr  - The first counter buffer.
+* @param[in] Counter1SizeWords - the first counter size in Words.
+* @param[in] CounterBuff2_ptr  - The second counter buffer.
+* @param[in] Counter2SizeWords - the second counter size in Words.
+*
+* @return result - an enum with the compare result:
+*                                0 - both counters are identical
+*                                1 - counter 1 is larger.
+*                                2 - counter 2 is larger.
+*/
+CCCommonCmpCounter_t CC_CommonCmpLsWordsUnsignedCounters(const uint32_t  *CounterBuff1_ptr,
+                                uint32_t   Counter1SizeWords,
+                                const uint32_t  *CounterBuff2_ptr,
+                                uint32_t   Counter2SizeWords);
+
+/********************************************************************************
+*
+* @brief This function returns the effective number of bits in the byte stream counter
+*        ( searching the highest '1' in the counter )
+*
+*        The function has one implementations: for little and big endian machines.
+*
+*        Assumed, that LSB of the counter is stored in the first cell in the array.
+*         For example, the value of the 8-Bytes counter B is :
+*             B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0] .
+*
+*
+* @param[in] CounterBuff_ptr -  The counter buffer.
+* @param[in] CounterSize     -  the counter size in bytes.
+*
+* @return result - The effective counters size in bits.
+*/
+
+uint32_t CC_CommonGetBytesCounterEffectiveSizeInBits( const uint8_t  *CounterBuff_ptr,
+                             uint32_t  CounterSize );
+
+/*******************************************************************************
+*             CC_CommonGetWordsCounterEffectiveSizeInBits                  *
+*******************************************************************************
+*
+* @brief This function returns the effective number of bits in the words array
+*        ( searching the highest '1' in the counter )
+*
+*        The function may works on little and big endian machines.
+*
+*        Assumed, that the words in array are ordered from LS word to MS word.
+*        For LITTLE Endian machines assumed, that LSB of the each word is stored in the first
+*        cell in the word. For example, the value of the 8-Bytes (B) counter is :
+*             B[7]<<56 | B[6]<<48 ............ B[1]<<8 | B[0]
+*
+*        For BIG Endian machines assumed, that MS byte of each word is stored in the first
+*        cell, LS byte is stored in the last place of the word.
+*        For example, the value of the 64 bit counter is :
+*         B[3] << 56 | B[2] << 48 B[1] << 8 | B[0],  B[7]<<56 | B[6]<<48 | B[5]<<8 | B[4]
+*
+*     NOTE !!: 1. For BIG Endian the counter buffer and its size must be aligned to 4-bytes word.
+*
+* @param[in] CounterBuff_ptr   -  The counter buffer.
+* @param[in] CounterSizeWords  -  The counter size in words.
+*
+* @return result - The effective counters size in bits.
+*
+*/
+uint32_t CC_CommonGetWordsCounterEffectiveSizeInBits( const uint32_t  *CounterBuff_ptr,
+                             uint32_t   CounterSizeWords);
+
+/********************************************************************************
+* @brief This function divides a vector by 2 - in a secured way
+*
+*        The LSB of the vector is stored in the first cell in the array.
+*
+*        for example:
+*
+*        a vector of 128 bit : the value is :
+*
+*        word[3] << 96 | word[2] << 64 ............ word[1] << 32 | word[0]
+*
+* @param[in] VecBuff_ptr     -  The vector buffer.
+* @param[in] SizeInWords     -  the counter size in words.
+*
+* @return result - no return value.
+*/
+void CC_CommonDivideVectorBy2(uint32_t *VecBuff_ptr,uint32_t SizeInWords);
+
+
+/********************************************************************************
+* @brief This function shifts left a big endian vector by Shift - bits (Shift < 8).
+*
+*        The MSB of the vector is stored in the first cell in the array,
+*
+*        For example, a vector of 128 bit is :
+*
+*        byte[n-1] | byte[n-2] ... byte[1] | byte[0]
+*
+* @param[in] VecBuff_ptr     -  The vector buffer.
+* @param[in] SizeInBytes     -  The counter size in bytes.
+* @param[in] Shift           -  The number of shift left bits, must be < 8.
+* @return no return value.
+*/
+
+void CC_CommonShiftLeftBigEndVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift);
+
+
+/*******************************************************************************
+*                      CC_CommonShiftRightVector                            *
+*******************************************************************************
+* @brief This function shifts right a vector by Shift - bits (Shift < 8).
+*
+*        The LSB of the vector is stored in the first cell in the array.
+*        For example, a vector of 128 bit is :
+*
+*        byte[n-1] | byte[n-2] ... byte[1] | byte[0]
+*
+* @param[in] VecBuff_ptr     -  The vector buffer.
+* @param[in] SizeInBytes     -  The counter size in bytes.
+* @param[in] Shift           -  The number of shift left bits, must be < 8.
+* @return no return value.
+*/
+void CC_CommonShiftRightVector(uint8_t *VecBuff_ptr, uint32_t SizeInBytes, int8_t Shift);
+
+
+/******************************************************************************
+*                      CC_CommonShiftLeftVector                            *
+******************************************************************************
+* @brief This function shifts left a vector by Shift - bits (Shift < 8).
+*
+*        The LSB of the vector is stored in the first cell in the array.
+*        For example, a vector of 128 bit is :
+*
+*        byte[n-1] | byte[n-2] ... byte[1] | byte[0]
+*
+* @param[in] VecBuff_ptr     -  The vector buffer.
+* @param[in] SizeInBytes     -  The counter size in bytes.
+* @param[in] Shift           -  The number of shift left bits, must be < 8.
+* @return no return value.
+*/
+void CC_CommonShiftLeftVector(uint8_t *VecBuff_ptr,uint32_t SizeInBytes, int8_t Shift);
+
+
+/**************************************************************
+* @brief This function adds 2 vectors ( A+B).
+*
+* @param[in] A_ptr       -  input vector A.
+* @param[in] B_ptr       -  input vector B.
+* @param[in] SizeInWords - The size in words
+* @param[in] Res_ptr     - The result pointer
+*
+* @return result  - Carry from high words addition.
+*/
+
+uint32_t  CC_CommonAdd2vectors (
+                           uint32_t *A_ptr,
+               uint32_t *B_ptr,
+               uint32_t SizeInWords,
+               uint32_t *Res_ptr );
+
+
+/*******************************************************************************
+*                      CC_CommonSubtractUintArrays                         *
+*******************************************************************************
+
+* @brief This function subtracts two little endian words arrays of length
+  SizeInWords:  Res = (A - B) and returns Borrow from subtracting of high
+  words.
+*
+* @param[in] A_ptr       -  input vector A.
+* @param[in] B_ptr       -  input vector B.
+* @param[in] SizeInWords -  size in words
+* @param[in] Res_ptr     -  result pointer
+*
+* @return  Borrow from high words subtracting.
+*/
+
+uint32_t CC_CommonSubtractUintArrays(const uint32_t *A_ptr,
+                  uint32_t *B_ptr,
+                  uint32_t  SizeInWords,
+                  uint32_t *Res_ptr );
+
+/*******************************************************************************
+*                      CC_CommonAddTwoLsbUint8Vectors                      *
+*******************************************************************************
+*
+* @brief This function adds two little endian vectors Res = (A + B) and returns carry.
+*
+*
+* @param[in] A_ptr       -  input vector A.
+* @param[in] B_ptr       -  input vector B.
+* @param[in] SizeInWords -  size in words
+* @param[in] Res_ptr     -  result pointer
+*
+* @return - carry from adding of two high bytes.
+*/
+
+uint32_t CC_CommonAddTwoLsbUint8Vectors(
+                  uint8_t  *A_ptr,
+                  uint8_t  *B_ptr,
+                  uint32_t  VectSizeInBytes,
+                  uint8_t  *Res_ptr );
+
+
+/*******************************************************************************
+*                      CC_CommonSubtractMSBUint8Arrays                     *
+*******************************************************************************
+
+* @brief This function subtracts two big endian byte arrays.
+*
+*   Assuming:  SizeA >= SizeB.
+*              Size of result buffer is not less, than sizeA.
+*
+* @param[in] A_ptr       -  Pointer to input vector A.
+* @param[in] sizeA       -  Size in bytes of each of vector A.
+* @param[in] B_ptr       -  Pointer to input vector B.
+* @param[in] sizeB       -  Size in bytes of each of vector B.
+* @param[in] Res_ptr     -  result pointer
+*
+* @return  Borrow from high byte of vector A.
+*/
+uint8_t CC_CommonSubtractMSBUint8Arrays(
+                  uint8_t  *A_ptr,
+                  uint32_t  sizeA,
+                  uint8_t  *B_ptr,
+                  uint32_t  sizeB,
+                  uint8_t  *Res_ptr );
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/dh/cc_dh.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/dh/cc_dh.c
new file mode 100644
index 0000000..da8630f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/dh/cc_dh.c
@@ -0,0 +1,846 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_rnd_common.h"
+#include "cc_rnd_error.h"
+#include "cc_rnd_local.h"
+#include "cc_dh_error.h"
+#include "cc_dh.h"
+#include "cc_dh_kg.h"
+#include "cc_rsa_build.h"
+#include "cc_rsa_prim.h"
+#include "rsa.h"
+#include "rsa_public.h"
+#include "rsa_private.h"
+#include "cc_fips_defs.h"
+
+
+/************************ Defines *******************************/
+
+/************************ Enums *********************************/
+
+/************************ macros ********************************/
+
+
+/************************ global data ***********************************/
+
+/************************ Private Functions ******************************/
+/* This function translates the DH hash modes into KDF hash modes */
+static CCKdfHashOpMode_t MakeKDFHashMode(CCDhHashOpMode_t hashMode)
+{
+
+        CCKdfHashOpMode_t outMode;
+
+        switch (hashMode) {
+        case CC_DH_HASH_SHA1_mode:
+                outMode = CC_KDF_HASH_SHA1_mode;
+                break;
+        case CC_DH_HASH_SHA224_mode:
+                outMode = CC_KDF_HASH_SHA224_mode;
+                break;
+        case CC_DH_HASH_SHA256_mode:
+                outMode = CC_KDF_HASH_SHA256_mode;
+                break;
+        case CC_DH_HASH_SHA384_mode:
+                outMode = CC_KDF_HASH_SHA384_mode;
+                break;
+        case CC_DH_HASH_SHA512_mode:
+                outMode = CC_KDF_HASH_SHA512_mode;
+                break;
+        default:
+                outMode = CC_KDF_HASH_OpModeLast;
+        }
+
+        return outMode;
+}
+
+/* This function translates the DH deriveFunc enum to KDF derive func enum */
+static CCKdfDerivFuncMode_t MakeKDFDeriveFuncMode(CCDhDerivationFuncMode_t deriveFunc)
+{
+
+        CCKdfDerivFuncMode_t outDeriveFunc;
+
+        switch (deriveFunc) {
+        case CC_DH_ASN1_Der_mode:
+                outDeriveFunc = CC_KDF_ASN1_DerivMode;
+                break;
+        case CC_DH_X963_DerMode:
+                outDeriveFunc = CC_KDF_ConcatDerivMode;
+                break;
+        default:
+                outDeriveFunc = CC_KDF_DerivFuncModeLast;
+        }
+
+        return outDeriveFunc;
+}
+/************************ Public Functions ******************************/
+
+
+CEXPORT_C CCError_t CC_DhGeneratePubPrv(
+                                           CCRndContext_t *rndContext_ptr,
+                                           uint8_t *Generator_ptr,              /*generator*/
+                                           size_t GeneratorSize,
+                                           uint8_t *Prime_ptr,                  /*modulus*/
+                                           size_t PrimeSize,
+                                           uint16_t L,         /*Exact length of Private key in bits*/
+                                           uint8_t *Q_ptr,                      /*order/in*/
+                                           size_t QSize,
+                                           CCDhOpMode_t DH_mode,            /*in*/
+                                           CCDhUserPubKey_t *tmpPubKey_ptr,  /*temp buff*/
+                                           CCDhPrimeData_t  *tmpPrimeData_ptr, /*temp buff*/
+                                           uint8_t *ClientPrvKey_ptr,           /*out*/
+                                           size_t  *ClientPrvKeySize_ptr,      /*in/out*/
+                                           uint8_t *ClientPub1_ptr,             /*out*/
+                                           size_t  *ClientPubSize_ptr)         /*in/out*/
+
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /* temporary byte shift masks */
+        uint8_t tmpByte, mask, mask1, shift;
+
+        /* the vector 2^(L-1) size*/
+        uint16_t tmpSize;
+
+        /* the comparing value, returned from the vectors compare */
+        CCCommonCmpCounter_t comp;
+
+        CCRndState_t   *rndState_ptr;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* check parameters */
+        if (rndContext_ptr == NULL)
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+        if (rndContext_ptr->rndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        rndState_ptr = (CCRndState_t *)(rndContext_ptr->rndState);
+        RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+        /* if an argument pointer is NULL return an error */
+        if (Generator_ptr == NULL || Prime_ptr == NULL ||
+            ClientPrvKey_ptr == NULL || ClientPub1_ptr == NULL ||
+            ClientPrvKeySize_ptr == NULL || ClientPubSize_ptr == NULL ||
+            tmpPubKey_ptr == NULL || tmpPrimeData_ptr == NULL)
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+
+        /* check DH mode */
+        if (DH_mode > CC_DH_NumOfModes)
+                return CC_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;
+
+        /* preliminary check of sizes */
+        if (PrimeSize > CC_DH_MAX_MOD_SIZE_IN_BYTES || PrimeSize == 0)
+                return CC_DH_INVALID_MODULUS_SIZE_ERROR;
+
+        if (GeneratorSize == 0 || GeneratorSize > PrimeSize)
+                return CC_DH_INVALID_ARGUMENT_SIZE_ERROR;
+
+        if (*ClientPubSize_ptr < PrimeSize)
+                return CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
+
+        if (*ClientPrvKeySize_ptr < PrimeSize)
+                return CC_DH_SECRET_KEY_SIZE_OUTPUT_ERROR;
+
+
+        /* Check the the generator according to DH mode */
+    if (DH_mode == CC_DH_PKCS3_mode)
+            tmpByte = 0; /* for checking PKCS3 part 6.  0 < g < p */
+    else  /* CC_DH_ANSI_X942_mode */
+        tmpByte = 1; /* for checking ANSI_X942 part 7.2.  1 < g < p-1 */
+
+        comp = CC_CommonCmpMsbUnsignedCounters( Generator_ptr,
+                                                   GeneratorSize,
+                                                   &tmpByte, 1);
+
+        if (comp != CC_COMMON_CmpCounter1GreaterThenCounter2)
+                return CC_DH_ARGUMENT_GENERATOR_SMALLER_THAN_ZERO_ERROR;
+
+        /*Compare the generator and the Prime: requested that g < P-1 */
+        Prime_ptr[PrimeSize-1] -= tmpByte; /* temporary p = p-1 */
+        comp = CC_CommonCmpMsbUnsignedCounters( Generator_ptr, GeneratorSize,
+                                                   Prime_ptr, PrimeSize );
+
+        if (comp != CC_COMMON_CmpCounter2GreaterThenCounter1)
+                return CC_DH_ARGUMENT_PRIME_SMALLER_THAN_GENERATOR_ERROR;
+
+        /* repair P */
+        Prime_ptr[PrimeSize-1] += tmpByte;
+
+        /*--------------------------------------------------------------------------------*/
+        /*         DH public-private keys generation                                      */
+        /*--------------------------------------------------------------------------------*/
+
+        /* temporary set prime modulus into temp buffer in little endianness */
+        // RL Endianness
+        CC_CommonReverseMemcpy( (uint8_t*)tmpPrimeData_ptr->DataIn , Prime_ptr , PrimeSize );
+
+        /* get actual size of prime in bits: min() used to prevent warnings */
+        tmpSize = CC_MIN( PrimeSize*8,
+                       (uint16_t)CC_CommonGetBytesCounterEffectiveSizeInBits(
+                                           (uint8_t*)tmpPrimeData_ptr->DataIn, PrimeSize) );
+
+        /* correction of Prime_ptr pointer and Size for removing of not significant zero-bytes */
+        if (PrimeSize - CALC_FULL_BYTES(tmpSize) > 0) {
+                Prime_ptr += PrimeSize - CALC_FULL_BYTES(tmpSize);
+                PrimeSize = CALC_FULL_BYTES(tmpSize);
+        }
+
+        switch (DH_mode) {
+        case CC_DH_PKCS3_mode:
+                /* ----------------------------------------------------------- *
+            PKCS#3:  set x private random value according to following:
+                                   1) If L = 0: set    0 < x < P-1;
+                                   2) If L > 0: set  2^(L-1) <= x < 2^L ,
+                                           where 2^(L-1) <= P.
+                  ----------------------------------------------------------- */
+                if (L == 0) {
+                        /* Option 1: L is not provided - check the minimum size of the private key buffer */
+                        if (*ClientPrvKeySize_ptr < PrimeSize) {
+                                Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
+                                goto End1;
+                        }
+
+                        /* random generation in range:  0 < x < P-1  (in little endian */
+                        Error = CC_RndGenerateVectorInRange( rndContext_ptr,
+                                                                tmpSize /*rndSizeInBits*/,
+                                                                (uint8_t*)tmpPrimeData_ptr->DataIn/*maxVect*/,
+                                                                (uint8_t*)tmpPrimeData_ptr->DataOut/*out*/ );
+                        if (Error != CC_OK)
+                                goto End;
+
+                        /* reverse privKey to big endianness */
+                        CC_CommonReverseMemcpy( ClientPrvKey_ptr , (uint8_t*)tmpPrimeData_ptr->DataOut , PrimeSize );
+
+                        /* private key size in bytes */
+                        *ClientPrvKeySize_ptr = PrimeSize;
+                }
+                else {  /* Option 2:  L > 0 and bit length of privKey must be exactly L bit */
+                        /* check L and the minimum size of the private key buffer */
+                        if (L > tmpSize) {
+                                Error = CC_DH_INVALID_L_ARGUMENT_ERROR;
+                                goto End1;
+                        }
+                        if ((*ClientPrvKeySize_ptr)*8 < L) {
+                                Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
+                                goto End1;
+                        }
+
+                        /* actual private key size in bytes and shift value */
+                        *ClientPrvKeySize_ptr = CALC_FULL_BYTES(L);
+                        if (*ClientPrvKeySize_ptr > CC_DH_MAX_MOD_SIZE_IN_BYTES) {
+                                Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
+                                goto End1;
+            }
+                        shift = ((8 - (L & 7)) & 7);
+
+                        /* if L = modulus size, then generate random x with exact bit-size = L
+                           and value in range:  2^(L-1) < x < P */
+                        if (L == tmpSize) {
+                                mask   = 0x7F >> shift;
+                                mask1  = 0x80 >> shift;
+
+                                /* set temporary MSBit of modulus = 0 for generation random in range without MSbit */
+                                ((uint8_t*)tmpPrimeData_ptr->DataIn)[*ClientPrvKeySize_ptr - 1] &= mask;
+
+                                /* generate random in range */
+                                Error = CC_RndGenerateVectorInRange(rndContext_ptr,
+                                                                      tmpSize /*rndSizeInBits*/,
+                                                                      (uint8_t*)tmpPrimeData_ptr->DataIn/*maxVect*/,
+                                                                      (uint8_t*)tmpPrimeData_ptr->DataOut/*out*/ );
+
+                                if (Error != CC_OK)
+                                        goto End;
+
+                                /* set MSBit of random to 1 */
+                                ((uint8_t*)tmpPrimeData_ptr->DataIn)[*ClientPrvKeySize_ptr - 1] |= mask1;
+
+                                /* reverse privKey to big endianness */
+                                CC_CommonReverseMemcpy( ClientPrvKey_ptr , (uint8_t*)tmpPrimeData_ptr->DataOut , *ClientPrvKeySize_ptr );
+                        }
+                        /* if L < modulus size, then generate random x of size L bits */
+                        else {
+                                /* random generation */
+                                Error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char *)ClientPrvKey_ptr, *ClientPrvKeySize_ptr );
+
+                                if (Error != CC_OK)
+                                        goto End;
+
+                                /* set two appropriate high bits of privKey to 00..1 to met the requirement 2^(L-1) <= x < 2^L */
+                                if ((L & 7) > 0) {
+                                        mask  = 0xFF >> shift;
+                                        mask1 = 0x80 >> shift;
+                                        ClientPrvKey_ptr[0] = (ClientPrvKey_ptr[0] & mask) | mask1;
+                                }
+                                /* if( (L & 7) == 0 ) */
+                                else {
+                                        ClientPrvKey_ptr[0] |= 0x80;
+                                }
+                        }
+                }
+
+                break;
+
+        case CC_DH_ANSI_X942_mode:
+                /* ----------------------------------------------------------- *
+                                              ANS X9.42:
+                                 1<= X <= q-1 or    1< X <= q-1
+                 --------------------------------------------------------------*/
+
+                /* check order */
+                if (Q_ptr == NULL) {
+                        Error = CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+                        goto End1;
+                }
+
+                if (QSize == 0 || QSize > PrimeSize) {
+                        Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
+                        goto End1;
+                }
+
+                /* check client private key buffer size */
+                if (*ClientPrvKeySize_ptr < QSize) {
+                        Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
+                        goto End1;
+                }
+
+                /* set order Q into temp buffer in little endianness */
+                CC_CommonReverseMemcpy( (uint8_t*)tmpPrimeData_ptr->DataIn, Q_ptr, QSize );
+
+                /* get actual size in bits */
+                tmpSize = (uint16_t)CC_CommonGetBytesCounterEffectiveSizeInBits(
+                                                                                    (uint8_t*)tmpPrimeData_ptr->DataIn,
+                                                                                    QSize );
+                /* private key size in bytes */
+                *ClientPrvKeySize_ptr = CALC_FULL_BYTES(tmpSize);
+
+                /* random in range:  1 < x < Q  (little endianness) */
+                Error = CC_RndGenerateVectorInRange( rndContext_ptr,
+                                                        tmpSize /*rndSizeInBits*/,
+                                                        (uint8_t*)tmpPrimeData_ptr->DataIn/*maxVect*/,
+                                                        (uint8_t*)tmpPrimeData_ptr->DataOut/*out*/);
+                if (Error != CC_OK)
+                        goto End;
+
+                /* reverse privKey to big endianness */
+                CC_CommonReverseMemcpy(ClientPrvKey_ptr, (uint8_t*)tmpPrimeData_ptr->DataOut, *ClientPrvKeySize_ptr);
+
+                break;
+
+        default:
+                Error = CC_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;
+                goto End1;
+
+        }
+
+        /* ----------------------------------------------------------- */
+        /*           Create the public key                             */
+        /* ----------------------------------------------------------- */
+
+        /* Build the RSA PublKey data structure for the Exp operation, using RSA_Encrypt primitive */
+        Error = CC_RsaPubKeyBuild(
+                                     tmpPubKey_ptr,
+                                     ClientPrvKey_ptr,
+                                     *ClientPrvKeySize_ptr,
+                                     Prime_ptr,
+                                     PrimeSize );
+        /* check error */
+        if (Error != CC_OK) {
+                goto End;
+        }
+
+        /*Call the exponent operation to calculate the ClientPub1 = Generator^privKey mod Prime */
+        Error = CC_RsaPrimEncrypt(
+                                     tmpPubKey_ptr,
+                                     tmpPrimeData_ptr,
+                                     Generator_ptr,
+                                     GeneratorSize,
+                                     ClientPub1_ptr );
+        if (Error != CC_OK) {
+                goto End;
+        }
+
+        *ClientPubSize_ptr = PrimeSize;
+
+End:
+
+    if (Error != CC_OK) {
+        CC_PalMemSetZero( ClientPrvKey_ptr, *ClientPrvKeySize_ptr);
+        *ClientPrvKeySize_ptr = 0;
+    }
+End1:
+        /* delete secure sensitive data */
+        CC_PalMemSetZero( tmpPubKey_ptr, sizeof(CCDhUserPubKey_t) );
+        CC_PalMemSetZero( tmpPrimeData_ptr, sizeof(CCDhPrimeData_t) );
+
+        return Error;
+
+}/* END OF CC_DhGeneratePubPrv function */
+
+
+CEXPORT_C CCError_t CC_DhGetSecretKey(
+                                          uint8_t *ClientPrvKey_ptr,
+                                          size_t ClientPrvKeySize,
+                                          uint8_t *ServerPubKey_ptr,
+                                          size_t ServerPubKeySize,
+                                          uint8_t *Prime_ptr,
+                                          size_t PrimeSize,
+                                          CCDhUserPubKey_t *tmpPubKey_ptr,
+                                          CCDhPrimeData_t  *tmpPrimeData_ptr,
+                                          uint8_t *SecretKey_ptr,
+                                          size_t *SecretKeySize_ptr)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        CCCommonCmpCounter_t cmpResult;
+        uint8_t one = 1;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* if an argument pointer is NULL return an error */
+        if (ClientPrvKey_ptr == NULL || ServerPubKey_ptr == NULL ||
+            Prime_ptr == NULL || tmpPubKey_ptr == NULL ||
+            tmpPrimeData_ptr == NULL || SecretKey_ptr == NULL || SecretKeySize_ptr == NULL)
+
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+
+        /*If an argument buffer size is zero return an error*/
+        if (PrimeSize == 0 || PrimeSize > CC_DH_MAX_MOD_SIZE_IN_BYTES ||
+            ClientPrvKeySize == 0 || ClientPrvKeySize > PrimeSize ||
+            ServerPubKeySize == 0 || ServerPubKeySize > PrimeSize ||
+            *SecretKeySize_ptr == 0 || *SecretKeySize_ptr < PrimeSize)
+                return CC_DH_INVALID_ARGUMENT_SIZE_ERROR;
+
+        /* 1. verifying that the private exponent is less than modulus, else subtract the modulus */
+        cmpResult = CC_CommonCmpMsbUnsignedCounters( ClientPrvKey_ptr, ClientPrvKeySize,
+                                                        Prime_ptr, PrimeSize );
+
+        if (cmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+                /* subtract modulus prime from private key and set result in temp buffer */
+                CC_CommonSubtractMSBUint8Arrays(ClientPrvKey_ptr, ClientPrvKeySize, Prime_ptr, PrimeSize,
+                                                   (uint8_t*)tmpPrimeData_ptr->DataIn);
+
+                /* build the Data for the Exp operation.
+                  Note: the user private key is set into public key structure */
+                Error = CC_RsaPubKeyBuild(
+                                             tmpPubKey_ptr,
+                                             (uint8_t*)tmpPrimeData_ptr->DataIn,
+                                             ClientPrvKeySize,
+                                             Prime_ptr,
+                                             PrimeSize);
+        } else {
+                /* build the Data for the Exp operation */
+                Error = CC_RsaPubKeyBuild(
+                                             tmpPubKey_ptr,
+                                             ClientPrvKey_ptr,
+                                             ClientPrvKeySize,
+                                             Prime_ptr,
+                                             PrimeSize);
+        }
+
+        if (Error != CC_OK)
+                goto End;
+
+        /* 3. create: Secret_key (or shared secret value) = Server_public_key *
+        *  ^ Prv mod Prime                                                    */
+        Error = CC_RsaPrimEncrypt(
+                                     tmpPubKey_ptr, /* Note: this is the private key */
+                                     tmpPrimeData_ptr,
+                                     ServerPubKey_ptr,
+                                     ServerPubKeySize,
+                                     SecretKey_ptr);
+
+        if (Error != CC_OK)
+                goto End;
+
+        /* Secret key (shared secret value) size in bytes, including leading  *
+        *  zeroes                                                             */
+        *SecretKeySize_ptr = PrimeSize;
+
+        /* Note: X9.42 7.5.1 requires that shared secret value != 1 */
+        cmpResult = CC_CommonCmpMsbUnsignedCounters(
+                                                &one, 1/*size*/,
+                                                SecretKey_ptr, PrimeSize);
+
+        if (cmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+                Error = CC_DH_ARGUMENT_BUFFER_SIZE_ERROR;
+                goto End;
+        }
+
+End:
+        /* delete secure sensitive data */
+        CC_PalMemSetZero(tmpPubKey_ptr, sizeof(CCDhUserPubKey_t));
+        CC_PalMemSetZero(tmpPrimeData_ptr, sizeof(CCDhPrimeData_t));
+
+        return Error;
+}  /* END of CC_DhGetSecretKey function */
+
+
+
+CEXPORT_C CCError_t CC_DhX942GetSecretData(
+                                                uint8_t                  *ClientPrvKey_ptr,
+                                                size_t                  ClientPrvKeySize,
+                                                uint8_t                  *ServerPubKey_ptr,
+                                                size_t                  ServerPubKeySize,
+                                                uint8_t                  *Prime_ptr,
+                                                size_t                  PrimeSize,
+                                                CCDhOtherInfo_t      *otherInfo_ptr,
+                                                CCDhHashOpMode_t     hashMode,
+                                                CCDhDerivationFuncMode_t DerivFunc_mode,
+                                                CCDhTemp_t           *tmpBuff_ptr,
+                                                uint8_t                  *SecretKeyingData_ptr,
+                                                size_t                   SecretKeyingDataSize )
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        size_t  SecretKeySize = PrimeSize;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check pointers */
+        if (tmpBuff_ptr == NULL || SecretKeyingData_ptr == NULL)
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+
+        /*check that the size of derived secret key is not NULL  */
+        if (SecretKeyingDataSize == 0)
+                return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
+
+        /*check that the keying data size is not too large  */
+        if (SecretKeyingDataSize > CC_DH_MAX_SIZE_OF_KEYING_DATA)
+                return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
+
+        /*Call the PKCS#3 get secret key function*/
+        Error = CC_DhGetSecretKey(
+                                    ClientPrvKey_ptr,
+                                    ClientPrvKeySize,
+                                    ServerPubKey_ptr,
+                                    ServerPubKeySize,
+                                    Prime_ptr,
+                                    PrimeSize,
+                                    &tmpBuff_ptr->UserPubKey,
+                                    &tmpBuff_ptr->PrimeData,
+                                    (uint8_t*)tmpBuff_ptr->TempBuff,
+                                    &SecretKeySize);
+
+        if (Error != CC_OK)
+                goto ExitOnError;
+
+
+        /*Let the keydataSize from the previous function determine the key data length in the next function*/
+        Error = CC_KdfKeyDerivFunc(
+                                     (uint8_t*)tmpBuff_ptr->TempBuff,
+                                     SecretKeySize,
+                                     otherInfo_ptr,
+                                     MakeKDFHashMode(hashMode),
+                                     MakeKDFDeriveFuncMode(DerivFunc_mode),
+                                     SecretKeyingData_ptr,
+                                     SecretKeyingDataSize);
+
+ExitOnError:
+
+        CC_PalMemSetZero(tmpBuff_ptr, sizeof(CCDhTemp_t));
+
+
+        return Error;
+
+}/* END OF _DX_DH_X942_GetSecretData */
+
+
+CEXPORT_C CCError_t CC_DhX942HybridGetSecretData(
+                                                      uint8_t            *ClientPrvKey_ptr1,
+                                                      size_t             ClientPrvKeySize1,
+                                                      uint8_t            *ClientPrvKey_ptr2,
+                                                      size_t             ClientPrvKeySize2,
+                                                      uint8_t            *ServerPubKey_ptr1,
+                                                      size_t             ServerPubKeySize1,
+                                                      uint8_t            *ServerPubKey_ptr2,
+                                                      size_t             ServerPubKeySize2,
+                                                      uint8_t            *Prime_ptr,
+                                                      size_t             PrimeSize,
+                                                      CCDhOtherInfo_t  *otherInfo_ptr,
+                                                      CCDhHashOpMode_t hashMode,
+                                                      CCDhDerivationFuncMode_t DerivFunc_mode,
+                                                      CCDhHybrTemp_t   *tmpDhHybr_ptr,
+                                                      uint8_t            *SecretKeyingData_ptr,
+                                                      size_t             SecretKeyingDataSize)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /*The assignment to Prime size is according to the real size of the buffer SecretKeyData_ptr*/
+        size_t SecretKeyDataSize1 = PrimeSize;
+        size_t SecretKeyDataSize2 = PrimeSize;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check pointers */
+        if (tmpDhHybr_ptr == NULL || SecretKeyingData_ptr == NULL)
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+
+        /*check that the size of derived secret key is not NULL  */
+        if (SecretKeyingDataSize == 0)
+                return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
+
+        /*check that the keying data size is not too large  */
+        if (SecretKeyingDataSize > CC_DH_MAX_SIZE_OF_KEYING_DATA)
+                return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
+
+        /* Note: other input parameters will be shecked in called functions */
+
+        /* get shared secret key (value) 1 */
+        Error = CC_DhGetSecretKey(
+                                    ClientPrvKey_ptr1,
+                                    ClientPrvKeySize1,
+                                    ServerPubKey_ptr1,
+                                    ServerPubKeySize1,
+                                    Prime_ptr,
+                                    PrimeSize,
+                                    &tmpDhHybr_ptr->UserPubKey,
+                                    &tmpDhHybr_ptr->PrimeData,
+                                    (uint8_t*)&tmpDhHybr_ptr->TempBuff,
+                                    &SecretKeyDataSize1);
+        if (Error != CC_OK)
+                goto End;
+
+        /* get shared secret key (value) 2 */
+        Error = CC_DhGetSecretKey(
+                                    ClientPrvKey_ptr2,
+                                    ClientPrvKeySize2,
+                                    ServerPubKey_ptr2,
+                                    ServerPubKeySize2,
+                                    Prime_ptr,
+                                    PrimeSize,
+                                    &tmpDhHybr_ptr->UserPubKey,
+                                    &tmpDhHybr_ptr->PrimeData,
+                                    (uint8_t*)&tmpDhHybr_ptr->TempBuff+SecretKeyDataSize1,
+                                    &SecretKeyDataSize2);
+        if (Error != CC_OK)
+                goto End;
+
+        /* Derive the secret key according to the secret key size and value   *
+        *  key1||key2                                 */
+
+
+        Error = CC_KdfKeyDerivFunc(
+                                     (uint8_t*)&tmpDhHybr_ptr->TempBuff,
+                                     (uint16_t)(SecretKeyDataSize1 + SecretKeyDataSize2),
+                                     otherInfo_ptr,
+                                     MakeKDFHashMode(hashMode),
+                                     MakeKDFDeriveFuncMode(DerivFunc_mode),
+                                     SecretKeyingData_ptr,
+                                     SecretKeyingDataSize );
+
+End:
+        CC_PalMemSetZero(tmpDhHybr_ptr, sizeof(CCDhHybrTemp_t));
+
+        return Error;
+
+}/* END OF CC_DhX942HybridGetSecretData */
+
+
+CEXPORT_C CCError_t CC_DhCheckPubKey(
+                                         uint8_t              *modP_ptr,             /*in */
+                                         size_t               modPsizeBytes,        /*in */
+                                         uint8_t              *orderQ_ptr,           /*in */
+                                         size_t               orderQsizeBytes,      /*in */
+                                         uint8_t              *pubKey_ptr,           /*in */
+                                         size_t               pubKeySizeBytes,      /*in */
+                                         CCDhTemp_t       *tempBuff_ptr          /*in */)
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /* size in bits of modulus P and order Q and public key */
+        uint32_t  modPsizeBits;
+        uint32_t  orderQsizeBits;
+        uint32_t  pubKeySizeBits;
+
+        /* comparing result */
+        int  cmpRes;
+        CCCommonCmpCounter_t cmpCounters;
+        CCDhPubKey_t  *tmpPubKey_ptr;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /*------------------------------- */
+        /* Step 1. Check input pointers   */
+        /*------------------------------- */
+
+        /* check pointers: modP, generator and tempBuff. Note: other pointers may be NULL  */
+        if (modP_ptr == NULL ||
+            orderQ_ptr == NULL ||
+            pubKey_ptr == NULL ||
+            tempBuff_ptr == NULL) {
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+        }
+        /* temp public key buffer */
+        tmpPubKey_ptr = (CCDhPubKey_t*)((void*)&tempBuff_ptr->UserPubKey.PublicKeyDbBuff);
+
+        /*----------------------------------------------------------- */
+        /* Step 2. Calculate and check the sizes of modulus and order */
+        /*----------------------------------------------------------- */
+        /* preliminary check */
+        if (modPsizeBytes > CC_DH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / 8)
+                return CC_DH_INVALID_MODULUS_SIZE_ERROR;
+
+        if (orderQsizeBytes > modPsizeBytes)
+                return CC_DH_INVALID_ORDER_SIZE_ERROR;
+
+        if (pubKeySizeBytes > modPsizeBytes)
+                return CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
+
+
+        /* convert input data into LSW arrays */
+        /*------------------------------------*/
+// RL - restrict zeroing
+        CC_PalMemSetZero( tempBuff_ptr, sizeof(CCDhTemp_t) );
+
+        Error = CC_CommonConvertMsbLsbBytesToLswMswWords(tmpPubKey_ptr->n, modPsizeBytes, modP_ptr, modPsizeBytes);
+        if (Error) {
+                Error = CC_DH_INVALID_MODULUS_SIZE_ERROR;
+                return Error;
+    }
+
+        Error = CC_CommonConvertMsbLsbBytesToLswMswWords(tmpPubKey_ptr->e, modPsizeBytes, orderQ_ptr, orderQsizeBytes);
+        if (Error) {
+                Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
+                goto End;
+    }
+
+        Error = CC_CommonConvertMsbLsbBytesToLswMswWords(tempBuff_ptr->PrimeData.DataIn, modPsizeBytes, pubKey_ptr, pubKeySizeBytes);
+        if (Error) {
+                Error = CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
+                goto End;
+    }
+
+        /* calculate sizes in bits of input parameters */
+        modPsizeBits   = CC_MIN(8*modPsizeBytes, CC_CommonGetWordsCounterEffectiveSizeInBits(tmpPubKey_ptr->n, (uint16_t)modPsizeBytes/4));
+        orderQsizeBits = CC_MIN(8*orderQsizeBytes, CC_CommonGetWordsCounterEffectiveSizeInBits(tmpPubKey_ptr->e, (uint16_t)(orderQsizeBytes+3)/4));
+        pubKeySizeBits = CC_MIN(8*pubKeySizeBytes, CC_CommonGetWordsCounterEffectiveSizeInBits(tempBuff_ptr->PrimeData.DataIn, (uint16_t)(pubKeySizeBytes+3)/4));
+
+        /* check sizes */
+        if (modPsizeBits < CC_DH_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ||
+            modPsizeBits % 256 != 0 ||
+            modPsizeBits > CC_DH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS) {
+                Error = CC_DH_INVALID_MODULUS_SIZE_ERROR;
+                goto End;
+        }
+
+        if (orderQsizeBits < CC_DH_SEED_MIN_SIZE_IN_BITS ||
+            orderQsizeBits % 32 != 0) {
+                Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
+                goto End;
+        }
+
+        if (pubKeySizeBits > modPsizeBits ||
+            pubKeySizeBits <= 1) {
+                Error = CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
+                goto End;
+        }
+
+
+        /*----------------------------------------------------------- */
+        /* Step 2. Check value of public key:   pubKey < P-1          */
+        /*         Note: pubKey > 1 already is checked above          */
+        /*----------------------------------------------------------- */
+
+        /* decrement modulus in temp buffer n (in little endianness). Note: the modulus is odd */
+        tmpPubKey_ptr->n[0] -= 1;
+
+        /* compare pub key saved in temp buff e to P-1 */
+        cmpCounters = CC_CommonCmpLsWordsUnsignedCounters(
+                                                            tmpPubKey_ptr->e, /* counter1 - pubKey */
+                                                            (uint16_t)(pubKeySizeBytes+3)/4,
+                                                            tmpPubKey_ptr->n, /* counter2 - (P-1) */
+                                                            (uint16_t)modPsizeBytes/4);
+
+        if (cmpCounters != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+                Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
+                goto End;
+        }
+
+        /*----------------------------------------------------*/
+        /* Step 4. Initialization of PubKey and PrivData      */
+        /*         structures for exponentiation              */
+        /*----------------------------------------------------*/
+
+        /* increment (revert) modulus in temp buffer n (in little endianness) */
+        tmpPubKey_ptr->n[0] += 1;
+
+        /* set modulus and exponent sizes in DH_PubKey structure  */
+        tmpPubKey_ptr->nSizeInBits = modPsizeBits;
+        tmpPubKey_ptr->eSizeInBits = orderQsizeBits;
+
+        /*  initialize the H value in LLF of PubKey for exponentiation  */
+        Error = RsaInitPubKeyDb( tmpPubKey_ptr );
+
+        if (Error != CC_OK) {
+                Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
+                goto End;
+        }
+
+        /*-----------------------------------------------------------*/
+        /* Step 3. Calculate Res = Key ^ Q mod P , if Res == 1,      */
+        /*         then key is valid, else non valid                 */
+        /*-----------------------------------------------------------*/
+
+        /* exponentiation DataOut = DataIn ^ exp mod n */
+        Error = RsaExecPubKeyExp(tmpPubKey_ptr, &tempBuff_ptr->PrimeData);
+
+        if (Error != CC_OK) {
+                Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
+                goto End;
+        }
+
+        /* set 1 to PubKey_ptr->n buffer (used as temp buffer) */
+        CC_PalMemSetZero((uint8_t*)&tmpPubKey_ptr->n, modPsizeBytes);
+        tmpPubKey_ptr->n[0] = 1;
+
+        /* compare DataOut to 1: */
+        cmpRes = CC_CommonCmpLsWordsUnsignedCounters(
+                                                       tempBuff_ptr->PrimeData.DataOut, modPsizeBytes/4, tmpPubKey_ptr->n, modPsizeBytes/4);
+
+        if (cmpRes != 0)  {/* if Res != 1 */
+                Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
+                goto End;
+    }
+
+End:
+
+        /* clean temp buffers */
+        CC_PalMemSetZero(tempBuff_ptr, sizeof(CCDhTemp_t));
+
+        return Error;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/dh/cc_dh_kg.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/dh/cc_dh_kg.c
new file mode 100644
index 0000000..3ce09d1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/dh/cc_dh_kg.c
@@ -0,0 +1,1547 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include "cc_rnd_common.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_hash_defs.h"
+#include "pki.h"
+#include "rsa.h"
+#include "rsa_public.h"
+#include "rsa_private.h"
+#include "cc_dh_error.h"
+#include "cc_dh.h"
+#include "cc_dh_kg.h"
+#include "cc_rnd_error.h"
+#include "cc_fips_defs.h"
+
+
+/************************ Defines *******************************/
+
+/************************ Enums *********************************/
+
+/************************ macros ********************************/
+
+/** @brief This macro is required to remove compilers warnings if the HASH or PKI is not supported */
+
+
+/*********************** Global data  ***************************/
+
+/************* External functions prototypes  *****************************/
+
+CCError_t RndGenerateWordsArrayInRange(CCRndContext_t *rndContext_ptr,
+                                              uint32_t   rndSizeInBits,
+                                              uint32_t  *maxVect_ptr,
+                                              uint32_t  *rndVect_ptr,
+                                              uint32_t  *tmp_ptr);
+
+/******************************************************************************************/
+/************************         Private Functions          ******************************/
+/******************************************************************************************/
+
+/********************************************************************************/
+/**
+ *      The function adds value to the number N, presented as bytes array in the buffer,
+ *      given by uint32_t pointer n_ptr, where MSbyte is a most left one.
+ *
+ *      Algorithm:
+ *          n = (N + val) mod 2^(8*sizeBytes).
+ *      Assumed: The array and its size are aligned to 32-bit words.
+ *           val > 0.
+ *
+ * @author reuvenl (7/1/2012)
+ *
+ * @param n_ptr
+ * @param sizeBytes
+ * @param val - value to add
+ *
+ * @return carry from last addition
+ */
+static uint32_t DhKgAddValueToMsbLsbBytesArray(uint32_t *arr_ptr, uint32_t val, uint32_t sizeBytes)
+{
+        int32_t i;
+        uint32_t *ptr = (uint32_t*)arr_ptr;
+        uint32_t tmp, curr;
+
+        for (i = sizeBytes/CC_32BIT_WORD_SIZE - 1; i >= 0; i--) {
+
+#ifndef BIG__ENDIAN
+                tmp = curr = CC_COMMON_REVERSE32(ptr[i]);
+#else
+                tmp = curr = ptr[i];
+#endif
+                tmp += val;
+
+#ifndef BIG__ENDIAN
+                ptr[i] = CC_COMMON_REVERSE32(tmp);
+#else
+                ptr[i] = tmp;
+#endif
+
+                if (tmp < curr) {
+                        val = 1;
+                } else {
+                        val = 0;
+                }
+        }
+
+        return val; /* carry */
+}
+
+
+/********************************************************************************/
+/**
+ * @brief This function returns the effective size in bits of the MSB bytes array.
+ *
+ *        Assumed, that MSB > 0 is stored in the most left cell in the array.
+ *
+ * @param[in] arr_ptr -  The counter buffer.
+ * @param[in] sizeInBytes -  The counter size in bytes.
+ *
+ * @return result - The effective counters size in bits.
+ */
+
+static uint32_t DhKgGetSizeInBitsOfMsbLsbBytesArray(uint8_t  *arr_ptr,
+                                                         uint32_t  sizeInBytes)
+{
+        /* FUNCTION LOCAL DECLERATIONS */
+
+        /* loop variable */
+        int32_t i;
+
+        /* the effective size in bits */
+        uint32_t sizeInBits = 8 * sizeInBytes;
+
+        /* the effective MS byte */
+        uint8_t msbVal = arr_ptr[0], mask = 0x80;
+
+        /* FUNCTION LOGIC */
+
+        /* adjusting the effective size in bits */
+        for (i = 0; i < 8 ; i++) {
+                /* if the MS bit is set exit the loop */
+                if (msbVal & mask) {
+                        break;
+                }
+
+                sizeInBits--;
+
+                mask >>= 1;
+
+        }
+
+        return sizeInBits;
+
+}/* END OF  DhKgGetSizeInBitsOfMsbLsbBytesArray */
+
+
+
+/** @brief The function finds prime number Q for key generation according to X9.42-2001.
+ *
+ *
+ * @param[in]  rndContext_ptr     - Pointer to the RND context buffer.
+ * @param[in]  QSizeBits          - The size of order of generator in bits. According to ANSI X9.42:
+ *                                  m must be multiple of 32 bits and 160 <= m. According to ANSI X9.30-1:
+ *                                  m = 160 bit. We allow using Q as multiplies of 32 in range 160 - 256 bits (see
+ *                                  FIPS 186-4 Tab. C.1).
+ * @param[in]  seedSizeBits      - The  seed size in bits.
+ * @param[in]  generateSeed       - The  flag defining whether the seed to be generated (1) or not (0),
+ * @param[out] Q_ptr              - The pointer to the order Q of generator. The buffer must be aligned to 4 bytes.
+ *                                  Note: The order Q is set as Words array, where LSWord is left most.
+ * @param[out] S_ptr              - The random seed used for generation of primes. The buffer must be aligned to 4 bytes.
+ *                                  Note: The seed is set in the buffer as BE bytes array.
+ * @param[in]  TempBuff1_ptr      - The temp buffer of size not less than max modulus size, aligned to 4 bytes.
+ * @param[in]  TempBuff2_ptr      - The temp buffer of size not less than max
+ *                                  modulus size, aligned to 4 bytes.
+ * @param[in]  TempBuff3_ptr      - The large temp buffer (aligned to 4 bytes) of size:
+ *                                    - on HW platform not less than 8*CC_DH_MAX_MOD_BUFFER_SIZE_IN_WORDS.
+ *                                    - on SW platform not less than 41*CC_DH_MAX_MOD_BUFFER_SIZE_IN_WORDS.
+ *
+ *   Note: The function is static, sizes of its input arrays (mod, ord, seed) are checked in
+ *         caller functions and don't need to be chcked again.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a predefined error code.
+ *
+ *
+ */
+static CCError_t DhX942FindPrimeQ(
+                                        CCRndContext_t *rndContext_ptr,
+                                        uint32_t          QsizeBits,           /*in */
+                                        uint32_t          seedSizeBits,        /*in */
+                                        uint32_t          generateSeed,        /*in */
+                                        uint32_t         *Q_ptr,               /*out*/
+                                        uint8_t          *S_ptr,               /*out*/
+                                        uint32_t         *TempBuff1_ptr,       /*in */
+                                        uint32_t         *TempBuff2_ptr,       /*in - large buffer*/
+                                        uint32_t         *TempBuff3_ptr )      /*in*/
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error;
+
+        /* size of order in 160-bit blocks: M1 */
+        uint32_t  M1;
+
+        /* primality flag (if prime, then isPrime = 1, else 0 ) */
+        int8_t  isPrime;
+
+        /* flag of first hash calculating */
+        uint8_t  isFirst = 1;
+
+
+        /* HASH input and result pointers */
+        uint32_t  *hashDataIn1_ptr, *hashDataIn2_ptr;
+        CCHashResultBuf_t   *hashRes1_ptr, *hashRes2_ptr;
+
+        /* current data pointer and sizes */
+        uint8_t  *current_ptr;
+
+        /* order size in bytes and in words */
+        uint32_t  QsizeBytes;
+
+        /* exact seed size in bits and in words */
+        uint32_t  seedSizeBytes, remainingSize;
+
+        /* shift value (in bits) for adding counter to seed */
+        uint32_t shift;
+        uint8_t  mask, mask1;
+
+        /* loop counters */
+        uint32_t i, j;
+        uint32_t countMilRabTests;
+
+
+        CCRndState_t   *rndState_ptr;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+        /* FUNCTION  LOGIC */
+
+        Error = CC_OK;
+
+        /* check parameters */
+        if (rndContext_ptr == NULL)
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+        if (rndContext_ptr->rndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        rndState_ptr = (CCRndState_t *)(rndContext_ptr->rndState);
+        RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+
+        /* Step 1. Check input parameters */
+        /*------------------------------- */
+
+        /* check pointers: modP, generator and tempBuff. Note: other pointers may be NULL  */
+        if (Q_ptr == NULL ||
+            S_ptr == NULL ||
+            TempBuff1_ptr == NULL ||
+            TempBuff2_ptr == NULL ||
+            TempBuff3_ptr == NULL) {
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+        }
+
+        /* --------------------------------- */
+        /*  Step 2.  Initializations         */
+        /* --------------------------------- */
+
+        /* order and seed sizes */
+        QsizeBytes = CALC_FULL_BYTES(QsizeBits);
+        seedSizeBytes = CALC_FULL_BYTES(seedSizeBits);
+
+        /* order size M1 in 160-bit blocks (rounded up) */
+        M1 = (QsizeBits + CC_DH_SEED_MIN_SIZE_IN_BITS - 1) / CC_DH_SEED_MIN_SIZE_IN_BITS;
+
+        /* if M1 > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / CC_DH_SEED_MIN_SIZE_IN_BITS,
+        *  then return error. This checking is for preventing KW warnings   */
+        if (M1 > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / CC_DH_SEED_MIN_SIZE_IN_BITS) {
+                return CC_DH_INVALID_ORDER_SIZE_ERROR;
+        }
+
+        /* RL  seed size must allow adding counters for hashing without overflow of temp buffers:*/
+        /* we limit this size relating to max buffer */
+        if (seedSizeBytes > (CC_DH_MAX_MOD_SIZE_IN_WORDS - 1) * sizeof(uint32_t))
+                return CC_DH_INVALID_SEED_SIZE_ERROR;
+
+        /* zeroing  Q buffer */
+        CC_PalMemSetZero(Q_ptr, QsizeBytes);
+
+        /* set HASH pointers to temp buffer */
+        hashDataIn1_ptr = TempBuff1_ptr;
+        hashDataIn2_ptr = TempBuff2_ptr;
+        hashRes1_ptr = (CCHashResultBuf_t*)TempBuff3_ptr;
+        hashRes2_ptr = hashRes1_ptr + 1;
+
+        /*------------------------------- */
+        /* Step 3. Create random prime Q  */
+        /*------------------------------- */
+
+        /* check size and copy seed S into HASH input buffers */
+        if (generateSeed != 1) {
+                if (seedSizeBits != DhKgGetSizeInBitsOfMsbLsbBytesArray(S_ptr, seedSizeBytes))
+                        return CC_DH_INVALID_SEED_SIZE_ERROR;
+
+                /* check that (seed + DH_MAX_HASH_COUNTER_VALUE) is less than
+                   2^seedSizeBits, i.e. prevent addition overflow in
+                   generation process */
+                CC_PalMemCopy((uint8_t *)hashDataIn2_ptr, S_ptr, seedSizeBytes);
+                if (DhKgAddValueToMsbLsbBytesArray(hashDataIn2_ptr, DH_SEED_MAX_ADDING_VAL, seedSizeBytes) != 0)
+                        return CC_DH_PASSED_INVALID_SEED_ERROR;
+        }
+
+        /* shift value to bit position of MSbit of the seed  */
+        shift = 8*seedSizeBytes - seedSizeBits;
+        mask = 0xFF >> shift;
+        mask1 = 0x80 >> shift;
+
+        /* initialize isPrime, orderSizeInBlocks, and Q buffer */
+        isPrime = CC_FALSE;
+
+        /* set count of M-R tests for Q sccording FIPS 186-4 C.3: Tab. C.1. */
+        if (QsizeBits <= 160) {
+                countMilRabTests = 19;
+        } else if (QsizeBits <= 224) {
+                countMilRabTests = 24;
+        } else if (QsizeBits <= 256) {
+                countMilRabTests = 27;
+        } else {
+                countMilRabTests = 28;
+        }
+
+        /* Step 3.1. Try Q candidates     */
+        /*--------------------------------*/
+        while (isPrime != CC_TRUE) {
+
+                uint32_t isSeedValid = 0;
+
+                /* Step 3.1.1. Create random seed  S  */
+                if (generateSeed == 1) {
+                        /* generation of random vector */
+                        while (isSeedValid == 0) {
+                                Error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char *)S_ptr, (size_t)seedSizeBytes);
+
+                                if (Error != CC_OK) {
+                                        goto EndWithError;
+                                }
+
+                                /* Set the MS bit of S and provide exact size of seed in bits */
+                                S_ptr[0] = (S_ptr[0] & mask) | mask1;
+
+                                /* check that (seed + DH_MAX_HASH_COUNTER_VALUE) is less than
+                                   2^seedSizeBits, i.e. prevent addition overflow */
+                                CC_PalMemCopy((uint8_t *)hashDataIn2_ptr, S_ptr, seedSizeBytes);
+                                if (DhKgAddValueToMsbLsbBytesArray(hashDataIn2_ptr, DH_SEED_MAX_ADDING_VAL, seedSizeBytes) == 0)
+                                        isSeedValid = 1;
+                        }
+
+                } else if (isFirst == 0) {
+                        return  CC_DH_PASSED_INVALID_SEED_ERROR;
+                }
+
+
+
+                /* copy seed into hashDataIn1/2 buffers */
+                CC_PalMemCopy((uint8_t *)hashDataIn1_ptr, S_ptr, seedSizeBytes);
+                CC_PalMemCopy((uint8_t *)hashDataIn2_ptr, S_ptr, seedSizeBytes);
+                DhKgAddValueToMsbLsbBytesArray(hashDataIn2_ptr, M1, seedSizeBytes);
+
+                /* set current pointer and size for copying HASH results into *
+                *  TempBuff3 as big endian bytes                  */
+                current_ptr = &((uint8_t*)Q_ptr)[QsizeBytes - CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES];
+                remainingSize = QsizeBytes;
+
+                /* Step 3.1.2. Create Q candidate:  For i=0 to M1 do:
+                Q = Q + (SHA1(S+i) XOR SHA1(S+M1+i))*(2^(160*i)) */
+                for (i = 0; i < M1; i++) {
+                        if (i != 0) {
+                                /* increment hashDataIn1 and hashDataIn2 by 1 *
+                                *  starting from second cycle             */
+                                DhKgAddValueToMsbLsbBytesArray(hashDataIn1_ptr, 1, seedSizeBytes);
+                                DhKgAddValueToMsbLsbBytesArray(hashDataIn2_ptr, 1, seedSizeBytes);
+                        }
+
+                        /* calculate first HASH result */
+                        Error = CC_Hash(
+                                         CC_HASH_SHA1_mode,
+                                         (uint8_t *)hashDataIn1_ptr,
+                                         seedSizeBytes,
+                                         *hashRes1_ptr );
+
+                        if (Error != CC_OK) {
+                                goto EndWithError;
+                        }
+
+
+                        /* calculate  second HASH result */
+                        Error = CC_Hash(
+                                         CC_HASH_SHA1_mode,
+                                         (uint8_t*)hashDataIn2_ptr,
+                                         seedSizeBytes,
+                                         *hashRes2_ptr);
+
+                        if (Error != CC_OK) {
+                                goto EndWithError;
+                        }
+
+                        /* XOR HASH results */
+                        for (j = 0; j < CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS; j++) {
+                                (*hashRes1_ptr)[j] ^= (*hashRes2_ptr)[j];
+                        }
+
+                        /* copying HASH results into Q buffer */
+                        if (remainingSize >= CC_DH_SEED_MIN_SIZE_IN_BYTES) {
+                                CC_PalMemCopy(current_ptr, hashRes1_ptr, CC_DH_SEED_MIN_SIZE_IN_BYTES);
+                                remainingSize -=  CC_DH_SEED_MIN_SIZE_IN_BYTES;
+                                current_ptr -= CC_DH_SEED_MIN_SIZE_IN_BYTES;
+                        } else {   /* copy remaining low bytes to Q_ptr */
+                                CC_PalMemCopy((uint8_t*)Q_ptr,
+                                                (uint8_t*)hashRes1_ptr + CC_DH_SEED_MIN_SIZE_IN_BYTES - remainingSize,
+                                                remainingSize);
+                        }
+
+                        /* set flag */
+                        isFirst = 0;
+
+                } /* end of for() loop */
+
+                /* set the High and Low bits of Q equal to 1 */
+                ((uint8_t*)Q_ptr)[0] |= 0x80;           /* MS bit - big endian */
+                ((uint8_t*)Q_ptr)[QsizeBytes-1] |= 0x01;  /* LS bit - big endian */
+
+
+                /* Step 3.2. Perform primality tests on Q: 8 Miller-Rabin and 1 Lucas tests (X9.42-2001) */
+                /*---------------------------------------------------------------------------------------*/
+
+                /* convert Q to words */
+                Error = CC_CommonConvertMsbLsbBytesToLswMswWords(Q_ptr, QsizeBytes, (uint8_t*)Q_ptr, QsizeBytes);
+                if (Error) {
+                        Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
+                        goto EndWithError;
+                }
+
+                Error = RsaPrimeTestCall(
+                                                 rndContext_ptr,
+                                                 Q_ptr,
+                                                 QsizeBytes/CC_32BIT_WORD_SIZE,
+                                                 countMilRabTests,
+                                                 &isPrime,
+                                                 TempBuff2_ptr,
+                                                 CC_DH_PRIME_TEST_MODE);
+
+                if (Error != CC_OK) {
+                        Error = CC_DH_PRIME_Q_GENERATION_FAILURE_ERROR;
+                        goto EndWithError;
+                }
+
+        } /* END of while() loop */
+
+
+        /* End of function */
+
+        return Error;
+
+        EndWithError:
+
+        CC_PalMemSetZero((uint8_t*)Q_ptr, QsizeBytes);
+        CC_PalMemSetZero((uint8_t*)S_ptr, seedSizeBytes);
+
+        return Error;
+
+} /* End of DhX942FindPrimeQ */
+
+
+/******************************************************************************************/
+/**
+ * @brief The function finds prime modulus P for key generation according to X9.42-2001.
+ *
+ * @param[in]  rndContext_ptr     - Pointer to the RND context buffer.
+ * @param[in]  modPSizeBits       - The  modulus (prime) P size in bits equal 256*n, where n >= 4.
+ * @param[in]  QSizeBbytes        - The size of order of generator in bytes. Must be m >= 20 bytes and
+ *                                  multiple of 4 bytes. According to ANSI X9.30-1: size = 20.
+ * @param[in]  orderQSizeBits     - The size of order of generator in bits. Must be m >= 160 and
+ *                                  multiple of 32 bits. According to ANSI X9.30-1: m = 160.
+ * @param[in]  seedSizeBits       - The  seed size in bits (the size must be:  seedSizeBits >= 160,
+ *                                  seedSizeBits <= modPSizeBits - 1 (the last required by implementation).
+ * @param[out] P_ptr              - The prime modulus P of structure P = j*Q + 1, where Q is prime
+ *                                  and j is an integer.The buffer must be aligned to 4 bytes.
+ * @param[out] Q_ptr              - The pointer to the order Q of generator. The buffer must be aligned to 4 bytes.
+ * @param[out] S_ptr              - The random seed used for generation of primes. The buffer must be aligned to 4 bytes.
+ * @param[out] pgenCounter_ptr    - The pointer to counter of tries to generate the primes.
+ * @param[in]  TempBuff1_ptr      - The temp buffer of size not less than max modulus size, aligned to 4 bytes.
+ * @param[in]  TempBuff2_ptr      - The large temp buffer of size:
+ *                                - on HW platform not less than 8*CC_DH_MAX_MOD_BUFFER_SIZE_IN_WORDS.
+ *                                - on SW platform not less than 41*CC_DH_MAX_MOD_BUFFER_SIZE_IN_WORDS.
+ * @param[in]  TempBuff3_ptr      - The temp buffer of size: 2*CC_DH_MAX_MOD_BUFFER_SIZE_IN_WORDS.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a predefined error code.
+ *
+ *   Note: The function is static, therefore sizes of its input arrays (mod, ord, seed) are checked in
+ *         caller functions and don't need to be chcked again.
+ *
+ */
+static CCError_t DhX942FindPrimeP(
+                                        CCRndContext_t *rndContext_ptr,
+                                        uint32_t          modPsizeBits,         /*in */
+                                        uint32_t          orderQsizeBits,       /*in */
+                                        uint32_t          seedSizeBits,         /*in */
+                                        uint32_t          *P_ptr,               /*out*/
+                                        uint32_t          *Q_ptr,               /*out*/
+                                        uint8_t           *S_ptr,               /*out*/
+                                        uint32_t          *pgenCounter_ptr,     /*out*/
+                                        uint32_t          *TempBuff1_ptr,       /*in */
+                                        uint32_t          *TempBuff2_ptr,       /*in - large buffer*/
+                                        uint32_t          *TempBuff_ptr )       /*in*/ // RL used in SW only
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error;
+
+        /* mod size in bytes and in words */
+        uint32_t  modSizeBytes, modSizeWords;
+
+        /* seed size in bytes and words */
+        uint32_t seedSizeBytes;
+
+        /* mod size in 160 bits blocks (rounded up) */
+        uint32_t  L1;
+
+        /* order sizes: M1 - in 160-bit blocks (rounded up) */
+        uint32_t  orderSizeWords, M1;
+
+        /* flag of first hash calculating */
+        uint8_t  isFirst = 1;
+
+        /* primality flag (if prime, then isPrime = 1, else 0 ) */
+        uint8_t  isPrime;
+
+        /* HASH input and result pointers */
+        uint32_t  *hashDataIn_ptr;
+        CCHashResultBuf_t   *hashRes_ptr;
+
+        /* current data pointer and size */
+        uint8_t  *current_ptr;
+        int32_t  remainingSize;
+
+        CCCommonCmpCounter_t  cmpRes;
+
+        /* loop counter and carry */
+        uint32_t i, carry;
+
+        /* temp buffers pointers */
+        uint32_t  *TempBuff3_ptr, *TempBuff4_ptr;
+        uint32_t  countMilRabTests;
+
+        /* FUNCTION  LOGIC */
+
+        Error = CC_OK;
+
+
+        /* --------------------------------- */
+        /* Step 1. Check input parameters    */
+        /*---------------------------------- */
+
+        /* check pointers: modP, generator and tempBuff. Note: other pointers may be NULL  */
+        if (P_ptr == NULL ||
+            Q_ptr == NULL ||
+            S_ptr == NULL ||
+            pgenCounter_ptr == NULL ||
+            TempBuff1_ptr == NULL   ||
+            TempBuff2_ptr == NULL   ||
+            TempBuff_ptr == NULL) {
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+        }
+
+        /* --------------------------------- */
+        /*  Step 2.  Initializations         */
+        /* --------------------------------- */
+
+        /* mod sizes in bytes */
+        modSizeBytes = CALC_FULL_BYTES(modPsizeBits);
+        modSizeWords = CALC_FULL_32BIT_WORDS(modPsizeBits);
+        /* mod size in 160 bit blocks */
+        L1 = (modPsizeBits + CC_DH_SEED_MIN_SIZE_IN_BITS - 1) / CC_DH_SEED_MIN_SIZE_IN_BITS;
+
+        /* order size: M1 - in 160-bit blocks (rounded up) */
+        M1 = (orderQsizeBits + CC_DH_SEED_MIN_SIZE_IN_BITS - 1) / CC_DH_SEED_MIN_SIZE_IN_BITS;
+        orderSizeWords = CALC_FULL_32BIT_WORDS(orderQsizeBits);
+
+        /* seedSize in bytes */
+        seedSizeBytes = CALC_FULL_BYTES(seedSizeBits);
+
+        /* zeroing of P  */
+        CC_PalMemSetZero(P_ptr, modSizeBytes + 2);
+
+        /* temp buffers pointers */
+        TempBuff3_ptr = TempBuff2_ptr + modSizeWords + 2;
+        TempBuff4_ptr = TempBuff3_ptr + 2*modSizeWords + 2;
+
+        /*------------------------------------------------------ */
+        /* Step 3.   Create random prime P = (Q*J + 1)           */
+        /*------------------------------------------------------ */
+
+        /* set pgenCounter 0 */
+        *pgenCounter_ptr = 0;
+
+        /* set HASH pointers to temp buffer */
+        hashDataIn_ptr = TempBuff1_ptr;
+        hashRes_ptr = (CCHashResultBuf_t*)TempBuff4_ptr;   /* used as temp buffer */
+
+        /* Calculating R = seed + 2*M1 , where R is set in hashDataIn:
+          copy the seed into hashDataIn_ptr (big endian);
+          set other bytes to 0; add M1 */
+
+        CC_PalMemCopy((uint8_t *)hashDataIn_ptr, S_ptr, seedSizeBytes);
+        DhKgAddValueToMsbLsbBytesArray(hashDataIn_ptr, 2*M1, seedSizeBytes);
+
+        /* set count of M-R tests for Q sccording FIPS 186-4 C.3: Tab. C.1. */
+        if (modPsizeBits < 3072) {
+                countMilRabTests = 3;
+        } else {
+                countMilRabTests = 2;
+        }
+
+        isPrime = CC_FALSE;
+
+        /* Step 3.1. Main loop - try P candidates */
+        /*----------------------------------------*/
+        while (isPrime != CC_TRUE) {
+                /* Step 3.1. Create P candidate:
+                For i=0 to L1 do:  P = P + SHA1(R+i) *(2^(160*i)) */
+
+                /* set current pointer and size for copying HASH results into *
+                *  mod P as big endian bytes              */
+                current_ptr = &((uint8_t*)P_ptr)[modSizeBytes - CC_DH_SEED_MIN_SIZE_IN_BYTES];
+                remainingSize = modSizeBytes;
+
+                for (i = 0; i < L1; i++) {
+                        /* Adding 1 to hashDataIn excluding the first hashing operation */
+                        if (isFirst != 1) {
+                                DhKgAddValueToMsbLsbBytesArray(hashDataIn_ptr, 1, seedSizeBytes);
+                        }
+
+                        /* set 0 to isFirst */
+                        isFirst = 0;
+
+                        /* calculate HASH result */
+                        Error = CC_Hash(
+                                         CC_HASH_SHA1_mode,
+                                         (uint8_t *)hashDataIn_ptr,
+                                         seedSizeBytes,
+                                         *hashRes_ptr );
+
+                        if (Error != CC_OK) {
+                                goto EndWithError;
+                        }
+
+                        /* set size for copying HASH result into P buffer */
+                        if (remainingSize >= CC_DH_SEED_MIN_SIZE_IN_BYTES) {
+                                CC_PalMemCopy(current_ptr, hashRes_ptr, CC_DH_SEED_MIN_SIZE_IN_BYTES);
+                                remainingSize -=  CC_DH_SEED_MIN_SIZE_IN_BYTES;
+                                current_ptr -= CC_DH_SEED_MIN_SIZE_IN_BYTES;
+                        } else {
+                                CC_PalMemCopy((uint8_t*)P_ptr,
+                                                (uint8_t*)hashRes_ptr + CC_DH_SEED_MIN_SIZE_IN_BYTES - remainingSize,
+                                                remainingSize);
+                        }
+
+                } /* end of j - loop */
+
+                /*-----------------------------------------------------------------------*/
+
+                /* convert P to LSW array */
+                Error = CC_CommonConvertMsbLsbBytesToLswMswWords(P_ptr, modSizeWords*4, (uint8_t*)P_ptr, modSizeBytes);
+                if (Error) {
+                        Error = CC_DH_INVALID_MODULUS_SIZE_ERROR;
+                        return Error;
+                }
+
+                /*----------------------------------------*/
+                /* Step 3.2. Set P = P - (P mod 2*Q) + 1  */
+                /* Note: Now all operations on LSW arrays */
+                /*----------------------------------------*/
+
+                /* set the High and Low bits of Q equal to 1 */
+                P_ptr[modSizeWords-1] |= 0x80000000; /* MS bit */
+
+                /* set TempBuff3 = 2*Q. Note: Result size is large by 1 byte (and word), than Q size */
+                carry = CC_CommonAdd2vectors(Q_ptr, Q_ptr, CC_MIN(modSizeWords, orderSizeWords), TempBuff3_ptr);
+
+                /* if carry occurs, set next word of TempBuff3 to 1, else to 0 */
+                if (carry != 0) {
+                        if(orderSizeWords + 1 > modSizeWords)
+                                return CC_DH_INVALID_ORDER_SIZE_ERROR;
+                        TempBuff3_ptr[orderSizeWords] = 1;
+                } else {
+                        TempBuff3_ptr[orderSizeWords] = 0;
+                }
+
+                /* calculate TempBuff4 = P mod 2*Q */
+                CC_PalMemSetZero((uint8_t*)TempBuff4_ptr, modSizeBytes);
+
+                Error = PkiLongNumDiv(
+                                            P_ptr,                      /*numerator P*/
+                                            modSizeWords,               /*P_size in words*/
+                                            TempBuff3_ptr,              /*divider */
+                                            orderSizeWords + 1,         /*divider_size in words*/
+                                            TempBuff4_ptr,              /*ModRes_ptr*/
+                                            TempBuff2_ptr              /*DivRes_ptr*/);
+                if (Error) {
+                        Error = CC_DH_PRIME_P_GENERATION_FAILURE_ERROR;
+                        return Error;
+                }
+
+                /* subtract: P = P - TempBuff4 */
+                CC_CommonSubtractUintArrays(P_ptr, TempBuff4_ptr, modSizeWords, P_ptr);
+
+                /* add 1 to P */
+                CC_CommonIncLsbUnsignedCounter(P_ptr, 1, (uint8_t)modSizeWords);
+
+                /* check: if P > 2^(L-1), then perform step 3.3. */
+                /*-----------------------------------------------*/
+
+                /*  set TempBuff5 = 2^(L-1): Note: L = modPsizeBits is        *
+                *   multiple of 32 bits                       */
+                CC_PalMemSetZero((uint8_t*)TempBuff4_ptr, modSizeBytes);
+                TempBuff4_ptr[modSizeWords - 1] = 0x80000000;
+
+                /* compare */
+                cmpRes = CC_CommonCmpLsWordsUnsignedCounters(
+                                                               P_ptr, (uint16_t)modSizeWords, TempBuff4_ptr, (uint16_t)modSizeWords);
+
+
+                /* Step 3.3. If P is not diverted, then perform primality               *
+                 *  tests on P: 8 Rabin-Miller and 1 Lucas tests (X9.42-2001)           *
+                 *----------------------------------------------------------------------*/
+
+                if (cmpRes == CC_COMMON_CmpCounter1GreaterThenCounter2) {
+                        Error = RsaPrimeTestCall(rndContext_ptr,
+                                                          P_ptr,
+                                                          modSizeWords,
+                                                          countMilRabTests,
+                                                          (int8_t*)&isPrime,
+                                                          TempBuff2_ptr,
+                                                          CC_DH_PRIME_TEST_MODE);
+                        if (Error != CC_OK) {
+                                Error = CC_DH_PRIME_P_GENERATION_FAILURE_ERROR;
+                                goto EndWithError;
+                        }
+                }
+
+                /* RL defines: 4096 -> PGEN_COUNTER_MAX_VAL,  L = 1024 -> PRIME_MOD_MIN_VAL */
+                /* update pgenCounter_ptr */
+                *pgenCounter_ptr += 1;
+
+                /* if pgenCounter >= 4096*N then return "generation is fail" */
+                if (*pgenCounter_ptr >= DH_X942_PGEN_COUNTER_CONST*(modPsizeBits + DH_X942_PRIME_MOD_MIN_VAL - 1)/DH_X942_PRIME_MOD_MIN_VAL) {
+                        Error = CC_DH_PRIME_P_GENERATION_FAILURE_ERROR;
+                        goto EndWithError;
+                }
+
+        } /* END of while(isPrime != CC_TRUE)*/
+
+        /* correction of pgenCounter */
+        *pgenCounter_ptr -= 1;
+
+        /* End of function */
+        return Error;
+
+        EndWithError:
+
+        CC_PalMemSetZero(P_ptr, modSizeBytes);
+
+        return Error;
+
+}/* End of DhX942FindPrimeP */
+
+
+
+
+/******************************************************************************************/
+/**
+ * @brief The function creates generator of GF(P) subgroup for key generation according to X9.42-2001.
+ *
+ *
+ * @param[in]  rndContext_ptr     - Pointer to the RND context buffer.
+ * @param[out] P_ptr              - The prime modulus P of structure P = j*Q + 1, where Q is prime
+ *                                  and j is an integer.The buffer must be aligned to 4 bytes.
+ * @param[in]  modPSizeBits       - The  modulus (prime) P size in bytes must be multiple of 4 bytes.
+ * @param[out] Q_ptr              - The pointer to the order Q of generator. The buffer must be aligned to 4 bytes.
+ * @param[in]  orderSizeBits      - The size of order of generator in bytes. Must be multiple of 4 bytes.
+ * @param[out] G_ptr              - The generator of GF(P) subgroup. The buffer must be aligned to 4 bytes.
+ *                                  size of buffer not less than modPSize in bytes.
+ * @param[in]  tempBuff1_ptr      - The temp buffer of size not less than DH max modulus size, aligned to 4 bytes.
+ * @param[in]  expTempBuff_ptr    - The temp buffer of defined structure.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a predefined error code.
+ *
+ *
+ */
+static CCError_t DhX942CreateGenerator(CCRndContext_t *rndContext_ptr,
+                                              uint32_t           *P_ptr,               /*in */
+                                              uint32_t           modSizeBits,          /*in */
+                                              uint32_t           *Q_ptr,               /*in */
+                                              uint32_t           orderSizeBits,        /*in */
+                                              uint32_t           *G_ptr,               /*out*/
+                                              uint32_t           *tempBuff1_ptr,       /*in */
+                                              CCDhExpTemp_t  *expTempBuff_ptr)     /*in */
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        // RL  J-factor is used in other functions
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /* modulus and order sizes in words */
+        uint32_t modSizeBytes, modSizeWords, orderSizeBytes;
+
+        uint32_t J_effectiveSizeBits;
+
+        /* compare flag */
+        CCCommonCmpCounter_t  compFlag;
+
+
+        /* INITIALIZATIONS */
+
+        modSizeBytes = CALC_FULL_BYTES(modSizeBits);
+        modSizeWords = CALC_FULL_32BIT_WORDS(modSizeBits);
+        orderSizeBytes = CALC_FULL_BYTES(orderSizeBits);
+
+
+        /* FUNCTION  LOGIC */
+
+        /*-------------------------------------*/
+        /* Step 1. Calculate J = (P - 1)/Q     */
+        /*-------------------------------------*/
+
+        /*  copy modulus into TempBuff1  */
+        CC_PalMemCopy((uint8_t*)expTempBuff_ptr->PubKey.n, (uint8_t*)P_ptr, modSizeBytes);
+        CC_PalMemSetZero((uint8_t*)expTempBuff_ptr->PubKey.n + modSizeBytes, CC_DH_MAX_MOD_SIZE_IN_BYTES - modSizeBytes);
+        /* copy order Q into aligned buffer */
+        CC_PalMemCopy((uint8_t*)expTempBuff_ptr->TempBuff, (uint8_t*)Q_ptr, orderSizeBytes);
+        CC_PalMemSetZero((uint8_t*)expTempBuff_ptr->TempBuff + orderSizeBytes, CC_DH_MAX_MOD_SIZE_IN_BYTES - orderSizeBytes);
+
+        /* subtract: P - 1 */
+        CC_CommonDecrLsbUnsignedCounter(expTempBuff_ptr->PubKey.n, 1, modSizeWords);
+
+        /* divide (P - 1)/Q */
+        PkiLongNumDiv(
+                            expTempBuff_ptr->PubKey.n,            /*numerator B*/
+                            modSizeWords,                         /*B_size in words*/
+                            expTempBuff_ptr->TempBuff,            /*Q - divider*/
+                            CALC_32BIT_WORDS_FROM_BYTES(orderSizeBytes),                 /*Q_size in words*/
+                            expTempBuff_ptr->PubKey.e,            /*ModRes_ptr*/
+                            tempBuff1_ptr                        /*DivRes_ptr*/);
+
+        /* calculate actual size of J in bits: Use min() to prevent warnings  */
+        J_effectiveSizeBits = CC_MIN(modSizeBits, CC_CommonGetWordsCounterEffectiveSizeInBits(
+                                                                                                  tempBuff1_ptr, modSizeWords));
+
+        /*---------------------------------------------------------------*/
+        /* Step 2. Generate random G : 1 < G < (P-1)  and                */
+        /*         set it into DataIn buffer, other bytes of buffer = 0  */
+        /*---------------------------------------------------------------*/
+        /* cleaning of temp buffer */
+        CC_PalMemSetZero((uint8_t*)&expTempBuff_ptr->PrimeData, sizeof(CCDhPrimeData_t));
+
+        /* generating rnd vector */
+
+        Error = RndGenerateWordsArrayInRange(rndContext_ptr,
+                                                  modSizeBits, expTempBuff_ptr->PubKey.n /*P-1*/,
+                                                  expTempBuff_ptr->PrimeData.DataIn /*RND*/,
+                                                  expTempBuff_ptr->PrimeData.DataOut/*temp*/);
+        if (Error != CC_OK) {
+                goto End;
+        }
+
+        /*----------------------------------------------------*/
+        /* Step 3. Initialization of PubKey and PrivData      */
+        /*         structures for exponentiation              */
+        /*----------------------------------------------------*/
+
+        /* cleaning of temp buffer */
+        CC_PalMemSetZero((uint8_t*)&expTempBuff_ptr->PubKey, sizeof(expTempBuff_ptr->PubKey));
+
+        /* set modulus in DH_PubKey structure for exponentiation G^J mod P */
+        CC_PalMemCopy((uint8_t*)expTempBuff_ptr->PubKey.n, (uint8_t*)P_ptr, modSizeBytes);
+        expTempBuff_ptr->PubKey.nSizeInBits = modSizeBits;
+        /* set exponent J and its size */
+        CC_PalMemCopy( (uint8_t*)expTempBuff_ptr->PubKey.e, (uint8_t*)tempBuff1_ptr, CALC_FULL_BYTES(J_effectiveSizeBits) );
+        expTempBuff_ptr->PubKey.eSizeInBits = J_effectiveSizeBits;
+
+        /*  initialize the H value in LLF of PubKey for exponentiation  */
+        Error = RsaInitPubKeyDb(&expTempBuff_ptr->PubKey);
+        if (Error != CC_OK) {
+                Error = CC_DH_INTERNAL_ERROR;
+                goto End;
+        }
+
+
+        /*-----------------------------------------------------------*/
+        /* Step 4. Calculate G = G ^ J mod P , if G == 1, change     */
+        /*         G (DataIn) and repeat exponentiation              */
+        /*-----------------------------------------------------------*/
+
+        compFlag = CC_COMMON_CmpCounter1AndCounter2AreIdentical;  /* 0 - means G == 1 */
+        /* set 1 to tempBuff1_ptr for comparing */// RL
+        CC_PalMemSetZero((uint8_t*)tempBuff1_ptr, modSizeBytes);
+        tempBuff1_ptr[0] = 1;
+
+        while (compFlag == 0) {
+                /* exponentiation DataOut = DataIn ^ Exp mod P */
+                Error = RsaExecPubKeyExp(&expTempBuff_ptr->PubKey, &expTempBuff_ptr->PrimeData);
+
+                if (Error != CC_OK) {
+                        Error = CC_DH_INTERNAL_ERROR;
+                        return Error;
+                }
+
+                /* compare DataOut to 1: */
+                compFlag = CC_CommonCmpLsWordsUnsignedCounters(
+                                                                 expTempBuff_ptr->PrimeData.DataOut, modSizeWords,
+                                                                 tempBuff1_ptr, modSizeWords);
+
+                /* if G == 1 change DataIn (by adding 1) for trying next G value */
+                if (compFlag == 0) {
+                        CC_CommonIncLsbUnsignedCounter(
+                                                         expTempBuff_ptr->PrimeData.DataIn, 1, (uint8_t)modSizeWords);
+                }
+        }
+
+        /* copy generator into output */
+        CC_PalMemCopy((uint8_t*)G_ptr, (uint8_t*)expTempBuff_ptr->PrimeData.DataOut, modSizeBytes);
+
+        /* End of function */
+        End:
+        return Error;
+
+}/* End of DhX942CreateGenerator */
+
+
+/******************************************************************************************/
+/**
+ * @brief The function generates a DH (DLP) domain parameters in GF(P) (see X9.42-2001)
+ *
+ *   The function parameters are the same as in CC_DhCreateDomainParams() function (see below)
+ *   besides one difference: this function not checks input parameters, because it is also used locally
+ *   in some other functions with input pointers = NULL.
+ *
+ *   Note: The function is static, therefore sizes of its input arrays (mod, ord, seed) are checked in
+ *         caller functions and don't need to be chcked again.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure - a predefined error code.
+ *
+ */
+static CCError_t DhCreateDomainParams(
+                                           CCRndContext_t *rndContext_ptr,
+                                           uint32_t          modPsizeBits,             /*in */
+                                           uint32_t          orderQsizeBits,           /*in */
+                                           uint32_t          seedSizeBits,             /*in */
+                                           uint8_t          *modP_ptr,                 /*out*/
+                                           uint8_t          *orderQ_ptr,               /*out*/
+                                           uint8_t          *generatorG_ptr,           /*out*/
+                                           uint32_t         *generGsizeBytes_ptr,      /*in/out*/
+                                           uint8_t          *factorJ_ptr,              /*out*/
+                                           uint32_t         *JsizeBytes_ptr,           /*in/out*/
+                                           uint8_t          *seedS_ptr,                /*in/out*/
+                                           int8_t            generateSeed,             /*in*/
+                                           uint32_t         *pgenCounter_ptr,          /*out*/
+                                           CCDhKgData_t  *DHKGbuff_ptr              /*in */)
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /* pointers to temp buffers for candidates to order Q, modulus P, seed S, generator G */
+        uint32_t  *Q_ptr, *P_ptr, *G_ptr, *J_ptr;
+        uint8_t  *S_ptr;
+
+        /* tries counter */
+        uint32_t  pgenCounter;
+
+        uint32_t  modSizeBytes, generatorSizeBits;
+
+        /* temp buffer pointers */
+        uint32_t  *TempBuff1_ptr, *TempBuff2_ptr;
+
+
+        /* --------------------------------- */
+        /*  Step 2.  Initializations         */
+        /* --------------------------------- */
+
+        /* clean DHKGbuff_ptr */
+        CC_PalMemSetZero(DHKGbuff_ptr, sizeof(CCDhKgData_t));
+
+        /* set Q, S and G- pointers on DHKGbuff_ptr->PrimData temp buffers */
+        Q_ptr = DHKGbuff_ptr->TempBuff2;
+        P_ptr = DHKGbuff_ptr->TempBuff3;
+        G_ptr = DHKGbuff_ptr->TempBuff4;
+        J_ptr = DHKGbuff_ptr->TempBuff5;
+        S_ptr = (uint8_t*)J_ptr;
+
+        /* set 32-bit temp pointers on KGData and PrimData temp buffers */
+        TempBuff1_ptr = DHKGbuff_ptr->TempBuff1;
+        TempBuff2_ptr = (uint32_t*)&(DHKGbuff_ptr->ExpTemps);
+
+        if (generateSeed == 0) {
+                CC_PalMemCopy((uint8_t*)S_ptr, seedS_ptr, CALC_FULL_BYTES(seedSizeBits));
+        }
+
+        modSizeBytes = CALC_FULL_BYTES(modPsizeBits);
+
+
+        /*------------------------------------------------------------------- */
+        /* Step 1. Find random prime Q and its Seed S according to ANSI X9.42 */
+        /*------------------------------------------------------------------- */
+
+        Error = DhX942FindPrimeQ(rndContext_ptr,
+                                      orderQsizeBits,            /*in */
+                                      seedSizeBits,              /*in */
+                                      generateSeed,              /*in */
+                                      Q_ptr,                     /*out*/
+                                      S_ptr,                     /*in/out*/
+                                      TempBuff1_ptr,             /*in */
+                                      TempBuff2_ptr,             /*in */
+                                      DHKGbuff_ptr->TempBuff6);  /*in */
+        if (Error != CC_OK) {
+                goto EndWithError;
+        }
+
+
+        /*------------------------------------------------------ */
+        /* Step 2.   Create random prime P = (Q*J + 1)           */
+        /*------------------------------------------------------ */
+
+        Error = DhX942FindPrimeP(rndContext_ptr,
+                                      modPsizeBits,        /*in */
+                                      orderQsizeBits,      /*in */
+                                      seedSizeBits,        /*in */
+                                      P_ptr,               /*out*/
+                                      Q_ptr,               /*out*/
+                                      S_ptr,               /*in */
+                                      &pgenCounter,        /*out*/
+                                      TempBuff1_ptr,       /*in */
+                                      TempBuff2_ptr,       /*in */
+                                      DHKGbuff_ptr->TempBuff6); /*in */
+
+        if (Error != CC_OK) {
+                goto EndWithError;
+        }
+
+
+        /*------------------------------------------------------ */
+        /* Step 3.   Create generator of GF(P) subgroup          */
+        /*------------------------------------------------------ */
+        if (generatorG_ptr != NULL) {
+                Error = DhX942CreateGenerator(rndContext_ptr,
+                                                   P_ptr,                                       /*in */
+                                                   modPsizeBits,                                /*in */
+                                                   Q_ptr,                                       /*in */
+                                                   orderQsizeBits,                              /*in */
+                                                   G_ptr,                                       /*out*/
+                                                   TempBuff1_ptr,                               /*in */
+                                                   (CCDhExpTemp_t*)&DHKGbuff_ptr->ExpTemps  /*in */);
+
+                if (Error != CC_OK) {
+                        goto EndWithError;
+                }
+
+                /* calculate size of generator and output it in big endianness */
+                generatorSizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(G_ptr, (uint16_t)modSizeBytes/CC_32BIT_WORD_SIZE);
+                *generGsizeBytes_ptr = CALC_FULL_BYTES(generatorSizeBits);
+
+                Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                                   generatorG_ptr, *generGsizeBytes_ptr, G_ptr, *generGsizeBytes_ptr);
+                if (Error != CC_OK) {
+                        Error = CC_DH_INVALID_GENERATOR_PTR_OR_SIZE_ERROR;
+                        goto EndWithError;
+                }
+        }
+
+        /* output of result parameters (in big endianness) */
+        Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(modP_ptr, modSizeBytes, P_ptr, modSizeBytes);
+        if (Error != CC_OK) {
+                Error = CC_DH_INVALID_MODULUS_SIZE_ERROR;
+                goto EndWithError;
+        }
+
+        if (orderQ_ptr != NULL) {
+                Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                                   orderQ_ptr, CALC_FULL_BYTES(orderQsizeBits), Q_ptr, CALC_FULL_BYTES(orderQsizeBits));
+                if (Error != CC_OK) {
+                        Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
+                        goto EndWithError;
+                }
+        }
+
+        /* copy generated seed into output */
+        if (generateSeed == 1) {
+                CC_PalMemCopy(seedS_ptr, (uint8_t*)S_ptr, CALC_FULL_BYTES(seedSizeBits));
+        }
+
+        /* if factorJ_ptr != NULL, then calculate this factor and its size. J = (P-1) / Q */
+
+        // RL Use J-factor from previous function
+        if (factorJ_ptr != NULL) {
+                PkiLongNumDiv(
+                                    P_ptr,                 /*numerator B*/
+                                    CALC_FULL_32BIT_WORDS(modPsizeBits),     /*B_size in words*/
+                                    Q_ptr,                 /*divider N */
+                                    CALC_FULL_32BIT_WORDS(orderQsizeBits),   /*N_size in words*/
+                                    TempBuff1_ptr,         /*ModRes_ptr*/
+                                    J_ptr                 /*DivRes_ptr*/);
+
+                /* calculate size of J in bits */
+                *JsizeBytes_ptr = CC_CommonGetWordsCounterEffectiveSizeInBits(J_ptr, (uint16_t)modSizeBytes/CC_32BIT_WORD_SIZE);
+
+                /* calculate size of J in bytes */
+                *JsizeBytes_ptr = CALC_FULL_BYTES(*JsizeBytes_ptr);
+
+                /* convert result to MSB bytes and output into factorJ_ptr buffer */
+                Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                                   factorJ_ptr, *JsizeBytes_ptr,
+                                                                   J_ptr, *JsizeBytes_ptr);
+                if (Error != CC_OK) {
+                        Error = CC_DH_INVALID_J_FACTOR_PTR_OR_SIZE_ERROR;
+                        goto EndWithError;
+                }
+        }
+
+        /*  if pgenCounter_ptr != NULL put out pgenCounter */
+        if (pgenCounter_ptr != NULL) {
+                *pgenCounter_ptr = pgenCounter;
+        }
+
+        goto End;
+
+        /* End of function */
+
+        EndWithError:
+
+        /* cleaning output buffers used also in internal computations */
+        CC_PalMemSetZero(modP_ptr, CALC_FULL_BYTES(modPsizeBits));
+
+        if (generatorG_ptr != NULL) {
+                CC_PalMemSetZero(generatorG_ptr, *generGsizeBytes_ptr);
+        }
+
+        if (orderQ_ptr != NULL) {
+                CC_PalMemSetZero(orderQ_ptr, CALC_FULL_BYTES(orderQsizeBits));
+        }
+
+        if (factorJ_ptr != NULL) {
+                CC_PalMemSetZero(factorJ_ptr, *JsizeBytes_ptr);
+        }
+
+        if (generateSeed == 1) {
+                CC_PalMemSetZero(seedS_ptr, CALC_FULL_BYTES(seedSizeBits));
+        }
+
+        End:
+        /* cleaning of temp buffer */
+        CC_PalMemSetZero(DHKGbuff_ptr, sizeof(CCDhKgData_t));
+
+        return Error;
+
+}/* End of DhCreateDomainParams */
+
+
+
+/******************************************************************************************/
+/************************         Public Functions           ******************************/
+/******************************************************************************************/
+
+/******************************************************************************************/
+/**
+* @brief The function generates a DH (DLP) domain parameters in GF(P) (see X9.42-2001)
+*
+*
+* @param [in]  rndContext_ptr     - Pointer to the RND context buffer.
+* @param [in]  modPSizeBits       - Size of the modulus (Prime) in bits equal 256*n, where n >= 4. FIPS 186-4
+*                                   defines 1024 and 2048 bit.
+* @param [in]  orderQSizeBits     - Size of the Generator's order in bits. FIPS 186-4 defines orderQSizeBits = 160
+*                                   for modulus 1024 bit and 224 or 256 bit for modPSizeBits = 2048. We not recommend
+                                    orderQSizeBits > 256 and returns an error if it > modPSizeBits/4 .
+* @param [in]  seedSizeBits       - The  seed size in bits. Requirements:
+*                                  seedSizeBits >= orderQSizeBits and seedSizeBits <= modPSizeBits ( the
+*                                  last is required by our implementation).
+* @param [out] modP_ptr           - The prime modulus P of structure P = J*Q + 1, where Q is prime
+*                                  and j is an integer. Size of the buffer for output generated value must
+*                                  be not less, than modulus size.
+* @param [out] orderQ_ptr         - The pointer to the order Q of generator. The size of the buffer for output
+*                                  generated value must be not less, than order size.
+* @param [out] generatorG_ptr     - The pointer to the generator of multiplicative subgroup in GF(P).
+*                                  If the pointer == NULL, the function returns an error. Size of the buffer
+*                               for output generated value must be not less, than modulus size.
+* @param [in/out]generGsizeBytes_ptr - The pointer to the one-word buffer, containing the generator size value (in bytes).
+*                                  The user must set the size of allocated buffer, and the function returns the
+*                               actual size of the generator in bytes.
+* @param [out] factorJ_ptr        - The pointer to buffer for integer factor J. If the pointer == NULL, the function
+*                                  not puts this parameter out. In this case JsizeBytes_ptr must be set to NULL,
+*                                  otherwise the function returns an error. The size of the buffer must be not less,
+*                                  than ( modPSizesBytes - orderQSizeBytes + 1 ).
+* @param [in/out] JsizeBytes_ptr  - The pointer to the size of integer factor J. If the pointer == NULL,
+*                                  the function not puts this parameter out. If output of the factor J is needed, the
+*                                  user must set the J size value equal to the size of allocated buffer, and the
+*                                  function returns the actual size of J in bytes.
+* @param [in/out] seedS_ptr       - The random seed used for generation of primes. The size of the buffer for output
+*                           generated value must be not less, than passed seed size (see above) and not less
+*                           20 bytes (160 bits).
+* @param [in] generateSeed        - The flag, defining whether the seed generated randomly by the function
+*                                  (generateSeed = 1), or it is passed by the input (generateSeed = 0).
+* @param [out] pgenCounter_ptr    - The pointer to counter of tries to generate the primes. If the pointer == NULL,
+*                                  the function not puts this parameter out.
+* @param [out] DHKGBuff_ptr       - The temp buffer for internal calculations. The buffer is defined as structure.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure - a predefined error code.
+ *
+*     Note:  1. Input and Output vectors are in big endianness (high most bit is left most one).
+*            2. For reliability of checking of input parameters, in case that the user don't wont output of
+*               some parameters (generator or factorJ), he must set both - a pointer to appropriate buffer and a
+*               pointer to its size equaled to NULL for these parameters, otherwise the function returns an error.
+ *            2. In case of any error the function may clean the output buffers.
+ *
+ */
+CEXPORT_C CCError_t CC_DhCreateDomainParams(
+                                                CCRndContext_t *rndContext_ptr,
+                                                uint32_t          modPsizeBits,             /*in */
+                                                uint32_t          orderQsizeBits,           /*in */
+                                                uint32_t          seedSizeBits,             /*in */
+                                                uint8_t          *modP_ptr,                 /*out*/
+                                                uint8_t          *orderQ_ptr,               /*out*/
+                                                uint8_t          *generatorG_ptr,           /*out*/
+                                                uint32_t         *generGsizeBytes_ptr,      /*in/out*/
+                                                uint8_t          *factorJ_ptr,              /*out*/
+                                                uint32_t         *JsizeBytes_ptr,           /*in/out*/
+                                                uint8_t          *seedS_ptr,                /*in/out*/
+                                                int8_t            generateSeed,             /*in*/
+                                                uint32_t         *pgenCounter_ptr,          /*out*/
+                                                CCDhKgData_t  *DHKGbuff_ptr              /*in */ )
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        uint32_t  modSizeBytes, orderSizeBytes;
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check pointers: modP, orderQ and temp buffer. Note: other pointers may be NULL, if not used  */
+        if (modP_ptr == NULL   ||
+            orderQ_ptr == NULL ||
+            seedS_ptr == NULL  ||
+            DHKGbuff_ptr == NULL) {
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+        }
+        /* check sizes */
+        if (modPsizeBits < CC_DH_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ||   /* check sizes */
+            modPsizeBits % 256 != 0 ||
+            modPsizeBits > CC_DH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS) {
+                return CC_DH_INVALID_MODULUS_SIZE_ERROR;
+        }
+
+        /* init the sizes */
+        modSizeBytes = CALC_FULL_BYTES(modPsizeBits);
+        orderSizeBytes = CALC_FULL_BYTES(orderQsizeBits);
+
+        if (orderQsizeBits < CC_DH_SEED_MIN_SIZE_IN_BITS ||
+            orderQsizeBits >  modPsizeBits / 4   ||
+            orderQsizeBits % CC_BITS_IN_32BIT_WORD != 0) {
+                return CC_DH_INVALID_ORDER_SIZE_ERROR;
+        }
+
+        if (seedSizeBits < orderQsizeBits/* according to X9.42-2001 */  ||
+            seedSizeBits > modPsizeBits /* our limitation of buffer size */) {
+                return CC_DH_INVALID_SEED_SIZE_ERROR;
+        }
+
+    /* check generator G pointers and buffer size, it is allowed that both generator and size are NULL */
+    if (((generatorG_ptr != NULL) && (generGsizeBytes_ptr == NULL)) ||
+        ((generatorG_ptr == NULL) && (generGsizeBytes_ptr != NULL)))
+        return CC_DH_INVALID_GENERATOR_PTR_OR_SIZE_ERROR;
+
+        /* check generator G buffer size */
+         if ((generGsizeBytes_ptr != NULL) && (*generGsizeBytes_ptr < modSizeBytes)) {
+                return CC_DH_INVALID_GENERATOR_PTR_OR_SIZE_ERROR;
+        }
+
+        /* check J-factor pointers and buffer size */
+        if ((factorJ_ptr == NULL && JsizeBytes_ptr != NULL) ||
+            (factorJ_ptr != NULL && JsizeBytes_ptr == NULL) ||
+            ((JsizeBytes_ptr != NULL) && (*JsizeBytes_ptr < (modSizeBytes - orderSizeBytes + 1)))) {
+                return CC_DH_INVALID_J_FACTOR_PTR_OR_SIZE_ERROR;
+        }
+
+        /* check generateSeed parameter */
+        if (generateSeed != 0 && generateSeed != 1) {
+                return CC_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;
+        }
+
+        /*   call exec function */
+        Error = DhCreateDomainParams(
+                                        rndContext_ptr,
+                                        modPsizeBits,             /*in */
+                                        orderQsizeBits,           /*in */
+                                        seedSizeBits,             /*in */
+                                        modP_ptr,                 /*out*/
+                                        orderQ_ptr,               /*out*/
+                                        generatorG_ptr,           /*out*/
+                                        generGsizeBytes_ptr,      /*in/out*/
+                                        factorJ_ptr,              /*out*/
+                                        JsizeBytes_ptr,           /*in/out*/
+                                        seedS_ptr,                /*in/out*/
+                                        generateSeed,             /*in*/
+                                        pgenCounter_ptr,          /*out*/
+                                        DHKGbuff_ptr);            /*in */
+
+        return Error;
+}/* End of CC_DhCreateDomainParams */
+
+
+/******************************************************************************************/
+/**
+* @brief The function checks the obtained DH domain parameters according X9.42-2001.
+*
+*        There may be 3 case of checking:
+*        1. Checking of primes only ( modulus P and order Q according to passed seed S and pgenCounter).
+*           In this case all pointers and sizes of said parameters must be passed (not NULL), but generator
+*           G pointer and it size must be both set to NULL.
+*        2. Checking of generator G only in assuming that primes parameters P, Q are valid. In ths case
+*           the user must to pass the P,Q,G pointers and sizes. The seed S pointer and size must be both
+*           set to NULL, otherwise the function returns an error.
+*        3. Checking all domain parameters. In this case all input parameters must be passed to the function.
+*
+*        If any of checked domain parameters is not compliant to X9.42-2001 standard and our implementation
+*        limitation, the function returns an error according to cc_dh_error.h file.
+*
+*        NOTE:  Detailed requirements to all used parameters are described above in CC_DhCreateDomainParams
+*               functions API.
+*
+* @param[in]  rndContext_ptr     - Pointer to the RND context buffer.
+* @param[out] modP_ptr           - The prime modulus P. Must be of structure P = j*Q + 1,
+*                                  where Q is prime and j is an integer.
+* @param[in]  modPSizeBits       - The  modulus (prime) P size in bits equal 256*n, where n >= 4.
+* @param[out] orderQ_ptr         - The pointer to the order Q of generator.
+* @param[in]  orderQSizeBytes    - The size of order of generator in bytes. According to ANSI X9.43:
+*                                  m must be multiple of 32 bits and m >= 160. According to ANSI X9.30-1:
+*                                  m = 160 bit. In our implementation required, that orderQSize <= modPSizeBytes/4.
+* @param[in]  generatorG_ptr     - The pointer to the generator of multiplicative subgroup in GF(P).
+* @param[in]  generatorSizeBytes - The size of generator in bytes (must be set if generator will be checked).
+* @param[in]  seedS_ptr          - The random seed used for generation of primes (must be set if
+*                                  primes will be checked).
+* @param[in]  seedSizeBits       - The seed size in bits. If the seed is used,
+*                      then its size must be:
+*                      seedSizeBits >= orderQSizeBits and
+*                      seedSizeBits <= modPSizeBits ( the last is
+*                      required by our implementation).
+* @param[in]  pgenCounter        - The counter of tries to generate the primes (must be set if primes
+*                                  will be checked).
+* @param[in] TempBuff_ptr        - The temp buffer of defined structure.
+*
+* @return CCError_t - On success CC_OK is returned, on failure or if one or more domain
+*                       parameters are invalid the function returns a predefined error code.
+*
+*     Note:  Input vectors are in big endianness.
+*
+*/
+CEXPORT_C CCError_t CC_DhCheckDomainParams(
+                                               CCRndContext_t *rndContext_ptr,
+                                               uint8_t               *modP_ptr,           /*in */
+                                               uint32_t               modPsizeBytes,      /*in */
+                                               uint8_t               *orderQ_ptr,         /*in */
+                                               uint32_t               orderQsizeBytes,    /*in */
+                                               uint8_t               *generatorG_ptr,     /*in */
+                                               uint32_t               generatorSizeBytes, /*in */
+                                               uint8_t               *seedS_ptr,          /*in */
+                                               uint32_t               seedSizeBits,       /*in */
+                                               uint32_t               pgenCounter,        /*in */
+                                               CCDhKgCheckTemp_t   *checkTempBuff_ptr   /*in */ )
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+
+        /* pointers to temp buffers */
+        uint32_t  *Q_ptr, *P_ptr;
+        CCDhKgData_t *DHKGbuff_ptr;
+        uint32_t  *TempBuff_ptr;
+
+        /* size of modulus in bits and in words */
+        uint32_t  modPsizeBits, modPsizeWords;
+
+        /* size  order Q (in bits) */
+        uint32_t  orderQsizeBits;
+
+        /* counter of trying to generate modulus P; pgenCounter*/
+        uint32_t  pgenCounter1;
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check pointers: modP, generator and tempBuff. Note: other pointers may be NULL  */
+        if (modP_ptr == NULL ||
+            orderQ_ptr == NULL ||
+            checkTempBuff_ptr == NULL) {
+                return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
+        }
+
+        /* check modulus and order sizes */
+        if (modPsizeBytes < CC_DH_MIN_VALID_KEY_SIZE_VALUE_IN_BITS / 8 ||
+            modPsizeBytes % CC_BITS_IN_32BIT_WORD != 0 ||
+            modPsizeBytes > CC_DH_MAX_MOD_SIZE_IN_BYTES) {
+                return CC_DH_INVALID_MODULUS_SIZE_ERROR;
+        }
+
+        if (orderQsizeBytes < CC_DH_SEED_MIN_SIZE_IN_BITS / 8 ||
+            orderQsizeBytes % CC_32BIT_WORD_SIZE != 0 ||
+            orderQsizeBytes > modPsizeBytes/4) {
+                return CC_DH_INVALID_ORDER_SIZE_ERROR;
+        }
+
+        /* Seed pointer and size checking:
+           If pointer or size of seed are illegal, then output an error.
+           Note: In case that primes checking is not needed, the seed pointer and size must be
+                     set to NULL  and are legal */
+        if ((seedSizeBits == 0 && seedS_ptr != NULL) ||
+            (seedSizeBits != 0 && seedS_ptr == NULL)) {
+                return CC_DH_CHECK_SEED_SIZE_OR_PTR_NOT_VALID_ERROR;
+        }
+
+        /* Generator pointer and size checking:
+           If pointer or size of generator are illegal, then output an error.
+           Note: In case that generator checking is not needed, its pointer and size are equaled to NULL */
+        if ((generatorSizeBytes == 0 && generatorG_ptr != NULL) ||
+            (generatorSizeBytes != 0 && generatorG_ptr == NULL)) {
+                return CC_DH_CHECK_GENERATOR_SIZE_OR_PTR_NOT_VALID_ERROR;
+        }
+
+
+
+
+        /* --------------------------------- */
+        /*  Step 2.  Initializations         */
+        /* --------------------------------- */
+
+        DHKGbuff_ptr = &checkTempBuff_ptr->DhKgBuff;
+        TempBuff_ptr = (uint32_t*)&checkTempBuff_ptr->CheckTempBuff;
+
+        /* clean TempBuff_ptr */
+        CC_PalMemSetZero(checkTempBuff_ptr, sizeof(CCDhKgCheckTemp_t));
+
+        /* calculate P and Q size in bits */
+        modPsizeWords = CALC_32BIT_WORDS_FROM_BYTES(modPsizeBytes);
+
+        /* set Q, P and G- pointers on DHKGbuff_ptr->PrimData temp buffers */
+        Q_ptr = TempBuff_ptr;
+        P_ptr = Q_ptr + modPsizeWords;
+
+        if (seedS_ptr != NULL) {
+                /*--------------------------------------------- */
+                /* Step 3. Calculate and check primes sizes     */
+                /*--------------------------------------------- */
+
+                /* temporary convert P and Q to little endian bytes arrays  *
+                *  for calculating their sizes in bits                 */
+                CC_CommonReverseMemcpy((uint8_t*)P_ptr, modP_ptr, modPsizeBytes);
+                CC_CommonReverseMemcpy((uint8_t*)Q_ptr, orderQ_ptr, orderQsizeBytes);
+
+                modPsizeBits = CC_MIN(8*modPsizeBytes, CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)P_ptr, (uint16_t)modPsizeBytes));
+                orderQsizeBits = CC_MIN(8*orderQsizeBytes, CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)Q_ptr, (uint16_t)orderQsizeBytes));
+
+                /*------------------------------------------------------------------- */
+                /* Step 4. Generate random primes P,Q for given seed Seed S according */
+                /*         to ANSI X9.42 for comparing with input parameters          */
+                /*         The called CreateDomainParams also checks sizes of input   */
+                /*         parameters                                                 */
+                /*------------------------------------------------------------------- */
+
+                Error =  DhCreateDomainParams(
+                                                 rndContext_ptr,
+                                                 modPsizeBits,                    /*in */
+                                                 orderQsizeBits,                  /*in */
+                                                 seedSizeBits,                    /*in */
+                                                 (uint8_t*)P_ptr,               /*out*/
+                                                 (uint8_t*)Q_ptr,               /*out*/
+                                                 NULL /*generatorG_ptr*/,      /*out*/
+                                                 NULL /*generatorSize_ptr*/,   /*out*/
+                                                 NULL /*factorJ_ptr*/,         /*out*/
+                                                 NULL /*JsizeBytes_ptr*/,      /*out*/
+                                                 seedS_ptr,                       /*in/out*/
+                                                 CC_FALSE /*generateSeed*/,       /*in*/
+                                                 &pgenCounter1,                   /*out*/
+                                                 DHKGbuff_ptr);                   /*in */
+
+                if (Error != CC_OK) {
+                        goto End;
+                }
+
+                /* -------------------------------------------------------------------*/
+                /* Step 5. Compare generated primes with input, if one of compares   */
+                /*         is not "equal", the output error                          */
+                /* -------------------------------------------------------------------*/
+
+                if (CC_PalMemCmp(modP_ptr, (uint8_t*)P_ptr, modPsizeBytes) != 0) {
+                        Error = CC_DH_CHECK_DOMAIN_PRIMES_NOT_VALID_ERROR;
+                        goto End;
+                }
+
+                else if (CC_PalMemCmp(orderQ_ptr, (uint8_t*)Q_ptr, orderQsizeBytes ) != 0) {
+                        Error = CC_DH_CHECK_DOMAIN_PRIMES_NOT_VALID_ERROR;
+                        goto End;
+                }
+
+                /* compare pgen counters */
+                else if (pgenCounter != pgenCounter1) {
+                        Error = CC_DH_CHECK_DOMAIN_PRIMES_NOT_VALID_ERROR;
+                        goto End;
+                }
+        }
+
+        /*-----------------------------------------------------------------*/
+        /* Step 4. Check generator using the function for checking of      */
+        /*    the public key because both perform identical operations     */
+        /*    with appropriate parameters. In this case:                   */
+        /*    if G > P-2, or G < 2, or G^Q != 1, then output an error      */
+        /*-----------------------------------------------------------------*/
+
+        if (generatorG_ptr != NULL) {
+                Error = CC_DhCheckPubKey(
+                                           modP_ptr,                                   /*in */
+                                           modPsizeBytes,                              /*in */
+                                           orderQ_ptr,                                 /*in */
+                                           orderQsizeBytes,                            /*in */
+                                           generatorG_ptr,                             /*in */
+                                           generatorSizeBytes,                         /*in */
+                                           &DHKGbuff_ptr->ExpTemps);                   /*in */
+
+                /* Set error code according to checked parameter issue */
+                if (Error == CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR ||
+                    Error == CC_DH_INVALID_PUBLIC_KEY_ERROR) {
+
+                        Error =  CC_DH_CHECK_GENERATOR_NOT_VALID_ERROR;
+                }
+        }
+
+        End:
+        /* cleaning of temp buffers */
+        CC_PalMemSetZero(&DHKGbuff_ptr->ExpTemps, sizeof(DHKGbuff_ptr->ExpTemps));
+
+        /* End of function */
+
+        return Error;
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_edw/cc_ec_edw.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_edw/cc_ec_edw.c
new file mode 100644
index 0000000..d4b2bf3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_edw/cc_ec_edw.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_hash_defs.h"
+#include "cc_rnd_common.h"
+#include "cc_ec_edw_api.h"
+#include "mbedtls_cc_ec_mont_edw_error.h"
+
+#include "ec_edw.h"
+#include "ec_edw_local.h"
+
+/******************************************************************************/
+/**  Ed25519 Sign/Verify two types APIs: 1. For signature concatenated with   *
+ *    message; 2. For detached signature and message with separate in/out      */
+/******************************************************************************/
+/******************************************************************************/
+/**
+ * The function creates EC Edwards signature on the message.
+ *
+ *    Note: Used detached form of signature, separated from the message.
+ *          Implemented algorithm of Bernstein D. etc. sign ed25519.
+ *
+ *  @return CC_OK on success,
+ *  @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+ */
+CEXPORT_C CCError_t CC_EcEdwSign (
+        uint8_t       *pSign,                /*!< [out] Pointer to the detached signature. */
+        size_t        *pSignSize,            /*!< [in/out] Pointer to the total size of the signature ;
+                                                            In  - the buffer size, which (must be at least 2*EC order size);
+                                                            Out - the actual size of output data. */
+        const uint8_t *pMsg,                 /*!< [in] Pointer to the message. */
+        size_t         msgSize,              /*!< [in] Message size in bytes: must be less, than
+                                                            (CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - 2*(EC_EDW modulus size)). */
+        const uint8_t *pSignSecrKey,         /*!< [in] Pointer to the signer secret key (seed || pulKey) */
+        size_t         secrKeySize,          /*!< [in] Size of signer secret key in bytes: (must be 2*EC order size). */
+        CCEcEdwTempBuff_t *pTempBuff)  /*!< [in] pointer to the temp buffer. */
+{
+    CCError_t err = CC_OK;
+    uint32_t ecEdwKeySizeBytes = CC_32BIT_WORD_SIZE*CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS;
+    uint32_t ecEdwSignSizeBytes = 2*ecEdwKeySizeBytes;
+    /* the pointer to EC domain */
+    const CCEcEdwDomain_t *pEcDomain;
+
+    /* check input pointers */
+    if (pSign == NULL || pSignSize == NULL ||
+            ((pMsg  == NULL)^(msgSize == 0)) ||
+            pSignSecrKey == NULL ||
+            pTempBuff == NULL) {
+        return CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
+    }
+
+    /* max size of message according to HASH update requirements */
+    if(msgSize >= CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES) {
+        return  CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+    /* conditions for secret key size and buff. size for signature output */
+    if (secrKeySize != 2*ecEdwKeySizeBytes  ||
+            *pSignSize < ecEdwSignSizeBytes) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+
+    /* get domain */
+    pEcDomain = EcEdwGetDomain25519();
+
+    /***********************************************/
+    /**      calculate signature on the massage   **/
+    /***********************************************/
+
+    err = EcEdwSign(pSign, pMsg, msgSize,
+                    pSignSecrKey, pEcDomain, pTempBuff);
+    if (err) {
+        goto End;
+    } else {
+        *pSignSize = 2*ecEdwKeySizeBytes;
+    }
+
+    End:
+
+    return err;
+}
+
+/******************************************************************************/
+/**
+ * The function verifies the EC Edwards ed25519 signature on the message.
+ *
+ *    Note: The input signature is in detached form, i.e. separated from the
+ *          message.
+ *
+ *     Verification is performed using EC Edwards ed25519 signature algorithm.
+ *
+ * @return CC_OK on success,
+ * @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+ */
+CEXPORT_C CCError_t CC_EcEdwVerify(
+        const uint8_t *pSign,                /*!< [in] Pointer to detached signature, i.e. the
+                                                                         signature is separated from the message. */
+        size_t         signSize,             /*!< [in] Size of the signature in bytes, it must be
+                                                                         equal to two EC Order size in bytes. */
+        const uint8_t *pSignPublKey,         /*!< [in] Pointer to signer public key. */
+        size_t         publKeySize,          /*!< [in] Size of the signer public key in bytes; must be
+                                                                         equal to EC modulus size. */
+        uint8_t       *pMsg,                 /*!< [in] Pointer to the message. */
+        size_t         msgSize,              /*!< [in] Pointer to the message size in bytes. Must be less than
+                                                                         (CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - 2*(EC_EDW modulus size)). */
+        CCEcEdwTempBuff_t *pTempBuff)  /*!< [in] the pointer to temp buffer. */
+
+{
+    CCError_t err = CC_OK;
+    uint32_t ecEdwSizeBytes = CC_32BIT_WORD_SIZE*CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS;
+    uint32_t ecEdwSignSizeBytes = 2*ecEdwSizeBytes;
+    const CCEcEdwDomain_t *pEcDomain;    /*the pointer to Edw. EC domain*/
+
+    /* set pointers to temp buffers */
+    if (pSign == NULL || pSignPublKey == NULL ||
+            ((pMsg  == NULL)^(msgSize == 0)) || pTempBuff == NULL) {
+        return  CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
+    }
+
+    if(signSize != ecEdwSignSizeBytes ) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+
+    if(msgSize > CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES) {
+        return  CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+    if (publKeySize != ecEdwSizeBytes) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+
+    /* get domain */
+    pEcDomain = EcEdwGetDomain25519();
+
+    /* perform scalar mult. and adding of two points */
+    err = EcEdwSignVerify (pSign, pMsg, msgSize,
+                           pSignPublKey, pEcDomain, pTempBuff);
+
+    return err;
+}
+
+
+/*******************************************************************/
+/**          Edwards Key Pair generation from seeds API            */
+/*******************************************************************/
+/**
+ @brief The function randomly generates Ec ed25519 private and public keys
+        using given seed.
+
+        The generation is performed using EC Edwards ed25519 algorithm.
+
+ @return CC_OK on success,
+ @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+ */
+CEXPORT_C CCError_t CC_EcEdwSeedKeyPair (
+        const uint8_t *pSeed,                  /*!< [in] Pointer to the given seed. */
+        size_t         seedSize,               /*!< [in] Size of the seed in bytes, must be equal the EC order size
+                                                                             in bytes. */
+        uint8_t       *pSecrKey,               /*!< [out] Pointer to the secret key, including the seed, concatenated
+                                                                             with the public key. */
+        size_t        *pSecrKeySize,           /*!< [in/out] Pointer to the size of the secret key buffer in bytes
+                                                                             (must be at least 2*EC order size). */
+        uint8_t       *pPublKey,               /*!< [out] Pointer to the public key. */
+        size_t        *pPublKeySize,           /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                                In  - the size of buffer must be at least EC modulus size;
+                                                                                Out - the actual size. */
+        CCEcEdwTempBuff_t *pTempBuff)
+{
+    CCError_t err = CC_OK;
+    uint32_t ecEdwSizeBytes = CC_32BIT_WORD_SIZE*CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS;
+    uint32_t ecEdwSecrKeySizeBytes = 2*ecEdwSizeBytes;
+    const CCEcEdwDomain_t *pEcDomain;    /*the pointer to Edw. EC domain*/
+
+
+    if (pSeed  == NULL || pSecrKey == NULL || pSecrKeySize == NULL ||
+            pPublKey == NULL || pPublKeySize == NULL ) {
+        return   CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
+    }
+
+    if(pTempBuff == NULL)
+        return CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
+
+    if(*pSecrKeySize < ecEdwSecrKeySizeBytes) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+    if (*pPublKeySize < ecEdwSizeBytes) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+
+    if (seedSize != ecEdwSizeBytes) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+
+    /* get domain */
+    pEcDomain = EcEdwGetDomain25519();
+
+    /* calculate publ/priv keys and clean temp buffer */
+    err = EcEdwSeedKeyPair(pPublKey, pSecrKey,
+                           pSeed, pEcDomain, (uint32_t*)pTempBuff);
+    if (err)
+        goto End;
+
+    *pSecrKeySize = ecEdwSecrKeySizeBytes;
+    *pPublKeySize = ecEdwSizeBytes;
+
+    End:
+    return err;
+}
+
+
+/*******************************************************************/
+/**          Edwards Key Pair (random) generation  API             */
+/*******************************************************************/
+/**
+ @brief The function randomly generates the EC Edwards ed25519 private and
+         public keys.
+
+       The generation performed using EC Edwards ed25519 algorithm.
+
+        @return CC_OK on success,
+        @return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+ */
+CEXPORT_C CCError_t CC_EcEdwKeyPair (
+        uint8_t       *pSecrKey,               /*!< [out] Pointer to the secret key (including seed and public key). */
+        size_t        *pSecrKeySize,           /*!< [in/out] Pointer to the size of the secret key in bytes,
+                                                                          (must be at least 2*EC order size). */
+        uint8_t       *pPublKey,               /*!< [out] Pointer to the public key. */
+        size_t        *pPublKeySize,           /*!< [in/out] - Pointer to the size of the public key in bytes.
+                                                                            In  - the size of buffer must be at least EC modulus size;
+                                                                            Out - the actual size. */
+        CCRndContext_t *pRndContext,       /*!< [in/out] Pointer to the RND context buffer. */
+        CCEcEdwTempBuff_t *pTempBuff)
+{
+    CCError_t err = CC_OK;
+    uint32_t ecEdwSizeBytes;
+    uint8_t *pSeed = (uint8_t*)pTempBuff;
+    const CCEcEdwDomain_t *pEcDomain;    /*the pointer to Edw. EC domain*/
+    CCRndState_t   *pRndState;
+    CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+
+    /* FUNCTION LOGIC */
+
+    /* check parameters */
+    if (pSecrKey == NULL || pSecrKeySize == NULL ||
+            pPublKey == NULL || pPublKeySize == NULL ||
+            pTempBuff == NULL) {
+        return   CC_EC_EDW_INVALID_INPUT_POINTER_ERROR;
+    }
+    if (pRndContext == NULL)
+        return CC_EC_EDW_RND_CONTEXT_PTR_INVALID_ERROR;
+
+    /* get domain */
+    pEcDomain = EcEdwGetDomain25519();
+
+    ecEdwSizeBytes = CC_32BIT_WORD_SIZE * pEcDomain->ecModSizeInWords;
+
+    if(*pSecrKeySize < 2*ecEdwSizeBytes) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+    if (*pPublKeySize < ecEdwSizeBytes) {
+        return CC_EC_EDW_INVALID_INPUT_SIZE_ERROR;
+    }
+
+    pRndState = (CCRndState_t *)(pRndContext->rndState);
+    RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
+
+    if (RndGenerateVectFunc == NULL)
+        return CC_EC_EDW_RND_GEN_VECTOR_FUNC_ERROR;
+
+
+    /* generate random seed */
+    err = RndGenerateVectFunc((void *)pRndState, (unsigned char *)pSeed, (size_t)ecEdwSizeBytes);
+    if (err) {
+        goto End;
+    }
+
+
+    /* generate key pair */
+    err = EcEdwSeedKeyPair(pPublKey, pSecrKey,
+                           pSeed, pEcDomain,
+                           (uint32_t*)pTempBuff + CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS);
+    if(err)
+        goto End;
+
+    *pSecrKeySize = 2*ecEdwSizeBytes;
+    *pPublKeySize = ecEdwSizeBytes;
+
+    End:
+    CC_PalMemSetZero(pTempBuff, ecEdwSizeBytes);
+    return err;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_mont/cc_ec_mont.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_mont/cc_ec_mont.c
new file mode 100644
index 0000000..e7d8cf4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_mont/cc_ec_mont.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_hash_defs.h"
+#include "cc_common.h"
+#include "cc_rnd_error.h"
+#include "cc_ec_mont_api.h"
+#include "mbedtls_cc_ec_mont_edw_error.h"
+#include "ec_mont_local.h"
+#include "ec_mont.h"
+#include "cc_general_defs.h"
+#include "md.h"
+
+// RL Debug
+#include "pki_dbg.h"
+
+/******************************************************************************/
+/*!
+   The function performs EC Montgomery scalar multiplication:
+         resPoint = scalar * point.<br>
+  <br>
+         Note: all byte arrays have LE order of bytes, i.e. LS byte is on left most place.<br>
+  <br>
+  return CCError_t
+*/
+CEXPORT_C CCError_t CC_EcMontScalarmult(
+                                uint8_t       *pResPoint,       /*!< [out] Pointer to the public (secret) key. */
+                                size_t        *pResPointSize,   /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                       In  - the size of the buffer. must be at least EC modulus
+                                                                             size (for curve25519 - 32 bytes).
+                                                                       Out - the actual size. */
+                                const uint8_t *pScalar,         /*!< [in] Pointer to the secret (private) key. */
+                                size_t         scalarSize,      /*!< [in] Pointer to the size of the secret key in bytes;
+                                                                     must be equal to EC order size (for curve25519 - 32 bytes). */
+                                const uint8_t *pInPoint,        /*!< [in] Pointer to the input point (compressed). */
+                                size_t         inPointSize,     /*!< [in] Size of the point - must be equal to CC_EC_MONT_MOD_SIZE_IN_BYTES. */
+                                CCEcMontTempBuff_t *pEcMontTempBuff)  /*!< [in] pointer temp buffer. */
+{
+        CCError_t err = CC_OK;
+        /* pointers to aligned buffers */
+        uint32_t *pResPoint32, *pScalar32, *pInPoint32;
+        size_t ecOrdSizeBytes, ecModSizeBytes;
+        size_t scalarSizeWords;
+        /* the pointer to EC domain (curve). */
+        const CCEcMontDomain_t *pEcDomain;
+        uint32_t ls, ms;
+
+
+        if (pResPoint == NULL || pResPointSize == NULL ||
+            pScalar == NULL || pInPoint == NULL ||
+            pEcMontTempBuff == NULL) {
+                return CC_EC_MONT_INVALID_INPUT_POINTER_ERROR;
+        }
+
+        /* get domain */
+        pEcDomain = EcMontGetCurve25519Domain();
+
+
+        /* set EC domain parameters sizes */
+        scalarSizeWords = pEcDomain->ecOrdSizeInWords;
+        ecModSizeBytes = pEcDomain->ecModSizeInWords * sizeof(uint32_t);
+        ecOrdSizeBytes = pEcDomain->ecOrdSizeInWords * sizeof(uint32_t);
+
+        /* check sizes */
+        if (*pResPointSize < ecModSizeBytes ||
+            inPointSize != ecModSizeBytes  ||
+            scalarSize != ecOrdSizeBytes) {
+                return CC_EC_MONT_INVALID_INPUT_SIZE_ERROR;
+        }
+
+        /* set pointers to temp buffer */
+        pScalar32 = pEcMontTempBuff->ecMontScalar;
+        pResPoint32 = pEcMontTempBuff->ecMontResPoint;
+        pInPoint32 = pEcMontTempBuff->ecMontInPoint;
+
+        /* convert input byte arrays to LE word arrays */
+        CC_CommonConvertLsbMsbBytesToLswMswWords(pScalar32, (uint8_t*)pScalar, scalarSize);
+        CC_CommonConvertLsbMsbBytesToLswMswWords(pInPoint32, (uint8_t*)pInPoint, ecModSizeBytes);
+
+        /* revert changed bytes in the scalar */
+        ls = pScalar32[0]; ms = pScalar32[scalarSizeWords-1];
+
+        /* set scalar bits according to EC Montgomery curve25519 algorithm:
+           byte[31] = (byte[31] & 127) | 64; byte[0] &= 248; */
+        pScalar32[scalarSizeWords-1] = (pScalar32[scalarSizeWords-1] & 0x7FFFFFFF) | 0x40000000;
+        pScalar32[0] &= 0xFFFFFFF8;
+
+        /* call llf pScalar multiplication function */
+        err = EcMontScalarmult(
+                              pResPoint32,
+                              pScalar32,
+                              pInPoint32,
+                              pEcDomain);
+        if (err) {
+                err = CC_ECMONT_INTERNAL_ERROR;
+                goto EndWithError;
+        }
+
+        /* revert changed bytes in the scalar */
+        pScalar32[0] = ls; pScalar32[scalarSizeWords-1] = ms;
+
+        /* output pResPoint to LE bytes array */
+        CC_CommonConvertLswMswWordsToLsbMsbBytes(pResPoint, pResPoint32, pEcDomain->ecModSizeInWords);
+        *pResPointSize = ecModSizeBytes;
+
+        EndWithError:
+        /* zeroing temp buffers, they are not used as input/output */
+        if ((uint8_t*)pScalar32 != pScalar) {
+                CC_PalMemSetZero((uint8_t*)pScalar32, ecModSizeBytes);
+        }
+        if ((uint8_t*)pResPoint32 != pResPoint) {
+                CC_PalMemSetZero((uint8_t*)pResPoint32, ecModSizeBytes);
+        }
+        if ((uint8_t*)pInPoint32 != pInPoint) {
+                CC_PalMemSetZero((uint8_t*)pInPoint32, ecModSizeBytes);
+        }
+
+        CC_PalMemSetZero(&pEcMontTempBuff->ecMontScalrMultTempBuff, sizeof(CCEcMontScalrMultTempBuff_t));
+        return err;
+
+}
+
+/*********************************************************************/
+/*!
+@brief The function performs EC Montgomery (Curve25519) scalar multiplication of base point:
+       res = scalar * base_point.
+
+       Note: all byte arrays have LE order of bytes, i.e. LS byte is on left most place.
+
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+*/
+
+CEXPORT_C CCError_t CC_EcMontScalarmultBase(
+                                uint8_t       *pResPoint,      /*!< [out] Pointer to the public (secret) key. */
+                                size_t        *pResPointSize,  /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                      In  - the size of buffer must be at least EC modulus size
+                                                                          (for curve25519 - 32 bytes);
+                                                                      Out - the actual size. */
+                                const uint8_t *pScalar,        /*!< [in] Pointer to the secret (private) key. */
+                                size_t         scalarSize,     /*!< [in] Pointer to the size of the scalar in bytes -
+                                                                    must be equal to EC order size (for curve25519 - 32 bytes). */
+                                CCEcMontTempBuff_t *pEcMontTempBuff) /*!< [in] pointer to the temp buffer. */
+{
+        CCError_t err = CC_OK;
+        /* pointers to aligned buffers */
+        uint32_t *pResPoint32, *pScalar32;
+        size_t ecOrdSizeBytes, ecModSizeBytes;
+        size_t scalarSizeWords;
+        const CCEcMontDomain_t *pEcDomain;
+        uint32_t ls, ms;
+
+        /* check parameters */
+        if (pResPoint  == NULL || pResPointSize == NULL ||
+            pScalar == NULL || pEcMontTempBuff == NULL) {
+                return CC_EC_MONT_INVALID_INPUT_POINTER_ERROR;
+        }
+
+        /* get domain */
+        pEcDomain = EcMontGetCurve25519Domain();
+
+        /* set EC domain parameters sizes */
+        scalarSizeWords = pEcDomain->ecOrdSizeInWords;
+        ecModSizeBytes = pEcDomain->ecModSizeInWords * sizeof(uint32_t);
+        ecOrdSizeBytes = scalarSizeWords * sizeof(uint32_t);
+
+        /* check sizes */
+        if (*pResPointSize < ecModSizeBytes ||
+            scalarSize != ecOrdSizeBytes) {
+                return CC_EC_MONT_INVALID_INPUT_SIZE_ERROR;
+        }
+
+        /* set pointers to temp buffer */
+        pScalar32 = pEcMontTempBuff->ecMontScalar;
+        pResPoint32 = pEcMontTempBuff->ecMontResPoint;
+
+        /* convert input byte arrays to LE word arrays */
+        CC_CommonConvertLsbMsbBytesToLswMswWords(pScalar32, (uint8_t*)pScalar, scalarSize);
+
+        /* revert changed bytes in the scalar */
+        ls = pScalar32[0]; ms = pScalar32[scalarSizeWords-1];
+
+        /* set scalar bits according to EC Montgomery curve25519 algorithm:
+           byte[31] = (byte[31] & 127) | 64; byte[0] &= 248; */
+        pScalar32[scalarSizeWords-1] = (pScalar32[scalarSizeWords-1] & 0x7FFFFFFF) | 0x40000000;
+        pScalar32[0] &= 0xFFFFFFF8;
+
+        /* call llf pScalar multiplication function */
+        err = EcMontScalarmult(
+                              pResPoint32,
+                              pScalar32,
+                              (uint32_t*)pEcDomain->ecGenX,
+                              pEcDomain);
+        if (err) {
+                err = CC_ECMONT_INTERNAL_ERROR;
+                goto EndWithError;
+        }
+
+        /* revert changed bytes in the scalar */
+        pScalar32[0] = ls; pScalar32[scalarSizeWords-1] = ms;
+
+        /* output pResPoint to LE bytes array */
+        CC_CommonConvertLswMswWordsToLsbMsbBytes(pResPoint, pResPoint32,
+                                                    pEcDomain->ecModSizeInWords);
+        *pResPointSize = ecModSizeBytes;
+
+
+        EndWithError:
+        /* zeroing temp buffers if they are not used as input/output */
+        if ((uint8_t*)pScalar32 != pScalar) {
+                CC_PalMemSetZero((uint8_t*)pScalar32, ecModSizeBytes);
+        }
+        if ((uint8_t*)pResPoint32 != pResPoint) {
+                CC_PalMemSetZero((uint8_t*)pResPoint32, ecModSizeBytes);
+        }
+
+        return err;
+
+}
+/********************************************************************/
+
+static CCError_t ecMontKeyPairBase (
+                              uint8_t *pPublKey,                    /*!< [out] Pointer to the public key. */
+                              size_t  *pPublKeySize,                /*!< [in/out] Pointer to the size of the public key in bytes
+                                                                    In  - the size of the buffer must be at least EC order size
+                                                                   (for curve25519 - 32 bytes);
+                                                                                     Out - the actual size. */
+                              uint8_t *pSecrKey,                    /*!< [out] Pointer to the secret key, including. */
+                              size_t  *pSecrKeySize,                /*!< [in/out] Pointer to the size of buffer for the secret key in bytes -
+                                                                                    must be at least EC order size (for curve25519 - 32 bytes). */
+                              const uint8_t *pInPoint,        /*!< [in] Pointer to the input point (compressed). must be of size CC_EC_MONT_MOD_SIZE_IN_BYTES */
+                              CCRndContext_t *pRndContext,      /*!< [in/out] Pointer to the RND context buffer. */
+                              CCEcMontTempBuff_t *pEcMontTempBuff) /*!< [in] pointer to EC domain (curve). */
+{
+        /* DEFINITIONS */
+
+        CCError_t err = CC_OK;
+        uint32_t ecScalarSizeBytes, ecModSizeBytes;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+        /* the pointer to EC domain (curve). */
+        const CCEcMontDomain_t *pEcDomain;
+
+
+        /* FUNCTION LOGIC */
+
+        /* check input parameters */
+        if (pSecrKey  == NULL || pSecrKeySize == NULL ||
+            pPublKey  == NULL || pPublKeySize == NULL ||
+            pRndContext == NULL || pEcMontTempBuff == NULL) {
+                return CC_EC_MONT_INVALID_INPUT_POINTER_ERROR;
+        }
+
+        /* get domain */
+        pEcDomain = EcMontGetCurve25519Domain();
+
+        /* EC pScalar size in bytes */
+        ecScalarSizeBytes = pEcDomain->ecOrdSizeInWords * sizeof(uint32_t);
+        ecModSizeBytes = pEcDomain->ecModSizeInWords * sizeof(uint32_t);
+
+        if (*pSecrKeySize < ecScalarSizeBytes ||
+            *pPublKeySize < ecScalarSizeBytes) {
+                return CC_EC_MONT_INVALID_INPUT_SIZE_ERROR;
+        }
+
+        /* generaate secret key (seed) */
+        RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
+        if(RndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        err = RndGenerateVectFunc(
+                        (void *)pRndContext->rndState,
+                        (unsigned char *)pSecrKey,
+                        (size_t)ecScalarSizeBytes);
+        if (err) {
+                goto End;
+        }
+
+        *pPublKeySize = ecModSizeBytes;
+
+        /* calculate public key by pScalar mult. */
+        if (pInPoint != NULL)
+        {
+            err = CC_EcMontScalarmult(
+                                    pPublKey,
+                                    pPublKeySize,
+                                    pSecrKey,
+                                    ecScalarSizeBytes,
+                                    pInPoint,
+                                    CC_EC_MONT_MOD_SIZE_IN_BYTES,
+                                    pEcMontTempBuff);
+        }
+        else /* use the curve base point*/
+        {
+            err = CC_EcMontScalarmultBase(
+                                    pPublKey,
+                                    pPublKeySize,
+                                    pSecrKey,
+                                    ecScalarSizeBytes,
+                                    pEcMontTempBuff);
+        }
+        if (err) {
+                goto End;
+        }
+
+        /* output results */
+        *pSecrKeySize = ecScalarSizeBytes;
+
+        End:
+
+        CC_PalMemSetZero(pEcMontTempBuff, sizeof(CCEcMontTempBuff_t));
+
+        if (err) {
+                CC_PalMemSetZero(pPublKey, ecModSizeBytes);
+                CC_PalMemSetZero(pSecrKey, ecScalarSizeBytes);
+        }
+        return err;
+
+}
+
+
+/*******************************************************************/
+/*!
+@brief The function randomly generates  private and public keys for Montgomery
+       Curve25519, with a configurable base point.
+
+
+\note All byte arrays are in LE order of bytes, i.e. LS byte is on the left most place. \par
+\note LS and MS bits of the Secret key are set according to EC Montgomery scalar mult. algorithm:
+                secrKey[0] &= 248; secrKey[31] &= 127; secrKey[31] |= 64;
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+
+*/
+CEXPORT_C CCError_t CC_EcMontKeyPairBase(
+                                         uint8_t *pPublKey,                    /*!< [out] Pointer to the public key. */
+                                         size_t  *pPublKeySize,                /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                                     In  - the size of the buffer must be at least EC order size
+                                                                                           (for curve25519 - 32 bytes);
+                                                                                     Out - the actual size. */
+                                         uint8_t *pSecrKey,                    /*!< [out] Pointer to the secret key, including. */
+                                         size_t  *pSecrKeySize,                /*!< [in/out] Pointer to the size of buffer for the secret key in bytes -
+                                                                                    must be at least EC order size (for curve25519 - 32 bytes). */
+                                         const uint8_t *pInPoint,        /*!< [in] Pointer to the input point (compressed). */
+                                         size_t         inPointSize,     /*!< [in] Size of the point - must be equal to CC_EC_MONT_MOD_SIZE_IN_BYTES. */
+                                         CCRndContext_t *pRndContext,      /*!< [in/out] Pointer to the RND context buffer. */
+                                         CCEcMontTempBuff_t *pEcMontTempBuff) /*!< [in] pointer to EC domain (curve). */
+{
+    if (inPointSize != CC_EC_MONT_MOD_SIZE_IN_BYTES)
+    {
+        return CC_EC_MONT_INVALID_INPUT_SIZE_ERROR;
+    }
+
+    return ecMontKeyPairBase(pPublKey, pPublKeySize, pSecrKey, pSecrKeySize, pInPoint, pRndContext, pEcMontTempBuff);
+}
+
+/*******************************************************************/
+/*!
+@brief The function randomly generates  private and public keys for Montgomery
+       Curve25519. it uses CC_EcMontKeyPair with the Generator point of the Curve
+
+
+\note All byte arrays are in LE order of bytes, i.e. LS byte is on the left most place. \par
+\note LS and MS bits of the Secret key are set according to EC Montgomery scalar mult. algorithm:
+                secrKey[0] &= 248; secrKey[31] &= 127; secrKey[31] |= 64;
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+
+*/
+CEXPORT_C CCError_t CC_EcMontKeyPair(
+                                         uint8_t *pPublKey,                    /*!< [out] Pointer to the public key. */
+                                         size_t  *pPublKeySize,                /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                                     In  - the size of the buffer must be at least EC order size
+                                                                                          (for curve25519 - 32 bytes);
+                                                                                     Out - the actual size. */
+                                         uint8_t *pSecrKey,                    /*!< [out] Pointer to the secret key, including. */
+                                         size_t  *pSecrKeySize,                /*!< [in/out] Pointer to the size of buffer for the secret key in bytes -
+                                                                                    must be at least EC order size (for curve25519 - 32 bytes). */
+                                         CCRndContext_t *pRndContext,      /*!< [in/out] Pointer to the RND context buffer. */
+                                         CCEcMontTempBuff_t *pEcMontTempBuff) /*!< [in] pointer to EC domain (curve). */
+{
+
+    return ecMontKeyPairBase(pPublKey, pPublKeySize, pSecrKey, pSecrKeySize, NULL, pRndContext, pEcMontTempBuff);
+}
+
+/*******************************************************************/
+/**
+@brief The function generates private and public keys for Montgomery Curve25519
+       using given seed.
+
+       Note: all byte arrays have LE order of bytes, i.e. LS byte is on left most place.
+
+@return CC_OK on success,
+@return a non-zero value on failure as defined mbedtls_cc_ec_mont_edw_error.h.
+*/
+CEXPORT_C CCError_t CC_EcMontSeedKeyPair (
+                      uint8_t       *pPublKey,       /*!< [out] Pointer to the public (secret) key. */
+                      size_t        *pPublKeySize,   /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                             In  - the size of buffer must be at least EC order size
+                                                                (for curve25519 - 32 bytes);
+                                                             Out - the actual size. */
+                      uint8_t       *pSecrKey,       /*!< [out] Pointer to the secret (private) key. */
+                      size_t        *pSecrKeySize,   /*!< [in/out] Pointer to the size of the secret key in bytes
+                                                              In  - the size of buffer must be at least EC order size
+                                                                (for curve25519 - 32 bytes);
+                                                              Out - the actual size. */
+                      const uint8_t *pSeed,          /*!< [in] Pointer to the given seed - 32 bytes. */
+                      size_t         seedSize,       /*!< [in/] Size of the seed in bytes (must be equal to CC_EC_MONT_SEEDBYTES). */
+                      CCEcMontTempBuff_t *pEcMontTempBuff)  /*!< [in] pointer temp buffer. */
+{
+        /* DEFINITIONS */
+
+        CCError_t err = CC_OK;
+        uint8_t *pScalar, *pRes;
+        CCHashResultBuf_t *pHashResult; /*takes 64 bytes in pEcMontTempBuff*/
+        uint32_t ecOrdSizeBytes, ecMontSizeBytes;
+        /* the pointer to EC domain (curve). */
+        const CCEcMontDomain_t *pEcDomain;
+        const mbedtls_md_info_t *md_info=NULL;
+
+        /* FUNCTION LOGIC */
+
+
+        /* check input parameters */
+        if (pSecrKey  == NULL || pSecrKeySize == NULL ||
+            pPublKey == NULL || pPublKeySize == NULL ||
+            pSeed == NULL || pEcMontTempBuff == NULL) {
+                return CC_EC_MONT_INVALID_INPUT_POINTER_ERROR;
+        }
+
+        /* get domain */
+        pEcDomain = EcMontGetCurve25519Domain();
+
+        ecOrdSizeBytes = pEcDomain->ecOrdSizeInWords*sizeof(uint32_t);
+        ecMontSizeBytes = pEcDomain->ecModSizeInWords*sizeof(uint32_t);
+
+        if (*pSecrKeySize < ecOrdSizeBytes ||
+             seedSize != ecOrdSizeBytes) {
+                return CC_EC_MONT_INVALID_INPUT_SIZE_ERROR;
+        }
+
+        pHashResult = (CCHashResultBuf_t*)pEcMontTempBuff;
+        pScalar = (uint8_t*)&pEcMontTempBuff->ecMontScalar;
+        pRes = (uint8_t*)&pEcMontTempBuff->ecMontResPoint;
+
+        /* copy seed into buffer with phys. memory (HW HASH requirement) */
+        CC_PalMemCopy(pScalar, pSeed, seedSize);
+
+        /* calculate secret key; note pScalar points  *
+        *  to the same mem. as pHashResult            */
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[CC_HASH_SHA512_mode] );
+        if (NULL == md_info) {
+             err = CC_EC_MONT_INVALID_INPUT_SIZE_ERROR;
+             goto End;
+
+        }
+        err = mbedtls_md(md_info,
+                         pScalar,
+                         seedSize,
+                        (unsigned char *)(*pHashResult));
+        if (err) {
+                goto End;
+        }
+
+        /* calculate the public key */
+        err = CC_EcMontScalarmultBase(
+                                (uint8_t*)&pEcMontTempBuff->ecMontResPoint[0],
+                                pPublKeySize,
+                                pScalar,  // check endianness !
+                                ecOrdSizeBytes,
+                                pEcMontTempBuff);
+
+        if (err) {
+                goto End;
+        }
+
+        /* set actual sizes of Secr. and publ. keys */
+        *pSecrKeySize = ecOrdSizeBytes;
+        *pPublKeySize = ecMontSizeBytes;
+
+        /* output secret and publ. keys */
+        CC_PalMemCopy(pSecrKey, (uint8_t*)pScalar, *pSecrKeySize);
+        CC_PalMemCopy(pPublKey, pRes, *pPublKeySize);
+
+        End:
+        /* clean the temp buffers */
+        CC_PalMemSetZero((uint8_t*)pEcMontTempBuff, sizeof(CCEcMontTempBuff_t));
+        if (err) {
+                CC_PalMemSetZero(pSecrKey, ecOrdSizeBytes);
+                CC_PalMemSetZero(pPublKey, ecMontSizeBytes);
+        }
+
+        return err;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdh.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdh.c
new file mode 100644
index 0000000..db24612
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdh.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "ec_wrst.h"
+#include "cc_fips_defs.h"
+
+/************************ Defines *************************************/
+
+/************************ Enums ***************************************/
+
+/************************ Typedefs ************************************/
+
+/************************ Global Data *********************************/
+
+/************* Private function prototype *****************************/
+
+
+/************************ Public Functions ****************************/
+
+
+/***********************************************************************
+ *               CC_EcdhSvdpDh function                            *
+ ***********************************************************************/
+CEXPORT_C CCError_t CC_EcdhSvdpDh(
+                                       CCEcpkiUserPublKey_t *PartnerPublKey_ptr,        /*in*/
+                                       CCEcpkiUserPrivKey_t *UserPrivKey_ptr,           /*in*/
+                                       uint8_t                  *SharedSecretValue_ptr,     /*out*/
+                                       size_t                   *SharedSecrValSize_ptr,     /*in/out*/
+                                       CCEcdhTempData_t     *TempBuff_ptr               /*in*/ )
+{
+        /* LOCAL INITIALIZATIONS AND DECLERATIONS */
+
+        /* the error identifier */
+        CCError_t Error = CC_OK;
+
+        CCEcpkiPublKey_t *PublKey_ptr;
+        CCEcpkiPrivKey_t *PrivKey_ptr;
+
+        /*  pointer to the current Domain structure */
+        CCEcpkiDomain_t *pDomain, *pPublDomain;
+        uint32_t modSizeInBytes;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* ...... checking the validity of the user private key pointer .......... */
+        if (UserPrivKey_ptr == NULL)
+                return CC_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR;
+
+        /* ...... checking the valid tag of the user private key pointer ......... */
+        if (UserPrivKey_ptr->valid_tag != CC_ECPKI_PRIV_KEY_VALIDATION_TAG)
+                return CC_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR;
+
+        /* .... checking the validity of the other partner public key pointer .... */
+        if (PartnerPublKey_ptr == NULL)
+                return CC_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR;
+
+        /* ...... checking the valid tag of the user private key pointer ......... */
+        if (PartnerPublKey_ptr->valid_tag != CC_ECPKI_PUBL_KEY_VALIDATION_TAG)
+                return CC_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR;
+
+        /* ...... checking the validity of the SharedSecretValue pointer ..........*/
+        if (SharedSecretValue_ptr == NULL)
+                return CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR;
+
+        /* ...... checking the validity of SharedSecrValSize_ptr pointer ......... */
+        if (SharedSecrValSize_ptr == NULL)
+                return CC_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR;
+
+        /* ...... checking the validity of temp buffers         .................. */
+        if (TempBuff_ptr == NULL)
+                return CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR;
+
+        /* ..  initializtions  and other checking   .... */
+        /* --------------------------------------------- */
+
+        /* derive  public and private keys pointers */
+        PublKey_ptr = (CCEcpkiPublKey_t*)&PartnerPublKey_ptr->PublKeyDbBuff;
+        PrivKey_ptr = (CCEcpkiPrivKey_t*)&UserPrivKey_ptr->PrivKeyDbBuff;
+
+        /* the pointers to private and public keys domains */
+        pDomain = &PrivKey_ptr->domain;
+        pPublDomain = &PublKey_ptr->domain;
+
+        /* if domains are not identical, return an error */
+        if(CC_PalMemCmp(pDomain, pPublDomain, sizeof(CCEcpkiDomain_t))) {
+                return CC_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR;
+        }
+
+        /* modulus size */
+        modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
+
+        /*  check the size of the buffer for Shared value  */
+        if (*SharedSecrValSize_ptr < modSizeInBytes) {
+                *SharedSecrValSize_ptr = modSizeInBytes;
+                return CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR;
+        }
+
+        /* performing DH operations by calling  EcWrstDhDeriveSharedSecret() function */
+        /*------------------------------------------------------------------*/
+        Error = EcWrstDhDeriveSharedSecret(
+                                 PublKey_ptr, PrivKey_ptr,
+                                 SharedSecretValue_ptr,
+                                 TempBuff_ptr);
+
+        if (Error != CC_OK)
+                goto End;
+
+        /* Set SharedSecrValSize = ModSizeInWords  for user control */
+        *SharedSecrValSize_ptr = modSizeInBytes;
+
+End:
+        if (Error != CC_OK) {
+        CC_PalMemSetZero(SharedSecretValue_ptr, *SharedSecrValSize_ptr);
+        *SharedSecrValSize_ptr = 0;
+    }
+    CC_PalMemSetZero(TempBuff_ptr, sizeof(CCEcdhTempData_t));
+
+        return Error;
+
+}/* END OF CC_EcdhSvdpDh */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdsa_sign.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdsa_sign.c
new file mode 100644
index 0000000..2ef8c8f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdsa_sign.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_ASYM_ECC
+
+/************* Include Files ****************/
+
+
+#include "cc_pal_mem.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "cc_ecpki_ecdsa.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_hash_defs.h"
+#include "cc_rnd_common.h"
+#include "cc_rsa_types.h"
+#include "cc_fips_defs.h"
+#include "ec_wrst.h"
+#ifdef USE_MBEDTLS_CRYPTOCELL
+#include "cc_general_defs.h"
+#include "md.h"
+#endif
+
+/************************ Defines *****************************************/
+#if ( CC_HASH_USER_CTX_SIZE_IN_WORDS > CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS )
+        #error CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS or CC_HASH_USER_CTX_SIZE_IN_WORDS  defined not correctly.
+#endif
+
+/************************ Enums *******************************************/
+
+/************************ Typedefs ****************************************/
+
+/************************ Global Data *************************************/
+
+extern const CCEcpkiHash_t ecpki_hash_info[CC_ECPKI_HASH_NumOfModes];
+extern const uint8_t ecpki_supported_hash_modes[CC_ECPKI_HASH_NumOfModes];
+/************* Private function prototype *********************************/
+
+/************************ Public Functions ********************************/
+
+
+/**************************************************************************
+ *                EcdsaSignInit function
+ **************************************************************************/
+/**
+   \brief
+   The EcdsaSignInit functions user shall call first to perform the
+   EC DSA Signing operation.
+
+   The function performs the following steps:
+   -# Validates all the inputs of the function. If one of the received
+      parameters is not valid, the function returns an error.
+   -# Initializes the working context and other variables and structures.
+   -# Calls the CC_HashInit() function.
+   -# Exits the handler with the OK code.
+
+   This function does not do ECDSA cryptographic processing. Rather, it
+   prepares a context that is used by the Update() and Finish() functions.
+
+   NOTE: Using of HASH functions with HASH size great, than EC modulus size, is not recommended!
+
+
+   @param[in,out] pSignUserContext A pointer to the user buffer for signing data.
+   @param[in]     pSignerPrivKey   A pointer to the private key that will be used to
+                                      sign the data.
+   @param[in]     hashMode            Defines the hash mode used for DSA.
+
+   @return <b>CCError_t</b>: <br>
+                         CC_OK<br>
+                         CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR
+                         CC_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR
+                         CC_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR
+                         CC_ECDSA_SIGN_INVALID_DOMAIN_ID_ERROR
+                         CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR
+*/
+CEXPORT_C CCError_t EcdsaSignInit(CCEcdsaSignUserContext_t  *pSignUserContext, /*in/out*/
+                                    CCEcpkiUserPrivKey_t      *pSignerPrivKey,   /*in*/
+                                    CCEcpkiHashOpMode_t       hashMode          /*in*/ )
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+        /* defining a pointer to the active context allcated by the CCM */
+        EcdsaSignContext_t *pWorkingContext;
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        const mbedtls_md_info_t *md_info=NULL;
+#endif
+
+        /* FUNCTION LOGIC */
+        pWorkingContext = (EcdsaSignContext_t*)&pSignUserContext->context_buff;
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* if the users context ID pointer is NULL return an error */
+        if (pSignUserContext == NULL){
+                return CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR;
+        }
+
+        /*if the private key object is NULL return an error*/
+        if (pSignerPrivKey == NULL){
+                err = CC_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR;
+                goto End;
+        }
+
+        /* check if the hash operation mode is legal */
+        if (hashMode >= CC_ECPKI_HASH_NumOfModes){
+                err = CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR;
+                goto End;
+        }
+
+        if (pSignerPrivKey->valid_tag != CC_ECPKI_PRIV_KEY_VALIDATION_TAG){
+                err = CC_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR;
+                goto End;
+        }
+
+        /* reset the Context handler for improper previous values initialized */
+        CC_PalMemSetZero(pWorkingContext, sizeof(EcdsaSignContext_t));
+
+        /* ................. loading the context .................................. */
+        /* ------------------------------------------------------------------------ */
+
+        /*Initializing the Hash operation mode in the ECDSA Context */
+
+        if (ecpki_supported_hash_modes[hashMode] == CC_FALSE) {
+                err = CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR;
+                goto End;
+        }
+
+        pWorkingContext->hashMode = hashMode;
+        pWorkingContext->hashResultSizeWords = ecpki_hash_info[pWorkingContext->hashMode].hashResultSize;
+
+        if (ecpki_hash_info[pWorkingContext->hashMode].hashMode < CC_HASH_NumOfModes) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[ecpki_hash_info[pWorkingContext->hashMode].hashMode] );
+        if (NULL == md_info) {
+                err = CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR;
+                goto End;
+        }
+        mbedtls_md_init(&(pWorkingContext->hash_ctx));
+        err = mbedtls_md_setup(&(pWorkingContext->hash_ctx), md_info, 0); // 0 = HASH, not HMAC
+        if (err != 0) {
+                goto End;
+        }
+        err = mbedtls_md_starts(&(pWorkingContext->hash_ctx));
+#else
+                err = CC_HashInit(&(pWorkingContext->hashUserCtxBuff),
+                                     ecpki_hash_info[pWorkingContext->hashMode].hashMode);
+#endif
+                if (err != CC_OK)
+                        goto End;
+        }
+
+        /* copy the ECPKI Private key to the context*/
+        CC_PalMemCopy(&pWorkingContext->ECDSA_SignerPrivKey, pSignerPrivKey, sizeof(CCEcpkiUserPrivKey_t));
+
+        /* set the ECDSA validation tag */
+        pSignUserContext->valid_tag = CC_ECDSA_SIGN_CONTEXT_VALIDATION_TAG;
+
+        End:
+        /*  clear the users context in case of error */
+        if (err != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                if(md_info!=NULL){
+                        mbedtls_md_free(&(pWorkingContext->hash_ctx));
+                }
+#endif
+                CC_PalMemSetZero(pSignUserContext, sizeof(CCEcdsaSignUserContext_t));
+        }
+
+        return err;
+
+}/* _DX_ECDSA_SignInit */
+
+
+
+/**************************************************************************
+ *                EcdsaSignUpdate function
+ **************************************************************************/
+/**
+   @brief  Performs a hash  operation on data allocated by the user
+           before finally signing it.
+
+           In case user divides signing data by block, he must call the Update function
+           continuously a number of times until processing of the entire data block is complete.
+
+       NOTE: Using of HASH functions with HASH size great, than EC modulus size,
+             is not recommended!
+
+   @param [in,out] pSignUserContext - The pointer to the user buffer for signing the database.
+   @param [in] pMessageDataIn - The pointer to the message data block for calculating the HASH.
+   @param [in] dataInSize -  The size of the message data block, in bytes. The data size,
+                   passed on each call of the function, besides the last call, must be a multiple of
+                   the HASH block size according to used HASH mode.
+
+   @return <b>CCError_t</b>: <br>
+                         CC_OK<br>
+                         CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR
+                         CC_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR
+                         CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR
+                         CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR
+                         CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR
+ */
+CEXPORT_C CCError_t EcdsaSignUpdate(
+                                           CCEcdsaSignUserContext_t  *pSignUserContext,  /*in/out*/
+                                           uint8_t                       *pMessageDataIn,    /* in */
+                                           size_t                        dataInSize         /* in */ )
+{
+        /* FUNCTION DECLERATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+        /*  pointers to the inner contexts */
+        EcdsaSignContext_t *pWorkingContext;
+
+        /* FUNCTION LOGIC */
+
+        /* sign working context */
+        pWorkingContext = (EcdsaSignContext_t*)&pSignUserContext->context_buff;
+
+        /* ....... checking the parameters validity ......... */
+        /* -------------------------------------------------------------------- */
+
+        /* if the users context pointer is NULL return an error */
+        if (pSignUserContext == NULL){
+                return CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR;
+        }
+
+        /* if the users context TAG is illegal return an error - the context is invalid */
+        if (pSignUserContext->valid_tag != CC_ECDSA_SIGN_CONTEXT_VALIDATION_TAG) {
+                err = CC_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR;
+                goto End;
+        }
+
+        /* if the users MessageDataIn pointer is illegal return an error */
+        if (pMessageDataIn == NULL && dataInSize) {
+                err = CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR;
+                goto End;
+        }
+
+        /* check that the data size < 2^29 (to prevent an overflow on the
+           transition to bits ) */
+        if (dataInSize >= (1UL << 29)) {
+                err = CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR;
+                goto End;
+        }
+
+        /* HASH update operations */
+        if (ecpki_hash_info[pWorkingContext->hashMode].hashMode < CC_HASH_NumOfModes) {
+                /*Operate the Hash update function for relevant version */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                err = mbedtls_md_update(&(pWorkingContext->hash_ctx), pMessageDataIn, dataInSize);
+#else
+                err = CC_HashUpdate( &(pWorkingContext->hashUserCtxBuff), pMessageDataIn, dataInSize );
+#endif
+                if (err != CC_OK) {
+                        goto End;
+                }
+        } else {
+                if (dataInSize != pWorkingContext->hashResultSizeWords*sizeof(uint32_t)) {
+                        /* DataInSize must fit exactly to the size of Hash output that we support */
+                        err = CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR;
+                        goto End;
+                }
+                /* Copy the DataIn_ptr to the HASH_Result */
+                CC_PalMemCopy((uint8_t*)pWorkingContext->hashResult, pMessageDataIn, dataInSize);
+        }
+
+
+        End:
+        /*  clear the users context in case of error */
+        if (err != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                mbedtls_md_free(&(pWorkingContext->hash_ctx));
+#endif
+                CC_PalMemSetZero(pSignUserContext, sizeof(CCEcdsaSignUserContext_t));
+        }
+
+        return err;
+
+}/* EcdsaSignUpdate */
+
+
+
+
+/**************************************************************************
+ *                EcdsaSignFinishInt function
+ **************************************************************************/
+/**
+   @brief  Performs initialization of variables and structures, calls the hash function
+           for the last block of data (if necessary) and then calculates digital signature.
+
+           NOTE: Using of HASH functions with HASH size great, than EC modulus size,
+                 is not recommended!
+             Algorithm according ANS X9.62 standard
+
+   @param[in] pSignUserContext -  A pointer to the user buffer for signing database.
+   @param[in,out] pRndContext - A pointer to the random generation function context.
+   @param[in] pSignatureOut - A pointer to a buffer for output of signature.
+   @param[in,out] pSignatureOutSize- A pointer to the size of a user passed buffer
+                     for signature (in), be not less than 2*orderSizeInBytes.
+   @param[out] isEphemerKeyInternal - A parameter defining whether the ephemeral key
+                     is internal or external (1 or 0).
+   @param[out] pEphemerKeyData - A pointer to external ephemeral key data. If it is given
+               (in case isEphemerKeyInternal=0), then the buffer must containing the
+               ephemeral private key of size equal to EC generator order size, where
+               LS-word is left most and MS-word is right most one.
+
+   @return <b>CCError_t</b>: <br>
+                         CC_OK<br>
+                         CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR <br>
+                         CC_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR <br>
+                         CC_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR <br>
+                         CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR <br>
+                         CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR <br>
+                         CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR <br>
+                         CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR <br>
+                         CC_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR <br>
+                         CC_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR <br>
+**/
+CEXPORT_C  CCError_t EcdsaSignFinishInt(
+                                           CCEcdsaSignUserContext_t   *pSignUserContext, /*in*/
+                                           CCRndContext_t             *pRndContext,      /*in/out*/
+                                           uint8_t                        *pSignOut,         /*out*/
+                                           size_t                         *pSignOutSize,     /*in/out*/
+                                           uint32_t                        isEphemerKeyInternal,/*in*/
+                                           uint32_t                       *pEphemerKeyData   /*in*/)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+        /* pointer to the active context  */
+        EcdsaSignContext_t  *pWorkingContext;
+
+        /* pointer to private key structure in ccmWorkingContext  */
+        CCEcpkiPrivKey_t  *pPrivKey;
+        /*  pointer to the current domain */
+        CCEcpkiDomain_t  *pDomain;
+
+        uint32_t  orderSizeInBytes = 0, orderSizeInWords = 0;
+        uint32_t  *pSignC, *pSignD;
+        uint32_t  *pMessRepres;
+        uint32_t  hashSizeWords;
+        uint32_t  *pTempBuff;
+
+        /* FUNCTION LOGIC */
+
+        /* the pointer to the internal Sign context */
+        pWorkingContext = (EcdsaSignContext_t*)&pSignUserContext->context_buff;
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* check the user context and RND context pointers */
+        if (pSignUserContext == NULL){
+                return CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR;
+        }
+
+        if (pRndContext == NULL){
+                err = CC_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR;
+                goto End;
+        }
+
+        /* check the user's context tag  */
+        if (pSignUserContext->valid_tag != CC_ECDSA_SIGN_CONTEXT_VALIDATION_TAG){
+                err = CC_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR;
+                goto End;
+        }
+
+        /* check the user's SignatureOut and SignatureOutSize pointers */
+        if (pSignOut == NULL){
+                err = CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR;
+                goto End;
+        }
+
+        if (pSignOutSize == NULL){
+                err = CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR;
+                goto End;
+        }
+
+        /* check isEphemerKeyInternal value and ephemeral key data pointer */
+        if (isEphemerKeyInternal > 1){
+                err = CC_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR;
+                goto End;
+        }
+
+        if (isEphemerKeyInternal == 0 && pEphemerKeyData == NULL){
+                err = CC_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR;
+                goto End;
+        }
+
+        /* ............. checking the validity of context ........ */
+        /* ------------------------------------------------------- */
+
+        /* check Hash mode */
+        if (pWorkingContext->hashMode >= CC_ECPKI_HASH_NumOfModes){
+                err = CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR;
+                goto End;
+        }
+
+        pPrivKey = (CCEcpkiPrivKey_t *)&pWorkingContext->ECDSA_SignerPrivKey.PrivKeyDbBuff;
+        /* Initializing domain parameters */
+        pDomain = &pPrivKey->domain;
+        orderSizeInBytes =  CALC_FULL_BYTES(pDomain->ordSizeInBits);
+        orderSizeInWords  =  CALC_FULL_32BIT_WORDS(pDomain->ordSizeInBits);
+        hashSizeWords  = pWorkingContext->hashResultSizeWords;
+
+        /* Temp buffers */
+        pMessRepres = ((EcWrstDsaSignDb_t*)&pWorkingContext->ecdsaSignIntBuff)->tempBuff;
+        pSignC       = pMessRepres + orderSizeInWords;
+        pSignD       = pSignC + orderSizeInWords;
+        pTempBuff    = pSignD + orderSizeInWords;
+
+        /* If the received output buffer is small than 2*orderSizeInBytes then return an error */
+        if (*pSignOutSize < 2*orderSizeInBytes){
+                err = CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR;
+                goto End;
+        }
+
+        /* Operating the HASH Finish function; only if it is needed */
+        if (pWorkingContext->hashMode <= CC_ECPKI_HASH_SHA512_mode) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                err = mbedtls_md_finish(&(pWorkingContext->hash_ctx), (unsigned char *)pWorkingContext->hashResult);
+#else
+                err = CC_HashFinish(&(pWorkingContext->hashUserCtxBuff), pWorkingContext->hashResult);
+#endif
+                if (err != CC_OK)
+                        goto End;
+        }
+
+        /* Derive message representative from HASH_Result: MessageRepresent =
+           leftmost OrderSizeInBits bits of HASH_Result */
+
+        /* Set 0 to MessageRepresent buffer of length OrdSizeInWords */
+        CC_PalMemSetZero(pMessRepres, sizeof(uint32_t)*orderSizeInWords);
+
+        /* Derive message representative = leftmost OrderSizeInBits bits of HASH_Result */
+        /* Add change Endianness for BE CPU */
+        if (pDomain->ordSizeInBits >= 32*hashSizeWords) {
+                CC_CommonReverseMemcpy((uint8_t*)pMessRepres, (uint8_t*)(pWorkingContext->hashResult),
+                                       sizeof(uint32_t)*hashSizeWords);
+        } else {
+                EcWrstDsaTruncateMsg(pMessRepres,
+                                     (uint8_t*)(pWorkingContext->hashResult), pDomain->ordSizeInBits);
+        }
+
+
+        /* ********  Call LLF ECDSA Sinature function  ************ */
+        err =  EcWrstDsaSign(
+                                     pRndContext, pPrivKey,
+                                     pMessRepres,
+                                     isEphemerKeyInternal, pEphemerKeyData,
+                                     pSignC, pSignD, pTempBuff);
+
+        if (err != CC_OK) {
+                err = CC_ECDSA_SIGN_SIGNING_ERROR;
+                goto End;
+        }
+
+        /* Output the reversed C,D strings of length orderSizeInBytes */
+        err = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                         pSignOut, orderSizeInBytes,
+                                                         pSignC, orderSizeInBytes);
+        if (err != CC_OK) {
+                err = CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR;
+                goto End;
+        }
+
+        err = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                         pSignOut + orderSizeInBytes, orderSizeInBytes,
+                                                         pSignD, orderSizeInBytes);
+        if (err != CC_OK) {
+                err = CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR;
+                goto End;
+        }
+
+        *pSignOutSize = 2*orderSizeInBytes;
+
+
+        End:
+        if (err != CC_OK) {
+                CC_PalMemSetZero(pSignOut, (2*orderSizeInBytes));
+        }
+#ifdef USE_MBEDTLS_CRYPTOCELL
+       mbedtls_md_free(&(pWorkingContext->hash_ctx));
+#endif
+        /* clear the users context  */
+        CC_PalMemSetZero(pSignUserContext, sizeof(CCEcdsaSignUserContext_t));
+
+        return err;
+
+}/* EcdsaSignFinish */
+
+
+
+/**************************************************************************
+ *                CC_EcdsaSign - integrated function
+ **************************************************************************/
+/**
+   @brief  Performs all of the ECDSA signing operations simultaneously.
+
+This function simply calls the Init, Update and Finish functions continuously.
+               This function's prototype is similar to the prototypes of the called functions
+               and includes all of their input and output arguments.
+
+   NOTE: Signature lgorithm according ANS X9.62 standard
+         Using of HASH functions with HASH size great, than EC modulus size, is not recommended!
+
+   @param[in,out] pRndContext - A pointer to the random generation function context.
+   @param[in,out] pSignUserContext - A pointer to the user buffer for signing database.
+   @param[in]     pSignerPrivKey   - A pointer to a user private key structure.
+   @param[in]     hashMode         - The enumerator variable defines hash function to be used.
+   @param[in]     pMessageDataIn   - A message data for calculation of hash.
+   @param[in]     messageSizeInBytes  - A size of block of message data in bytes.
+   @param[in]     SignOut_ptr      - A pointer to a buffer for output of signature.
+   @param[in,out] SignOutSize_ptr  - A pointer to the size of user passed buffer for signature (in)
+                                        and size of actual signature (out). The size of buffer
+                                        must be not less than 2*OrderSizeInBytes.
+
+   @return <b>CCError_t
+**/
+CEXPORT_C CCError_t CC_EcdsaSign(
+                                     CCRndContext_t              *pRndContext,           /*in/out*/
+                                     CCEcdsaSignUserContext_t    *pSignUserContext,      /*in/out*/
+                                     CCEcpkiUserPrivKey_t        *pSignerPrivKey,        /*in*/
+                                     CCEcpkiHashOpMode_t         hashMode,              /*in*/
+                                     uint8_t                         *pMessageDataIn,        /*in*/
+                                     size_t                           messageSizeInBytes,    /*in*/
+                                     uint8_t                         *pSignOut,              /*out*/
+                                     size_t                          *pSignOutSize           /*in*/)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+        /* FUNCTION LOGIC */
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /*****  EcdsaSignInit  ********/
+        err = EcdsaSignInit( pSignUserContext, pSignerPrivKey, hashMode );
+
+        if (err!=CC_OK)
+                return err;
+
+        /*****  EcdsaSignUpdate  ********/
+        err = EcdsaSignUpdate(pSignUserContext, pMessageDataIn,
+                                    messageSizeInBytes);
+        if (err!=CC_OK)
+                return err;
+
+        /*****  EcdsaSignFinish  ********/
+        err = EcdsaSignFinish(pSignUserContext, pRndContext,
+                                    pSignOut, pSignOutSize);
+        return err;
+
+}/* END OF CC_EcdsaSign */
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdsa_verify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdsa_verify.c
new file mode 100644
index 0000000..e95ea41
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecdsa_verify.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_ASYM_ECC
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "cc_common.h"
+#include "cc_rsa_types.h"
+#include "cc_fips_defs.h"
+#include "ec_wrst.h"
+#ifdef USE_MBEDTLS_CRYPTOCELL
+#include "cc_general_defs.h"
+#include "md.h"
+#endif
+
+/************************ Defines *****************************************/
+#if ( CC_HASH_USER_CTX_SIZE_IN_WORDS > CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS )
+        #error CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS or CC_HASH_USER_CTX_SIZE_IN_WORDS  defined not correctly.
+#endif
+
+/************************ Enums *******************************************/
+/************************ Typedefs ****************************************/
+/************************ Global Data *************************************/
+extern const CCEcpkiHash_t ecpki_hash_info[CC_ECPKI_HASH_NumOfModes];
+extern const uint8_t ecpki_supported_hash_modes[CC_ECPKI_HASH_NumOfModes];
+/************* Private function prototype *********************************/
+
+/************************ Public Functions ********************************/
+
+/**************************************************************************
+ *                EcdsaVerifyInit  function
+ **************************************************************************/
+/**
+   @brief  Prepares a context that is used by the Update and Finish functions
+           but does not perform elliptic curve cryptographic processing
+
+                    The function:
+                        - Receives and decrypts user data (working context).
+                        - Checks input parameters of  ECDSA Vrifying primitive.
+                        - Calls hash init function.
+                        - Initializes variables and structures for calling next functions.
+                        - Encrypts and releases working context.
+
+                        NOTE: Using of HASH functions with HASH size great, than EC modulus size,
+                        is not recommended!
+
+   @param[in,out] pVerifyUserContext - A pointer to the user buffer for verifying database.
+   @param[in] pSignerPublKey - A pointer to a Signer public key structure.
+   @param[in] hashMode - The enumerator variable defines the hash function to be used.
+
+   @return <b>CCError_t</b>: <br>
+                         CC_OK<br>
+                         CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
+                         CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR <br>
+                         CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR <br>
+                         CC_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR <br>
+                         CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
+**/
+CEXPORT_C CCError_t EcdsaVerifyInit(
+                                           CCEcdsaVerifyUserContext_t  *pVerifyUserContext, /*in/out*/
+                                           CCEcpkiUserPublKey_t        *pSignerPublKey,     /*in*/
+                                           CCEcpkiHashOpMode_t         hashMode               /*in*/ )
+{
+        /* FUNCTION DECLERATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+        /* defining a pointer to the active context allcated by the CCM */
+        EcdsaVerifyContext_t *pWorkingContext;
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        const mbedtls_md_info_t *md_info=NULL;
+#endif
+
+        /* FUNCTION LOGIC */
+
+        pWorkingContext = (EcdsaVerifyContext_t*)&pVerifyUserContext->context_buff;
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* if the users context ID pointer is NULL return an error */
+        if (pVerifyUserContext == NULL){
+                return CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR;
+        }
+
+        /*if the private key object is NULL return an error*/
+        if (pSignerPublKey == NULL){
+                err = CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR;
+                goto End;
+        }
+
+        /* check if the hash operation mode is legal */
+        if (hashMode >= CC_ECPKI_HASH_NumOfModes){
+                err = CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR;
+                goto End;
+        }
+
+        if (pSignerPublKey->valid_tag != CC_ECPKI_PUBL_KEY_VALIDATION_TAG){
+                err = CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR;
+                goto End;
+        }
+
+        /* reset the Context handler for improper previous values initialized */
+        CC_PalMemSet(pWorkingContext, 0, sizeof(EcdsaVerifyContext_t));
+
+        /* ................. loading the context .................................. */
+        /* ------------------------------------------------------------------------ */
+
+        /*Initializing the Hash operation mode in the ECDSA Context */
+
+
+        if (ecpki_supported_hash_modes[hashMode] == CC_FALSE) {
+                err = CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR;
+                goto End;
+        }
+
+        pWorkingContext->hashMode = hashMode;
+        pWorkingContext->hashResultSizeWords = ecpki_hash_info[pWorkingContext->hashMode].hashResultSize;
+
+        if (ecpki_hash_info[pWorkingContext->hashMode].hashMode < CC_HASH_NumOfModes) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[ecpki_hash_info[pWorkingContext->hashMode].hashMode] );
+                if (NULL == md_info) {
+                        err = CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR;
+                        goto End;
+                }
+                mbedtls_md_init(&(pWorkingContext->hash_ctx));
+                err = mbedtls_md_setup(&(pWorkingContext->hash_ctx), md_info, 0); // 0 = HASH, not HMAC
+                if (err != 0) {
+                        goto End;
+                }
+                err = mbedtls_md_starts(&(pWorkingContext->hash_ctx));
+#else
+                err = CC_HashInit(&(pWorkingContext->hashUserCtxBuff), ecpki_hash_info[pWorkingContext->hashMode].hashMode);
+#endif
+                if (err != CC_OK)
+                        goto End;
+        }
+
+        /* copy the ECPKI Public key to the context*/
+        CC_PalMemCopy(&pWorkingContext->ECDSA_SignerPublKey, pSignerPublKey, sizeof(CCEcpkiUserPublKey_t));
+
+        /* set the ECDSA validation tag */
+        pVerifyUserContext->valid_tag = CC_ECDSA_VERIFY_CONTEXT_VALIDATION_TAG;
+
+        End:
+        /*  clear the users context in case of error */
+        if (err != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                if(md_info!=NULL){
+                        mbedtls_md_free(&(pWorkingContext->hash_ctx));
+                }
+#endif
+                CC_PalMemSetZero(pVerifyUserContext, sizeof(CCEcdsaVerifyUserContext_t));
+        }
+
+        return err;
+
+}/* EcdsaVerifyInit */
+
+
+/**************************************************************************
+ *                EcdsaVerifyUpdate function
+ **************************************************************************/
+/**
+   @brief  Performs a hash  operation on data allocated by the user
+           before finally verifying its signature.
+
+           In case user divides signing data by block, he must call the Update function
+           continuously a number of times until processing of the entire data block is complete.
+
+       NOTE: Using of HASH functions with HASH size greater, than EC modulus size,
+             is not recommended.
+
+   @param [in,out] pVerifyUserContext - The pointer to the user buffer for verifying database.
+   @param [in] pMessageDataIn - The message data for calculating Hash.
+   @param [in]dataInSize - The size of the message data block, in bytes. The data size,
+                   passed on each call of the function, besides the last call, must be
+                   a multiple of the HASH block size according to used HASH mode.
+
+   @return <b>CCError_t</b>: <br>
+                         CC_OK<br>
+                         CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
+                         CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR <br>
+                         CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR <br>
+                         CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR <br>
+                         CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
+ **/
+CEXPORT_C CCError_t EcdsaVerifyUpdate(
+                                             CCEcdsaVerifyUserContext_t *pVerifyUserContext, /*in/out*/
+                                             uint8_t                        *pMessageDataIn,     /* in */
+                                             size_t                         dataInSize          /* in */ )
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+        /* defining a pointer to the active context allcated by the CCM */
+        EcdsaVerifyContext_t *pWorkingContext;
+
+        /* FUNCTION LOGIC */
+
+        /* sign working context */
+        pWorkingContext = (EcdsaVerifyContext_t*)&pVerifyUserContext->context_buff;
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* if the users context pointer is NULL return an error */
+        if (pVerifyUserContext == NULL){
+                return CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR;
+        }
+
+        /* if the users context TAG is illegal return an error - the context is invalid */
+        if (pVerifyUserContext->valid_tag != CC_ECDSA_VERIFY_CONTEXT_VALIDATION_TAG){
+                err = CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR;
+                goto End;
+        }
+
+        /* if the users MessageDataIn pointer is illegal return an error */
+        if (pMessageDataIn == NULL && dataInSize){
+                err = CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR;
+                goto End;
+        }
+
+        /* check that the data size < 2^29 (to prevent an overflow on the
+           transition to bits ) */
+        if (dataInSize >= (1UL << 29)){
+                err = CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR;
+                goto End;
+        }
+
+
+        /* HASH update operations */
+        if (ecpki_hash_info[pWorkingContext->hashMode].hashMode < CC_HASH_NumOfModes) {
+                /*Operate the Hash update function for relevant version */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                err = mbedtls_md_update(&(pWorkingContext->hash_ctx), pMessageDataIn, dataInSize);
+#else
+                err = CC_HashUpdate( &(pWorkingContext->hashUserCtxBuff), pMessageDataIn, dataInSize );
+#endif
+                if (err != CC_OK) {
+                        goto End;
+                }
+        } else {
+                if (dataInSize != ecpki_hash_info[pWorkingContext->hashMode].hashResultSize*CC_32BIT_WORD_SIZE) {
+                        /* DataInSize must fit exactly to the size of Hash output that we support */
+                        err = CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR;
+                        goto End;
+                }
+                /* Copy the DataIn_ptr to the HASH_Result */
+                CC_PalMemCopy((uint8_t *)pWorkingContext->hashResult,pMessageDataIn,dataInSize);
+        }
+
+        End:
+        /*  clear the users context in case of error */
+        if (err != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                mbedtls_md_free(&(pWorkingContext->hash_ctx));
+#endif
+                CC_PalMemSetZero(pVerifyUserContext, sizeof(CCEcdsaVerifyUserContext_t));
+        }
+
+        return err;
+
+}/* EcdsaVerifyUpdate */
+
+
+
+/**************************************************************************
+ *                EcdsaVerifyFinish function
+ **************************************************************************/
+/**
+   @brief  Performs initialization of variables and structures,
+           calls the hash function for the last block of data (if necessary),
+           than calls EcWrstDsaVerify function for verifying signature
+           according to EC DSA algorithm.
+
+       NOTE: Using of HASH functions with HASH size greater, than EC modulus size,
+             is not recommended!
+             Algorithm according ANS X9.62 standard
+
+   @param[in] pVerifyUserContext - A pointer to the user buffer for verifying the database.
+   @param[in] pSignatureIn       - A pointer to a buffer for the signature to be compared
+   @param[in] SignatureSizeBytes    - The size of a user passed signature (must be 2*orderSizeInBytes).
+
+   @return <b>CCError_t</b>: <br>
+              CC_OK <br>
+                          CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
+                          CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR <br>
+                          CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR <br>
+                          CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
+                          CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR <br>
+                          CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR <br>
+**/
+CEXPORT_C CCError_t EcdsaVerifyFinish(
+                                             CCEcdsaVerifyUserContext_t *pVerifyUserContext,  /*in*/
+                                             uint8_t                        *pSignatureIn,        /*in*/
+                                             size_t                         SignatureSizeBytes  /*in*/)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+        /* pointer to the active context  */
+        EcdsaVerifyContext_t *pWorkingContext;
+        /* pointer to public key structure in ccmWorkingContext  */
+        CCEcpkiPublKey_t  *PublKey_ptr;
+        /*  EC domain ID and pointer to the current domain */
+        /*  pointer to the current domain */
+        CCEcpkiDomain_t   *pDomain;
+
+        uint32_t  *pMessRepres, *pSignatureC, *pSignatureD;
+        uint32_t   hashSizeWords;
+        uint32_t   orderSizeInBytes, orderSizeInWords;
+
+        /* FUNCTION LOGIC */
+
+        /* the pointer to the internal Verify context */
+        pWorkingContext = (EcdsaVerifyContext_t*)&pVerifyUserContext->context_buff;
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* if the users context pointer is NULL return an error */
+        if (pVerifyUserContext == NULL){
+                return CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR;
+        }
+
+        /* if the users context TAG is illegal return an error - the context is invalid */
+        if (pVerifyUserContext->valid_tag != CC_ECDSA_VERIFY_CONTEXT_VALIDATION_TAG){
+                err = CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR;
+                goto End;
+        }
+
+        /* if the users Signature pointer is illegal then return an error */
+        if (pSignatureIn == NULL){
+                err = CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR;
+                goto End;
+        }
+
+
+        /* ............. checking the validity of context ........ */
+        /* ------------------------------------------------------- */
+
+        /* check Hash mode */
+        if (pWorkingContext->hashMode >= CC_ECPKI_HASH_NumOfModes){
+                err = CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR;
+                goto End;
+        }
+
+        PublKey_ptr = (CCEcpkiPublKey_t *)&pWorkingContext->ECDSA_SignerPublKey.PublKeyDbBuff;
+
+        /* Initializing domain parameters */
+        pDomain = &PublKey_ptr->domain;
+        orderSizeInBytes  =  CALC_FULL_BYTES(pDomain->ordSizeInBits);
+        orderSizeInWords  =  CALC_FULL_32BIT_WORDS(pDomain->ordSizeInBits);
+
+        /* if the user signature size is not equal to 2*ModSizeInBytes, then return an error */
+        if (SignatureSizeBytes != 2*orderSizeInBytes){
+                err = CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR;
+                goto End;
+        }
+
+        /*Operating the HASH Finish function only in case that Hash operation is needed*/
+        if (pWorkingContext->hashMode <= CC_ECPKI_HASH_SHA512_mode) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                err = mbedtls_md_finish(&(pWorkingContext->hash_ctx), (unsigned char *)pWorkingContext->hashResult);
+#else
+                err = CC_HashFinish(&(pWorkingContext->hashUserCtxBuff), pWorkingContext->hashResult);
+#endif
+                if (err != CC_OK)
+                        goto End;
+        }
+
+        /*  Initialization of  EcWrstDsaVerify arguments */
+        hashSizeWords        = pWorkingContext->hashResultSizeWords;
+        /* Temp buffers */
+        pSignatureC       = ((EcWrstDsaVerifyDb_t*)(pWorkingContext->ccEcdsaVerIntBuff))->tempBuff;
+        pSignatureD       = pSignatureC + orderSizeInWords; /* Max lengths of C in whole words */
+        pMessRepres = pSignatureD + orderSizeInWords;
+
+        // Check shortened cleaning
+        /* Clean memory  */
+        CC_PalMemSetZero(pSignatureC, 2*4*orderSizeInWords); //-> pSignatureC[orderSizeInWords-1] = 0;
+        //-> pSignatureD[orderSizeInWords-1] = 0;
+        CC_PalMemSetZero(pMessRepres, 4*orderSizeInWords);   //-> pMessRepres[orderSizeInWords-1] = 0;
+
+        /* Derive message representative = leftmost OrderSizeInBits bits of HASH_Result */
+        if (pDomain->ordSizeInBits >= 32*hashSizeWords) {
+                CC_CommonReverseMemcpy((uint8_t*)pMessRepres,
+                                          (uint8_t*)(pWorkingContext->hashResult), 4*hashSizeWords);
+        } else {
+                EcWrstDsaTruncateMsg(pMessRepres,
+                                      (uint8_t*)(pWorkingContext->hashResult), pDomain->ordSizeInBits);
+
+        }
+
+        /* Convert signature data to words array with little entian order of  *
+        *  words                                  */
+        pSignatureC[orderSizeInWords-1] = 0;
+        CC_CommonReverseMemcpy((uint8_t*)pSignatureC, pSignatureIn, orderSizeInBytes);
+        pSignatureD[orderSizeInWords-1] = 0;
+        CC_CommonReverseMemcpy((uint8_t*)pSignatureD, pSignatureIn + orderSizeInBytes, orderSizeInBytes);
+
+        /*------------------------------*/
+        /* Verifying operation      */
+        /*------------------------------*/
+        err =  EcWrstDsaVerify(PublKey_ptr, pMessRepres, orderSizeInWords, pSignatureC, pSignatureD);
+        if (err != CC_OK) {
+                err = CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR;
+        }
+
+        End:
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        mbedtls_md_free(&(pWorkingContext->hash_ctx));
+#endif
+
+        /* clear the users context  */
+        CC_PalMemSetZero(pVerifyUserContext, sizeof(CCEcdsaVerifyUserContext_t));
+
+        return err;
+
+
+}/* End EcdsaVerifyFinish */
+
+
+/**************************************************************************
+ *                CC_EcdsaVerify integrated function
+ **************************************************************************/
+/**
+   @brief  Performs all ECDSA verifying operations simultaneously.
+
+           This function simply calls the Init, Update and Finish functions continuously.
+
+       NOTE: Using of HASH functions with HASH size great, than EC modulus size,
+             is not recommended!
+             Algorithm according ANS X9.62 standard
+
+
+   @param[in]  pVerifyUserContext - A pointer to the user buffer for verifying database.
+   @param[in]  pUserPublKey       - A pointer to a user public key structure.
+   @param[in]  hashMode              - The enumerator variable defines the hash function to be used.
+   @param[in]  pMessageDataIn     - Message data for calculating hash.
+   @param[in]  messageSizeInBytes    - Size of block of message data in bytes.
+   @param[in]  pSignatureIn       - A pointer to a buffer for output of signature.
+   @param[in]  SignatureSizeBytes    - Size of signature, in bytes (must be 2*orderSizeInBytes).
+
+   @return <b>CCError_t</b>: <br>
+                        CC_OK <br>
+                        CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR <br>
+                        CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR <br>
+                        CC_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR <br>
+                        CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR <br>
+                        CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR <br>
+                        CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR <br>
+                        CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR <br>
+                        CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR <br>
+                        CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR <br>
+                        CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR <br>
+                        CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR <br>
+**/
+CEXPORT_C CCError_t CC_EcdsaVerify (
+                                        CCEcdsaVerifyUserContext_t *pVerifyUserContext,  /*in/out*/
+                                        CCEcpkiUserPublKey_t       *pUserPublKey,        /*in*/
+                                        CCEcpkiHashOpMode_t        hashMode,            /*in*/
+                                        uint8_t                        *pSignatureIn,        /*in*/
+                                        size_t                         SignatureSizeBytes,  /*in*/
+                                        uint8_t                        *pMessageDataIn,      /*in*/
+                                        size_t                         messageSizeInBytes  /*in*/)
+{
+        /* FUNCTION DECLERATIONS */
+
+        CCError_t err = CC_OK;
+
+        /* FUNCTION LOGIC */
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+
+        err = EcdsaVerifyInit(pVerifyUserContext, pUserPublKey, hashMode);
+
+        if (err!=CC_OK)
+                return err;
+
+        err = EcdsaVerifyUpdate(pVerifyUserContext, pMessageDataIn, messageSizeInBytes);
+        if (err!=CC_OK)
+                return err;
+
+        err = EcdsaVerifyFinish(pVerifyUserContext, pSignatureIn,
+                                      SignatureSizeBytes);
+        return err;
+
+}/* END OF CC_EcdsaVerify */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecies.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecies.c
new file mode 100644
index 0000000..ef55d10
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecies.c
@@ -0,0 +1,494 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "cc_ecpki_build.h"
+#include "cc_ecpki_kg.h"
+#include "cc_fips_defs.h"
+#include "cc_kdf.h"
+#include "cc_rnd_common.h"
+#include "ec_wrst.h"
+#include "cc_kdf.h"
+
+/************************ Defines *************************************/
+
+/************************ Enums ***************************************/
+
+/************************ Typedefs ************************************/
+
+/************************ Global Data *********************************/
+
+/************* Private function prototype *****************************/
+
+/************************ Public Functions ****************************/
+
+
+/***********************************************************************
+ *                        EciesKemEncrypt                     *
+ ***********************************************************************/
+/**
+ @brief: The function creates and encrypts (encapsulate) the Secret Key of
+     required size according to the ISO/IEC 18033-2 standard [1],
+     sec. 10.2.3 - ECIES-KEM Encryption.
+
+   For calling this function in applications must be used the macro
+   definition CC_EciesKemEncrypt(). The function itself has additional input
+   of external ephemeral key pair, used only for testing goals.
+
+   The system parameters of the function, named in the standard [1] - sec. 10.2.1,
+   are set as follows:
+     - CofactorMode = 0, because all elliptic curves, used in CC, have cofactor = 1;
+     - OldCofactorMode = 0 (according to previous);
+     - CheckMode = 1 - means that checking of the recipient's public key should
+       be performed;
+     - SingleHashMode = 1 - for compliance with ANSI X9.63-2001;
+     - Avaliable KDF functions are KDF1 or KDF2 ([1] - sec. 5.6.3).
+       For compliance with ANSI X9.63-2001 must be used KDF2 function.
+
+   The function performs the following:
+     - Checks input parameters: pointers, buffers sizes etc.
+     - Generates random ephemeral EC key pair by calling the CC_EcpkiGenKeyPairCall
+       function.
+     - Converts the ephemeral public key to ciphertext by calling of the
+       CC_EcpkiPubKeyExport function.
+     - Calls the EcWrstDhDeriveSharedSecret function to calculate the shared secret value SV.
+     - Calls the CC_KdfKeyDerivFunc function to calculate the Secret Keying
+       data using the secret value SV.
+     - Exits.
+
+   NOTE:
+        1. The term "sender" indicates an entity, who creates and performs
+       encapsulation of the Secret Key using this function. The term
+       "recipient" indicates an other entity which receives and decrypts
+       the Secret Key.
+    2. All used public and private keys must relate to the same EC Domain.
+    3. The recipient's public key, before using in this function, must be
+       checked that it is on elliptic curve. For this goal the user may
+       build the key structure using CC_EcpkiPubKeyBuildAndPartlyCheck
+       function.
+    4. The function may be used also in Key Transport Schemes, in partial,
+       in Integrated Encryption Scheme (ANSI X9.63-2001 5.8 - ECIES without
+       optional SharedData).
+
+ PARAMETERS:
+
+ @param[in]  pRecipUzPublKey -  A pointer to the recipient's public key.
+ @param[in]  kdfHashfMode -   An enumerator variable, defining the used HASH
+                  function.
+ @param[in]  kdfDerivMode -   An enumerator variable, defining which KDF function mode
+                  is used KDF1 or KDF2 (see enumerator definition in cc_kdf.h).
+ @param[in]  isSingleHashMode - Specific ECIES mode definition 0,1 according to [1] - sec.10.2.
+ @param[in]  pEphUzPrivKey -    The pointer to the external ephemeral private key. This key is used
+                  only for testing the function. In regular using the pointer should be
+                  set to NULL and then the random key pair should be generated internally.
+ @param[in]  pEphUzPublKey    - A pointer to the ephemeral public key related to the private key (must
+                  be set to NULL if pEphUzPrivKey = NULL).
+ @param[out] pSecrKey -       A pointer to the buffer for the Secret Key data to be generated.
+ @param[in]  secrKeySize -    A size of the Secret Key data in bytes.
+ @param[OUT] pCipherData -    A pointer to the encrypted cipher text.
+ @param[in/OUT]  pCipherDataSize - A pointer to the size of the buffer for output of the CipherData (in)
+                  and its actual size in bytes (out).
+ @param[in]  pTempBuff -      A pointer to the temporary buffer of size
+                  specified by the CCEciesTempData_t
+                  structure.
+ @param [in] pFipsCtx -     Pointer to temporary buffer used in case FIPS certification if required
+ @return  CCError_t:
+        CC_OK
+        CC_ECIES_INVALID_PUBL_KEY_PTR_ERROR
+        CC_ECIES_INVALID_PUBL_KEY_TAG_ERROR
+        CC_ECIES_INVALID_PUBL_KEY_VALUE_ERROR
+        CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR
+        CC_ECIES_INVALID_KDF_HASH_MODE_ERROR
+        CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR
+        CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR
+        CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR
+        CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR
+        CC_ECIES_INVALID_CIPHER_DATA_SIZE_ERROR
+        CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR
+*/
+CEXPORT_C CCError_t EciesKemEncrypt(
+                      CCEcpkiUserPublKey_t      *pRecipUzPublKey,   /*in*/
+                      CCKdfDerivFuncMode_t       kdfDerivMode,          /*in*/
+                      CCKdfHashOpMode_t          kdfHashMode,           /*in*/
+                      uint32_t                       isSingleHashMode,      /*in*/
+                      CCEcpkiUserPrivKey_t      *pExtEphUzPrivKey,      /*in*/
+                      CCEcpkiUserPublKey_t      *pExtEphUzPublKey,      /*in*/
+                      uint8_t                   *pSecrKey,      /*out*/
+                      size_t                     secrKeySize,           /*in*/
+                      uint8_t                       *pCipherData,           /*out*/
+                      size_t                    *pCipherDataSize,   /*in/out*/
+                      CCEciesTempData_t         *pTempBuff,         /*in*/
+                      CCRndContext_t            *pRndContext,       /*in*/
+                      CCEcpkiKgFipsContext_t   *pFipsCtx)       /*in*/
+{
+
+    /* LOCAL DECLARATIONS */
+
+    CCError_t error;
+
+    /*  pointer to EC domain  */
+    const CCEcpkiDomain_t    *pDomain;
+    uint32_t   modSizeInBytes, kdfDataSize;
+    uint8_t   *pKdfData;
+    /* pointers to ephemeral key pair, which should be used */
+    CCEcpkiUserPrivKey_t    *pEphUzPrivKey;
+    CCEcpkiUserPublKey_t    *pEphUzPublKey;
+    CCEcpkiPublKey_t        *pRecipPublKey;
+    CCEcpkiPrivKey_t        *pEphPrivKey;
+
+
+    /* FUNCTION LOGIC */
+
+    /* Initialize Error */
+    error = CC_OK;
+
+        /* .........    checking the validity of input parameters  .......... */
+        /* Note: pRndContext and pFipsCtx will be checked in called functions */
+    /* ------------------------------------------------------------------- */
+
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* check the validity of the user static private key */
+    if (pRecipUzPublKey == NULL)
+        return CC_ECIES_INVALID_PUBL_KEY_PTR_ERROR;
+
+    if (pRecipUzPublKey->valid_tag != CC_ECPKI_PUBL_KEY_VALIDATION_TAG)
+        return CC_ECIES_INVALID_PUBL_KEY_TAG_ERROR;
+
+    /* check KDF and HASH modes */
+    if (kdfDerivMode != CC_KDF_ISO18033_KDF1_DerivMode &&
+        kdfDerivMode != CC_KDF_ISO18033_KDF2_DerivMode)
+        return CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR;
+
+    /* check HASH mode */
+    if (kdfHashMode > CC_KDF_HASH_NumOfModes)
+        return CC_ECIES_INVALID_KDF_HASH_MODE_ERROR;
+
+    /* check the Ephemeral key pair: must be both Null or both actual */
+    if ((pExtEphUzPrivKey == NULL) ^ (pExtEphUzPublKey == NULL))
+        return CC_ECIES_INVALID_EPHEM_KEY_PAIR_PTR_ERROR;
+
+    if (pExtEphUzPrivKey != NULL &&
+        pExtEphUzPrivKey->valid_tag != CC_ECPKI_PRIV_KEY_VALIDATION_TAG)
+        return CC_ECIES_INVALID_PRIV_KEY_TAG_ERROR;
+
+    if (pExtEphUzPublKey != NULL &&
+        pExtEphUzPublKey->valid_tag != CC_ECPKI_PUBL_KEY_VALIDATION_TAG)
+        return CC_ECIES_INVALID_PUBL_KEY_TAG_ERROR;
+
+    /* check the pointer to the buffer for secret key output */
+    if (pSecrKey == NULL)
+        return CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR;
+
+    /* check the size of secret key to be generated */
+    if (secrKeySize == 0)
+        return CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR;
+
+    /* checking the buffer for cipher text output */
+    if (pCipherData == NULL)
+        return CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR;
+
+    if (pCipherDataSize == NULL)
+        return CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR;
+
+    /* checking the temp buffer pointer  */
+    if (pTempBuff == NULL)
+        return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
+
+
+    /* ..  initializtions  and other checking   .... */
+    /* --------------------------------------------- */
+
+    /* derive and check domainID from recipient Public Key */
+    pRecipPublKey = (CCEcpkiPublKey_t*)&pRecipUzPublKey->PublKeyDbBuff;
+    pDomain = &pRecipPublKey->domain;
+
+    /* check EC Domain ID */
+    if (pDomain->DomainID >= CC_ECPKI_DomainID_OffMode)
+        return CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+
+    /* modulus size */
+    modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
+
+    /* check cipher output buffer size */
+    if (*pCipherDataSize < 2*modSizeInBytes + 1)
+        return  CC_ECIES_INVALID_CIPHER_DATA_SIZE_ERROR;
+
+    if (pExtEphUzPrivKey == NULL) {
+        /* use internal genrated ephemeral Key Pair */
+        error = CC_EcpkiKeyPairGenerate(pRndContext,  /*in/out*/
+                          (const CCEcpkiDomain_t *)pDomain,
+                          &pTempBuff->PrivKey,
+                          &pTempBuff->PublKey,
+                          &pTempBuff->tmp.KgTempBuff,
+                          pFipsCtx);
+
+
+        if (error != CC_OK)
+            goto End;
+
+        pEphUzPrivKey = &pTempBuff->PrivKey; // r
+        pEphUzPublKey = &pTempBuff->PublKey; // g~ = r*G
+    } else {
+        /* use external ephemeral Key Pair */
+        pEphUzPrivKey = pExtEphUzPrivKey;
+        pEphUzPublKey = pExtEphUzPublKey;
+    }
+
+    /* convert ephemeral public key to standard form */
+    error = CC_EcpkiPubKeyExport(
+                    pEphUzPublKey,          /*in*/
+                    CC_EC_PointUncompressed,    /*in*/
+                    (uint8_t*)&pTempBuff->zz, /*out*/
+                    pCipherDataSize);       /*in/out*/   /* Number of Bytes that were copied to zz*/
+    if (error != CC_OK)
+        goto End;
+
+
+    /* call  EcWrstDhDeriveSharedSecret function to calculate the Secret Value */
+    /* --------------------------------------------------------------- */        // h~ = r*h
+    pEphPrivKey = (CCEcpkiPrivKey_t*)&pEphUzPrivKey->PrivKeyDbBuff;
+    error = EcWrstDhDeriveSharedSecret(pRecipPublKey,   /*in*/
+                 (CCEcpkiPrivKey_t *)(pEphPrivKey->PrivKey), /*in*/
+                 &((uint8_t*)&pTempBuff->zz)[*pCipherDataSize], /*out*/ /* Next available space in zz where the (SV X coordinate of multiplication) will be stored*/
+                 &pTempBuff->tmp.DhTempBuff); /*in*/
+    if (error != CC_OK)
+        goto End;
+
+
+    /* derive the Keying Data from the Secret Value by calling the KDF function    */
+    /* --------------------------------------------------------------------------- */
+
+    /* set pointer  and size of input data for KDF function */
+    if (isSingleHashMode == CC_TRUE) { /* z = X */
+        pKdfData = &((uint8_t*)&pTempBuff->zz)[*pCipherDataSize];
+        kdfDataSize = modSizeInBytes;
+    } else { /*z = C0 || X*/
+        pKdfData = (uint8_t*)&pTempBuff->zz;
+        kdfDataSize = *pCipherDataSize + modSizeInBytes;
+    }
+
+    /*derive the Keying Data */
+    error = CC_KdfKeyDerivFunc(
+                     pKdfData/*ZZSecret*/,
+                     kdfDataSize/*ZZSecretSize*/,
+                     NULL/*&otherInfo*/,
+                     kdfHashMode,
+                     kdfDerivMode,
+                     pSecrKey,
+                     secrKeySize);
+    if (error != CC_OK)
+        goto End;
+
+    /* Output of the Cipher Data (C0) = Ephemeral Public Key */
+    CC_PalMemCopy(pCipherData, pTempBuff->zz, *pCipherDataSize);
+
+End:
+    if (error != CC_OK) {
+        *pCipherDataSize = 0;
+    }
+    /* clean temp buffers */
+    CC_PalMemSetZero(pTempBuff, sizeof(CCEciesTempData_t));
+
+    return error;
+
+}/* END OF CC_EciesKemEncrypt */
+
+
+/***********************************************************************
+ *                        CC_EciesKemDecrypt                       *
+ ***********************************************************************/
+/**
+ @brief: The function decrypts the encapsulated Secret Key passed by
+     sender according to the ISO/IEC 18033-2 standard [1],
+     sec. 10.2.4 - ECIES-KEM Decryption.
+
+   The system parameters of the function, named in [1], sec. 10.2.1,
+   are set as follows:
+     - CofactorMode = 0, because all elliptic curves, used in CC, have
+       cofactor = 1;
+     - OldCofactorMode = 0 (according to previous);
+     - CheckMode = 1 - means perform checking of ephemeral public key (mandatory
+       in this case);
+     - SingleHashMode = 1 - for compliance with ANSI X9.63-2001;
+     - Avaliable KDF functions are KDF1 or KDF2 ([1] - sec. 5.6.3).
+       For compliance with ANSI X9.63-2001 must be used KDF2 function.
+
+   The function performs the following:
+     - Checks input parameters: pointers, buffers sizes etc.
+     - Checks, that the sender's ephemeral public key relates to
+       used EC Domain and initializes the Key structure.
+     - Calls the EcWrstDhDeriveSharedSecret function to calculate the secret value SV.
+     - Calls the CC_KdfKeyDerivFunc function to calculate the Secret Keying
+       data using secret value SV.
+     - Exits.
+
+   NOTE:
+     1. The term "sender" indicates an entity, who creates and performs
+    Encapsulation of the Secret Key using this function. The term
+    "recipient" indicates an other entity which receives and decrypts
+    the Cipher data and derives the Shared Secret Key.
+     2. All used public and private keys must relate to the same EC Domain.
+     3. The function may be used also in Key Transport Schemes, in partial,
+    in Integrated Encryption Scheme (ANSI X9.63-2001 5.8 - ECIES without
+    optional SharedData).
+
+ PARAMETERS:
+
+ @param[in]  pRecipUzPrivKey -  A pointer to the recipient's private key.
+ @param[in]  kdfHashfMode -   An enumerator variable, defining used HASH function.
+ @param[in]  kdfDerivMode -   An enumerator variable, defining which KDF function mode
+                  is used KDF1 or KDF2 (see enumerator definition in cc_kdf.h).
+ @param[in]  isSingleHashMode - Specific ECIES mode definition: 0,1 according to [1] - sec.10.2.
+ @param[in]  pCipherData -    A pointer to the received encrypted cipher data.
+ @param[in]  cipherDataSize - A size of the cipher data in bytes.
+ @param[out] pSecrKey -       A pointer to the buffer for the Secret Key data to be generated.
+ @param[in]  secrKeySize -    A size of the Secret Key data in bytes.
+ @param[in]  pTempBuff -      A pointer to the temporary buffer of size
+                  specified by the CCEciesTempData_t
+                  structure.
+ @return  CCError_t:
+        CC_OK
+        CC_ECIES_INVALID_PRIV_KEY_PTR_ERROR
+        CC_ECIES_INVALID_PRIV_KEY_TAG_ERROR
+        CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR
+        CC_ECIES_INVALID_KDF_HASH_MODE_ERROR
+        CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR
+        CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR
+        CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR
+        CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR
+*/
+CEXPORT_C CCError_t CC_EciesKemDecrypt(
+                       CCEcpkiUserPrivKey_t *pRecipUzPrivKey,       /*in*/
+                       CCKdfDerivFuncMode_t     kdfDerivMode,           /*in*/
+                       CCKdfHashOpMode_t       kdfHashMode,         /*in*/
+                       uint32_t                     isSingleHashMode,       /*in*/
+                       uint8_t                      *pCipherData,           /*in*/
+                       size_t                    cipherDataSize,    /*in*/
+                       uint8_t                      *pSecrKey,      /*out*/
+                       size_t                    secrKeySize,           /*in*/
+                       CCEciesTempData_t        *pTempBuff )        /*in*/
+{
+
+    /* LOCAL DECLARATIONS */
+
+    CCError_t error = CC_OK;
+
+    /*  EC domain ID and info structure */
+    const CCEcpkiDomain_t    *pDomain;
+    uint32_t   modSizeInBytes, kdfDataSize;
+    uint8_t   *pKdfData;
+    CCEcpkiPrivKey_t  *pRecipPrivKey;
+
+
+    /* ................. checking the validity of input parameters  .......... */
+    /* ----------------------------------------------------------------------- */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* check the validity of the recipient's private key */
+    if (pRecipUzPrivKey == NULL)
+        return CC_ECIES_INVALID_PRIV_KEY_PTR_ERROR;
+
+    if (pRecipUzPrivKey->valid_tag != CC_ECPKI_PRIV_KEY_VALIDATION_TAG)
+        return CC_ECIES_INVALID_PRIV_KEY_TAG_ERROR;
+
+    /*check KDF and HASH modes */
+    if (kdfDerivMode != CC_KDF_ISO18033_KDF1_DerivMode &&
+        kdfDerivMode != CC_KDF_ISO18033_KDF2_DerivMode)
+        return CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR;
+
+    if (kdfHashMode > CC_KDF_HASH_NumOfModes)
+        return CC_ECIES_INVALID_KDF_HASH_MODE_ERROR;
+
+    /* check the pointer to the buffer for secret key output */
+    if (pSecrKey == NULL)
+        return CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR;
+
+    /* checking the size of secret key to be generated */
+    if (secrKeySize == 0)
+        return CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR;
+
+    /* check the buffer for cipher text output */
+    if (pCipherData == NULL)
+        return CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR;
+
+    /* checking the temp buffer pointer  */
+    if (pTempBuff == NULL)
+        return CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR;
+
+    /* ..  initializations  and other checking   .... */
+    /* ---------------------------------------------- */
+
+    /* derive domainID from recipient Private Key */
+    pRecipPrivKey = (CCEcpkiPrivKey_t*)&(pRecipUzPrivKey->PrivKeyDbBuff);
+    pDomain = &pRecipPrivKey->domain;
+
+    /* check EC Domain ID */
+    if (pDomain->DomainID >= CC_ECPKI_DomainID_OffMode)
+        return CC_ECPKI_INVALID_DOMAIN_ID_ERROR;
+
+    /* modulus size */
+    modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
+
+    /* partially check the cipher data C0 (ephemeral public key)
+       and initialize appropriate CC Key structure */
+    error = CC_EcpkiPublKeyBuildAndCheck(
+                      pDomain,           /*in*/
+                      pCipherData,       /*in - ephem. publ.key data*/
+                      cipherDataSize,        /*in*/
+                      ECpublKeyPartlyCheck,  /*in*/
+                      &pTempBuff->PublKey,   /*out*/
+                      &pTempBuff->tmp.buildTempbuff ); /*in*/
+    if (error != CC_OK)
+        goto End;
+
+    /* call  EcWrstDhDeriveSharedSecret function to calculate the Secret Value SV */
+    /* ----------------------------------------------------------------- */
+    error = EcWrstDhDeriveSharedSecret(
+                 (CCEcpkiPublKey_t*)&pTempBuff->PublKey.PublKeyDbBuff,  /*in*/
+                 (CCEcpkiPrivKey_t *)pRecipPrivKey->PrivKey, /*in*/
+                 &((uint8_t*)&pTempBuff->zz)[cipherDataSize],          /*out*/
+                 &pTempBuff->tmp.DhTempBuff);    /*in*/
+
+    if (error != CC_OK)
+        goto End;
+
+    /* set pointer  and size of input data for KDF function */
+    if (isSingleHashMode == CC_TRUE) { /* zz = SV */
+        pKdfData = &((uint8_t*)&pTempBuff->zz)[cipherDataSize];
+        kdfDataSize = modSizeInBytes;
+    } else { /* zz = C0 || SV */
+        pKdfData = (uint8_t*)&pTempBuff->zz;
+        kdfDataSize = cipherDataSize + modSizeInBytes;
+        /* set cipherData  C0 in the temp buffer zz */
+        CC_PalMemCopy((uint8_t*)&pTempBuff->zz, pCipherData,
+                cipherDataSize);
+    }
+
+    /* derive the Keying Data from the ZZ Value by calling the KDF function */
+    /* -----------------------------------------------------------------  - */
+    error = CC_KdfKeyDerivFunc(
+                     pKdfData/*ZZSecret*/,
+                     kdfDataSize/*ZZSecretSize*/,
+                     NULL/*&otherInfo*/,
+                     kdfHashMode,
+                     kdfDerivMode,
+                     pSecrKey,
+                     secrKeySize);
+End:
+    /* clean temp buffers */
+    CC_PalMemSetZero(pTempBuff, sizeof(CCEciesTempData_t));
+
+    return error;
+
+}/* END OF CC_EciesKemDecrypt */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_build_priv.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_build_priv.c
new file mode 100644
index 0000000..31166a9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_build_priv.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "cc_fips_defs.h"
+#include "ec_wrst.h"
+
+/************************ Defines ***************************************/
+
+/************************ Enums *****************************************/
+
+/************************ Typedefs **************************************/
+
+/************************ Global Data ***********************************/
+
+/************* Private function prototype *******************************/
+
+/************************ Public Functions ******************************/
+
+/**********************************************************************************
+ *                    CC_EcpkiPrivKeyBuild function                            *
+ **********************************************************************************/
+/**
+ * The function checks and imports (builds) private key and EC domain into
+ * structure of defined type.
+ *
+ *  This function should be called before using of the private key. Input
+ *  domain structure must be initialized by EC parameters and auxiliary
+ *  values, using CC_EcpkiGetDomain or CC_EcpkiSetDomain functions.
+ *
+ *  The function does the following:
+ *      - Checks validity of incoming variables and pointers;
+ *      - Converts private key to words arrays with little endian order
+ *        of the words and copies it in the UserPrivKey buffer.
+ *      - Copies EC domain into UserPrivKey  buffer.
+ *
+ * @author reuvenl (8/11/2014)
+ * @param pDomain - The pointer to EC domain structure.
+ * @param pPrivKeyIn - The pointer to private key data.
+ * @param PrivKeySizeInBytes - The size of private key data in bytes.
+ * @param pUserPrivKey - The pointer to private key structure.
+ *
+ * @return CEXPORT_C CCError_t
+ */
+CEXPORT_C CCError_t CC_EcpkiPrivKeyBuild(
+                                             const CCEcpkiDomain_t *pDomain,        /*in */
+                                             const uint8_t             *pPrivKeyIn,     /*in*/
+                                             size_t                    privKeySizeInBytes,/*in*/
+                                             CCEcpkiUserPrivKey_t  *pUserPrivKey    /*out*/)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* the private key structure pointer */
+        CCEcpkiPrivKey_t *pPrivKey;
+        /*  EC domain info structure and parameters */
+        uint32_t  orderSizeInBytes;
+        /* the err return code identifier */
+        CCError_t err = CC_OK;
+
+        /* FUNCTION LOGIC */
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* checking the validity of arguments */
+        if (pPrivKeyIn == NULL)
+                return  CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR;
+        if (pUserPrivKey == NULL)
+                return  CC_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR;
+        if (pDomain == NULL)
+                return  CC_ECPKI_DOMAIN_PTR_ERROR;
+
+        /* check EC domain parameters sizes */
+        if ((pDomain->modSizeInBits > (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS * 32)) ||
+            (pDomain->ordSizeInBits > (pDomain->modSizeInBits + 1))) {
+                return CC_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR;
+        }
+
+
+        /****************  FUNCTION LOGIC  **************************************/
+
+        /* the pointer to the key database */
+        pPrivKey = (CCEcpkiPrivKey_t *)((void*)pUserPrivKey->PrivKeyDbBuff);
+
+        /* check key size */
+        orderSizeInBytes = CALC_FULL_BYTES(pDomain->ordSizeInBits);
+        if (privKeySizeInBytes == 0 || privKeySizeInBytes > orderSizeInBytes)
+                return  CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR;
+
+        /* loading the private key (little endian)*/
+        err = CC_CommonConvertMsbLsbBytesToLswMswWords(
+                                                         pPrivKey->PrivKey, sizeof(pPrivKey->PrivKey),
+                                                         pPrivKeyIn, privKeySizeInBytes);
+        if (err != CC_OK) {
+                err = CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR;
+                goto End;
+        }
+
+        /* check the value of the private key */
+        if (privKeySizeInBytes == orderSizeInBytes) {
+                if (CC_CommonCmpLsWordsUnsignedCounters(
+                                                          pPrivKey->PrivKey, (uint16_t)(privKeySizeInBytes+3)/sizeof(uint32_t),
+                                                          pDomain->ecR, (uint16_t)(privKeySizeInBytes+3)/sizeof(uint32_t)) !=
+                    CC_COMMON_CmpCounter2GreaterThenCounter1) {
+                        err = CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR;
+                        goto End;
+                }
+        }
+
+        /* compare to 0 */
+        if (CC_CommonGetWordsCounterEffectiveSizeInBits(pPrivKey->PrivKey,
+                                                           (privKeySizeInBytes+3)/sizeof(uint32_t)) == 0) {
+                err = CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR;
+                goto End;
+        }
+
+
+        /* copy EC domain */
+        CC_PalMemCopy(&pPrivKey->domain, pDomain, sizeof(CCEcpkiDomain_t));
+
+        /* ................ set the private key validation tag ................... */
+        pUserPrivKey->valid_tag = CC_ECPKI_PRIV_KEY_VALIDATION_TAG;
+
+        End:
+        /* if the created structure is not valid - clear it */
+        if (err != CC_OK) {
+                CC_PalMemSetZero(pUserPrivKey, sizeof(CCEcpkiUserPrivKey_t));
+        }
+
+        return err;
+
+} /* End of CC_EcpkiPrivKeyBuild() */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_build_publ.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_build_publ.c
new file mode 100644
index 0000000..105411d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_build_publ.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_ecpki_types.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "cc_fips_defs.h"
+#include "ec_wrst.h"
+
+/************************ Defines ***************************************/
+
+
+/************************ Enums *****************************************/
+
+/************************ Typedefs **************************************/
+
+/************************ Global Data ***********************************/
+
+/************* Private function prototype *******************************/
+
+/************************ Public Functions ******************************/
+
+CEXPORT_C CCError_t CC_EcpkiPublKeyBuildAndCheck(
+                                            const CCEcpkiDomain_t   *pDomain,           /*in*/
+                                            uint8_t                     *pPubKeyIn,         /*in*/
+                                            size_t                      publKeySizeInBytes, /*in*/
+                                            ECPublKeyCheckMode_t        checkMode,          /*in*/
+                                            CCEcpkiUserPublKey_t    *pUserPublKey,       /*out*/
+                                            CCEcpkiBuildTempData_t *tempBuff           /*in*/)
+
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* the private key structure pointer */
+        CCEcpkiPublKey_t *pPublKey;
+        /* EC modulus size in bytes*/
+        uint32_t  modSizeInBytes, modSizeInWords;
+        /* Point control pc pc and pc1 = pc&6*/
+        uint32_t  pc, pc1;
+        /* the err return code identifier */
+        CCError_t err = CC_OK;
+        CCCommonCmpCounter_t cmp;
+
+        /* FUNCTION LOGIC */
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* ...... checking the validity of the User given pointers ......... */
+        if (pUserPublKey == NULL)
+                return  CC_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR;
+        if (pPubKeyIn == NULL)
+                return  CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR;
+        if (pDomain == NULL)
+                return  CC_ECPKI_DOMAIN_PTR_ERROR;
+        /* check input values */
+        if (checkMode >= PublKeyChecingOffMode)
+                return  CC_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR;
+        if ((checkMode != CheckPointersAndSizesOnly) && (tempBuff == NULL))
+                return  CC_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR;
+
+        /* check EC domain parameters sizes */
+        if ((pDomain->modSizeInBits > (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS * 32)) ||
+            (pDomain->ordSizeInBits > (pDomain->modSizeInBits + 1))) {
+                return CC_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR;
+        }
+
+
+        /* ...... Initializations  ............... */
+
+        pPublKey = (CCEcpkiPublKey_t*)((void*)pUserPublKey->PublKeyDbBuff);
+        modSizeInBytes = CALC_FULL_BYTES(pDomain->modSizeInBits);
+        modSizeInWords = CALC_32BIT_WORDS_FROM_BYTES(modSizeInBytes);
+
+        if(modSizeInWords>=CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS){ /*To remove static analyzer warning*/
+                return CC_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR;
+        }
+
+        /* point control */
+        pc = pPubKeyIn[0];
+        if (pc >= CC_EC_PointCompresOffMode || pc == CC_EC_PointContWrong)
+                return CC_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR;
+        pc1 = pc & 0x6; /*compression. mode*/
+
+        /* preliminary check key size */
+        if (pc1 == CC_EC_PointCompressed) {
+                if (publKeySizeInBytes != modSizeInBytes + 1)
+                        return  CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR;
+        } else {
+                if (publKeySizeInBytes != 2*modSizeInBytes + 1)
+                        return  CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR;
+        }
+
+        /* ...... copy the buffers to the key handle structure ................ */
+        /* -------------------------------------------------------------------- */
+
+        /* RL ? clear the public key db */
+        CC_PalMemSetZero((uint8_t*)pUserPublKey, sizeof(CCEcpkiUserPublKey_t));
+
+        /* copy public key Xin to X, Yin to Y */
+        err = CC_CommonConvertMsbLsbBytesToLswMswWords(pPublKey->x, sizeof(pPublKey->x),
+                                                       pPubKeyIn + 1, modSizeInBytes);
+        if (err != CC_OK) {
+                err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+                goto End;
+        }
+
+    /* check public key X value */
+    cmp = CC_CommonCmpLsWordsUnsignedCounters(pPublKey->x, modSizeInWords,
+                             pDomain->ecP, modSizeInWords);
+    if(cmp != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        return CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+    }
+
+        if (pc1 == CC_EC_PointUncompressed || pc1 == CC_EC_PointHybrid) {
+                /*  PC1 = 4 or PC1 = 6 */
+                err = CC_CommonConvertMsbLsbBytesToLswMswWords(
+                                                                 pPublKey->y, sizeof(pPublKey->y),
+                                                                 pPubKeyIn + 1 + modSizeInBytes, modSizeInBytes);
+                if (err != CC_OK) {
+                        err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+                        goto End;
+                }
+
+        /* check public key Y value */
+        cmp = CC_CommonCmpLsWordsUnsignedCounters(pPublKey->y, modSizeInWords,
+                              pDomain->ecP, modSizeInWords);
+        if(cmp != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+            return CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+        }
+
+        }
+
+        /* initialize LLF public key   */
+        /*-----------------------------*/
+        /* copy EC domain */
+        CC_PalMemCopy(&pPublKey->domain, pDomain, sizeof(CCEcpkiDomain_t));
+
+        /* Initialization, partly checking and uncompressing (if needed) of the public key */
+        err = EcWrstInitPubKey(pPublKey, pc);
+        if (err != CC_OK) {
+                err = CC_ECPKI_INTERNAL_ERROR;
+                goto End;
+        }
+
+
+        /*  additional (full) checking of public key  */
+        /*--------------------------------------------*/
+        if (checkMode == ECpublKeyFullCheck) {
+                err = EcWrstFullCheckPublKey(pPublKey, (uint32_t*)tempBuff);
+                if (err != CC_OK) {
+                        goto End;
+                }
+        }
+
+
+        /* ................ set the private key validation tag ................... */
+        pUserPublKey->valid_tag = CC_ECPKI_PUBL_KEY_VALIDATION_TAG;
+
+        End:
+        /* if the created structure is not valid - clear it */
+        if (err != CC_OK) {
+                CC_PalMemSetZero(pUserPublKey, sizeof(CCEcpkiUserPublKey_t));
+        }
+    if (tempBuff != NULL) {
+        CC_PalMemSetZero(tempBuff, sizeof(CCEcpkiBuildTempData_t));
+    }
+
+        return err;
+
+
+} /* End of CC_EcpkiPublKeyBuildAndCheck() */
+
+
+/***********************************************************************************
+ *                     CC_EcpkiPubKeyExport function                           *
+ ***********************************************************************************/
+/**
+  @brief The function converts an existed public key into the big endian and outputs it.
+
+                 The function performs the following steps:
+                 - checks input parameters,
+                 - Converts the X,Y coordinates of public key EC point to big endianness.
+                 - Sets the public key as follows:
+                          In case "Uncompressed" point:  PubKey = PC||X||Y, PC = 0x4 - single byte;
+                          In other cases returns an error.
+                 - Exits.
+
+                 NOTE: - At this stage supported only uncompressed point form,
+                       - Size of output X and Y coordinates is equal to ModSizeInBytes.
+
+  @param[in]  pUserPublKey -   A pointer to the public key structure initialized by CC.
+  @param[in]  compression  -   An enumerator parameter, defines point compression.
+  @param[out] pExportPublKey - A pointer to the buffer for export the public key bytes
+                       array in big endian order of bytes. Size of buffer must be
+                       not less than 2*ModSiseInBytes+1 bytes.
+  @param[in/out] pPublKeySizeBytes - A pointer to size of the user passed
+                       public key buffer (in) and the actual size of exported
+                       public key (out).
+
+  @return CCError_t - CC_OK,
+                        CC_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR
+                        CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR
+                        CC_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR
+                        CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR
+                        CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR
+                        CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR
+*/
+CEXPORT_C CCError_t CC_EcpkiPubKeyExport(
+                                              CCEcpkiUserPublKey_t      *pUserPublKey,       /*in*/
+                                              CCEcpkiPointCompression_t  compression,        /*in*/
+                                              uint8_t                       *pExportPublKey,     /*in*/
+                                              size_t                        *pPublKeySizeBytes   /*in/out*/)
+{
+        /*-------------------- FUNCTION DECLARATIONS ------------------------*/
+
+        /* the private key structure pointer */
+        CCEcpkiPublKey_t *publKey;
+
+        /* EC modulus size in words and in bytes*/
+        uint32_t   modSizeInBytes, modSizeInWords;
+        uint8_t    yBit;
+
+        /* the err return code identifier */
+        CCError_t err = CC_OK;
+
+        /*............. Checking input parameters   ..............................*/
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        if (pUserPublKey == NULL)
+                return  CC_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR;
+
+        if (pExportPublKey == NULL)
+                return  CC_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR;
+
+        if (pUserPublKey->valid_tag != CC_ECPKI_PUBL_KEY_VALIDATION_TAG)
+                return CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_VALIDATION_TAG_ERROR;
+
+        if (pPublKeySizeBytes == NULL)
+                return  CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR;
+
+        if (compression == CC_EC_PointContWrong || compression >= CC_EC_PointCompresOffMode)
+                return CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR;
+
+
+        /*   FUNCTION LOGIC  */
+
+        publKey = (CCEcpkiPublKey_t *)((void*)pUserPublKey->PublKeyDbBuff);
+
+        /* EC modulus size */
+        modSizeInBytes = CALC_FULL_BYTES(publKey->domain.modSizeInBits);
+        modSizeInWords = CALC_FULL_32BIT_WORDS(publKey->domain.modSizeInBits);
+
+        /* calc. MS Bit of Y */
+        yBit = (uint8_t)(publKey->y[0] & 1);
+
+        /* Convert public key to big endianness export form */
+        switch (compression) {
+        case CC_EC_PointCompressed:
+
+                if (*pPublKeySizeBytes < modSizeInBytes + 1)
+                        return  CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR;
+
+                /* point control byte */
+                pExportPublKey[0] = 0x02 | yBit;
+
+                err = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                                 pExportPublKey + 1, 4*modSizeInWords,
+                                                                 publKey->x, modSizeInBytes);
+                if (err != CC_OK) {
+                        err = CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+                        goto End;
+                }
+
+                *pPublKeySizeBytes = modSizeInBytes + 1;
+                break;
+
+        case CC_EC_PointUncompressed:
+        case CC_EC_PointHybrid:
+
+                if (*pPublKeySizeBytes < 2*modSizeInBytes + 1)
+                        return  CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR;
+
+                /* Point control byte */
+                if (compression == CC_EC_PointUncompressed)
+                        pExportPublKey[0] = 0x04;
+                else
+                        pExportPublKey[0] = (0x06 | yBit);
+
+                err = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                                 pExportPublKey + 1, 4*((modSizeInBytes+3)/4),
+                                                                 publKey->x, modSizeInBytes );
+                if (err != CC_OK) {
+                        err = CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+                        goto End;
+                }
+                err = CC_CommonConvertLswMswWordsToMsbLsbBytes(
+                                                                 pExportPublKey + 1 + modSizeInBytes, 4*((modSizeInBytes+3)/4),
+                                                                 publKey->y, modSizeInBytes );
+                if (err != CC_OK) {
+                        err = CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+                        goto End;
+                }
+
+                /* Set publKeySizeInBytes */
+                *pPublKeySizeBytes = 2*modSizeInBytes + 1;
+                break;
+
+        default:
+                return CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR;
+        }
+        End:
+        if (err != CC_OK) {
+                CC_PalMemSetZero(pExportPublKey, *pPublKeySizeBytes);
+                *pPublKeySizeBytes = 0;
+        }
+        return err;
+
+} /* End of CC_EcpkiPubKeyExport */
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_domain.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_domain.c
new file mode 100644
index 0000000..c616094
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_domain.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include "cc_ecpki_types.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pki.h"
+#include "ec_wrst.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_fips_defs.h"
+#include "cc_ecpki_domains_defs.h"
+
+
+/************************ Defines ***************************************/
+
+/************************ Enums *****************************************/
+
+/************************ Typedefs **************************************/
+
+/************************ Global Data ***********************************/
+
+extern const getDomainFuncP ecDomainsFuncP[CC_ECPKI_DomainID_OffMode];
+/************* Private function prototype *******************************/
+
+/************************ Public Functions ******************************/
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetEcDomain(CCEcpkiDomainID_t domainId)
+{
+    if (domainId >= CC_ECPKI_DomainID_OffMode) {
+        return NULL;
+    }
+
+    if (ecDomainsFuncP[domainId] == NULL) {
+        return NULL;
+    }
+
+    return ((ecDomainsFuncP[domainId])());
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_kg.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_kg.c
new file mode 100644
index 0000000..69d7dbc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_kg.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mem.h"
+#include "cc_rnd_common.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pki.h"
+#include "ec_wrst.h"
+#include "cc_general_defs.h"
+#include "cc_fips_defs.h"
+#include "cc_rnd_local.h"
+
+
+/***************  CC_EcpkiKeyPairGenerateBase function  **************/
+/**
+ @brief Generates a pair of private and public keys using configurable base point
+ in little endian ordinary form according to [ANS X9.31].
+
+    The function performs the following:
+      1. Checks the validity of all of the function inputs. If one of the received
+         parameters is not valid, it returns an error.
+      2. Cleans buffers and generates random private key.
+      3. Calls the low level function PkaEcWrstScalarMult to generate EC public key.
+      4. Outputs the user public and private key structures in little endian form.
+      5. Cleans temporary buffers.
+      6. Exits.
+
+ @param [in/out] pRndContext - Pointer to RND context.
+ @param [in] pDomain  - The pointer to current EC domain.
+ @param [in] ecX_ptr - The X cordinate of the base point. little endian.
+ @param [in] ecY_ptr - The Y cordinate of the base point. little endian.
+ @param [out] pUserPrivKey - The pointer to the private key structure.
+ @param [out] pUserPublKey - The pointer to the public key structure.
+ @param [in] pTempBuf - Temporary buffers of size, defined by CCEcpkiKgTempData_t.
+ @param [in] pFipsCtx - Pointer to temporary buffer used in case FIPS certification if required
+
+ @return <b>CCError_t</b>: <br>
+                       CC_OK<br>
+                        CC_ECPKI_RND_CONTEXT_PTR_ERROR
+                        CC_ECPKI_DOMAIN_PTR_ERROR<br>
+                        CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR<br>
+                        CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR<br>
+                        CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR<br>
+*/
+CEXPORT_C CCError_t CC_EcpkiKeyPairGenerateBase(
+                                           CCRndContext_t              *pRndContext,         /*in/out*/
+                                           const CCEcpkiDomain_t       *pDomain,             /*in*/
+                                           const uint32_t              *ecX_ptr,             /*in*/
+                                           const uint32_t              *ecY_ptr,             /*in*/
+                                           CCEcpkiUserPrivKey_t        *pUserPrivKey,        /*out*/
+                                           CCEcpkiUserPublKey_t        *pUserPublKey,        /*out*/
+                                           CCEcpkiKgTempData_t         *pTempBuff,           /*in*/
+                                           CCEcpkiKgFipsContext_t      *pFipsCtx)            /*in*/
+{
+        CCError_t err = CC_OK;
+        CCEcpkiPrivKey_t *pPrivKey;
+        uint32_t  orderSizeInWords;
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+
+        /* ......... checking the validity of arguments .......... */
+        /* ------------------------------------------------------- */
+
+        if (pRndContext == NULL)
+                return CC_ECPKI_RND_CONTEXT_PTR_ERROR;
+
+        if (pDomain == NULL)
+                return CC_ECPKI_DOMAIN_PTR_ERROR;
+
+        if (ecX_ptr == NULL || ecY_ptr == NULL)
+            return CC_ECPKI_INVALID_BASE_POINT_PTR_ERROR;
+
+        if (pUserPrivKey == NULL)
+                return CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR;
+
+        if (pUserPublKey == NULL)
+                return CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR;
+
+        if (pTempBuff == NULL)
+                return CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR;
+
+        /* .........  clear all input structures  ............*/
+
+        CC_PalMemSetZero( pUserPrivKey, sizeof(CCEcpkiUserPrivKey_t) );
+        CC_PalMemSetZero( pUserPublKey, sizeof(CCEcpkiUserPublKey_t) );
+
+        /* the pointer to the key database */
+        pPrivKey = (CCEcpkiPrivKey_t *)&pUserPrivKey->PrivKeyDbBuff;
+
+        orderSizeInWords = (pDomain->ordSizeInBits+CC_BITS_IN_32BIT_WORD-1)/CC_BITS_IN_32BIT_WORD;
+        /*  set EC order as max. vect. */
+        CC_PalMemCopy(pTempBuff, pDomain->ecR, sizeof(uint32_t)*orderSizeInWords);
+
+        /* generate random private key vector in range: 1 < privKey < EcOrder *
+         * Note: we exclude privKey = 1, allowed by FIPS 186-4, because the   *
+        *  negligible low probability of its random generation                */
+        pPrivKey->PrivKey[orderSizeInWords - 1] = 0;
+        err = CC_RndGenerateVectorInRange(pRndContext, (uint32_t)pDomain->ordSizeInBits,
+                                            (uint8_t*)pTempBuff/*MaxVect*/, (uint8_t*)pPrivKey->PrivKey/*RndVect*/);
+        if (err) {
+                goto End;
+        }
+
+        err = EcWrstGenKeyPairBase(pDomain, ecX_ptr, ecY_ptr, pUserPrivKey, pUserPublKey, pTempBuff);
+        if (err) {
+                goto End;
+        }
+
+        err = FIPS_ECC_VALIDATE(pRndContext, pUserPrivKey, pUserPublKey, pFipsCtx);
+
+        End:
+        if (err) {
+                CC_PalMemSetZero(pUserPrivKey, sizeof(CCEcpkiUserPrivKey_t));
+                CC_PalMemSetZero(pUserPublKey, sizeof(CCEcpkiUserPublKey_t));
+        }
+        if (pFipsCtx != NULL) {
+                CC_PalMemSetZero(pFipsCtx, sizeof(CCEcpkiKgFipsContext_t));
+        }
+
+        CC_PalMemSetZero(pTempBuff, sizeof(CCEcpkiKgTempData_t));
+        return err;
+}/* END OF CC_EcpkiKeyPairGenerateBase */
+
+/***************  CC_EcpkiKeyPairGenerate function  **************/
+/**
+ @brief Generates a pair of private and public keys in little endian ordinary form according to [ANS X9.31].
+
+    The function performs the following:
+      1. Checks the validity of all of the function inputs. If one of the received
+         parameters is not valid, it returns an error.
+      2. Cleans buffers and generates random private key.
+      3. Calls the low level function PkaEcWrstScalarMult to generate EC public key.
+      4. Outputs the user public and private key structures in little endian form.
+      5. Cleans temporary buffers.
+      6. Exits.
+
+ @param [in/out] pRndContext - The pointer to random context (state).
+ @param [in] pDomain  - The pointer to current EC domain.
+ @param [out] pUserPrivKey - The pointer to the private key structure.
+ @param [out] pUserPublKey - The pointer to the public key structure.
+ @param [in] pTempBuf - Temporary buffers of size, defined by CCEcpkiKgTempData_t.
+ @param [in] pFipsCtx - Pointer to temporary buffer used in case FIPS certification if required
+
+ @return <b>CCError_t</b>: <br>
+                       CC_OK<br>
+                        CC_ECPKI_RND_CONTEXT_PTR_ERROR
+                        CC_ECPKI_DOMAIN_PTR_ERROR<br>
+                        CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR<br>
+                        CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR<br>
+                        CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR<br>
+*/
+CEXPORT_C CCError_t CC_EcpkiKeyPairGenerate(
+                                           CCRndContext_t         *pRndContext,  /*in/out*/
+                                           const CCEcpkiDomain_t  *pDomain,      /*in*/
+                                           CCEcpkiUserPrivKey_t   *pUserPrivKey, /*out*/
+                                           CCEcpkiUserPublKey_t   *pUserPublKey, /*out*/
+                                           CCEcpkiKgTempData_t   *pTempBuff,    /*in*/
+                                           CCEcpkiKgFipsContext_t *pFipsCtx)    /*in*/
+{
+
+    if (NULL == pDomain) {
+        return CC_ECPKI_DOMAIN_PTR_ERROR;
+    }
+
+    return CC_EcpkiKeyPairGenerateBase(pRndContext, pDomain, pDomain->ecGx, pDomain->ecGy,
+                                       pUserPrivKey, pUserPublKey, pTempBuff, pFipsCtx);
+}
+
+/**********************************************************************/
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_local.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_local.h
new file mode 100644
index 0000000..d3e5122
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/cc_ecpki_local.h
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_ECPKI_LOCAL_H
+#define _CC_ECPKI_LOCAL_H
+
+ /** @file
+   *  @brief this file contains the prototype of the service functions for
+   *         the CryptoCell ECPKI module that are intendet for internaly usage.  */
+
+
+#include "cc_error.h"
+#include "cc_ecpki_types.h"
+#include "cc_rnd_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/*-------------------------------------------------*/
+/*  User passed structures validation tags         */
+/*-------------------------------------------------*/
+
+/* the ECPKI user public key user validity TAG */
+#define CC_ECPKI_PUBL_KEY_VALIDATION_TAG  0xEC000001
+/* the ECPKI user private key user validity TAG */
+#define CC_ECPKI_PRIV_KEY_VALIDATION_TAG 0xEC000002
+
+/* the ECDSA signing user context validity TAG */
+#define CC_ECDSA_SIGN_CONTEXT_VALIDATION_TAG   0xEC000003
+/* the ECDSA verifying user context validity TAG */
+#define CC_ECDSA_VERIFY_CONTEXT_VALIDATION_TAG 0xEC000004
+
+typedef struct {
+    uint16_t hashResultSize;
+    CCHashOperationMode_t hashMode;
+}CCEcpkiHash_t;
+
+
+
+
+/************************ macros ********************************/
+
+/************************ Typedefs  *****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+/**************************************************************************
+ *                EcdsaSignInit function
+ **************************************************************************/
+/*!
+@brief
+The EcdsaSignInit functions user shall call first to perform the EC DSA Signing operation.
+
+   The function performs the following steps:
+   -# Validates all the inputs of the function. If one of the received
+      parameters is not valid, the function returns an error.
+   -# Calls the CC_HashInit() function.
+   -# Exits the handler with the OK code.
+
+   This function does not do ECDSA cryptographic processing. Rather, it
+   prepares a context that is used by the Update() and Finish() functions.
+
+@note
+Using of HASH functions with HASH size great, than EC modulus size, is not recommended!
+
+@return CC_OK on success.
+@return a non-zero value on failure as defined cc_ecpki_error.h.
+*/
+CIMPORT_C CCError_t EcdsaSignInit(
+             CCEcdsaSignUserContext_t  *pSignUserContext,    /*!< [in/out] A pointer to the user buffer for signing data. */
+             CCEcpkiUserPrivKey_t      *pSignerPrivKey,      /*!< [in]  A pointer to the private key that is used to sign the data. */
+             CCEcpkiHashOpMode_t       hashMode             /*!< [in]  Defines the hash mode used for DSA. */
+             );
+
+/**************************************************************************
+ *                EcdsaSignUpdate function
+ **************************************************************************/
+/*!
+@brief Performs a hash  operation on data allocated by the user
+before finally signing it.
+
+In case user divides signing data by block, he must call the Update function
+continuously a number of times until processing of the entire data block is complete.
+
+@note
+Using of HASH functions with HASH size great, than EC modulus size, is not recommended!
+
+@return CC_OK on success.
+@return a non-zero value on failure as defined cc_ecpki_error.h.
+ */
+CIMPORT_C CCError_t EcdsaSignUpdate(
+               CCEcdsaSignUserContext_t    *pSignUserContext,  /*!< [in/out] The pointer to the user buffer for signing the database. */
+               uint8_t                         *pMessageDataIn,    /*!< [in]  The pointer to the message data block for calculating the HASH. */
+               size_t                          dataInSize         /*!< [in]  The size of the message data block, in bytes.
+                                              The data size, passed on each call of the function, besides the last call,
+                                              must be a multiple of the HASH block size according to used HASH mode. */
+               );
+
+/**************************************************************************
+ *                _DX_ECDSA_Sign_Finish function
+ **************************************************************************/
+/*!
+@brief Performs initialization of variables and structures, calls the hash function
+for the last block of data (if necessary) and then calculates digital signature.
+Algorithm according ANS X9.62 standard.
+
+@note
+Using of HASH functions with HASH size great, than EC modulus size, is not recommended!
+
+@return CC_OK on success.
+@return a non-zero value on failure as defined cc_ecpki_error.h.
+**/
+CIMPORT_C  CCError_t EcdsaSignFinishInt(
+               CCEcdsaSignUserContext_t   *pSignUserContext,       /*!< [in]  A pointer to the user buffer for signing database. */
+               CCRndContext_t             *pRndContext,            /*!< [in/out] A pointer to the random generation function context. */
+               uint8_t                        *pSignOut,               /*!< [out] A pointer to a buffer for output of signature. */
+               size_t                         *pSignOutSize,           /*!< [in/out] A pointer to the size of a user passed buffer for
+                                                 signature (in), be not less than 2*orderSizeInBytes. */
+               uint32_t                        isEphemerKeyInternal,   /*!< [in] A parameter defining whether the ephemeral key is
+                                                 internal or external (1 or 0). */
+               uint32_t                       *pEphemerKeyData         /*!< [in] A pointer to external ephemeral key data.
+                                           If it is given (case isEphemerKeyInternal=0), then the buffer
+                                           must containing the ephemeral private key of size equal to
+                                           EC generator order size, where LS-word is left most and MS-word
+                                           is right most one. */
+               );
+
+/**************************************************************************
+ *                EcdsaSignFinish function
+ **************************************************************************/
+/*!
+@brief The macro definition for calling the ::EcdsaSignFinishInt function with internal generation of ephemeral keys.
+
+@note
+Using of HASH functions with HASH size great, than EC modulus size, is not recommended!
+
+The macro calls the function with the following arguments as constant:
+isEphemerKeyInternal = 1 and pEphemerKeyData = NULL.
+*/
+#define EcdsaSignFinish(pSignUserContext, pRndContext, pSignatureOut, pSignatureOutSize) \
+EcdsaSignFinishInt((pSignUserContext), (pRndContext), (pSignatureOut), (pSignatureOutSize), 1, NULL)
+
+/**************************************************************************
+ *                EcdsaVerifyInit  function
+ **************************************************************************/
+/*!
+@brief Prepares a context that is used by the Update and Finish functions
+but does not perform elliptic curve cryptographic processing
+
+The function:
+- Receives and decrypts user data (working context).
+- Checks input parameters of  ECDSA Verifying primitive.
+- Calls hash init function.
+- Initializes variables and structures for calling next functions.
+- Encrypts and releases working context.
+
+@note
+Using of HASH functions with HASH size great, than EC modulus size, is not recommended!
+
+@return CC_OK on success.
+@return a non-zero value on failure as defined cc_ecpki_error.h.
+*/
+CIMPORT_C CCError_t EcdsaVerifyInit(
+                       CCEcdsaVerifyUserContext_t  *pVerifyUserContext,    /*!< [in/out] A pointer to the user buffer for verifying database. */
+                       CCEcpkiUserPublKey_t        *pSignerPublKey,        /*!< [in]  A pointer to a Signer public key structure. */
+                       CCEcpkiHashOpMode_t         hashMode               /*!< [in]  The enumerator variable defines the hash function to be used. */
+                       );
+
+
+/**************************************************************************
+ *                EcdsaVerifyUpdate function
+ **************************************************************************/
+/*!
+@brief Performs a hash  operation on data allocated by the user
+before finally verifying its signature.
+
+In case user divides signing data by block, he must call the Update function
+continuously a number of times until processing of the entire data block is complete.
+
+@note
+Using of HASH functions with HASH size greater, than EC modulus size, is not recommended.
+
+@return CC_OK on success.
+@return a non-zero value on failure as defined cc_ecpki_error.h.
+*/
+CIMPORT_C CCError_t EcdsaVerifyUpdate(
+                         CCEcdsaVerifyUserContext_t *pVerifyUserContext, /*!< [in/out] The pointer to the user buffer for verifying database. */
+                         uint8_t                        *pMessageDataIn,     /*!< [in]  The message data for calculating Hash. */
+                         size_t                         dataInSize          /*!< [in]  The size of the message data block, in bytes.
+                                                         The data size, passed on each call of the function, besides the last call,
+                                                         must be a multiple of the HASH block size according to used HASH mode. */
+                         );
+
+
+/**************************************************************************
+ *                EcdsaVerifyFinish function
+ **************************************************************************/
+
+/*!
+@brief Performs initialization of variables and structures,
+calls the hash function for the last block of data (if necessary),
+than calls EcWrstDsaVerify function for verifying signature according to
+ANS X9.62 standard.
+
+@note
+Using of HASH functions with HASH size greater, than EC modulus size, is not recommended!
+
+@return CC_OK on success.
+@return a non-zero value on failure as defined cc_ecpki_error.h.
+**/
+CIMPORT_C CCError_t EcdsaVerifyFinish(
+                         CCEcdsaVerifyUserContext_t  *pVerifyUserContext,    /*!< [in]  A pointer to the user buffer for verifying the database. */
+                         uint8_t                         *pSignatureIn,          /*!< [in]  A pointer to a buffer for the signature to be compared. */
+                         size_t                          SignatureSizeBytes /*!< [in]  The size of a user passed signature (must be 2*orderSizeInBytes). */
+                         );
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _CC_ECPKI_LOCAL_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192k1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192k1.c
new file mode 100644
index 0000000..ff19a5d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192k1.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+/***********************************************************************************
+ *   Data base of ecpki_domain_secp192k1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp192k1 = {
+    /* Field modulus :  GF_Modulus =  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37 - big end*/
+    {0xFFFFEE37,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* EC equation parameters a, b  */
+    /* a = 0  - big end  from SEC2 */
+    {0x0},
+    /* b = 3 - big end  from SEC2 */
+    {0x3},
+    /* Order of generator: FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D big end  from SEC2 */
+    {0x74DEFD8D,0x0F69466A,0x26F2FC17,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF},
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D   X - big end  from SEC2 */
+    {0xEAE06C7D,0x1DA5D1B1,0x80B7F434,0x26B07D02,0xC057E9AE,0xDB4FF10E},
+    /* 9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D  Y - big end  from SEC2 */
+    {0xD95E2F9D,0x4082AA88,0x15BE8634,0x844163D0,0x9C5628A7,0x9B2F2F6D},
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0x00000000,0x00000000,0x00000000,0x00000000,0x00000080,
+        0x8681F478,0x000000EC,0x00000000,0x00000000,0x00000080}, //80 00000000 00000000 000000EC 8681F478
+    #else  // CC_SUPPORT_PKA_64_16
+    {0x00000000,0x00000000,0x00000080,0x00000000, 0x00000000,
+        0x00000000,0x00000000,0x00000080,0x00000000,0x00000000},
+    #endif
+
+    192, /* Size of field modulus in bits */
+    192, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp192k1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_192K1"
+};
+
+
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp192k1DomainP(void)
+{
+    return &ecpki_domain_secp192k1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192k1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192k1.h
new file mode 100644
index 0000000..718dac3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192k1.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_ECPKI_DOMAIN_SECP192K1_H
+#define CC_ECPKI_DOMAIN_SECP192K1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp192k1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192r1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192r1.c
new file mode 100644
index 0000000..e623bce
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192r1.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+/***********************************************************************************
+ *   Data base of ecpki_domain_secp192r1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp192r1 = {
+    /* Field modulus :  GF_Modulus =  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF - big end*/
+    {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* EC equation parameters a, b  */
+    /* a = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC  - big end  from SEC2 */
+    {0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* b = 64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1 - big end  from SEC2 */
+    {0xC146B9B1,0xFEB8DEEC,0x72243049,0x0FA7E9AB,0xE59C80E7,0x64210519},
+
+    /* Order of generator: FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831 big end  from SEC2 */
+    {0xB4D22831,0x146BC9B1,0x99DEF836,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* 188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012   X - big end  from SEC2 */
+    {0x82FF1012,0xF4FF0AFD,0x43A18800,0x7CBF20EB,0xB03090F6,0x188DA80E},
+    /* 7192B95FFC8DA78631011ED6B24CDD573F977A11E794811  Y - big end  from SEC2 */
+    {0x1E794811,0x73F977A1,0x6B24CDD5,0x631011ED,0xFFC8DA78,0x07192B95},
+
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0x00000080,0x00000000,0x00000000,0x00000000,0x00000080,
+        0x1083E4F5,0x00000033,0x00000000,0x00000000,0x00000080},
+    #else  // CC_SUPPORT_PKA_64_16
+    {0x00000000,0x00000000,0x00000080,0x00000000, 0x00000000,
+        0x00000000,0x00000000,0x00000080,0x00000000,0x00000000},
+    #endif
+
+    192, /* Size of field modulus in bits */
+    192, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp192r1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_192R1" /*NIST_P192*/
+};
+
+
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp192r1DomainP(void)
+{
+    return &ecpki_domain_secp192r1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192r1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192r1.h
new file mode 100644
index 0000000..eeeb4d9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp192r1.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_ECPKI_DOMAIN_SECP192R1_H
+#define CC_ECPKI_DOMAIN_SECP192R1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp192r1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224k1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224k1.c
new file mode 100644
index 0000000..ac386f8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224k1.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+
+/***********************************************************************************
+ *   Data base of CC_ECPKI_DomainID_secp224k1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp224k1 = {
+    /* Field modulus :  GF_Modulus =  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D - big end*/
+    {0xFFFFE56D,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* EC equation parameters a, b  */
+    /* a = -0  - big end  from SEC2 */
+    {0},
+    /* b = 5 - big end  from SEC2 */
+    {5},
+    /* Order of generator: 10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7 big end  from SEC2 */
+    {0x769FB1F7,0xCAF0A971,0xD2EC6184,0x0001DCE8,0x00000000,0x00000000,0x00000000,0x00000001},
+
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C   X - big end  from SEC2 */
+    {0xB6B7A45C,0x0F7E650E,0xE47075A9,0x69A467E9,0x30FC28A1,0x4DF099DF,0xA1455B33},
+    /* 7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5  Y - big end  from SEC2 */
+    {0x556D61A5,0xE2CA4BDB,0xC0B0BD59,0xF7E319F7,0x82CAFBD6,0x7FBA3442,0x7E089FED},
+
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0x00000000,0x00000000,0x00000000,0x00000000,0x00000080,
+        0xFE23172D,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x000000FF},
+    #else  // CC_SUPPORT_PKA_64_16
+    {0x00000000,0x00000000,0x00000080,0x00000000, 0x00000000,
+        0xFFFFFFFF,0xFFFFFFFF,0x000000FF,0x00000000,0x00000000},
+    #endif
+
+    224, /* Size of field modulus in bits */
+    225, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp224k1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_224K1"
+};
+
+
+
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp224k1DomainP(void)
+{
+    return &ecpki_domain_secp224k1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224k1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224k1.h
new file mode 100644
index 0000000..49611b0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224k1.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_ECPKI_DOMAIN_SECP224K1_H
+#define CC_ECPKI_DOMAIN_SECP224K1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp224k1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224r1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224r1.c
new file mode 100644
index 0000000..64af032
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224r1.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+/***********************************************************************************
+ *   Data base of CC_ECPKI_DomainID_secp224r1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp224r1 = {
+    /* Field modulus :  GF_Modulus =  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001  - big end*/
+    {0x00000001,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* EC equation parameters a, b  */
+    /* a = -3 = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE  - big end  from SEC2 */
+    {0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* b = B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4 - big end  from SEC2 */
+    {0x2355FFB4,0x270B3943,0xD7BFD8BA,0x5044B0B7,0xF5413256,0x0C04B3AB,0xB4050A85},
+
+    /* Order of generator: ord= FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D big end  from SEC2 */
+    {0x5C5C2A3D,0x13DD2945,0xE0B8F03E,0xFFFF16A2,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21   X - big end  from SEC2 */
+    {0x115C1D21,0x343280D6,0x56C21122,0x4A03C1D3,0x321390B9,0x6BB4BF7F,0xB70E0CBD},
+    /* BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34  Y - big end  from SEC2 */
+    {0x85007E34,0x44D58199,0x5A074764,0xCD4375A0,0x4C22DFE6,0xB5F723FB,0xBD376388},
+
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0x0000007F,0x00000000,0x00000000,0x00000000,0x00000080,
+        0x0074AE8F,0x00000000,0x00000000,0x00000000,0x00000080},
+    #else  // CC_SUPPORT_PKA_64_16
+    {0x00000000,0x00000000,0x00000080,0x00000000, 0x00000000,
+        0x00000000,0x00000000,0x00000080,0x00000000,0x00000000},
+    #endif
+
+    224, /* Size of field modulus in bits */
+    224, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp224r1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_224R1" /*NIST_P224*/
+};
+
+
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp224r1DomainP(void)
+{
+    return &ecpki_domain_secp224r1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224r1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224r1.h
new file mode 100644
index 0000000..76b79e7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp224r1.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_ECPKI_DOMAIN_SECP224R1_H
+#define CC_ECPKI_DOMAIN_SECP224R1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp224r1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256k1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256k1.c
new file mode 100644
index 0000000..ec21deb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256k1.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+
+/***********************************************************************************
+ *   Data base of CC_ECPKI_DomainID_secp256k1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp256k1 = {
+    /* Field modulus :  GF_Modulus =  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F - big end*/
+    {0xFFFFFC2F,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* EC equation parameters a, b  */
+    /* a = 0  - big end  from SEC2 */
+    {0x00000000},
+    /* b = 7 - big end  from SEC2 */
+    {0x00000007},
+
+    /* Order of generator: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 big end  from SEC2 */
+    {0xD0364141,0xBFD25E8C,0xAF48A03B,0xBAAEDCE6,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798   X - big end  from SEC2 */
+    {0x16F81798,0x59F2815B,0x2DCE28D9,0x029BFCDB,0xCE870B07,0x55A06295,0xF9DCBBAC,0x79BE667E},
+    /* 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8  Y - big end  from SEC2 */
+    {0xFB10D4B8,0x9C47D08F,0xA6855419,0xFD17B448,0x0E1108A8,0x5DA4FBFC,0x26A3C465,0x483ADA77},
+
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0x00000000,0x00000000,0x00000000,0x00000000,0x00000080,
+        0x000000A2,0x00000000,0x00000000,0x00000000,0x00000080},
+    #else  // CC_SUPPORT_PKA_64_16
+    {0x00000000,0x00000000,0x00000080,0x00000000, 0x00000000,
+        0x00000000,0x00000000,0x00000080,0x00000000,0x00000000},
+    #endif
+
+    256, /* Size of field modulus in bits */
+    256, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp256k1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_256K1"
+};
+
+
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp256k1DomainP(void)
+{
+    return &ecpki_domain_secp256k1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256k1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256k1.h
new file mode 100644
index 0000000..0522cd4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256k1.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_ECPKI_DOMAIN_SECP256K1_H
+#define CC_ECPKI_DOMAIN_SECP256K1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp256k1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256r1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256r1.c
new file mode 100644
index 0000000..5ea561e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256r1.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+
+/***********************************************************************************
+ *   Data base of CC_ECPKI_DomainID_secp256r1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp256r1 = {
+    /* Field modulus :  GF_Modulus =  FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF - big end*/
+    {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF},
+    /* EC equation parameters a, b  */
+    /* a = FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC  - big end  from SEC2 */
+    {0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0x00000000,0x00000001,0xFFFFFFFF},
+    /* b = 5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B - big end  from SEC2 */
+    {0x27D2604B,0x3BCE3C3E,0xCC53B0F6,0x651D06B0,0x769886BC,0xB3EBBD55,0xAA3A93E7,0x5AC635D8},
+
+    /* Order of generator: FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551 big end  from SEC2 */
+    {0xFC632551,0xF3B9CAC2,0xA7179E84,0xBCE6FAAD,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0xFFFFFFFF},
+
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296   X - big end  from SEC2 */
+    {0xD898C296,0xF4A13945,0x2DEB33A0,0x77037D81,0x63A440F2,0xF8BCE6E5,0xE12C4247,0x6B17D1F2},
+    /* 4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5  Y - big end  from SEC2 */
+    {0x37BF51F5,0xCBB64068,0x6B315ECE,0x2BCE3357,0x7C0F9E16,0x8EE7EB4A,0xFE1A7F9B,0x4FE342E2},
+
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0xFFFFFF7F,0xFFFFFF7F,0xFFFFFFFF,0x0000007F,0x00000080,
+        0xFFFFFFA1,0xFFFFFF7F,0xFFFFFFFF,0x0000007F,0x00000080},
+    #else  // CC_SUPPORT_PKA_64_16
+    {0xFFFFFFFF,0x0000007F,0x00000080,0x00000000, 0x00000000,
+        0xFFFFFFFF,0x0000007F,0x00000080,0x00000000,0x00000000},
+    #endif
+
+    256, /* Size of field modulus in bits */
+    256, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp256r1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_256R1" /*NIST_P256*/
+
+};
+
+
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp256r1DomainP(void)
+{
+    return &ecpki_domain_secp256r1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256r1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256r1.h
new file mode 100644
index 0000000..9972e32
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp256r1.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_ECPKI_DOMAIN_SECP256R1_H
+#define CC_ECPKI_DOMAIN_SECP256R1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp256r1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp384r1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp384r1.c
new file mode 100644
index 0000000..ea5f27b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp384r1.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+
+/***********************************************************************************
+ *   Data base of CC_ECPKI_DomainID_secp384r1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp384r1 = {
+    /* Field modulus :                            *
+    *  GF_Modulus =  FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF - big end*/
+    {0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+        0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* EC equation parameters a, b  */
+    /* a = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC   - big end  from SEC2 */
+    {0xFFFFFFFC,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+        0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+    /* b = B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF  - big end  from SEC2 */
+    {0xD3EC2AEF,0x2A85C8ED,0x8A2ED19D,0xC656398D,0x5013875A,0x0314088F,0xFE814112,0x181D9C6E,
+        0xE3F82D19,0x988E056B,0xE23EE7E4,0xB3312FA7},
+
+    /* Order of generator: FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973  big end  from SEC2 */
+    {0xCCC52973,0xECEC196A,0x48B0A77A,0x581A0DB2,0xF4372DDF,0xC7634D81,0xFFFFFFFF,0xFFFFFFFF,
+        0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF},
+
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7    X - big end  from SEC2 */
+    {0x72760AB7,0x3A545E38,0xBF55296C,0x5502F25D,0x82542A38,0x59F741E0,0x8BA79B98,0x6E1D3B62,
+        0xF320AD74,0x8EB1C71E,0xBE8B0537,0xAA87CA22},
+    /* 3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F   Y - big end  from SEC2 */
+    {0x90EA0E5F,0x7A431D7C,0x1D7E819D,0x0A60B1CE,0xB5F0B8C0,0xE9DA3113,0x289A147C,0xF8F41DBD,
+        0x9292DC29,0x5D9E98BF,0x96262C6F,0x3617DE4A},
+
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0x00000000,0x00000000,0x00000000,0x00000000,0x00000080,
+        0x00000000,0x00000000,0x00000000,0x00000000,0x00000080},
+    #else  // CC_SUPPORT_PKA_64_16
+    {0x00000000,0x00000000,0x00000080,0x00000000, 0x00000000,
+        0x00000000,0x00000000,0x00000080,0x00000000,0x00000000},
+    #endif
+
+    384, /* Size of field modulus in bits */
+    384, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp384r1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_384R1"
+
+};
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp384r1DomainP(void)
+{
+    return &ecpki_domain_secp384r1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp384r1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp384r1.h
new file mode 100644
index 0000000..c202f71
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp384r1.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef CC_ECPKI_DOMAIN_SECP384R1_H
+#define CC_ECPKI_DOMAIN_SECP384R1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp384r1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp521r1.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp521r1.c
new file mode 100644
index 0000000..6346470
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp521r1.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+
+/**************** The domain structure describing *************/
+/**
+// The structure containing EC domain parameters in little-endian form.
+// Elliptic curve: Y^2 = X^3 + A*X + B over prime fild GFp
+
+typedef  struct {
+
+    // Field modulus:  GF_Modulus = P
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC equation parameters a, b
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // Order of generator: EC_GenerOrder
+    uint32_t    ecOrd [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    // Generator (EC base point) coordinates in projective form
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    // EC cofactor EC_Cofactor_K
+    uint32_t    ecH;
+    // include the specific fields that are used by the low level
+    uint32_t      barrTagBuff[CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS];
+    // Size of fields in bits
+    uint32_t    modSizeInBits;
+    uint32_t    ordSizeInBits;
+    // Size of each inserted Barret tag in words; 0 - if not inserted
+    uint32_t    barrTagSizeInWords;
+    CCEcpkiDomainID_t   DomainID;
+    int8_t  name[20];
+
+} CCEcpkiDomain_t;
+
+*/
+
+
+/***********************************************************************************
+ *   Data base of CC_ECPKI_DomainID_secp521r1: structure of type  CCEcpkiDomain_t    *
+ *       All data is given in little endian order of words in arrays               *
+ ***********************************************************************************/
+static const CCEcpkiDomain_t ecpki_domain_secp521r1 = {
+    /* Field modulus :                            *
+    *  GF_Modulus =  P= 1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF */
+    {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+     0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x000001FF},
+    /* EC equation parameters a, b  */
+    /* a = 1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC  - big end  from SEC2 */
+    {0xFFFFFFFC,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+     0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x000001FF},
+    /* b = Bec= 51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00  */
+    {0x6B503F00,0xEF451FD4,0x3D2C34F1,0x3573DF88,0x3BB1BF07,0x1652C0BD,0xEC7E937B,0x56193951,
+     0x8EF109E1,0xB8B48991,0x99B315F3,0xA2DA725B,0xB68540EE,0x929A21A0,0x8E1C9A1F,0x953EB961,0x00000051},
+
+    /* Order of generator: 1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409 big end  from SEC2 */
+    {0x91386409,0xBB6FB71E,0x899C47AE,0x3BB5C9B8,0xF709A5D0,0x7FCC0148,0xBF2F966B,0x51868783,
+     0xFFFFFFFA,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x000001FF},
+
+    /* Generator  coordinates in affine form: EC_Gener_X, EC_Gener_Y (in ordinary representation) */
+    /* Gx= C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66  */
+    {0xC2E5BD66,0xF97E7E31,0x856A429B,0x3348B3C1,0xA2FFA8DE,0xFE1DC127,0xEFE75928,0xA14B5E77,
+     0x6B4D3DBA,0xF828AF60,0x053FB521,0x9C648139,0x2395B442,0x9E3ECB66,0x0404E9CD,0x858E06B7,0x000000C6},
+    /* Gy= 11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650  Y - big end  from SEC2 */
+    {0x9FD16650,0x88BE9476,0xA272C240,0x353C7086,0x3FAD0761,0xC550B901,0x5EF42640,0x97EE7299,
+     0x273E662C,0x17AFBD17,0x579B4468,0x98F54449,0x2C7D1BD9,0x5C8A5FB4,0x9A3BC004,0x39296A78,0x00000118},
+    1, /* EC cofactor K */
+
+    /* Barrett tags NP,RP */
+    #ifdef CC_SUPPORT_PKA_128_32
+    {0x00000000,0x00000000,0x00000000,0x00000000,0x00000080,
+        0x00000000,0x00000000,0x00000000,0x00000000,0x00000080},
+    #else  // CC_SUPPORT_PKA_64_16
+    {0x00000000,0x00000000,0x00000080,0x00000000, 0x00000000,
+        0x00000000,0x00000000,0x00000080,0x00000000,0x00000000},
+    #endif
+
+    521, /* Size of field modulus in bits */
+    521, /* Size of order of generator in bits */
+    5,   /* Size of each inserted Barret tag in words; 0 - if not inserted */
+
+    CC_ECPKI_DomainID_secp521r1,    /* EC Domain identifier - enum */
+    "SECG_PRIME_521R1" /*NIST_P521*/
+};
+
+
+
+
+/**
+ @brief    the function returns the domain pointer id the domain is supported for the product;
+        otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp521r1DomainP(void)
+{
+    return &ecpki_domain_secp521r1;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp521r1.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp521r1.h
new file mode 100644
index 0000000..00f8cb4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ec_wrst/ecc_domains/cc_ecpki_domain_secp521r1.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CC_ECPKI_DOMAIN_SECP521R1_H
+#define CC_ECPKI_DOMAIN_SECP521R1_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ @brief    the function returns the domain pointer
+ @return   return domain pointer
+
+*/
+const CCEcpkiDomain_t *CC_EcpkiGetSecp521r1DomainP(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffc_domain/cc_ffc_domain.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffc_domain/cc_ffc_domain.c
new file mode 100644
index 0000000..9cabcb3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffc_domain/cc_ffc_domain.c
@@ -0,0 +1,1347 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include "cc_pal_types_plat.h"
+#include "cc_pal_types.h"
+#include "cc_rnd_common.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_rsa_types.h"
+#include "cc_hash_defs.h"
+#include "mbedtls_cc_hkdf.h"
+#include "pki.h"
+#include "rsa.h"
+#include "cc_ffc_domain_error.h"
+#include "cc_ffc_domain.h"
+#include "cc_rnd_error.h"
+#include "cc_fips_defs.h"
+#include "cc_general_defs.h"
+
+
+/************************ Defines *******************************/
+
+/************************ Enums *********************************/
+
+/************************ macros ********************************/
+
+/** @brief This macro is required to remove compilers warnings if the HASH or PKI is not supported */
+
+
+/*********************** Global data  ***************************/
+
+//extern CCFfcDomainParamSizes_t ffcDomainParamSizes[CC_FFC_DOMAIN_PARAMS_SET_NUM_OFF_MODE];
+//extern CCFfcDhHashBlockAndDigestSizes_t FfcDhHashBlockAndDigestSizes[CC_FFCDH_HASH_NUM_OFF_MODE];
+
+extern CCError_t RsaPrimeTestCall(CCRndContext_t *pRndContext, uint32_t *pPrimeP, int32_t sizeWords,
+                                  int32_t rabinTestsCount, int8_t *pIsPrime, uint32_t *pTempBuff,
+                  CCRsaDhPrimeTestMode_t primeTestMode);
+
+/************* External functions prototypes  *****************************/
+
+//static
+CCError_t RndGenerateWordsArrayInRange(CCRndContext_t *pRndContext,
+                      uint32_t   rndSizeInBits,
+                      uint32_t  *maxVect_ptr,
+                      uint32_t  *rndVect_ptr,
+                      uint32_t  *tmp_ptr);
+
+/************************ Private Functions ******************************/
+
+/* This function translates the DH-Hash modes into HASH and KDF-Hash modes
+ * and gives HASH block and digest sizes (in bytes). Note: the function sets on output
+ * only required parameters, which pointers are not NULL.
+ * */
+CCError_t FfcGetHashMode(CCHashOperationMode_t *pHashMode, /* optional */
+             mbedtls_hkdf_hashmode_t *pHkdfHashMode, /* optional */
+             uint32_t *pBlockSize,                /* optional */
+             uint32_t *pDigestSize,               /* optional */
+             CCFfcHashOpMode_t ffcHashMode)     /* FFC HASH mode */
+{
+    CCError_t err = CC_OK;
+        CCHashOperationMode_t hashMode;
+        mbedtls_hkdf_hashmode_t hkdfHashMode;
+        size_t blockize, digestSize;
+
+        blockize = CC_HASH_BLOCK_SIZE_IN_BYTES; /* for all modes besides SHA384, SHA512 */
+        switch (ffcHashMode) {
+        case CC_FFC_HASH_SHA1_MODE:
+            hashMode = CC_HASH_SHA1_mode;
+            hkdfHashMode = CC_HKDF_HASH_SHA1_mode;
+            digestSize = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_FFC_HASH_SHA224_MODE:
+            hashMode = CC_HASH_SHA224_mode;
+            hkdfHashMode = CC_HKDF_HASH_SHA224_mode;
+            digestSize = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_FFC_HASH_SHA256_MODE:
+            hashMode = CC_HASH_SHA256_mode;
+            hkdfHashMode = CC_HKDF_HASH_SHA256_mode;
+            digestSize = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_FFC_HASH_SHA384_MODE:
+            hashMode = CC_HASH_SHA384_mode;
+            hkdfHashMode = CC_HKDF_HASH_SHA384_mode;
+        blockize = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+            digestSize = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+               break;
+        case CC_FFC_HASH_SHA512_MODE:
+            hashMode = CC_HASH_SHA512_mode;
+            hkdfHashMode = CC_HKDF_HASH_SHA512_mode;
+            digestSize = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+        blockize = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+                break;
+        default:
+            return CC_FFC_DOMAIN_INVALID_HASH_MODE_ERROR;
+        }
+
+        /* output required parameters only */
+        if(pHashMode != NULL)
+            *pHashMode = hashMode;
+        if(pHkdfHashMode != NULL)
+            *pHkdfHashMode = hkdfHashMode;
+        if(pDigestSize != NULL)
+            *pDigestSize = digestSize;
+        if(pBlockSize != NULL)
+            *pBlockSize = blockize;
+
+        return err;
+}
+
+/*!
+ * The function returns FFC Domain parameters sizes according to given ID of
+ * approved set of Domain parameters FA,FB or FC (see SP 800-56A and FIPS 186-4 sec.1 standards).
+ *
+ */
+CCError_t FfcGetDomainSizes(
+        uint32_t *pMaxSecurStrength,        /*!< Maximum security strength supported, in bits. */
+        uint32_t *pPrimeLen,                /*!< Field (prime P) length in bytes. */
+        uint32_t *pOrderLen,                /*!< Subgroup order Q length in bytes. */
+        uint32_t *pMinHashLen,              /*!< Minimum length of HASH output in bytes. */
+        CCFfcParamSetId_t  ffcParamSetId) /*!< Enum. defining set of lengths of domain parameters, approved
+                                                     by SP 800-56A and FIPS 186-4 standards */
+{
+    CCError_t err = CC_OK;
+    CCFfcDomainParamSizes_t  *pParamsSet;
+    /*! Define and initialize DH domain parameters sizes array */
+    CCFfcDomainParamSizes_t ffcDomainParamSizes[(uint32_t)CC_FFC_PARAMS_SET_NUM_OFF_MODE] =
+                                           CC_FFC_DOMAIN_PARAM_SIZES_SET;
+
+    if(ffcParamSetId >= CC_FFC_PARAMS_SET_NUM_OFF_MODE)
+        return CC_FFC_DOMAIN_INVALID_SIZES_SET_ID_ERROR;
+
+    pParamsSet = &ffcDomainParamSizes[ffcParamSetId];
+
+    if(pMaxSecurStrength != NULL)
+        *pMaxSecurStrength = pParamsSet->maxSecurStrength;
+    if(pPrimeLen != NULL)
+        *pPrimeLen = pParamsSet->primeSize >> 3;
+    if(pOrderLen != NULL)
+        *pOrderLen = pParamsSet->orderSize >> 3;
+    if(pMinHashLen != NULL)
+        *pMinHashLen = pParamsSet->minHashLen >> 3;
+
+    return err;
+}
+
+
+
+
+
+/******************************************************************************************/
+/************************         Private Functions          ******************************/
+/******************************************************************************************/
+
+/********************************************************************************/
+/**
+ *      The function adds value to the number N, presented as bytes array, where MSbyte
+ *      is a most left one.
+ *
+ *      Algorithm: N = (N + val) mod 2^(8*sizeBytes).
+ *      Assumed: The array and its size are aligned to 32-bit words.
+ *
+ * @return carry from last addition
+ */
+static
+uint8_t FfcAddValueToMsbLsbBytesArray(uint8_t *pArr, uint32_t val, uint32_t sizeBytes)
+{
+        int32_t i;
+        uint32_t word, carry;
+
+        /* check input data */
+//        if(((uint32_t)pArr & 3) || (sizeBytes % 4) || (sizeBytes == 0)) {
+//          return CC_FFC_DOMAIN_BUFFER_ALIGNMENTS_ERROR;
+//        }
+
+        carry = val;
+        for (i = sizeBytes - 1; i >= 0; i -= 4) {
+            /*set input bytes to word */
+            word =  pArr[i-3]; word = (word<<8) | pArr[i-2];
+            word = (word<<16) | pArr[i-1]; word = (word<<24) | pArr[i];
+            carry += word;
+            /* set 4 bytes of sum into array */
+            pArr[i] = carry & 0xFF; pArr[i-1] = (carry>>8) & 0xFF;
+            pArr[i-2] = (carry>>16) & 0xFF; pArr[i-3] = (carry>>24) & 0xFF;
+
+            carry = (carry < word);
+        }
+
+        return (uint8_t)(carry & 1);
+}
+
+#define FFC_CMP_BE2LE_FIRST_GREAT   1
+#define FFC_CMP_BE2LE_FIRST_SMALL  -1
+#define FFC_CMP_BE2LE_EQUALLED      0
+
+
+/**  The function compares two big numbers, presented by:
+ *   - the first as BE bytes array, the second - as LE 32-bit words array.
+ *
+ *   Note: assumed, that sizes in bytes of both arrays are equalled.
+ *         in the first buffer
+ */
+static
+int32_t FfcCmpBeBytes2LeWordsBigNum(uint8_t *pBeBytes, uint32_t *pLeWords, size_t sizeWords)
+{
+        int32_t i, j, cmp;
+        uint32_t word;
+
+        cmp = FFC_CMP_BE2LE_EQUALLED;
+        i = 0;
+        for (j = sizeWords-1; j >= 0; j--) {
+            /*set 4 input bytes to word */
+            word =  pBeBytes[i++]; word = (word<<8) | pBeBytes[i++];
+            word = (word<<8) | pBeBytes[i++]; word = (word<<8) | pBeBytes[i++];
+            if(word > pLeWords[i]) {
+                cmp = FFC_CMP_BE2LE_FIRST_GREAT;
+            } else if(word < pLeWords[i]){
+                cmp = FFC_CMP_BE2LE_FIRST_SMALL;
+            }
+        }
+
+        return cmp;
+}
+
+
+
+#ifdef FFC_FURTHER_USING
+/********************************************************************************/
+/**
+ * @brief This function returns the effective size in bits of the MSB bytes array.
+ *
+ *        Assumed, that MSB > 0 is stored in the most left cell in the array.
+ *
+ * @param[in] arr_ptr -  The counter buffer.
+ * @param[in] sizeInBytes -  The counter size in bytes.
+ *
+ * @return result - The effective counters size in bits.
+ */
+
+//static
+uint32_t FfcGetSizeInBitsOfMsbLsbBytesArray(uint8_t  *arr_ptr,
+                                                       uint32_t  sizeInBytes)
+{
+        /* FUNCTION LOCAL DECLERATIONS */
+
+        /* loop variable */
+        int32_t i;
+
+        /* the effective size in bits */
+        uint32_t sizeInBits = 8 * sizeInBytes;
+
+        /* the effective MS byte */
+        uint8_t msbVal = arr_ptr[0], mask = 0x80;
+
+        /* FUNCTION LOGIC */
+
+        /* adjusting the effective size in bits */
+        for (i = 0; i < 8 ; i++) {
+                /* if the MS bit is set exit the loop */
+                if (msbVal & mask) {
+                        break;
+                }
+
+                sizeInBits--;
+
+                mask >>= 1;
+
+        }
+
+        return sizeInBits;
+
+}/* END OF  FfcDhKgGetSizeInBitsOfMsbLsbBytesArray */
+#endif
+
+
+/**
+ * The function returns count of Rabin-Miller tests, required for generation
+ * primes in FFC DSA and DH algorithms according to FIPS 186-4, sec. C.3: Tab. C.1.
+ *
+ * If input size not meets one of standard sizes of FFC Prime modulus or Order,
+ * then the function returns an error.
+ */
+static
+CCError_t FfcGetCountOfRabMilTests(uint32_t *pCountTests, size_t primeSizeBits)
+{
+    switch(primeSizeBits) {
+    /* sizes set for FFC Order */
+    case 160:
+        *pCountTests = 19;
+        break;
+    case 224:
+        *pCountTests = 24;
+        break;
+    case 256:
+        *pCountTests = 27;
+        break;
+    /* sizes set for FFC Prime modulus */
+    case 1024:
+        *pCountTests = 3;
+        break;
+    case 2048:
+        *pCountTests = 3;
+        break;
+    case 3072:
+        *pCountTests = 2;
+        break;
+    default:
+        return CC_FFC_DOMAIN_INVALID_ARGUMENT_SIZE_ERROR;
+    }
+
+    return CC_OK;
+}
+
+
+/**
+ * The function checks that ptr != NULL and outSize <= buffSize .
+ *
+ * In case the user gives both output pointer and size equal to zero,
+ * then the function ignores any checking and exits with OK
+ */
+static
+CCError_t FfcCheckPtrAndSize(void *pOut, size_t *pBuffSizeBytes, void *pIn, size_t inSizeBytes) {
+
+    CCError_t err = CC_OK;
+
+    if((pOut == NULL) && (pBuffSizeBytes == NULL)) {
+        goto End;
+    }
+
+    if((pOut == NULL) || (pIn == NULL)) {
+        err = CC_FFC_DOMAIN_INVALID_ARGUMENT_PTR_ERROR;
+        goto End; \
+    }
+
+    if(inSizeBytes > *pBuffSizeBytes) {
+        err = CC_FFC_DOMAIN_INVALID_ARGUMENT_SIZE_ERROR;
+        goto End;
+    }
+
+End:
+    return err;
+}
+
+
+/**
+ * The function finds prime Order Q for FFC Domain generation according to FIPS 186-4 sec.A.i.2.
+ *
+ * Note: Sizes in bytes of P, Q, HASH should be multiple of 4.
+ *       Size of pTmp buffer = 3*PrimeSizeWords + orderSizeWords + 1.
+ */
+static
+CCError_t FfcFips186v4FindOrderQ(
+            CCFfcDomain_t *pDomain,           /* [in/out]  pointer to FFC Domain. */
+            CCRndContext_t *pRndContext,      /* [in] context defining used random function and state. */
+            CCFfcGenerateSeed_t generateSeed, /*in*/
+            CCFfcDomainTmpBuff_t *pTmpBuff)   /*!< [in] pointer to FFC Domain temp buffer structure. */{
+
+    /* FUNCTION DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t err = CC_OK;
+
+    /* random function given by the user */
+    CCRndState_t *pRndState;
+    CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+    uint32_t *pOrder; /*out, LE words */
+    uint32_t    orderSizeWords, orderSizeBytes; /*in*/
+    uint8_t  *pSeed; /*BE bytes array */
+    uint32_t  seedSizeBytes, hashDigestSize;
+    /* primality flag (if prime, then isPrime = 1, else 0 ) */
+    int8_t  isPrime;
+    uint32_t *pHashData, *pTmp1;
+    uint32_t countRabMilTests;
+    CCHashOperationMode_t hashMode;
+    const mbedtls_md_info_t *md_info=NULL;
+
+    /* check some parameters */
+    CHECK_AND_SET_ERROR((pDomain == NULL), CC_FFC_DOMAIN_INVALID_DOMAIN_PTR_ERROR);
+    CHECK_AND_SET_ERROR((pRndContext == NULL), CC_FFC_DOMAIN_INVALID_RND_CTX_PTR_ERROR);
+
+    /* INITIALIZATION  */
+
+    pRndState = (CCRndState_t*)&(pRndContext->rndState);
+    RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
+
+    pOrder = pDomain->order;
+    orderSizeBytes = pDomain->ordLenWords * CC_32BIT_WORD_SIZE;
+    orderSizeWords = pDomain->ordLenWords;
+    pSeed = pDomain->seed;
+    seedSizeBytes = pDomain->seedSizeBytes;
+    hashDigestSize = pDomain->hashDigestSize;
+    /* set temp buffers */
+    pHashData = (uint32_t*)&pTmpBuff->TmpBuff[0]; /*orderSizeWords+1*/
+    pTmp1 = pHashData + orderSizeWords + 1; /*buffer 3*PrimeSizeWords*/
+
+    /* FUNCTION  LOGIC */
+
+    /* zeroing word, next after MSWord of Q, for carry, which can occur
+     * in P generation function. */
+    pOrder[orderSizeWords] = 0;
+
+    /* get count of R-M tests */
+    CHECK_ERROR(FfcGetCountOfRabMilTests(&countRabMilTests, orderSizeBytes*CC_BITS_IN_BYTE));
+    /* get HASH related parameters */
+    CHECK_ERROR(FfcGetHashMode(&hashMode, NULL/*pHkdfHashMode*/, NULL/*pBlockSize*/, NULL, pDomain->ffcHashMode/*in*/));
+
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+    if (NULL == md_info) {
+        err = CC_FFC_DOMAIN_GENERATION_FAILURE_ERROR;
+        goto End;
+    }
+
+    /*-------------------------------------------------*/
+    /*        FFC prime Order generation  loop         */
+    /*-------------------------------------------------*/
+    while(1) {
+    /*     Create random domain seed sec.A.1.1.2.     */
+        if(generateSeed == CC_FFC_GENERATE_NEW_SEED) {
+            CHECK_ERROR(RndGenerateVectFunc(pRndState, pSeed, seedSizeBytes));
+        }
+
+        err = mbedtls_md(md_info, pSeed, seedSizeBytes, (unsigned char *)pHashData);
+        if (err) {
+             goto End;
+        }
+
+        /* copy min(orderSizeBytes, hashDigestSize) bytes from HASH result to order Q buffer:
+         * steps 5,6,7 of sec.A.1.1.2 process: U = HASH(seed) mod 2^(OrdSizeInBits-1) */
+        if(orderSizeBytes >= hashDigestSize) {
+            CC_PalMemCopy((uint8_t*)pOrder + orderSizeBytes - hashDigestSize, (uint8_t*)pHashData, hashDigestSize);
+        } else {
+            CC_PalMemCopy((uint8_t*)pOrder, (uint8_t*)pHashData + hashDigestSize - orderSizeBytes, orderSizeBytes);
+        }
+        /* set MS and LS bits of order Q to 1 */
+        pOrder[0] |= 0x80000000;
+        pOrder[orderSizeWords - 1] |= 0x00000001;
+
+        /* convert pOrder to LE words array for primality testing */
+        CHECK_ERROR(CC_CommonConvertMsbLsbBytesToLswMswWords(
+                               pOrder, orderSizeBytes, (uint8_t*)pOrder, orderSizeBytes));
+
+        /* test primality of Order */
+        CHECK_ERROR(RsaPrimeTestCall(pRndContext, pOrder, orderSizeWords,
+                             countRabMilTests, &isPrime, pTmp1,
+                             (CCFfcPrimeTestMode_t)CC_FFC_PRIME_TEST_MODE));
+        if(isPrime) {
+            goto End;
+        } else {
+            /* if seed is given, but Q is not prime, then return an error */
+            CHECK_AND_SET_ERROR((generateSeed == CC_FFC_USE_GIVEN_SEED) && (isPrime == 0),
+                        CC_FFC_DOMAIN_GENERATION_FAILURE_ERROR);
+        }
+    }
+
+
+    /* End of function */
+  End:
+    if(err) {
+        CC_PalMemSetZero(pDomain, sizeof(CCFfcDomain_t));
+        CC_PalMemSetZero(pTmpBuff, sizeof(CCFfcDomainTmpBuff_t));
+    }
+
+    return err;
+
+} /* End of FfcFips186v4FindOrderQ */
+
+
+/**
+ * The function finds prime Order Q for FFC Domain generation according to FIPS 186-4 sec.A.i.2.
+ *
+ * Note: Sizes in bytes of P, Q, HASH should be multiple of 4.
+ *       Size in words of pTmp buffer should be not less than
+ *          (2MaxModSize + MaxHashSize + 2MaxOrdeSize + 2).
+ */
+static
+CCError_t FfcFips186v4FindPrimeP(
+            CCFfcDomain_t *pDomain,           /* [in/out]  pointer to FFC Domain. */
+            CCRndContext_t *pRndContext,      /* [in] context defining used random function and state. */
+            int8_t *pIsPrime,                 /* [out] pointer to indication, that prime is found. */
+            CCFfcDomainTmpBuff_t *pTmpBuff)   /*!< [in] pointer to FFC Domain temp buffer structure. */{
+
+    /* FUNCTION DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t err = CC_OK;
+
+    /* primality flag (if prime, then isPrime = 1, else 0 ) */
+    uint32_t  j, offset;
+    uint32_t  counter, countBlocks;
+    uint32_t  primeSizeBytes, primeSizeWords, remainBytes;
+    uint32_t *pOrder, *pPrimeP; /*LE words */
+    uint32_t *pCurrPtr;
+    uint32_t  orderSizeBytes, orderSizeWords;
+    uint8_t  *pHashInput; /*BE bytes array*/
+    uint32_t  seedSizeBytes, hashDigestSize;
+    uint32_t  countRabMilTests;   /*count of Rabin-Miller tests*/
+    /* temp buffers */
+    uint32_t *p2Q, *pRemC, *pTmp1;
+    uint32_t  addValue;
+    CCHashOperationMode_t hashMode;
+    const mbedtls_md_info_t *md_info=NULL;
+
+    /* minimal check of some parameters */
+    CHECK_AND_SET_ERROR(pDomain == NULL, CC_FFC_DOMAIN_INVALID_DOMAIN_PTR_ERROR);
+    CHECK_AND_SET_ERROR(pRndContext == NULL, CC_FFC_DOMAIN_INVALID_RND_CTX_PTR_ERROR);
+
+    /* INITIALIZATION  */
+
+    pPrimeP = pDomain->prime;
+    primeSizeWords = pDomain->modLenWords;
+    primeSizeBytes = primeSizeWords*CC_32BIT_WORD_SIZE;
+    pOrder = pDomain->order;
+    orderSizeBytes = pDomain->ordLenWords*CC_32BIT_WORD_SIZE;
+    orderSizeWords = orderSizeBytes;
+    seedSizeBytes = pDomain->seedSizeBytes;
+    hashDigestSize = pDomain->hashDigestSize;
+
+    /* set pointers to temp buffers. Total max size of pTmp buffer in words:
+     * (2MaxModSize + MaxHashSize + 2MaxOrdeSize + 2) =  194 words for
+     * ModSz=2048bit and OrdSz=256bit, or 258 words for ModSz=3072bit */
+    p2Q = (uint32_t*)&pTmpBuff->TmpBuff[0]; /*buffer for 2*Q, size=orderSizeWords+1. */
+    pRemC = p2Q + orderSizeWords+1; /*buffer for remainder C of size = orderSizeWords+1.*/
+    pHashInput = (uint8_t*)(pRemC + orderSizeWords+1); /*buffer for hash-input data of size = seedSizeWords.*/
+    pTmp1 = pRemC + orderSizeWords+1 + seedSizeBytes/CC_32BIT_WORD_SIZE; /*buffer of size = 3*primeSizeWords.*/
+
+    /* n = count of full HASH blocks in prime P. */
+    countBlocks = primeSizeBytes / hashDigestSize; /* n */
+    remainBytes = primeSizeBytes % hashDigestSize; /*not full block size*/
+
+
+    /* FUNCTION  LOGIC */
+
+    *pIsPrime = CC_FALSE;
+    offset = 1;
+
+    /* get count of R-M tests */
+    CHECK_ERROR(FfcGetCountOfRabMilTests(&countRabMilTests, primeSizeBytes*CC_BITS_IN_BYTE));
+
+    /* get HASH related parameters */
+    CHECK_ERROR(FfcGetHashMode(&hashMode, NULL/*pHkdfHashMode*/, NULL/*pBlockSize*/, NULL, pDomain->ffcHashMode/*in*/));
+
+    /* calculate p2Q = 2*Q with setting carry into MS word */
+    p2Q[orderSizeWords] = CC_CommonAdd2vectors(pOrder, pOrder, orderSizeWords, p2Q/*res*/);
+    /* copy seed into hashing buffer */
+    CC_PalMemCopy(pHashInput, pDomain->seed, seedSizeBytes);
+
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+    if (NULL == md_info) {
+         err = CC_FFC_DOMAIN_GENERATION_FAILURE_ERROR;
+         goto End;
+    }
+
+    /* try to generate prime P up to 4*primeSizeInBits times; if not successes,
+     * then return an error (sec. A.1.1.2, process: 11). */
+    for(counter = 0; counter < 4*primeSizeBytes*CC_BITS_IN_BYTE; counter++) {
+        /*  Create primeP using HASH and Seed sec.A.1.1.2.  */
+        pCurrPtr = pPrimeP;
+
+        for(j = 0; j < countBlocks; j++) {
+            addValue = offset + j;
+            FfcAddValueToMsbLsbBytesArray(pHashInput, addValue, seedSizeBytes/CC_32BIT_WORD_SIZE);
+
+            err = mbedtls_md(md_info, pHashInput, seedSizeBytes, (unsigned char*)pCurrPtr);
+            if (err) {
+                    goto End;
+            }
+
+            pCurrPtr += hashDigestSize/CC_32BIT_WORD_SIZE;
+        }
+
+        if(remainBytes > 0) {
+            addValue = offset + j;
+            FfcAddValueToMsbLsbBytesArray(pHashInput, addValue, seedSizeBytes/CC_32BIT_WORD_SIZE);
+
+            err = mbedtls_md(md_info, pHashInput, seedSizeBytes, (unsigned char*)pRemC); /*temporary use pRemC*/
+            if (err) {
+                    goto End;
+            }
+
+            CC_PalMemCopy((uint8_t*)pCurrPtr, (uint8_t*)pRemC, remainBytes);
+        }
+
+        /* zero remaining (redundant) last bytes */
+
+        /* set MsBit of prime to 1 */
+        ((uint8_t*)pPrimeP)[0] |= 0x80;
+
+        /*zero additional words for carry */
+        pPrimeP[primeSizeWords] = 0;
+        p2Q[orderSizeWords] = 0;
+
+            /* convert prime to LE words */
+        CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(pPrimeP, primeSizeWords);
+
+            /* calculate P so that P = 1 mod(2*Q) */
+        /*------------------------------------*/
+            /* calculate remainder C = P % 2Q */
+        CHECK_ERROR(PkiLongNumDiv(pPrimeP/*numerator*/, primeSizeWords, p2Q/*divider*/,
+                orderSizeWords+1, pRemC/*remainder C*/, pTmp1/*DivRes - not used*/));
+
+        /* P = P-(C-1):  if P odd then C=C-1, else P=P+1 and then P=P-C */
+        if((pPrimeP[0] & 1UL) == 1) {
+            pRemC[0]--;
+        } else {
+            pPrimeP[0]++;
+        }
+        CC_CommonSubtractUintArrays(pPrimeP, pRemC, primeSizeWords, pPrimeP/*res*/);
+
+        /* if P>2^(L-1) then test prime, else increase offset and repeat generation */
+        if((pPrimeP[primeSizeWords-1] & 0x80000000) != 0) {
+            CHECK_ERROR(RsaPrimeTestCall(pRndContext, pPrimeP, primeSizeWords, countRabMilTests,
+                    pIsPrime, pTmp1, (CCRsaDhPrimeTestMode_t)CC_FFC_PRIME_TEST_MODE));
+
+            if(*pIsPrime == 1) { /* the prime is found */
+                /* set counter into Domain */
+                pDomain->genCounter = counter;
+                goto End;
+            }
+        }
+
+        /* repeat generation of prime P with new offset*/
+        offset += (countBlocks+1);
+    }
+
+        /* if reached this row, then the function exits for further
+         * continuing generation of new Q and P */
+
+        /* End of function */
+  End:
+
+    if(err) {
+        CC_PalMemSetZero(pDomain, sizeof(CCFfcDomain_t));
+        CC_PalMemSetZero(pTmpBuff, sizeof(CCFfcDomainTmpBuff_t));
+    }
+
+    return err;
+
+} /* End of FfcFips186v4FindPrimeP */
+
+
+/**
+ * The function creates FFC sub-group Generator Q according to FIPS 186-4 sec.A.2.3
+ *
+ * Note: Sizes in bytes of P, Q, HASH should be multiple of 4.
+ *       Size in words of pTmp buffer should be not less than
+ *          (2MaxModSize + MaxHashSize + 2MaxOrdeSize + 2).
+ */
+static
+CCError_t FfcFips186v4CreateGenerator(
+            CCFfcDomain_t *pDomain,          /* [in/out]  pointer to FFC Domain. */
+            CCRndContext_t *pRndContext,     /* [in] context defining used random function and state. */
+            uint8_t index,                   /* [in] index of FFC Generator, allowing to generate different
+                                                Generators for the same FFC parameters Prime P and Order Q. */
+            CCFfcDomainTmpBuff_t *pTmpBuff)  /*!< [in] pointer to FFC Domain temp buffer structure. */{
+    /* FUNCTION DECLARATIONS */
+
+
+    CCError_t err = CC_OK;
+    uint16_t  count = 0; /*loop counter*/
+    size_t    primeSizeBytes;
+    uint32_t  *pPrimeP; /*LE words */
+    size_t    hashDataSizeBytes;
+    uint8_t  *pIndex;/* point on index inside the hashData*/
+    uint8_t   ggen[4] = {0x67,0x67,0x65,0x6E};
+    uint32_t  one = 1;
+    CCCommonCmpCounter_t cmp;
+    CCHashOperationMode_t hashMode;
+    const mbedtls_md_info_t *md_info=NULL;
+
+    /* pointers to temp buffers: for variables E, U, W,
+     * named in the said standard sec;                       */
+    uint32_t  *pDivResE/*e*/, *pHashDataU/*u*/, *pHashResW/*W*/, *pTmp1/*dummy*/;
+
+    CHECK_AND_SET_ERROR((pDomain == NULL), CC_FFC_DOMAIN_INVALID_DOMAIN_PTR_ERROR);
+    CHECK_AND_SET_ERROR((pRndContext == NULL), CC_FFC_DOMAIN_INVALID_RND_CTX_PTR_ERROR);
+    CHECK_AND_SET_ERROR((pDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG),
+                        CC_FFC_DOMAIN_VALIDATION_TAG_ERROR);
+
+        /* FUNCTION  LOGIC */
+
+    primeSizeBytes = pDomain->modLenWords * CC_32BIT_WORD_SIZE;
+    pPrimeP = pDomain->prime;
+
+    /* set pointers and calculate W = HASH of U */
+
+    pHashResW = (uint32_t*)&pTmpBuff->TmpBuff[0]; /* buffer size CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_BYTES + 12 */
+    pHashDataU = pHashResW + pDomain->hashDigestSize / CC_32BIT_WORD_SIZE;
+
+
+    /* repeat generation while count != 0 */
+    count = 1;
+
+    while(count != 0) {
+        /*-----------------------------------------*/
+        /* set U data = Seed||"ggen"||index||count */
+        /*-----------------------------------------*/
+        pIndex = (uint8_t*)pHashDataU; /*now used as temporary pointer*/
+        CC_PalMemCopy(pIndex, pDomain->seed, pDomain->seedSizeBytes);
+        pIndex += pDomain->seedSizeBytes;
+        CC_PalMemCopy(pIndex, ggen, sizeof(ggen));
+        pIndex += sizeof(ggen);
+        *pIndex = index;
+        /* copy counter after address, pointed by pIndex*/
+        pIndex[1] = count & 0xFF; pIndex[2] = (count>>8) & 0xFF;
+        hashDataSizeBytes = pDomain->seedSizeBytes + sizeof(ggen) + sizeof(count) + 1/*index*/;
+
+        /* get HASH related parameters */
+        CHECK_ERROR(FfcGetHashMode(&hashMode, NULL/*pHkdfHashMode*/, NULL/*pBlockSize*/, NULL, pDomain->ffcHashMode/*in*/));
+
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+        if (NULL == md_info) {
+             err = CC_FFC_DOMAIN_GENERATION_FAILURE_ERROR;
+             goto End;
+        }
+
+        /* calculate W = HASH(U) */
+        err = mbedtls_md(md_info, (uint8_t*)pHashDataU, hashDataSizeBytes, (unsigned char *)pHashResW);
+        if (err) {
+                goto End;
+        }
+
+        /* convert Hash result to LE words array */
+        CC_CommonConvertMsbLsbBytesToLswMswWords(pHashResW, pDomain->hashDigestSize,
+                                     (uint8_t*)pHashResW, pDomain->hashDigestSize);
+
+        /*--------------------------*/
+        /*   calculate  e = P / Q   */
+        /*--------------------------*/
+
+        pDomain->prime[primeSizeBytes-1] ^= 1; /* temporary: P = p-1;*/
+        pDivResE = pHashDataU; /* pHashDataU not used now */
+        pTmp1 = pDivResE + pDomain->ordLenWords;
+
+        /* e = (p-1) / q */
+        CHECK_ERROR(PkiLongNumDiv(pPrimeP/*numerator*/, pDomain->modLenWords,
+                      pDomain->order/*divider*/, pDomain->ordLenWords,
+                      pTmp1/*remainder C*/, pDivResE/*DivRes - not used*/));
+        pDomain->prime[primeSizeBytes-1] ^= 1; /*reset: P = P+1*/
+
+        /* calculate Generator g = W^e mod P */
+        err = PkiExecModExpLeW(
+                pDomain->genG, /*G res*/
+                pHashResW, /*W*/
+                pDomain->ordLenWords, /*W size*/
+                &pDomain->prime[0],  /*prime P - modulus*/
+                pDomain->modLenWords*CC_BITS_IN_32BIT_WORD, /*P size in bits*/
+                pDivResE, /*E exponent*/
+                pDomain->ordLenWords); /* Q size in words*/
+
+        /* check error */
+        if (err != CC_OK) {
+            goto End;
+        }
+
+        /* check that g > 1, else repeat generation with count++. */
+        cmp = CC_CommonCmpLsWordsUnsignedCounters(pDomain->genG, pDomain->modLenWords, &one, sizeof(one));
+        if(cmp == CC_COMMON_CmpCounter1GreaterThenCounter2) {
+            /* set results into Domain */
+            pDomain->indexOfGenerator = index;
+            break;
+        }
+        count++;
+    }
+
+        /* End of function */
+  End:
+
+    if(err) {
+        CC_PalMemSetZero(pDomain, sizeof(CCFfcDomain_t));
+        CC_PalMemSetZero((uint8_t*)pTmpBuff, sizeof(CCFfcDomainTmpBuff_t));
+    }
+
+        return err;
+
+} /* End of FfcFips186v4FindPrimeP */
+
+
+/** The function performs preliminary checking of Domain generation input parameters.
+ *
+ *   This checking is related only to pointers and sizes of input parameters in
+ *   accordance with  NIST SP 56A rev.2, referring to FIPS 184-4 standards, but not
+ *   means standard full validation of them.
+ *
+ */
+static CCError_t FfcDomainMinCheckInput(
+                CCFfcDomain_t *pDomain,          /*!< [out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,     /*!< [in] random generation function context. */
+                size_t primeSizeBits,            /*!< [in] size of domain's prime modulus in bits (see requirements above). */
+                size_t orderSizeBits,            /*!< [in] size of domain's sub-group order in bits. The size should meet
+                                                           to one of allowed sizes according given. */
+                uint8_t *pSeed,                  /*!< [in] optional pointer to the seed for domain generation and validation.
+                                                           If Seed should be generated internally, then Seed pointer and size
+                                                           should be zero. */
+                size_t seedSizeBytes,            /*!< [in] optional seed size in bytes */
+                CCFfcGenerateSeed_t generateSeed,/*!< [in] enumerator indicates to generate a new domain Seed. */
+                uint32_t genCounter,             /*!< [in] optional value of count of iterations, required for generation
+                               of FFC Domain from given Seed. If Seed is given, and actually calculated
+                               count is not equal to given, then the function returns an error.
+                               If a new Seed is required (i.e. the counter is not known), then input
+                               genCounter should be set 0. */
+                CCFfcParamSetId_t ffcParamSetId, /*!< [in] enumerator, defining the set of FFC domain parameters
+                                                           according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t ffcHashMode,   /*!< [in] enumerator ID of used SHAXXX HASH mode, supported by the product.
+                                                           Note: HASH SHA1 function may be used only with SA set of domain parameters
+                                                           (sec. 5.8.1, tab.6); with other sets the function returns an error. */
+               uint8_t indexOfGener             /*!< [in] index of FFC Generator, allowing to generate different FFC generators with
+                                                   the same FFC parameters (Prime and Order), existed in the domain. */
+)
+{
+    /* The return error identifier */
+    CCError_t err = CC_OK;
+
+    uint32_t hashMinLen;
+    uint32_t primeSizeBytes, orderSizeBytes;
+    CCHashOperationMode_t hashMode;
+
+    /* Step 1. Check input parameters */
+    /*------------------------------- */
+    CHECK_AND_SET_ERROR((pDomain == NULL), CC_FFC_DOMAIN_INVALID_DOMAIN_PTR_ERROR);
+    CHECK_AND_SET_ERROR((pRndContext == NULL), CC_RND_CONTEXT_PTR_INVALID_ERROR);
+    CHECK_AND_SET_ERROR((pRndContext->rndGenerateVectFunc == NULL), CC_FFC_DOMAIN_INVALID_RND_FUNCTION_PTR_ERROR);
+    /* check enumerators */
+    CHECK_AND_SET_ERROR(ffcParamSetId >= CC_FFC_PARAMS_SET_NUM_OFF_MODE, CC_FFC_DOMAIN_INVALID_HASH_MODE_ERROR);
+    CHECK_AND_SET_ERROR(ffcParamSetId >= CC_FFC_PARAMS_SET_NUM_OFF_MODE, CC_FFC_DOMAIN_INVALID_HASH_MODE_ERROR);
+    CHECK_AND_SET_ERROR(ffcParamSetId >= CC_FFC_PARAMS_SET_NUM_OFF_MODE, CC_FFC_DOMAIN_INVALID_SEED_GENERATION_MODE_ERROR);
+
+    /* check seed and generation counter */
+    if((generateSeed == CC_FFC_GENERATE_NEW_SEED) || (generateSeed == CC_FFC_SEED_NOT_USED)) {
+    /* case that the seed and generation counter not known and not given. */
+    CHECK_AND_SET_ERROR(pSeed != NULL, CC_FFC_DOMAIN_SEED_IS_NOT_REQUIRED_ERROR);
+    CHECK_AND_SET_ERROR(genCounter != 0, CC_FFC_DOMAIN_GEN_COUNTER_NOT_VALID_ERROR);
+    } else {
+        /* case of actually used input of seed and counter */
+        CHECK_AND_SET_ERROR(pSeed == NULL, CC_FFC_DOMAIN_INVALID_SEED_PTR_ERROR);
+        CHECK_AND_SET_ERROR(genCounter == 0, CC_FFC_DOMAIN_GEN_COUNTER_NOT_VALID_ERROR);
+    }
+
+    /* get HASH mode and sizes, FFC sizes set and insert them into Domain. */
+    CHECK_AND_SET_ERROR(FfcGetHashMode(&hashMode, NULL/*pHkdfHashMode*/,
+                &pDomain->hashBlockSize, &pDomain->hashDigestSize, ffcHashMode/*in*/),
+                          CC_FFC_DOMAIN_INVALID_HASH_MODE_ERROR);
+    CHECK_AND_SET_ERROR(FfcGetDomainSizes(NULL/*pMaxSecurStrength*/, &primeSizeBytes,
+                          &orderSizeBytes, &hashMinLen, ffcParamSetId/*in*/),
+                                  CC_FFC_DOMAIN_INVALID_SIZES_SET_ID_ERROR);
+
+    /* check that FFC Prime and Order sizes are meet to given ffcParamSetId */
+    CHECK_AND_SET_ERROR(primeSizeBits != primeSizeBytes*CC_BITS_IN_BYTE, CC_FFC_DOMAIN_INVALID_PRIME_SIZE_ERROR);
+    CHECK_AND_SET_ERROR(orderSizeBits != orderSizeBytes*CC_BITS_IN_BYTE, CC_FFC_DOMAIN_INVALID_ORDER_SIZE_ERROR);
+
+    /* check Hash and Seed sizes according to required FFC parameters Set ID */
+    CHECK_AND_SET_ERROR(pDomain->hashDigestSize < hashMinLen, CC_FFC_DOMAIN_INVALID_LOW_HASH_SIZE_ERROR);
+    CHECK_AND_SET_ERROR((seedSizeBytes < orderSizeBytes) || (seedSizeBytes > CC_FFC_DOMAIN_SEED_MAX_SIZE_IN_BYTES),
+                 CC_FFC_DOMAIN_INVALID_SEED_SIZE_ERROR);
+
+    /* set other parameters into FFC Domain */
+    pDomain->ffcParamSetId = ffcParamSetId;
+    pDomain->ffcHashMode = ffcHashMode;
+    pDomain->indexOfGenerator = indexOfGener;
+    pDomain->seedSizeBytes = seedSizeBytes;
+    pDomain->modLenWords = primeSizeBytes/CC_32BIT_WORD_SIZE;
+    pDomain->ordLenWords = orderSizeBytes/CC_32BIT_WORD_SIZE;
+    pDomain->seedSizeBytes = seedSizeBytes;
+    pDomain->genCounter = genCounter;
+
+    /* End of function */
+End:
+
+    return err;
+
+}
+
+
+
+/***********************************************************************/
+/*!
+@brief This function generates FFC domain parameters according to NIST SP 56A rev.2, referring to FIPS 184-4 standard.
+\par<ol><li>
+<li> The function generates FFC Domain from given Seed or generates a new random Seed and then the Domain, depending on
+geneSeedId value: 0,1 (see type definition). </li>
+<li> The function calculates prime modulus P, subgroup generator G with order Q using Seed and HASH function and
+parameters and then compares count of performed iterations with given right value. In other words, the function recalculates
+previously generated FFC domain from given Seed (sections SP 56A rev.2 5.5.1.1 and FIPS 184-4 A.1.1.2, A.1.1.3, A.2.3). </li>
+<li> The function allows generation domains with approved set of parameters sizes (SP 56A rev.2 5.5.1.1), given by
+enumerator CCFfcParamSetId_t. </li>
+<li> The function validates received FFC domain parameters and sets them into Domain structure. </li></ol>
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+ */
+//static
+CCError_t FfcFips186v4GenerateDomain(
+                                CCFfcDomain_t *pDomain,          /*!< [out] pointer to  FFC Domain structure. */
+                                CCRndContext_t *pRndContext,     /*!< [in] random generation function context. */
+                                size_t primeSizeBits,            /*!< [in] size of domain's prime modulus in bits (see requirements above). */
+                                size_t orderSizeBits,            /*!< [in] size of domain's sub-group order in bits. The size should meet
+                                                                           to one of allowed sizes according given. */
+                                uint8_t *pSeed,                  /*!< [in] optional pointer to the seed for domain generation and validation.
+                                                                           If Seed should be generated internally, then Seed pointer and size
+                                                                           should be zero, because the Seed will be saved in the domain. */
+                                size_t seedSizeBytes,            /*!< [in] seed size in bytes, should meets to given ffcParamSetId. */
+                                CCFfcGenerateSeed_t generateSeed,/*!< [in] enumerator indicates to generate a new domain Seed. */
+                                uint32_t genCounter,             /*!< [in] optional value of count of iterations, required for generation
+                                                                       of FFC Domain from given Seed. If Seed is given, and actually calculated
+                                                                       count is not equal to given, then the function returns an error.
+                                                                       If a new Seed is required (i.e. the counter is not known), then input
+                                                                       genCounter should be set 0. */
+                                CCFfcParamSetId_t ffcParamSetId, /*!< [in] enumerator, defining the set of FFC domain parameters
+                                                                      according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                                CCFfcHashOpMode_t ffcHashMode,   /*!< [in] enumerator ID of used SHAXXX HASH mode, supported by the product.
+                                                                      Note: HASH SHA1 function may be used only with SA set of domain parameters
+                                                                      (sec. 5.8.1, tab.6); with other sets the function returns an error. */
+                                uint8_t generIndex,              /*!< [in] index of FFC Generator, allowing to generate different FFC generators with
+                                                                      the same FFC parameters prime P and Order Q, existed in the domain. */
+                                CCFfcDomainTmpBuff_t *pTmpBuff   /*!< [in] pointer to FFC Domain temp buffer structure. */
+)
+{
+
+    /* FUNCTION DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t err = CC_OK;
+    int8_t isPrime; /* indication, that prime is found (0, 1). */
+
+
+    /* FUNCTION  LOGIC */
+
+    /* preliminary checking of input pointers and sizes according to given ffcParamSetId
+     * and ffcHashMode; save checked data into Domain structure */
+    CHECK_ERROR(FfcDomainMinCheckInput(pDomain, pRndContext, primeSizeBits, orderSizeBits,
+                                  pSeed, seedSizeBytes, generateSeed, genCounter,
+                                  ffcParamSetId, ffcHashMode, generIndex));
+        /* check temp buffer */
+    CHECK_AND_SET_ERROR((pTmpBuff == NULL), CC_FFC_DOMAIN_INVALID_ARGUMENT_PTR_ERROR);
+
+    /* main loop of FFC domain generation:
+     * !!! Note: the loop, according to Standard algorithm, is not limited
+     * therefore we need insert an  WatchDog timer. */
+    while(1) {
+        /* generate FFC Order Q */
+        CHECK_ERROR(FfcFips186v4FindOrderQ(pDomain, pRndContext, generateSeed, pTmpBuff));
+        /* generate FFC Prime modulus P */
+        CHECK_ERROR(FfcFips186v4FindPrimeP(pDomain, pRndContext, &isPrime, pTmpBuff));
+
+        /* check that both P,Q are prime */
+        if(isPrime == 1) {
+            break;
+        }
+    }
+
+    /* if the Seed is given, then check iterations counter  */
+    CHECK_AND_SET_ERROR((generateSeed == CC_FFC_USE_GIVEN_SEED) && (pDomain->genCounter != genCounter),
+                CC_FFC_DOMAIN_GENERATION_FAILURE_ERROR);
+
+    /* create FFC Generator with given Index */
+    CHECK_ERROR(FfcFips186v4CreateGenerator(pDomain,  pRndContext, generIndex, pTmpBuff));
+
+    /* End of function */
+  End:
+    if(err) {
+        CC_PalMemSetZero(pDomain, sizeof(CCFfcDomain_t));
+        CC_PalMemSetZero(pTmpBuff, sizeof(CCFfcDomainTmpBuff_t));
+    }
+
+        return err;
+
+}
+
+
+
+
+
+/*******************************************************************************************/
+/*!
+@brief This function generates FFC domain parameters according to NIST SP 56A rev.2, referring to FIPS 184-4 standard.
+\par<ol><li>
+<li> The function generates FFC Domain from given Seed and iterations count and sets them into Domain structure.
+If actual count of iterations is not equalled to given value, then the function returns an error. </li>
+<li> The function calculates prime modulus P, subgroup generator G with order Q using Seed and given Generator
+index, allowing to generate different FFC generators with same P and Q, according to SP 56A rev.2 sec.5.5.1.1
+and FIPS 184-4 A.1.1.2, A.2.3. </li>
+<li> The function allows generation domains only for approved set of parameters sizes (SP 56A rev.2 5.5.1.1),
+given by enumerator ID of type CCFfcParamSetId_t. </li></ol>
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ffc_domain_error.h.
+
+*/
+CEXPORT_C CCError_t CC_FfcGenerateDomainFromSeed(
+                CCFfcDomain_t *pDomain,        /*!< [out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,   /*!< [in] random generation function context. */
+                size_t primeSizeBits,          /*!< [in] size of domain's prime modulus in bits (see requirements above). */
+                size_t orderSizeBits,          /*!< [in] size of domain's sub-group order in bits (see requirements above). */
+                uint8_t  *pSeed,               /*!< [in] pointer to the seed for domain generation and validation; */
+                size_t   seedSizeBytes,        /*!< [in] seed size in bytes */
+                uint32_t genCounter,           /*!< [in] exact value of count of main loop iterations, required for generation
+                                     FFC Domain from given Seed. If actual count is not equal to given,
+                                     then the function returns an error. */
+                CCFfcParamSetId_t ffcParamSetId,/*!< [in] enumerator, defining the set of FFC domain parameters
+                                     according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t ffcHashMode, /*!< [in] enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode may be
+                                     used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint8_t generIndex,            /*!< [in] an index of FFC Generator,  allowing to generate different FFC generators with
+                                    the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainTmpBuff_t *pTmpBuff /*!< [in] pointer to FFC Domain temp buffer structure. */
+)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+        /* call generation function */
+        err = FfcFips186v4GenerateDomain(
+            pDomain, pRndContext, primeSizeBits, orderSizeBits,
+                        pSeed, seedSizeBytes, CC_FFC_USE_GIVEN_SEED, genCounter,
+                        ffcParamSetId, ffcHashMode, generIndex, pTmpBuff);
+
+        if(err == CC_OK) {
+            pDomain->validTag = CC_FFC_DOMAIN_VALIDATION_TAG;
+        }
+
+        return err;
+}
+
+
+/*******************************************************************************************/
+/*!
+@brief This function generates FFC Domain parameters including new Seed Seed according to
+ NIST SP 56A rev.2 with referring to FIPS 184-4 standard.
+\par<ol><li>
+<li> The function generates a new Seed, calculates FFC Domain parameters and sets them into Domain. </li>
+<li> The function calculates prime modulus P, subgroup generator G with order Q using Seed and given Generator
+index, allowing to generate different FFC generators with same P and Q, according to SP 56A rev.2 sec.5.5.1.1
+and FIPS 184-4 A.1.1.2, A.2.3. </li>
+<li> The function allows generation Domain only for approved set of parameters sizes (SP 56A rev.2 5.5.1.1),
+given by enumerator ID of type CCFfcParamSetId_t. </li></ol>
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ffc_domain_error.h.
+
+*/
+CEXPORT_C CCError_t CC_FfcGenerateDomainAndSeed(
+                CCFfcDomain_t *pDomain,         /*!< [out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,    /*!< [in] random generation function context. */
+                size_t primeSizeBits,           /*!< [in] size of domain's prime modulus in bits (see requirements above). */
+                size_t orderSizeBits,           /*!< [in] size of domain's sub-group order in bits (see requirements above). */
+                size_t seedSizeBytes,           /*!< [in] required size of the seed in bytes; it must be not less than
+                                       HASH security strength, defined in given ffcParamsSet. */
+                CCFfcParamSetId_t ffcParamSetId,/*!< [in] enumerator, defining the set of FFC domain parameters
+                                          according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t ffcHashMode,  /*!< [in] enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode may be
+                                      used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint8_t generIndex,             /*!< [in] an index of FFC Generator, allowing to generate different FFC generators with
+                                          the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainTmpBuff_t *pTmpBuff  /*!< [in] pointer to FFC Domain temp buffer structure. */
+)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+        /* call generation function */
+        err = FfcFips186v4GenerateDomain(
+            pDomain, pRndContext, primeSizeBits, orderSizeBits, NULL/*pSeed*/,
+            seedSizeBytes, CC_FFC_GENERATE_NEW_SEED, 0/*generCounter*/,
+                        ffcParamSetId, ffcHashMode, generIndex, pTmpBuff);
+
+        if(err == CC_OK) {
+            pDomain->validTag = CC_FFC_DOMAIN_VALIDATION_TAG;
+        }
+
+        return err;
+}
+
+//static
+//CCError_t
+
+/*******************************************************************************************/
+/*!
+@brief The function validates received FFC domain parameters and sets them into Domain structure.
+<ol><li> Validation of performed according to NIST SP 56A rev.2, sec. 5.5.2 and to FIPS 184-4 standard. </li>
+</li> If optional parameters (Seed and pgenCounter) are given, then the function performs full validation by generation
+primes P,Q from the given Seed and compares calculated and received parameters according to the FIPS 184-4, A.1.1.3. </li>
+</li> Generator G is validated according to sec. A.2.3. </li>
+</li> If optional parameters pSeed, seedSize, pgenCounter are zero, and the user explicitly sets validation mode to
+"Trusted Data", then the function performs only checking of pointers, sizes and some relations between parameters. <li>.
+</li> All  input byte-arrays should be set with big endianness order of bytes, i.e. MS Byte is a leftmost one. </li></ol>
+@return CC_OK on success.
+@return A non-zero value on failure, as defined in cc_dh_error.h, cc_rnd_error.h.
+ */
+CEXPORT_C CCError_t CC_FfcValidateAndImportDomain(
+                CCFfcDomain_t *pDomain,          /*!< [out] optional (used on Full Validation mode only), pointer to FFC Domain. */
+                CCRndContext_t *pRndContext,     /*!< [in] optional (used on Full Validation mode only), random generation
+                                                           function context. */
+                uint8_t *pPrime,                 /*!< [in] pointer to prime modulus of the finite field (P). */
+                size_t  primeSizeBits,           /*!< [in] prime P size in bits. */
+                uint8_t *pOrder,                 /*!< [in] pointer to the order Q of the generator. */
+                size_t  orderSizeBits,           /*!< [in] order size in bits. */
+                uint8_t *pGenerator,             /*!< [in] pointer to generator G of subgroup of FFC. */
+                size_t  generSizeBytes,          /*!< [in] generator G size in bytes (see note bellow). */
+                uint8_t *pSeed,                  /*!< [in] optional (used on Full Validation mode only), pointer to the Seed,
+                                                           if the Seed is not given, then should be set to NULL. */
+                size_t  seedSizeBytes,           /*!< [in] optional size of Seed in bytes; if Seed not given, then
+                                       should be set to 0. */
+                CCFfcParamSetId_t ffcParamSetId, /*!< [in] enumerator, defining the set of FFC domain parameters
+                                       according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t ffcHashMode,   /*!< [in] enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode may be
+                                       used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint32_t genCounter,             /*!< [in] optional, counter of main iterations loop, performed during
+                                       domain generation with Seed. */
+                uint8_t generIndex,              /*!< [in] an index of FFC Generator, allowing to generate different FFC generators with
+                                                          the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainValidMode_t validMode,/*!< [in] enumerator, defining validation mode of of domain parameters:
+                                       "full" (approved by FIPS standard), "partial"
+                                       and "trusted" (validated previously); using of both second
+                                       modes is not approved by standards and is fully on the user
+                                       responsibility. */
+                CCFfcDomainTmpBuff_t *pTmpBuff   /*!< [in] optional pointer to FFC Domain temp buffer structure. Used only
+                                                           on Full validation mode, on Trusted mode may be set to NULL. */
+
+)
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t err = CC_OK;
+    size_t primeSizeBytes, orderSizeBytes;
+
+
+    /*      INITIALIZATIONS       */
+
+    primeSizeBytes = primeSizeBits/CC_BITS_IN_BYTE;
+    orderSizeBytes = orderSizeBits/CC_BITS_IN_BYTE;
+
+    /* check parameters */
+    CHECK_AND_SET_ERROR((pGenerator == NULL) != (generSizeBytes == 0), CC_FFC_DOMAIN_INVALID_OPTIONAL_PARAM_ERROR);
+    CHECK_AND_SET_ERROR(validMode >= CC_FFC_DOMAIN_VALIDAT_NUM_OFF_MODE, CC_FFC_DOMAIN_INVALID_VALIDAT_MODE_ERROR);
+
+    /*----------------------------------------------------------------------------*
+     *                 case of full validation mode                               *
+     *--------------------------------------------------------------------------- */
+    if(validMode == CC_FFC_DOMAIN_VALIDAT_FULL_MODE) {
+        CHECK_AND_SET_ERROR(pSeed == NULL, CC_FFC_DOMAIN_INVALID_SEED_PTR_ERROR);
+
+        /* generate Domain from given Seed. */
+        CHECK_ERROR(FfcFips186v4GenerateDomain(
+            pDomain, pRndContext, primeSizeBits, orderSizeBits, pSeed, seedSizeBytes,
+            CC_FFC_USE_GIVEN_SEED, genCounter, ffcParamSetId, ffcHashMode, generIndex, pTmpBuff));
+
+        /* compare input data with generated parameters */
+        CHECK_AND_SET_ERROR(FfcCmpBeBytes2LeWordsBigNum(pPrime, pDomain->prime, primeSizeBytes/CC_32BIT_WORD_SIZE),
+                    CC_FFC_DOMAIN_PRIME_NOT_VALID_ERROR);
+        CHECK_AND_SET_ERROR(FfcCmpBeBytes2LeWordsBigNum(pOrder, pDomain->order, orderSizeBytes/CC_32BIT_WORD_SIZE),
+                    CC_FFC_DOMAIN_ORDER_NOT_VALID_ERROR);
+//      CHECK_AND_SET_ERROR(CC_PalMemCmp(pSeed, pDomain->seed, orderSizeBytes/CC_32BIT_WORD_SIZE),
+//                  CC_FFC_DOMAIN_SEED_IS_NOT_VALID_ERROR);
+        CHECK_AND_SET_ERROR(genCounter != pDomain->genCounter, CC_FFC_DOMAIN_GEN_COUNTER_NOT_VALID_ERROR);
+
+        /* create FFC sub-group generator G with given index */
+        if(pGenerator != NULL) {
+            CHECK_ERROR(FfcFips186v4CreateGenerator(pDomain, pRndContext, generIndex, pTmpBuff));
+            /* check the generator */
+            CHECK_AND_SET_ERROR(FfcCmpBeBytes2LeWordsBigNum(pGenerator, &pDomain->genG[0], primeSizeBytes),
+                        CC_FFC_DOMAIN_GENERATOR_NOT_VALID_ERROR);
+        }
+    }
+    /*--------------------------------------------------------------------------------------
+     * the case, that the user has obtained insurance, that all Domain input data is correct,
+     * therefore the following checking is minimal and not means validation of the Domain. *
+     *-------------------------------------------------------------------------------------*/
+    else if (validMode == CC_FFC_DOMAIN_TRUSTED_DATA_MODE) {
+
+            /* check input pointers and sizes according to given ffcParamSetId and ffcHashMode */
+            CHECK_ERROR(FfcDomainMinCheckInput(pDomain, pRndContext, primeSizeBits, orderSizeBits,
+                                          pSeed, seedSizeBytes, CC_FFC_USE_GIVEN_SEED, genCounter,
+                                          ffcParamSetId, ffcHashMode, generIndex));
+
+            /* check Prime, Order and Generator  */
+            CHECK_AND_SET_ERROR((pPrime == NULL) || (pOrder == NULL)  || (pGenerator == NULL),
+                        CC_FFC_DOMAIN_INVALID_ARGUMENT_PTR_ERROR);
+
+            /* set data into Domain as LE words array */
+            CC_CommonConvertMsbLsbBytesToLswMswWords(pDomain->prime, primeSizeBytes, pPrime, primeSizeBytes);
+            CC_CommonConvertMsbLsbBytesToLswMswWords(pDomain->order, orderSizeBytes, pOrder, primeSizeBytes);
+            CC_CommonConvertMsbLsbBytesToLswMswWords(pDomain->genG, primeSizeBytes, pGenerator, primeSizeBytes);
+            if(pSeed != NULL) {/*set data as is */
+                CC_PalMemCopy(pDomain->seed, pSeed, seedSizeBytes);
+            }
+            /* Note: part of settings is done by FfcDomainMinCheckInput() function. */
+    }
+
+    if(err == CC_OK) {
+        pDomain->validTag = CC_FFC_DOMAIN_VALIDATION_TAG;
+    }
+
+End:
+
+    if(err) {
+        CC_PalMemSetZero(pDomain, sizeof(CCFfcDomain_t));
+        if(pTmpBuff != NULL) {
+            CC_PalMemSetZero((uint8_t*)pTmpBuff, sizeof(CCFfcDomainTmpBuff_t));
+        }
+    }
+
+        return err;
+}
+
+
+
+/*******************************************************************************************/
+/*!
+@brief This function extracts FFC domain parameters from Domain structure for external using.
+<ol><li> Assumed, that FFC domain is properly generated or validated according to the FIPS 184-4, standard. </li>
+<li> The function checks input/output pointers and buffers sizes, converts the DH Domain parameters
+to big endianness output arrays (with leading zeros if exists). </li>
+<li> If the user not need any domain parameters, then appropriate pointers (for buffer and size)
+should be set to NULL </li>
+<li> Note: The sizes of buffers are given by pointers, were the referred [in/out] values are:
+[in] - the buffer size, [out] - actual data size. </li></ol>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcExportDomain(
+                CCFfcDomain_t *pDomain,          /*!< [in] pointer to FFC Domain to be exported. */
+                uint8_t *pPrime,                 /*!< [out] pointer to prime modulus of the finite field (P). */
+                size_t  *pPrimeSize,             /*!< [in/out] pointer to prime P size in bytes. */
+                uint8_t *pGenerator,             /*!< [out] pointer to generator of subgroup (G). */
+                size_t  *pGeneratorSize,         /*!< [in/out] pointer to generator G size in bytes. */
+                uint8_t *pOrder,                 /*!< [out] pointer to the order of the generator G. */
+                size_t  *pOrderSize,             /*!< [in/out] pointer to order of generator Q size in bytes. */
+                uint8_t *pSeed,                  /*!< [out] pointer to the Seed, used for Domain generation;
+                                                      if Seed is not required, then the pointer and size should be NULL. */
+                size_t  *pSeedSize,              /*!< [in/out] size of the Seed in bytes - if the Seed not exist,
+                                                      in the Domain, the function sets the size = 0. */
+                CCFfcParamSetId_t *pFfcParamSetId, /*!< [in] pointer to enumerator ID, defining the set of FFC domain parameters
+                                                      parameters according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t *pFfcHashMode, /*!< [in] pointer to enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode
+                                                      may be used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint32_t *pGenCounter,           /*!< [out] pointer to count of iterations, which were performed
+                                                      during Domain generation. */
+                uint8_t  *pIndexOfGenerator      /*!< pointer to index, of  FFC Generator existed in the Domain. */
+)
+{
+
+        /* The return error identifier */
+    CCError_t err = CC_OK;
+    size_t primeSizeBytes;
+    size_t orderSizeBytes;
+
+    /* check input Domain */
+    CHECK_AND_SET_ERROR((pDomain == NULL), CC_FFC_DOMAIN_INVALID_DOMAIN_PTR_ERROR);
+    CHECK_AND_SET_ERROR((pDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG),
+                         CC_FFC_DOMAIN_VALIDATION_TAG_ERROR);
+
+    primeSizeBytes = pDomain->modLenWords * CC_32BIT_WORD_SIZE;
+    orderSizeBytes = pDomain->ordLenWords * CC_32BIT_WORD_SIZE;
+
+    /*----------------------------------------------------------------------------------------*
+     * Check output buffers: ptr != NULL, outSize <= buffSize and set data to output buffers. *
+     *----------------------------------------------------------------------------------------*/
+    /* Prime P */
+    if((pPrime != NULL) && (pPrimeSize != NULL)) {
+        CHECK_ERROR(FfcCheckPtrAndSize(pPrime, pPrimeSize, pDomain->prime, primeSizeBytes));
+        CHECK_ERROR(CC_CommonConvertLswMswWordsToMsbLsbBytes(pPrime, primeSizeBytes, pDomain->prime, primeSizeBytes));
+        *pPrimeSize = primeSizeBytes;
+    }
+    /* Order Q */
+    if((pOrder != NULL) && (pOrderSize != NULL)) {
+        CHECK_ERROR(FfcCheckPtrAndSize(pOrder, pOrderSize, pDomain->order, orderSizeBytes));
+        CHECK_ERROR(CC_CommonConvertLswMswWordsToMsbLsbBytes(pOrder, orderSizeBytes, pDomain->order, orderSizeBytes));
+        *pOrderSize = orderSizeBytes;
+    }
+    /* Generator G */
+    if((pGenerator != NULL) && (pGeneratorSize != NULL)) {
+        CHECK_ERROR(FfcCheckPtrAndSize(pGenerator, pGeneratorSize, pDomain->genG, primeSizeBytes));
+        CHECK_ERROR(CC_CommonConvertLswMswWordsToMsbLsbBytes(pGenerator, primeSizeBytes, pDomain->genG, primeSizeBytes));
+        *pGeneratorSize = primeSizeBytes;
+    }
+    /* Seed */
+    if((pSeed != NULL) && (pSeedSize != NULL)) {
+        CHECK_ERROR(FfcCheckPtrAndSize(pSeed, pSeedSize, pDomain->seed, pDomain->seedSizeBytes));
+        CHECK_AND_SET_ERROR(CC_PalMemCopy(pSeed, pDomain->seed, pDomain->seedSizeBytes),
+                       CC_FFC_DOMAIN_INVALID_OPTIONAL_PARAM_ERROR);
+        *pSeedSize = pDomain->seedSizeBytes;
+    }
+
+    /* Output enumerator and number parameters */
+    if(pFfcParamSetId != NULL) {
+        *pFfcParamSetId = pDomain->ffcParamSetId;
+    }
+    if(pFfcHashMode != NULL) {
+        *pFfcHashMode =  pDomain->ffcHashMode;
+    }
+    if(pGenCounter != NULL) {
+        *pGenCounter = pDomain->genCounter;
+    }
+    if(pIndexOfGenerator != NULL) {
+        *pIndexOfGenerator = pDomain->indexOfGenerator;
+    }
+
+End:
+    /* Note: because the Domain is not secret,
+     * we don't zeroing buffers in case of in/out errors
+     */
+    return err;
+}
+
+
+
+/*******************************************************************************************/
+/*!
+@brief The function creates a new FFC subgroup Generator for existed FFC Domain.
+<ol><li> Assumed, that FFC domain is properly generated or imported previously and meets
+to the FIPS 184-4, sec. A.1.1.2 standard. </li>
+<li> The function checks input/output pointers and buffers sizes and creates new Generator
+according to sec. A.2.3. and sets it into Domain structure. </li></ol>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcCreateNewGenerator(
+                CCFfcDomain_t *pDomain,        /*!< [in/out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,   /*!< [in] random generation function context. */
+                uint8_t index,                 /*!< [in] index allowing to generate some FFC generators with
+                                                    the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainTmpBuff_t *pTmpBuff /*!< [in] pointer to FFC Domain temp buffer structure. */
+)
+{
+    /* The return error identifier */
+    CCError_t err = CC_OK;
+
+    CHECK_AND_SET_ERROR((pDomain == NULL), CC_FFC_DOMAIN_INVALID_RND_CTX_PTR_ERROR);
+    CHECK_AND_SET_ERROR((pDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG),
+                         CC_FFC_DOMAIN_VALIDATION_TAG_ERROR);
+
+    return FfcFips186v4CreateGenerator(pDomain, pRndContext, index, pTmpBuff);
+
+End:
+    return err;
+
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffcdh/cc_ffcdh.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffcdh/cc_ffcdh.c
new file mode 100644
index 0000000..70f22cd
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffcdh/cc_ffcdh.c
@@ -0,0 +1,2540 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include "cc_bitops.h"
+#include "cc_pal_types_plat.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_error.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_rnd_common.h"
+#include "cc_rnd_error.h"
+#include "cc_rnd_local.h"
+#include "cc_hash_defs.h"
+#include "cc_general_defs.h"
+#include "mbedtls/md.h"
+#include "mbedtls_cc_hkdf.h"
+#include "cc_ffcdh_error.h"
+#include "cc_ffcdh.h"
+#include "cc_ffc_domain.h"
+#include "cc_ffcdh.h"
+#include "cc_ffcdh_local.h"
+#include "cc_fips_defs.h"
+#include "pki.h"
+
+/************************ Defines *******************************/
+
+/************************ Enums *********************************/
+
+/************************ macros ********************************/
+
+/************************ global data ***********************************/
+
+extern CCError_t FfcGetHashMode(
+                    CCHashOperationMode_t *pHashMode, /* optional */
+                    mbedtls_hkdf_hashmode_t *pHkdfHashMode, /* optional */
+                    uint32_t *pBlockSize,              /* optional */
+                    uint32_t *pDigestSize,             /* optional */
+                    CCFfcHashOpMode_t ffcHashMode);    /* ffc HASH mode */
+
+
+extern CCError_t FfcGetDomainSizes(
+                    uint32_t *pMaxSecurStrength,        /* Maximum security strength supported, in bits. */
+                    uint32_t *pPrimeLen,                /* Field (prime P) length in bytes. */
+                    uint32_t *pOrderLen,                /* Subgroup order Q length in bytes. */
+                    uint32_t *pMinHashLen,              /* Minimum length of HASH output in bytes. */
+                    CCFfcParamSetId_t  ffcParamSetId);  /* Enum. defining set of lengths of domain parameters, approved
+                                                         by SP 800-56A and FIPS 186-4 standards */
+
+/************************ Private Functions ******************************/
+
+#ifdef FFC_FURTHER_USING
+/* The function converts little endianness bytes array to big endianness without leading zeros.
+ * Note: The function is not constant-time and intended for work with non secure data.
+ *       Overlapping of buffers is not allowed.  */
+static CCError_t LeBytesArrayToBeBytesWithoutZeros (
+                                uint8_t *pBeDst,   /* LE destination */
+                                uint8_t *pLeSrc,   /* BE source */
+                                size_t *pSizeBytes /* pointer to size: in - buffer size,
+                                                       out -  actual size without leading zeros */
+)
+{
+    CCError_t err = CC_OK;
+    int32_t i, j;
+
+    CHECK_AND_SET_ERROR((*pSizeBytes == 0), CC_FFCDH_INVALID_ARGUMENT_SIZE_ERROR);
+
+        j = 0;
+        i = *pSizeBytes-1;
+        while (pLeSrc[i] == 0) {  /* remove leading zeros */
+            i--;
+        }
+
+        /* copy actual data */
+        for (; i>=0; i--) {
+            pBeDst[j++] = pLeSrc[i];
+        }
+
+        *pSizeBytes = j; /* output actual size */
+End:
+        return err;
+}
+#endif
+
+#ifdef FFC_FURTHER_USING
+/* The function converts big endianness bytes array to little endianness without leading zeros.
+ * Note: The function is not constant-time and intended for work with non secure data */
+static void BeBytesArrayToLeEBytes (
+                                uint8_t  *pLeDst, /* LE destination */
+                                uint8_t  *pBeSrc, /* BE source */
+                                uint32_t *pSizeBytes) /* pointer to size: in - buffer size,
+                                                         out -  actual size without leading zeros */
+{
+        int32_t i, j;
+        int32_t count0 = 0;
+
+        j = 0;
+
+        if(*pSizeBytes == 0)
+            return;
+
+        /* remove leading zeros */
+    while (pBeSrc[count0] == 0) {
+        count0++;
+    }
+
+    /* copy actual data */
+    for (i = *pSizeBytes - 1; i >= count0; i--) {
+            pLeDst[j++] = pBeSrc[i];
+    }
+    *pSizeBytes = *pSizeBytes -count0;
+
+    return;
+}
+#endif
+
+
+#ifdef FFC_FURTHER_USING
+/*******************************************************************************
+ *             CC_CommonGetBytesCounterEffectiveSizeInBits                  *
+ *******************************************************************************
+ *
+ * @brief This function returns the effective number of bits in the byte stream counter
+ *        ( searching the highest '1' in the counter )
+ *
+ *        Assumed, that MSB of the counter is stored in the first cell in the
+ *         array. For example, the value of the 8-Bytes numberer B is :
+ *             B[0]<<56 | B[1]<<48 ............ B[6]<<8 | B[7] .
+ *
+ * @param[in] pCounter -  The counter buffer.
+ * @param[in] CounterSize -  the counter size in bytes.
+ *
+ * @return result - The effective counters size in bits.
+ */
+
+static uint32_t FfcDhGetBeCounterEffectiveSizeInBits(const uint8_t *pCounterBuffp,
+                                                     uint32_t *pCountLeadingZeros,
+                                                     uint32_t counterSize)
+{
+    /* FUNCTION LOCAL DECLARATIONS */
+
+    /* loop variable */
+    int32_t i;
+
+    /* the effective size in bits */
+    uint32_t effectSizeInBits;
+
+    /* the effective MS byte (the one that is not zero) */
+    uint8_t effectMsByteVal;
+
+    /* FUNCTION LOGIC */
+
+    /* STEP1 : a loop for adjusting the counter size by neglecting the MSB zeros */
+        *pCountLeadingZeros = 0
+    while (i < counterSize) {
+        if (pCounterBuff[i] != 0)
+            break;
+        else
+            *pCountLeadingZeros++;
+    }
+
+    /* STEP2 : if counter size is 0 - return 0 */
+    if (CounterSize == 0)
+        return 0;
+
+    /* set the effective MS byte */
+    effectMsByteVal = pCounterBuff[i];
+
+    /* initialize the effective size as the counters size (with MSB zeros) */
+    counterEffectSizeInBits = counterSize * 8;
+
+    /* STEP 3 : adjusting the effective size in bits */
+    for (i = 0; i < 8; i++) {
+        if (effectMsByteVal & 0x80)
+            break;
+
+        counterEffectSizeInBits--;
+        effectMsByteVal <<= 1;
+
+    }/* end of adjusting the effective size in bits loop */
+
+    return counterEffectSizeInBits;
+
+}/* END OF CC_DhGetBeCounterEffectiveSizeInBits */
+#endif
+
+/* The function writes the separate bytes-array (Src) into the Dst buffer.
+ *
+ * Of first, he function sets the string length as first 2-bytes big endianness counter,
+ * then writes the data, promote the pointer to next after the data position. If
+ * pointer to FullLen != NULL, then add the size of written source to FullLen value.
+ *
+ * \note: Assumed that all parameters, including possible buffers overflow, are
+ * checked and correct.
+ * \note: Dst buffer should be given by allocated pointer to pointer and not by
+ *  address of the buffer address.
+ */
+static void FfcDhWriteBufferBeToBe(
+                uint8_t **ppDst,      /* [in/out] pointer to pointer to destination buffer:
+                                         in - start address, out - next address after writing data. */
+                uint8_t  *pSrc,       /* [in] pointer to source buffer */
+                uint32_t  curLen,     /* [in] size of source buffer in bytes. */
+                uint32_t *pFullLen)   /* [in/out] pointer to accumulated full length of
+                                          written data. */
+{
+    /* set length and data */
+    (*ppDst)[0] = (uint8_t)((curLen>>8) & 0xFF); (*ppDst)[1] = (uint8_t)(curLen & 0xFF);
+    *ppDst += CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+    CC_PalMemCopy(*ppDst, pSrc, curLen);
+
+    /* update the Dst pointer */
+    *ppDst += curLen;
+    if(pFullLen != NULL){
+        *pFullLen += (curLen + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES);
+    }
+
+    return;
+}
+
+
+/* The function writes the separate LE words Src array into the Dst BE bytes buffer.
+ *
+ * Of first, the function sets the Src length as 2-bytes big endianness length-counter,
+ * then writes the data, converted to BE bytes and promote the pointer to next position
+ * after the data . If pointer to FullLen != NULL, then the function adds the size of
+ * source to FullLen value.
+ *
+ * \note: Assumed that all parameters, including possible buffers overflow, are
+ * checked and correct.
+ * \note: Dst buffer should be given by allocated pointer to pointer and not by
+ *  address of the buffer address.
+ */
+static void FfcDhWriteBufferLeToBe(
+                uint8_t **ppDst,      /* [in/out] pointer to pointer to destination buffer:
+                                         in - start address, out - next address after writing data. */
+                uint32_t *pSrc,       /* [in] pointer to source buffer, given as LE words array. */
+                uint32_t  curLen,     /* [in] size of source in words. */
+                uint32_t *pFullLen)   /* [in/out] pointer to accumulated full length (in bytes) of
+                                          all written data. */
+{
+    int32_t i, j;
+    curLen = curLen << 2; /* now size is in bytes*/
+    /* set length and data */
+    (*ppDst)[0] = (uint8_t)((curLen>>8) & 0xFF); (*ppDst)[1] = (uint8_t)(curLen & 0xFF);
+    *ppDst += CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+//  CHECK_AND_SET_ERROR(CC_CommonConvertLswMswWordsToMsbLsbBytes(*ppDst, curLen, pSrc, curLen));
+
+    for (i = curLen - 1, j = 0; i >= 0; i--, j++) {
+        (*ppDst)[i] = (uint8_t)(pSrc[j / CC_32BIT_WORD_SIZE] >> ((j % CC_32BIT_WORD_SIZE) << 3));
+    }
+
+    /* update the Dst pointer */
+    *ppDst += curLen;
+    if(pFullLen != NULL){
+        *pFullLen += (curLen + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES);
+    }
+
+    return;
+}
+
+
+#ifdef FFC_FURTHER_USING
+/* The function writes the byte-string Src into the Dst buffer with
+ * setting the length as first 2-bytes counter and control of remaining
+ * size of destination buffer.
+ * \note: The function promotes the destination pointer by written bytes and
+ * decreases the remaining size */
+static CCError_t FfcDhWriteBuffers(uint8_t **ppDst, uint8_t *pSrc,
+                           size_t len, size_t *pRemainLen)
+{
+    if(ppDst == NULL || *ppDst == NULL)
+        return CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR;
+    if(len + 2 > *pRemainLen)
+        return CC_FFCDH_BUFFER_OVERFLOW_ERROR;
+    /* set length and data */
+    (*ppDst)[0] = (uint8_t)((len>>1) & 0xFF); (*ppDst)[1] = (uint8_t)(len & 0xFF);
+    *ppDst += CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+
+    if(pSrc != NULL && len != 0) {
+        CC_PalMemCopy(*ppDst, pSrc, len);
+    }
+    /* update the Dst pointer and Remaining length */
+    *ppDst += len;
+    *pRemainLen -= (len + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES);
+
+    return CC_OK;
+}
+
+
+/*! The function copies "len" bytes from pSrc to pDst buffer and sets
+ *  offset of pDst buffer from base address to pCurrOffset. */
+static void FfcDhWriteBufferAndOffset(uint8_t **ppDst, uint8_t *pSrc,
+                              size_t len, uint16_t *pCurrOffset, uint8_t *pBaseAddr)
+{
+    *pCurrOffset = (uint16_t)((*ppDst - pBaseAddr)&0xFFFF);
+    /* set length and data */
+    (*ppDst)[0] = (uint8_t)((len>>1) & 0xFF); (*ppDst)[1] = (uint8_t)(len & 0xFF);
+    *ppDst += CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+
+    if(len != 0) {
+        CC_PalMemCopy(*ppDst, pSrc, len);
+    }
+    /* update the Dst pointer and Offset of next buffer */
+    *ppDst += len;
+
+    return;
+}
+#endif
+
+#ifdef FFC_FURTHER_USING
+static CCError_t FfcGetBufferSize(uint8_t **ppSrc, size_t *pLen, size_t *pRemainLen)
+{
+    size_t len;
+    len = (((size_t)((*ppSrc)[0])) << 8) | (*ppSrc)[1];
+    if(len > 0) {
+        if((*pRemainLen < CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES) ||
+           (*pRemainLen - CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES < len)) {
+            return CC_FFCDH_BUFFER_OVERFLOW_ERROR;
+        }
+    }
+    *pRemainLen -= CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+    *ppSrc += CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+    *pLen = len;
+
+    return CC_OK;
+}
+#endif
+
+/************************ Public Functions ******************************/
+
+/*******************************************************************************************/
+/*! The functions initializes the DH Context structure:
+<li> zeroes context buffers, initializes 3 MS bytes of validation tag by context ID and sets LS byte
+to zero to prepare it for further indications of setting appropriate parts of data into context
+*/
+CEXPORT_C CCError_t  CC_FfcDhInitCtx( CCFfcDhUserContext_t *pDhUserCtx)
+{
+       /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check contexts pointers */
+    CHECK_AND_SET_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+
+        /* zeroing the Context */
+        CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+
+        /* check that DhCtx is initialized to zero */
+        pDhUserCtx->validTag = FFCDH_CTX_VALID_TAG_INIT_VAL;
+
+End:
+        return err;
+}
+
+
+/*******************************************************************************************/
+/*! The functions destroys (zeroes) the DH Context structure.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+
+*/
+CEXPORT_C CCError_t  CC_FfcDhFreeCtx( CCFfcDhUserContext_t *pDhUserCtx)
+{
+       /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check contexts pointers */
+    CHECK_AND_SET_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+
+        /* zeroing the Context */
+        CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+
+End:
+        return err;
+}
+
+
+
+/**************************************************************/
+/* The function calculates internal structures FfcDhSchemeInfo_t and FfcDhSchemeDataOffsets_t,
+ * describing which parameters and data are used in the scheme and where appropriate  entries of
+ * the data are saved in the Context.
+ *
+ * When some member of the structure FfcDhSchemeInfo_t in the context is equal to 1,
+ * then appropriate parameter is needed for the Scheme and if it is 0 - not.
+ * The places of the data entries are given by offsets in FfcDhSchemeDataOffsets_t structure.
+ * Assumed: all input parameters are checked and set correctly.
+ *
+ * Note: Offsets of OtherInfo Sub-Entries given from base address = &pDhCth->extendDataBuffer[0];
+ */
+static CCError_t FfcDhSchemeInfo(
+            DhContext_t *pDhCtx,   /*!< [in/out] pointer to internal DH context structure */
+            uint8_t *pAlgId,       /*!< [in] pointer to Algorithm ID agreed by both parties. */
+            size_t algIdSize,      /*!< [in] size of Algorithm ID in bytes. Should be less than
+                            CC_FFCDH_MAX_SIZE_OF_ALG_ID_SUB_ENTRY. */
+            uint8_t *pUserId,      /*!< [in] pointer to the user ID - a distinct identifier of the user. */
+            size_t userIdSize,     /*!< [in] size of the user ID in bytes. */
+            uint8_t *pPartnId,     /*!< [in] pointer to the partner ID - a distinct identifier of the party. */
+            size_t partnIdSize)     /*!< [in] size of the partner ID in bytes. */
+{
+
+    /* FUNCTION DECLARATIONS */
+
+    uint32_t publKeySize;
+//  uint32_t nonceSize;
+    /* pointer to structure, containing information about input
+     * parameters needed, for chosen Scheme, party role (U,V) and
+     * confirmation role (provider, recipient). */
+    FfcDhSchemeInfo_t *schemeInfo = &pDhCtx->schemeInfo;
+    /* Structure, containing offsets and sizes of  parties Info */
+    FfcDhSchemeDataOffsets_t *pDataOffsets = &pDhCtx->dataOffsets;
+    CCFfcDhSchemeId_t dhSchemeId = pDhCtx->dhSchemeId;
+        CCFfcDhUserPartyIs_t userParty = pDhCtx->userParty;
+        CCFfcDhUserConfirmMode_t confirmMode = pDhCtx->confirmMode;
+        uint8_t *pBaseAddr = (uint8_t*)&pDhCtx->extendDataBuffer;
+
+
+    publKeySize = pDhCtx->ffcDomain.modLenWords*CC_32BIT_WORD_SIZE;
+    pDhCtx->nonceSize = pDhCtx->ffcDomain.ordLenWords*CC_32BIT_WORD_SIZE;
+//  pDhCtx->macTagSize = DH_SHA_PARAMETERS_SIZES_IN_BYTES[pDhCtx->];
+
+    /* FUNCTION  logic */
+
+    /* zeroing of schemeInfo */
+    CC_PalMemSetZero(schemeInfo, sizeof(FfcDhSchemeInfo_t));
+
+    /* calculate buffers offsets, dependent on user and partner roles. */
+    /* Note: these offsets points directly on data (no length counter before) */
+    pDataOffsets->kdfCounterOffset = 0; /*!< KDF counter offset: is a base=0 for counting other offsets */
+    /* set shared secret value size for Hybrid modes = 2*primeSize and for other modes = 1*primeSize. */
+    pDataOffsets->sharedSecrSize = publKeySize*(1 + ((dhSchemeId == CC_FFCDH_SCHEM_HYBRID_ONE_FLOW) || \
+                                                 (dhSchemeId == CC_FFCDH_SCHEM_HYBRID1)));
+    pDataOffsets->sharedSecrOffset = pDataOffsets->kdfCounterOffset + CC_FFCDH_KDF_COUNTER_SIZE_IN_BYTES;
+    /* The following offsets points on the length counters of OtherInfo entries */
+    pDataOffsets->algIdOffset = FFCDH_SET_OFFSET(pDataOffsets->sharedSecrOffset, pDataOffsets->sharedSecrSize);
+
+    /*-------------------------------------------------------------*/
+    /* set Scheme Info indication values about required parameters */
+    /*-------------------------------------------------------------*/
+    if(userParty == CC_FFCDH_PARTY_U) {
+        switch(dhSchemeId) {
+        case CC_FFCDH_SCHEM_HYBRID1: /* user: stat=1,ephem=1,nonce=0;  partn: stat=1,ephem=1,nonce=0; */
+            /* set keys used info */
+            schemeInfo->doUserStatKey = 1;
+            schemeInfo->doUserEphemKey = 1;
+            schemeInfo->doPartnerStatKey = 1;
+            schemeInfo->doPartnerEphemKey = 1;
+
+            /* set confirmation roles and nonces info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            schemeInfo->doConfirmProvid = /* = bilateral||VtoU */
+                ((confirmMode == CC_FFCDH_CONFIRM_U_TO_V) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doConfirmRecip =  /* = bilateral||UtoV */
+                ((confirmMode == CC_FFCDH_CONFIRM_V_TO_U) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            break;
+
+        case CC_FFCDH_SCHEM_EPHEM: /* user: stat=0,ephem=1,nonce=0; partn: stat=0,ephem=1,nonce=0; */
+            /* set keys used info */
+            schemeInfo->doUserEphemKey = 1;
+            schemeInfo->doPartnerEphemKey = 1;
+            /* no confirmation */
+            break;
+
+        case CC_FFCDH_SCHEM_HYBRID_ONE_FLOW: /* user: stat=1,ephem=1,nonce=0;  partn: stat=1,ephem=0,nonce=(confirm==VtoU); */
+            /* set keys used info */
+            schemeInfo->doUserStatKey = 1;
+            schemeInfo->doUserEphemKey = 1;
+            schemeInfo->doPartnerStatKey = 1;
+
+            /* set confirmation roles and nonces info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            schemeInfo->doConfirmProvid = /* = bilateral||VtoU */
+                ((confirmMode == CC_FFCDH_CONFIRM_U_TO_V) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doConfirmRecip =  /* = bilateral||UtoV */
+                ((confirmMode == CC_FFCDH_CONFIRM_V_TO_U) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doPartnerNonce = schemeInfo->doConfirmProvid;
+            break;
+
+        case CC_FFCDH_SCHEM_ONE_FLOW: /* user: stat=0,ephem=1,nonce=0;  partn: stat=1,ephem=0,nonce=0 */
+            /* set keys used info */
+            schemeInfo->doUserEphemKey = 1;
+            schemeInfo->doPartnerStatKey = 1;
+
+            /* set confirmation roles and nonces info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            if(confirmMode != CC_FFCDH_CONFIRM_V_TO_U) {
+                return CC_FFCDH_INVALID_CONFIRM_MODE_ERROR;
+            } else {
+                schemeInfo->doConfirmRecip = 1;  /*user is recipient*/
+                schemeInfo->doPartnerNonce = 1;
+            }
+            break;
+
+        case CC_FFCDH_SCHEM_STATIC: /* user: stat=1,ephem=1,nonce=0;  partn: stat=1,ephem=0,nonce=(confirm?); */
+            /* set keys used info */
+            schemeInfo->doUserStatKey = 1;
+            schemeInfo->doPartnerStatKey = 1;
+
+            /* set confirmation roles and nonces info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            schemeInfo->doConfirmProvid = /* = bilateral||UtoV */
+                ((confirmMode == CC_FFCDH_CONFIRM_U_TO_V) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doConfirmRecip =  /* = bilateral||UtoV */
+                ((confirmMode == CC_FFCDH_CONFIRM_V_TO_U) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doUserNonce = 1; /* always = 1: see sec.6.3.3.1*/
+            schemeInfo->doPartnerNonce = schemeInfo->doConfirmProvid;
+            break;
+
+        default:
+            return CC_FFCDH_INVALID_SCHEM_ID_ERROR;
+
+            /* calculate user and partner Info data offsets (starts from Party ID). */
+//          pDataOffsets->userIdOffset = FFCDH_SET_OFFSET(pDataOffsets->algIdOffset, algIdSize);
+//          pDataOffsets->partnIdOffset= FFCDH_SET_OFFSET(pDataOffsets->algIdOffset, CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES);
+        }
+    } else { /* userParty == CC_FFCDH_PARTY_V */
+        switch(dhSchemeId) {
+        case CC_FFCDH_SCHEM_HYBRID1:
+            /* set keys used info */
+            schemeInfo->doUserStatKey = 1;
+            schemeInfo->doUserEphemKey = 1;
+            schemeInfo->doPartnerStatKey = 1;
+            schemeInfo->doPartnerEphemKey = 1;
+
+            /* set confirmation roles and nonce info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            schemeInfo->doConfirmProvid =
+                ((confirmMode == CC_FFCDH_CONFIRM_V_TO_U) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doConfirmRecip =
+                ((confirmMode == CC_FFCDH_CONFIRM_U_TO_V) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            break;
+
+        case CC_FFCDH_SCHEM_EPHEM:
+            /* set keys used info */
+            schemeInfo->doUserEphemKey = 1;
+            schemeInfo->doPartnerEphemKey = 1;
+            /* no confirmation */
+            break;
+
+        case CC_FFCDH_SCHEM_HYBRID_ONE_FLOW:
+            /* set keys used info */
+            schemeInfo->doUserStatKey = 1; /* ephem=0*/
+            schemeInfo->doPartnerStatKey = 1;
+            schemeInfo->doPartnerEphemKey = 1;
+
+            /* set confirmation roles and nonces info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            schemeInfo->doConfirmProvid = /* = bilateral||VtoU */
+                ((confirmMode == CC_FFCDH_CONFIRM_V_TO_U) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doConfirmRecip =  /* = bilateral||UtoV */
+                ((confirmMode == CC_FFCDH_CONFIRM_U_TO_V) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doUserNonce = schemeInfo->doConfirmRecip;
+            break;
+
+        case CC_FFCDH_SCHEM_ONE_FLOW: /* user: stat=1,ephem=0,nonce=0;  partn: stat=0,ephem=1,nonce=0 */
+            /* set keys used info */
+            schemeInfo->doUserStatKey = 1;
+            schemeInfo->doPartnerEphemKey = 1;
+
+            /* set confirmation roles and nonces info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            if((confirmMode != CC_FFCDH_CONFIRM_V_TO_U)) {
+                return CC_FFCDH_INVALID_CONFIRM_MODE_ERROR;
+            } else {
+                schemeInfo->doConfirmProvid = 1; /*user is provider*/
+                schemeInfo->doUserNonce = 1;
+            }
+            break;
+
+        case CC_FFCDH_SCHEM_STATIC: /* user: stat=1,ephem=1,nonce=0;  partn: stat=1,ephem=0,nonce=(confirm?); */
+            /* set keys used info */
+            schemeInfo->doUserStatKey = 1;
+            schemeInfo->doPartnerStatKey = 1;
+
+            /* set confirmation roles and nonces info */
+            if(confirmMode == CC_FFCDH_CONFIRM_NOT_USED)
+                break;
+            schemeInfo->doConfirmProvid = /* = bilateral||VtoU */
+                ((confirmMode == CC_FFCDH_CONFIRM_V_TO_U) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doConfirmRecip =  /* = bilateral||UtoV */
+                ((confirmMode == CC_FFCDH_CONFIRM_U_TO_V) || (confirmMode == CC_FFCDH_CONFIRM_BILATERAL));
+            schemeInfo->doUserNonce = schemeInfo->doConfirmRecip;
+            schemeInfo->doPartnerNonce = schemeInfo->doConfirmProvid;
+            break;
+
+        default:
+            return CC_FFCDH_INVALID_SCHEM_ID_ERROR;
+        }
+
+        /* calculate user and partner PartyInfo data offsets (starts from Party ID). */
+//      pDataOffsets->userIdOffset = FFCDH_SET_OFFSET(pDataOffsets->algIdOffset, CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES);
+//      pDataOffsets->partnIdOffset = FFCDH_SET_OFFSET(pDataOffsets->algIdOffset, algIdSize);
+    }
+
+    /* calculate user Info data sub-entries offsets */
+//  pDataOffsets->userStatPublKeyOffset = FFCDH_SET_OFFSET(pDataOffsets->userIdOffset, userIdSize);
+//  pDataOffsets->userEphemPublKeyOffset = FFCDH_COND_SET_OFFSET(pDataOffsets->userStatPublKeyOffset, publKeySize, schemeInfo->doUserStatKey);
+//  pDataOffsets->userNonceOffset = FFCDH_COND_SET_OFFSET(pDataOffsets->userEphemPublKeyOffset, publKeySize, schemeInfo->doUserEphemKey);
+//  pDataOffsets->userOtherDataOffset = FFCDH_COND_SET_OFFSET(pDataOffsets->userNonceOffset, nonceSize, schemeInfo->doUserNonce);
+//
+//  /* calculate partner Info data sub-entries offsets */
+//  pDataOffsets->partnStatPublKeyOffset = FFCDH_SET_OFFSET(pDataOffsets->partnIdOffset, partnIdSize);
+//  pDataOffsets->partnEphemPublKeyOffset = FFCDH_COND_SET_OFFSET(pDataOffsets->partnStatPublKeyOffset, publKeySize, schemeInfo->doPartnerStatKey);
+//  pDataOffsets->partnNonceOffset = FFCDH_COND_SET_OFFSET(pDataOffsets->partnEphemPublKeyOffset, publKeySize, schemeInfo->doPartnerEphemKey);
+//  pDataOffsets->partnOtherDataOffset = FFCDH_COND_SET_OFFSET(pDataOffsets->partnNonceOffset, nonceSize, schemeInfo->doPartnerNonce); ;
+//
+//  pDataOffsets->suppPublInfoOffset = FFCDH_SET_OFFSET(pDataOffsets->algIdOffset, algIdSize + 2*CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES);
+//  pDataOffsets->suppPrivInfoOffset = FFCDH_SET_OFFSET(pDataOffsets->suppPublInfoOffset, CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES);
+
+    /* copy AlgId, User ID and Partner ID into Context */
+    CC_PalMemCopy(pBaseAddr + pDataOffsets->algIdOffset, pAlgId, algIdSize);
+    CC_PalMemCopy(pDhCtx->userId, pUserId, userIdSize);
+    pDhCtx->userIdSizeBytes = userIdSize;
+    CC_PalMemCopy(pDhCtx->partnerId, pPartnId, partnIdSize);
+    pDhCtx->partnerIdSizeBytes = partnIdSize;
+
+//  pDataOffsets->userInfoSize;            /*!< full size of Party U data */
+//  pDataOffsets->partnInfoSize;           /*!< full size of partner data */
+//  pDataOffsets->suppPublInfoSize;
+//  pDataOffsets->suppPublInfoSize;
+//
+//End:
+
+    return CC_OK;
+}
+
+
+
+/*******************************************************************************************/
+/*! The function sets into DH context FFCDH Scheme agreed parameters: SchemeId, User role, Confirmation mode etc.
+\note The context is used in DH Agreement functions, implementing NIST SP 800-56A rev.2 standard.
+\note Assumed, that input FFC Domain is properly generated or imported and validated according to
+NIST SP 800-56A and FIPS 186-4 standards.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CEXPORT_C CCError_t  CC_FfcDhCtxSetSchemeParams(
+                            CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to context structure, containing all parameters and data,
+                                                                        defining DH Key Agreement Scheme */
+                            CCFfcDomain_t *pDomain,           /*!< [in] pointer to DH FFC Domain structure. */
+                            uint8_t *pAlgId,                  /*!< [in] pointer to Algorithm ID agreed by both parties and indicates how the derived
+                                                                        secret keying material will be parsed and for which algorithms (sec.5.8.1.2).
+                                                                        In partial, Algorithm ID should indicate also how much bits are intended for
+                                                                        internal confirmation MAC algorithm and how much remaining bits will be
+                                                                        returned to the user for external applications/algorithms (the total size should
+                                                                        be equal to chosen secretKeyDataSize). */
+                            size_t algIdSize,                 /*!< [in] size of Algorithm ID in bytes, should be less than
+                                                        CC_FFCDH_MAX_SIZE_OF_ALG_ID_SUB_ENTRY. */
+                            size_t secretKeyingDataSize,      /*!< [in] size in bytes of shared secret keying data, which will be extracted and in
+                                                                                    the next steps and passed to the user for using in  external algorithm(s).
+                                                                                    It is used for calculation of Derived Keying material size =
+                                                                                    key size of the used HMAC function + secretKeyingDataSize. */
+                            uint8_t *pUserId,                 /*!< [in] pointer to the user ID - a distinct identifier of the user. */
+                            size_t userIdSize,                /*!< [in] size of the user ID in bytes. */
+                            uint8_t *pPartnId,                /*!< [in] pointer to the partner ID - a distinct identifier of the party. */
+                            size_t partnIdSize,               /*!< [in] size of the partner ID in bytes. */
+                            CCFfcDhUserPartyIs_t userParty,   /*!< [in] enumerator, defining role of the user (function's caller) in the
+                                                                        DH Agreement Scheme: partyU or partyV. */
+                            CCFfcDhSchemeId_t dhSchemeId,     /*!< [in] enumerator ID of used FFC DH Key Agreement Scheme, as defined
+                                                                in sec. 6, tab. 12. */
+                            CCFfcParamSetId_t ffcParamSetId,  /*!< [in] enumerator, defining the set of FFC domain parameters
+                                                                                    according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                            CCFfcDhKdfModeSp56A_t kdfMode,    /*!< [in] enumerator ID of used KDF function, based on HASH or HMAC algorithms. In current
+                                                                        implementation is allowed only KDF HMAC_RFC5869 mode, according to KDF_HMAC_RFC-5869. */
+                            CCFfcHashOpMode_t ffcHashMode,    /*!< [in] enumerator ID of used SHAXXX HASH mode, supported by the product.
+                                                                        Note: HASH SHA1 function may be used only with SA set of domain parameters
+                                                                        (sec. 5.8.1, tab.6); with other sets the function returns an error. */
+                            CCFfcDhUserConfirmMode_t confirmMode, /*!< enumerator, defining confirmation mode of each party: provider
+                                                                        or/and recipient, according to sec. 5.9. */
+                            uint8_t *pHmacSalt,               /*!< [in] optional, pointer to the Salt, used as key in HMAC-KDF function on appropriate modes.
+                                                                        If HMAC-KDF mode is set, and the pointer and size are zero, then the Salt is
+                                                                        treated as full-zero bytes array of size equalled to block-size of used HMAC function.
+                                                                        If HMAC-KDF mode is HMAC_RFC5869_MODE, then the Salt is treated as HMAC Key.
+                                                                        If only one of parameters (pointer and size) is zero, but other not, then the
+                                                                        function returns an error. */
+                            size_t  hmacSaltSize,             /*!< [in] optional, size of Salt in bytes, should be equalled to the HMAC block size if
+                                                                        salt is used. */
+                            size_t  macTagSize                /*!< [in] optional, size in bytes of confirmation MacTag. Should be in range:
+                                                                        [CC_FFCDH_MIN_SIZE_OF_CONFIRM_MAC_TAG_BYTES, CC_FFCDH_MAX_SIZE_OF_CONFIRM_MAC_TAG_BYTES]. */
+)
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* the return error identifier */
+        CCError_t err = CC_OK;
+        /* pointer to internal DH context structure */
+        DhContext_t *pDhCtx;
+        uint32_t hashSize, minHashSize;
+        uint32_t ffcPrimeSize, ffcOrderSize;
+        CCHashOperationMode_t hashMode;
+//        FfcDhSchemeDataOffsets_t *pOffsets;
+//        uint32_t ffcOrderSizeBytes;
+//        uint8_t *pTmp, *pBaseAddr;
+//        uint16_t zzSize; /* size of shared secret ZZ, depended on Scheme */
+//        uint16_t remainLen; /* remaining size of buffers to write */
+//        uint32_t ffcOrderSize;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+
+        /* ...... checking the parameters validity ........ */
+        /* ------------------------------------------------ */
+
+        /* check contexts pointers and tags */
+    CHECK_AND_RETURN_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+        /* check that DhCtx is valid */
+    CHECK_AND_RETURN_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+    CHECK_AND_SET_ERROR(FFCDH_CHECK_CTX_VALID_TAG_BITS(pDhUserCtx->validTag, FFCDH_CTX_VALID_TAG_INIT_VAL),
+                CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR);
+    /* Check FFC Domain pointer and validation tag */
+    CHECK_AND_RETURN_ERROR(pDomain == NULL, CC_FFCDH_INVALID_DOMAIN_PTR_ERROR);
+    CHECK_AND_SET_ERROR(pDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG,
+                CC_FFCDH_INVALID_DOMAIN_VALIDAT_TAG_ERROR);
+
+    /* check user and algorithm IDs pointers and sizes */
+    CHECK_AND_RETURN_ERROR((pUserId == NULL || userIdSize == 0 || userIdSize > CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES),
+                CC_FFCDH_INVALID_USER_PARTY_ID_ERROR);
+    CHECK_AND_RETURN_ERROR((pAlgId == NULL) || (algIdSize == 0) || (algIdSize > CC_FFCDH_MAX_SIZE_OF_ALG_ID_ENTRY_BYTES),
+                    CC_FFCDH_ALGORITHM_ID_ERROR);
+        /* check optional Salt data */
+    CHECK_AND_RETURN_ERROR((pHmacSalt == NULL) != (hmacSaltSize == 0) ||
+                    (hmacSaltSize > CC_FFCDH_MAX_SIZE_OF_ALG_ID_ENTRY_BYTES), CC_FFCDH_ALGORITHM_ID_ERROR);
+
+         /* check all enumerators */
+    CHECK_AND_RETURN_ERROR(dhSchemeId    >= CC_FFCDH_SCHEM_NUM_OFF_MODE, CC_FFCDH_INVALID_SCHEM_ID_ERROR);
+    CHECK_AND_RETURN_ERROR(ffcParamSetId >= CC_FFC_PARAMS_SET_FC, CC_FFCDH_INVALID_DOMAIN_SIZES_SET_ID_ERROR);
+    CHECK_AND_RETURN_ERROR(kdfMode       >= CC_FFCDH_KDF_NUM_OFF_MODE, CC_FFCDH_INVALID_KDF_MODE_ERROR);
+    CHECK_AND_RETURN_ERROR(ffcHashMode   >= CC_FFC_HASH_NUM_OFF_MODE, CC_FFCDH_INVALID_HASH_MODE_ERROR);
+    CHECK_AND_RETURN_ERROR(userParty     >= CC_FFCDH_PARTY_NUM_OFF_MODE, CC_FFCDH_INVALID_USER_PARTY_ID_ERROR);
+    CHECK_AND_RETURN_ERROR(confirmMode   >= CC_FFCDH_CONFIRM_NUM_OFF_MODE, CC_FFCDH_INVALID_CONFIRM_MODE_ERROR);
+
+        /* Get internal context structure */
+        pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff;
+
+        /* check that FFC params Set in Domain meets to given by input value. */
+        CHECK_AND_SET_ERROR(pDomain->ffcParamSetId != ffcParamSetId, CC_FFCDH_INVALID_DOMAIN_DATA_ERROR);
+
+        /* get HASH related parameters */
+        CHECK_ERROR(FfcGetHashMode(&hashMode, NULL/*pHkdfHashMode*/, NULL/*pBlockSize*/, &hashSize, ffcHashMode/*in*/));
+
+        /* get DH Domain related parameters */
+        CHECK_ERROR(FfcGetDomainSizes(NULL/*pMaxSecurStrengthBytes*/, &ffcPrimeSize/*pPrimeLenBytes*/,
+                &ffcOrderSize/*pOrderLenBytes*/, &minHashSize, ffcParamSetId));
+
+        /* check that Domain generation parameters are meets to given Domain sizes set ffcParamSetId. */
+        CHECK_AND_SET_ERROR((pDomain->modLenWords * CC_32BIT_WORD_SIZE != ffcPrimeSize) ||
+                    (pDomain->ordLenWords * CC_32BIT_WORD_SIZE != ffcOrderSize) ||
+                    (pDomain->ffcHashMode != ffcHashMode), CC_FFCDH_INVALID_DOMAIN_DATA_ERROR);
+
+        /* check HASH mode (size) according to standard security for FFC Sizes Set:
+         * SP 800-56A rev.2, tab.6,8 */
+        CHECK_AND_SET_ERROR(hashSize < minHashSize, CC_FFCDH_INVALID_LOW_HASH_SIZE_ERROR);
+
+        /* check confirmation mode according to Scheme and user party (U,V).
+           Note: in other schemes allowed all modes */
+        if(confirmMode != CC_FFCDH_CONFIRM_NOT_USED) {
+            /* check Scheme and Confirmation accordance */
+            CHECK_AND_SET_ERROR(
+               (dhSchemeId == CC_FFCDH_SCHEM_EPHEM)         ||
+           ((dhSchemeId == CC_FFCDH_SCHEM_ONE_FLOW) &&
+            (confirmMode != CC_FFCDH_CONFIRM_V_TO_U))   ||
+           ((dhSchemeId == CC_FFCDH_SCHEM_HYBRID_ONE_FLOW) &&
+            (confirmMode != CC_FFCDH_CONFIRM_U_TO_V)),
+            CC_FFCDH_INVALID_CONFIRM_MODE_ERROR);
+
+                /* if confirmation is used, then check MacTag size */
+                CHECK_AND_SET_ERROR((macTagSize > CC_FFCDH_MAX_SIZE_OF_CONFIRM_MAC_TAG_BYTES) ||
+                                (macTagSize < CC_FFCDH_MIN_SIZE_OF_CONFIRM_MAC_TAG_BYTES),
+                                CC_FFCDH_MAC_TAG_SIZE_INVALID_ERROR);
+                /* set MacTag size */
+                pDhCtx->macTagSize = macTagSize;
+        }
+
+        /* check the optional HMAC salt, used in key derivation on HMAC mode */
+        CHECK_AND_SET_ERROR((pHmacSalt != NULL) != (hmacSaltSize != 0),
+                    CC_FFCDH_INVALID_HMAC_SALT_PARAMS_ERROR);
+
+
+        /*------------------------------------------*/
+        /*            set DH Scheme parameters      */
+        /*------------------------------------------*/
+
+        /* HMAC KDF parameters */
+        if(kdfMode == CC_FFCDH_KDF_HMAC_RFC5869_MODE) {
+        /* check that the user not trying to pass redundant HMAC salt */
+        CHECK_AND_SET_ERROR((pHmacSalt == NULL) || (hmacSaltSize == 0), CC_FFCDH_INVALID_HMAC_SALT_PARAMS_ERROR);
+        }
+#ifdef CC_FFCDH_KDF_HMAC_ONE_STEP_MODE
+        else if(kdfMode == CC_FFCDH_KDF_HMAC_SINGLE_STEP_MODE) {
+            CHECK_AND_SET_ERROR((pHmacSalt == NULL) ||
+                        (hmacSaltSize != DhHashBlockAndDigestSizes[hashMode].blockSizeInBytes),
+                            CC_FFCDH_INVALID_HMAC_SALT_PARAMS_ERROR);
+        }
+        else {
+            err = CC_FFCDH_INVALID_KDF_MODE_ERROR;
+            goto End;
+        }
+#endif
+
+        /* copy FFC Domain into DH context */
+        CC_PalMemCopy(&pDhCtx->ffcDomain, pDomain, sizeof(pDhCtx->ffcDomain));
+
+        /* copy given Salt into DH context */
+        if(pHmacSalt != NULL) {
+            pDhCtx->hmacSaltSizeBytes = hmacSaltSize;
+                CC_PalMemCopy(pDhCtx->hmacSalt, pHmacSalt, hmacSaltSize);
+                pDhCtx->hmacSaltSizeBytes = hmacSaltSize;
+        }
+
+        /* set DH Scheme parameters into Context */
+        pDhCtx->dhSchemeId   = dhSchemeId;
+        pDhCtx->ffcHashMode  = ffcHashMode;
+        pDhCtx->kdfMode      = kdfMode;
+        pDhCtx->userParty    = userParty;
+        pDhCtx->confirmMode  = confirmMode;
+        pDhCtx->ffcParamSet  = ffcParamSetId;
+        pDhCtx->nonceSize    = ffcOrderSize;
+        pDhCtx->secretKeyingDataSize = secretKeyingDataSize;
+        pDhCtx->macTagSize = macTagSize;
+
+        /* set required size of keying material to be derived according to confirmation mode and HMAC size */
+        if(confirmMode < CC_FFCDH_CONFIRM_NOT_USED) {
+            pDhCtx->derivedKeyingMaterialSize = secretKeyingDataSize + CC_FFCDH_SIZE_OF_CONFIRM_MAC_KEY_IN_BYTES;
+        }
+
+        err = FfcDhSchemeInfo(pDhCtx, pAlgId, algIdSize, pUserId, userIdSize, pPartnId, partnIdSize);
+        if(err)
+            goto End;
+
+//        ffcOrderSize = pDhCtx->ffcDomain.ordLenBytes;
+//
+//        /* size of shared secret ZZ */
+//        zzSize = pDhCtx->ffcDomain.modLenBytes;
+//        if((dhSchemeId == CC_FFCDH_SCHEM_HYBRID1) || (dhSchemeId == CC_FFCDH_SCHEM_HYBRID_ONE_FLOW)) {
+//          zzSize += pDhCtx->ffcDomain.modLenBytes;
+//        }
+
+         /* set validation tag */
+        pDhUserCtx->validTag |= FFCDH_CTX_VALID_TAG_SCHEM_PARAM_BIT;
+
+End:
+        if (err != CC_OK) {
+                /* delete secure sensitive data */
+                CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+    }
+
+        return err;
+
+}/* END OF CC_FfcDhCtxSetSchemeParams function */
+
+
+
+/*******************************************************************************************/
+/*! The function generates public/private FFC Key pair according to
+ *  NIST SP 800-56A rev.2 standard.
+ *  Assumed: all in/out pointers and contexts content are correct;
+ *           all arrays are set with little endianness order of bytes and words;
+ *           size of output private key = FFC generator order size;
+ *           size of output public key = FFC prime (module) size;
+ *           leading zeros are given, if existing.
+ */
+static CCError_t FfcDhGenKeyPair ( // RL check, that result keys are put out in CC only on end of generation
+            CCFfcDomain_t *pFfcDomain,    /*!< [in] pointer to DH FFC Domain structure. */
+            CCRndContext_t *pRndContext,    /*!< [in] random generation function context. */
+            uint32_t *pPrivKey,             /*!< [out] pointer to private key buffer. */
+            uint32_t *pPublKey)             /*!< [out] pointer to public key buffer. */
+{
+    CCError_t err = CC_OK;
+
+    uint32_t primeModSize = pFfcDomain->modLenWords*CC_32BIT_WORD_SIZE;
+    uint32_t ffcOrderSize = pFfcDomain->ordLenWords*CC_32BIT_WORD_SIZE;
+
+    /* generate random in range [1, q-1]- little endianness  */
+    err = CC_RndGenerateVectorInRange(
+            pRndContext,                             /*in*/
+            pFfcDomain->ordLenWords*CC_BITS_IN_32BIT_WORD, /*rndSizeInBits*/
+            (uint8_t*)&pFfcDomain->order[0],         /*maxVect*/
+            (uint8_t*)pPrivKey);                     /*out*/
+
+    if (err != CC_OK) {
+        goto End;
+    }
+
+// RL convert bytes to words only for #ifdef BIG__ENDIAN
+    /* convert key to big endianness bytes */
+//  CC_CommonReverseMemcpy(pPrivKey, pPrivKey, ffcOrderSize);
+
+
+    /* ----------------------------------------------------------- */
+    /*           Create the public key                             */
+    /* ----------------------------------------------------------- */
+    err = PkiExecModExpLeW(
+        pPublKey,                       /*public key - out*/
+        pFfcDomain->genG,               /*generator G*/
+        primeModSize,                   /*generator size in words*/
+        pFfcDomain->prime,              /*prime P*/
+        primeModSize*CC_BITS_IN_BYTE,   /*P size in bits*/
+        pPrivKey,                       /*priv.key - exponent*/
+        ffcOrderSize);                   /*priv.key size in word*/
+
+    /* check error */
+    if (err != CC_OK) {
+        goto End;
+    }
+
+
+End:
+    return err;
+
+}
+
+
+/*******************************************************************************************/
+/*!
+@brief The function generates FFC DH key pairs according to DH Scheme and NIST SP 800-56A rev.2 standard:
+<ol><li> - count of required key pairs (one or two is dependent on DH Scheme and user Party (U or V),
+inserted into Context. For each of key pair the function performs the following steps: </li>
+<li> - randomly generates the private key X according to section 5.6.1.1 and FIPS 184-4, B.1.1; </li>
+<li> - the sizes of primes P,Q should be taken from DH FFC sizes set previously inserted into Context;  </li>
+<li> - calculates the associated public key  Y = G^X mod P; </li>
+<li> - sets private and public keys in appropriate place in the Context according to user party (U,V) and keys
+status (static, ephemeral); </li>
+<li> - exports the public key as big endianness order of bytes. </li></ol>
+\note Before calling of this function, DH context should be initialized, DH Scheme parameters and
+DH Domain are inserted by calling appropriate functions, else the function returns an error.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcDhGeneratePublPrivKeys(
+                                CCFfcDhUserContext_t *pDhUserCtx,/*!< [in/out] pointer to DH FFC User Context structure. */
+                                CCRndContext_t *pRndContext )     /*!< [in] random generation function context. */
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+        /* temp pointers */
+        uint32_t *pPrivKey, *pPublKey;
+//        uint8_t *pprime;
+//        uint32_t nonceSize;
+        DhContext_t *pDhCtx; /* pointer to the internal DH context structure */
+        /* RND state and function pointers */
+        CCRndState_t   *pRndState;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* check contexts pointers and tags */
+    CHECK_AND_RETURN_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+        /* check that DhCtx is valid for user keys generation step: *
+        *  DH Scheme and Domain are set.                           */
+    CHECK_AND_RETURN_ERROR(FFCDH_CHECK_CTX_VALID_TAG_BITS(pDhUserCtx->validTag, FFCDH_CTX_VALID_TAG_INIT_VAL),
+                                                   CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR);
+
+        /* Check RND context pointer. Note: full check of context will be  *
+        *  performed in the called CC_RndGenerateVectorInRange function */
+    CHECK_AND_RETURN_ERROR(pRndContext == NULL, CC_RND_CONTEXT_PTR_INVALID_ERROR);
+        pRndState = (CCRndState_t*)&(pRndContext->rndState);
+        RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
+        CHECK_AND_RETURN_ERROR(RndGenerateVectFunc == NULL, CC_RND_GEN_VECTOR_FUNC_ERROR);
+
+        pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff; /* get internal DH context */
+//        pBaseAddr = &pDhCtx->extendDataBuffer[0];
+
+        /* get FFC domain parameters */
+//        ffcOrderSize = pDhCtx->ffcDomain.modLenBytes;
+//        ffcOrderSize = pDhCtx->ffcDomain.ordLenBytes;
+//        pprime = &pDhCtx->ffcDomain.prime[0];
+
+//        nonceSize = pDhCtx->ffcDomain.ordLenBytes;
+
+
+        /* ------------------------------------------------------------  *
+         *  Generate user private and public keys using method, defined  *
+         *  in FIPS 186-4 B.1.2 (by testing candidates)                  *
+         * ------------------------------------------------------------  */
+
+        /* static key pair */
+    if(pDhCtx->schemeInfo.doUserStatKey == 1) {
+        /* set static key */
+        pPrivKey = &pDhCtx->statPrivKey[0];
+        pPublKey = &pDhCtx->userStatPublKey[0];
+        /* generate static private and public keys */
+        err = FfcDhGenKeyPair(&pDhCtx->ffcDomain, pRndContext, pPrivKey, pPublKey);
+        if (err != CC_OK) {
+            goto End;
+        }
+        pDhCtx->validTag |= FFCDH_CTX_VALID_TAG_USER_STAT_KEY_BIT;
+
+    }
+    /* ephemeral key pair */
+    if(pDhCtx->schemeInfo.doUserEphemKey == 1){
+        pPrivKey = &pDhCtx->ephemPrivKey[0];
+        pPublKey = &pDhCtx->userEphemPublKey[0];
+        /* generate static private and public keys */
+        err = FfcDhGenKeyPair(&pDhCtx->ffcDomain, pRndContext, pPrivKey, pPublKey);
+        if (err != CC_OK) {
+            goto End;
+        }
+        pDhCtx->validTag |= FFCDH_CTX_VALID_TAG_USER_EPHEM_KEY_BIT;
+    } else if(pDhCtx->schemeInfo.doUserNonce == 1) {
+        /* generate random nonce */
+        CHECK_ERROR(RndGenerateVectFunc(pRndState, pDhCtx->userNonce, pDhCtx->nonceSize));
+        pDhCtx->validTag |= FFCDH_CTX_VALID_TAG_USER_NONCE_BIT;
+    }
+
+End:
+        if (err != CC_OK) {
+                /* delete secure sensitive data */
+                CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+    }
+
+        return err;
+
+}/* END OF CC_FfcDhGeneratePublPrivKeys function */
+
+
+
+
+/*******************************************************************************************/
+/*!
+@brief This function validates the FFC DH public key according to NIST SP 800-56A rev.2,
+       sec.5.6.2.3.1 and checking mode:
+
+<ul><li> - on "partial" mode - checks the pointers and high/low limits of key value;</li>
+<li> - on "full" mode - checks also that the the key belongs to the FFC subgroup; </li></ul>
+\note Before calling of this function, appropriate FFC Domain parameters should be obtained and validated,
+else the function returns an error.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcDhValidatePublKey(
+            CCFfcDomain_t *pDomain,          /*!< [in/out] pointer to DH FFC Context structure. */
+            uint8_t *pPublKeyData,             /*!< [in] pointer to given DH FFC public key formatted as big endianness array;
+                                     it should be in range [2, P-2], where P is the Domain Prime P. */
+            size_t publKeyDataSize,            /*!< [in] pointer to public key size, in bytes: should be not great than Prime size. */
+
+            CCFfcDhKeyValidMode_t validatMode, /*!< [in] enumerator ID defining the validation mode:
+                                     CC_FFCDH_CHECK_FULL_MODE - full validation (sec. 5.6.2.3.1);
+                                     CC_FFCDH_CHECK_PARTIAL_MODE - check pointers, sizes and range of values. */
+            uint32_t *pTmpBuff)                 /*!< [in] temporary buffer of size not less Prime size. */
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+    uint32_t *pPrime;
+    uint32_t *pPublKey32;
+        size_t  primeSizeBytes;
+        size_t  primeSizeWords, orderSizeWords;
+        uint32_t  one;
+        CCCommonCmpCounter_t cmp;
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+
+        /* ............... check parameters validity ................... */
+        /* ------------------------------------------------------------- */
+
+        CHECK_AND_RETURN_ERROR(pDomain == NULL, CC_FFCDH_INVALID_DOMAIN_PTR_ERROR);
+        CHECK_AND_RETURN_ERROR(pDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG,
+                           CC_FFCDH_INVALID_DOMAIN_DATA_ERROR);
+        CHECK_AND_RETURN_ERROR((pPublKeyData == NULL) || (pTmpBuff == NULL),
+                    CC_FFCDH_INVALID_PUBL_KEY_PTR_ERROR);
+        CHECK_AND_RETURN_ERROR(publKeyDataSize == 0, CC_FFCDH_INVALID_PUBLIC_KEY_SIZE_ERROR);
+
+        /* get FFC domain parameters */
+        primeSizeWords = pDomain->modLenWords;
+    orderSizeWords = pDomain->ordLenWords;
+        primeSizeBytes = primeSizeWords*CC_32BIT_WORD_SIZE;
+
+        pPrime = &pDomain->prime[0];
+        pPublKey32 = pTmpBuff;
+
+
+        /* check input enumerators */
+        CHECK_AND_RETURN_ERROR(validatMode >= CC_FFCDH_KEY_VALIDAT_NUM_OFF_MODE,
+                       CC_FFCDH_INVALID_VALIDAT_MODE_ERROR);
+
+    /* convert pPublKeyData to LE words array */
+        CHECK_ERROR(CC_CommonConvertMsbLsbBytesToLswMswWords(pPublKey32/*out32*/, primeSizeBytes,
+                                     pPublKeyData/*in8*/, publKeyDataSize));
+
+        /*----------------------------------------------------------------------*/
+        /*   Public Key Validation: sec.5.6.2.3.1, step.1 (partial validation)  */
+        /*----------------------------------------------------------------------*/
+        /* preliminary check the key size */
+//        CHECK_AND_SET_ERROR(publKeyDataSize != ffcPrimeSize, CC_FFCDH_INVALID_PUBLIC_KEY_SIZE_ERROR);
+
+    /* check public key value range [2,P-2]:  1 < publKey < P-1; */
+        pPrime[0] -= 1; /*temporary set P = P-1*/
+    cmp = CC_CommonCmpLsWordsUnsignedCounters(pPrime, primeSizeWords, pPublKey32, primeSizeWords);
+    CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1GreaterThenCounter2, CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR);
+    pPrime[0] += 1; /*repair P */
+    /* compare to 1 */
+    one = 1;
+    cmp = CC_CommonCmpLsWordsUnsignedCounters(pPublKey32, primeSizeWords, &one, 1);
+    CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1GreaterThenCounter2,
+                CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR);
+
+
+        /*--------------------------------------------------------------------*/
+        /*         For Full Validation perform step.2 of sec.5.6.2.3.1:       */
+    /*               check, that 1 = (PublKey ^ FfcOrder) mod P.                   */
+        /*--------------------------------------------------------------------*/
+    if(validatMode == CC_FFCDH_KEY_VALIDAT_FULL_MODE) {
+
+        err = PkiExecModExpLeW(
+            pPublKey32,                       /*result - out*/
+            pPublKey32,                       /*public key - in*/
+            primeSizeWords,                   /*public key size - in*/
+            pPrime,                           /*prime P - modulus*/
+            primeSizeWords*CC_BITS_IN_32BIT_WORD, /*P size in bits*/
+            &pDomain->order[0],  /* sub-group order Q*/
+            orderSizeWords);                  /* Q size in words*/
+
+        /* check error */
+        if (err != CC_OK) {
+            goto End;
+        }
+
+        cmp = CC_CommonCmpLsWordsUnsignedCounters(pPublKey32, primeSizeWords, &one, 1);
+        CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1AndCounter2AreIdentical,
+                    CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR);
+    }
+
+End:
+
+    CC_PalMemSetZero((uint8_t*)pTmpBuff, primeSizeBytes);
+
+    return err;
+
+} /* CC_FfcDhValidatePublKey */
+
+
+
+/*******************************************************************************************/
+/*!
+@brief The function checks and sets the FFC DH partner's public key into DH Context
+according to NIST SP 800-56A rev.2 sec.5.6.2.3.1 and checking mode:
+
+<ul><li> - if the key belongs to user's party, then the function returns an error, meaning
+that the user should use other function to import both public and private keys together;</li>.
+<li> - on "partial" mode - checks the pointers and high/low limits of key value;</li>
+<li> - on "full" mode - checks also that the the key belongs to the FFC subgroup; </li>
+<li> - sets the key data into DH Context according to party's role and key status. </li></ul>
+\note Before calling of this function, DH context should be initialized and Scheme and FFC Domain
+parameters are inserted by calling appropriate functions, else the function returns an error.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcDhValidateAndImportPublKey(
+                                CCFfcDhUserContext_t *pDhUserCtx,  /*!< [in/out] pointer to DH FFC Context structure. */
+                                uint8_t *pPublKeyData,             /*!< [in] pointer to given DH FFC public key or Nonce in big endianness;
+                                                                          it should be in range [2, P-2], where P is the Domain Prime. */
+                                size_t publKeyDataSize,            /*!< [in] public key size, in bytes: should be not great than Domain Prime size. */
+                                CCFfcDhKeyValidMode_t validatMode, /*!< [in] enumerator ID defining the validation mode:
+                                                                           CC_FFCDH_CHECK_FULL_MODE - full validation (sec. 5.6.2.3.1);
+                                                                           CC_FFCDH_CHECK_PARTIAL_MODE - check pointers, sizes and range of values. */
+                                CCFfcDhKeyStatus_t keyStatus       /*!< [in] enumerator, defining the key status according to its life time
+                                                                          or purpose: static/ephemeral */
+)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+        DhContext_t *pDhCtx; /* internal DH context */
+        CCFfcDomain_t *pFfcDomain;
+        uint32_t *pPublKey32, *pPublKeySizeBytes;
+        uint32_t  primeSizeBytes, primeSizeWords, previousKeySize;
+        uint32_t testBit = 0;
+
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check contexts pointers and tags */
+        CHECK_AND_RETURN_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+        /* check that DhCtx is valid for user keys generation step: *
+        *  DH Scheme and Domain are set.                           */
+        CHECK_AND_SET_ERROR(FFCDH_CHECK_CTX_VALID_TAG_BITS(pDhUserCtx->validTag,
+                   FFCDH_CTX_VALID_TAG_SCHEM_PARAM_SET), CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR);
+
+        /* Get internal context structure */
+        pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff;
+        pFfcDomain = &pDhCtx->ffcDomain;
+        /* check domain validation tag */
+        CHECK_AND_SET_ERROR(pFfcDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG,
+                    CC_FFCDH_INVALID_DOMAIN_DATA_ERROR);
+
+        /* get FFC domain parameters */
+        primeSizeWords = pFfcDomain->modLenWords;
+        primeSizeBytes = primeSizeWords*CC_32BIT_WORD_SIZE;
+
+        CHECK_AND_SET_ERROR(pPublKeyData == NULL, CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR);
+        /* check input enumerators */
+        CHECK_AND_SET_ERROR(keyStatus >= CC_FFCDH_KEY_STATUS_NUM_OFF_MODE, CC_FFCDH_INVALID_KEY_STATUS_ERROR);
+        CHECK_AND_SET_ERROR(validatMode >= CC_FFCDH_KEY_VALIDAT_NUM_OFF_MODE, CC_FFCDH_INVALID_VALIDAT_MODE_ERROR);
+        /* preliminary check of public key size */
+        CHECK_AND_SET_ERROR(publKeyDataSize == 0, CC_FFCDH_INVALID_PUBLIC_KEY_SIZE_ERROR);
+
+        /* check that the key meets to scheme requirements and set the pointer to
+         * the appropriate place in the context */
+    if(keyStatus == CC_FFCDH_KEY_STATIC) {
+        previousKeySize = pDhCtx->partnerStatPublKeySizeBytes; /*size of previous inserted key*/
+        if(pDhCtx->schemeInfo.doPartnerStatKey == 1) {
+            pPublKey32 = pDhCtx->partnerStatPublKey;
+            pPublKeySizeBytes = &pDhCtx->partnerStatPublKeySizeBytes;
+            testBit = FFCDH_CTX_VALID_TAG_PARTN_STAT_KEY_BIT;
+
+        } else {
+            err = CC_FFCDH_THE_KEY_IS_NOT_REQUIRED_ERROR;
+            goto End;
+        }
+    } else if(keyStatus == CC_FFCDH_KEY_EPHEMER) {
+        previousKeySize = pDhCtx->partnerEphemPublKeySizeBytes; /*size of previous inserted key*/
+        if(pDhCtx->schemeInfo.doPartnerEphemKey == 1) {
+            pPublKey32 = pDhCtx->partnerEphemPublKey;
+            pPublKeySizeBytes = &pDhCtx->partnerEphemPublKeySizeBytes;
+            testBit = FFCDH_CTX_VALID_TAG_PARTN_EPHEM_KEY_BIT;
+        } else {
+            err = CC_FFCDH_THE_KEY_IS_NOT_REQUIRED_ERROR;
+            goto End;
+        }
+    }
+
+    /* check that other key wasn't inserted previously on this place */
+        CHECK_AND_SET_ERROR(previousKeySize != 0, CC_FFCDH_ILLEGAL_TRY_REWRITE_PARAM_ERROR);
+
+       /* Check Public Key Data validity */
+        err = CC_FfcDhValidatePublKey(
+                &pDhCtx->ffcDomain,
+                pPublKeyData,
+                        publKeyDataSize, /*size with leading zeros*/
+                        validatMode,
+                        (uint32_t*)&pDhCtx->tmpBuff);
+
+        if (err != CC_OK) {
+                goto End;
+        }
+
+        /* copy the public key into context as LE words array. */
+        CHECK_ERROR(CC_CommonConvertMsbLsbBytesToLswMswWords(pPublKey32/*out32*/, primeSizeBytes,
+                                     pPublKeyData/*in8*/, publKeyDataSize));
+
+        *pPublKeySizeBytes = primeSizeBytes;
+
+        /* set valid tag bit according to key status */
+        pDhCtx->validTag |= testBit;
+
+End:
+        if (err != CC_OK) {
+                /* delete secure sensitive data */
+                CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+    }
+
+        return err;
+}
+
+/*******************************************************************************************/
+/*!
+@brief The function checks and sets the FFC DH user's private/public key pair into DH Context
+according to NIST SP 800-56A rev.2 sec.5.6.2.3.1 and checking mode:
+
+<ul><li> - if the key belongs to partner's party, then the function returns an error, meaning
+that the user should use other function to import only public key;</li>.
+<li> - on "partial" mode - checks the pointers and high/low limits of key value;</li>
+<li> - on "full" mode - checks also that the the public key meets to private key; </li>
+<li> - sets the key data into DH Context according to party's role and key status. </li></ul>
+\note Before calling of this function, DH context should be initialized and Scheme and FFC Domain
+parameters are inserted by calling appropriate functions, else the function returns an error.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcDhValidateAndImportKeyPair(
+                                CCFfcDhUserContext_t *pDhUserCtx,  /*!< [in/out] pointer to DH FFC Context structure. */
+                                uint8_t *pPrivKeyData,             /*!< [in] pointer to given DH FFC private key in big endianness;
+                                                                             it should be in range [1, n-1], where n is the Domain generator order. */
+                                size_t privKeyDataSize,            /*!< [in] private key size, in bytes: should be equaled Domain
+                                                                             generator order size. */
+                                uint8_t *pPublKeyData,             /*!< [in] pointer to given DH FFC public key in big endianness;
+                                                                          it should be in range [2, P-2], where P is the Domain Prime. */
+                                size_t publKeyDataSize,            /*!< [in] public key size, in bytes: should be equaled to Domain Prime size,
+                                                                             including leading zeros. */
+                                CCFfcDhKeyValidMode_t validatMode, /*!< [in] enumerator ID defining the validation mode:
+                                                                             CC_FFCDH_CHECK_FULL_MODE - full validation (sec. 5.6.2.3.1);
+                                                                             CC_FFCDH_CHECK_PARTIAL_MODE - check pointers, sizes and range of values. */
+                                CCFfcDhKeyStatus_t keyStatus       /*!< [in] enumerator, defining the key status according to its life time
+                                                                             or purpose: static/ephemeral/nonce */
+)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t err = CC_OK;
+        DhContext_t *pDhCtx; /* internal DH context */
+        CCFfcDomain_t *pFfcDomain;
+        uint32_t *pPublKey32, *pPrivKey32;
+//        uint16_t   *pPublKey32Size;
+        uint32_t  *pPrime, *pOrder, one = 0;
+        size_t  primeSizeBytes, orderSizeBytes;
+        size_t  primeSizeWords, orderSizeWords;
+        uint32_t  testBit;
+        uint32_t  *pPrivKeySize, *pPublKeySize;
+//        uint8_t  *pBaseAddr; /* start address for offsets counting */
+//        CCFfcDhCtxPublKeys_t *pPublKey32s;
+        CCCommonCmpCounter_t cmp;
+//        bool isKeyRequested;
+        uint32_t *pTmpBuff; /* used size = Prime size */
+
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check contexts pointers and tags */
+        CHECK_AND_RETURN_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+        /* check that DhCtx is valid for user keys generation step: *
+        *  DH Scheme and Domain are set.                           */
+        CHECK_AND_SET_ERROR(FFCDH_CHECK_CTX_VALID_TAG_BITS(pDhUserCtx->validTag,
+                FFCDH_CTX_VALID_TAG_DOMAIN_SET), CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR );
+
+        /* preliminary check of private/public key pointers and sizes */
+        CHECK_AND_SET_ERROR(pPrivKeyData == NULL, CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR);
+        CHECK_AND_SET_ERROR(pPublKeyData == NULL, CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR);
+        CHECK_AND_SET_ERROR(privKeyDataSize == 0, CC_FFCDH_INVALID_PRIVATE_KEY_SIZE_ERROR);
+        CHECK_AND_SET_ERROR(publKeyDataSize == 0, CC_FFCDH_INVALID_PUBLIC_KEY_SIZE_ERROR);
+
+        /* check input enumerators */
+        CHECK_AND_SET_ERROR(keyStatus >= CC_FFCDH_KEY_STATUS_NUM_OFF_MODE, CC_FFCDH_INVALID_KEY_STATUS_ERROR);
+        CHECK_AND_SET_ERROR(validatMode >= CC_FFCDH_KEY_VALIDAT_NUM_OFF_MODE, CC_FFCDH_INVALID_VALIDAT_MODE_ERROR);
+
+        /* Get internal context structure */
+        pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff;
+        pFfcDomain = &pDhCtx->ffcDomain;
+        /* check domain validation tag */
+        CHECK_AND_SET_ERROR(pFfcDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG, CC_FFCDH_INVALID_DOMAIN_DATA_ERROR);
+
+        /* get FFC domain parameters */
+        primeSizeWords = pFfcDomain->modLenWords;
+        orderSizeWords = pFfcDomain->ordLenWords;
+        primeSizeBytes = primeSizeWords*CC_32BIT_WORD_SIZE;
+        orderSizeBytes = orderSizeWords*CC_32BIT_WORD_SIZE;
+
+        pPrime = &pDhCtx->ffcDomain.prime[0]; /* Prime p */
+        pOrder = &pDhCtx->ffcDomain.order[0]; /* Order q */
+        pTmpBuff = &pDhCtx->tmpBuff.TempBuff[0]; /* used size = Prime size */
+
+        /* set base address for offsets counting */
+//        pBaseAddr = &pDhCtx->extendDataBuffer[0];
+
+        /* check that the key meets to scheme requirements and set the pointers to
+         * appropriate place in the context */
+    if(keyStatus == CC_FFCDH_KEY_STATIC) {
+        if(pDhCtx->schemeInfo.doUserStatKey == 1) {
+            pPrivKey32 = &pDhCtx->statPrivKey[0];
+            pPublKey32 = &pDhCtx->userStatPublKey[0];
+            testBit = FFCDH_CTX_VALID_TAG_USER_STAT_KEY_BIT;
+            pPrivKeySize = &pDhCtx->statPrivKeySizeBytes;
+            pPublKeySize = &pDhCtx->userStatPublKeySizeBytes;
+        } else {
+            err = CC_FFCDH_INVALID_KEY_STATUS_ERROR;
+            goto End;
+        }
+    } else if(keyStatus == CC_FFCDH_KEY_EPHEMER) {
+        if(pDhCtx->schemeInfo.doUserEphemKey == 1) {
+            pPrivKey32 = &pDhCtx->ephemPrivKey[0];
+            pPublKey32 = &pDhCtx->userEphemPublKey[0];
+            testBit = FFCDH_CTX_VALID_TAG_USER_EPHEM_KEY_BIT;
+            pPrivKeySize = &pDhCtx->ephemPrivKeySizeBytes;
+            pPublKeySize = &pDhCtx->userEphemPublKeySizeBytes;
+        } else {
+            err = CC_FFCDH_INVALID_KEY_STATUS_ERROR;
+            goto End;
+        }
+    }
+
+    /* check that the key is not inserted previously */
+    CHECK_AND_SET_ERROR((*pPrivKeySize != 0) || (*pPublKeySize != 0),
+                CC_FFCDH_ILLEGAL_TRY_REWRITE_PARAM_ERROR);
+
+    /* convert the keys to LE words array and set into Context */
+        CHECK_ERROR(CC_CommonConvertMsbLsbBytesToLswMswWords(pPublKey32/*out32*/, primeSizeBytes,
+                                     pPublKeyData/*in8*/, publKeyDataSize));
+        CHECK_ERROR(CC_CommonConvertMsbLsbBytesToLswMswWords(pPrivKey32/*out32*/, orderSizeBytes,
+                                     pPrivKeyData/*in8*/, privKeyDataSize));
+
+    /* check private key value range [1,q-1]:  1 <= privlKey <= q-1; */
+    cmp = CC_CommonCmpLsWordsUnsignedCounters(pOrder, orderSizeWords, pPrivKey32, orderSizeWords);
+    CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1GreaterThenCounter2, CC_FFCDH_INVALID_PRIVATE_KEY_VALUE_ERROR);
+    one = 0;
+    cmp = CC_CommonCmpLsWordsUnsignedCounters(pPrivKey32, orderSizeWords, &one, 1);
+    CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1GreaterThenCounter2, CC_FFCDH_INVALID_PRIVATE_KEY_VALUE_ERROR);
+
+    /* check public key value range [2,p-2]:  1 < privlKey < p-1; */
+    pPrime[0] -= 1;
+    cmp = CC_CommonCmpLsWordsUnsignedCounters(pPrime, primeSizeWords, pPublKey32, primeSizeWords);
+    CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1GreaterThenCounter2, CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR);
+    pPrime[0] += 1; /*reset p*/
+    one = 1;
+    cmp = CC_CommonCmpLsWordsUnsignedCounters(pPublKey32, primeSizeWords, &one, 1);
+    CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1GreaterThenCounter2, CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR);
+
+
+        /* copy private and public key data into context and set leading zeros */
+//        CC_PalMemCopy(pPrivKey32 + (ffcOrderSize - privKeyDataSize), pPrivKeyData, privKeyDataSize);
+//        CC_PalMemSet(pPrivKey32, 0, (ffcOrderSize - privKeyDataSize)); /*zeroing leading zeros*/
+//        CC_PalMemCopy(pPublKey32 + (ffcPrimeSize - publKeyDataSize), pPublKeyData, publKeyDataSize);
+//        CC_PalMemSet(pPublKey32, 0, (ffcPrimeSize - publKeyDataSize)); /*zeroing leading zeros*/
+
+
+        /* Full check of Public Key Data validity by recomputing the public key from private:
+         * (SP 56A rev.2, sec.5.6.2.1.4).  */
+    if(validatMode == CC_FFCDH_KEY_VALIDAT_FULL_MODE) {
+        /* calculate PublKey as LE words array */
+        err = PkiExecModExpLeW(
+            pTmpBuff,               /*exp.result - out*/
+            &pFfcDomain->genG[0],   /*FFC generator - in*/
+            primeSizeWords,         /*generator size - in*/
+            pPrime,                 /*prime P - modulus*/
+            primeSizeWords*CC_BITS_IN_32BIT_WORD, /*P size in bits*/
+            pPrivKey32,             /* private key */
+            orderSizeWords);        /* private key full size in bytes */
+
+        /* check error */
+        if (err != CC_OK) {
+            goto End;
+        }
+
+        /* check that recalculated publ. key is equaled to input key. */
+        cmp = CC_CommonCmpLsWordsUnsignedCounters(pTmpBuff, primeSizeWords, pPublKey32, primeSizeWords);
+        CHECK_AND_SET_ERROR(cmp != CC_COMMON_CmpCounter1AndCounter2AreIdentical, CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR);
+    }
+
+
+        /* set valid tag bit according to key status */
+    pDhCtx->validTag |= testBit;
+
+End:
+        if (err != CC_OK) {
+                /* delete secure sensitive data */
+                CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+    }
+
+        return err;
+}
+
+
+/*******************************************************************************************/
+/*!
+@brief This function generates random Nonce, used in appropriate DH Schemes (NIST SP 56A rev.2 sec.5.9, 6).
+<li> The function generates random vector of given size, sets it into DH context according. </li>
+\note Before calling of this function, DH context should be initialized and Scheme parameters and
+DH Domain are inserted by calling appropriate functions, else the function returns an error.
+\note The Nonce should be generated and the function called only if it is required by DH scheme, and
+the Nonce is not inserted previously, else the function returns an error.
+\note The function is used when the user not generates an ephemeral key, but requires key confirmation and
+therefore Nonce generation.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcDhGenerateRandomNonce(
+                                CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to DH FFC Context structure. */
+                                CCRndContext_t *pRndContext)      /*!< [in] random generation function context. */
+{
+    CCError_t err = CC_OK;
+    DhContext_t *pDhCtx;
+//  uint8_t *pNonce;
+
+        /* RND state and function pointers */
+        CCRndState_t   *pRndState;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check context pointer and tag */
+        CHECK_AND_RETURN_ERROR(pDhUserCtx == NULL, CC_FFCDH_INVALID_CONTEXT_PTR_ERROR);
+        /* check that DhCtx is valid for user keys generation step: */
+        CHECK_AND_SET_ERROR(pDhUserCtx->validTag != FFCDH_CTX_VALID_TAG_DOMAIN_SET, CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR);
+
+        /* Get internal context structure */
+        pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff;
+
+        /* check that Nonce is required according to DH Scheme */
+        CHECK_AND_SET_ERROR(pDhCtx->schemeInfo.doUserNonce == 0, CC_FFCDH_NONCE_IS_NOT_REQUIRED_ERROR);
+
+//       /* check userParty enumerator. */
+//        CHECK_AND_SET_ERROR(userParty >= CC_FFCDH_PARTY_NUM_OFF_MODE, CC_FFCDH_INVALID_USER_PARTY_ID_ERROR);
+//
+        /* Check RND context pointer. Note: full check of RND context will be  *
+        *  performed in the called CC_RndGenerateVectorInRange function */
+    CHECK_AND_SET_ERROR(pRndContext == NULL, CC_RND_CONTEXT_PTR_INVALID_ERROR);
+        RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
+        CHECK_AND_SET_ERROR(RndGenerateVectFunc == NULL, CC_RND_GEN_VECTOR_FUNC_ERROR);
+        pRndState = (CCRndState_t*)&(pRndContext->rndState);
+
+          /* check that this Nonce is not inserted previously */
+        CHECK_AND_SET_ERROR(pDhCtx->userNonceSizeBytes != 0, CC_FFCDH_ILLEGAL_TRY_REWRITE_PARAM_ERROR);
+
+        /* generate random Nonce and set it into Context. Note: Nonce is not an integer. */
+        CHECK_ERROR(RndGenerateVectFunc(pRndState, &pDhCtx->userNonce[0], pDhCtx->nonceSize));
+
+End:
+    if (err != CC_OK) {
+        /* delete secure sensitive data */
+        CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+    }
+
+    return err;
+}
+
+
+/*******************************************************************************************/
+/*!
+@brief This function formats the UserInfo according to the user role (PartyU or PartyV) and NIST SP 56A rev.2,
+       sec. 5.8.1.2, 5.8.1.2.1.
+
+<ul><li>  Input and previously inserted data is concatenated as defined in the CCFfcDhPartyInfo_t structure and
+ sets it into the Context:  UserInfo = UserId||UserStatPublKey||UserStatPublKey||UserNonce}{||UserOtherData}, where: </li>
+<li> - UserInfo and each its sub-entry are formatted as length (Len) and then appropriate data: Len||Data,
+where each length is a 2-bytes big endianness counter; </li>
+<li> - If any sub-entry is not used in chosen DH Scheme, than its lengths should be set 0 and the data is empty. </li>
+<li> - total size of PartyInfo, including said lengths, should be not great, than the size of CCDhPartyInfo_t. </li></ul>
+\note Before calling of this function the User should initialize DH Context, insert FFC Domain, DH Scheme parameters and
+all his Private/Public Keys (or Nonce) using appropriate CC functions.
+\note The output from this function will be exported to the other party of the Agreement and vice versa, UserInfo, received
+from other party, will be used as input to DhCtxSetSchemeData() function.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcDhCreateUserInfo(
+                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to context structure, containing all data,
+                                                               used in DH Key Agreement Scheme. */
+                        uint8_t *pUserOtherData,          /*!< [in] optional, pointer to other data, which the user will
+                                                                    insert in addition to its ID, keys and Nonce. */
+                        size_t userOtherDataSize,         /*!< [in] optional, size of additional data (in bytes), which the
+                                                                    user will include into the UserInfo. */
+                        uint8_t *pUserConfirmText,        /*!< [in] optional, pointer to confirmation Text of the User. */
+                        size_t  userConfirmTextSize,      /*!< [in] optional size of Text data of partyU, in bytes. */
+                        CCFfcDhPartyInfo_t *pUserInfo,    /*!< [out] pointer to the concatenated UserInfo (i.e. PartyU or PartyV Info). */
+                        size_t *pUserInfoSize             /*!< [in/out] pointer to the size of UserInfo, in bytes:
+                                                                in -  given buffer size (should be not less than CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_ENTRY;
+                                                                out - actual size of UserInfo, including length counters */
+)
+{
+    /* FUNCTION DECLARATIONS */
+
+        CCError_t err = CC_OK; /* return error identifier */
+        DhContext_t  *pDhCtx;
+        /* actual size of UserInfo data */
+        uint8_t *pTmp; /* temp pointer */
+        uint8_t *pBaseAddr;
+        uint32_t fullLen = 0;
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check contexts pointers and tags */
+        if(pDhUserCtx == NULL) {
+            return CC_FFCDH_INVALID_CONTEXT_PTR_ERROR;
+        }
+        /* check that DhCtx is valid for user keys generation step: *
+        *  DH Scheme, Domain and Keys are set.                      */
+        CHECK_AND_SET_ERROR(pDhUserCtx->validTag != FFCDH_CTX_VALID_TAG_ALL_KEYS_SET, CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR);
+        /*  check the mandatory data pointers  */
+        CHECK_AND_SET_ERROR(pUserInfo == NULL || pUserInfoSize == NULL, CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR);
+    /* check the optional data pointers and sizes */
+        CHECK_AND_SET_ERROR((pUserOtherData == NULL) != (userOtherDataSize == 0), CC_FFCDH_OPTIONAL_DATA_ERROR);
+        CHECK_AND_SET_ERROR((pUserConfirmText == NULL) != (userConfirmTextSize == 0), CC_FFCDH_OPTIONAL_DATA_ERROR);
+
+    /* check sizes */
+        CHECK_AND_SET_ERROR(userOtherDataSize > CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_OTHER_DATA_BYTES, CC_FFCDH_PARTY_INFO_SUB_ENTRY_SIZE_ERROR);
+        CHECK_AND_SET_ERROR(userConfirmTextSize > CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES, CC_FFCDH_PARTY_INFO_SUB_ENTRY_SIZE_ERROR);
+
+        /* Get internal context structure */
+    pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff;
+
+    /* address of extended data buffer */
+    pBaseAddr = &pDhCtx->extendDataBuffer[0];
+
+    /* set temp pointer and save userOtherData in the Context */
+    pTmp = pBaseAddr + pDhCtx->dataOffsets.userIdOffset;
+
+    /* concatenate generated previously user data into context extendDataBuffer */
+    FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->userId, pDhCtx->userIdSizeBytes, &fullLen);
+    FfcDhWriteBufferLeToBe(&pTmp, pDhCtx->userStatPublKey, pDhCtx->userStatPublKeySizeBytes, &fullLen);
+    FfcDhWriteBufferLeToBe(&pTmp, pDhCtx->userEphemPublKey, pDhCtx->userEphemPublKeySizeBytes, &fullLen);
+    FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->userNonce, pDhCtx->userNonceSizeBytes, &fullLen);
+    FfcDhWriteBufferBeToBe(&pTmp, pUserOtherData, userOtherDataSize, &fullLen);
+
+
+    CHECK_AND_SET_ERROR(fullLen > *pUserInfoSize, CC_FFCDH_LOW_OUTPUT_BUFF_SIZE_ERROR);
+
+    /* output concatenated UserInfo data */
+    pDhCtx->currInsertedDataSize = fullLen;
+    pDhCtx->dataOffsets.userInfoSize = fullLen;
+    CC_PalMemCopy(pUserInfo, pBaseAddr + pDhCtx->dataOffsets.userIdOffset, fullLen);
+    /* concatenate user's Confirmation Text */
+    pTmp = (uint8_t*)&pUserInfo + fullLen;
+    FfcDhWriteBufferBeToBe(&pTmp, pUserConfirmText, userConfirmTextSize, &fullLen);
+    *pUserInfoSize = fullLen;
+
+    /* update validation tag */
+    pDhUserCtx->validTag |= FFCDH_CTX_VALID_TAG_USER_INFO_BIT;
+
+
+End:
+    if(err != CC_OK) {
+        CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+    }
+
+    return err;
+
+}
+
+
+static CCError_t FfcDhValidatePartnInfoPublKey(
+                DhContext_t  *pDhCtx,                 /*!< [in/out] pointer to internal DH Context structure. */
+                CCFfcDhKeyValidMode_t keyValidatMode, /*!< [in] enum. key validation mode */
+                uint8_t **ppCtxKey,                   /*!< [in/out] pointer to pointer to context publ.key buffer */
+                uint8_t **ppInKey)                    /*!< [in/out] pointer to pointer to partnerInfo publ.keydata */
+{
+        CCError_t err = CC_OK; /* return error identifier */
+    uint32_t size1;  /*key size in Context*/
+    uint32_t size2;  /*size received*/
+    uint8_t *pKey = *ppCtxKey;
+
+
+    /* get key sizes from Context and from the PartnerInfo */
+    size1 = FFCDH_GET_LENGTH(*ppCtxKey); /*in ctx*/
+    size2 = FFCDH_GET_LENGTH(*ppInKey);  /*in partner Info*/
+
+    /* if the key was inserted previously, compare the data, else check and import the key */
+    if(size1 == pDhCtx->ffcDomain.modLenWords*CC_32BIT_WORD_SIZE) {
+        CHECK_AND_SET_ERROR(size1 != size2,  CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+        CHECK_AND_SET_ERROR(CC_PalMemCmp(*ppCtxKey, *ppInKey, size1), CC_FFCDH_PARTN_INFO_PARSING_DATA_ERROR);
+
+    } else if(size1 == 0){
+        /* check and import the partner's key */
+        err = CC_FfcDhValidatePublKey(
+            &pDhCtx->ffcDomain,
+            *ppInKey,  size2, /*received PublKey*/
+            keyValidatMode,
+            &pDhCtx->tmpBuff.TempBuff[0]);
+        CHECK_ERROR(err);
+
+        /* copy the key into Context and set size */
+        FfcDhWriteBufferBeToBe(&pKey, *ppInKey, size2, &pDhCtx->currInsertedDataSize);
+    } else {
+        err = CC_FFCDH_PARTN_INFO_PARSING_DATA_ERROR;
+    }
+
+    /* promote pointers to next Info entries */
+    *ppCtxKey += size1;
+    *ppInKey  += size2;
+
+End:
+    return err;
+
+}
+
+
+/*******************************************************************************************/
+/*!
+@brief This function implements FFC DH primitive according to section 5.7.1.1 of NIST SP 56A rev.2 standard.
+       The function computes and concatenates the shared secret values according to DH Scheme:
+        - on all schemes:  SharedSecretVal = partnerPublKey1 ^ userPrivKey1 modulo Prime;
+        - on hybrid schemes: SharedSecretVal2 = partnerPublKey2 ^ userPrivKey2 modulo Prime, and then
+          concatenates them:  SharedSecretVal = SharedSecretVal || SharedSecretVal2;
+
+\note Before calling of this function the user should obtain assurance of public and private keys, involved in the key
+agreement, using one of methods, described in section 5.6.2 of above named standard.
+\note For assurance of keys validity the user can use appropriate APIs for generating or building and validation,
+of keys, described in CC_dh.h file.
+\note The function intended for internal using in Keying Material derivation inside CC DH functions.
+Assumed, that all required data is inserted properly in the DH Context.
+@return CC_OK on success.
+@return A non-zero value on failure as defined in cc_dh_error.h or cc_rnd_error.h.
+*/
+static CCError_t FfcDhCalcSharedSecretVal(DhContext_t *pDhCtx) /*!< [in/out] pointer to context structure, containing all data,
+                                                                       and buffers, used in DH Key Agreement Scheme. */
+
+{
+    CCError_t err = CC_OK;
+    CCFfcDomain_t *pFfcDomain = &pDhCtx->ffcDomain;
+    FfcDhSchemeInfo_t *schemeInfo = &pDhCtx->schemeInfo;
+//  FfcDhSchemeDataOffsets_t *pDataOffsets = &pDhCtx->dataOffsets;
+    uint32_t *userPrivKey1 = NULL, *partnPublKey1 = NULL;
+    uint32_t *userPrivKey2 = NULL, *partnPublKey2 = NULL;
+    uint8_t *pSharedSecretVal1 = NULL, *pSharedSecretVal2 = NULL;
+//  uint32_t publKeyDataSize = 0; //, privKeySize;
+    uint32_t primeSizeBytes, orderSizeBytes;
+    uint32_t primeSizeWords, orderSizeWords;
+    uint32_t *pZ; /* aligned pointer to Shared Secret */
+
+        /* get FFC domain parameters */
+        primeSizeWords = pFfcDomain->modLenWords;
+    orderSizeWords = pFfcDomain->ordLenWords;
+        primeSizeBytes = pFfcDomain->modLenWords*CC_32BIT_WORD_SIZE;
+    orderSizeBytes = pFfcDomain->ordLenWords*CC_32BIT_WORD_SIZE;
+
+    /* set pointers to shared secret value according to user and partner roles (U,V). */
+    if(pDhCtx->userParty == CC_FFCDH_PARTY_U) {
+        pSharedSecretVal1 = &pDhCtx->extendDataBuffer[0] + CC_FFCDH_KDF_COUNTER_SIZE_IN_BYTES;
+        pSharedSecretVal2 = pSharedSecretVal1 + primeSizeBytes;
+    } else if(pDhCtx->userParty == CC_FFCDH_PARTY_V){
+        pSharedSecretVal2 = &pDhCtx->extendDataBuffer[0] + CC_FFCDH_KDF_COUNTER_SIZE_IN_BYTES;
+        pSharedSecretVal1 = pSharedSecretVal2 + primeSizeBytes;
+    }
+
+    /* set first pointers to appropriate keys for all DH Schemes */
+    if(schemeInfo->doUserStatKey) {
+        userPrivKey1 = &pDhCtx->statPrivKey[0];
+        pDhCtx->statPrivKeySizeBytes = orderSizeBytes;
+    } else {
+        userPrivKey1 = &pDhCtx->ephemPrivKey[0];
+        pDhCtx->ephemPrivKeySizeBytes = orderSizeBytes;
+    }
+
+    if(schemeInfo->doPartnerStatKey) {
+        partnPublKey1 = &pDhCtx->partnerStatPublKey[0];
+        pDhCtx->partnerStatPublKeySizeBytes = primeSizeBytes;
+    } else {
+        partnPublKey1 = &pDhCtx->partnerEphemPublKey[0];
+        pDhCtx->partnerEphemPublKeySizeBytes = primeSizeBytes;
+    }
+
+//  publKeyDataSize = primeSizeBytes;
+    /* align pointer to address */
+    pZ = (uint32_t*)((uint32_t)pSharedSecretVal1 & (~(uint32_t)3));
+// !!!  pDhCtx-> ???
+
+    /* calculate first shared secret */
+    err = PkiExecModExpLeW(
+        pZ,              /*exp.result - out*/
+        partnPublKey1,   /*public key - in*/
+        primeSizeWords,  /*public key size - in*/
+        &pDhCtx->ffcDomain.prime[0], /*prime P - modulus*/
+        primeSizeWords*CC_BITS_IN_32BIT_WORD,  /*P size in bits*/
+        userPrivKey1,    /* sub-group order Q*/
+        orderSizeWords); /* Q size in words*/
+
+    /* check error */
+    if (err != CC_OK) {
+        goto End;
+    }
+    /* convert Z to BE bytes */
+    CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(pZ, primeSizeWords);
+
+    /* calculation of second shared secret, if needed */
+    if(pDhCtx->dhSchemeId == CC_FFCDH_SCHEM_HYBRID1 ||
+       pDhCtx->dhSchemeId == CC_FFCDH_SCHEM_HYBRID_ONE_FLOW) {
+
+        /* set second pointers to appropriate keys for all DH Schemes */
+        if(schemeInfo->doUserEphemKey) {
+            userPrivKey2 = &pDhCtx->ephemPrivKey[0];
+            pDhCtx->ephemPrivKeySizeBytes = orderSizeBytes;
+        } else {
+            userPrivKey2 = &pDhCtx->statPrivKey[0];
+            pDhCtx->statPrivKeySizeBytes = orderSizeBytes;
+        }
+
+        if(schemeInfo->doPartnerEphemKey) {
+            partnPublKey2 = &pDhCtx->partnerEphemPublKey[0];
+            pDhCtx->partnerEphemPublKeySizeBytes = primeSizeBytes;
+        } else  {
+            partnPublKey2 = &pDhCtx->partnerStatPublKey[0];
+            pDhCtx->partnerStatPublKeySizeBytes = primeSizeBytes;
+        }
+
+        /* calculate second shared secret */
+        pZ = (uint32_t*)((uint32_t)pSharedSecretVal2 & (~(uint32_t)3));
+        err = PkiExecModExpLeW(
+            pZ,            /*exp.result - out*/
+            partnPublKey2, /*public key - in*/
+            primeSizeWords, /*public key size - in*/
+            &pDhCtx->ffcDomain.prime[0],             /*prime P - modulus*/
+            primeSizeWords*CC_BITS_IN_BYTE, /*P size in bits*/
+            userPrivKey2,       /* sub-group order Q*/
+            orderSizeWords); /* Q size in words*/
+
+        /* check error */
+        if (err != CC_OK) {
+            goto End;
+        }
+
+        /* convert Z to BE bytes */
+        CC_CommonInPlaceConvertBytesWordsAndArrayEndianness(pZ, primeSizeWords);
+
+    }
+
+End:
+    if (err != CC_OK) {
+        /* delete secure sensitive data */
+        CC_PalMemSetZero((uint8_t*)pDhCtx, sizeof(DhContext_t));
+    }
+
+    return err;
+
+}
+
+#ifdef FFC_FURTHER_USING
+
+/* The function updates offsets for further using */
+static void FfcDhUpdateOffsets(DhContext_t *pDhCtx,
+                   CCFfcDhUserPartyIs_t userParty)
+{
+    uint8_t *pTmp1;
+    uint16_t size1, partnerInfoNewOffset;
+    FfcDhSchemeDataOffsets_t *dataOffsets = &pDhCtx->dataOffsets;
+    int32_t diffOffsets;
+
+    if(userParty == CC_FFCDH_PARTY_U) {
+
+        pTmp1 = &pDhCtx->extendDataBuffer[0] + pDhCtx->dataOffsets.userOtherDataOffset;
+        size1 = FFCDH_GET_LENGTH(pTmp1); /* size of user Other data*/
+        partnerInfoNewOffset = pDhCtx->dataOffsets.userOtherDataOffset + size1 +
+                           CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+        /* difference between new and old offsets */
+        diffOffsets = pDhCtx->dataOffsets.partnIdOffset - partnerInfoNewOffset;
+
+        /* move partner info to new position */
+        pTmp1 = &pDhCtx->extendDataBuffer[0] + partnerInfoNewOffset;
+        FfcDhWriteBufferBeToBe(&pTmp1, &pDhCtx->extendDataBuffer[0] + pDhCtx->dataOffsets.partnIdOffset,
+                             pDhCtx->dataOffsets.partnInfoSize + pDhCtx->dataOffsets.suppPublInfoSize +
+                             pDhCtx->dataOffsets.suppPrivInfoSize);
+        /* update */
+        dataOffsets->partnIdOffset -= diffOffsets;
+        dataOffsets->partnStatPublKeyOffset -= diffOffsets;
+        dataOffsets->partnEphemPublKeyOffset -= diffOffsets;
+        dataOffsets->partnNonceOffset -= diffOffsets;
+        dataOffsets->partnOtherDataOffset -= diffOffsets;
+
+        dataOffsets->suppPublInfoOffset = dataOffsets->partnIdOffset + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES +
+                          pDhCtx->dataOffsets.partnInfoSize;
+        dataOffsets->suppPrivInfoOffset = dataOffsets->suppPublInfoOffset + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES +
+                                      dataOffsets->suppPublInfoSize;
+    } else {
+        pTmp1 = &pDhCtx->extendDataBuffer[0] + pDhCtx->dataOffsets.partnOtherDataOffset;
+        size1 = FFCDH_GET_LENGTH(pTmp1); /* size of user Other data*/
+        partnerInfoNewOffset = pDhCtx->dataOffsets.userOtherDataOffset + size1 +
+                           CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+        /* difference between new and old offsets */
+        diffOffsets = pDhCtx->dataOffsets.userOtherDataOffset - partnerInfoNewOffset;
+        /* move user info to new position */
+        FfcDhWriteBufferBeToBe(&pDhCtx->extendDataBuffer[0] + partnerInfoNewOffset,
+                             &pDhCtx->extendDataBuffer[0] + pDhCtx->dataOffsets.partnIdOffset,
+                             pDhCtx->dataOffsets.partnInfoSize + pDhCtx->dataOffsets.suppPublInfoSize +
+                             pDhCtx->dataOffsets.suppPrivInfoSize);
+
+        dataOffsets->userIdOffset -= diffOffsets;
+        dataOffsets->userStatPublKeyOffset -= diffOffsets;
+        dataOffsets->userEphemPublKeyOffset -= diffOffsets;
+        dataOffsets->userNonceOffset -= diffOffsets;
+        dataOffsets->userOtherDataOffset -= diffOffsets;
+
+        dataOffsets->suppPublInfoOffset = dataOffsets->userIdOffset + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES +
+                          pDhCtx->dataOffsets.userInfoSize;
+        dataOffsets->suppPrivInfoOffset = dataOffsets->suppPublInfoOffset + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES +
+                                      dataOffsets->suppPublInfoSize;
+    }
+
+    return;
+}
+#endif
+
+
+/* The function compares party Info entries, inserted into DH context and
+ * given by the partner in the PartnerInfo buffer.
+ * If the data is not equaled, then the function returns an error. After the data
+ * checking the function promotes the data pointers to the next Info entry.
+ *
+ */
+static CCError_t  FfcDhCmpInfoEntries(uint8_t **ppCtxEntry, uint8_t **ppPartnEntry)
+{
+        CCError_t err = CC_OK; /* return error identifier */
+        uint32_t calcSize, partnSize;
+
+        calcSize = FFCDH_GET_LENGTH(*ppCtxEntry); /* size of PartnerId from Ctx; & pTmp1 += 2 */
+        partnSize = FFCDH_GET_LENGTH(*ppPartnEntry); /*  -- " -- from Partner's data */
+    CHECK_AND_SET_ERROR(calcSize != partnSize,  CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+    CHECK_AND_SET_ERROR(CC_PalMemCmp(*ppCtxEntry, *ppPartnEntry, partnSize), CC_FFCDH_PARTN_INFO_PARSING_DATA_ERROR);
+    /* promote pointers to next entry (partnStatPublKey) */
+    *ppCtxEntry += calcSize;
+    *ppPartnEntry += partnSize;
+
+End:
+    return err;
+}
+
+
+/******************************************************************************************/
+/*!
+@brief The function calculates user's confirmation MacTags for FFC DH Schemes according to NIST SP 56A rev.2 standard.
+
+\note Before calling of this function the user should obtain assurance of used FFC Domain and public, private keys,
+involved in the key agreement, using one of the methods, described in sec. 5.6.2 of above named standard.
+<ul><li> - depending on DH Scheme, calculates confirmation HMAC MacTag, which is intended to be provided to the partner
+(sec. 5.2, 5.9, 6); in this case the secret keying material is parsed to MacKey of size, equaled to HMAC key size. </li>
+<li> - in our implementation HMAC key size defined equal to FFC sub-group order (meets to sec.5.9.3). </li>
+<li> - if in the chosen DH Scheme the user is not Confirmation provider, then both the pointer and the size of
+appropriate MacTag should be set to NULL. </li>
+<li>  - for detailed description of Confirmation "MacData" see CCFfcDhConfirmMacData_t structure definition. </li></ul>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined in cc_dh_error.h, cc_kdf_error.h or cc_hash_error.h.
+*/
+
+static CCError_t FfcDhCalcConfirmMacTags(
+                        DhContext_t *pDhCtx,               /*!< [in] pointer to the user's DH context structure, containing all data, defining
+                                                                   DH Key Agreement Scheme. The context shall be initialized for user's roles
+                                                                   (U or V; Provider or Receiver) using CC_FfcDhSetCtx function. */
+                        uint8_t  *pUserConfirmText,        /*!< [in] optional, pointer to confirmation Text of the User. */
+                        uint32_t  userConfirmTextSize,     /*!< [in] optional size of Text data of partyU, in bytes. */
+                        uint8_t  *pPartnerConfirmText,     /*!< [in] optional, pointer to confirmation Text of the Partner. */
+                        uint32_t  partnerConfirmTextSize)  /*!< [in] optional, size of Text data of partyV, in bytes. */
+
+{
+    /* Function Declarations    */
+
+        CCError_t err = CC_OK; /* return error identifier */
+        uint8_t messStr1[] = "KS_1_U", messStr2[] = "KS_2_U", strV[] = "V";
+        uint8_t *pMessStr; /*a pointer to messageString*/
+        uint8_t *pTmp;
+    /* address of extended data buffer */
+        uint8_t *pBaseAddr = &pDhCtx->extendDataBuffer[0];
+        uint32_t fullLen = 0;
+
+        CCHashOperationMode_t hashMode;
+    const mbedtls_md_info_t *mdInfo = NULL;
+
+
+
+#define MESSAGE_STR_SIZE 6
+
+
+    /* if confirmation is required, then set formatted MacData string according
+     * to scheme and user roles in confirmation (U,V and Provider - P, Recipient - R):
+     *   MacData = messageString||IdP||IdR||EphemDataP||EphemDataR{||TextP}
+     *   SP 800-56A sec. 5.9. */
+
+/* set messageString according to Hybrid (or not) confirm. mode  */
+    if((pDhCtx->dhSchemeId == CC_FFCDH_SCHEM_HYBRID1) ||
+            (pDhCtx->dhSchemeId == CC_FFCDH_SCHEM_HYBRID_ONE_FLOW)) {
+        pMessStr = &messStr2[0];
+    } else {
+        pMessStr = &messStr1[0];
+    }
+
+    /* get HASH mode and op. size */
+    CHECK_ERROR(FfcGetHashMode(&hashMode, NULL, NULL/*pBlockSize*/,
+                     NULL/*pDigestSize*/, pDhCtx->ffcHashMode));
+
+        /* calculate MacTag for user as provider */
+    if(pDhCtx->schemeInfo.doConfirmProvid == 1) {
+        if(pDhCtx->userParty == CC_FFCDH_PARTY_V) {
+            CC_PalMemCopy(&pMessStr[5], strV, 1); /*set user V letter*/
+        }
+
+        /* copy all required confirmation data to context buffer */
+        pTmp = pBaseAddr + pDhCtx->dataOffsets.algIdOffset;
+        FfcDhWriteBufferBeToBe(&pTmp, pMessStr, MESSAGE_STR_SIZE, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->userId, pDhCtx->userIdSizeBytes, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->partnerId, pDhCtx->partnerIdSizeBytes, &fullLen);
+        FfcDhWriteBufferLeToBe(&pTmp, &pDhCtx->userEphemPublKey[0], pDhCtx->userStatPublKeySizeBytes>>2, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->userNonce, pDhCtx->userNonceSizeBytes, &fullLen);
+        FfcDhWriteBufferLeToBe(&pTmp, &pDhCtx->partnerEphemPublKey[0], pDhCtx->partnerStatPublKeySizeBytes>>2, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->partnerNonce, pDhCtx->partnerNonceSizeBytes, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pUserConfirmText, userConfirmTextSize, &fullLen);
+
+        /* call HMAC function with Key derived from pDhCtx->derivedKeyingMaterial  */
+        mdInfo = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+        if( mdInfo == NULL ){
+            return CC_FFCDH_INVALID_HASH_MODE_ERROR;
+        }
+        err = mbedtls_md_hmac( mdInfo,
+                            &pDhCtx->derivedKeyingMaterial[0]/*HmacKey*/,
+                            CC_FFCDH_SIZE_OF_CONFIRM_MAC_KEY_IN_BYTES/*HmacKeySize*/,
+                            pBaseAddr + pDhCtx->dataOffsets.algIdOffset/*data*/,
+                            fullLen/*dataInSize*/,
+                            (unsigned char*)pDhCtx->userMacTag/*result*/ );
+        if (err != CC_OK){
+            goto End;
+        }
+    }
+
+
+
+    /* calculate MacTag for partner as provider */
+    if(pDhCtx->schemeInfo.doConfirmRecip == 1) {
+        if(pDhCtx->userParty == CC_FFCDH_PARTY_U) {
+            CC_PalMemCopy(&pMessStr[5], strV, 1); /*set partner V letter*/
+        }
+
+        /* copy all required confirmation data to context buffer */
+        pTmp = pBaseAddr + pDhCtx->dataOffsets.algIdOffset;
+        FfcDhWriteBufferBeToBe(&pTmp, pMessStr, MESSAGE_STR_SIZE, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->partnerId, pDhCtx->partnerIdSizeBytes, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->userId, pDhCtx->userIdSizeBytes, &fullLen);
+        FfcDhWriteBufferLeToBe(&pTmp, pDhCtx->partnerEphemPublKey, pDhCtx->partnerStatPublKeySizeBytes>>2, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->partnerNonce, pDhCtx->partnerNonceSizeBytes, &fullLen);
+        FfcDhWriteBufferLeToBe(&pTmp, pDhCtx->userEphemPublKey, pDhCtx->userStatPublKeySizeBytes>>2, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pDhCtx->userNonce, pDhCtx->userNonceSizeBytes, &fullLen);
+        FfcDhWriteBufferBeToBe(&pTmp, pPartnerConfirmText, partnerConfirmTextSize, &fullLen);
+
+
+        err = mbedtls_md_hmac( mdInfo,
+                            &pDhCtx->derivedKeyingMaterial[0]/*HmacKey*/,
+                            CC_FFCDH_SIZE_OF_CONFIRM_MAC_KEY_IN_BYTES/*KeySize*/,
+                            pBaseAddr + pDhCtx->dataOffsets.algIdOffset/*data*/,
+                            fullLen/*dataInSize*/,
+                            (unsigned char*)pDhCtx->partnerMacTag/*result*/);
+        if (err != CC_OK){
+            goto End;
+
+        }
+    }
+
+
+End:
+    return err;
+
+}
+
+
+
+
+/*******************************************************************************************/
+/*!
+@brief This function checks and sets given "OtherInfo" entries, calculates shared secret value and
+       derives the "secret keying material".
+       The function's implementation meets to NIST SP 56A rev.2 standard requirements.
+\note Before calling of this function, DH Context should be initialized, DH Scheme, Domain parameters and all
+required user's Private, Public keys or nonces are inserted by calling appropriate CC functions.
+<ul><li>  The function sets input data into the Context to form the "OtherInfo" (sec. 5.8.1) according to
+said standard and the implementation requirements:
+<li>  - OtherInfo = AlgorithmId||PartyUInfo||PartyVInfo {||SuppPubInfo}{||SuppPrivInfo}, where each PartyInfo is
+formatted as : </li>
+<li>  - Remark: AlgorithmId includes information about length in bits of derived Keying Material and its
+ parsing between internal using for confirmation HMAC algorithm and output Secret Keying Data
+ and algorithm, which it is intended for. </li>
+<li>  - PartyInfo = PartyId||PartyStatPublKey||PartyEphemKey||PartyNonce{||PartyOtherData}. </li>
+<li>  - for detailed description of "OtherInfo" construction and concatenation its sub-entries, see
+CCFfcDhOtherInfo_t structure definition; </li></ul>
+\note - the function performs the following calculations:
+<ul><li> - calculates shared secret value according to DH Scheme:
+   -  SharedSecretVal = (PublKey1 ^ PrivKey1)  modulo Prime  or
+   -  SharedSecretVal = (PartnPublKey1 ^ UserPrivKey1) || (PartnPublKey2 ^ UserPrivKey2)  modulo Prime; </li>
+<li> - derives the secret keying material of required size from the shared secret value by calling KDF function
+with shared OtherInfo data: DerivedKeyingMaterial = KDF(ZZ, OtherInfo, keyingMaterialSize); </li></ul>
+<ul><li> - If DH Scheme includes Key Confirmation, then the function calculates confirmation HMAC MacTag, which is
+intended to be provided to the partner (sec. 5.2, 5.9, 6); in this case the secret keying material is parsed to MacKey
+of size, equaled to HMAC key size. </li>
+<li> - in our implementation HMAC key size is defined to be equaled to FFC sub-group order (meets to sec.5.9.3). </li>
+<li> - if in the chosen DH Scheme the user is not a Confirmation Provider, then both the pointer and the size of
+appropriate MacTag should be set to NULL. </li>
+<li>  - for detailed description of Confirmation "MacData" see CCFfcDhConfirmMacData_t structure definition. </li></ul>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+
+CEXPORT_C CCError_t CC_FfcDhSetAndCalculateSchemeData(
+                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to context structure, containing all data, used in DH Key
+                                                                Agreement Scheme, required for implementation of said standard. */
+                        /*! Partner's Data to be included into OtherInfo entry. Detailed description see in CCFfcDhOtherInfo_t. */
+                        uint8_t *pPartnerInfo,            /*!< [in] pointer to the concatenated PartnerInfo. Detailed description see in CCFfcDhOtherInfo_t. */
+                        size_t sizeOfPartnerInfo,         /*!< [in] size of PartnerInfo, in bytes, should be <= CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES. */
+                        CCFfcDhPartyInfoValidMode_t partnInfoValidMode, /*!< enumerator, defining which of public keys (static, ephemeral),
+                                                                included in the PartnerInfo, should be full validated and which partial only. */
+                        uint8_t *pSuppPubInfo,            /*!< [in] pointer to optional shared public data to be included into SuppPubInfo entry */
+                        size_t suppPubInfoSize,           /*!< [in] size of SuppPubInfo data, in bytes. */
+                        uint8_t *pSuppPrivInfo,           /*!< [in] pointer to optional shared private data to be included into SuppPrivInfo entry */
+                        size_t suppPrivInfoSize,          /*!< [in] size of other SuppPrivInfo data, in bytes (should be not great than
+                                                                    CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES */
+                        uint8_t *pUserMacTag,             /*!< [out] optional, pointer to the user-provider confirmation MacTag depending
+                                                                   on used Key Agreement Scheme. The tag is calculated by HMAC with given
+                                                                   hashMode, as described in SP800-56A sec. 5.9. */
+                        size_t  macTagSize                /*!< [in] optional, required size in bytes of confirmation MacTag. */
+)
+{
+    /* FUNCTION DECLARATIONS */
+
+    CCError_t err = CC_OK; /* return error identifier */
+    DhContext_t  *pDhCtx = NULL;
+    uint8_t *pBaseAddr = NULL;
+    uint8_t *pTmp1 = NULL/* Context data pointer */;
+    uint8_t *pTmp2 = NULL/* Partner given data pointer */;
+    uint32_t size1 = 0, size2 = 0, ffcOrderSize;
+    CCFfcDhKeyValidMode_t partnStatKeyValidMode, partnEphemKeyValidMode;
+    /* pointer and size of shared secret value. */
+    uint8_t *pZZ;
+    uint32_t zzSize;
+    uint8_t *pOtherInfo;
+    mbedtls_hkdf_hashmode_t hkdfHashMode;
+
+//        CCFfcDhKeyValidMode_t validatMode;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* check contexts pointers and tags */
+    if (pDhUserCtx == NULL) {
+    return CC_FFCDH_INVALID_CONTEXT_PTR_ERROR;
+    }
+
+    /* check that DhCtx is valid for user keys generation step: *
+    *  DH Scheme, Domain and Keys are set.                      */
+    CHECK_AND_SET_ERROR((pDhUserCtx->validTag != FFCDH_CTX_VALID_TAG_USER_INFO_SET),
+                     CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR);
+    /*  check the mandatory data pointers and sizes */
+    CHECK_AND_SET_ERROR((pPartnerInfo == NULL), CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR);
+    CHECK_AND_SET_ERROR(((sizeOfPartnerInfo == 0) || (sizeOfPartnerInfo > CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES)),
+                              CC_FFCDH_INVALID_ARGUMENT_SIZE_ERROR);
+    /*  check the optional data pointers and sizes */
+    CHECK_AND_SET_ERROR(((pSuppPubInfo == NULL) != (suppPubInfoSize == 0)) ||
+                        (suppPubInfoSize > CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES),
+                              CC_FFCDH_OPTIONAL_DATA_ERROR);
+    CHECK_AND_SET_ERROR(((pSuppPrivInfo == NULL) != (suppPrivInfoSize == 0)) ||
+                        (suppPrivInfoSize > CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES),
+                              CC_FFCDH_OPTIONAL_DATA_ERROR);
+    CHECK_AND_SET_ERROR(partnInfoValidMode >= CC_FFCDH_NO_FULL_VALIDAT_MODE, CC_FFCDH_INVALID_VALIDAT_MODE_ERROR);
+    /*  check optional confirmation data pointers and sizes */
+    CHECK_AND_SET_ERROR((pUserMacTag == NULL) != (macTagSize == 0), CC_FFCDH_OPTIONAL_DATA_ERROR);
+//        CHECK_AND_SET_ERROR(((pUserConfirmText == NULL) != (userConfirmTextSize == 0)) ||
+//                                 (userConfirmTextSize > CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES),
+//                CC_FFCDH_OPTIONAL_DATA_ERROR);
+//        CHECK_AND_SET_ERROR(((pPartnerConfirmText == NULL) != (partnerConfirmTextSize == 0)) ||
+//                                 (partnerConfirmTextSize > CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES),
+//                                  CC_FFCDH_OPTIONAL_DATA_ERROR);
+
+
+        /* Get internal context structure */
+    pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff;
+
+    if(pDhCtx->schemeInfo.doConfirmProvid == 1) {
+        CHECK_AND_SET_ERROR((pUserMacTag == NULL) || (macTagSize != pDhCtx->macTagSize),
+                             CC_FFCDH_OPTIONAL_DATA_ERROR);
+    }
+
+    /* set base address to partner info = PartnerId in the DH Context. */
+    pBaseAddr = &pDhCtx->extendDataBuffer[0] + pDhCtx->dataOffsets.partnIdOffset;
+    pTmp1 = pBaseAddr;        /* in ctx */
+    pTmp2 = &pPartnerInfo[0]; /* in received data */
+
+        /* get FFC domain parameters */
+    ffcOrderSize = pDhCtx->ffcDomain.ordLenWords*CC_32BIT_WORD_SIZE;
+
+    /*-----------------------------------*/
+    /* Check and import PartnerInfo data */
+    /*-----------------------------------*/
+
+    /* set validation mode for each of keys */
+    if(partnInfoValidMode == CC_FFCDH_BOTH_KEYS_FULL_VALIDAT_MODE) {
+        partnStatKeyValidMode = CC_FFCDH_KEY_VALIDAT_FULL_MODE;
+        partnEphemKeyValidMode = CC_FFCDH_KEY_VALIDAT_FULL_MODE;
+    } else {
+        partnStatKeyValidMode  = CC_FFCDH_KEY_VALIDAT_PARTIAL_MODE;
+        partnEphemKeyValidMode = CC_FFCDH_KEY_VALIDAT_PARTIAL_MODE;
+    }
+    if (partnInfoValidMode == CC_FFCDH_STAT_KEY_FULL_VALIDAT_MODE) {
+        partnStatKeyValidMode = CC_FFCDH_KEY_VALIDAT_FULL_MODE;
+    }
+    if(partnInfoValidMode == CC_FFCDH_EPHEM_KEY_FULL_VALIDAT_MODE) {
+        partnEphemKeyValidMode = CC_FFCDH_KEY_VALIDAT_FULL_MODE;
+    }
+
+    /* check partner ID data */
+    CHECK_ERROR(FfcDhCmpInfoEntries(&pTmp1, &pTmp2));
+
+//  size1 = FFCDH_GET_LENGTH(pTmp1); /* size of PartnerId from Ctx; & pTmp1 += 2 */
+//  size2 = FFCDH_GET_LENGTH(pTmp2); /*  -- " -- from Partner's data */
+//  CHECK_AND_SET_ERROR(size1 != size2,  CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+//  CHECK_AND_SET_ERROR(CC_PalMemCmp(pTmp1, pTmp2, size2), CC_FFCDH_PARTN_INFO_PARSING_DATA_ERROR);
+//  /* promote pointers to next entry (partnStatPublKey) */
+//  pTmp1 += size1;
+//  pTmp2 += size2;
+
+
+
+/* ????? should be revised:  check that inserted = passeD  */
+
+    /* check and (if needed) import the partner`s static PublKey.
+     * note: the pointers will be updated to next buffer */
+    if(pDhCtx->schemeInfo.doPartnerStatKey) {
+        /* check and import the Key, promote pointers to next Info entries */
+        err = FfcDhValidatePartnInfoPublKey(
+            pDhCtx,
+            partnStatKeyValidMode,
+            &pTmp1   /* in context*/,
+            &pTmp2); /* in PartnerInfo */
+        CHECK_ERROR(err);
+    } else {
+        /* get sizes and promote pointers to next entry */
+        size1 = FFCDH_GET_LENGTH(pTmp1);
+        size2 = FFCDH_GET_LENGTH(pTmp2);
+        /* check that given key size == 0, i.e. that partner not passes redundant key */
+        CHECK_AND_SET_ERROR((size1 != 0) || (size2 != 0), CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+    }
+
+    /* check and (if needed) import the partner`s static PublKey.
+     * note: the pointers will be updated to next buffer */
+    if(pDhCtx->schemeInfo.doPartnerEphemKey) {
+        /* check and import (if needed) the Key */
+        err = FfcDhValidatePartnInfoPublKey(
+            pDhCtx,
+            partnEphemKeyValidMode,
+            &pTmp1 /* in context*/,
+            &pTmp2 /* in PartnerInfo */);
+        CHECK_ERROR(err);
+// ????
+    } else if (pDhCtx->schemeInfo.doPartnerNonce){
+        /* check and import nonce */
+        size1 = FFCDH_GET_LENGTH(pTmp1); /* size of Partner's nonce from Ctx; & pTmp1 += 2 */
+        size2 = FFCDH_GET_LENGTH(pTmp2); /*  -- " -- from Partner's data */
+        if(size1 != 0) {
+            CHECK_AND_SET_ERROR(size1 != size2, CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+            CHECK_AND_SET_ERROR(CC_PalMemCmp(pTmp1, pTmp2, size1), CC_FFCDH_PARTN_INFO_PARSING_DATA_ERROR);
+        } else {
+            CHECK_AND_SET_ERROR(size2 != ffcOrderSize, CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+            /* copy nonce into context */
+            FfcDhWriteBufferBeToBe(&pTmp1, pTmp2,  size2, &pDhCtx->currInsertedDataSize);
+        }
+    } else {
+        /* check that key size, given by Partner == 0, i.e. that partner not passes redundant key */
+        CHECK_AND_SET_ERROR(size2 != 0, CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+    }
+
+    /* import Partner's Other data */
+    size1 = FFCDH_GET_LENGTH(pTmp1); /* size of Partner Other data from Ctx; & pTmp1 += 2 */
+    size2 = FFCDH_GET_LENGTH(pTmp2); /*  -- " -- from Partner's data */
+    CHECK_AND_SET_ERROR(size1 != 0, CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+    CHECK_AND_SET_ERROR(size2 > CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_OTHER_DATA_BYTES, CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+    FfcDhWriteBufferBeToBe(&pTmp1, pTmp2, size2, &pDhCtx->currInsertedDataSize); /* copy to Context */
+    /* import Supplied public and private data */
+    CHECK_AND_SET_ERROR(suppPubInfoSize > CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES, CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+    CHECK_AND_SET_ERROR(suppPrivInfoSize > CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES, CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR);
+    FfcDhWriteBufferBeToBe(&pTmp1, pSuppPubInfo, suppPubInfoSize, &pDhCtx->currInsertedDataSize);
+    FfcDhWriteBufferBeToBe(&pTmp1, pSuppPrivInfo, suppPrivInfoSize, &pDhCtx->currInsertedDataSize);
+
+    /*--------------------------------------------------*/
+    /* Calculate Shared Secret Value using DH primitive */
+    /*--------------------------------------------------*/
+    FfcDhCalcSharedSecretVal(pDhCtx);
+
+    /*----------------------------------------------------------------------
+    * Calculate Shared Secret Keying Data using HASH KDF using HMAC KDF.
+    * Derivation method meets to requirements of SP 800-56A sec. 5.8, refer
+    * to SP 800-56C. Note, that these standards allowing implementation
+    * with application specified formatting of concatenated OtherInfo entries
+    * and used HMAC modes. In partial, is allowed using RFC 5869 mode of HMAC
+    * (SP 800-56C sec.4) with formatting, described below.
+    *----------------------------------------------------------------------*/
+
+    if(pDhCtx->kdfMode == CC_FFCDH_KDF_HMAC_RFC5869_MODE) {
+        /* on this RFC 5869 mode is used the following format of input data to
+         * key derivation function: on randomness extraction step are used: Salt (s)
+         * and ShredSecretValue ZZ as message to generate pseudo random key (PRK);
+         * on expansion step the function concatenates input DhOtherInfo and 1-byte counter
+         * to derive the KeyingMaterial */
+
+        /* get pointer and size of shared secret value */
+        pZZ = &pDhCtx->extendDataBuffer[0] + (size_t)pDhCtx->dataOffsets.sharedSecrOffset;
+        zzSize = FFCDH_GET_LENGTH(pZZ); /*get size and promote the pointer*/
+        pOtherInfo = pZZ + zzSize; /*get OtherInfo*/
+
+        /* get HKDF Hash mode ID */
+        CHECK_ERROR(FfcGetHashMode(NULL/*pHashMode*/, &hkdfHashMode, NULL/*pBlockSize*/,
+                         NULL/*pDigestSize*/, pDhCtx->ffcHashMode));
+
+        /* call HKDF RFC5869 function */
+        err = mbedtls_hkdf_key_derivation(
+                hkdfHashMode,
+                (uint8_t*)&pDhCtx->hmacSalt[0],
+                (size_t)pDhCtx->hmacSaltSizeBytes,
+                pZZ/*shared secret value - Ikm*/,
+                zzSize/*shared secret size - IkmLen*/,
+                pOtherInfo /*OtherInfo - Info*/,
+                pDhCtx->currInsertedDataSize/*InfoLen*/,
+                pDhCtx->derivedKeyingMaterial/*Okm*/,
+                pDhCtx->derivedKeyingMaterialSize/*OkmLen*/,
+                CC_FALSE/*IsStrongKkey*/);
+    }
+
+    /* if confirmation is required, then set formatted MacData string according
+     * to scheme and user roles in confirmation (U,V and Provider - P, Recipient - R):
+     *   MacData = messageString||IdP||IdR||EphemDataP||EphemDataR{||TextP}
+     * (see SP 800-56A sec. 5.9). */
+    if(pDhCtx->schemeInfo.doConfirmProvid) {
+        err = FfcDhCalcConfirmMacTags(pDhCtx, pDhCtx->userConfirmText, pDhCtx->userConfirmTextSize,
+                pDhCtx->partnerConfirmText, pDhCtx->partnerConfirmTextSize);
+        CHECK_ERROR(err);
+
+        /* output the user MacTag */
+        CC_PalMemCopy(pUserMacTag, pDhCtx->userMacTag, macTagSize);
+    }
+
+    /* update validation tag  */
+        pDhCtx->validTag |= FFCDH_CTX_VALID_TAG_SCHEM_DATA_BIT;
+
+End:
+    if(err != CC_OK) {
+        CC_PalMemSetZero(pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+    }
+
+        return err;
+
+}
+
+
+/*******************************************************************************************/
+/*!
+@brief This function performs DH Key Agreement Confirmation and, on success, outputs the shared keying data.
+The function calculates expected partner's confirmation MacTag' and compares it to value,
+received from the partner.
+<li> If the tags are not equaled, then the function returns an error and zeroes the secure
+sensitive data. </li>
+<li> If no errors, the function puts the derived secret keying data into output buffer. </li>
+\note Assumed, that the user yet have obtained assurance of public and private keys,
+involved in the key agreement.
+\note Before calling this function the user should perform all required DH Key Agreement
+operations, including calculation of shared secret keying material by calling
+CC_FfcDhCalcUserConfirmMacTag function.
+\note If according to chosen Scheme the user is not a Confirmation Recipient,
+then all, the pointer and the size of MacTag should be
+set to zero, else the function returns an error.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined in cc_dh_error.h
+*/
+CEXPORT_C CCError_t CC_FfcDhGetSharedSecretKeyingData(
+                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in] pointer to the user's DH context structure, containing all data,
+                                                               defining DH Key Agreement Scheme and its results.  */
+                        uint8_t *pSecretKeyData,          /*!< [out] pointer to the shared secret keying data, extracted
+                                                                from keying material after parsing to . */
+                        size_t  *pSecretKeyDataSize,      /*!< [in/out] the pointer to the size of shared secret key data:
+                                                               in - size of the given output buffer, out - actual size of extracted
+                                                               key data */
+                        uint8_t *pPartnerMacTag,          /*!< [in] optional, pointer to the confirmation MacTag, provided by the partner */
+                        size_t   macTagSize)              /*!< [in] optional, size of partner's MacTag, in bytes */
+{
+    CCError_t err = CC_OK; /* return error identifier */
+    DhContext_t *pDhCtx;
+    uint8_t *pKeyData;
+    uint32_t hashBlockSize;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* check contexts pointers and tags */
+    if (pDhUserCtx == NULL) {
+    return CC_FFCDH_INVALID_CONTEXT_PTR_ERROR;
+    }
+    /* check that DhCtx is valid for user keys generation step: *
+    *  DH Scheme, Domain and Keys are set.                      */
+    CHECK_AND_SET_ERROR((pDhUserCtx->validTag != FFCDH_CTX_VALID_TAG_SCHEM_DATA_SET),
+                    CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR);
+    /* check output keying data parameters */
+    CHECK_AND_SET_ERROR(pSecretKeyData == NULL, CC_FFCDH_KEYING_DATA_PTR_INVALID_ERROR);
+    CHECK_AND_SET_ERROR(pSecretKeyDataSize == NULL, CC_FFCDH_KEYING_DATA_SIZE_PTR_INVALID_ERROR);
+
+    /* Get internal context structure */
+    pDhCtx = (DhContext_t*)&pDhUserCtx->contextBuff;
+
+    /* get HMAC key size in bytes */
+    CHECK_ERROR(FfcGetHashMode(NULL/*pHashMode*/, NULL/*hkdfHashMode*/, &hashBlockSize,
+                   NULL/*pDigestSize*/, pDhCtx->ffcHashMode));
+
+    /* check that given output buffer is enough for the keying data */
+    CHECK_AND_SET_ERROR(*pSecretKeyDataSize < pDhCtx->secretKeyingDataSize,
+                   CC_FFCDH_KEYING_DATA_SIZE_INVALID_ERROR);
+    /*  check optional confirmation data pointers and sizes */
+    CHECK_AND_SET_ERROR((pPartnerMacTag == NULL) != (macTagSize == 0), CC_FFCDH_OPTIONAL_DATA_ERROR);
+
+    /* if confirmation is needed check appropriate parameters */
+    if(pDhCtx->schemeInfo.doConfirmRecip == 1) {
+        CHECK_AND_SET_ERROR(pPartnerMacTag == NULL, CC_FFCDH_MAC_TAG_PTR_INVALID_ERROR);
+        CHECK_AND_SET_ERROR(macTagSize != pDhCtx->macTagSize, CC_FFCDH_MAC_TAG_SIZE_INVALID_ERROR);
+
+    /* compare calculated partner's MacTag with received value and return error,
+     * if they are not equaled  */
+    CHECK_AND_SET_ERROR(CC_PalMemCmp(pPartnerMacTag, pDhCtx->partnerMacTag, macTagSize),
+                    CC_FFCDH_MAC_TAG_DATA_INVALID_ERROR);
+    }
+
+    /* set pointer to the second part of keying material, and output the
+     * Secret Keying Data */
+    pKeyData = &pDhCtx->extendDataBuffer[0] + pDhCtx->dataOffsets.sharedSecrOffset + hashBlockSize;
+    *pSecretKeyDataSize = pDhCtx->secretKeyingDataSize;
+    CC_PalMemCopy(pSecretKeyData, pKeyData, pDhCtx->secretKeyingDataSize);
+
+End:
+    CC_PalMemSetZero((uint8_t*)pDhUserCtx, sizeof(CCFfcDhUserContext_t));
+
+
+    return err;
+
+}
+
+
+
+/*******************************************************************************************/
+/*!
+@brief This function implements FFC DH primitive according to section 5.7.1.1 of NIST SP 56A rev.2 standard.
+       The function computes the shared secret value:  SharedSecretVal = partnerPublKey ^ userPrivKey modulo Prime.
+\note Before calling of this function the user should obtain assurance of FFC Domain, public and private keys,
+involved in the key agreement, using one of methods, described in section 5.6.2 of above named standard.
+\note For assurance of keys validity the user can use appropriate APIs for generating or building and validation,
+of keys, described in cc_ffcdh.h file.
+@return CC_OK on success.
+@return A non-zero value on failure as defined in cc_dh_error.h or cc_rnd_error.h.
+*/
+CEXPORT_C CCError_t CC_FfcDhGetSharedSecretVal(
+                    CCFfcDomain_t *pDomain,         /*!< [in/out] pointer to DH FFC Context structure. */
+                    uint8_t *pSharedSecretVal,      /*!< [out] pointer to the shared secret value in big endianness order
+                                                              of bytes in the array (MS-byte is a most left one). This
+                                                              buffer should be at least of prime (modulus) size in bytes. */
+                    size_t *pSharedSecretValSize,   /*!< [in/out] pointer to the shared secret value size:
+                                                              input - size of the given buffer, it should be at least
+                                                              prime (modulus) size bytes; output - actual size. */
+                    uint8_t *pPrivKeyData,          /*!< [in] pointer to given DH FFC private key in big endianness;
+                                                              the Key should be in range [1, n-1], where n is the Domain
+                                                              generator order. */
+                    size_t privKeyDataSize,         /*!< [in] private key size, in bytes: should be not great than Domain
+                                                              generator order size. */
+                    uint8_t *pPublKeyData,          /*!< [in] pointer to given DH FFC public key in big endianness;
+                                                              the key should be in range [2, P-2], where P is the Domain Prime. */
+                    size_t publKeyDataSize,         /*!< [in] public key size, in bytes: should be not great than Domain Prime size. */
+                    uint32_t *pTmpBuff              /*!< [in] pointer to temporary buffer of size = (Prime size + Order size). */
+)
+{
+
+    CCError_t err = CC_OK; /* return error identifier */
+    size_t primeSizeBytes, orderSizeBytes;
+    size_t primeSizeWords, orderSizeWords;
+    size_t sharSecrSizeBits;
+    uint32_t *pPublKey32, *pPrivKey32;
+    uint32_t word = 1; /* buffer = 1*/
+    CCCommonCmpCounter_t cmp1, cmp2;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    primeSizeWords = pDomain->modLenWords;
+    orderSizeWords = pDomain->ordLenWords;
+    primeSizeBytes = primeSizeWords * CC_32BIT_WORD_SIZE;
+    orderSizeBytes = orderSizeWords * CC_32BIT_WORD_SIZE;
+
+    /* check FFC Domain pointer and validation tag */
+    CHECK_AND_RETURN_ERROR(pDomain == NULL, CC_FFCDH_INVALID_DOMAIN_PTR_ERROR);
+    CHECK_AND_RETURN_ERROR((pDomain->validTag != CC_FFC_DOMAIN_VALIDATION_TAG),
+                CC_FFCDH_INVALID_DOMAIN_DATA_ERROR);
+
+    /* check in/out data pointers */
+    CHECK_AND_SET_ERROR((pSharedSecretVal == NULL) || (pSharedSecretValSize == NULL),
+                 CC_FFCDH_INVALID_SHARED_SECR_VAL_PTR_ERROR);
+    CHECK_AND_SET_ERROR(pPrivKeyData == NULL, CC_FFCDH_INVALID_PRIV_KEY_PTR_ERROR);
+    CHECK_AND_SET_ERROR(pPublKeyData == NULL, CC_FFCDH_INVALID_PUBL_KEY_PTR_ERROR);
+
+    /* check that in/out sizes meets to DH Domain parameters and buffers sizes. */
+    CHECK_AND_SET_ERROR(*pSharedSecretValSize < primeSizeBytes, CC_FFCDH_LOW_OUTPUT_BUFF_SIZE_ERROR);
+
+    /* convert public/private keys to LE words */
+    pPublKey32 = pTmpBuff;
+    pPrivKey32 = pPublKey32 + pDomain->modLenWords;
+    CHECK_AND_SET_ERROR(CC_CommonConvertMsbLsbBytesToLswMswWords(
+                     pPublKey32, primeSizeBytes, pPublKeyData, publKeyDataSize),
+                         CC_FFCDH_INVALID_PUBLIC_KEY_SIZE_ERROR);
+    CHECK_AND_SET_ERROR(CC_CommonConvertMsbLsbBytesToLswMswWords(
+                     pPrivKey32, orderSizeBytes, pPrivKeyData, privKeyDataSize),
+                         CC_FFCDH_INVALID_PRIVATE_KEY_SIZE_ERROR);
+
+    /* check public key 1 < publKey < prime-1 */
+        word = 1;
+        pDomain->prime[pDomain->modLenWords-1] ^= 1UL; /* temporary prime -= 1; */
+    cmp1 = CC_CommonCmpLsWordsUnsignedCounters(pPublKey32, primeSizeWords, &word, 1);
+    cmp2 = CC_CommonCmpLsWordsUnsignedCounters(pPublKey32, primeSizeWords, pDomain->prime, primeSizeWords);
+    pDomain->prime[primeSizeWords-1] ^= 1UL; /* reset prime */
+    CHECK_AND_SET_ERROR((cmp1 != CC_COMMON_CmpCounter1GreaterThenCounter2) ||
+                (cmp2 != CC_COMMON_CmpCounter2GreaterThenCounter1),
+                CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR );
+
+    /* check private key 0 < privlKey < order */
+    word = 0;
+    cmp1 = CC_CommonCmpLsWordsUnsignedCounters(pPrivKey32, primeSizeWords, &word, 1);
+    cmp2 = CC_CommonCmpLsWordsUnsignedCounters(pPrivKey32, primeSizeWords, pDomain->order, orderSizeWords);
+    CHECK_AND_SET_ERROR((cmp1 != CC_COMMON_CmpCounter1GreaterThenCounter2) ||
+                (cmp2 != CC_COMMON_CmpCounter2GreaterThenCounter1),
+                CC_FFCDH_INVALID_PRIVATE_KEY_VALUE_ERROR);
+
+    /* calc. shared secret value */
+    CHECK_ERROR(PkiExecModExpLeW(
+            pPublKey32/*pOut*/, pPublKey32/*pIn data*/, primeSizeWords/*inSizeWords*/,
+                    pDomain->prime/**pMod*/, primeSizeBytes*CC_BITS_IN_BYTE /*modSizeBits*/,
+                    pPrivKey32/*pExp*/,  orderSizeWords/*expSizeWords*/));
+
+    /* get actual size of shared secret value */
+    sharSecrSizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(pPublKey32, primeSizeWords);
+    *pSharedSecretValSize = ROUNDUP_BITS_TO_BYTES(sharSecrSizeBits);
+
+    /* output result as BE bytes array without leading zeros */
+    CHECK_ERROR(CC_CommonConvertLswMswWordsToMsbLsbBytes(pSharedSecretVal, *pSharedSecretValSize,
+                                                 pPublKey32, primeSizeWords));
+
+End:
+    /* zero secret data */
+    CC_PalMemSetZero(pTmpBuff, primeSizeBytes + orderSizeBytes);
+    if(err) {
+        CC_PalMemSetZero(pPrivKeyData, privKeyDataSize);
+        CC_PalMemSetZero(pSharedSecretVal, primeSizeBytes);
+    }
+
+
+    return err;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffcdh/cc_ffcdh_local.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffcdh/cc_ffcdh_local.h
new file mode 100644
index 0000000..350952b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/ffcdh/cc_ffcdh_local.h
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_FFCDH_LOCAL_H
+#define _CC_FFCDH_LOCAL_H
+
+#include "cc_ffc_domain.h"
+#include "cc_ffcdh.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+
+
+/*! DH Context Validation Tag initial value.                                  *
+\note low bytes of validation tag are used for setting bits, indicate         *
+   that into the context inserted data appropriate to DH Agreement functions  *
+*  flow                                                                       */
+#define FFCDH_CTX_VALID_TAG_INIT_VAL     0xFFCD0000
+
+/*!< DH Context Validation Tag Bits for appropriate steps of functions flow   *
+* according to description in the CCDhCtx_t structure definition.             */
+#define FFCDH_CTX_VALID_TAG_INITIALIZATION_BIT  (1UL<<0)  /*!< FFCDH Context is initialised to zero data */
+#define FFCDH_CTX_VALID_TAG_SCHEM_PARAM_BIT     (1UL<<1)  /*!< FFCDH Scheme parameters are set */
+#define FFCDH_CTX_VALID_TAG_DOMAIN_BIT          (1UL<<2)  /*!< FFCDH Domain is set into Context */
+#define FFCDH_CTX_VALID_TAG_USER_STAT_KEY_BIT   (1UL<<3)  /*!< FFCDH user static keys (private and public) are set */
+#define FFCDH_CTX_VALID_TAG_USER_EPHEM_KEY_BIT  (1UL<<4)  /*!< FFCDH user ephemeral keys (private and public) are set */
+#define FFCDH_CTX_VALID_TAG_USER_NONCE_BIT      (1UL<<5)  /*!< FFCDH user Nonce is set */
+#define FFCDH_CTX_VALID_TAG_PARTN_STAT_KEY_BIT  (1UL<<6)  /*!< FFCDH partner static public key */
+#define FFCDH_CTX_VALID_TAG_PARTN_EPHEM_KEY_BIT (1UL<<7)  /*!< FFCDH partner ephemeral public key is set */
+#define FFCDH_CTX_VALID_TAG_PARTN_NONCE_BIT     (1UL<<8)  /*!< FFCDH partner Nonce is set */
+#define FFCDH_CTX_VALID_TAG_USER_INFO_BIT       (1UL<<9)  /*!< FFCDH UserInfo Data is set */
+#define FFCDH_CTX_VALID_TAG_SCHEM_DATA_BIT      (1UL<<10) /*!< FFCDH Scheme Data is set */
+#define FFCDH_CTX_VALID_TAG_AGREEM_COMPLET_BIT  (1UL<<11) /*!< FFCDH Key Agreement is completed */
+
+/* All validation bits for Private/Public Keys joined together */
+#define FFCDH_CTX_VALID_TAG_ALL_KEYS_BITS          \
+    (FFCDH_CTX_VALID_TAG_USER_STAT_KEY_BIT  || \
+    FFCDH_CTX_VALID_TAG_USER_EPHEM_KEY_BIT  || \
+    FFCDH_CTX_VALID_TAG_USER_NONCE_BIT      || \
+    FFCDH_CTX_VALID_TAG_PARTN_STAT_KEY_BIT  || \
+    FFCDH_CTX_VALID_TAG_PARTN_EPHEM_KEY_BIT || \
+    FFCDH_CTX_VALID_TAG_PARTN_NONCE_BIT)
+
+/*!< DH Context Validation Tags for appropriate steps of functions flow       *
+* according to description in the CCDhCtx_t structure definition.             */
+#define FFCDH_CTX_VALID_TAG_SCHEM_PARAM_SET   (FFCDH_CTX_VALID_TAG_INIT_VAL         || FFCDH_CTX_VALID_TAG_SCHEM_PARAM_BIT)    /*!< DH Scheme parameters are set */
+#define FFCDH_CTX_VALID_TAG_DOMAIN_SET        (FFCDH_CTX_VALID_TAG_SCHEM_PARAM_SET  || FFCDH_CTX_VALID_TAG_DOMAIN_BIT)         /*!< DH Domain is set into Context */
+#define FFCDH_CTX_VALID_TAG_ALL_KEYS_SET      (FFCDH_CTX_VALID_TAG_DOMAIN_SET       || FFCDH_CTX_VALID_TAG_ALL_KEYS_BITS)      /*!< DH all keys are set */
+#define FFCDH_CTX_VALID_TAG_USER_INFO_SET     (FFCDH_CTX_VALID_TAG_ALL_KEYS_SET     || FFCDH_CTX_VALID_TAG_USER_INFO_BIT)      /*!< DH User Info is set */
+#define FFCDH_CTX_VALID_TAG_SCHEM_DATA_SET    (FFCDH_CTX_VALID_TAG_USER_INFO_SET    || FFCDH_CTX_VALID_TAG_SCHEM_DATA_BIT)     /*!< DH Scheme Data is set */
+#define FFCDH_CTX_VALID_TAG_AGREEM_COMPLETED  (FFCDH_CTX_VALID_TAG_KEY_MATERIAL_SET || FFCDH_CTX_VALID_TAG_AGREEM_COMPLET_BIT) /*!< DH Key Agreement is completed */
+
+/* the macro converts bit value (0,1) and offset to to appropriate number = bit<<offset. */
+#define FFCDH_OFFS_TO_VAL(bit, offset)  ((bit) << (offset))
+
+#ifdef FFC_FURTHER_USING
+/*! Offsets of bits defining FFC DH Scheme parameters in Scheme Info variable.
+ *  Each enum. value defines offset of the bit, indicating that the named parameter
+ *  is needed according to Scheme, user party (U,V) and confirmation role */
+typedef enum
+{
+    FFCDH_DO_CTX_INIT,             /*!< do DH context init */
+    FFCDH_DO_SCHEME_PARAMS,        /*!< insert Scheme parameters */
+    FFCDH_DO_DOMAIN,               /*!< insert Domain parameters */
+    FFCDH_DO_USER_STAT_KEY,        /*!< user should have static key */
+    FFCDH_DO_USER_EPHEM_KEY,       /*!< user should have ephemeral key */
+    FFCDH_DO_USER_NONCE,           /*!< user should have Nonce key */
+    FFCDH_DO_PARTN_STAT_KEY,       /*!< partner should have static key */
+    FFCDH_DO_PARTN_EPHEM_KEY,      /*!< partner should have static key */
+    FFCDH_DO_PARTN_NONCE,          /*!< partner should have static key */
+    FFCDH_DO_CONFIRM_PROVID,       /*!< user is confirm provider */
+    FFCDH_DO_CONFIRM_RECIP,        /*!< user is confirm recipient */
+
+    FFCDH_DO_OFF_MODE,             /*!< not allowed value */
+    FFCDH_DO_PARAMS_LAST = 0x7FFFFFFF
+} FfcDhSchemeInfoBits_t;
+
+
+/* Define DH Scheme Info bits for given FFCDH Scheme , user party (U,V) and confirmation role */
+/* Scheme: dhHybrid1 */
+#define FFCDH_HYBRID1_U  ((1UL<<FFCDH_DO_USER_STAT_KEY)||(1<<FFCDH_DO_USER_EPHEM_KEY)|| \
+                      (1<<FFCDH_DO_PARTN_STAT_KEY)||(1<<FFCDH_DO_PARTN_EPHEM_KEY))
+#define FFCDH_HYBRID1_V FFCDH_HYBRID1_U
+/* Scheme: dhEphem: NoConfirm */
+#define FFCDH_EPHEM_U  ((1UL<<FFCDH_DO_USER_STAT_KEY)||(1<<FFCDH_DO_USER_EPHEM_KEY)|| \
+                    (1<<FFCDH_DO_PARTN_STAT_KEY)||(0<<FFCDH_DO_PARTN_EPHEM_KEY))
+#define FFCDH_EPHEM_V  FFCDH_EPHEM_U
+/* Scheme: dhHybridOneFlow_U */
+#define FFCDH_HYBRID_ONE_FLOW_U  ((1UL<<FFCDH_DO_USER_STAT_KEY)||(1<<FFCDH_DO_USER_EPHEM_KEY)|| \
+                              (1<<FFCDH_DO_PARTN_STAT_KEY)||(0<<FFCDH_DO_PARTN_EPHEM_KEY))
+#define FFCDH_HYBRID_ONE_FLOW_V  ((1UL<<FFCDH_DO_USER_STAT_KEY)||(0<<FFCDH_DO_USER_EPHEM_KEY)|| \
+                              (1<<FFCDH_DO_PARTN_STAT_KEY)||(1<<FFCDH_DO_PARTN_EPHEM_KEY))
+/* Scheme: dhOneFlow_U */
+#define FFCDH_ONE_FLOW_U  ((0UL<<FFCDH_DO_USER_STAT_KEY)||(1<<FFCDH_DO_USER_EPHEM_KEY)|| \
+                       (1<<FFCDH_DO_PARTN_STAT_KEY)||(0<<FFCDH_DO_PARTN_EPHEM_KEY))
+#define FFCDH_ONE_FLOW_V  ((1UL<<FFCDH_DO_USER_STAT_KEY)||(0<<FFCDH_DO_USER_EPHEM_KEY)|| \
+                       (0<<FFCDH_DO_PARTN_STAT_KEY)||(1<<FFCDH_DO_PARTN_EPHEM_KEY))
+/* Scheme: dhStatic */
+#define FFCDH_STATIC_U  ((1UL<<FFCDH_DO_USER_STAT_KEY)||(0<<FFCDH_DO_USER_EPHEM_KEY)|| \
+                      (1<<FFCDH_DO_PARTN_STAT_KEY)||(0<<FFCDH_DO_PARTN_EPHEM_KEY))
+#define FFCDH_STATIC_V  FFCDH_STATIC_U
+#endif
+
+
+/************************** Macros ******************************/
+
+/* The macro sets uint16 length (len) into bytes-buffer, given by the pointer (ptr) as
+ * 2-bytes big endianness counter, and then promote the pointer by 2 bytes.
+ * Note: Dst buffer should be given by pointer (not by buffer name). */
+#define FFCDH_SET_LENGTH(ptr, len) \
+    (ptr)[0] = ((len)>>1) & 0xFF; (ptr)[1] = (len) & 0xFF; \
+    (ptr) += CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+/* The macro reads length (2 bytes BE number) from bytes-buffer into uint16 value
+ * and promotes pointer to next buffer (sub-entry).
+ * Note: Dst buffer should be given by pointer (not by buffer name). */
+#define FFCDH_GET_LENGTH(ptr) (((uint16_t)((ptr)[0])<< 8) | (ptr)[1]); \
+    (ptr) += CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES;
+#define FFCDH_SET_OFFSET(prevOffset, prevDataSize)  ((prevOffset) + (prevDataSize) + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES)
+/* macro sets offset depending on condition value which shall be 1 or 0. If it is 1,
+ * then prevDataSize is added to offset, else - not added. All sizes are uint16_t values. */
+#define FFCDH_COND_SET_OFFSET(prevOffset, prevDataSize, conditionVal)  \
+    ((prevOffset) + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES + ((prevDataSize) & (uint16_t)((0UL - (conditionVal)) & 0xFFFFUL)))
+
+/* Macros for checking DH Context validation tag according to
+ * DH functions flow stage. In other words, check that all required
+ * previous stages (functions calls) are done. If all is done, the macro
+ * returns 0, else returns 1.
+ */
+#define FFCDH_CHECK_CTX_VALID_TAG_BITS(validTag, checkBits) (((validTag) & (checkBits)) != (checkBits))
+
+/* enumerator, defining parameters */
+typedef enum
+{
+    FFCDH_NO_PARAM,
+    FFCDH_DO_PARAM,
+    FFCDH_PARAM_DONE
+}FfcDhParamsSetting_t;
+
+
+/************************ Structures ******************************/
+
+
+/*! Structure, defining which FFC DH parameters are involved in the Scheme
+    according to Scheme ID, user party (U,V) and confirmation role. If some
+    member of the structure is equal to 1, then appropriate  parameter is
+    needed and if 0 - not. */
+typedef struct
+{
+    uint32_t doUserStatKey;
+    uint32_t doUserEphemKey;
+    uint32_t doUserNonce;
+    uint32_t doPartnerStatKey;
+    uint32_t doPartnerEphemKey;
+    uint32_t doPartnerNonce;
+    uint32_t doConfirmProvid;
+    uint32_t doConfirmRecip;
+
+}FfcDhSchemeInfo_t;
+
+
+/*! Structure, defining sizes and offsets of OtherInfo sub-entries
+ *  inside the KdfBuffer buffer, placed in the DH context (see SP 56A, sec. 5.8.1.2, 5.8.1.2.1).
+ *  extendOtherInfo = counter||ZZ||AlgId||PartyUInfo||PartyVinfo||suppPublInfo||suppPrivInfo;
+ *  Each PartyInfo = PartyId||StatPublKeyInfo||EphemKeyInfo||nonce||OtherPartyData
+ *  Note: - Each sub-entry includes 2-bytes, defining its size.
+ *        - If any sub-entry is not used then its size should be set to 0 and data - empty.
+ *        - size of the structure - 21 word = 84 bytes. */
+typedef struct
+{
+    uint32_t  kdfCounterOffset;        /*!< KDF counter offset */
+    uint32_t  sharedSecrOffset;        /*!< offset of the Algorithm ID data */
+
+    /* Other Info Entries */
+    uint32_t  algIdOffset;             /*!< offset of the Algorithm ID data */
+    uint32_t  userIdOffset;            /*!< offset of the userIdOffset = userInfo */
+    uint32_t  userStatPublKeyOffset;   /*!< offset of the static public key. */
+    uint32_t  userEphemPublKeyOffset;  /*!< offset of the ephemeral key. */
+    uint32_t  userNonceOffset;         /*!< offset of nonce (if present) */
+    uint32_t  userOtherDataOffset;     /*!< offset of user other (additional) data */
+
+    uint32_t  partnIdOffset;           /*!< offset of the partnIdOffset = partnInfo */
+    uint32_t  partnStatPublKeyOffset;  /*!< offset of the static public key. */
+    uint32_t  partnEphemPublKeyOffset; /*!< offset of the ephemeral key. */
+    uint32_t  partnNonceOffset;        /*!< offset of nonce (if present) */
+    uint32_t  partnOtherDataOffset;    /*!< offset of partner other (additional) data */
+
+    uint32_t  suppPublInfoOffset;      /*!< offset of supplied public Info data */
+    uint32_t  suppPrivInfoOffset;      /*!< offset of supplied private Info data */
+
+    /* data entries sizes in bytes */
+    uint32_t  sharedSecrSize;          /*!< size of the Algorithm ID data */
+    uint32_t  algIdSize;               /*!< offset of the Algorithm ID data */
+    uint32_t  userInfoSize;            /*!< full size of user data */
+    uint32_t  partnInfoSize;           /*!< full size of partner data */
+    uint32_t  suppPublInfoSize;        /*!< size of supplied public Info data */
+    uint32_t  suppPrivInfoSize;        /*!< size of supplied private Info data */
+
+}FfcDhSchemeDataOffsets_t;
+
+
+
+
+
+/**************************************************************/
+/*! DH Key Agreement  context structure, used in DH functions.
+    The context contains appropriate parameters and data in accordance with NIST SP 800-56A Rev. 2 standard
+    and this implementation definitions.
+    \note  Some buffers for internal using of functions may be set on tmpBuff structure in the context.
+    \note  The domain parameters and keys are saved in arrays with little endianness order of bytes and words
+            (i.e. LS byte/word are right most) with indication of entry size.
+    \note  Public keys, when are used in KDF and MAC calculations, are presented as big endianness bytes arrays
+           with constant size, equalled to field size, and leading zeros, if existed.
+    \note  Max.size of Context:
+*/
+typedef struct
+{
+        uint32_t validTag; /*!< the context validation tag, indicates that the context and its members are set
+                                according to current stage of DH functions flow. The bits of LS Bytes of validTag
+                                indicate, that appropriate function was done or data inserted (1 - done, 0 - not done):
+                                b'0 - context initialised to zero;
+                                b'1 - DH Scheme parameters (DH Scheme, HASH mode, KDF mode, user party,
+                                      confirmation mode etc.) are inserted;
+                                b'2 - FFC Domain is inserted;
+                                b'3,4 - user's static/ephemeral keys, needed by the Scheme, are inserted;
+                                b'5,6 - partner's static/ephemeral keys, needed by the Scheme, are inserted;
+                                b'7 - PartyUInfo, PartyVInfo and Confirmation TextU, TextV are inserted;
+                                b'8 - Shared Secret Keying Material and user's MacTag are calculated;
+                                b'9 - calculating of expected partner's MacTag and its comparing with the
+                                      value, received from the partner, are done. */
+
+        /*! DH FFC Domain parameters structure (p,q,g,{seed,genCounter}. */
+        CCFfcDomain_t ffcDomain; // 636 bytes
+        /*!  FFC DH Key Agreement Scheme parameters */
+        CCFfcDhSchemeId_t dhSchemeId;      /*!< enumerator ID of used FFC DH Key Agreement Scheme (see sec. 6, table 12). */
+        CCFfcDhKdfModeSp56A_t kdfMode;     /*!< enumerator ID of used KDF function supported KDF, based on
+                                             HASH or HMAC algorithms. */
+        CCFfcHashOpMode_t ffcHashMode;     /*!< enumerator ID of used SHA-x HASH mode, supported by the
+                                             product (Note: MD5 is not supported). */
+        CCFfcDhUserPartyIs_t userParty;    /*!< enumerator, defining user (i.e. the function's caller) party in DH Agreement (U or V). */
+        CCFfcDhUserConfirmMode_t confirmMode; /*!< enumerator, defining confirmation mode of each party: is it provider
+                                                   or/and recipient, according to sec. 5.9. */
+        CCFfcParamSetId_t ffcParamSet;     /*!< enumerator, defining the set of FFC domain parameters
+                                              according to SP 56A rev.2 section 5.5.1.1, tab.1. and FIPS 186-4 sec.4.2. */
+        /*! Internal structure "schemeInfo": each its member indicates that appropriate scheme parameter or operation is required
+            according to chosen Scheme, user party (U,V) and Confirmation role. Size of buffer 8*sizeof(uint32_t). */
+        FfcDhSchemeInfo_t schemeInfo;
+
+        uint32_t hmacSaltSizeBytes;
+        uint32_t hmacSalt[CC_FFCDH_MAX_SIZE_OF_HMAC_SALT_BUFF_BYTES/CC_32BIT_WORD_SIZE];
+        uint32_t nonceSize; /* size of nonce, agreed by both parties: shall be = order size, if exist, or 0 otherwise */
+
+        /*! Derived secret keying data and keying material sizes (in bytes) and buffer for it placing. */
+        uint32_t secretKeyingDataSize; /* size keying data to be derived and used as result output secretKeyingData. */
+        /*! the derived Keying material, which consists (parsed) from two keys: HMAC Key (of size = size of HASH,
+         *  used in confirmation) and secretKeyingData of above stated size */
+        uint8_t  derivedKeyingMaterial[CC_FFCDH_MAX_SIZE_OF_KEYING_MATERIAL_BYTES];
+        uint32_t derivedKeyingMaterialSize; /* size in bytes). */
+
+        /*!  User's private static, ephemeral keys and Nonce (if present):
+         *   Note: Size of each one of private keys buffer is equaled to actual FFC generator order size;
+         *         bytes and words order is little endianness and leading zeros are present. */
+        uint32_t statPrivKeySizeBytes;
+        uint32_t statPrivKey[CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_WORDS];  /*!<  user's static private key. */
+        uint32_t ephemPrivKeySizeBytes;
+        uint32_t ephemPrivKey[CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_WORDS];  /*!<  user's ephemeral private key. */
+
+//       uint32_t userInfoSize, partnInfoSize;
+        /*!  User and partner public keys: static, ephemeral and nonce (if present):
+         *   userStaticPublic, userEphemerPublic keys and nonce,
+         *   Max.size of two structures: 2*(2*ModSize + OrderSize + 3w) = 520 bytes*/
+//        CCFfcDhCtxPublKeys_t userPublKeys; // max.size: 2*ModSize + OrderSize + 8 = 520 bytes
+//        CCFfcDhCtxPublKeys_t partnPublKeys; // max.size 2*256+8 = 520 bytes
+        // The structure userPublKeys includes:
+        uint32_t userIdSizeBytes; /*!< user's ID actual size in bytes  */
+        uint8_t  userId[CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES]; /*!<  user's ID. */
+        uint32_t userStatPublKeySizeBytes;  /*!< user's static ephemeral public key size in bytes  */
+        uint32_t userStatPublKey[CC_FFCDH_MAX_MOD_SIZE_IN_WORDS]; /*!<  user's static ephemeral public key. */
+        uint32_t userEphemPublKeySizeBytes;  /*!< user's ephemeral public key size in bytes  */
+        uint32_t userEphemPublKey[CC_FFCDH_MAX_MOD_SIZE_IN_WORDS]; /*!<  user's ephemeral public key. */
+        uint32_t userNonceSizeBytes;  /*!< actual size of user's Nonce {0 if not inserted)  */
+        uint8_t  userNonce[CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BYTES]; /*!<  user's Nonce */
+        uint32_t userConfirmTextSize; /*!< [in] optional size of Text data of partyU, in bytes. */
+        uint8_t  userConfirmText[CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES]; /*!< confirmation Text of the User. */
+
+        /*!  Partner's public key/keys: static and ephemeral (if present): */
+        // The structure partnPublKeys includes:
+        uint32_t partnerIdSizeBytes;  /*!< user's ID actual size in bytes  */
+        uint8_t  partnerId[CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES];  /*!<  user's ID. */
+        uint32_t partnerStatPublKeySizeBytes;  /*!< partner's static ephemeral public key size in bytes  */
+        uint32_t partnerStatPublKey[CC_FFCDH_MAX_MOD_SIZE_IN_WORDS];  /*!<  partner's static ephemeral public key. */
+        uint32_t partnerEphemPublKeySizeBytes;  /*!< partner's ephemeral public key size in bytes  */
+        uint32_t partnerEphemPublKey[CC_FFCDH_MAX_MOD_SIZE_IN_WORDS];  /*!<  partner's ephemeral public key. */
+        uint32_t partnerNonceSizeBytes;  /*!< partner's's Nonce */
+        uint8_t  partnerNonce[CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BYTES];  /*!<  partner Nonce */
+        uint32_t partnerConfirmTextSize; /*!< [in] size of the Text data of the partner, in bytes. */
+        uint8_t  partnerConfirmText[CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES]; /*!< confirmation Text of the Partner. */
+
+        /* buffers to be included in DH KDF data and OtherInfo data */
+//        uint8_t commonBuffForKdf[CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_COMMON_BUFF]; /* KdfCounter || Zz || AlgId */
+//        uint8_t userInfo[CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES];    /* user Info: userId||userStatPublKey||userephemerPublKey||userNonce */
+//        uint8_t partnerInfo[CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES]; /* partner Info: partnerId||partnerStatPublKey||partnerEphemerPublKey||partnerNonce */
+//        uint8_t supplPublInfo[CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES]; /* supplied public data known for both parties */
+//        uint8_t supplPrivInfo[CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES]; /* supplied private data known for both parties */
+
+
+
+        /*!  FFC DH extended Data buffer, containing data used for extraction secret keying material by KDF function.
+         *   The buffer includes: Counter||SharedSecretZz||OtherInfo data. See sec. 5.8.1, 5.8.1.1, 5.8.1.2. */
+        uint8_t  extendDataBuffer[CC_FFCDH_MAX_SIZE_OF_KDF_DATA_BUFFER_BYTES];
+        uint32_t currInsertedDataSize;
+        uint32_t otherInfoSize;
+
+//        CCFfcDhOtherInfo_t otherInfoBuff;   /*!< buffer, containing "other data", shared by both key agreement
+//                                             parties and constructed according to concatenation method, described
+//                                             in sec. 5.8.1 of said standard current implementation requirements.
+//                                             For detailed description see CCFfcDhOtherInfo_t definition.
+//                                             Max.size 884 bytes.  */
+
+        /*! Structure, containing offsets and sizes of  parties Info in OterInfo buffer (in bytes) */
+        FfcDhSchemeDataOffsets_t dataOffsets;
+
+//        CCFfcDhConfirmMacData_t macData;  /*!< buffer for confirmation data, ordered according
+//                                            to sec. 5.9, 5.9.1.1 and party role (U,V). Max size 614 bytes. */
+        //        CCFfcDhConfirmMacData_t macDataV;  /*!< structure, containing confirmation data ordered by provider V,
+//                                             according to sec. 5.9, 5.9.1.1 */
+        /*!  FFC DH Key Agreement Scheme MacTags */
+        CCHashResultBuf_t userMacTag;    /*!< buffer for calculation confirmation MacTag of user as provider. */
+        CCHashResultBuf_t partnerMacTag; /*!< buffer for calculation confirmation MacTag of partner as provider. */
+        uint32_t macTagSize;             /*!< size in bytes of confirmation MacTag-s */
+        /*! Temp buffer, used in internal calculations */
+        CCFfcDhTemp_t tmpBuff;           /*!< [in] structure, containing internal temp buffers, used in DH functions,
+                                             such as Derived Keying Data, offsets of specific entries in otherInfo, MacData ,
+                                             work space buffers etc. */
+} DhContext_t;
+
+
+/* Check Context size: print error message if the size is not correct */
+#define DH_LOCAL_CONTEXT_SIZE_BYTES \
+ROUNDUP_BYTES_TO_32BIT_WORD((FFC_DOMAIN_SIZE_BYTES + CC_FFCDH_MAX_SIZE_OF_HMAC_SALT_BUFF_BYTES + CC_FFCDH_MAX_SIZE_OF_KEYING_MATERIAL_BYTES + \
+4*CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BYTES/*2priv,2nonce*/ + 2*CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES + 4*CC_FFCDH_MAX_MOD_SIZE_IN_BYTES + \
+CC_FFCDH_MAX_SIZE_OF_KDF_DATA_BUFFER_BYTES + 2*CC_HASH_RESULT_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE/*MacTags*/ + 32/*schemeInfo*/ + \
+84/*dataOffsets*/ + 2*CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES + 26*CC_32BIT_WORD_SIZE/*separ.words*/ + CC_FFCDH_CTX_TMP_BUFF_MAX_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE))
+
+#if (CC_FFCDH_CONTEXT_BUFF_SIZE_IN_BYTES != DH_LOCAL_CONTEXT_SIZE_BYTES)
+#error CC_FFCDH_CONTEXT_SIZE_IN_WORDS defined not correct.
+#endif
+
+/* Data base array, indicating combination of parameters and operations, required by different Schemes.
+ *
+ * This 3-dimensional array contains structures of mentioned above parameters appropriates, for each Schemes.
+ */
+//FfcDhSchemeInfo_t ffcdhSchemeMatrix[CC_FFCDH_SCHEM_NUM_OFF_MODE][CC_FFCDH_PARTY_NUM_OFF_MODE][CC_FFCDH_CONFIRM_NUM_OFF_MODE];
+//
+//#define FFCDH_SCHEMES_MATRIX
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/cc_hkdf.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/cc_hkdf.c
new file mode 100644
index 0000000..14a0765
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/cc_hkdf.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_common_math.h"
+#include "cc_hmac.h"
+#include "cc_hkdf.h"
+#include "cc_hkdf_error.h"
+#include "cc_fips_defs.h"
+
+/************************ Defines *******************************/
+
+/************************ Enums *********************************/
+
+/************************ macros ********************************/
+
+
+/************************    Global Data    ******************************/
+
+/************************ Private Functions ******************************/
+
+/**
+ *   The function returns a number of attributes related to a given hkdf hash mode
+ */
+static CCError_t GetParamsFromHKDFHashMode(
+                CCHkdfHashOpMode_t    HKDFhashMode,
+                CCHashOperationMode_t* HashMode_ptr,
+                uint32_t*                  HashOutputSizeBytes_ptr,
+                uint32_t*                  BlockSizeBytes_ptr)
+{
+    *BlockSizeBytes_ptr = CC_HASH_BLOCK_SIZE_IN_BYTES;    /*for all modes, besides SHA512*/
+
+    switch (HKDFhashMode) {
+    case CC_HKDF_HASH_SHA1_mode:
+        *HashMode_ptr = CC_HASH_SHA1_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA224_mode:
+        *HashMode_ptr  = CC_HASH_SHA224_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA256_mode:
+        *HashMode_ptr  = CC_HASH_SHA256_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA384_mode:
+        *HashMode_ptr = CC_HASH_SHA384_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+        *BlockSizeBytes_ptr = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA512_mode:
+        *HashMode_ptr = CC_HASH_SHA512_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+        *BlockSizeBytes_ptr = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+        break;
+    default:
+        return CC_HKDF_INVALID_ARGUMENT_HASH_MODE_ERROR;
+    }
+
+    return CC_OK;
+}
+
+/****************************************************************/
+/**
+ * @brief HkdfExtract performs the extract stage of the HMAC-based key derivation, according to RFC5869.
+    Computes a pseudo random key as PRK = HMAC_HASH (key=Salt , Data=Ikm)
+*/
+CCError_t  HkdfExtract(CCHkdfHashOpMode_t HKDFhashMode,
+                uint8_t*                salt_ptr,
+                size_t                  salt_len,
+                uint8_t*                ikm_ptr,
+                uint32_t                ikm_len,
+                uint8_t*                prk_ptr,
+                uint32_t*               prk_len_ptr)
+{
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    /* HASH function context structure buffer and parameters  */
+    CCHashOperationMode_t hashMode;
+    uint32_t  HashOutputSizeBytes;
+    uint32_t  BlockSizeBytes;
+
+    /*The result buffer for the Hash*/
+    CCHashResultBuf_t   HmacResultBuff;
+    uint8_t   SaltBuffer[CC_HKDF_MAX_HASH_KEY_SIZE_IN_BYTES]={0};
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    if (prk_ptr == NULL || prk_len_ptr == NULL || ikm_ptr == NULL) {
+        return CC_HKDF_INVALID_ARGUMENT_POINTER_ERROR;
+    }
+
+    Error = GetParamsFromHKDFHashMode(HKDFhashMode, &hashMode, &HashOutputSizeBytes, &BlockSizeBytes);
+    if (Error != CC_OK)
+        goto End;
+
+    if (*prk_len_ptr < HashOutputSizeBytes ) {
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+    }
+
+    if (salt_ptr == NULL){
+        if (salt_len!=0)
+            return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+    }
+
+    if (salt_len==0) {
+        salt_len = (uint16_t)HashOutputSizeBytes;
+        salt_ptr = SaltBuffer;
+    }
+
+    //check that salt len is not bigger than the macximum allowed size key
+    if ( salt_len != (uint16_t)salt_len )
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+
+    Error = CC_Hmac( hashMode, salt_ptr, (uint16_t)salt_len, ikm_ptr, ikm_len, HmacResultBuff);
+    if (Error != CC_OK)
+        goto End;
+
+
+    /* Copying HASH data into output buffer */
+    CC_PalMemCopy(prk_ptr,(uint8_t *)HmacResultBuff, HashOutputSizeBytes);
+    *prk_len_ptr = HashOutputSizeBytes;
+
+End:
+    /* clean temp buffers */
+    CC_PalMemSetZero(&HmacResultBuff, sizeof(CCHashResultBuf_t));
+
+    return Error;
+
+}/* END OF HkdfExtract */
+
+/**
+ * @brief HkdfExpand performs the expand stage of the HMAC-based key derivation, according to RFC5869.
+    N = Ceil(L/HashLen)
+    T = T(1) | T(2) | T(3) . . . . . | T(N)
+    Computes the output key Material as follow OKM = first L octets of T
+    where:
+    T(0) = empty_string (zero length)
+    T(1) = HMAC_HASH ( PRK, T(0) | info |0x01 )
+    T(2) = HMAC_HASH ( PRK, T(1) | info |0x02 )
+    T(N) = HMAC_HASH ( PRK, T(N-1) | info |N )   N<=255
+*/
+CCError_t  HkdfExpand(CCHkdfHashOpMode_t HKDFhashMode,
+                   uint8_t*                prk_ptr,
+                   uint32_t                prk_len,
+                   uint8_t*                info,
+                   uint32_t                info_len,
+                   uint8_t*                okm_ptr,
+                   uint32_t                okm_len)
+{
+    uint32_t T[CC_HKDF_MAX_HASH_DIGEST_SIZE_IN_BYTES/sizeof(uint32_t)]={0};
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    /* HASH function context structure buffer and parameters  */
+    CCHashOperationMode_t hashMode;
+    uint32_t  HashOutputSizeBytes;
+    uint32_t  BlockSizeBytes;
+    CCHmacUserContext_t  UserContext;
+
+    uint32_t N;
+    uint32_t i;
+    uint8_t counter;
+    uint32_t disp=0;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    if (info == NULL) {
+        info_len = 0;
+    }
+
+    if (prk_ptr == NULL || prk_len == 0 || okm_ptr == NULL) {
+        return CC_HKDF_INVALID_ARGUMENT_POINTER_ERROR;
+    }
+
+    Error = GetParamsFromHKDFHashMode(HKDFhashMode, &hashMode, &HashOutputSizeBytes, &BlockSizeBytes);
+    if (Error != CC_OK)
+        goto End;
+
+    if (prk_len < HashOutputSizeBytes) {
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+    }
+
+    N = okm_len / HashOutputSizeBytes;
+    if ( N*HashOutputSizeBytes != okm_len ){
+        ++N;
+    }
+
+    if (N > 255)
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+
+    for (i=1; i<=N; i++) {
+        counter = (uint8_t)i;
+
+        Error = CC_HmacInit(&UserContext, hashMode, prk_ptr, prk_len);
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        if (i != 1) {
+            Error = CC_HmacUpdate(&UserContext, (uint8_t*)T, HashOutputSizeBytes);
+            if(Error != CC_OK) {
+                goto End;
+            }
+        }
+
+        Error = CC_HmacUpdate(&UserContext, info, info_len);
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        Error = CC_HmacUpdate(&UserContext, &counter, 1);
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        Error = CC_HmacFinish(&UserContext, T);
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        CC_PalMemCopy(okm_ptr+disp, T, (i!=N)?HashOutputSizeBytes:okm_len-disp);
+        disp += HashOutputSizeBytes;
+    }
+
+    return Error;
+
+End:
+    /* clean outbuffer when error  */
+    CC_PalMemSetZero(okm_ptr, okm_len);
+
+    return Error;
+
+}
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief CC_HkdfKeyDerivFunc performs the HMAC-based key derivation, according to RFC5869
+*/
+CEXPORT_C CCError_t  CC_HkdfKeyDerivFunc(
+                        CCHkdfHashOpMode_t HKDFhashMode,
+                        uint8_t*                Salt_ptr,
+                        size_t                SaltLen,
+                        uint8_t*                Ikm_ptr,
+                        uint32_t                IkmLen,
+                        uint8_t*                Info,
+                        uint32_t                InfoLen,
+                        uint8_t*                Okm,
+                        uint32_t                OkmLen,
+                        CCBool                  IsStrongKkey
+                        )
+{
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    uint8_t   PRKBuffer[CC_HKDF_MAX_HASH_DIGEST_SIZE_IN_BYTES];
+    uint32_t  PRKBuffer_Len = sizeof(PRKBuffer);
+
+    if (IsStrongKkey == CC_FALSE) {
+        Error = HkdfExtract(HKDFhashMode, Salt_ptr, SaltLen, Ikm_ptr, IkmLen,
+                    PRKBuffer, &PRKBuffer_Len);
+
+        if (Error != CC_OK)
+            return Error;
+
+        Error = HkdfExpand(HKDFhashMode, PRKBuffer, PRKBuffer_Len, Info, InfoLen, Okm, OkmLen);
+    }
+    else { //skip extraction phase
+        Error = HkdfExpand(HKDFhashMode, Ikm_ptr, IkmLen, Info, InfoLen, Okm, OkmLen);
+    }
+
+    return Error;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/cc_kdf.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/cc_kdf.c
new file mode 100644
index 0000000..901f31b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/cc_kdf.c
@@ -0,0 +1,469 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_common_math.h"
+#include "cc_kdf.h"
+#include "cc_kdf_error.h"
+#include "cc_fips_defs.h"
+#include "cc_general_defs.h"
+#ifdef USE_MBEDTLS_CRYPTOCELL
+#include "md.h"
+#else
+#include "cc_hash.h"
+#endif
+#include "cc_hash_defs.h"
+
+/************************ Defines *******************************/
+
+/************************ Enums *********************************/
+
+/************************ macros ********************************/
+
+
+/************************    Global Data    ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************************************************************
+*   The function performs  Hash update for data with the size not
+*   aligned to Hash block.
+*
+*   Note: remBuffSize_ptr - a pointer to the remaining size of the
+*         temp buffer to fill by the data.
+*
+************************************************************************/
+
+/**
+ *   The function performs  Hash update for data with the size not
+ *   aligned to Hash block.
+ *
+ *   Note: remBuffSize_ptr - a pointer to the remaining size of the
+ *         temp buffer to fill by the data.
+ *
+ * @author reuvenl (4/3/2013)
+ *
+ * @param hashContext_ptr - HASH context pointer
+ * @param data_ptr        - input data pointer
+ * @param dataSize        - input data size in bytes
+ * @param buff_ptr        - buffer for remaining data accumulation
+ * @param remBuffSize_ptr - size of data on the buffer
+ * @param blockSizeBytes  - size of HASH input block in bytes according to mode.
+ *
+ * @return CCError_t
+ */
+static CCError_t KdfHashUnalignUpdate(
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                             mbedtls_md_context_t *p_hash_ctx,
+#else
+                             CCHashUserContext_t  *hashContext_ptr,
+#endif
+                             uint8_t *data_ptr, uint32_t dataSize,
+                             uint8_t *buff_ptr, uint32_t *remBuffSize_ptr,
+                             uint32_t blockSizeBytes)
+{
+    CCError_t error = CC_OK;
+    uint32_t  tmpSize;
+    uint8_t  *tmp_ptr;
+
+    /* set buff_ptr to begin of empty part of temp buffer */
+    tmp_ptr = buff_ptr + *remBuffSize_ptr;
+
+    /* if the temp buffer not empty, append it by the data and update Hash on it */
+    if (dataSize >= blockSizeBytes - *remBuffSize_ptr) {
+
+        CC_PalMemCopy(tmp_ptr, data_ptr, blockSizeBytes - *remBuffSize_ptr);
+
+        /* update on the data in temp buffer */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        error = mbedtls_md_update(p_hash_ctx, buff_ptr, blockSizeBytes);
+#else
+        error = CC_HashUpdate( hashContext_ptr, buff_ptr, blockSizeBytes);
+#endif
+        if (error != CC_OK)
+            return error;
+
+        /* update pointers and sizes */
+        data_ptr += blockSizeBytes - *remBuffSize_ptr;
+        dataSize -= blockSizeBytes - *remBuffSize_ptr;
+        *remBuffSize_ptr = 0;
+        tmp_ptr = buff_ptr;
+    } else {
+        CC_PalMemCopy(tmp_ptr, data_ptr, dataSize);
+        *remBuffSize_ptr += dataSize;
+        return error;
+    }
+
+    /* Update Hash on remaining input data */
+    tmpSize = dataSize % blockSizeBytes;
+    if (tmpSize > 0) {
+        dataSize -= tmpSize;
+        CC_PalMemCopy(tmp_ptr, data_ptr + dataSize, tmpSize);
+        *remBuffSize_ptr += tmpSize;
+    }
+
+    if (dataSize > 0){
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        error = mbedtls_md_update(p_hash_ctx, data_ptr, dataSize);
+#else
+        error = CC_HashUpdate( hashContext_ptr, data_ptr, dataSize);
+#endif
+    }
+
+    return error;
+}
+
+
+/**
+ * The function returns CC_HASH defined parameters according to given
+ * KDF Hash mode
+ *
+ */
+static CCError_t  KdfGetHashParameters(
+                                CCKdfHashOpMode_t kdfhashMode,
+                                CCHashOperationMode_t *pHashMode,
+                                uint32_t *pHashBlockSize,
+                                uint32_t *pHashDigestSize)
+{
+        switch (kdfhashMode) {
+        case CC_KDF_HASH_SHA1_mode:
+                *pHashMode = CC_HASH_SHA1_mode;
+                *pHashDigestSize = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+                *pHashBlockSize = CC_HASH_BLOCK_SIZE_IN_BYTES;
+                break;
+        case CC_KDF_HASH_SHA224_mode:
+                *pHashMode = CC_HASH_SHA224_mode;
+                *pHashDigestSize = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+                *pHashBlockSize = CC_HASH_BLOCK_SIZE_IN_BYTES;
+                break;
+        case CC_KDF_HASH_SHA256_mode:
+                *pHashMode = CC_HASH_SHA256_mode;
+                *pHashDigestSize = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+                *pHashBlockSize = CC_HASH_BLOCK_SIZE_IN_BYTES;
+                break;
+
+        case CC_KDF_HASH_SHA384_mode:
+                *pHashMode = CC_HASH_SHA384_mode;
+                *pHashDigestSize = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+                *pHashBlockSize = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+                break;
+        case CC_KDF_HASH_SHA512_mode:
+                *pHashMode = CC_HASH_SHA512_mode;
+                *pHashDigestSize = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+                *pHashBlockSize = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+                break;
+
+        default:
+                return CC_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR;
+        }
+
+        return CC_OK;
+}
+
+
+/************************ Public Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+
+/****************************************************************/
+
+
+/****************************************************************/
+/*!
+ @brief CC_KdfKeyDerivFunc performs key derivation according to one of the modes defined in standards:
+        ANS X9.42-2001, ANS X9.63, ISO/IEC 18033-2.
+
+The present implementation of the function allows the following operation modes:
+<ul><li> CC_KDF_ASN1_DerivMode - mode based on  ASN.1 DER encoding; </li>
+<li> CC_KDF_ConcatDerivMode - mode based on concatenation;</li>
+<li> CC_KDF_X963_DerivMode = CC_KDF_ConcatDerivMode;</li>
+<li> CC_KDF_ISO18033_KDF1_DerivMode, CC_KDF_ISO18033_KDF2_DerivMode - specific modes according to
+ISO/IEC 18033-2 standard.</li></ul>
+
+The purpose of this function is to derive a keying data from the shared secret value and some
+other optional shared information, included in OtherInfo (SharedInfo).
+
+\note All buffers arguments are represented in Big-Endian format.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_kdf_error.h.
+*/
+CCError_t  CC_KdfKeyDerivFunc(
+                    uint8_t              *pZzSecret,            /*!< [in]  A pointer to shared secret value octet string. */
+                    size_t                zzSecretSize,         /*!< [in]  The size of the shared secret value in bytes.
+                                                                           The maximal size is defined as: ::CC_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE. */
+                    CCKdfOtherInfo_t     *pOtherInfo,           /*!< [in]  A pointer to the structure, containing pointers to the data, shared by
+                                       two entities of agreement, depending on KDF mode:
+                                                                           1. On KDF ASN1 mode OtherInfo includes ASN1 DER encoding of AlgorithmID (mandatory),
+                                                                             and some optional data entries as described in part 7.7.1 of the X9.42 standard;
+                                                                           2. On both ISO18033-2 KDF1, KDF2 modes this parameter is ignored and may be set to NULL;
+                                                                           3. On other modes it is optional and may be set to NULL. */
+                    CCKdfHashOpMode_t     kdfHashMode,          /*!< [in]  The KDF identifier of hash function to be used. The hash function output
+                                       must be at least 160 bits. */
+                    CCKdfDerivFuncMode_t  derivMode,            /*!< [in]  The enum value, specifies one of above described derivation modes. */
+                    uint8_t              *pKeyingData,          /*!< [out] A pointer to the buffer for derived keying data. */
+                    size_t                keyingDataSize        /*!< [in]  The size in bytes of the keying data to be derived.
+                                                                           The maximal size is defined as :: CC_KDF_MAX_SIZE_OF_KEYING_DATA. */
+)
+
+{
+
+    /* FUNCTION DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t error = CC_OK;
+    /* HASH function context structure buffer and parameters  */
+    CCHashOperationMode_t hashMode;
+    uint32_t  hashOutputSize;
+
+    /*The result buffer for the Hash*/
+    CCHashResultBuf_t   hashResultBuff;
+    /* Total count of full HASH blockss for deriving the keying data */
+    uint32_t  countOfHashBlocks;
+
+    /* Loop counters */
+    uint32_t  i, j;
+    /*counter of Hash blocks (to be hashed with ZZ and OtherInfo) */
+    uint32_t counter;
+    /* Current output buffer position */
+    uint32_t currentOutputBuffPos = 0;
+
+    uint8_t   *pTemp;
+    uint32_t  remBuffSize, hashBlockSize;
+    uint32_t  kdfHashTempBuff[CC_HASH_SHA512_BLOCK_SIZE_IN_WORDS];
+    CCKdfOtherInfoEntries_t fromKdfMode;
+
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    const mbedtls_md_info_t *md_info=NULL;
+    mbedtls_md_context_t hash_ctx;
+#else
+    CCHashUserContext_t  hashContext;
+#endif
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    if (pZzSecret == NULL || pKeyingData == NULL) {
+        return CC_KDF_INVALID_ARGUMENT_POINTER_ERROR;
+    }
+
+    if (derivMode >= CC_KDF_DerivFunc_NumOfModes) {
+        return CC_KDF_INVALID_KEY_DERIVATION_MODE_ERROR;
+    }
+
+    if (derivMode == CC_KDF_ASN1_DerivMode &&
+        (pOtherInfo == NULL || pOtherInfo->dataPointers[CC_KDF_ALGORITHM_ID] == 0)) {
+        return CC_KDF_INVALID_ARGUMENT_POINTER_ERROR;
+    }
+
+    /*On KDF1 and KDF2 derivation modes set OtherInfo_ptr = NULL */
+    if (derivMode == CC_KDF_ISO18033_KDF1_DerivMode ||
+        derivMode == CC_KDF_ISO18033_KDF2_DerivMode) {
+        pOtherInfo = NULL;
+    }
+
+    /* Check sizes of the input data to be hashed according to KDF        *
+    *  limitations                            */
+    if (zzSecretSize == 0 || zzSecretSize > CC_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE) {
+        return CC_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR;
+    }
+
+    /* Check the size of keying data output. Note: because max size is
+       limited in our implementation by CC_KDF_MAX_SIZE_OF_KEYING_DATA
+       bytes */
+    if (keyingDataSize == 0 || keyingDataSize > CC_KDF_MAX_SIZE_OF_KEYING_DATA) {
+        return  CC_KDF_INVALID_KEYING_DATA_SIZE_ERROR;
+    }
+
+
+        /* Get HASH parameters according to current operation modes */
+        /*----------------------------------------------------------*/
+        error = KdfGetHashParameters(
+                        kdfHashMode,
+                        &hashMode,
+                        &hashBlockSize,
+                        &hashOutputSize);
+        if (error != CC_OK)
+                goto End;
+
+
+        /* Count of HASH blocks and temp buffer pointer and size */
+    countOfHashBlocks = ( keyingDataSize + hashOutputSize - 1 )/ hashOutputSize;
+    pTemp = (uint8_t*)&kdfHashTempBuff[0];
+
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+    if (NULL == md_info)
+    {
+        error = CC_KDF_INVALID_ARGUMENT_POINTER_ERROR;
+        goto End;
+    }
+    mbedtls_md_init(&hash_ctx);
+    error = mbedtls_md_setup(&hash_ctx, md_info, 0);    // 0 = HASH, not HMAC
+    if (error != 0)
+    {
+        goto End;
+    }
+#endif
+
+    /* **********  Keying data derivation loop ************ */
+
+    for (i = 0; i < countOfHashBlocks; i++) {
+        remBuffSize = 0;
+
+        /*.... HASH Init function .....*/
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        error = mbedtls_md_starts(&hash_ctx);
+#else
+        error = CC_HashInit(&hashContext, hashMode);
+#endif
+        if (error != CC_OK)
+            goto End;
+
+        /*....... Hashing input data by calling HASH_Update function .......*/
+        /*------------------------------------------------------------------*/
+
+        /*.... Hashing of the shared secret value ....*/
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        error = KdfHashUnalignUpdate(&hash_ctx,
+                                           pZzSecret,zzSecretSize,
+                                           pTemp, &remBuffSize, hashBlockSize);
+#else
+        error = KdfHashUnalignUpdate(&hashContext,
+                                           pZzSecret,zzSecretSize,
+                                           pTemp, &remBuffSize, hashBlockSize);
+#endif
+        if (error != CC_OK)
+            goto End;
+
+        /*.... Hashing of the AlgorithmID (on ASN1 Derivation Mode only) ....*/
+        if (derivMode == CC_KDF_ASN1_DerivMode) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                error = KdfHashUnalignUpdate(&hash_ctx,
+                                                       pOtherInfo->dataPointers[CC_KDF_ALGORITHM_ID],
+                                                       pOtherInfo->dataSizes[CC_KDF_ALGORITHM_ID],
+                                                       pTemp, &remBuffSize, hashBlockSize);
+#else
+            error = KdfHashUnalignUpdate(&hashContext,
+                                                   pOtherInfo->dataPointers[CC_KDF_ALGORITHM_ID],
+                                                   pOtherInfo->dataSizes[CC_KDF_ALGORITHM_ID],
+                                                   pTemp, &remBuffSize, hashBlockSize);
+#endif
+            if (error != CC_OK)
+                goto End;
+
+            fromKdfMode = CC_KDF_PARTY_U_INFO;
+        } else {
+            fromKdfMode = CC_KDF_ALGORITHM_ID;
+        }
+
+        /* Set the blocks counter in big endianness mode */
+        if (derivMode == CC_KDF_ISO18033_KDF1_DerivMode)
+            counter = i;
+        else
+            counter = i+1;
+
+#ifndef BIG__ENDIAN
+        counter = CC_COMMON_REVERSE32(counter);
+#endif
+
+        /*.... Hashing of the blocks counter ....*/
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        error = KdfHashUnalignUpdate(&hash_ctx,
+                                           (uint8_t *)&counter,
+                                           sizeof(uint32_t),
+                                           pTemp, &remBuffSize,
+                                           hashBlockSize);
+#else
+        error = KdfHashUnalignUpdate(&hashContext,
+                                           (uint8_t *)&counter,
+                                           sizeof(uint32_t),
+                                           pTemp, &remBuffSize,
+                                           hashBlockSize);
+#endif
+        if (error != CC_OK)
+            goto End;
+
+        /* ..... Hashing of remaining data of the OtherInfo ..... */
+        if (pOtherInfo != NULL) {
+
+            /* OtherInfo data concatenating and hashing loop */
+            for (j = fromKdfMode; j < CC_KDF_MAX_COUNT_OF_ENTRIES; j++) {
+                                /* if entry exists then hash it */
+                if (pOtherInfo->dataPointers[j] != NULL && pOtherInfo->dataSizes[j] != 0) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                        error = KdfHashUnalignUpdate(
+                                                            &hash_ctx,
+                                                            pOtherInfo->dataPointers[j]/*pointer to entry data*/,
+                                                            pOtherInfo->dataSizes[j]/*size of entry data*/,
+                                                            pTemp, &remBuffSize, hashBlockSize);
+#else
+                    error = KdfHashUnalignUpdate(
+                                                        &hashContext,
+                                                        pOtherInfo->dataPointers[j]/*pointer to entry data*/,
+                                                        pOtherInfo->dataSizes[j]/*size of entry data*/,
+                                                        pTemp, &remBuffSize, hashBlockSize);
+#endif
+                    if (error != CC_OK)
+                        goto End;
+                }
+            }
+        }
+
+        /* last Hash update on remaining data in the temp buffer */
+        if (remBuffSize > 0) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+            error = mbedtls_md_update(&hash_ctx, pTemp, remBuffSize);
+#else
+            error = CC_HashUpdate(&hashContext, pTemp, remBuffSize);
+#endif
+            if (error != CC_OK)
+                goto End;
+        }
+
+        /* ..........  HASH Finish operation ............. */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        error = mbedtls_md_finish(&hash_ctx, (unsigned char *)hashResultBuff);
+#else
+        error = CC_HashFinish(&hashContext, hashResultBuff);
+#endif
+        if (error != CC_OK)
+            goto End;
+
+        /* Correction of output data size for last block ( if it is not full ) */
+        if (i == (countOfHashBlocks - 1)){
+                hashOutputSize = keyingDataSize - i * hashOutputSize;
+
+        }
+        /* Copying HASH data into output buffer */
+        CC_PalMemCopy(&pKeyingData[currentOutputBuffPos],(uint8_t *)hashResultBuff, hashOutputSize);
+
+        /* Increment the output buffer position */
+        currentOutputBuffPos += hashOutputSize;
+    }
+
+End:
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        if(md_info!=NULL){
+                mbedtls_md_free(&hash_ctx);
+        }
+#endif
+        /* clean temp buffers */
+        CC_PalMemSetZero(&hashResultBuff, sizeof(CCHashResultBuf_t));
+        CC_PalMemSetZero(&kdfHashTempBuff, sizeof(kdfHashTempBuff));
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        CC_PalMemSetZero(&hash_ctx, sizeof(hash_ctx));
+#else
+        CC_PalMemSetZero(&hashContext, sizeof(hashContext));
+#endif
+
+    return error;
+
+}/* END OF CC_KdfKeyDerivFunc */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/mbedtls_cc_hkdf.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/mbedtls_cc_hkdf.c
new file mode 100644
index 0000000..faa4cd4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/kdf/mbedtls_cc_hkdf.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_common_math.h"
+#include "mbedtls_cc_hkdf.h"
+#include "mbedtls_cc_hkdf_error.h"
+#include "cc_fips_defs.h"
+#include "mbedtls/md.h"
+#include "cc_general_defs.h"
+
+/************************ Defines *******************************/
+
+/************************ Enums *********************************/
+
+/************************ macros ********************************/
+
+
+/************************    Global Data    ******************************/
+
+/************************ Private Functions ******************************/
+
+/**
+ *   The function returns a number of attributes related to a given hkdf hash mode
+ */
+static CCError_t GetParamsFromHKDFHashMode(
+        mbedtls_hkdf_hashmode_t    HKDFhashMode,
+                CCHashOperationMode_t* HashMode_ptr,
+                uint32_t*                  HashOutputSizeBytes_ptr,
+                uint32_t*                  BlockSizeBytes_ptr,
+        const mbedtls_md_info_t **mdInfo)
+{
+    *BlockSizeBytes_ptr = CC_HASH_BLOCK_SIZE_IN_BYTES;    /*for all modes, besides SHA512*/
+
+    switch (HKDFhashMode) {
+    case CC_HKDF_HASH_SHA1_mode:
+        *HashMode_ptr = CC_HASH_SHA1_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA224_mode:
+        *HashMode_ptr  = CC_HASH_SHA224_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA256_mode:
+        *HashMode_ptr  = CC_HASH_SHA256_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA384_mode:
+        *HashMode_ptr = CC_HASH_SHA384_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+        *BlockSizeBytes_ptr = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+        break;
+    case CC_HKDF_HASH_SHA512_mode:
+        *HashMode_ptr = CC_HASH_SHA512_mode;
+        *HashOutputSizeBytes_ptr = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+        *BlockSizeBytes_ptr = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+        break;
+    default:
+        *mdInfo = NULL;
+        return CC_HKDF_INVALID_ARGUMENT_HASH_MODE_ERROR;
+    }
+
+    *mdInfo = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[*HashMode_ptr] );
+    if( *mdInfo == NULL ){
+        return CC_HKDF_INVALID_ARGUMENT_HASH_MODE_ERROR;
+    }
+
+    return CC_OK;
+}
+
+/****************************************************************/
+/**
+ * @brief HkdfExtract performs the extract stage of the HMAC-based key derivation, according to RFC5869.
+    Computes a pseudo random key as PRK = HMAC_HASH (key=Salt , Data=Ikm)
+*/
+CCError_t  HkdfExtract(mbedtls_hkdf_hashmode_t HKDFhashMode,
+                uint8_t*                salt_ptr,
+                size_t                  salt_len,
+                uint8_t*                ikm_ptr,
+                uint32_t                ikm_len,
+                uint8_t*                prk_ptr,
+                uint32_t*               prk_len_ptr)
+{
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    /* HASH function context structure buffer and parameters  */
+    CCHashOperationMode_t hashMode;
+    uint32_t  HashOutputSizeBytes;
+    uint32_t  BlockSizeBytes;
+
+    /*The result buffer for the Hash*/
+    CCHashResultBuf_t   HmacResultBuff;
+    uint8_t   SaltBuffer[CC_HKDF_MAX_HASH_KEY_SIZE_IN_BYTES]={0};
+    const mbedtls_md_info_t *mdInfo = NULL;
+
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    if (prk_ptr == NULL || prk_len_ptr == NULL || ikm_ptr == NULL) {
+        return CC_HKDF_INVALID_ARGUMENT_POINTER_ERROR;
+    }
+
+    Error = GetParamsFromHKDFHashMode(HKDFhashMode, &hashMode, &HashOutputSizeBytes, &BlockSizeBytes, &mdInfo);
+    if (Error != CC_OK)
+        goto End;
+
+    if (*prk_len_ptr < HashOutputSizeBytes ) {
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+    }
+
+    if (salt_ptr == NULL){
+        if (salt_len!=0)
+            return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+    }
+
+    if (salt_len==0) {
+        salt_len = (uint16_t)HashOutputSizeBytes;
+        salt_ptr = SaltBuffer;
+    }
+
+    //check that salt len is not bigger than the macximum allowed size key
+    if ( salt_len != (uint16_t)salt_len )
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+
+    Error = mbedtls_md_hmac( mdInfo,
+                 salt_ptr, (uint16_t)salt_len,
+                 ikm_ptr, ikm_len,
+                 (unsigned char*)HmacResultBuff );
+    if (Error != CC_OK){
+        goto End;
+    }
+
+
+    /* Copying HASH data into output buffer */
+    CC_PalMemCopy(prk_ptr,(uint8_t *)HmacResultBuff, HashOutputSizeBytes);
+    *prk_len_ptr = HashOutputSizeBytes;
+
+End:
+    /* clean temp buffers */
+    CC_PalMemSetZero(&HmacResultBuff, sizeof(CCHashResultBuf_t));
+
+    return Error;
+
+}/* END OF HkdfExtract */
+
+/**
+ * @brief HkdfExpand performs the expand stage of the HMAC-based key derivation, according to RFC5869.
+    N = Ceil(L/HashLen)
+    T = T(1) | T(2) | T(3) . . . . . | T(N)
+    Computes the output key Material as follow OKM = first L octets of T
+    where:
+    T(0) = empty_string (zero length)
+    T(1) = HMAC_HASH ( PRK, T(0) | info |0x01 )
+    T(2) = HMAC_HASH ( PRK, T(1) | info |0x02 )
+    T(N) = HMAC_HASH ( PRK, T(N-1) | info |N )   N<=255
+*/
+CCError_t  HkdfExpand(mbedtls_hkdf_hashmode_t HKDFhashMode,
+                   uint8_t*                prk_ptr,
+                   uint32_t                prk_len,
+                   uint8_t*                info,
+                   uint32_t                info_len,
+                   uint8_t*                okm_ptr,
+                   uint32_t                okm_len)
+{
+    uint32_t T[CC_HKDF_MAX_HASH_DIGEST_SIZE_IN_BYTES/sizeof(uint32_t)]={0};
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    /* HASH function context structure buffer and parameters  */
+    CCHashOperationMode_t hashMode;
+    uint32_t  HashOutputSizeBytes;
+    uint32_t  BlockSizeBytes;
+
+    uint32_t N;
+    uint32_t i;
+    uint8_t counter;
+    uint32_t disp=0;
+    const mbedtls_md_info_t *mdInfo = NULL;
+    mbedtls_md_context_t hmacCtx;
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    if (info == NULL) {
+        info_len = 0;
+    }
+
+    if (prk_ptr == NULL || prk_len == 0 || okm_ptr == NULL) {
+        return CC_HKDF_INVALID_ARGUMENT_POINTER_ERROR;
+    }
+
+    Error = GetParamsFromHKDFHashMode(HKDFhashMode, &hashMode, &HashOutputSizeBytes, &BlockSizeBytes, &mdInfo);
+    if (Error != CC_OK)
+        return Error;
+
+    if (prk_len < HashOutputSizeBytes) {
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+    }
+
+    N = okm_len / HashOutputSizeBytes;
+    if ( N*HashOutputSizeBytes != okm_len ){
+        ++N;
+    }
+
+    if (N > 255)
+        return CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR;
+
+    /* Initialize the hmac ctx */
+    mbedtls_md_init( &hmacCtx );
+    Error = mbedtls_md_setup( &hmacCtx, mdInfo, 1 );
+    if (Error != CC_OK){
+        goto End;
+    }
+
+    for (i=1; i<=N; i++) {
+        counter = (uint8_t)i;
+
+
+        Error = mbedtls_md_hmac_starts( &hmacCtx, prk_ptr, prk_len );
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        if (i != 1) {
+            Error = mbedtls_md_hmac_update( &hmacCtx, (uint8_t*)T, HashOutputSizeBytes );
+            if(Error != CC_OK) {
+                goto End;
+            }
+        }
+
+        Error = mbedtls_md_hmac_update( &hmacCtx, info, info_len );
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        Error = mbedtls_md_hmac_update( &hmacCtx, &counter, 1 );
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        Error = mbedtls_md_hmac_finish(&hmacCtx, (unsigned char*)T);
+        if(Error != CC_OK) {
+            goto End;
+        }
+
+        CC_PalMemCopy(okm_ptr+disp, T, (i!=N)?HashOutputSizeBytes:okm_len-disp);
+        disp += HashOutputSizeBytes;
+    }
+
+    mbedtls_md_free( &hmacCtx );
+    return Error;
+
+End:
+    /* Free the md context */
+    mbedtls_md_free( &hmacCtx );
+    /* clean outbuffer when error  */
+    CC_PalMemSetZero(okm_ptr, okm_len);
+
+    return Error;
+
+}
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief mbedtls_hkdf_key_derivation performs the HMAC-based key derivation, according to RFC5869
+*/
+CCError_t  mbedtls_hkdf_key_derivation(
+            mbedtls_hkdf_hashmode_t HKDFhashMode,
+                        uint8_t*                Salt_ptr,
+                        size_t                SaltLen,
+                        uint8_t*                Ikm_ptr,
+                        uint32_t                IkmLen,
+                        uint8_t*                Info,
+                        uint32_t                InfoLen,
+                        uint8_t*                Okm,
+                        uint32_t                OkmLen,
+                        CCBool                  IsStrongKkey
+                        )
+{
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    uint8_t   PRKBuffer[CC_HKDF_MAX_HASH_DIGEST_SIZE_IN_BYTES];
+    uint32_t  PRKBuffer_Len = sizeof(PRKBuffer);
+
+    if (IsStrongKkey == CC_FALSE) {
+        Error = HkdfExtract(HKDFhashMode, Salt_ptr, SaltLen, Ikm_ptr, IkmLen,
+                    PRKBuffer, &PRKBuffer_Len);
+
+        if (Error != CC_OK){
+            return Error;
+        }
+
+
+        Error = HkdfExpand(HKDFhashMode, PRKBuffer, PRKBuffer_Len, Info, InfoLen, Okm, OkmLen);
+    }
+    else { //skip extraction phase
+        Error = HkdfExpand(HKDFhashMode, Ikm_ptr, IkmLen, Info, InfoLen, Okm, OkmLen);
+    }
+
+    return Error;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka.c
new file mode 100644
index 0000000..674d801
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka.c
@@ -0,0 +1,1164 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_hal_plat.h"
+#include "cc_sram_map.h"
+#include "dx_crys_kernel.h"
+#include "cc_regs.h"
+#include "pka_hw_defs.h"
+#include "pki.h"
+#include "pki_dbg.h"
+#include "pka.h"
+#include "ec_wrst.h"
+#include "pka_error.h"
+#include "cc_common_math.h"
+#include "cc_hal.h"
+#include "cc_int_general_defs.h"
+
+extern CC_PalMutex CCAsymCryptoMutex;
+
+/* Maximum allowed PKA registers are 32 (PKA_MAX_COUNT_OF_PHYS_MEM_REGS): first 2 (PKA_REG_N & PKA_REG_NP) servers for N (modulus) and Np respectivly.
+   last 2 (PKA_REG_T0 & PKA_REG_T1) are reserved for HW use. so we have total of 28 registers for SW usage
+   list of maximum 28 allowed temp PKA registers for functions.
+   Note: last 2 are numbered 0xFF - for debug goals */
+const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS] = {PKA_REG_N, PKA_REG_NP,
+        0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,
+        0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,
+        0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,PKA_REG_T0,PKA_REG_T1};
+
+#if defined PKA_DEBUG && defined DEBUG
+uint32_t tempRes[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+uint32_t tempRes1[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+#endif
+
+
+/***********      PkaSetRegsMapTab function      **********************/
+/**
+ * @brief This function initializes the PKA registers sizes table.
+ *
+ *   The function checks input parameters and sets the physical memory registers mapping-table
+ *   according to parameters, passed by the user:
+ *     - start address of register 0 is the start address of PKA data registers memory
+ *       CC_SRAM_PKA_BASE_ADDRESS (defined in cc_sram_map.h file);
+ *     - special registers are set as follows: N=0,NP=1,T0=30,T1=31;
+ *     - all registers have the same size, equalled to given size;
+ *
+ * @return - None.
+ *
+ */
+static void PkaSetRegsMapTab(int32_t   countOfRegs,         /*!< [in] The count of registeres, requirred by the user. */
+                              int32_t   regSizeInPkaWords)  /*!< [in] Size of registers in PKA big words (e.g. 128-bit words). */
+{
+        uint32_t  currentAddr;
+        int32_t i;
+
+        /* start addres of PKA mem. */
+        currentAddr = CC_SRAM_PKA_BASE_ADDRESS;
+
+        /* set addresses of the user requested registers (excluding T0,T1) */
+        for (i = 0; i < PKA_MAX_COUNT_OF_PHYS_MEM_REGS-2; i++) {
+                if (i < countOfRegs - 2) {
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + i*sizeof(uint32_t), currentAddr);
+                        currentAddr += regSizeInPkaWords*PKA_WORD_SIZE_IN_32BIT_WORDS;
+                } else {
+                        /* write designation, that PKI entry is not in use */
+                        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, MEMORY_MAP0)+ i*sizeof(uint32_t), PKA_ADDRESS_ENTRY_NOT_USED);
+                }
+        }
+        /* set addresses of 2 temp registers: T0=30, T1=31 */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + 30*sizeof(uint32_t), currentAddr);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + 31*sizeof(uint32_t),
+                                currentAddr + regSizeInPkaWords*PKA_WORD_SIZE_IN_32BIT_WORDS);
+
+        /* set default virtual addresses of N,NP,T0,T1 registers into N_NP_T0_T1_Reg */
+        PKA_DEFAULT_N_NP_T0_T1_REG();
+
+        return;
+
+}
+
+
+/***********      PkaDivLongNum function      **********************/
+/**
+ * @brief The function divides long number A*(2^S) by B:
+ *            Res =  A*(2^S) / B,  remainder A = A*(2^S) % B.
+ *        where: A,B - are numbers of size, which is not grate than, maximal operands size,
+ *               and B > 2^S;
+ *               S  - exponent of binary factor of A.
+ *               ^  - exponentiation operator.
+ *
+ *        The function algorithm:
+ *
+ *        1. Let nWords = S/32; nBits = S % 32;
+ *        2. Set Res = 0, rT1 = OpA;
+ *        3. for(i=0; i<=nWords; i++) do:
+ *            3.1. if(i < nWords )
+ *                   s1 = 32;
+ *                 else
+ *                   s1 = nBits;
+ *            3.2. rT1 = rT1 << s1;
+ *            3.3. call PKA_div for calculating the quotient and remainder:
+ *                      rT2 = floor(rT1/opB) //quotient;
+ *                      rT1 = rT1 % opB      //remainder (is in rT1 register);
+ *            3.4. Res = (Res << s1) + rT2;
+ *           end do;
+ *        4. Exit.
+ *
+ *        Assuming:
+ *                  - 5 PKA registers are used: OpA, OpB, Res, rT1, rT2.
+ *                  - The registers sizes and mapping tables are set on default mode
+ *                    according to operands size.
+ *                  - The PKA clocks are initialized.
+ *        NOTE !   Operand OpA shall be overwritten by remainder.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ *
+ */
+static CCError_t PkaDivLongNum(uint8_t      lenId, /*!< [in] ID of operation size (modSize+32). */
+                                 int8_t       OpA,   /*!< [in] Operand A: virtual register pointer of A . */
+                                 uint32_t     S,     /*!< [in] exponent of binary factor of A. */
+                                 int8_t       OpB,   /*!< [in] Operand B: virtual register pointer of B. */
+                                 int8_t       Res,   /*!< [out] Virtual register pointer for result quotient. */
+                                 int8_t       rT1,   /*!< [in] Virtual pointer to remainder. */
+                                 int8_t       rT2)   /*!< [in] Virtual pointer of temp register. */
+{
+        uint32_t  nBits, nWords;
+        uint32_t  i;
+        int8_t s1 = 0; /* current shift count */
+
+
+        /* calculate shifting parameters (words and bits ) */
+        nWords = (CALC_FULL_32BIT_WORDS((uint32_t)S));
+        nBits  = (uint32_t)S % CC_BITS_IN_32BIT_WORD;
+
+        /* copy operand OpA (including extra word) into temp reg rT1 */
+        PKA_COPY(LEN_ID_MAX_BITS, rT1/*dst*/, OpA/*src*/);
+
+        /* set Res = 0 (including extra word) */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, Res/*dst*/);
+
+
+        /* Step 1.  Shifting and dividing loop                */
+        for (i = 0; i < nWords; i++) {
+                /* 3.1 set shift value s1  */
+                if (i > 0)
+                        s1 = CC_BITS_IN_32BIT_WORD;
+                else
+                        s1 = nBits;
+
+                /* 3.2. shift: rT1 = rT1 * 2**s1 (in code (s1-1), because PKA performs S+1 shifts) */
+                if (s1 > 0) {
+                        PKA_SHL_FILL0( lenId+1, rT1/*Res*/, rT1/*OpA*/, (s1-1)/*S*/);
+                }
+
+                /* 3.3. perform PKA_DIV for calculating a quotient rT2 = floor(rT1 / N)
+                        and remainder rT1 = rT1 % OpB  */
+                PKA_DIV( lenId+1, rT2/*Res*/, rT1 /*OpA*/, OpB /*B*/);
+
+#ifdef LLF_PKI_PKA_DEBUG_
+                /* debug copy result into temp buffer */
+                CC_PalMemSetZero((uint8_t*)tempRes, sizeof(tempRes));
+                PkaCopyDataFromPkaReg(
+                                      tempRes/*dst_ptr*/, RegSizeWords,
+                                      rT1/*srcReg*/);
+#endif
+
+                /* 3.4. Res = Res * 2**s1 + Res;   */
+                if (s1 > 0) {
+                        PKA_SHL_FILL0( lenId+1, Res /*Res*/, Res /*OpA*/, (s1-1)/*S*/);
+                }
+
+                PKA_ADD( lenId+1, Res   /*Res*/, Res /*OpA*/, rT2 /*OpB*/);
+        }
+
+        PKA_WAIT_ON_PKA_DONE();
+
+        return CC_OK;
+
+}
+
+
+
+/***********        PkaModDivideBy2            **********************/
+/**
+ * @brief This function performs modular division by 2: rRes = rX / 2 mod rN.
+ *
+ * @return - None.
+ *
+ */
+void  PkaModDivideBy2(uint32_t    lenId,  /*!< [in]  ID of entry of regsSizesTable containing rX modulus exact length. */
+                      uint32_t    rX,    /*!< [in]  Virtual pointer to PKA register X.                                */
+                      uint32_t    rN,    /*!< [out]  Virtual pointer to PKA register, containing the modulus N.        */
+                      uint32_t    rRes)  /*!< [out]  Virtual pointer to PKA register, containing the result.           */
+{
+        uint32_t bitVal = 0;
+
+    if (rX != rRes) {
+                PKA_COPY(LEN_ID_MAX_BITS, rRes/*dst*/, rX/*src*/);
+        }
+
+        /* if the vector rX is odd, then add the modulus and then  divide by 2 */
+
+        PKA_READ_BIT0(lenId+1, rRes/*regNum*/, bitVal);
+        if (bitVal == 1) {
+                PKA_ADD(lenId+1, rRes/*Res*/, rRes/*P*/, rN/*OpB=N=0*/);
+        }
+
+        /* divide by 2 */
+        PKA_SHR_FILL0(lenId+1, rRes/*Res*/, rRes/*P*/, 1-1/*S*/);
+
+
+}
+
+
+/***********   PkaGetRegEffectiveSizeInBits  function **********************/
+/**
+ * @brief This function returns effective size in bits of data placed in PKA register.
+ *
+ * @return - Effective size of data in register (bits).
+ *
+ */
+uint32_t   PkaGetRegEffectiveSizeInBits(uint32_t  reg) /*!< [in] Register virt. pointer. */
+{
+        // RL Do resistant and add flag to arg.
+        int size = 1, i;
+        uint32_t  addr;
+        uint32_t  currWord = 0, mask = 1Ul << 31;
+
+        /* read register address and full operation size in bits */
+        PKA_GET_REG_ADDRESS(reg, addr);
+        PKA_GET_REG_SIZE(size, LEN_ID_MAX_BITS/*lenID*/);
+
+        /* register size in words */
+        size = CALC_FULL_32BIT_WORDS(size);
+
+        /* read words and find MSWord */
+        for (i = size-1 ; i >= 0  ; i--) {
+                PKA_HW_READ_VALUE_FROM_PKA_MEM(addr + i, currWord);
+                if (currWord != 0)
+                        break;
+        }
+
+        size = CC_BITS_IN_32BIT_WORD*(i+1); //in bits
+
+        if (currWord == 0)
+                return size;
+
+        /* find number of bits in the MS word */
+        for (i = 1; i <= CC_BITS_IN_32BIT_WORD; i++) {
+                if (currWord & mask)
+                        break;
+                size--;
+                mask >>= 1;
+        }
+
+        return size;
+}
+
+
+/***********     PkaGetNextMsBit  function     **********************/
+/**
+ * @brief The function returns MS-bit from register r.
+ *
+ *
+ * @author reuvenl (6/12/2014)
+ *
+ * @return uint32_t - bit's value
+ */
+uint32_t  PkaGetNextMsBit(uint32_t rX,      /*!< [in] Register virt. pointer. */
+              int32_t i,            /*!< [in] Index of the requirred bit. */
+              uint32_t *pW,         /*!< [in] Pointer to 32-bit current word, which must be saved by
+                            caller through reading bits from the register. */
+              uint32_t *pIsNew)     /*!< [in] Pointer to indicator is this a new start (pIsNew=1) of
+                            the function for this register. The value is updated
+                            to 0 by the function after first start. */
+{
+        uint32_t b;
+
+        if (*pIsNew || (i & 31UL) == 31) {
+                PKA_READ_WORD_FROM_REG(*pW, i>>5, rX);
+                /* ones only */
+                if ((i & 31UL) != 31)
+                        *pW <<= (31 - (i & 31UL));
+                *pIsNew = 0;
+        }
+
+        b = *pW >> 31;
+        *pW <<= 1;
+
+        return b;
+}
+
+
+
+/***********     PkaGet2MsBits  function     **********************/
+/**
+ * @brief The function returns 2 MS-bits from register r.
+ *
+ * @author reuvenl (6/12/2014)
+ *
+ * @return uint32_t - bit's value
+ */
+uint32_t PkaGet2MsBits(uint32_t rX,        /*!< [in] Register virt. pointer. */
+            int32_t i,         /*!< [in] Index of the required bit. */
+            uint32_t *pW,      /*!< [in] Pointer to 32-bit current word, which must be saved by
+                            caller through reading bits from the register. */
+            uint32_t *pIsNew)  /*!< [in] Pointer to indicator is it a new start other function
+                            for this register or not. The value is updated
+                            to FALSE by the function after start. */
+{
+        uint32_t b;
+
+        PKA_ASSERT(!(i&1), "PkaGet2MsBits: even bit");
+
+        if (*pIsNew || (i & 0x1F) == 30) {
+                PKA_READ_WORD_FROM_REG(*pW, i>>5, rX);
+                *pIsNew = 0;
+        }
+
+        b = (*pW >> (i&0x1F)) & 0x3;
+
+        return b;
+}
+
+
+/***********     PkaFinishAndMutexUnlock  function     **********************/
+/**
+ * @brief This function clears the PKA memory and clock, and unlocks the Asymmetric mutex.
+ *
+ * @return  None
+ */
+void PkaSetLenIds(uint32_t  sizeInBits,  /*!< [in] The exact size operation for the LenId. */
+          uint32_t  lenId)       /*!< [in] ID of entry of regsSizesTable defines register length
+                                with word extension. */
+{
+
+        PKA_SET_REG_SIZE(sizeInBits, lenId);
+        PKA_SET_REG_SIZE(GET_FULL_OP_SIZE_BITS(sizeInBits), lenId+1);
+
+}
+
+
+/***********     PkaInitAndMutexLock  function     **********************/
+/**
+ * @brief This function Inialize the PKA memory and clock, and locks the Asymmetric mutex.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+
+CCError_t PkaInitAndMutexLock(uint32_t  sizeInBits,   /*!< [in] Operation (modulus) exact size in bits. The value must
+                                   be in interval from defined min. to  max. size in bits. */
+                uint32_t *pkaRegCount)  /*!< [in/out] As input - required registers for operation.
+                                   As output - actual available regs, must be at least as required. */
+{
+        CCError_t err = CC_OK;
+
+        err = CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE);
+        if (err != CC_SUCCESS) {
+                CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* verify that the device is not in fatal error state before activating the PKA engine */
+        CC_IS_FATAL_ERR_ON(err);
+        if (err == CC_TRUE) {
+                err = PKA_FATAL_ERR_STATE_ERROR;
+                goto EndUnlockMutex;
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        err = CC_IS_WAKE;
+        if (err != CC_SUCCESS) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* initialize the PKA engine on default mode with size of registers       */
+        err = PkaInitPka(sizeInBits, 0 /*sizeInWords*/, pkaRegCount);
+
+        if (err != CC_SUCCESS) {
+            /* decrease CC counter at the end of each operation */
+            if (CC_IS_IDLE != CC_SUCCESS) {
+                CC_PalAbort("Fail to decrease PM counter\n");
+            }
+        }
+
+EndUnlockMutex:
+        if (err != CC_SUCCESS) {
+            if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
+                    CC_PalAbort("Fail to release mutex\n");
+            }
+        }
+
+        return err;
+}
+
+
+/***********     PkaFinishAndMutexUnlock  function     **********************/
+/**
+ * @brief This function clears the PKA memory and clock, and unlocks the Asymmetric mutex.
+ *
+ * @return  None
+ */
+void PkaFinishAndMutexUnlock(uint32_t pkaRegCount) /*!< [in] Number of registers to clear. */
+{
+        // clear used registers
+        if (pkaRegCount > 0) {
+                pkaRegCount = CC_MIN(PKA_MAX_COUNT_OF_PHYS_MEM_REGS-2, pkaRegCount);
+                /* clear used PKA registers for security goals */
+                PkaClearBlockOfRegs(PKA_REG_N/*FirstReg*/, pkaRegCount, LEN_ID_MAX_BITS/*LenID*/);
+        }
+
+        /* Finish PKA operations (waiting PKI done and close PKA clocks) */
+        PkaFinishPka();
+
+        /* decrease CC counter at the end of each operation */
+        if (CC_IS_IDLE != CC_SUCCESS) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+        }
+
+        /* release the hardware semaphore */
+        if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != CC_SUCCESS) {
+                CC_PalAbort("Fail to release mutex\n");
+        }
+
+}
+
+
+/***********      PkaSetRegsSizesTab function      **********************/
+/**
+ * @brief This function initializes the PKA registers sizes table.
+ *
+ *      The function sets sizes table as follows:
+ *            -  tab[0] = MaxSizeBits; //maximal size, usually this is exact modulus size in bits
+ *            -  tab[1] = Extended size with extra bits, aligned to big words.
+ *            -  other entrie,
+                uint32_t  Xs = PKA_SIZE_ENTRY_NOT_USED, means - not used.
+ *
+ * @return - None.
+ *
+ */
+void PkaSetRegsSizesTab(uint32_t     opSizeInBits,   /*!< [in] Size of PKA operations (modulus) in bits. The value must be in interval
+ *                                              from defined Min. to Max. size bits */
+                         int32_t      regSizeInPkaWords) /*!< [in] Size of registers in PKA big words (e.g. 128-bit words). */
+{
+
+        uint32_t  i;
+
+        /* Set exact op. size */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), opSizeInBits);
+        /* Set size with extra bits aligned to big words */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0) + CC_32BIT_WORD_SIZE, GET_FULL_OP_SIZE_BITS(opSizeInBits));
+
+        /* remaining entries set to PKA_SIZE_ENTRY_NOT_USED for debugging goals */
+        for (i = 2; i < PKA_NUM_OF_PKA_LEN_IDS_REGS; i++) {
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0) + CC_32BIT_WORD_SIZE*i,
+                                                     regSizeInPkaWords*CC_PKA_WORD_SIZE_IN_BITS);
+        }
+
+        return;
+
+}
+
+/***********      PkaInitPka function      **********************/
+/**
+ * @brief This function initializes the PKA engine.
+ *
+ *    The function performs the following:
+ *      - initializes the PKA_SizesTable, PKA_MappingTable and special register
+ *        N_NP_T0_T1 according to user passed register sizes, registers mapping
+ *        and default N_NP_T0_T1 value.
+ *
+ *    The function calls the PkaSetRegsSizesTab  and PkaSetRegsMapTab
+ *    functions and sets N_NP_T0_T1 value into N_NP_T0_T1 register.
+ *    Notes:
+ *            - See remarks to PkaSetRegsSizesTab and PkaSetRegsMapTab functions.
+ *            - The function allocates one additional word for each register if it is needed for extra bits.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ *
+ */
+CCError_t PkaInitPka(uint32_t   opSizeInBits,        /*!< [in] Operation (modulus) exact size in bits. The value must
+                                be in interval from defined min. to  max. size in bits. */
+                       uint32_t   regSizeInPkaWords,     /*!< [in] PKA register size. not exact for operation (== modulus). */
+                       uint32_t   *pRegsCount)       /*!< [in/out] As input - required registers for operation (including PKA
+                                                               temp registers T0,T1). As output - actual available regs, must be
+                                                               at least as required. */
+{
+        int32_t  regsCount;
+        uint32_t  regSizeIn32BitWords;
+        uint32_t  minRegSizeInPkaWords;
+        uint32_t mask = 0;
+
+        if (opSizeInBits < PKA_MIN_OPERATION_SIZE_BITS ) {
+                return  PKA_REGISTER_SIZES_ERROR;
+        }
+
+        /* calculate pka register size */
+        if (opSizeInBits < (2*(CC_PKA_WORD_SIZE_IN_BITS+PKA_EXTRA_BITS))) {
+                regSizeIn32BitWords = CALC_FULL_32BIT_WORDS(opSizeInBits+CC_PKA_WORD_SIZE_IN_BITS+PKA_EXTRA_BITS-1);
+                if ((opSizeInBits+CC_PKA_WORD_SIZE_IN_BITS+PKA_EXTRA_BITS-1) % CC_BITS_IN_32BIT_WORD) {
+                        regSizeIn32BitWords++;
+                }
+        } else {
+                regSizeIn32BitWords = CALC_FULL_32BIT_WORDS(opSizeInBits);
+        }
+
+        minRegSizeInPkaWords = GET_FULL_OP_SIZE_PKA_WORDS(regSizeIn32BitWords*CC_BITS_IN_32BIT_WORD);
+
+        /* check given regs size or set it, if is not given */
+        if (regSizeInPkaWords > 0) {
+                if (regSizeInPkaWords < minRegSizeInPkaWords)
+                        return PKA_REGISTER_SIZES_ERROR;
+        } else {
+                regSizeInPkaWords = minRegSizeInPkaWords;
+        }
+
+        /* actually avaliable count of PKA registers */
+        regsCount = CC_MIN(CC_SRAM_PKA_SIZE_IN_BYTES / (regSizeInPkaWords*PKA_WORD_SIZE_IN_BYTES),
+                             PKA_MAX_COUNT_OF_PHYS_MEM_REGS);
+
+        if (pRegsCount != NULL) {
+#ifdef PKA_DEBUG
+                // checking number of registers are enough to execute this function
+                if ((size_t)regsCount < *pRegsCount) {
+                        return PKA_REGS_COUNT_ERROR;
+                }
+#endif
+                *pRegsCount = regsCount;
+        }
+
+        /* Mask PKA interrupt */
+        mask = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, PKA_EXP_MASK, mask, 1);
+        CC_HalMaskInterrupt(mask);
+
+        /*     enabling the PKA clocks      */
+        CC_HAL_WRITE_REGISTER( CC_REG_OFFSET(CRY_KERNEL, PKA_CLK_ENABLE), 0x1UL );
+
+        /* setting the PKA registers mapping table */
+        PkaSetRegsMapTab(regsCount, regSizeInPkaWords);
+
+        /* setting the PKA registers sizes table   */
+        PkaSetRegsSizesTab(opSizeInBits, regSizeInPkaWords);
+
+        return CC_OK;
+
+}
+
+
+/***********     PkaCalcNpIntoPkaReg  function      **********************/
+/**
+ * The function uses physical data pointers to calculate and output
+ * the Barrett tag Np.
+ *
+ *  For RSA it uses truncated sizes:
+ *      Np = truncated(2^(3*A+3*X-1) / ceiling(n/(2^(N-2*A-2*X)));
+ *  For ECC - full sizes of not truncated input arguments:
+ *      Np = truncated(2^(N+A+X-1) / n);
+ *
+ *      function assumes modulus in PKA reg 0, and output is to PKA reg 1
+ *
+ * @author reuvenl (5/1/2014)
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t  PkaCalcNpIntoPkaReg(uint32_t lenId,  /*!< [in] ID of entry of regsSizesTable defines register length
+                                with word extension. */
+                                  uint32_t  sizeNbits,  /*!< [in] The exact size of the modulus. */
+                                  int8_t regN,          /*!< [in] Virtual address (number) holding the modulus n. */
+                                  int8_t regNp,     /*!< [out] Virtual address (number) holding Np. */
+                                  int8_t regTemp1,  /*!< [in] Virtual address (number) for temporary usage. */
+                                  int8_t regTempN)  /*!< [in] Virtual address (number) for temporary usage. */
+{
+        CCError_t err = 0;
+        int32_t i;
+        uint32_t  A = CC_PKA_WORD_SIZE_IN_BITS;
+        uint32_t  X = PKA_EXTRA_BITS;
+        int32_t wT,bNom,wNom; /*Sizes in words and bits  */
+        uint32_t val;
+        int32_t sh, st;
+
+        // clear temp registers
+        PKA_2CLEAR(LEN_ID_MAX_BITS, regTemp1);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, regTempN);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, regNp);
+
+        // copy modulus (regN) into temprarty register - regTempN
+        PKA_COPY(LEN_ID_MAX_BITS /* LenID */, regTempN /* OpDest */, regN /* OpSrc */);
+
+        if (sizeNbits <= (2*A + 2*X)) {
+                wNom = CALC_FULL_32BIT_WORDS(sizeNbits+A+X-1);
+                /* Sizes of nominator (N+A+X-1) in 32-bit words */
+                bNom = (sizeNbits+A+X-1) % CC_BITS_IN_32BIT_WORD; /*remain bits*/
+                if (bNom) {
+                        val = 1UL << bNom;
+                } else {
+                        wNom++;
+                        val = 1UL;
+                }
+
+                /* Set rT2 = 2^(N+A+X-1) */
+                PKA_WRITE_WORD_TO_REG(val, wNom-1, regTemp1);
+                // use LEN_ID_MAX_BITS for small sizes, since lenId is exact mod size which is not enought in this case!!!
+                PKA_DIV(LEN_ID_MAX_BITS/*LenID*/, regNp, regTemp1, regTempN);
+        }
+        /* If  (N > 2*A + 2*X) - truncated */
+        else {
+                /* Set rT1 = 2^D, where D=(3*A+3*X-1) division nominator size */
+                wNom = CALC_FULL_32BIT_WORDS(3*A + 3*X - 1); /*words count in nominator */
+                /* Calc. sizes of Nominator */
+                bNom = (3*A + 3*X - 1) % CC_BITS_IN_32BIT_WORD; /*remain bits count*/
+                if (bNom) {
+                        val = 1UL << bNom;
+                } else {
+                        wNom++;
+                        val = 1UL;
+                }
+
+                /* Set rT1 = 2^D, where D=(3*A+3*X-1) */
+                PKA_WRITE_WORD_TO_REG(val, wNom-1, regTemp1);
+
+                /* Set rN = high part of the modulus as divisor */
+                /* count low bits to truncate the modulus */
+                st = sizeNbits - 2*A - 2*X;
+                /* count of words to truncate */
+                wT = st / CC_BITS_IN_32BIT_WORD;
+                /* shift for truncation */
+                sh = st % CC_BITS_IN_32BIT_WORD;
+
+
+                /* prevent further ceiling increment, if it not needed */
+                PKA_SUB_IM(lenId+1/*LenID*/, regTempN, regTempN, 1/*OpBIm*/);
+
+                /* truncate modulus by words and then by bits */
+                for (i=0; i<wT; i++) {
+                        PKA_SHR_FILL0(lenId+1/*LenID*/, regTempN, regTempN, CC_BITS_IN_32BIT_WORD-1);
+                }
+                if (sh) {
+                        PKA_SHR_FILL0(lenId+1/*LenID*/, regTempN, regTempN, sh-1);
+                }
+
+                /* Ceiling */
+                PKA_ADD_IM(lenId+1/*LenID*/, regTempN, regTempN, 1/*OpBIm*/);
+                PKA_DIV(LEN_ID_MAX_BITS/*LenID*/, regNp, regTemp1, regTempN);  //use LEN_ID_MAX_BITS to make sure we catch the whole size
+        }
+
+        // clear temp registers
+        PKA_2CLEAR(LEN_ID_MAX_BITS, regTemp1);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, regTempN);
+
+        return err;
+}
+
+
+/***********      PkaClearBlockOfRegs function      **********************/
+/**
+ * @brief This function clears block of PKA registers + temp registers 30,31.
+ *
+ *        Assumings: - PKA is initialized properly.
+ *                   - Length of extended (by word) registers is placed into LenID entry of
+ *                sizes table.
+ *               - Meets condition: firstReg <= 30.
+ *               - All registers, given to cleaning, are inside the allowed memory.
+ *
+ * @return - None.
+ *
+ */
+void PkaClearBlockOfRegs( uint32_t  firstReg,      /*!< [in] Virtual address (number) of first register in block. */
+                           int32_t   countOfRegs,  /*!< [in] Count of registers to clear. */
+                           uint32_t  lenId)        /*!< [in] ID of entry of regsSizesTable defines register length
+                                with word extension. */
+{
+    int32_t i;
+    uint32_t size,  addr;
+
+    /* check registers count */
+    PKA_ASSERT(!(firstReg >= 32 || firstReg + countOfRegs > 32), "PkaClearBlockOfRegs: firstReg > 32 or firstReg + countOfRegs > 32");
+
+    /* calculate size of register in words */
+    PKA_GET_REG_SIZE(size, lenId);
+    size = CALC_FULL_32BIT_WORDS(size);
+
+    /* clear ordinary and temp registers without PKA operations */
+
+    for (i = 0; i < countOfRegs; i++) {
+            PKA_GET_REG_ADDRESS(firstReg+i/*VirtReg*/,addr/*physAddr*/);
+            PKA_HW_CLEAR_PKA_MEM(addr, size);
+    }
+    PKA_GET_REG_ADDRESS(PKA_REG_T1/*VirtReg*/,addr/*physAddr*/);
+    PKA_HW_CLEAR_PKA_MEM(addr, size);
+    PKA_GET_REG_ADDRESS(PKA_REG_T0/*VirtReg*/,addr/*physAddr*/);
+    PKA_HW_CLEAR_PKA_MEM(addr, size);
+
+    return;
+}
+
+/***********      PkaCopyDataFromPkaReg      **********************/
+/**
+ * @brief This function copies data from PKA register into output buffer .
+ *
+ *        Assumings: - PKA is initialized.
+ *                   - Length of extended (by word) registers is placed into LenID entry of
+ *                     sizes table.
+ *                   - If the extra word of register must be cleared also the user must
+ *                     set LenID according to extended register size
+ *
+ * @return - None.
+ *
+ */
+void PkaCopyPkaRegIntoBeByteBuff(uint8_t *dst_ptr,   /*!< [out] Virtual address (number) of source PKA register. */
+                            uint32_t  sizeWords, /*!< [in] Buffer size in words. */
+                            uint32_t  srcReg)    /*!< [in] Source register. */
+{
+        uint32_t  currAddr;
+        uint32_t  tempWord;
+        int32_t  ii;
+
+        /* copy data from src buffer into PKA register with 0-padding  *
+        *  in the last PKA-word                       */
+        PKA_GET_REG_ADDRESS(srcReg, currAddr);
+
+        PKA_MUTEX_LOCK;
+        PKA_WAIT_ON_PKA_DONE();
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RADDR), currAddr);
+        for(ii = sizeWords-1; ii >= 0; ii--) {
+                WAIT_SRAM_DATA_READY;
+                tempWord = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RDATA));
+                tempWord = CC_COMMON_REVERSE32(tempWord);
+                CC_PalMemCopy(&dst_ptr[ii*CC_32BIT_WORD_SIZE], (uint8_t *)&tempWord, CC_32BIT_WORD_SIZE);
+        }
+        WAIT_SRAM_DATA_READY;
+        PKA_MUTEX_UNLOCK;
+        return;
+
+}
+
+
+/***********      PkaCopyDataFromPkaReg      **********************/
+/**
+ * @brief This function copies data from PKA register into output buffer .
+ *
+ *        Assumings: - PKA is initialized.
+ *                   - Length of extended (by word) registers is placed into LenID entry of
+ *                     sizes table.
+ *                   - If the extra word of register must be cleared also the user must
+ *                     set LenID according to extended register size
+ *
+ * @return - None.
+ *
+ */
+void PkaCopyDataFromPkaReg(uint32_t *dst_ptr,    /*!< [out] Pointer to destination buffer. */
+                            uint32_t  sizeWords, /*!< [in]  Source size in words. */
+                            uint32_t  srcReg)    /*!< [in]  Virtual address (number) of source PKA register. */
+{
+        uint32_t  currAddr;
+
+        PKA_GET_REG_ADDRESS(srcReg, currAddr/*PhysAddr*/);
+        PKA_HW_READ_BLOCK_FROM_PKA_MEM(currAddr, dst_ptr, sizeWords );
+
+        return;
+
+}
+
+
+void PkaCopyByteBuffIntoPkaReg(uint32_t dstReg,     /*!< [out] Virtual address (number) of destination register. */
+                            uint32_t lenId,         /*!< [in] ID of entry of regsSizesTable defines registers length with word extension. */
+                            const uint8_t *src_ptr, /*!< [in] Pointer to source buffer big endian. */
+                            uint32_t size)          /*!< [in] Data size in bytes. */
+{
+        uint32_t  currAddr;
+        uint32_t  regSize;
+        uint32_t  sizeWords;
+        uint32_t  tempWord;
+        uint32_t  remainBytes = size % CC_32BIT_WORD_SIZE;
+        uint32_t ii;
+
+        /* copy data from src buffer into PKA register with 0-padding  *
+        *  in the last PKA-word                       */
+        PKA_GET_REG_ADDRESS(dstReg, currAddr);
+    size -= remainBytes;
+
+        PKA_MUTEX_LOCK;
+        PKA_WAIT_ON_PKA_DONE();
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), currAddr);
+        for(ii = 0; ii< size; ii+=CC_32BIT_WORD_SIZE) {
+                CC_PalMemCopy((uint8_t *)&tempWord, &src_ptr[ii], CC_32BIT_WORD_SIZE);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), tempWord);
+                WAIT_SRAM_DATA_READY;
+        }
+    if (remainBytes > 0) {
+        tempWord = 0;
+                CC_PalMemCopy((uint8_t *)&tempWord, &src_ptr[ii], remainBytes);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), tempWord);
+                WAIT_SRAM_DATA_READY;
+    }
+        PKA_MUTEX_UNLOCK;
+        /* data size aligned to full PKA-word */
+        sizeWords =  ((CALC_32BIT_WORDS_FROM_BYTES(size+remainBytes)+PKA_WORD_SIZE_IN_32BIT_WORDS-1)/PKA_WORD_SIZE_IN_32BIT_WORDS) * \
+                     PKA_WORD_SIZE_IN_32BIT_WORDS;
+        currAddr = currAddr + sizeWords;
+
+        /* register size in bits */
+        PKA_GET_REG_SIZE(regSize, lenId);
+        regSize = CALC_FULL_32BIT_WORDS(regSize);
+
+        /* zeroe not significant high words of the register */
+        if (regSize > sizeWords) {
+                PKA_HW_CLEAR_PKA_MEM(currAddr, regSize - sizeWords);
+        }
+
+        return;
+}
+
+/***********      PkaCopyDataIntoPkaReg function      **********************/
+/**
+* @brief This function  copies source data BE byte buffer into PKA register LE word buffer.
+*
+*        Assumings: - PKA is initialized.
+*                   - Length of extended (by word) registers is placed into LenID entry of
+*                     sizes table.
+*                   - If the extra word of register must be cleared also the user must
+*                     set LenID according to extended register size
+*
+* @return - None.
+*
+*/
+void PkaCopyBeByteBuffIntoPkaReg(uint32_t dstReg,      /*!< [out] Virtual address (number) of destination register. */
+                            uint32_t lenId,            /*!< [in] ID of entry of regsSizesTable defines registers length with word extension. */
+                            const  uint8_t *src_ptr,   /*!< [in] Pointer to source buffer big endian. */
+                            uint32_t sizeWords)        /*!< [in] Data size in word. */
+{
+        uint32_t  currAddr;
+        uint32_t  regSize;
+        uint32_t  tempWord;
+        uint32_t  size = sizeWords*CC_32BIT_WORD_SIZE;
+        int32_t ii;
+
+        /* copy data from src buffer into PKA register with 0-padding  *
+        *  in the last PKA-word                       */
+        PKA_GET_REG_ADDRESS(dstReg, currAddr);
+
+        PKA_MUTEX_LOCK;
+        PKA_WAIT_ON_PKA_DONE();
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), currAddr);
+        for(ii = size-CC_32BIT_WORD_SIZE; ii >= 0; ii-=CC_32BIT_WORD_SIZE) {
+                CC_PalMemCopy((uint8_t *)&tempWord, &src_ptr[ii], CC_32BIT_WORD_SIZE);
+                tempWord = CC_COMMON_REVERSE32(tempWord);
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), tempWord);
+                WAIT_SRAM_DATA_READY;
+        }
+        PKA_MUTEX_UNLOCK;
+        /* data size aligned to full PKA-word */
+        sizeWords =  ((sizeWords+PKA_WORD_SIZE_IN_32BIT_WORDS-1)/PKA_WORD_SIZE_IN_32BIT_WORDS) * \
+                     PKA_WORD_SIZE_IN_32BIT_WORDS;
+        currAddr = currAddr + sizeWords;
+
+        /* register size in bits */
+        PKA_GET_REG_SIZE(regSize, lenId);
+        regSize = CALC_FULL_32BIT_WORDS(regSize);
+
+        /* zeroe not significant high words of the register */
+        if (regSize > sizeWords) {
+                PKA_HW_CLEAR_PKA_MEM(currAddr, regSize - sizeWords);
+        }
+
+#if defined PKA_DEBUG && defined DEBUG
+        /*! PKA_DEBUG */
+        PkaCopyDataFromPkaReg(tempRes, regSize, dstReg);
+#endif
+        return;
+}
+
+
+/***********      PkaCopyDataIntoPkaReg function      **********************/
+/**
+* @brief This function  copies source data into PKA register .
+*
+*        Assumings: - PKA is initialized.
+*                   - Length of extended (by word) registers is placed into LenID entry of
+*                     sizes table.
+*                   - If the extra word of register must be cleared also the user must
+*                     set LenID according to extended register size
+*
+ * @return - None.
+*
+*/
+void PkaCopyDataIntoPkaReg(uint32_t    dstReg,      /*!< [out] Virtual address (number) of destination register. */
+                            uint32_t    lenId,          /*!< [in] ID of entry of regsSizesTable defines registers length with word extension. */
+                            const  uint32_t  *src_ptr,  /*!< [in] Pointer to source buffer. */
+                            uint32_t    sizeWords ) /*!< [in] Data size in words. */
+{
+        uint32_t  currAddr;
+        uint32_t  regSize;
+
+        /* copy data from src buffer into PKA register with 0-padding  *
+        *  in the last PKA-word                       */
+        PKA_GET_REG_ADDRESS(dstReg, currAddr);
+        PKA_HW_LOAD_BLOCK_TO_PKA_MEM(currAddr, src_ptr, sizeWords);
+
+        /* data size aligned to full PKA-word */
+        sizeWords =  ((sizeWords+PKA_WORD_SIZE_IN_32BIT_WORDS-1)/PKA_WORD_SIZE_IN_32BIT_WORDS) * \
+                     PKA_WORD_SIZE_IN_32BIT_WORDS;
+        currAddr = currAddr + sizeWords;
+
+        /* register size in words */
+        PKA_GET_REG_SIZE(regSize, lenId);
+        regSize = CALC_FULL_32BIT_WORDS(regSize);
+
+        /* zeroe not significant high words of the register */
+        if (regSize > sizeWords) {
+                PKA_HW_CLEAR_PKA_MEM(currAddr, regSize - sizeWords);
+        }
+
+#if defined PKA_DEBUG && defined DEBUG
+        /*! PKA_DEBUG */
+        PkaCopyDataFromPkaReg(tempRes, regSize, dstReg);
+#endif
+        return;
+}
+
+
+/***********      PkaFinishPka function      **********************/
+/**
+* @brief This function  disables PKA clock .
+*
+ * @return - None.
+*
+*/
+void PkaFinishPka(void)
+{
+        /*     disable the PKA clocks      */
+        CC_HAL_WRITE_REGISTER( CC_REG_OFFSET(CRY_KERNEL,PKA_CLK_ENABLE) , 0x0UL );
+        return;
+}
+
+
+/***********      PkaClearPkaRegWords function      **********************/
+/**
+* @brief This function  clears words in a PKA register .
+*
+* @return - None.
+*
+*/
+void PkaClearPkaRegWords(uint32_t    pkaReg,        /*!< [in/out] Virtual address (number) of the register. */
+                          uint32_t   addrWordOffset )   /*!< [in] Word offset to start clearing. */
+{
+        uint32_t  currAddr;
+        uint32_t  regSize;
+
+        /* copy data from src buffer into PKA register with 0-padding  *
+        *  in the last PKA-word                       */
+        PKA_GET_REG_ADDRESS(pkaReg, currAddr);
+        currAddr = currAddr + addrWordOffset;
+
+        /* register size in words */
+        PKA_GET_REG_SIZE(regSize, LEN_ID_MAX_BITS);
+        regSize = CALC_FULL_32BIT_WORDS(regSize);
+
+        /* zeroe not significant high words of the register */
+        if (regSize > addrWordOffset) {
+                PKA_HW_CLEAR_PKA_MEM(currAddr, regSize - addrWordOffset);
+        }
+
+        return;
+}
+
+
+/***********     PkaIsRegModEqual  function      **********************/
+/**
+ * The function returns result (x == y mod n).
+ * Assumed: n - in reg. 0, lenId = 1.
+ *
+ * @author reuvenl (6/20/2014)
+ *
+ * @return True if equal, otherwise false
+ */
+bool PkaIsRegModEqual(uint32_t reg1,     /*!< [in] Virtual address (number) of the register1. */
+                uint32_t reg2,     /*!< [in] Virtual address (number) of the register2. */
+                uint32_t regTmp1,  /*!< [in] Virtual address (number) of the tmp register1. */
+                uint32_t regTmp2)  /*!< [in] Virtual address (number) of the tmp register2. */
+{
+        uint32_t status;
+
+        PKA_REDUCE(LEN_ID_N_BITS, reg1, regTmp1);
+        PKA_REDUCE(LEN_ID_N_BITS, reg2, regTmp2);
+        PKA_COMPARE_STATUS(LEN_ID_N_PKA_REG_BITS, regTmp1, regTmp2, status);
+        return(bool)(status==1);
+}
+
+
+/***********      PkaGetBitFromPkaReg function     **********************/
+/**
+ * @brief This function returns bit i from PKA register.
+ *
+ * @return - returns the bit number i (counting from left).
+ *
+ */
+uint8_t  PkaGetBitFromPkaReg(uint32_t   rX,    /*!< [in] Virtual pointer to PKA register. */
+                             uint32_t LenID,   /*!< [in] ID of entry of regsSizesTable containing rX register length
+                            with word extension. */
+                             int32_t  i,       /*!< [in] Number of bit to be tested. */
+                             uint32_t   rT)    /*!< [in] Temp register. If it is not necessary to keep rX, then
+                            set rT=rX for saving memory space. */
+{
+        uint32_t j;
+        uint32_t numWords, numBits; /* number shifts by word and by bit */
+        uint32_t bitVal;
+
+        /* copy extended rX=>rT */
+        if (rX != rT)
+                PKA_COPY(LEN_ID_MAX_BITS, rT/*dst*/, rX/*src*/);
+
+        /* number shifts */
+        numWords = i / CC_BITS_IN_32BIT_WORD;
+        numBits =  i % CC_BITS_IN_32BIT_WORD;
+
+        /* shift by words */
+        for (j = 0; j < numWords; j++) {
+                PKA_SHR_FILL0(LenID+1, rT/*Result*/, rT/*N*/, CC_BITS_IN_32BIT_WORD-1/*S*/);
+        }
+
+        /* shift by bits */
+        if (numBits >= 1)
+                PKA_SHR_FILL0(LenID+1, rT/*Result*/, rT/*N*/, numBits-1/*S*/);
+
+        /* test LS Bit */
+        PKA_READ_BIT0( LenID+1, rT/**/, bitVal);
+        return(bitVal);
+
+
+}
+
+
+/***********      PkaExecFullModInv function     **********************/
+/**
+ * @brief This function calculates modular inversion Res = 1/B mod N for both odd and even modulus.
+ *
+ *        The function works with virtual pointers to PKA registers (sequence numbers)
+ *        and does the following:
+ *
+ *        1. Checks the parity of modulus N (in register 0) and operand B. If they both are even,
+ *           returns an error (inverse is not exist)
+ *        2. If the modulus is odd, then calls the LLF_PKI_PKA_ModInv function for calculating
+ *           the inverse.
+ *        3. If the modulus is even, then the function performs the following:
+ *           3.1  Saves modulus N: rT0<=N;
+ *           3.2. Sets B into reg N: N<=B.
+ *           3.3. Res = N^-1 mod B (call LLF_PKI_PKA_ModInv ); Restore mod: N<=rT0;
+ *           3.4. rT0 = high(N*N^-1) = LLF_PKI_PKA_HMul(N,Res,rT0);
+ *           3.5. Shift right rT0 >> 32;
+ *           3.6. rT1 = low(N*N^-1) = LLF_PKI_PKA_LMul(N,Res,rT1);
+ *           3.7. Res = rT0 / B : call LLF_PKI_PKA_LongDiv(rT0,B,Res);
+ *           3.7. rT0 = rT1 / B : call LLF_PKI_PKA_Div(rT1,B,rT0);
+ *           3.8. Res = Res + rT0 : ModAdd(Res,rT0,Res);
+ *           3.9. If reminder of division > 0, then Res= Res+1;
+ *           3.10. Res = N-Res;
+ *        4. Exit.
+ *
+ *     NOTE:
+ *       -  The operand B shal be rewritten by GCD(N,B).
+ *       -  The function needs 6 PKA regs: N(0), OpB, Res, rT0, rT1, rT2.
+ *       -  PKA sizes table entrys must be set:  0 - exact modSizeBits, 1 - modSizeBits+32 bits,
+ *       -  Before executing modular operations, the modulus must be set into r0 register of PKA.
+ *       -  The function not checks the input parameters, because they must be checked previously.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t PkaExecFullModInv(int8_t         OpB,  /*!< [in] Operand B: virtual register pointer. Valid values: 0 <= OpA <= 31. */
+                              int8_t         Res,  /*!< [out] Virtual register pointer for result data. Valid values: 0 <= Res <= 31. */
+                              int8_t         rT0,  /*!< [in] The virtual pointers to temp register. */
+                              int8_t         rT1,  /*!< [in] The virtual pointers to temp register. */
+                              int8_t         rT2,  /*!< [in] The virtual pointers to temp register. */
+                              int8_t         rT3)  /*!< [in] The virtual pointers to temp register. */
+{
+        CCError_t error = CC_OK;
+        uint32_t ModSizeBits, ModSizeWords;
+        uint32_t status;
+        uint32_t bitVal;
+        /* virtual pointer to modulus register, by default: N=0 */
+        uint8_t  N = PKA_REG_N;
+
+        /* get modulus size */
+        PKA_GET_REG_SIZE(ModSizeBits, LEN_ID_N_BITS);
+        ModSizeWords = CALC_FULL_32BIT_WORDS(ModSizeBits);
+
+        /* Step 1.  Check the parity of the modulus  */
+        /* test: is the modulus even? */
+        PKA_READ_BIT0(LEN_ID_N_PKA_REG_BITS, PKA_REG_N/*N*/, bitVal);
+        if (bitVal == 1 /*odd N*/) {
+                /* Step 2.  Process case of odd modulus      */
+                PKA_MOD_INV(LEN_ID_N_BITS, Res, OpB);
+        } else { /*even N*/
+                /* Step 3. Process case of even modulus      */
+        /* in case of even B: calculate GCD and return error message, */
+                /*  that inverse does not exists                              */
+                /* check, is the operand B odd or even */
+                PKA_READ_BIT0(LEN_ID_N_PKA_REG_BITS, OpB, bitVal);
+                if (bitVal == 0) {
+                        return PKA_INVERSION_NOT_EXISTS_ERROR;
+                }
+
+                /* in case of odd B: calculate modular inverse and GCD        */
+                /* 3.1. Save previous modulus also into rT0 and into rT1 (rT1 - working copy)*/
+                PKA_COPY(LEN_ID_MAX_BITS/*LenID*/, rT0/*OpDest*/, N/*OpSrc*/);
+                PKA_COPY(LEN_ID_MAX_BITS/*LenID*/, rT1/*OpDest*/, N/*OpSrc*/);
+
+                /* 3.2. Set OpB into modulus register 0 ) */
+                PKA_COPY(LEN_ID_MAX_BITS/*LenID*/, N/*OpDest*/, OpB/*OpSrc*/);
+
+                /* 3.3 Calculate Res =  1/N mod B  */
+                PKA_MOD_INV(LEN_ID_N_BITS/*LenID*/, Res, rT1/*mod N*/);
+
+
+                /* restore modulus */
+                PKA_COPY(LEN_ID_MAX_BITS/*LenID*/, N/*OpDest*/, rT0/*OpSrc*/);
+
+                /* 3.4. Calculate rT0 = PKA_MUL_HIGH(N*Res) i.e. HighHalf + 1 word of(N*Res)
+                        Note: LenId=0, because this operation adds extra word itself */
+                PKA_MUL_HIGH(LEN_ID_N_BITS, rT0/*Result*/, N, Res);
+
+
+                /* 3.5. Shift right rT0 for deleting 1 low word - no need in new HW */
+
+                /* 3.6. Calculate rT2 = PKA_MUL_LOW(N*Res) i.e. LowHalf of(N*Res) */
+                PKA_MUL_LOW(LEN_ID_N_BITS, rT2/*Result*/, N, Res);
+
+                /* 3.6. Divide long num Res = (rT1 * 2**(ModSizeBits - 32))/B */
+                error = PkaDivLongNum(LEN_ID_N_BITS,              /*LenID of exact size*/
+                                       rT0,                /*numerator*/
+                                       CC_BITS_IN_32BIT_WORD*ModSizeWords+CC_BITS_IN_32BIT_WORD,     /*Shift*/
+                                       OpB,                /*divider*/
+                                       Res,                /*result*/
+                                       rT1,
+                                       rT3);
+
+                if (error != CC_OK) {
+                        return error;
+                }
+
+                /* 3.7. Subtract 1 from low part and divide it by B */
+                PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, rT2/*Result*/, rT2/*numerat*/, 1/*OpB*/);
+                PKA_DIV(LEN_ID_N_PKA_REG_BITS, rT0/*Result*/, rT2/*numerat*/, OpB/*divider*/);
+
+                /* 3.8. Calculate: Res = Res+rT0, Res=Res+1, Res = N - Res; */
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, Res, Res, rT0);
+
+                /* 3.9. If remainder rT2 is not 0, then add 1 to rT0 result */
+                PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT2/*OpA*/, 0/*OpB*/, status);
+                if (status != 1) {
+                        PKA_ADD_IM(LEN_ID_N_PKA_REG_BITS, Res, Res, 1 );
+                }
+                /* 3.10. Res = N - Res; */
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, Res, N, Res);
+        }
+
+        return error;
+}
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka.h
new file mode 100644
index 0000000..ee338be
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef PKA_H
+#define PKA_H
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+#include "pka_hw_defs.h"
+#include "cc_pka_defs_hw.h"
+#include "pki_dbg.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* values for defining, that PKA entry is not in use */
+#define PKA_SIZE_ENTRY_NOT_USED  0xFFFFFFFF
+#define PKA_ADDRESS_ENTRY_NOT_USED  0xFFC
+
+/* define result discard value */
+#define RES_DISCARD  0x3F
+
+
+#define SWAP_INT8(x,y)  { \
+   uint32_t  temp; \
+   temp = (x); x = (y); y = temp; \
+}
+
+
+
+/* if you want to execute operation using function defined in pki_dbg.c,
+ then change the define of PKA_EXEC_OP_DEBUG to 1, else define it as empty.
+ Make sure the library is compiled with flag DEBUG=1, so pki_dbg.c exists in library */
+#define PKA_EXEC_OP_DEBUG 0
+#if (PKA_EXEC_OP_DEBUG  && defined PKA_DEBUG && defined DEBUG)
+    #define PKA_EXEC_OPERATION PkiDbgExecOperation
+#else   // not debug mode
+    #define PKA_EXEC_OPERATION(Opcode,lenId,isAImmed,OpA,isBImmed,OpB,ResDiscard,Res,Tag) { \
+        uint32_t fullOpCode; \
+        fullOpCode = PKA_SET_FULL_OPCODE((Opcode),(lenId),(isAImmed),(OpA),(isBImmed),(OpB),(ResDiscard),(Res),(Tag)); \
+        PKA_WAIT_ON_PKA_PIPE_READY(); \
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, OPCODE), fullOpCode); \
+    }
+#endif
+
+/*************************************************************************/
+/* Macros for calling PKA operations (names according to operation issue */
+/*************************************************************************/
+
+/*----------------------------------*/
+/*   1.  ADD - SUBTRACT operations  */
+/*----------------------------------*/
+/*  Add:   Res =  OpA + OpB  */
+#define   PKA_ADD(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_ADD,(lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  AddIm:  Res =  OpA + OpBIm  */
+#define   PKA_ADD_IM(lenId, Res, OpA, OpBIm)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_ADD,(lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
+/*  Sub:  Res =  OpA - OpB  */
+#define   PKA_SUB(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_SUB,(lenId),0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  SubIm:  Res =  OpA - OpBIm  */
+#define   PKA_SUB_IM(lenId, Res, OpA, OpBIm)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_SUB,(lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
+/*  Neg:  Res =  0 - OpB  */
+#define   PKA_NEG(lenId, Res, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_SUB, (lenId), 1, 0, 0, (OpB), 0, (Res), 0 )
+/*  ModAdd:  Res =  (OpA + OpB) mod N  */
+#define   PKA_MOD_ADD(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODADD, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  ModAddIm:  Res =  (OpA + OpBIm) mod N  */
+#define   PKA_MOD_ADD_IM(lenId, Res, OpA, OpBIm)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODADD, (lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
+/*  ModSub:  Res =  (OpA - OpB) mod N  */
+#define   PKA_MOD_SUB(lenId, Res, OpA, OpB)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODSUB, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  ModSubIm:  Res =  (OpA - OpBIm) mod N  */
+#define   PKA_MOD_SUB_IM(lenId, Res, OpA, OpBIm)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODSUB, (lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
+/*  ModNeg:  Res =  (0 - OpB) mod N  */
+#define   PKA_MOD_NEG(lenId, Res, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODSUB, (lenId), 1, 0, 0, (OpB), 0, (Res), 0 )
+
+
+/*----------------------------------*/
+/*   2.  Logical   operations       */
+/*----------------------------------*/
+
+/*  AND:  Res =  OpA & OpB  */
+#define   PKA_AND(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 0, (OpB), 0, (Res) , 0 )
+/*  AndIm:  Res =  OpA & OpB  */
+#define   PKA_AND_IM(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, (OpB), 0, (Res) , 0 )
+/*  Tst0:  OpA & 0x1 -  tests the bit 0 of operand A. If bit0 = 0, then ZeroOfStatus = 1, else 0  */
+#define   PKA_TEST_BIT0(lenId, OpA)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x01, 1, RES_DISCARD , 0 )
+/*  TstBit:  OpA & (1<<i) -  tests the bit i of operand A. If biti = 0, then ZeroOfStatus = 1, else 0  */
+#define   PKA_TEST_BIT(lenId, OpA, i)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x01<<(i), 1, RES_DISCARD , 0 )
+/*  Clr0:  Res =  OpA & (-2)  - clears the bit 0 of operand A.  Note:  -2 = 0x1E  for 5-bit size */
+#define   PKA_CLEAR_BIT0(lenId, Res, OpA)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x1E, 0, (Res), 0 )
+/*  Clr:  Res =  OpA & 0  - clears the operand A.  */
+#define   PKA_CLEAR(lenId, OpA)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x00, 0, (OpA), 0 )
+/*  Clear:  for full clearing the actual register opA, this macro calls Clr operation twice.  */
+#define   PKA_2CLEAR(lenId, OpA)   \
+            PKA_CLEAR(lenId, OpA);  \
+            PKA_CLEAR(lenId, OpA)
+/*  OR:  Res =  OpA || OpB  */
+#define   PKA_OR(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  OrIm:  Res =  OpA || OpB  */
+#define   PKA_OR_IM(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpA), 1, (OpB), 0, (Res), 0 )
+/*  Copy:  OpDest =  OpSrc || 0  */
+#define   PKA_COPY(lenId, OpDest, OpSrc)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpSrc), 1, 0x00, 0, (OpDest), 0 )
+/*  Set0:  Res =  OpA || 1  : set bit0 = 1, other bits are not changed */
+#define   PKA_SET_BIT0(lenId, Res, OpA)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpA), 1, 0x01, 0, (Res), 0 )
+/*  Xor:  Res =  OpA ^ OpB  */
+#define   PKA_XOR(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  XorIm:  Res =  OpA ^ OpB  */
+#define   PKA_XOR_IM(lenId, Res, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, (OpB), 0, (Res), 0 )
+/*  Flip0:  OpA =  OpA || 1  - inverts the bit 0 of operand A  */
+#define   PKA_FLIP_BIT0(lenId, Res, OpA)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, 0x01, 0, (Res), 0 )
+/*  Invert:  Res =  OpA ^ 0xFFF.FF  :  inverts all bits of OpA .
+                    Note: 0xFFFFF =  0x1F for 5 bits size of second operand */
+#define   PKA_INVERT_BITS(lenId, Res, OpA)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, 0x1F, 0, (Res), 0 )
+/*  Compare:  OpA ^ OpB . Rsult of compare in ZeroBitOfStatus:  If OpA == OpB then Z = 1 */
+#define   PKA_COMPARE(lenId, OpA, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 0, (OpB), 1, (0), 0 )
+/*  CompareImmediate:  OpA ^ OpB . Rsult of compare in ZeroBitOfStatus:  If OpA == OpB then status Z = 1 */
+#define   PKA_COMPARE_IM(lenId, OpA, OpBim)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, (OpBim), 1, (0), 0 )
+
+
+/*----------------------------------*/
+/*   3.  SHIFT    operations  - S <= 31      */
+/*----------------------------------*/
+
+/*  SHR0:  Res =  OpA >> (S+1) :   shifts right operand A by S+1 bits, insert 0 to left most bits */
+#define   PKA_SHR_FILL0(lenId, Res, OpA, S)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHR0, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
+/*  SHR1:  Res =  OpA >> (S+1) :   shifts right operand A by S+1 bits, insert 1 to left most bits */
+#define   PKA_SHR_FILL1(lenId, OpA, S, Res)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHR1, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
+/*  SHL0:  Res =  OpA << (S+1) :   shifts left operand A by S+1 bits, insert 0 to right most bits */
+#define   PKA_SHL_FILL0(lenId, Res, OpA, S)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHL0, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
+/*  SHL1:  Res =  OpA << (S+1) :   shifts left operand A by S+1 bits, insert 1 to right most bits */
+#define   PKA_SHL_FILL1(lenId, OpA, S, Res)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHL1, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
+
+
+/*-----------------------------------------------------*/
+/*   2.  Multiplication and other   operations         */
+/*       Note:  See notes to PKA_ExecOperation */
+/*-----------------------------------------------------*/
+
+/*  RMul:  Res =  LowHalfOf(OpA * OpB), where size of operands and result is equaled to operation
+           size, defined by lenId. Note: for receiving full result, the lenId must be set according
+           to (sizeA + sizeB) and leading not significant bits of operands must be zeroed */
+#define   PKA_MUL_LOW(lenId, Res, OpA, OpB)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MULLOW, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  HMul:  Res =  HighHalfOf(OpA * OpB) + one high word of low half of (OpA * OpB), where size of
+           operands is equaled to operation size, defined by lenId. Note: Size of operation result
+           is by one word large, than operation size */
+#define   PKA_MUL_HIGH(lenId, Res, OpA, OpB)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MULHIGH, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  ModMul:  Res =  OpA * OpB  mod N - modular multiplication */
+#define   PKA_MOD_MUL(lenId, Res, OpA, OpB)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMUL, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  ModMulN:  Res =  OpA * OpB  mod N - modular multiplication (final reduction is omitted)*
+*   up to PKA_EXTRA_BITS extra bits                               */
+#define   PKA_MOD_MUL_NFR(lenId, Res, OpA, OpB)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMULN, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  ModMulAcc:  Res =  OpA * OpB + OpC mod N - modular multiplication and     *
+*   adding, result reduced                                */
+#define   PKA_MOD_MUL_ACC(lenId, Res, OpA, OpB, OpC)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMLAC, (lenId), 0, (OpA), 0, (OpB), 0, (Res), (OpC) )
+/*  ModMulAccN:  Res =  OpA * OpB + OpC mod N - modular multiplication and    *
+*   acdding (final reduction is omitted) -  up to PKA_EXTRA_BITS extra bits                       */
+#define   PKA_MOD_MUL_ACC_NFR(lenId, Res, OpA, OpB, OpC)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMLACNR, (lenId), 0, (OpA), 0, (OpB), 0, (Res), (OpC) )
+/*  ModExp:  Res =  OpA ** OpB  mod N - modular exponentiation */
+#define   PKA_MOD_EXP(lenId, Res, OpA, OpB)   \
+             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODEXP, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  Divide:  Res =  OpA / OpB , OpA = OpA mod OpB - division,  */
+#define   PKA_DIV(lenId, Res, OpA, OpB) \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_DIVISION, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
+/*  ModInv:  Modular inversion: calculates   Res = 1/OpB mod N  */
+#define   PKA_MOD_INV(lenId, Res, OpB)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODINV, (lenId), 1,1, 0,(OpB), 0,(Res), 0 )
+/* Modular reduction: Res = OpB mod B  by subtract the modulus B     *
+*   times, while Res > B. Counter C should be set in the Tag bits of Status   */
+#define   PKA_REDUCE(lenId, Res, OpA)   \
+            PKA_EXEC_OPERATION( PKA_OPCODE_ID_REDUCTION, (lenId), 0, (OpA), 0, 0/*opB not need*/, 0, (Res), 0/*Tag*/ )
+
+
+/*************************************************
+  **************  second Level macros ************
+**************************************************/
+
+ /* mod inversion using exponentiation, used when 'a' can be even number, but *
+ *  runs at constant time                                                     */
+#define PKA_MOD_INV_W_EXP(res,a,nm2)    {\
+    PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS,(nm2), 0/*n*/, 2); \
+    PKA_MOD_EXP(LEN_ID_N_BITS,(res),(a),(nm2)); \
+}
+
+#define PKA_SET_VAL(a,v) {\
+    PKA_AND_IM(LEN_ID_N_PKA_REG_BITS,a,a,0); \
+    PKA_OR_IM( LEN_ID_N_PKA_REG_BITS,a,a,v); \
+}
+
+#define PKA_COMPARE_STATUS(lenId, a, b, stat) {\
+    PKA_COMPARE(lenId,a,b); \
+    PKA_GET_STATUS_ALU_OUT_ZERO(stat);\
+}
+
+#define PKA_COMPARE_IM_STATUS(lenId, a, b,stat)  {\
+    PKA_COMPARE_IM(lenId,a,b); \
+    PKA_GET_STATUS_ALU_OUT_ZERO(stat);\
+}
+
+#define PKA_READ_BIT0(lenId,reg,bitVal) {\
+    PKA_TEST_BIT0(lenId,reg); \
+    PKA_GET_STATUS_ALU_OUT_ZERO(bitVal); \
+    (bitVal) = !(bitVal); \
+}
+
+/*uint32 b - bit i value, i-num. of LS bit, i <= 31*/
+#define PKA_READ_BIT(bitVal,reg,i) {\
+    PKA_TEST_BIT(1/*lenId*/,reg,(i),0); \
+    PKA_GET_STATUS_ALU_OUT_ZERO((bitVal)); \
+    (bitVal) = !(bitVal); \
+}
+
+#define PKA_READ_WORD_FROM_REG(val,i,virtReg) {\
+    uint32_t addr; \
+    PKA_GET_REG_ADDRESS(virtReg, addr);\
+    PKA_HW_READ_VALUE_FROM_PKA_MEM(addr+(i), val); \
+}
+
+#define PKA_WRITE_WORD_TO_REG(Val,i,VirtReg) {\
+    uint32_t addr;\
+    PKA_GET_REG_ADDRESS((VirtReg),addr);\
+    PKA_HW_LOAD_VALUE_TO_PKA_MEM(addr+(i),(Val));\
+}
+
+CCError_t PkaExecFullModInv(int8_t         OpB,
+                              int8_t         Res,
+                              int8_t         rT0,
+                              int8_t         rT1,
+                              int8_t         rT2,
+                              int8_t         rT3 );
+
+uint8_t  PkaGetBitFromPkaReg(uint32_t   rX,
+                 uint32_t   lenId,
+                 int32_t    i,
+                 uint32_t   rT);
+
+
+void  PkaModDivideBy2(uint32_t    lenId,
+              uint32_t    rX,
+              uint32_t    rN,
+              uint32_t    rRes);
+
+
+CCError_t PkaInitAndMutexLock(uint32_t  sizeInBits,
+                uint32_t *pkaRegCount);
+
+void PkaFinishAndMutexUnlock(uint32_t pkaRegCount);
+
+void PkaSetLenIds(uint32_t  sizeInBits,
+        uint32_t lenId);
+
+void PkaSetRegsSizesTab(uint32_t    opSizeInBits,
+             int32_t     regSizeInPkaWords);
+
+
+CCError_t PkaInitPka(uint32_t   opSizeInBits,
+            uint32_t   regSizeInPkaWords,
+            uint32_t   *pRegsCount);
+
+#define PKA_INIT_PKA_DEFAULT(opSizeInBits) \
+        PkaInitPka((opSizeInBits), 0 /*sizeInWords*/, NULL/*(pRegsCount)*/)
+
+
+void PkaFinishPka(void);
+
+
+CCError_t  PkaCalcNpIntoPkaReg(uint32_t lenId,
+                uint32_t  sizeNbits,
+                int8_t regN,
+                int8_t regNp,
+                int8_t regTemp1,
+                int8_t regTempN);
+
+void PkaClearBlockOfRegs(uint32_t  firstReg,
+                         int32_t   countOfRegs,
+                         uint32_t  lenId);
+
+void PkaClearPkaRegWords(uint32_t    dstReg,
+              uint32_t    sizeWords);
+
+void PkaCopyByteBuffIntoPkaReg(uint32_t    dstReg,
+                 uint32_t    lenId,
+                 const uint8_t  *src_ptr,
+                 uint32_t    size);
+
+void PkaCopyBeByteBuffIntoPkaReg(uint32_t    dstReg,
+                 uint32_t    lenId,
+                 const uint8_t  *src_ptr,
+                 uint32_t    sizeWords);
+
+void PkaCopyDataIntoPkaReg(uint32_t    dstReg,
+                 uint32_t    lenId,
+                 const uint32_t  *src_ptr,
+                 uint32_t    sizeWords);
+
+void PkaCopyPkaRegIntoBeByteBuff(uint8_t *dst_ptr,
+                  uint32_t  sizeWords,
+                  uint32_t  srcReg);
+
+void PkaCopyDataFromPkaReg( uint32_t *dst_ptr,
+                  uint32_t  sizeWords,
+                  uint32_t  srcReg);
+
+uint32_t PkaGetRegEffectiveSizeInBits(uint32_t  reg);
+
+bool PkaIsRegModEqual(uint32_t reg1, uint32_t reg2, uint32_t regTmp1, uint32_t regTmp2);
+
+
+uint32_t  PkaGetNextMsBit(uint32_t r, int32_t i, uint32_t *pW, uint32_t *pIsNew);
+
+
+uint32_t  PkaGet2MsBits(uint32_t r, int32_t i, uint32_t *pW, uint32_t *pIsNew);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_defs.h
new file mode 100644
index 0000000..236f194
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_defs.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PKA_DEFS_H
+#define PKA_DEFS_H
+
+#include "cc_sram_map.h"
+#include "cc_pal_types.h"
+#include "cc_pka_hw_plat_defs.h"
+
+
+/* minimal and maximal allowed size of PKA data memory registers in bits */
+#define PKA_MIN_OPERATION_SIZE_BITS                     CC_BITS_IN_32BIT_WORD
+#ifdef CC_CONFIG_SUPPORT_HK
+#define PKA_MAX_OPERATION_SIZE_BITS                     (CC_SRP_MAX_MODULUS_SIZE_IN_BITS+CC_PKA_WORD_SIZE_IN_BITS)
+#else
+#define PKA_MAX_OPERATION_SIZE_BITS                     (CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS+CC_PKA_WORD_SIZE_IN_BITS)
+#endif
+
+
+#define CC_SRAM_PKA_SIZE_IN_BYTES       (CC_PKA_SRAM_SIZE_IN_KBYTES*CC_1K_SIZE_IN_BYTES)
+#define CC_SRAM_PKA_MAX_SIZE                  CC_SRAM_PKA_SIZE_IN_BYTES
+
+/* PKA word size in bits/32bit words */
+#define PKA_WORD_SIZE_IN_BYTES  (CC_PKA_WORD_SIZE_IN_BITS/CC_BITS_IN_BYTE)
+#define PKA_WORD_SIZE_IN_32BIT_WORDS  (CC_PKA_WORD_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD)
+
+/* maximal size of extended register in "big PKA words" and in 32-bit words:  *
+   the size defined according to RSA as more large, and used to define some   *
+*  auxiliary buffers sizes                                */
+#define PKA_MAX_REGISTER_SIZE_IN_PKA_WORDS ((PKA_MAX_OPERATION_SIZE_BITS+PKA_EXTRA_BITS+CC_PKA_WORD_SIZE_IN_BITS-1)/CC_PKA_WORD_SIZE_IN_BITS)
+#define PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS  (PKA_MAX_REGISTER_SIZE_IN_PKA_WORDS*PKA_WORD_SIZE_IN_32BIT_WORDS)
+
+
+/* Full register (operation) size including extra PKA-word (128/64-bit). Op size *
+*  must include extra bits if needed in the algorithm
+// Adding 1 for operation with carry/additional bits              */
+#define GET_FULL_OP_SIZE_PKA_WORDS(opSizeInBits)    (((opSizeInBits)/CC_PKA_WORD_SIZE_IN_BITS + (((opSizeInBits) & (CC_PKA_WORD_SIZE_IN_BITS-1)) > 0)) + 1)
+#define GET_FULL_OP_SIZE_BITS(opSizeInBits)         (CC_PKA_WORD_SIZE_IN_BITS*GET_FULL_OP_SIZE_PKA_WORDS((opSizeInBits)))
+#define GET_FULL_OP_SIZE_32BIT_WORDS(opSizeInBits)  (GET_FULL_OP_SIZE_BITS((opSizeInBits)) / CC_BITS_IN_32BIT_WORD)
+
+
+/* The maximal count of allowed sizes of PKA operands or register-variables */
+#define PKA_NUM_OF_PKA_LEN_IDS_REGS                        8
+
+/* enumerator, defining ID-s of PKA registers sizes, inserted in PKA sizes    *
+*  table                                                                      */
+typedef enum {
+    LEN_ID_N_BITS = 0,          // 0  - for modulus size    (RSA, EC)
+    LEN_ID_N_PKA_REG_BITS,      // 1  - for operation size  (RSA, EC)
+    LEN_ID_PQ_BITS,         // 2  - for P, Q size       (RSA)
+    LEN_ID_PQ_PKA_REG_BITS,     // 3  - for operations on P, Q size  (RSA)
+    LEN_ID_AUX_PRIME_BITS,      // 4  - for P1,P2,Q1,Q2 101 bit size (RSA)
+    LEN_ID_AUX_PRIME_PKA_REG_BITS,  // 5  - for operations on P1,P2,Q1,Q2 101 bit size  (RSA)
+    LEN_ID_NP_BITS,         // 6  - for calculating Np  (RSA, EC)
+    LEN_ID_MAX_BITS ,       // 7  - size of PKA registers (RSA: CC_RSA_MAX_KEY_GENERATION_SIZE_BITS; EC: reg.size)
+    LEN_ID_MAX,             // 8  - not allowed, indicates out of range  (RSA, EC)
+}LenIdTypes_t;
+
+
+#endif // PKA_GEN_DEFS_H
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_error.h
new file mode 100644
index 0000000..6ec5c97
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_error.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef PKA_ERROR_H
+#define PKA_ERROR_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* base address -  0x00F10B00 */
+
+#define PKA_HW_VERSION_NOT_CORRECT_ERROR   (PKA_MODULE_ERROR_BASE + 0x0UL)
+#define PKA_HW_PIC_DECRYPED_FAILURE_ERROR  (PKA_MODULE_ERROR_BASE + 0x1UL)
+#define PKA_KG_UNSUPPORTED_KEY_SIZE        (PKA_MODULE_ERROR_BASE + 0x2UL)
+#define PKA_KEY_ILLEGAL_SIZE_ERROR     (PKA_MODULE_ERROR_BASE + 0x3UL)
+
+#define PKA_CONVERT_PRIV_KEY_TO_CRT_NOT_SUPPORTED       (PKA_MODULE_ERROR_BASE + 0x10UL)
+#define PKA_CONVERT_PRIV_KEY_TO_CRT_FACTORS_NOT_FOUND   (PKA_MODULE_ERROR_BASE + 0x11UL)
+#define PKA_CRT_WITH_512_BITS_KEY_ERROR         (PKA_MODULE_ERROR_BASE + 0x12UL)
+
+/* Error definitions for PKA using */
+#define PKA_ILLEGAL_PTR_ERROR                       (PKA_MODULE_ERROR_BASE + 0x20UL)
+#define PKA_ENTRIES_COUNT_ERROR                     (PKA_MODULE_ERROR_BASE + 0x21UL)
+#define PKA_REGISTER_SIZES_ERROR                    (PKA_MODULE_ERROR_BASE + 0x22UL)
+#define PKA_SET_MAP_MODE_ERROR                      (PKA_MODULE_ERROR_BASE + 0x23UL)
+#define PKA_ILLEGAL_OPERAND_LEN_ERROR               (PKA_MODULE_ERROR_BASE + 0x24UL)
+#define PKA_ILLEGAL_OPERAND_ERROR                   (PKA_MODULE_ERROR_BASE + 0x25UL)
+#define PKA_ILLEGAL_OPCODE_ERROR                    (PKA_MODULE_ERROR_BASE + 0x26UL)
+#define PKA_NOT_ENOUGH_MEMORY_ERROR                 (PKA_MODULE_ERROR_BASE + 0x27UL)
+#define PKA_ILLEGAL_OPERAND_TYPE_ERROR              (PKA_MODULE_ERROR_BASE + 0x28UL)
+#define PKA_INVERSION_NOT_EXISTS_ERROR              (PKA_MODULE_ERROR_BASE + 0x29UL)
+#define PKA_NOT_ENOUGH_TEMP_REGS_ERROR              (PKA_MODULE_ERROR_BASE + 0x2AUL)
+#define PKA_OPERATION_NOT_SUPPORTED_ERROR           (PKA_MODULE_ERROR_BASE + 0x2BUL)
+#define PKA_MOD_EVEN_USE_OTHER_FUNC_ERROR           (PKA_MODULE_ERROR_BASE + 0x2CUL)
+#define PKA_DIVIDER_IS_NULL_ERROR                   (PKA_MODULE_ERROR_BASE + 0x2EUL)
+#define PKA_MODULUS_IS_NULL_ERROR                   (PKA_MODULE_ERROR_BASE + 0x2FUL)
+#define PKA_DATA_SIZE_ERROR                         (PKA_MODULE_ERROR_BASE + 0x30UL)
+#define PKA_OPERATION_SIZE_ERROR                    (PKA_MODULE_ERROR_BASE + 0x31UL)
+
+#define PKA_ILLEGAL_PKA_ADDRESS_ERROR               (PKA_MODULE_ERROR_BASE + 0x32UL)
+#define PKA_ILLEGAL_PKA_VIRT_PTR_ERROR              (PKA_MODULE_ERROR_BASE + 0x33UL)
+#define PKA_NAF_KEY_SIZE_ERROR                      (PKA_MODULE_ERROR_BASE + 0x34UL)
+#define PKA_NAF_BUFFER_SIZE_ERROR                   (PKA_MODULE_ERROR_BASE + 0x35UL)
+#define PKA_NAF_KEY_ERROR                           (PKA_MODULE_ERROR_BASE + 0x36UL)
+#define PKA_NAF_INTERNAL_ERROR                      (PKA_MODULE_ERROR_BASE + 0x37UL)
+#define PKA_REGS_COUNT_ERROR                        (PKA_MODULE_ERROR_BASE + 0x38UL)
+#define PKA_INTERNAL_ERROR                          (PKA_MODULE_ERROR_BASE + 0x39UL)
+#define PKA_FATAL_ERR_STATE_ERROR                   (PKA_MODULE_ERROR_BASE + 0x3AUL)
+
+/* modular functions errors */
+#define PKA_MOD_SQUARE_ROOT_NOT_EXIST_ERROR         (PKA_MODULE_ERROR_BASE + 0x40UL)
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_hw_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_hw_defs.h
new file mode 100644
index 0000000..7688361
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_hw_defs.h
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef PKA_HW_DEFS_H
+#define PKA_HW_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "dx_crys_kernel.h"
+#include "cc_regs.h"
+#include "cc_hal_plat.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_bitops.h"
+#include "pka_defs.h"
+#include "cc_util_pm.h"
+
+
+/* PKA OPCODE register fields positions (low bit position) */
+#define PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET   5
+#define PKA_OPCODE_TAG_POS                        CC_REG_BIT_SHIFT(OPCODE, TAG)     // bit shift   0
+#define PKA_OPCODE_RESULT_POS                     CC_REG_BIT_SHIFT(OPCODE, REG_R)   // bit shift   6
+#define PKA_OPCODE_OPERAND_2_POS                  CC_REG_BIT_SHIFT(OPCODE, REG_B)   // bit shift  12
+#define PKA_OPCODE_OPERAND_1_POS                  CC_REG_BIT_SHIFT(OPCODE, REG_A)   // bit shift  18
+#define PKA_OPCODE_LEN_POS                        CC_REG_BIT_SHIFT(OPCODE, LEN)     // bit shift  24
+#define PKA_OPCODE_OPERATION_ID_POS               CC_REG_BIT_SHIFT(OPCODE, OPCODE)      // bit shift  27
+#define PKA_OPCODE_R_DISCARD_POS                  (PKA_OPCODE_RESULT_POS + PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET)
+#define PKA_OPCODE_OPERAND_2_IMMED_POS            (PKA_OPCODE_OPERAND_2_POS + PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET)
+#define PKA_OPCODE_OPERAND_1_IMMED_POS            (PKA_OPCODE_OPERAND_1_POS + PKA_OPCODE_RES_OPERAND_MSBIT_OFFSET)
+
+/* PKA STATUS register fields positions (low bit position) */
+#define PKA_STATUS_ALU_OUT_ZERO_POS               CC_REG_BIT_SHIFT(PKA_STATUS, ALU_OUT_ZERO)  // bit shift  12
+#define PKA_STATUS_DIV_BY_ZERO_POS                CC_REG_BIT_SHIFT(PKA_STATUS, DIV_BY_ZERO)   // bit shift  14
+#define PKA_STATUS_ALU_CARRY_POS                  CC_REG_BIT_SHIFT(PKA_STATUS, ALU_CARRY)     // bit shift  9
+
+
+/* PKA N_NP_T0_T1 register fields positions (low bit position) */
+#define PKA_N_NP_T0_T1_REG_N_POS                  CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, N_VIRTUAL_ADDR)    // bit shift  0
+#define PKA_N_NP_T0_T1_REG_NP_POS                 CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, NP_VIRTUAL_ADDR)   // bit shift  5
+#define PKA_N_NP_T0_T1_REG_T0_POS                 CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, T0_VIRTUAL_ADDR)   // bit shift  10
+#define PKA_N_NP_T0_T1_REG_T1_POS                 CC_REG_BIT_SHIFT(N_NP_T0_T1_ADDR, T1_VIRTUAL_ADDR)   // bit shift  15
+
+/* PKA N_NP_T0_T1 register default (reset) value: N=0, NP=1, T0=30, T1=31 */
+#define PKA_REG_N                                           0
+#define PKA_REG_NP                                          1
+#define PKA_REG_T0                                          30
+#define PKA_REG_T1                                          31
+#define PKA_N_NP_T0_T1_REG_DEFAULT_VAL                  (PKA_REG_N  << PKA_N_NP_T0_T1_REG_N_POS  | \
+                                                         PKA_REG_NP << PKA_N_NP_T0_T1_REG_NP_POS | \
+                                                         PKA_REG_T0 << PKA_N_NP_T0_T1_REG_T0_POS | \
+                                                         PKA_REG_T1 << PKA_N_NP_T0_T1_REG_T1_POS)
+
+/* PKA control values  */
+#define PKA_PIPE_READY                                   1
+#define PKA_OP_DONE                                      1
+
+
+/* PKA HW defined OPCODE values, according to HW documentation  */
+#define PKA_OPCODE_ID_ADD           0x4U    // @0x4 - Add,Inc
+#define PKA_OPCODE_ID_SUB           0x5U    // @0x5 - Sub,Dec,Neg
+#define PKA_OPCODE_ID_MODADD        0x6U    // @0x6 - ModAdd,ModInc
+#define PKA_OPCODE_ID_MODSUB        0x7U    // @0x7 - ModSub,ModDec,ModNeg
+#define PKA_OPCODE_ID_AND           0x8U    // @0x8 - AND,TST0,CLR0
+#define PKA_OPCODE_ID_OR            0x9U    // @0x9 - OR,COPY,SET0
+#define PKA_OPCODE_ID_XOR           0xAU    // @0xa - XOR,FLIP0,INVERT,COMPARE
+#define PKA_OPCODE_ID_SHR0          0xCU    // @0xc - SHR0
+#define PKA_OPCODE_ID_SHR1          0xDU    // @0xd - SHR1
+#define PKA_OPCODE_ID_SHL0          0xEU    // @0xe - SHL0
+#define PKA_OPCODE_ID_SHL1          0xFU    // @0xf - SHL1
+#define PKA_OPCODE_ID_MULLOW        0x10U   // @0x10 - MulLow
+#define PKA_OPCODE_ID_MODMUL        0x11U   // @0x11 - ModMul
+#define PKA_OPCODE_ID_MODMULN       0x12U   // @0x12 - ModMulN
+#define PKA_OPCODE_ID_MODEXP        0x13U   // @0x13 - ModExp
+#define PKA_OPCODE_ID_DIVISION      0x14U   // @0x14 - Division
+#define PKA_OPCODE_ID_MODINV        0x15U   // @0x15 - ModInv
+//#define PKA_OPCODE_ID_DIV         0x16U   // @0x16 - RL the code not used
+#define PKA_OPCODE_ID_MULHIGH           0x17U   // 0x17 - MULHigh
+#define PKA_OPCODE_ID_MODMLAC       0x18U   // 0x18 - ModMulAcc
+#define PKA_OPCODE_ID_MODMLACNR         0x19U   // 0x19 - ModMulAccNR
+#define PKA_OPCODE_ID_SEPINT        0x1AU   // 0x1A - sepInt
+#define PKA_OPCODE_ID_REDUCTION         0x1BU   // 0x1B - Reduction
+#define PKA_OPCODE_ID_TERMINATE     0x0U    // @0x00 - Terminate
+
+#define   PKA_MAX_OPCODE    0x1BU
+
+
+/*************************************************************/
+/* Macros for waiting PKA machine ready states               */
+/*************************************************************/
+
+
+/* defining a macro for waiting to the PKA_PIPE_READY */
+#define PKA_WAIT_ON_PKA_PIPE_READY() \
+do { \
+   volatile uint32_t output_reg_val; \
+   do \
+   { \
+      output_reg_val = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_PIPE_RDY) ); \
+   }while( (output_reg_val & 0x01) != PKA_PIPE_READY ); \
+}while(0)
+
+/* defining a macro for waiting to the PKA_OP_DONE */
+#define PKA_WAIT_ON_PKA_DONE() \
+do { \
+   volatile uint32_t output_reg_val; \
+   do \
+   { \
+      output_reg_val = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_DONE) ); \
+   }while( (output_reg_val & 0x01) != PKA_OP_DONE ); \
+}while(0)
+
+
+/**************************************************************/
+/*  Macros for controlling PKA machine and changing           */
+/*  PKA sizes table and mapping table settings.               */
+/**************************************************************/
+
+/*  Set_N_NP_T0_T1_REG:  Sets addresses of registers N,NP,T0,T1 into special register */
+#define   PKA_SET_N_NP_T0_T1_REG(N, NP, T0, T1) \
+        PKA_WAIT_ON_PKA_DONE();  /*!! Needed to wait PKA not to disturb in the it's work !!!*/\
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, N_NP_T0_T1_ADDR), \
+       (uint32_t)( (N) << PKA_N_NP_T0_T1_REG_N_POS   | \
+                    (NP) << PKA_N_NP_T0_T1_REG_NP_POS  | \
+                    (T0) << PKA_N_NP_T0_T1_REG_T0_POS  | \
+                    (T1) << PKA_N_NP_T0_T1_REG_T1_POS  ) )
+
+/*  Set default N_NP_T0_T1_REG:  Sets default values of registers addresses
+    N=0, NP=1, T0=30, T1=31 into special register N_NP_T0_T1_REG */
+#define   PKA_DEFAULT_N_NP_T0_T1_REG()  \
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, N_NP_T0_T1_ADDR), \
+                              PKA_N_NP_T0_T1_REG_DEFAULT_VAL)
+
+/* Returns the ALU Zero-bit from PKA_STATUS register */
+#define PKA_GET_STATUS_ALU_OUT_ZERO(status)  { \
+    PKA_WAIT_ON_PKA_DONE(); \
+    status = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL,PKA_STATUS)); \
+    status = ((status) >> PKA_STATUS_ALU_OUT_ZERO_POS ) & 1UL; \
+}
+
+/*Returns the DividerIsZero-bit from PKA_STATUS register */
+#define PKA_GET_STATUS_DIV_BY_ZERO( status)  { \
+    PKA_WAIT_ON_PKA_DONE(); \
+    status = CC_HAL_READ_REGISTER( CC_REG_OFFSET (CRY_KERNEL,PKA_STATUS)); \
+    status = ((status) >> PKA_STATUS_DIV_BY_ZERO_POS ) & 1; \
+}
+
+/* Returns the ALU Carry-bit from PKA_STATUS register */
+#define PKA_GET_STATUS_CARRY(status)  { \
+    PKA_WAIT_ON_PKA_DONE(); \
+    status = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL,PKA_STATUS)); \
+    status = ((status) >> PKA_STATUS_ALU_CARRY_POS ) & 1; \
+}
+
+
+/******************************************************************/
+/* Macros for setting and reading sizes from PKA regsSizesTable   */
+/******************************************************************/
+
+/*  Sets the size into regsSizesTable entry */
+#define PKA_SET_REG_SIZE(SizeBits, EntryNum) \
+    PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA not to disturb in the it's work !!!*/\
+    CC_HAL_WRITE_REGISTER((CC_REG_OFFSET(CRY_KERNEL ,PKA_L0) + 4*(EntryNum)), (SizeBits) )
+
+/*  Gets the size from regsSizesTable entry */
+#define PKA_GET_REG_SIZE(SizeBits, EntryNum) \
+    PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA to get right results !!!*/\
+    SizeBits = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL ,PKA_L0) + 4*(EntryNum))
+
+/******************************************************************/
+/* Macros for setting and reading addresses of PKA data registers */
+/******************************************************************/
+
+/*The following macros are used for setting and reading the data registers addresses in mapping table.*/
+
+/*  Sets the physical address PhysAddr of register VirtReg in mapping table */
+#define PKA_SET_REG_ADDRESS(VirtReg, PhysAddr) \
+    PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA to complete before changing mapping !!!*/\
+    CC_HAL_WRITE_REGISTER((CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + 4*(VirtReg)), (PhysAddr))
+
+/*  Returns the physical address of register VirtReg from mapping table  */
+#define PKA_GET_REG_ADDRESS(VirtReg, PhysAddr)\
+    PKA_WAIT_ON_PKA_DONE(); /*!! Needed to wait PKA to complete before changing mapping !!!*/\
+    (PhysAddr) = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + 4*(VirtReg))
+
+
+/******************************************************************/
+/*          Macros for setting Full PKI opcode                    */
+/******************************************************************/
+#define PKA_SET_FULL_OPCODE( Opcode,LenID,IsAImmed,OpA,IsBImmed,OpB,ResDiscard,Res,Tag ) \
+    ( ((Opcode))      << PKA_OPCODE_OPERATION_ID_POS     | \
+      ((LenID))       << PKA_OPCODE_LEN_POS              | \
+      ((IsAImmed))    << PKA_OPCODE_OPERAND_1_IMMED_POS  | \
+      ((OpA))         << PKA_OPCODE_OPERAND_1_POS        | \
+      ((IsBImmed))    << PKA_OPCODE_OPERAND_2_IMMED_POS  | \
+      ((OpB))         << PKA_OPCODE_OPERAND_2_POS        | \
+      ((ResDiscard))  << PKA_OPCODE_R_DISCARD_POS        | \
+      ((Res))         << PKA_OPCODE_RESULT_POS           | \
+      ((Tag))         << PKA_OPCODE_TAG_POS  )
+
+
+/******************************************************************/
+/*          Macros for reading and loading PKA memory data        */
+/******************************************************************/
+/* macros to lock/unlock the Mutex on each SRAM read/write    *
+*  used only when symmetric driver uses the one or more of the following regs:
+*  PKA_SRAM_ADDR, PKA_SRAM_RDATA, PKA_SRAM_WDATA, SRAM_DATA_READY     */
+#ifdef CC_IOT
+    #define PKA_MUTEX_LOCK
+    #define PKA_MUTEX_UNLOCK
+#else
+    extern CC_PalMutex CCSymCryptoMutex;
+
+    #define PKA_MUTEX_LOCK  \
+        if(CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != CC_SUCCESS) { \
+           CC_PalAbort("Fail to acquire mutex\n");}
+
+    #define PKA_MUTEX_UNLOCK \
+        if(CC_PalMutexUnlock(&CCSymCryptoMutex) != CC_SUCCESS) { \
+           CC_PalAbort("Fail to release mutex\n");}
+#endif
+
+/* ******************************************************************* */
+/* MACRO DEFINITIONS FOR WORKING WITH INDIRECT ACCESS TO PKA SRAM DATA */
+/* ******************************************************************* */
+/* defining a macro to clear the not-completed part of PKA big word*
+*  ii value was set in macro calling  PKA_SRAM_WRITE_CLR()         */
+#define PKA_SRAM_WRITE_CLR(SizeWords) \
+   for(; ii < (((SizeWords+(PKA_WORD_SIZE_IN_32BIT_WORDS-1))/PKA_WORD_SIZE_IN_32BIT_WORDS)*PKA_WORD_SIZE_IN_32BIT_WORDS) ; ii++) { \
+       CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), 0); \
+       WAIT_SRAM_DATA_READY; \
+   }
+
+
+/* defining a macro to wait on SRAM ready;
+       currently waiting is not needed   */
+// #define DO_WAIT_SRAM_DATA_READY
+// #define PKA_DELEY 0
+#ifndef DO_WAIT_SRAM_DATA_READY
+    #define WAIT_SRAM_DATA_READY
+#elif defined PKA_DELEY
+    #define WAIT_SRAM_DATA_READY  { \
+        volatile uint32_t ii; \
+        for(ii=0; ii<PKA_DELEY; ) ii++; \
+    }
+#else
+    #define WAIT_SRAM_DATA_READY { \
+        volatile uint32_t dummy; \
+        do { \
+            dummy = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, SRAM_DATA_READY)); \
+           }while(!(dummy & 0x1));\
+    }
+#endif
+
+/* macro to load block to SRAM memory */
+#define PKA_HW_LOAD_BLOCK_TO_PKA_MEM(Addr, ptr, SizeWords) \
+do { \
+   uint32_t ii; \
+   PKA_MUTEX_LOCK; \
+   PKA_WAIT_ON_PKA_DONE();\
+   CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_SRAM_ADDR), (Addr)); \
+   for(ii = 0; ii < (SizeWords); ii++) \
+   { \
+       CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), ((uint32_t*)(ptr))[ii]); \
+       WAIT_SRAM_DATA_READY; \
+   } \
+   PKA_SRAM_WRITE_CLR(SizeWords) \
+   PKA_MUTEX_UNLOCK; \
+}while(0)
+
+/* macro to load a value to SRAM with 32-bit access */
+#define PKA_HW_LOAD_VALUE_TO_PKA_MEM(Addr, Val) \
+do { \
+   PKA_MUTEX_LOCK; \
+   PKA_WAIT_ON_PKA_DONE();\
+   CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), (Addr)); \
+   CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), (Val)); \
+   WAIT_SRAM_DATA_READY; \
+   PKA_MUTEX_UNLOCK; \
+}while(0)
+
+
+/* macro to clear PKA memory: Addr must be alighned to PKA_WORD_SIZE */
+#define PKA_HW_CLEAR_PKA_MEM(Addr, SizeWords) \
+do { \
+   uint32_t ii; \
+   PKA_MUTEX_LOCK; \
+   PKA_WAIT_ON_PKA_DONE();\
+   CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), (Addr)); \
+   for( ii = 0; ii < (uint32_t)(SizeWords); ii++ ) \
+   { \
+      CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), 0x0UL ); \
+      WAIT_SRAM_DATA_READY; \
+   }\
+   PKA_SRAM_WRITE_CLR((SizeWords)); \
+   PKA_MUTEX_UNLOCK; \
+}while(0)
+
+/* macro to read a value from the PKA data memory */
+#define PKA_HW_READ_VALUE_FROM_PKA_MEM(Addr, Val) \
+do { \
+   volatile uint32_t dummy; \
+   PKA_MUTEX_LOCK; \
+   PKA_WAIT_ON_PKA_DONE();\
+   CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RADDR), (Addr)); \
+   WAIT_SRAM_DATA_READY; \
+   dummy = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RDATA)); \
+   (Val) = dummy; \
+   WAIT_SRAM_DATA_READY; \
+   PKA_MUTEX_UNLOCK; \
+}while(0)
+
+/* macro to read a block from the PKA data memory */
+#define PKA_HW_READ_BLOCK_FROM_PKA_MEM(Addr, ptr, SizeWords) \
+do { \
+   uint32_t ii; \
+   volatile uint32_t dummy; \
+   PKA_MUTEX_LOCK; \
+   PKA_WAIT_ON_PKA_DONE();\
+   CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RADDR), (Addr)); \
+   for(ii = 0; ii < (SizeWords); ii++) \
+   { \
+      WAIT_SRAM_DATA_READY; \
+      dummy = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_RDATA));\
+      ((uint32_t*)(ptr))[ii] = (dummy); \
+   } \
+   WAIT_SRAM_DATA_READY; \
+   PKA_MUTEX_UNLOCK; \
+}while(0)
+
+/************************ Enums ********************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PKA_HW_DEFS_H
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_point_compress_regs_def.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_point_compress_regs_def.h
new file mode 100644
index 0000000..ce15d85
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pka_point_compress_regs_def.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PKA_POINT_COMPRESS_REGS_DEF_H
+#define PKA_POINT_COMPRESS_REGS_DEF_H
+
+/*stack*/
+#define PKA_REG_X     2
+#define PKA_REG_Y     3
+#define PKA_REG_EC_A  4
+#define PKA_REG_EC_B  5
+
+/*Square root*/
+/*in*/
+#define PKA_REG_Y1    PKA_REG_Y    //zQ
+#define PKA_REG_Y2    PKA_REG_EC_A //zN
+/*stack*/
+#define PKA_REG_T     6   //zT
+#define PKA_REG_Z     7   //zZ
+#define PKA_REG_EX    8   //zEx
+#define PKA_REG_YT    9   //zYt
+
+/* Jacobi symbol */
+/*in*/
+#define PKA_REG_A    10   //za
+#define PKA_REG_B    11   //zb
+/*stack*/
+#define PKA_REG_C    12   //zc
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki.c
new file mode 100644
index 0000000..09ee4c5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki.c
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mutex.h"
+#include "cc_hal_plat.h"
+#include "cc_sram_map.h"
+#include "dx_crys_kernel.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "pka_hw_defs.h"
+#include "pki.h"
+#include "ec_wrst.h"
+#include "pka_hw_defs.h"
+#include "pka.h"
+#include "pka_error.h"
+#ifdef DEBUG
+        #include <assert.h>
+#endif
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+#if defined PKA_DEBUG && defined DEBUG
+uint32_t tempRes[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+uint32_t tempRes1[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+#endif
+
+
+/***********    PkiCalcNp  function      **********************/
+/**
+ * The function uses physical data pointers to calculate and output
+ * the Barrett tag Np.
+ *
+ *  For RSA it uses truncated sizes:
+ *      Np = truncated(2^(3*A+3*X-1) / ceiling(n/(2^(N-2*A-2*X)));
+ *  For ECC - full sizes of not truncated input arguments:
+ *      Np = truncated(2^(N+A+X-1) / n);
+ *
+ * @author reuvenl (5/1/2014)
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t  PkiCalcNp(uint32_t *pNp, /*!< [out] The pointer to the Barrett tag Np buffer. If pNp = Null,
+                            the function not outputs calculated Np. */
+                        uint32_t *pN,       /*!< [out] The pointer to the modulus n. */
+                        uint32_t  sizeNbits)    /*!< [in] The exact size of the modulus. */
+{
+        CCError_t err = 0;
+        uint32_t  A = CC_PKA_WORD_SIZE_IN_BITS;
+        uint32_t  X = PKA_EXTRA_BITS;
+        uint32_t pkaReqRegs = 6;
+        int32_t wN, wNp;
+
+        /* usage of PKA registers */
+        int8_t  rN = PKA_REG_N;
+        int8_t  rNp = PKA_REG_NP;
+        int8_t  rT2 = regTemps[2];
+        int8_t  rT4 = regTemps[4];
+
+        /* Calc. sizes of modulus in words and reminder in bits */
+        wN = CALC_FULL_32BIT_WORDS(sizeNbits);
+        wNp = CALC_FULL_32BIT_WORDS(A + X - 1);
+
+        err = PkaInitAndMutexLock(sizeNbits, &pkaReqRegs);
+        if (err != CC_SUCCESS) {
+                CC_PalAbort("Fail to acquire mutex\n");
+        }
+        /* Set modulus in T1 */
+        PkaCopyDataIntoPkaReg(rN/*dstReg*/, LEN_ID_MAX_BITS/*lenId*/, pN/*src_ptr*/, wN);
+        err = PkaCalcNpIntoPkaReg(LEN_ID_N_BITS, sizeNbits, rN /* regN */, rNp /* regNp */, rT2, rT4);
+        if (err != CC_SUCCESS) {
+                goto End;
+        }
+        /* Output Np */
+        PkaCopyDataFromPkaReg(pNp/*dst_ptr*/, wNp, rNp/*srcReg*/);
+End:
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+
+        return err;
+}
+
+
+/***********    PkiLongNumDiv   function      **********************/
+/**
+ * @brief  This function performs division of big numbers, passed by physical pointers,
+ *              using the PKA.
+ *              .
+ *     Computes modRes = A mod B. divRes_ptr = floor(A/B)
+ *     Lengths: A[ALen], B[BLen], modRes[BLen], divRes[ALen].
+ *     Assumes:  c > 0.
+ *
+ *     PKA registers using: A=>r2, B=>r3, divRes=>r4, modRes=>r2 (r2 is rewritten by remainder).
+ *
+ * Author: R.Levin
+ *
+ * Last Revision: 1.00.00
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ *
+ * Update History:
+ * Rev 1.00.00, Date 4 Feb. 2008,
+ *
+ */
+CCError_t  PkiLongNumDiv(uint32_t *pNumA,        /*!< [in] The pointer to numerator A vector. */
+                           uint32_t numASizeInWords,  /*!< [in] Length of numerator A in words.*/
+                           uint32_t *pNumB,        /*!< [in] The pointer to divider B (modulus).*/
+                           uint32_t numBSizeInWords,  /*!< [in] The size of B vector in words.*/
+                           uint32_t *pModRes,   /*!< [out] The pointer to modulus result (reminder of division). */
+                           uint32_t *pDivRes)   /*!< [out] The pointer to result of division.*/
+{
+        CCError_t error = CC_OK;
+        uint32_t  opSizeWords;
+        uint32_t status;
+        uint32_t pkaReqRegs = 6;
+    int8_t  rT2 = regTemps[2];
+        int8_t  rT3 = regTemps[3];
+        int8_t  rT4 = regTemps[4];
+
+
+        opSizeWords = CC_MAX(numASizeInWords, numBSizeInWords);
+
+        error = PkaInitAndMutexLock(CC_BITS_IN_32BIT_WORD*opSizeWords, &pkaReqRegs);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        /* copying all needed data into PKA memory before starting PKA operations */
+        /* A=>r2, B=>r3,                                                          */
+        /* copy numerator into PKA register: A=>r2 */
+        PkaCopyDataIntoPkaReg( rT2/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumA/*src_ptr*/, numASizeInWords);
+
+        /* copy divisor into PKA register: B=>r3 */
+        PkaCopyDataIntoPkaReg( rT3/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumB/*src_ptr*/, numBSizeInWords);
+
+        /* check, that divisor is not null, else return error */
+        PKA_ADD_IM( LEN_ID_N_PKA_REG_BITS/*LenID*/, rT4/*Res*/, rT3/*OpA*/, 0/*Imm OpB*/);
+        PKA_GET_STATUS_ALU_OUT_ZERO(status);
+        if (status == 1) {
+                error = PKA_DIVIDER_IS_NULL_ERROR;
+                goto End;
+        }
+
+        /* division in PKA: quotient: r4 = r2 / r3; remainder: r2 = r2 % r3        */
+        PKA_DIV( LEN_ID_N_PKA_REG_BITS/*LenID*/, rT4/*Res*/, rT2/*OpA*/, rT3/*OpB*/);
+
+
+        /*        output the results                                               */
+        if (pDivRes != NULL) {
+                PkaCopyDataFromPkaReg(pDivRes,  numASizeInWords, rT4/*srcReg*/);
+        }
+
+        if (pModRes != NULL) {
+                PkaCopyDataFromPkaReg(pModRes,  numBSizeInWords, rT2/*srcReg*/);
+        }
+
+End:
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+        return error;
+
+}
+
+
+/***********     PkiLongNumMul  function     **********************/
+/**
+ * @brief This function performs multiplication of big numbers, passed by physical
+ *              pointers, using the PKA.
+ *
+ *        The RMul operation is : (A * B)
+ *
+ *        The function performs the following algorithm:
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t PkiLongNumMul(uint32_t *pNumA ,      /*!< [in] The pointer of A words array (LS word is left most). */
+                          uint32_t  numASizeInBits, /*!< [in] The size of vectors in bits. */
+                          uint32_t *pNumB ,      /*!< [in] The pointer of B words array (LS word is left most). */
+                          uint32_t *pRes)    /*!< [out] The pointer to the result buffer. */
+{
+        CCError_t error = CC_OK;
+        uint32_t  OpSizeInWords;
+        uint32_t pkaReqRegs = 6;
+        int8_t  rT2 = regTemps[2];
+        int8_t  rT3 = regTemps[3];
+        int8_t  rT4 = regTemps[4];
+
+#ifdef LLF_PKI_PKA_DEBUG
+        /* check the operands size, used for RSA only */
+        if (2*numASizeInBits > (CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS+CC_PKA_WORD_SIZE_IN_BITS)) {
+               return PKA_ILLEGAL_OPERAND_LEN_ERROR;
+    }
+#endif
+
+        /* set operation size in words */
+        if (CALC_FULL_32BIT_WORDS(2*numASizeInBits) < CALC_FULL_32BIT_WORDS(PKA_MIN_OPERATION_SIZE_BITS))
+                OpSizeInWords = CALC_FULL_32BIT_WORDS(PKA_MIN_OPERATION_SIZE_BITS);
+
+        else
+                OpSizeInWords = CALC_FULL_32BIT_WORDS(2*numASizeInBits);
+
+
+        error = PkaInitAndMutexLock(CC_BITS_IN_32BIT_WORD*OpSizeInWords, &pkaReqRegs);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        /* copying all needed data into PKA memory before starting PKA operations */
+        /* A=>r2, B=>r3,                                                          */
+        /* copy A into PKA register: A=>r2 */
+        PkaCopyDataIntoPkaReg(rT2/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumA/*src_ptr*/,
+                               CALC_FULL_32BIT_WORDS(numASizeInBits));
+
+        /* copy B into PKA register: B=>r2 */
+        PkaCopyDataIntoPkaReg(rT3/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumB/*src_ptr*/,
+                               CALC_FULL_32BIT_WORDS(numASizeInBits));
+
+
+        /* multiply in PKA:  r4 = r2 * r3; */
+        PKA_MUL_LOW(LEN_ID_N_PKA_REG_BITS/*lenId*/, rT4/*Res*/, rT2/*OpA*/, rT3/*OpB*/);
+
+        /* output the results */
+        PkaCopyDataFromPkaReg(pRes, OpSizeInWords, rT4/*srcReg*/ );
+
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+
+        return error;
+}
+
+
+/***********     PkiConditionalSecureSwapUint32  function     **********************/
+/**
+ * @brief The function performs conditional swapping of two values in secure
+ *  mode
+ *
+ *  if(swp == 1) {tmp = *x; *x = *y; *y = tmp;}
+ *
+ * @return None
+ */
+void PkiConditionalSecureSwapUint32(uint32_t *x,    /*!< [in/out] the pointer to x-variable. */
+                    uint32_t *y,    /*!< [in/out] the pointer to y-variable. */
+                    uint32_t swp)   /*!< [in] swapping condition [0,1]. */
+{
+        int32_t tmpX = *x;
+        int32_t tmpY = *y;
+        int32_t tmp  = tmpX ^ tmpY;
+
+        swp = -swp;
+        tmp &= swp;
+        *x = tmpX ^ tmp;
+        *y = tmpY ^ tmp;
+}
+
+
+/***********     PkiClearAllPka  function     **********************/
+/**
+ * @brief This function clears the PKA memory.
+ *
+ * @return  None
+ */
+void PkiClearAllPka(void)
+{
+        uint32_t pkaRegCount = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
+        uint32_t regSizeInBits = ((CC_PKA_SRAM_SIZE_IN_KBYTES*CC_1K_SIZE_IN_BYTES*CC_BITS_IN_BYTE)/PKA_MAX_COUNT_OF_PHYS_MEM_REGS)-CC_PKA_WORD_SIZE_IN_BITS;
+
+        if (PkaInitAndMutexLock(regSizeInBits, &pkaRegCount) != CC_SUCCESS) {
+                return;
+        }
+
+        PkaFinishAndMutexUnlock(pkaRegCount);
+        return;
+
+}
+
+/*!< get next two bits of scalar*/
+uint32_t PkiGetNextTwoMsBits(uint32_t *pScalar, uint32_t *pWord, int32_t i)
+{
+        uint32_t twoBits = 0;
+        //        twoBits = (*pWord >> (i & (CC_BITS_IN_32BIT_WORD - 1))) & 3;
+        twoBits = (*pWord >> (CC_BITS_IN_32BIT_WORD - 2));
+        /* get next bit of scalar */
+        if ((i % CC_BITS_IN_32BIT_WORD) != 0) {
+                *pWord <<= 2;
+        } else {
+                *pWord = pScalar[(i / CC_BITS_IN_32BIT_WORD)-1];
+        }
+        //        i--;
+
+        return twoBits;
+}
+
+
+/*!< the function checks is array equal to 0: *
+*    if arr == 0, then return 0, else 1.      */
+bool PkiIsUint8ArrayEqualTo0(const uint8_t *arr, size_t size)
+{
+        uint32_t i;
+        uint8_t  s = 0;
+        for (i = 0; i < size; i++)
+                s |= arr[i];
+        /* if(arr == 0) return 1, else 0. */
+        return !(bool)((0UL - s) >> 31);
+
+}
+
+/*!< the function compares equality of two buffers of same size:
+     if they are equal - return 0, else 1. */
+bool PkiAreBuffersEqual(const void *buff1, const void *buff2, size_t sizeInBytes)
+{
+        uint32_t i;
+        uint8_t  s = 0;
+        for (i = 0; i < sizeInBytes; i++)
+                s |= (((uint8_t*)buff1)[i] ^ ((uint8_t*)buff2)[i]);
+        /* if equalled return 0, else 1. */
+        return !(bool)((0UL - s) >> 31);
+
+}
+
+/************************************************************************/
+/**
+ * @brief The function copies uint8 big endianness data into PKA register.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         PKA registers used: dstReg.
+ *         The size of pTemp buffer is at least PKA register size (appropriate to
+ *         register size lenID) and dataSizeBytes <= temp buffer size (in bytes).
+ *
+ * @return  no return value
+ */
+void PkaCopyBe8DataIntoPkaReg(uint32_t  dstReg,       /* [out] virtual pointer to destination PKA register. */
+                 uint32_t lenId,          /* [in] PKA register length ID.*/
+                 const uint8_t *pSrc,     /* [in] pointer to source buffer. */
+                 uint32_t dataSizeBytes,  /* [in] size of the data in bytes */
+                 uint32_t *pTemp)         /* [in] pointer to the temp buffer of
+                                             size >= PKA SRAM register size. */
+{
+    uint32_t  regSizeBits, regSizeWords;
+//  uint32_t currAddr, word, dataSizeWords;
+//  int32_t i, j = 0;
+
+    PKA_GET_REG_SIZE(regSizeBits, lenId);
+    regSizeWords = CALC_FULL_32BIT_WORDS(regSizeBits); /*size in words*/
+
+//  CC_CommonConvertMsbLsbBytesToLswMswWords(pTemp, regSizeWords*CC_32BIT_WORD_SIZE, pSrc, dataSizeBytes);
+    CC_PalMemSetZero((uint8_t*)pTemp + dataSizeBytes, regSizeWords*CC_32BIT_WORD_SIZE - dataSizeBytes);
+    CC_CommonReverseMemcpy((uint8_t*)pTemp, (uint8_t*)pSrc, dataSizeBytes);
+//  dataSizeWords = CALC_32BIT_WORDS_FROM_BYTES(dataSizeBytes);
+    PkaCopyDataIntoPkaReg(dstReg, lenId, pTemp, regSizeWords);
+
+//  dataSizeWords = CALC_32BIT_WORDS_FROM_BYTES(dataSizeBytes);
+//  PKA_GET_REG_ADDRESS(dstReg, currAddr);
+//
+//  if(i > 3) {
+//      for(i = dataSizeBytes-1; i > 0; i -= 4, j++) {
+//          word = (pSrc[i] << 24) | (pSrc[i-1] << 16) |
+//                 (pSrc[i-2] << 8) | pSrc[i-3];
+//          PKA_HW_LOAD_VALUE_TO_PKA_MEM(currAddr, word);
+//          currAddr += CC_32BIT_WORD_SIZE;
+//      }
+    return;
+}
+
+
+/************************************************************************/
+/**
+ * @brief The function copies data from PKA register into uint8 buffer in big endianness order.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         PKA registers used: srcReg.
+ *         The size (in 32-bit words) of pTemp buffer is at least the data size,
+ *         in words (rounded up).
+ *
+ * @return  no return value
+ */
+void PkaCopyDataFromPkaRegToBe8Buff(
+            uint8_t  *pDst,      /* [out] pointer to the destination buffer of size >= sizeBytes. */
+            uint32_t  srcReg,    /* [in] virtual pointer to source PKA register. */
+            uint32_t  sizeBytes, /* [in] size of the data in PKA register in bytes */
+            uint32_t  *pTemp)    /* [in] pointer to the temp buffer of size (in bytes) >= sizeBytes. */
+{
+    PkaCopyDataFromPkaReg(pTemp, CALC_32BIT_WORDS_FROM_BYTES(sizeBytes), srcReg);
+    CC_CommonReverseMemcpy(pDst, (uint8_t*)pTemp, sizeBytes);
+
+    return;
+}
+
+
+
+/***********     PkiExecExpBe  function      **********************/
+/**
+ * @brief Executes the modular exponentiation using PKA for BE input parameters.
+ *
+ *  The function input/output arrays are in big endianness order of bytes.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         All sizes aligned to 32-bit words, leading zeros are present if exist.
+ *         PKA registers used: r0,r1,r2,r3,r4, r30,r31.
+ *         The size of pTemp buffer should be at least modulus size plus 2*PKA_WORD_SIZE,
+ *         where all sizes are rounded up to uint32 size.
+ *
+ * @return  no return value
+ */
+CCError_t  PkiExecModExpBe(
+                uint8_t *pOut,        /* [out] pointer to the exponentiation result with size >= modulus size (in bytes),
+                                               equaled to modulus size in bytes (including leading zeros. */
+                uint8_t *pIn,         /* [in]  pointer to the input data. */
+                uint32_t inSizeBytes, /* [in]  input data size in bytes */
+                uint8_t *pMod,        /* [in]  pointer to the modulus. */
+                uint32_t modSizeBits, /* [in]  modulus size in bits */
+                uint8_t *pExp,        /* [in]  pointer to the exponent buffer. */
+                uint32_t expSizeBytes,/* [in]  exponent size in bytes; should be <= modulus size (in bytes). */
+                uint32_t *pTemp)      /* [in]  pointer to the temp buffer of size >= modulus size. */
+{
+    CCError_t err = CC_OK;
+    uint32_t modSizeBytes;
+    uint32_t pkaRegsCount = 7;
+        /* define virtual registers pointers  */
+    #define IN_REG  2
+    #define EXP_REG 3
+    #define OUT_REG 4
+
+
+    err = PkaInitAndMutexLock(modSizeBits, &pkaRegsCount);
+    if (err != CC_OK) {
+        return err;
+    }
+
+    modSizeBytes = CALC_FULL_BYTES(modSizeBits);
+
+    /*  copy modulus into PKA */
+    PkaCopyBe8DataIntoPkaReg(PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pMod/*srcPtr*/,
+                         modSizeBytes, pTemp);
+
+    /* Calculate NP */
+    err =  PkaCalcNpIntoPkaReg(LEN_ID_N_BITS,
+            modSizeBits,  /* [in] The exact size of the modulus. */
+            PKA_REG_N,    /* [in] PKA reg, holding the modulus n. */
+            PKA_REG_NP,   /* [out PKA reg. - Np result. */
+                    IN_REG, OUT_REG);  /* PKA regs, used as temporaries. */
+
+    if (err != CC_OK) {
+        goto End;
+    }
+
+
+        /*  copy the Data and Exponent into PKA registers                  */
+    PkaCopyBe8DataIntoPkaReg(IN_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pIn, inSizeBytes, pTemp);
+    PkaCopyBe8DataIntoPkaReg(EXP_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pExp, expSizeBytes, pTemp);
+
+        /*  calculate the exponent result: OUT_REG */
+    PKA_MOD_EXP(LEN_ID_N_BITS/*LenID*/, OUT_REG, IN_REG/*OpA*/, EXP_REG/*OpB*/);
+
+    /* output result as big endiannness bytes array */
+    PkaCopyDataFromPkaRegToBe8Buff(pOut, OUT_REG, modSizeBytes, pTemp);
+
+End:
+    /*  Finish PKA and copy result */
+    PkaFinishAndMutexUnlock(pkaRegsCount);
+
+        /* undef virtual registers pointers  */
+    #undef IN_REG
+    #undef EXP_REG
+    #undef OUT_REG
+
+    return err;
+
+}
+
+/***********     PkiExecExpLeW  function      **********************/
+/**
+ * @brief Executes modular exponentiation using PKA for LE input parameters.
+ *
+ *  The function input/output arrays are given as little endianness words arrays.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         All sizes aligned to 32-bit words, leading zeros are present if exist.
+ *         PKA registers used: r0,r1,r2,r3,r4, r30,r31.
+ *
+ * @return  no return value
+ */
+CCError_t  PkiExecModExpLeW(
+                uint32_t *pOut,         /* [out] pointer to the exponentiation result with size, equalled
+                                                to modulus size in words (including leading zeros). */
+                uint32_t *pIn,         /* [in]  pointer to the input data. */
+                uint32_t inSizeWords,  /* [in]  input data size in words */
+                uint32_t *pMod,        /* [in]  pointer to the modulus. */
+                uint32_t modSizeBits,  /* [in]  modulus size in bits */
+                uint32_t *pExp,        /* [in]  pointer to the exponent buffer. */
+                uint32_t expSizeWords) /* [in]  exponent size: should be <= modulus size (in words). */
+{
+    CCError_t err = CC_OK;
+    uint32_t modSizeWords;
+    uint32_t pkaRegsCount = 7;
+        /* define virtual registers pointers  */
+    #define IN_REG  2
+    #define EXP_REG 3
+    #define OUT_REG 4
+
+
+    err = PkaInitAndMutexLock(modSizeBits, &pkaRegsCount);
+    if (err != CC_OK) {
+        return err;
+    }
+
+    modSizeWords = CALC_FULL_32BIT_WORDS(modSizeBits);
+
+    /*  copy modulus into PKA */
+    PkaCopyDataIntoPkaReg(PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/,
+                  pMod/*srcPtr*/, modSizeWords);
+
+    /* Calculate NP */
+    err =  PkaCalcNpIntoPkaReg(LEN_ID_N_BITS,
+            modSizeBits,  /* [in] The exact size of the modulus. */
+            PKA_REG_N,    /* [in] PKA reg, holding the modulus n. */
+            PKA_REG_NP,   /* [out PKA reg. - Np result. */
+            IN_REG, OUT_REG);  /* PKA regs, used as temporaries. */
+    if(err) {
+          goto End;
+    }
+
+    /*  copy the Data and Exponent into PKA registers  */
+    PkaCopyDataIntoPkaReg(IN_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pIn, inSizeWords);
+    PkaCopyDataIntoPkaReg(EXP_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pExp, expSizeWords);
+
+        /*  calculate the exponent result: OUT_REG */
+    PKA_MOD_EXP(LEN_ID_N_BITS/*LenID*/, OUT_REG, IN_REG/*OpA*/, EXP_REG/*OpB*/);
+
+    /* output result as big endiannness bytes array */
+    PkaCopyDataFromPkaReg(pOut, modSizeWords, OUT_REG);
+
+End:
+    /*  Finish PKA and copy result */
+    PkaFinishAndMutexUnlock(pkaRegsCount);
+
+        /* undef virtual registers pointers  */
+    #undef IN_REG
+    #undef EXP_REG
+    #undef OUT_REG
+
+    return err;
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki.h
new file mode 100644
index 0000000..a41b909
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef PKA_EXPORT_H
+#define PKA_EXPORT_H
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* the macro gets two bits [i+1,i] LE words array */
+#define PKI_GET_TWO_BITS_FROM_WORDS_ARRAY(pArr, i) \
+   ((pArr[(i)>>5] >> ((i)&31)) & 3)
+/* the macro gets bit[i] from LE words array */
+#define PKI_GET_BIT_FROM_WORDS_ARRAY(pArr, i) \
+   ((pArr[(i)>>5] >> ((i)&31)) & 1)
+
+
+bool PkiIsModSquareRootExists(void);
+
+void PkiClearAllPka(void);
+
+void PkiConditionalSecureSwapUint32(uint32_t *x,
+                    uint32_t *y,
+                    uint32_t swp);
+
+CCError_t  PkiCalcNp(uint32_t *pNp,
+            uint32_t *pN,
+            uint32_t  sizeNbits);
+
+
+CCError_t  PkiLongNumDiv(uint32_t *pNumA,
+               uint32_t numASizeInWords,
+               uint32_t *pNumB,
+               uint32_t numBSizeInWords,
+               uint32_t *pModRes,
+               uint32_t *pDivRes);
+
+
+CCError_t PkiLongNumMul(uint32_t *pNumA ,
+              uint32_t  ASizeInBits,
+              uint32_t *pNumB ,
+              uint32_t *pRes);
+
+/*!< get next two bits of scalar*/
+uint32_t PkiGetNextTwoMsBits(uint32_t *pScalar, uint32_t *pWord, int32_t i);
+
+/*!< the function checks is array equal to 0  *
+*    if(arr == 0) return 0, else 1.           */
+bool PkiIsUint8ArrayEqualTo0(const uint8_t *arr, size_t size);
+
+/*!< the function compares equality of two buffers of same size:
+     if they are equal - return 1, else 0. */
+bool PkiAreBuffersEqual(const void *buff1, const void *buff2, size_t sizeInBytes);
+
+/************************************************************************/
+/**
+ * @brief The function copies uint8 big endianness data into PKA register.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         PKA registers used: dstReg.
+ *         The size of pTemp buffer is at least PKA register size appropriate to
+ *         register size lenID and dataSizeBytes <= temp buffer size (in bytes).
+ *
+ * @return  no return value
+ */
+void PkaCopyBe8DataIntoPkaReg(uint32_t  dstReg,       /* [out] virtual pointer to destination PKA register. */
+                 uint32_t lenId,          /* [in] PKA register length ID.*/
+                 const uint8_t *pSrc,     /* [in] pointer to source buffer. */
+                 uint32_t dataSizeBytes,  /* [in] size of the data in bytes */
+                 uint32_t *pTemp);        /* [in] pointer to the temp buffer of size >= register size. */
+
+/************************************************************************/
+/**
+ * @brief The function copies data from PKA register into uint8 buffer in big endianness order.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         PKA registers used: srcReg.
+ *         The size (in 32-bit words) of pTemp buffer is at least the data size,
+ *         in words (rounded up).
+ *
+ * @return  no return value
+ */
+void PkaCopyDataFromPkaRegToBe8Buff(
+            uint8_t  *pDst,      /* [out] pointer to the destination buffer of size >= sizeBytes. */
+            uint32_t  srcReg,    /* [in] virtual pointer to source PKA register. */
+            uint32_t  sizeBytes, /* [in] size of the data in PKA register in bytes */
+            uint32_t  *pTemp);   /* [in] pointer to the temp buffer of size (in bytes) >= sizeBytes. */
+
+
+/***********     PkiExecExpBe  function      **********************/
+/**
+ * @brief Executes the modular exponentiation using PKA.
+ *
+ *  The function input/output arrays are in big endianness order of bytes.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         PKA registers used: r0,r1,r2,r3,r4, r30,r31.
+ *         The size of the pOut and pTemp buffers is at least the modulus size.
+ *
+ * @return  no return value
+ */
+CCError_t  PkiExecModExpBe(
+                uint8_t *pOut,        /* [out] pointer to the exponentiation result with size,
+                                               equaled to modulus size in words (including leading zeros. */
+                uint8_t *pIn,         /* [in]  pointer to the input data. */
+                uint32_t inSizeBytes, /* [in]  input data size in words */
+                uint8_t *pMod,        /* [in]  pointer to the modulus. */
+                uint32_t modSizeBits, /* [in]  modulus size in bits */
+                uint8_t *pExp,        /* [in]  pointer to the exponent buffer. */
+                uint32_t expSizeBytes,/* [in]  exponent size in words. */
+                uint32_t *pTemp);     /* [in]  pointer to the temp buffer of size >= modulus size. */
+
+
+/***********     PkiExecExpLeW  function      **********************/
+/**
+ * @brief Executes modular exponentiation using PKA for LE input parameters.
+ *
+ *  The function input/output arrays are given as little endianness words arrays.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         All sizes aligned to 32-bit words, leading zeros are present if exist.
+ *         PKA registers used: r0,r1,r2,r3,r4, r30,r31.
+ *
+ * @return  no return value
+ */
+CCError_t  PkiExecModExpLeW(
+                uint32_t *pOut,        /* [out] pointer to the exponentiation result with size, equalled
+                                                to modulus size in words (including leading zeros). */
+                uint32_t *pIn,         /* [in]  pointer to the input data. */
+                uint32_t inSizeWords,  /* [in]  input data size in words */
+                uint32_t *pMod,        /* [in]  pointer to the modulus. */
+                uint32_t modSizeBits,  /* [in]  modulus size in bits */
+                uint32_t *pExp,        /* [in]  pointer to the exponent buffer. */
+                uint32_t expSizeWords);/* [in]  exponent size: should be <= modulus size (in words). */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_dbg.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_dbg.c
new file mode 100644
index 0000000..be2889b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_dbg.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mem.h"
+#include "cc_common_math.h"
+#include "pki.h"
+#include "pka_ec_wrst.h"
+#include "pka_error.h"
+#include "pki_dbg.h"
+
+/* temp buffers used for debugging of PKA operations */
+#if defined PKA_DEBUG && defined DEBUG
+
+uint32_t tempRes[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+uint32_t tempRes1[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+
+/***********     PkiDbgPrintReg  function     **********************/
+/**
+ * @brief The function prints label and PKA register as big endian bytes array.
+ *
+ * @author reuvenl (8/25/2013)
+ *
+ * @return  None
+ */
+void PkiDbgPrintReg(const char*  label,  /*!< [in] Label string. */
+                   const uint32_t reg)   /*!< [in] Register virt. pointer. */
+{
+        uint32_t tmp[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS] = {0};
+        uint32_t sizeBits;
+        uint32_t sizeBytes;
+        uint32_t sizeWords;
+        int32_t i;
+
+        if (reg > PKA_REG_T1) {
+                PKA_PRINTF("Can't print reg %d, reg is too big \n", reg);
+                exit(1);
+        }
+        sizeBits = PkaGetRegEffectiveSizeInBits(reg);
+        sizeBytes = CALC_FULL_BYTES(sizeBits);
+        sizeWords = CALC_FULL_32BIT_WORDS(sizeBits);
+        if ((sizeBytes > sizeof(tmp)) ||
+            ((sizeBits == 0) && (reg < PKA_REG_T0))) {
+                PKA_PRINTF("Can't print reg %d, size in %d\n", reg, sizeBytes);
+        }
+        PkaCopyDataFromPkaReg(tmp, sizeWords, reg);
+
+        PKA_PRINTF("%s [%d] ", label, sizeBits);
+        for (i=(sizeBytes - 1); i>=0; i--) {
+                PKA_PRINTF("%02X", ((uint8_t*)tmp)[i] & 0xFF);
+        }
+        PKA_PRINTF("\n");
+}
+
+
+/***********     PkiDbgPrintUint32BuffAsNum  function     **********************/
+/**
+ * @brief This The function prints the label and 32-bit words buffer (LS-word is
+ *  a left most) as a big hexadecimal number (MS-digit is a left most).
+ *
+ * @author reuvenl (8/25/2013)
+ *
+ * @return  None
+ */
+void PkiDbgPrintUint32BuffAsNum(const char     *label, /*!< [in] Label string. */
+                     const uint32_t *pBuf,  /*!< [in] 32-bit words buffer to print. */
+                     uint32_t  sizeWords)   /*!< [in] size of pBuff in 32-bit words. */
+{
+        uint32_t sizeBits;
+        int32_t i;
+
+        sizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(pBuf, sizeWords);
+
+        PKA_PRINTF("%s [%d] ", label, sizeBits);
+        for (i=(sizeWords - 1); i>=0; i--) {
+                PKA_PRINTF("%08X", pBuf[i]);
+        }
+        PKA_PRINTF("\n");
+}
+
+/***********     PkiDbgPrintUint8BuffAsNum  function     **********************/
+/**
+ * @brief This The function prints the label and bytes array (LS-byte is
+ *  a left most) as a big hexadecimal number (MS-digit is a left most).
+ *
+ * @author reuvenl (14/02/2016)
+ *
+ * @return  None
+ */
+void PkiDbgPrintUint8BuffAsNum(const char     *label, /*!< [in] Label string. */
+                     const uint8_t *pBuf,  /*!< [in] 32-bit words buffer to print. */
+                     uint32_t  sizeBytes)   /*!< [in] size of pBuff in 32-bit words. */
+{
+        uint32_t sizeBits;
+        int32_t i;
+
+        sizeBits = CC_CommonGetBytesCounterEffectiveSizeInBits(pBuf, sizeBytes);
+
+        PKA_PRINTF("%s [%d] ", label, sizeBits);
+        for (i=(sizeBytes - 1); i>=0; i--) {
+                PKA_PRINTF("%02X", pBuf[i]);
+        }
+        PKA_PRINTF("\n");
+}
+
+/***********     PkiDbgPrintUintBuf  function     **********************/
+/**
+ * @brief This The function prints the label and bytes array as string.
+ *
+ * @author reuvenl (14/02/2016)
+ *
+ * @return  None
+ */
+void PkiDbgPrintUint8Buff(const char     *label, /*!< [in] Label string. */
+                     const uint8_t *pBuf,  /*!< [in] 32-bit words buffer to print. */
+                     uint32_t  sizeBytes)   /*!< [in] size of pBuff in 32-bit words. */
+{
+        uint32_t sizeBits;
+        uint32_t i;
+
+        sizeBits = CC_CommonGetBytesCounterEffectiveSizeInBits(pBuf, sizeBytes);
+
+        PKA_PRINTF("%s [%d] ", label, sizeBits);
+        for (i=0; i<sizeBytes; i++) {
+                PKA_PRINTF("%02X", pBuf[i]);
+        }
+        PKA_PRINTF("\n");
+}
+#endif
+
+#if defined PKA_DEBUG && defined DEBUG
+/***********    PkiDbgExecOperation (with virtual pointers)     ******************/
+/**
+ * @brief This function executes any allowed PKA mathematic operation according to
+ *        user passed Opcode.
+ *
+ *        The function receives code of operation, virtual pointers to PKI registers
+ *        (sequence number), for arguments and result, and operates PKA machine by writing
+ *        full operation code into OPCODE register. Then the function calls macros for
+ *        waiting the PKA pipe ready signal.
+ *        If opcode is illegal or one of operands is illegal, the function returns an
+ *        error code defined in pka_error.h file.
+ *
+ *        The user don't call this function directly. For user convenience, in llf_pki.h file  are
+ *        given some macros for calling this function according to each performed operation.
+ *
+ *     NOTES:
+ *       -  Before executing modular operations, the modulus must be set into N=r0 register of PKA.
+ *       -  Before modular multiplication and exponentiation must be calculated and set into NP=r1
+ *          register the Barrett modulus tag NP = 2**(sizeN+132) / N.
+ *       -  In operations with immediate operands (IsImmediate bit = 1), the operand value (5-bit)
+ *          is treated as sign-extended. That means: low 4 bits are treated as unsigned operand
+ *          value in range 0-15 and bit 5 is a sign (with extension to all high bits of register,
+ *          in which the full operand shall be set).
+ *       -  In shift operations the 5-bits shift operand is treated as unsigned value in range 0-31
+ *          (count of shifts is equaled to shift operand value + 1).
+ *       -  The LMul operation gives the low half of multiplication result of length equaled to
+ *          operation size. The leading not significant bits of the operands and result (including
+ *          the the extra word) must be zeroed.
+ *       -  The HMul operation gives the high half of multiplication result plus one high word of low
+ *          half of full multiplication result. Therefore this result is by one word large, than
+ *          operation size. The leading not significant bits of the operands and result,
+ *          including extra word must be zeroed.
+ *       -  The ModInv operation calculates Res = 1/OpB mod N for odd modulus. Operand A is ignored.
+ *          In case of even modulus the function returns an error. Therefore in this case
+ *          (also for odd modulus) the user may call the PkaExecFullModInv function.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t PkiDbgExecOperation(uint32_t       Opcode,      /*!< [in] The operation code according HW PKA definitions. Valid values: 0 - max Opcode. */
+                               uint32_t       lenId,        /*!< [in] ID of the length of operands according to register sizes table
+                                    (means the number of entry in the table). Valid values: 0...7. */
+                               uint32_t       isAImmed,     /*!< [in] If isBImmed = 1, then operand A treated as immediate value, else -
+                                    as virtual register pointer. Valid values:0,1. */
+                               uint32_t       OpA,          /*!< [in] Operand A: an immediate value or virtual register pointer,
+                                    according to isAImmed parameter. */
+                               uint32_t       isBImmed,     /*!< [in] If isBImmed = 1, then operand B treated as immediate value, else -
+                                    as virtual register pointer. Valid values:0,1. */
+                               uint32_t       OpB,          /*!< [in] Operand B: an immediate value or virtual register pointer,
+                                    according to isBImmed parameter. */
+                               uint32_t       ResDiscard,   /*!< [in] If ResDiscard = 1, then result is discarded. */
+                               uint32_t       Res,          /*!< [Out] Virtual register pointer for result data.
+                                    Value Res = RES_DISCARD means result must be discarded. */
+                               uint32_t       Tag )         /*!< [in] The user defined value (Tag <= 31), used for indication goals. */
+
+{
+        CCError_t Error = CC_OK;
+        uint32_t FullOpCode;
+        uint32_t status;
+        uint8_t  OpPrint;
+        uint32_t opSizeInBits, RegSizeWords;
+
+        /* if Res == RES_DISCARD , then result is discarded */
+        if (Res == (int8_t)RES_DISCARD) {
+                ResDiscard = 1;
+                Res = 0;
+        }
+
+        /* set operation size according to lenId+1 for debug copy and clearing registers */
+        if (lenId == LEN_ID_MAX_BITS) {
+                PKA_GET_REG_SIZE(opSizeInBits, LEN_ID_MAX_BITS);
+        } else if (lenId & 1) {
+                PKA_GET_REG_SIZE(opSizeInBits, lenId);
+        } else {
+                PKA_GET_REG_SIZE(opSizeInBits, lenId+1);
+        }
+
+        RegSizeWords = PKA_WORD_SIZE_IN_32BIT_WORDS*((opSizeInBits+CC_PKA_WORD_SIZE_IN_BITS-1)/CC_PKA_WORD_SIZE_IN_BITS);
+
+        /*************************************************/
+        /*      check input parameters                   */
+        /*************************************************/
+
+        if (Opcode  > PKA_MAX_OPCODE) {
+                Error =  PKA_ILLEGAL_OPCODE_ERROR;
+                goto End;
+        }
+
+        if (lenId >= LEN_ID_MAX) {
+                Error = PKA_ILLEGAL_OPERAND_LEN_ERROR;
+                goto End;
+        }
+
+        if (isAImmed   > 1 ||
+            isBImmed   > 1 ||
+            ResDiscard > 1) {
+                Error = PKA_ILLEGAL_OPERAND_TYPE_ERROR;
+                goto End;
+        }
+
+        if ((OpA >  31)      ||
+            (OpB >  31)      ||
+            (Res >  31)      ||
+            (Tag >  31)) {
+                Error = PKA_ILLEGAL_OPERAND_ERROR;
+                goto End;
+        }
+
+        /* for ModInv and Div operation check, that modulus or divider are not 0 */
+        if (Opcode == PKA_OPCODE_ID_MODINV || Opcode == PKA_OPCODE_ID_DIVISION) {
+                int8_t OpT;  /* number of register to test its Value = 0 */
+
+                /* Set OpT: 0 - for ModInv, OpB - for Div */
+                if (Opcode == PKA_OPCODE_ID_MODINV) {
+                        Error = PKA_MODULUS_IS_NULL_ERROR;
+                        OpT = 0;
+                } else {
+                        Error = PKA_DIVIDER_IS_NULL_ERROR;
+                        OpT = OpB;
+                }
+
+                /* Create full opcode word for add immediate 0 operation */
+                FullOpCode = PKA_SET_FULL_OPCODE(PKA_OPCODE_ID_ADD, lenId,0/*isAImmed*/,OpT/*N*/,1,0/*imm 0*/,1/*ResDiscard*/,0/*dumm*/,Tag);
+
+                /* write full opcode into PKA OPCODE register */
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL,OPCODE), FullOpCode);
+
+                /* test zero bit of STATUS register */
+                PKA_GET_STATUS_ALU_OUT_ZERO(status);
+                if (status == 1)
+                        goto End;
+                else
+                        Error = CC_OK;
+        }
+
+        /* for ModInv operation check, that OpB is odd, else return Error (can't calculate,
+           the user must use other function) */
+        if (Opcode == PKA_OPCODE_ID_MODINV) {
+                /* Create full opcode word for Test bit 0 operation */
+                FullOpCode = PKA_SET_FULL_OPCODE(PKA_OPCODE_ID_AND, lenId, 0/*isAImmed*/, 0/*N*/, 1, 1/*imm 1*/, 1/*ResDiscard*/, 0/*dumm*/, Tag);
+
+                /* write full opcode into PKA OPCODE register */
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, OPCODE), FullOpCode);
+
+                /* test zero bit of STATUS register */
+                PKA_GET_STATUS_ALU_OUT_ZERO(status);
+
+                if (status == 1) {
+                        Error = PKA_MOD_EVEN_USE_OTHER_FUNC_ERROR;
+                        goto End;
+                }
+        }
+
+
+        /*************************************************/
+        /*      main PKI operation of this function      */
+        /*************************************************/
+
+        FullOpCode = PKA_SET_FULL_OPCODE(Opcode, lenId, isAImmed, OpA, isBImmed, OpB, ResDiscard, Res, Tag);
+        PKA_WAIT_ON_PKA_PIPE_READY();
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, OPCODE), FullOpCode);
+
+
+        /*************************************************/
+        /* finishing operations for different cases      */
+        /*************************************************/
+        if (Opcode == PKA_OPCODE_ID_DIVISION) {
+                /* for Div operation check, that OpB != 0, else return Error */
+                PKA_GET_STATUS_DIV_BY_ZERO(status);
+                if (status == 1) {
+                        Error = PKA_DIVIDER_IS_NULL_ERROR;
+                        goto End;
+                }
+        }
+
+        /* wait for PKA done bit */
+        PKA_WAIT_ON_PKA_DONE();
+
+        /* if operation Tag = Print, then copy result into tempRes buffer */
+        if (1/*Tag == PKA_TAG_DebugPtint*/ &&
+            ResDiscard == 0 && Opcode != PKA_OPCODE_ID_TERMINATE && Opcode != PKA_OPCODE_ID_SEPINT) {
+                CC_PalMemSetZero(tempRes, sizeof(tempRes));
+                PkaCopyDataFromPkaReg(tempRes/*dst_ptr*/, RegSizeWords, Res/*srcReg*/);
+
+                if (Opcode == PKA_OPCODE_ID_DIVISION || Opcode == PKA_OPCODE_ID_MODINV) {
+                        if (Opcode == PKA_OPCODE_ID_DIVISION)
+                                OpPrint = OpA;
+                        else
+                                OpPrint = OpB;
+
+                        PkaCopyDataFromPkaReg(tempRes1/*dst_ptr*/, RegSizeWords, OpPrint/*srcReg*/);
+                }
+        }
+
+        End:
+
+        return Error;
+
+}
+
+#endif /* #if PKA_EXEC_OP_DEBUG */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_dbg.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_dbg.h
new file mode 100644
index 0000000..8d2088e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_dbg.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef PKI_DBG_H
+#define PKI_DBG_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "pka_hw_defs.h"
+#include "cc_pal_abort.h"
+
+
+#ifdef GMP_DEBUG
+#include "gmp-utils.h"
+#endif
+
+#if defined PKA_DEBUG && defined DEBUG
+
+#include <stdio.h>
+#include "cc_pal_abort.h"
+#define PKA_PRINTF printf
+#define ASSERT(x)  if(!(x)) {CC_PalAbort(x);}
+#define PKA_ASSERT(x, string) if(!(x)) {CC_PalAbort(string);}
+
+        /* if the value is defined, then debug printing is performed
+        in the parts of code, where the global variable gDoDebugPrint
+        is set to 1 in run time */
+        //#define DBG_PRINT_ON_FAIL_ONLY 1
+        //#define USE_GMP_TEST_DEBUG_BUFFER 1
+        //#define ECC_DEBUG 1
+
+        /* reference to temp buffers used for debugging of PKA operations */
+        extern uint32_t tempRes[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+        extern uint32_t tempRes1[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
+
+void PkiDbgPrintReg(
+                  const char*  label,
+                  const uint32_t reg);
+
+void PkiDbgPrintUint32BuffAsNum(
+                  const char     *label,
+                  const uint32_t *pBuf,
+                  uint32_t  sizeWords);
+
+void PkiDbgPrintUint8BuffAsNum(const char     *label,
+                     const uint8_t *pBuf,
+                     uint32_t  sizeBytes);
+void PkiDbgPrintUint8Buff(const char     *label,
+                     const uint8_t *pBuf,
+                     uint32_t  sizeBytes);
+
+CCError_t PkiDbgExecOperation(uint32_t       Opcode,
+            uint32_t       lenId,
+            uint32_t       isAImmed,
+            uint32_t       OpA,
+            uint32_t       isBImmed,
+            uint32_t       OpB,
+            uint32_t       ResDiscard,
+            uint32_t       Res,
+            uint32_t       Tag);
+
+/* Special debug prints */
+#define PKA_START_FUNC printf("\n[ %s\n",  __func__)
+#define PKA_FINISH_FUNC printf("] %s\n",  __func__)
+#define PPR(reg) printf(#reg); PkiDbgPrintReg("=",reg)
+#define PPB(buf, size) {printf(#buf); PkiDbgPrintUint32BuffAsNum("=", buf, size);}
+/* macro for printing one PKA register */
+#define PKI_DBG_PRINT_REG(label, reg) \
+     do{PKA_PRINTF("%s",label);       \
+        PkiDbgPrintReg(#reg"=",reg); } while (0)
+/* macro for printing up to 4 PKA regs; if some regs not need,  *
+*  then set value RES_DISCARD                                   */
+#define PKI_DBG_PRINT_REGS(label, reg1, reg2, reg3, reg4) \
+     do{PKA_PRINTF("%s",label);                           \
+        if(reg1<32) PkiDbgPrintReg(#reg1"=",reg1);        \
+        if(reg2<32) PkiDbgPrintReg(#reg2"=",reg2);        \
+        if(reg3<32) PkiDbgPrintReg(#reg3"=",reg3);        \
+        if(reg4<32) PkiDbgPrintReg(#reg4"=",reg4);} while(0)
+
+/***************************************/
+#else  // not PKA_DEBUG
+
+#define PkiDbgPrintReg(label, reg)
+#define PkiDbgPrintUint32BuffAsNum(label, pBuf, sizeWords)
+#define PkiDbgPrintUint8BuffAsNum(label, pBuf, sizeBytes)
+#define PkiDbgPrintUint8Buff(label, pBuf, sizeBytes)
+
+#define PKA_PRINTF(format, ...)  do{}while(0)
+#define ASSERT(x)  do{}while(0)
+#define PKA_ASSERT(x, string)
+
+#define PKA_START_FUNC
+#define PKA_FINISH_FUNC
+#define PPR(reg)
+#define PPB(buf,size)
+#define PKI_DBG_PRINT_REGS(label, reg1, reg2, res3, reg4)
+#define PKI_DBG_PRINT_REG(label, reg)
+
+#endif /* end of if/else PKA_DEBUG */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_modular_arithmetic.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_modular_arithmetic.c
new file mode 100644
index 0000000..3964b8e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_modular_arithmetic.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "pka.h"
+#include "ec_wrst.h"
+#include "pki.h"
+#include "pki_modular_arithmetic.h"
+
+#include "pki_dbg.h"
+/* virt. pointers to pka regs. (regs. ID-s)*/
+#include "pka_point_compress_regs_def.h"
+
+
+
+/***********     PkiCalcJacobiSymbol  function     **********************/
+/**
+ * @brief Calculate Jacobi symbol for a and prime b numbers.
+ *  Assumed: a, b are a positive numbers.
+ *  Note: PKA_REG_A, PKA_REG_B registers are destroed by the function.
+ *
+ * @author reuvenl (10/26/2014)
+ *
+ * @return int32_t jacobi symbol value.
+ */
+int32_t PkiCalcJacobiSymbol(void)
+{
+    int32_t r,  t;
+    uint32_t stat, w, w1;
+
+
+    /* Note: Check GCD - not need because b - prime.
+       Convert a to  positive numbers - not need  */
+
+    /* case PKA_REG_A = 0 or PKA_REG_A = 1 */
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, 0, stat); /*if(a==0) r = 0*/
+    if(stat == 1) {
+        r = 0;
+        goto End;
+    }
+
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, 1, stat); /*if(a==0) r = 0*/
+    if(stat == 1) {
+        r = 1;
+        goto End;
+    }
+
+    r = 1;
+
+    /* Evaluate Jacobi symb. */
+    do {
+        /* 1. Remove 0-LS bits of PKA_REG_A */
+         t = 0;
+         w = 0;
+
+         while(w == 0) {/* remove 0- words */
+            PKA_READ_WORD_FROM_REG(w, 0, PKA_REG_A);
+            if(w == 0) {
+                PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, PKA_REG_A, 32-1);
+                t += 32;
+            }
+         }
+
+         while((w & 1) == 0){
+            w >>= 1;
+            t += 1;
+         }
+         if((t & 0x1F) != 0) {/* removes 0-bits */
+            PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, PKA_REG_A, (t & 0x1F) - 1);
+         }
+
+         /* 2. Change sign if b mod 8 == 3 or 5 */
+         PKA_READ_WORD_FROM_REG(w1, 0, PKA_REG_B);
+
+         if(t & 1) {
+            if((w1 & 7) == 3 || (w1 & 7) == 5)
+                r = -r;
+         }
+
+         /* 3. Quadratic reciprocity law */
+         if((w & 3) == 3 && (w1 & 3) == 3){
+             r = -r;
+         }
+
+         PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_C, PKA_REG_A);
+         PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, PKA_REG_B);
+         PKA_DIV(LEN_ID_N_PKA_REG_BITS, PKA_REG_B, PKA_REG_A, PKA_REG_C);  /* a = b mod a */
+         PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_B, PKA_REG_C);     /* b = a prev. */
+
+         PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, 0, stat);
+
+    } while(stat != 1); /*while a != 0*/
+End:
+
+return r;
+
+} /* End of PkiCalcJacobiSymbol*/
+
+
+/***********     PkiIsModSquareRootExists  function     **********************/
+/**
+ * @brief The function calculates square root modulo prime:
+ *   PKA_REG_Y1 = PKA_REG_Y2 ^ 1/2 mod rP if root exists, else returns an error.
+ *
+ *   Assuming: 1. The modulus N is a prime.
+ *             2. Y2 is less than modulus.
+ *
+ * @return true if the root exists, or false if not.
+ */
+bool PkiIsModSquareRootExists(void)
+{
+    uint32_t w=0, stat;
+    int32_t s, i;
+    bool rootEx = false;
+    int32_t jcb;
+
+
+    /* if Y^2 = 0, return Y=0 */
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y2, 0, stat);
+    if(stat == 1){
+        PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y1); /* Y1=0*/
+        rootEx = true;
+        goto End;
+    }
+
+    /* read w = mod[0]*/
+    PKA_READ_WORD_FROM_REG(w, 0/*i*/, PKA_REG_N);
+
+    /* ----------------------------------------- */
+    /* Case P=3 mod 4, then PKA_REG_Y1 = +- PKA_REG_Y2^(P+1)/4 */
+    /* ----------------------------------------- */
+    if((w & 0x3) == 3) {
+        PKA_ADD_IM(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y1, PKA_REG_N, 1);
+        PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, PKA_REG_Y1, 2-1);
+        PKA_MOD_EXP(LEN_ID_N_BITS, PKA_REG_Y1, PKA_REG_Y2, PKA_REG_T);
+        goto End;
+    }
+
+    /* ------------------------------------------------ */
+    /* Case P=5 mod 8, then PKA_REG_Y1 calculated by algorithm */
+    /* ------------------------------------------------ */
+    if((w & 0x7) == 5) {
+        PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, PKA_REG_YT, PKA_REG_N, 1);  /* PKA_REG_YT = PKA_REG_N-1*/
+        PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_Z, PKA_REG_YT, 2-1);
+        PKA_MOD_EXP(LEN_ID_N_BITS, PKA_REG_T, PKA_REG_Y2, PKA_REG_Z);   /* d = PKA_REG_T = PKA_REG_Y2^((PKA_REG_N-1)/4)*/
+        PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, 1, stat);
+        if(stat == 1) {
+            PKA_ADD_IM(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, PKA_REG_N, 3);
+            PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, PKA_REG_T, 3-1);
+            PKA_MOD_EXP(LEN_ID_N_BITS, PKA_REG_Y1, PKA_REG_Y2, PKA_REG_T);
+        }
+        else {
+            PKA_COMPARE_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, PKA_REG_YT, stat);  /* PKA_REG_T =? PKA_REG_N-1*/
+            if(stat == 1) {
+                PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, PKA_REG_N, 5);
+                PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, PKA_REG_T, 3-1);
+                PKA_SHL_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_YT, PKA_REG_Y2, 2-1);  /* PKA_REG_YT = 4*PKA_REG_Y2 */
+                PKA_MOD_EXP(LEN_ID_N_BITS, PKA_REG_Z, PKA_REG_YT, PKA_REG_T);
+                PKA_SHL_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_YT, PKA_REG_Y2, 1-1);  /* PKA_REG_YT = 2*PKA_REG_Y2 */
+                PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_Y1, PKA_REG_Z, PKA_REG_YT);   /* PKA_REG_Y1 = 2*PKA_REG_Y2*(4rY2)^((PKA_REG_N-5)/8) */
+            }
+        }
+
+        goto End;
+    }
+
+
+    /* --------------------------------- */
+    /* Case of other modulus structure   */
+    /* --------------------------------- */
+
+    /* check if root exist using jacoby symbol */
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, PKA_REG_Y2);
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_B, PKA_REG_N);
+    jcb = PkiCalcJacobiSymbol(/*, PKA_REG_A, PKA_REG_B*/);
+    if(jcb == -1)
+        goto End;
+
+    /* state P-1 as Q * 2^s, where Q is odd */
+    PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y1, PKA_REG_N, 1);  /**/
+    w -= 1;
+    s = 0;
+    while(w == 0) { /*remove 0-words*/
+        PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y1, PKA_REG_Y1, 32-1);
+        s += 32;
+        PKA_READ_WORD_FROM_REG(w, 0/*i*/, PKA_REG_Y1);
+    }
+    /* remove 0-bits */
+    i = 0;
+    while((w & 1) == 0){
+        w >>= 1;
+        i++;
+    }
+    s += i;
+    if(i > 0)
+        PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y1, PKA_REG_Y1, i-1);
+
+    /* find first non residue number (modulo N) starting from 2 */
+    jcb = 0;
+    PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, PKA_REG_Z);
+    PKA_SET_BIT0(LEN_ID_N_PKA_REG_BITS, PKA_REG_Z, PKA_REG_Z); /* z = 1*/
+    while (jcb != -1) {
+        PKA_ADD_IM(LEN_ID_N_PKA_REG_BITS, PKA_REG_Z, PKA_REG_Z, 1);
+
+        /*set jacoby input values */
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_A, PKA_REG_Z);
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_B, PKA_REG_N);
+        jcb = PkiCalcJacobiSymbol(/*, PKA_REG_A, PKA_REG_B*/);
+    }
+
+    PKA_MOD_EXP(LEN_ID_N_BITS, PKA_REG_Z, PKA_REG_Z, PKA_REG_Y1); /* */
+    PKA_ADD_IM(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y1, PKA_REG_Y1, 1);
+    PKA_SHR_FILL0(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y1, PKA_REG_Y1, 1-1);  /* PKA_REG_Y1 = (PKA_REG_Y1+1)/2  */
+    PKA_MOD_EXP(LEN_ID_N_BITS, PKA_REG_Y1, PKA_REG_Y2, PKA_REG_Y1);  /* PKA_REG_Y1 = PKA_REG_Y2^PKA_REG_Y1  */
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, PKA_REG_YT, PKA_REG_Y2);
+    PKA_MOD_INV(LEN_ID_N_BITS, PKA_REG_T, PKA_REG_YT);
+    for(;;) {
+        PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_YT, PKA_REG_Y1, PKA_REG_Y1);   /* PKA_REG_YT = PKA_REG_Y1^2  */
+        PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_YT, PKA_REG_YT, PKA_REG_T);    /* PKA_REG_YT = PKA_REG_YT * PKA_REG_Y2^-1  */
+        i = 0;
+        while(1) {
+            /*if(PKA_REG_YT == 1) break;*/
+            PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_YT, 1, stat);
+            if(stat == 1)
+                break;
+            i++;
+            PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_YT,PKA_REG_YT, PKA_REG_YT);    /* PKA_REG_YT = PKA_REG_YT^2 */
+        }
+        /* if PKA_REG_Y1^2 * PKA_REG_Y2^-1 == 1 (mod rP), return */
+        if(i == 0) {
+            rootEx = true;
+            goto End;
+        }
+        if(s-i == 1) { /* mul instead pow */
+            PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_Y1, PKA_REG_Y1, PKA_REG_Z);
+        } else {
+            w  =  1 << ((s-i-1) & 31);
+            i = (s-i-1) / 32; /*i was free*/
+            PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, PKA_REG_EX);
+            PKA_WRITE_WORD_TO_REG(w, i, PKA_REG_EX);
+            PKA_MOD_EXP(LEN_ID_N_BITS, PKA_REG_YT, PKA_REG_Z, PKA_REG_EX);
+            PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_Y1, PKA_REG_Y1, PKA_REG_YT);   /* PKA_REG_Y1 = r * PKA_REG_Z^(2^(s-i-1)) */
+        }
+    }
+End:
+    /* Check result for PKA_REG_N mod 8 = {3,5} */
+    if((w & 3) == 3 || (w & 7) == 5){
+        PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_T, PKA_REG_Y1, PKA_REG_Y1);
+        PKA_COMPARE_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_T, PKA_REG_Y2, stat);
+        if(stat == 1)
+            rootEx = true;
+    }
+
+    return rootEx;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_modular_arithmetic.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_modular_arithmetic.h
new file mode 100644
index 0000000..c161eb9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/common/pki_modular_arithmetic.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _PKI_MODULAR_ARITHMETIC_H
+#define _PKI_MODULAR_ARITHMETIC_H
+
+#include "cc_pal_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+int32_t PkiCalcJacobiSymbol(void);
+bool PkiCalcModSquareRoot(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw.c
new file mode 100644
index 0000000..fb27325
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw.c
@@ -0,0 +1,846 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mutex_plat.h"
+#include "cc_hal_plat.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_error.h"
+#include "cc_ec_edw_api.h"
+#include "mbedtls_cc_ec_mont_edw_error.h"
+
+#include "pka_hw_defs.h"
+#include "pka_defs.h"
+#include "ec_edw_local.h"
+#include "pka.h"
+#include "pki.h"
+#include "pka_error.h"
+#include "ec_edw.h"
+#include "pka_ec_edw_glob_regs_def.h"
+
+#include "pki_dbg.h"
+#include "cc_int_general_defs.h"
+#include "cc_general_defs.h"
+#include "md.h"
+
+/* global data definitions */
+extern CC_PalMutex CCAsymCryptoMutex;
+
+
+/*********************************************************************/
+/*!
+@brief The function performs EC Edwards key pair generation using seed.
+
+       Libsodium analog: crypto_sign_ed25519_seed_keypair() function
+
+ @return CCError_t
+*/
+CCError_t EcEdwSeedKeyPair(
+                               uint8_t *pPublKey,                    /*!< [out] a pointer to publickey (compressed,
+                                                                           the size = ec modulus size) */
+                               uint8_t *pSecrKey,                    /*!< [out] a pointer to secret key, stated as concatenation
+                                                                          of seed amd public key (the size = 2 * ec modulus size) */
+                               const uint8_t  *pSeed,                /*!< [in] a pointer to the seed (the size = ec order size) */
+                               const CCEcEdwDomain_t *pEcDomain,   /*!< [in] pointer to EC domain (curve). */
+                               uint32_t *pTempBuff)             /*!< [in] pointer to the temp buffer. */
+{
+        CCError_t err = CC_OK;
+        uint32_t pkaRegsUsed;
+        uint32_t edwSizeWords = pEcDomain->ecModSizeInWords;
+        uint32_t edwSizeBytes = edwSizeWords * sizeof(uint32_t);
+
+        /* set pointers to temp buffers */
+        uint32_t *pPrivKey32/*az*/ = pTempBuff;
+        uint32_t *pPublKey32/*az*/ = pPrivKey32 + edwSizeWords;
+        uint32_t *pCoordX32/*az*/ = pPublKey32 + edwSizeWords;
+        const mbedtls_md_info_t *md_info=NULL;
+
+        /* get the hardware semaphore  */
+        err = CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE);
+        if (err != CC_SUCCESS) {
+                CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* verify that the device is not in fatal error state before activating the PKA engine */
+        CC_IS_FATAL_ERR_ON(err);
+        if (err == CC_TRUE) {
+                /* release the hardware semaphore */
+                if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != CC_SUCCESS) {
+                        CC_PalAbort("Fail to release mutex\n");
+                }
+                return PKA_FATAL_ERR_STATE_ERROR;
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        err = CC_IS_WAKE;
+        if (err != CC_SUCCESS) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* init PKA, mapping and sizes tables */
+        pkaRegsUsed = 30;
+        err = PkaInitPka(pEcDomain->ecModSizeInBits, 0/*edwSizeWords*/,
+                         &pkaRegsUsed/*regs.count*/);
+
+        if (err != CC_SUCCESS) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+
+        /* calculate private key from seed (first half of SignSecrKey) */
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[CC_HASH_SHA512_mode] );
+        if (NULL == md_info) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+        err = mbedtls_md(md_info,
+                         (uint8_t*)pSeed,
+                         edwSizeBytes,
+                        (unsigned char *)pPrivKey32);
+        if (err != CC_OK) {
+                goto End;
+        }
+
+        pPrivKey32[0] &= 0xFFFFFFF8;              // & 248;
+        pPrivKey32[edwSizeWords-1] &=  0x3FFFFFFF;// & 63;
+        pPrivKey32[edwSizeWords-1] |=  0x40000000;// | 64;
+
+        /* call EC scalar multiplication function */
+        err = EcEdwSpecialScalarMultBase(
+                                pCoordX32, /*coord.X*/
+                                pPublKey32,/*coord.Y*/
+                                pPrivKey32,
+                                edwSizeWords,
+                                pEcDomain);
+        if (err)
+                goto End;
+
+
+        /* set high bit of Y */
+        pPublKey32[edwSizeWords-1] |= ((pCoordX32[0] & 1) << 31);
+
+        /* results output */
+        CC_PalMemCopy(pSecrKey, pSeed, edwSizeBytes);
+        CC_CommonConvertLswMswWordsToLsbMsbBytes(pPublKey, pPublKey32, edwSizeWords);
+        CC_PalMemCopy(pSecrKey + edwSizeBytes, pPublKey, edwSizeBytes);
+
+End:
+        CC_PalMemSetZero(pTempBuff, 3*edwSizeBytes);
+        PkaFinishAndMutexUnlock(pkaRegsUsed);
+        return err;
+}
+
+/*********************************************************************/
+/*!
+ * The function performs input/output parameters for EC Edwards
+ * scalar multiplication.
+ *
+ *         resPoint(Y,_) = k*inPoint(X,Y), where:
+ *         the point is given with LE order of the words.
+ *
+ *         Assuming:
+ *              The PKA HW is turned ON and initialized yet;
+ *
+ * \return CCError_t
+ */
+CCError_t  EcEdwScalarMultBase(
+                                uint32_t  *pResPointX,             /*!< [out] a pointer (optional) to result EC point coordinate X. */
+                                uint32_t  *pResPointY,             /*!< [out] a pointer to result EC point coordinate Y. */
+                                uint32_t  *pScalar,                /*!< [in]  a pointer to the scalar. */
+                                size_t     scalarSizeWords,        /*!< [in]  the scalar size in words. */
+                                const CCEcEdwDomain_t *pEcDomain     /*!< [in]  a pointer to EC domain (curve). */)
+{
+
+        /* Definitions */
+
+        CCError_t err = CC_OK;
+        size_t edwSizeWords = pEcDomain->ecModSizeInWords;
+        size_t scalarSizeInBits;
+
+
+        /* Get exact scalar size in bits */
+        scalarSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(pScalar, scalarSizeWords);
+        if (scalarSizeInBits == 0)
+                return CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR;
+
+        /* ********************************************* */
+        /*   load needed data to defined pka registers   */
+        /* ********************************************* */
+
+        /*   pEcDomain modulus and Barr. tag */
+        PkaCopyDataIntoPkaReg(EDW_REG_N, LEN_ID_MAX_BITS, pEcDomain->ecModP, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_NP, LEN_ID_MAX_BITS, pEcDomain->ecModBarrTag,
+                              CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+        /* set precalculated points data: G,2G,4G  */
+        PkaCopyDataIntoPkaReg(EDW_REG_SG,   LEN_ID_MAX_BITS, pEcDomain->sg,   edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_DG,   LEN_ID_MAX_BITS, pEcDomain->dg,   edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_PG,   LEN_ID_MAX_BITS, pEcDomain->pg,   edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_MPG,  LEN_ID_MAX_BITS, pEcDomain->mpg,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_SG2,  LEN_ID_MAX_BITS, pEcDomain->sg2,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_DG2,  LEN_ID_MAX_BITS, pEcDomain->dg2,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_PG2,  LEN_ID_MAX_BITS, pEcDomain->pg2,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_MPG2, LEN_ID_MAX_BITS, pEcDomain->mpg2, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_SG4,  LEN_ID_MAX_BITS, pEcDomain->sg4,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_DG4,  LEN_ID_MAX_BITS, pEcDomain->dg4,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_PG4,  LEN_ID_MAX_BITS, pEcDomain->pg4,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_MPG4, LEN_ID_MAX_BITS, pEcDomain->mpg4, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_XG2,  LEN_ID_MAX_BITS, pEcDomain->xg2,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_YG2,  LEN_ID_MAX_BITS, pEcDomain->yg2,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_TG2,  LEN_ID_MAX_BITS, pEcDomain->tg2,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_XG4,  LEN_ID_MAX_BITS, pEcDomain->xg4,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_YG4,  LEN_ID_MAX_BITS, pEcDomain->yg4,  edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_TG4,  LEN_ID_MAX_BITS, pEcDomain->tg4,  edwSizeWords);
+        /* set D2 */
+        PkaCopyDataIntoPkaReg(EDW_REG_D2, LEN_ID_MAX_BITS, pEcDomain->ecAuxValD2, edwSizeWords);
+
+        /*--------------------------------------------------------------------*
+        * perform EC scalar multiplication:  used PKA registers defined in    *
+        *    "pka_ec_edw_glob_regs_def."h file; input - scalr;                *
+        *     output registers: EC_MONT_REG_YS and EDW_REG_XS                 *
+        *---------------------------------------------------------------------*/
+
+        /* used common scalarMult function; output regs:  *
+         *       x<-EDW_REG_SG, y<-EDW_REG_DG             */
+        err = PkaEcEdwScalarMultBase(pScalar, scalarSizeInBits);
+        if (err) {
+                goto End;
+        }
+
+        /* output result point: x,y */
+        PkaCopyDataFromPkaReg(pResPointX/*dst*/, edwSizeWords, EDW_REG_SG/*srcReg*/);
+        PkaCopyDataFromPkaReg(pResPointY/*dst*/, edwSizeWords, EDW_REG_DG/*srcReg*/);
+
+        End:
+        return err;
+}
+
+/*********************************************************************/
+/*!
+ * The function performs input/output parameters for EC Edwards scalar
+ * multiplication for special scalars.
+ *
+ *         resPoint(Y,_) = k*inPoint(X,Y), where:
+ *         the point is given with LE order of the words.
+ *
+ *         Assuming:
+ *              The PKA HW is turned on and initialized yet;
+ *
+ * \return CCError_t
+ */
+CCError_t  EcEdwSpecialScalarMultBase(
+                                       uint32_t  *pResPointX,             /*!< [out] a pointer to result EC point coordinate X. */
+                                       uint32_t  *pResPointY,             /*!< [out] a pointer to result EC point coordinate Y. */
+                                       uint32_t  *pScalar,                /*!< [in]  a pointer to the scalar. */
+                                       size_t     scalarSizeWords,         /*!< [in]  the scalar size in words. */
+                                       const CCEcEdwDomain_t *pEcDomain /*!< [in]  a pointer to EC domain (curve). */)
+{
+
+        /* Definitions */
+
+        CCError_t err = CC_OK;
+        size_t   edwSizeWords = pEcDomain->ecModSizeInWords;
+        size_t   scalarSizeBits;
+
+        /* Get exact scalar size in bits */
+        scalarSizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(pScalar, scalarSizeWords);
+        if (scalarSizeWords == 0)
+                return CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR;
+
+        /* ********************************************* */
+        /*   load needed data to defined pka registers   */
+        /* ********************************************* */
+
+        /*   pEcDomain modulus and Barr. tag */
+        PkaCopyDataIntoPkaReg(EDW_REG_N, LEN_ID_MAX_BITS, pEcDomain->ecModP, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_NP, LEN_ID_MAX_BITS, pEcDomain->ecModBarrTag,
+                              CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+        /* set precalculated points data: G,4G...32G,  */
+        PkaCopyDataIntoPkaReg(EDW_REG_SG4, LEN_ID_MAX_BITS, pEcDomain->sg4, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_DG4, LEN_ID_MAX_BITS, pEcDomain->dg4, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_PG4, LEN_ID_MAX_BITS, pEcDomain->pg4, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_MPG4, LEN_ID_MAX_BITS, pEcDomain->mpg4, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_SG8, LEN_ID_MAX_BITS, pEcDomain->sg8, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_DG8, LEN_ID_MAX_BITS, pEcDomain->dg8, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_PG8, LEN_ID_MAX_BITS, pEcDomain->pg8, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_MPG8, LEN_ID_MAX_BITS, pEcDomain->mpg8, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_SG16, LEN_ID_MAX_BITS, pEcDomain->sg16, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_DG16, LEN_ID_MAX_BITS, pEcDomain->dg16, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_PG16, LEN_ID_MAX_BITS, pEcDomain->pg16, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_MPG16, LEN_ID_MAX_BITS, pEcDomain->mpg16, edwSizeWords);
+        /* s = 32G*/
+        PkaCopyDataIntoPkaReg(EDW_REG_XS, LEN_ID_MAX_BITS, pEcDomain->xg32, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_YS, LEN_ID_MAX_BITS, pEcDomain->yg32, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_TS, LEN_ID_MAX_BITS, pEcDomain->tg32, edwSizeWords);
+        PKA_CLEAR(LEN_ID_MAX_BITS, EDW_REG_ZS);
+        PKA_SET_BIT0(LEN_ID_MAX_BITS, EDW_REG_ZS, EDW_REG_ZS);
+        /* set 4N */
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_N_4, EDW_REG_N, EDW_REG_N);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_N_4, EDW_REG_N_4, EDW_REG_N_4);
+        /* set D2 */
+        PkaCopyDataIntoPkaReg(EDW_REG_D2, LEN_ID_MAX_BITS, pEcDomain->ecAuxValD2, edwSizeWords);
+
+        /*--------------------------------------------------------------------*
+        * perform EC scalar multiplication:  used PKA registers defined in    *
+        *    "pka_ec_edw_glob_regs_def."h file; input - scalr;                *
+        *     output registers: EC_MONT_REG_YS and EDW_REG_XS                 *
+        *---------------------------------------------------------------------*/
+        /* use special (more fasted) scalarMult function */
+        err = PkaEcEdwSpecialScalarMultBase(pScalar, scalarSizeBits);
+
+        if (err) {
+                goto End;
+        }
+
+        /* output result point: X,Y */
+        PkaCopyDataFromPkaReg(pResPointX/*dst*/, edwSizeWords, EDW_REG_SG8/*srcReg*/);
+        PkaCopyDataFromPkaReg(pResPointY/*dst*/, edwSizeWords, EDW_REG_DG8/*srcReg*/);
+
+        End:
+        return err;
+}
+
+
+/**
+ * The function createss EC Edwards detatched signature on given message
+ *
+ * Implemented algorithm of Bernstein D. etc. sign ed25519 detached.
+ *
+ * @author reuvenl (1/21/2016)
+ *
+ * @return CCError_t
+ */
+CCError_t  EcEdwSign (
+                       uint8_t       *pEdwSign,             /*!< [out] - the pointer to the signature (detatched). */
+                       const uint8_t *pMsg,                 /*!< [in] - the pointer to the message. */
+                       size_t         msgSize,              /*!< [in] - the message size in bytes: it must be less, than
+                                                                 CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES. */
+                       const uint8_t *pSignSecrKey,         /*!< [in] - the pointer to the signer secret key, stated as
+                                                                 concatenation of the seed and public key) */
+                       const CCEcEdwDomain_t *pEcDomain,      /*!< [in] pointer to EDW EC domain (curve). */
+                       CCEcEdwTempBuff_t *pEcEdwSignTempBuff)   /*!< [in] pointer to the temp buffer. */
+{
+
+        CCError_t err = CC_OK;
+        size_t edwSizeWords = pEcDomain->ecOrdSizeInWords;
+        size_t edwSizeBytes = edwSizeWords * sizeof(uint32_t);
+        size_t hashSizeWords = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES / sizeof(uint32_t);
+        size_t sizeToHash, msgSize1;
+
+        /* set pointers to temp buffers */
+        uint32_t *pPrivKey = (uint32_t*)pEcEdwSignTempBuff; /*h1||h2 = hash(seed)*/
+        uint32_t *pEphPriv = pPrivKey + edwSizeWords; /*nonce*/
+        uint32_t *pSign = pEphPriv + edwSizeWords; /*h2 is placed there for hash*/
+        uint32_t *pHash = pSign + 2*edwSizeWords; /*second part of */
+        uint32_t *pIntegrVal/*hram*/ = pHash + CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS;
+
+        const mbedtls_md_info_t *md_info=NULL;
+        mbedtls_md_context_t *p_hash_ctx = NULL;
+
+        /*-------------------------------------------------*/
+        /*          Process signature calculation          */
+        /*-------------------------------------------------*/
+
+        /* 1. Calculate hash512(seed) = pPrivKey||h2 for private key (for h2 temporary used pEphPrivKy buff) */
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[CC_HASH_SHA512_mode] );
+        if (NULL == md_info) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+        err = mbedtls_md(md_info,
+                         (uint8_t*)pSignSecrKey,
+                         edwSizeBytes,
+                        (unsigned char *)pPrivKey);
+        if (err != CC_OK) {
+                goto End; // h1 = 32 bytes of hash(seed) ;
+        }
+
+        /* save privKey = h1 and set bits */
+        ((uint8_t*)pPrivKey)[0]  &= 248;
+        ((uint8_t*)pPrivKey)[edwSizeBytes-1] &= 63;
+        ((uint8_t*)pPrivKey)[edwSizeBytes-1] |= 64;
+
+        /* 2. Calculate a nonce for ephemeral priv. key:  hash(h2||msg)  */
+        /*---------------------------------------------------------------*/
+        p_hash_ctx = (mbedtls_md_context_t*)(pIntegrVal + 2*edwSizeWords);
+        mbedtls_md_init(p_hash_ctx);
+        err = mbedtls_md_setup(p_hash_ctx, md_info, 0); // 0 = HASH, not HMAC
+        if (err != CC_OK) {
+                goto End;
+        }
+        err = mbedtls_md_starts(p_hash_ctx);
+        if (err != CC_OK)
+                goto End;
+
+        if (msgSize == 0) {
+                sizeToHash = edwSizeBytes;
+                msgSize1 = 0;
+        } else {
+                if (msgSize <= CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES - edwSizeBytes) {
+                        CC_PalMemCopy((uint8_t*)pEphPriv + edwSizeBytes, pMsg, msgSize);
+                        sizeToHash = edwSizeBytes + msgSize;
+                        msgSize1 = 0;
+                } else {
+                        sizeToHash = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+                        CC_PalMemCopy((uint8_t*)pEphPriv + edwSizeBytes, pMsg, sizeToHash - edwSizeBytes);
+                        msgSize1 = msgSize - (sizeToHash - edwSizeBytes);
+                }
+        }
+        err = mbedtls_md_update(p_hash_ctx, (uint8_t*)pEphPriv/*h2*/, sizeToHash);
+        if (err != CC_OK) /*full block, padded by msg*/
+                goto End;
+
+        if (msgSize1 > 0) {
+                err = mbedtls_md_update(p_hash_ctx, (uint8_t*)pMsg+(sizeToHash - edwSizeBytes), msgSize1);
+                if (err != CC_OK)   /*remaining bytes of the msg*/
+                        goto End;
+        }
+        err = mbedtls_md_finish(p_hash_ctx, (unsigned char *)pEphPriv);
+        if (err != CC_OK)
+                goto End;
+
+        mbedtls_md_free(p_hash_ctx);
+        p_hash_ctx = NULL;
+
+        /*------------------------------------------*/
+        /*        PKA Initialization                */
+        /*------------------------------------------*/
+        /* get and lock the PKA hardware */
+        err = CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE);
+        if (err != CC_SUCCESS) {
+                CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* verify that the device is not in fatal error state before activating the PKA engine */
+        CC_IS_FATAL_ERR_ON(err);
+        if (err == CC_TRUE) {
+                /* release the hardware semaphore */
+                if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != CC_SUCCESS) {
+                        CC_PalAbort("Fail to release mutex\n");
+                }
+                return PKA_FATAL_ERR_STATE_ERROR;
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        err = CC_IS_WAKE;
+        if (err != CC_SUCCESS) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* init PKA mapping according to 2*EC modulus size  */
+        err = PkaInitPka(2*CC_BITS_IN_32BIT_WORD*edwSizeWords,
+                         0/*regSizeInPkaWords*/, NULL/*pRegsCount*/);
+        if (err != CC_SUCCESS) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+
+        /* 3. calculate reduced ephemer. priv. Key */
+        PkaCopyDataIntoPkaReg(EDW_REG_N, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecOrdN, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_EPH_PRIV, LEN_ID_N_PKA_REG_BITS, pEphPriv, hashSizeWords);
+        PKA_DIV(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5/*4*/, EDW_REG_EPH_PRIV/*24*/, EDW_REG_N/*0*/);
+        PkaCopyDataFromPkaReg(pEphPriv/*dst*/, edwSizeWords, EDW_REG_EPH_PRIV/*srcReg*/);
+
+        /* remapping of PKA registers and sizes for scalar mult. */
+        err = PkaInitPka(pEcDomain->ecModSizeInBits, pEcDomain->ecModSizeInWords, NULL);
+        if (err != CC_SUCCESS) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+
+        /* 4. calculate ephemer. public key */
+        err = EcEdwScalarMultBase(
+                                 pSign+edwSizeWords, /*Eph.Publ. X*/
+                                 pSign,              /*Eph.Publ. Y*/
+                                 pEphPriv,           /*Eph.Priv. key*/
+                                 edwSizeWords,       /*scalarSize*/
+                                 pEcDomain);         /*Ec Domain*/
+        if (err) {
+                goto End;
+        }
+
+        /* convert eph. public key to compressed: MSBit(Y) = LSBit(X) */
+        pSign[edwSizeWords-1] ^= ((pSign[edwSizeWords] & 1) << 31);
+
+        /* copy the user public key to the signature second half */
+        CC_PalMemCopy(((uint8_t*)pSign+edwSizeBytes), pSignSecrKey+edwSizeBytes, edwSizeBytes);
+
+        /* 5. concatenate data for integrity value: EphPublKey || userPublKey || Msg */
+        /*---------------------------------------------------------------------------*/
+
+        if (msgSize == 0) {
+                sizeToHash = 2*edwSizeBytes;
+                msgSize1 = 0;
+        } else {
+                if (msgSize <= CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES - 2*edwSizeBytes) {
+                        CC_PalMemCopy((uint8_t*)pSign + 2*edwSizeBytes, pMsg, msgSize);
+                        sizeToHash = 2*edwSizeBytes + msgSize;
+                        msgSize1 = 0;
+                } else {
+                        sizeToHash = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+                        CC_PalMemCopy((uint8_t*)pSign + 2*edwSizeBytes, pMsg, sizeToHash - 2*edwSizeBytes);
+                        msgSize1 = msgSize - 2*edwSizeBytes;
+                }
+        }
+
+        /* 6. calculate hash for integrity value */
+        p_hash_ctx = (mbedtls_md_context_t*)(pIntegrVal + 2*edwSizeWords);
+        mbedtls_md_init(p_hash_ctx);
+        err = mbedtls_md_setup(p_hash_ctx, md_info, 0); // 0 = HASH, not HMAC
+        if (err != CC_OK) {
+                goto End;
+        }
+        err = mbedtls_md_starts(p_hash_ctx);
+        if (err != CC_OK)
+                goto End;
+        err = mbedtls_md_update(p_hash_ctx, (uint8_t*)pSign, sizeToHash);
+        if (err != CC_OK)
+                goto End;
+
+        if (msgSize1 > 0) {
+                err = mbedtls_md_update(p_hash_ctx, (uint8_t*)pMsg+2*edwSizeBytes, msgSize1);
+                if (err != CC_OK)
+                        goto End;
+        }
+        err = mbedtls_md_finish(p_hash_ctx, (unsigned char *)pIntegrVal);
+        if (err != CC_OK)
+                goto End;
+
+        /* PKA registers remapping according to 2*EC order size  */
+        err = PkaInitPka(2*CC_BITS_IN_32BIT_WORD*edwSizeWords,
+                         0/*regSizeInPkaWords*/, NULL/*pRegsCount*/);
+        if (err != CC_SUCCESS) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+
+        /* 7. set data to PKA registers and reduce integrity value */
+        PkaCopyDataIntoPkaReg(EDW_REG_N, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecOrdN, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_INTEGR, LEN_ID_N_PKA_REG_BITS, pIntegrVal, hashSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_USER_PRIV, LEN_ID_N_PKA_REG_BITS, pPrivKey, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_EPH_PRIV, LEN_ID_N_PKA_REG_BITS, pEphPriv, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_NP, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecOrdBarrTag,
+                              CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+        PKA_DIV(LEN_ID_N_PKA_REG_BITS, EDW_REG_D2/*temp*/, EDW_REG_INTEGR, EDW_REG_N);
+
+        /* set sizes for modMul op. according to actual size of the EC order  */
+        PKA_WAIT_ON_PKA_DONE();
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_L0), pEcDomain->ecOrdSizeInBits);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_L0) + 4,
+                                edwSizeWords*CC_BITS_IN_32BIT_WORD + CC_PKA_WORD_SIZE_IN_BITS);
+
+
+        /* 8. calculation of the Edw. specific signature value edwSignVal */
+        /*----------------------------------------------------------------*/
+        PKA_MOD_MUL(LEN_ID_N_BITS, EDW_REG_SIGN/*res*/, EDW_REG_INTEGR, EDW_REG_USER_PRIV);
+        PKA_MOD_ADD(LEN_ID_N_BITS, EDW_REG_SIGN/*res*/, EDW_REG_SIGN, EDW_REG_EPH_PRIV);
+        /* output EdwSignVal from PKA  */
+        PkaCopyDataFromPkaReg(&pSign[edwSizeWords]/*dst*/, edwSizeWords, EDW_REG_SIGN/*srcReg*/);
+        CC_PalMemCopy(pEdwSign, pSign, 2*edwSizeBytes);
+
+        End:
+        if((md_info!=NULL) && (p_hash_ctx!=NULL)) {
+                mbedtls_md_free(p_hash_ctx);
+        }
+        CC_PalMemSetZero(pEcEdwSignTempBuff, sizeof(CCEcEdwTempBuff_t));
+        PkaFinishAndMutexUnlock(CC_INFINITE);
+
+        return err;
+}
+
+/*********************************************************************/
+/*!
+@brief The function performs two EC Edwards scalar multiplication and adding
+       of points:  resPoint = scalarA * Point(X,Y) + scalarB * BasePointG.
+
+       Assuming: - PKA is initialized yet (including setting N and NP in registers);
+                 - Input point may be given in uncompressed form (given both coord. X,Y)
+                   or in compressed form: coordinate Y only and LSBit of X on bit place,
+                   equalled to modulus size in bits (255 for ec25519).
+
+ @return CCError_t
+*/
+CCError_t EcEdwAddTwoScalarMult(
+                                 uint32_t *pResPoint,        /*!< [out] the pointer to the result point in compressed
+                                                                 form (coordinate Y, the size in bytes = ec modulus size). */
+                                 uint32_t *pScalarA,         /*!< [in] pointer to the scalarA, the size = ec modulus size in bytes). */
+                                 uint32_t *pPointY,          /*!< [in] a pointer to the input point coordinate Y - in uncompressed
+                                                                 form, if given coordinate X, or in compressed form if coordinate
+                                                                 X == NULL (the size of Y in bytes = ec modulus size). */
+                                 uint32_t *pPointX,          /*!< [in, optional] the pointer to input point coordinate X for uncompressed
+                                                                 form of point(the size of Y in bytes = ec modulus size). */
+                                 uint32_t *pScalarB,         /*!< [in] pointer to the scalarB, the size = ec modulus sizein bytes). */
+                                 const CCEcEdwDomain_t *pEcDomain /*!< [in] pointer to EC domain (curve). */)
+{
+        CCError_t err = CC_OK;
+        size_t edwSizeWords;
+        size_t scalarAsizeBits, scalarBsizeBits;
+        uint32_t isOddX = 0, shift;
+
+        /* count of bits for MS bit setting of Y coordinate */
+        shift = 31;
+
+        /* get bit sizes of scalars */
+        edwSizeWords = pEcDomain->ecModSizeInWords;
+        scalarAsizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits( pScalarA, edwSizeWords);
+        scalarBsizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits( pScalarB, edwSizeWords);
+
+        /*   pEcDomain modulus and Barr. tag and input point X,Y */
+        PkaCopyDataIntoPkaReg(EDW_REG_N, LEN_ID_MAX_BITS, pEcDomain->ecModP, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_NP, LEN_ID_MAX_BITS, pEcDomain->ecModBarrTag,
+                              CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+        /*--------------------------------------------------------------*/
+        /* decompression of input point, if given in compressed form    */
+        /*--------------------------------------------------------------*/
+        if (pPointX == NULL) {
+                /* load EC params data into PKA */
+                PkaCopyDataIntoPkaReg(EDW_REG_D, LEN_ID_MAX_BITS, pEcDomain->ecParamD, edwSizeWords);
+                PkaCopyDataIntoPkaReg(EDW_REG_Q58, LEN_ID_MAX_BITS, pEcDomain->ecAuxValQ58, edwSizeWords);
+                PkaCopyDataIntoPkaReg(EDW_REG_SQRTM1, LEN_ID_MAX_BITS, pEcDomain->ecAuxValSqrt_1, edwSizeWords);
+
+                /* extract LSBit of X from compressed Y */
+                isOddX = (pPointY[edwSizeWords-1] >> shift) & 1;
+                pPointY[edwSizeWords-1] &= ~(1UL << shift); /*clean MSBit in Y-buffer*/
+
+                /* load point coord. Y into PKA */
+                PkaCopyDataIntoPkaReg(EDW_REG_YP, LEN_ID_MAX_BITS, pPointY/*Y*/, edwSizeWords);
+
+                /* decompress input Point (in/out registers: EDW_REG_YP - in, EDW_REG_XP - out) */
+                PkaEcEdwDecompress(EDW_REG_XP, EDW_REG_YP, isOddX);
+
+        } else {
+                /* load point coord. X,Y data */
+                PkaCopyDataIntoPkaReg(EDW_REG_YP, LEN_ID_MAX_BITS, pPointY/*Y*/, edwSizeWords);
+                PkaCopyDataIntoPkaReg(EDW_REG_XP, LEN_ID_MAX_BITS, pPointX/*Y*/, edwSizeWords);
+        }
+
+        /* call EC scalar mult. add function with implicitly defined registers:
+           input aff. point P is in registers: (EDW_REG_XP, EDW_REG_YP)
+           output aff. point R is in registers: (EDW_REG_XR, EDW_REG_YR) */
+        err = PkaEcEdwAddTwoScalarMult(
+                                      EDW_REG_XR, EDW_REG_YR,
+                                      EDW_REG_XP, EDW_REG_YP,
+                                      pScalarA, scalarAsizeBits,
+                                      pScalarB, scalarBsizeBits,
+                                      pEcDomain);
+        if (err != CC_OK)
+                goto End;
+
+
+        /* output result point in compressed form Y */
+        PkaCopyDataFromPkaReg(pResPoint/*dst*/, edwSizeWords, EDW_REG_XR/*srcReg*/); /*X*/
+        /* get bit b'0 of XR */
+        PKA_READ_BIT0(LEN_ID_MAX_BITS, EDW_REG_XR, isOddX);
+        PkaCopyDataFromPkaReg(pResPoint/*dst*/, edwSizeWords, EDW_REG_YR/*srcReg*/); /*Y*/
+        /* set MSbit YR =  b'0 XR */
+        if(pPointX == NULL) {
+                pResPoint[edwSizeWords-1] |= (isOddX << shift);
+        }
+
+        End:
+        return err;
+}
+
+
+/**
+ * The function verifies EC Edwards detatched signature on given message
+ *
+ * Implemented algorithm of Bernstein D. etc.
+ *
+ * @author reuvenl (1/21/2016)
+ *
+ * @return CCError_t
+ */
+CCError_t  EcEdwSignVerify (
+                        const uint8_t *pInSign,              /*!< [in] - the pointer to input signature. */
+                        const uint8_t *pMsg,                 /*!< [in] - the pointer to the message. */
+                        size_t         msgSize,              /*!< [in] - the message size in bytes: it must not great
+                                                                  than CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES. */
+                        const uint8_t *pSignPublKey,         /*!< [in] - the pointer to the signer public key, stated
+                                                                  in compressed form of coordinate Y */
+                        const CCEcEdwDomain_t *pEcDomain,  /*!< [in] pointer to EDW EC domain (curve). */
+                        CCEcEdwTempBuff_t *pEcEdwTempBuff) /*!< [in] pointer to the temp buffer. */
+{
+
+        CCError_t err = CC_OK;
+        size_t edwSizeWords = pEcDomain->ecModSizeInWords;
+        size_t edwSizeBytes = edwSizeWords * sizeof(uint32_t);
+        size_t hashSizeWords = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES / sizeof(uint32_t);
+        uint32_t sizeToHash, msgSize1;
+        /* set pointers to 32-bit aligned buffers */
+        uint32_t *pSign = (uint32_t*)pEcEdwTempBuff;
+        /* next uses the same buff */
+        uint32_t *pIntegrVal = pSign/*hram*/;
+        uint32_t *pPublKeyY = pIntegrVal + edwSizeWords;
+        uint32_t *pEdwSignVal = pPublKeyY + edwSizeWords;
+        uint32_t *pEphPubl = pEdwSignVal + edwSizeWords;
+        uint32_t *pResPoint = pEphPubl + edwSizeWords; /*use previous buff*/
+
+        const mbedtls_md_info_t *md_info=NULL;
+        mbedtls_md_context_t *p_hash_ctx = (mbedtls_md_context_t*)(pResPoint + 2*edwSizeWords);;
+
+        /* get and lock the PKA hardware */
+        err = CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE);
+        if (err != CC_SUCCESS) {
+                CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* verify that the device is not in fatal error state before activating the PKA engine */
+        CC_IS_FATAL_ERR_ON(err);
+        if (err == CC_TRUE) {
+                /* release the hardware semaphore */
+                if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != CC_SUCCESS) {
+                        CC_PalAbort("Fail to release mutex\n");
+                }
+                return PKA_FATAL_ERR_STATE_ERROR;
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        err = CC_IS_WAKE;
+        if (err != CC_SUCCESS) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /*-------------------------------------------------*/
+        /*          Process signature verification         */
+        /*-------------------------------------------------*/
+
+        /* check that EdwSignValue have two MS bits = 0 */
+        if (pInSign[2*edwSizeBytes - 1] >> ((pEcDomain->ecModSizeInBits % CC_BITS_IN_32BIT_WORD) - 2)) {
+                return CC_EC_EDW_SIGN_VERIFY_FAILED_ERROR;
+        }
+
+        /* check that publ.key != 0 */
+        if (PkiIsUint8ArrayEqualTo0(pSignPublKey, edwSizeBytes)) {
+
+                return CC_EC_EDW_SIGN_VERIFY_FAILED_ERROR;
+        }
+
+        /* create integrity value on: EphPublKey || userPublKey || Msg */
+        /*-------------------------------------------------------------*/
+
+        /* copy input EphPublKey||userPublKey to aligned buffer as bytes */
+        CC_PalMemCopy((uint8_t*)pSign, pInSign, edwSizeBytes);
+        CC_PalMemCopy((uint8_t*)pSign + edwSizeBytes, pSignPublKey, edwSizeBytes);
+
+        if (msgSize == 0) {
+                sizeToHash = 2*edwSizeBytes;
+                msgSize1 = 0;
+        } else {
+                if (msgSize <= CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES - 2*edwSizeBytes) {
+                        CC_PalMemCopy((uint8_t*)pSign + 2*edwSizeBytes, pMsg, msgSize);
+                        sizeToHash = 2*edwSizeBytes + msgSize;
+                        msgSize1 = 0;
+                } else {
+                        sizeToHash = CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES;
+                        CC_PalMemCopy((uint8_t*)pSign + 2*edwSizeBytes, pMsg, sizeToHash - 2*edwSizeBytes);
+                        msgSize1 = msgSize - (sizeToHash - 2*edwSizeBytes);
+                }
+        }
+
+        /*         HASH operations      */
+        /*------------------------------*/
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[CC_HASH_SHA512_mode] );
+        if (NULL == md_info) {
+                err = CC_EC_EDW_SIGN_VERIFY_FAILED_ERROR;
+                goto End;
+        }
+        mbedtls_md_init(p_hash_ctx);
+        err = mbedtls_md_setup(p_hash_ctx, md_info, 0); // 0 = HASH, not HMAC
+        if (err != CC_OK) {
+                goto End;
+        }
+        err = mbedtls_md_starts(p_hash_ctx);
+        if (err != CC_OK)
+                goto End;
+
+        err = mbedtls_md_update(p_hash_ctx, (uint8_t*)pSign/*h2*/, sizeToHash);
+        if (err != CC_OK) /*full block, padded by msg*/
+                goto End;
+
+        if (msgSize1 > 0) {
+                err = mbedtls_md_update(p_hash_ctx, (uint8_t*)pMsg+(sizeToHash - 2*edwSizeBytes), msgSize1);
+                if (err != CC_OK)   /*remaining bytes of the msg*/
+                        goto End;
+        }
+        err = mbedtls_md_finish(p_hash_ctx, (unsigned char *)pSign);
+        if (err != CC_OK)
+                goto End;
+
+        /* reduce IntegrVal by EC order, set result into EDW_REG_INTEGR  */
+        /*---------------------------------------------------------------*/
+
+        /* init PKA mapping and sizes tables according to 2 modulus size */
+        err = PkaInitPka(CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES*CC_BITS_IN_BYTE,
+                         0/*RegSizeInWords*/, NULL);
+        if (err != CC_SUCCESS) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+
+        /* load IntegrVal and mod.P into paired register for each parameter */
+        PkaCopyDataIntoPkaReg(EDW_REG_INTEGR, LEN_ID_N_PKA_REG_BITS, pSign/*IntegrVal*/, hashSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_N, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecOrdN, edwSizeWords);
+        /* reduce by order */
+        PKA_DIV(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5/*4 not used*/, EDW_REG_INTEGR/*3*/, EDW_REG_N);
+        /* output reduced EphPrivKey */
+        PkaCopyDataFromPkaReg(pIntegrVal/*dst*/, edwSizeWords, EDW_REG_INTEGR/*srcReg*/);
+
+        /* init PKA mapping and sizes tables according to EC modulus size */
+        /*----------------------------------------------------------------*/
+        err = PkaInitPka(pEcDomain->ecModSizeInBits, 0/*pEcDomain->ecModSizeInWords*/, NULL);
+        if (err != CC_SUCCESS) {
+                err = CC_ECEDW_INTERNAL_ERROR;
+                goto End;
+        }
+
+        /* set the user publ. key as words and negate it */
+        CC_CommonConvertLsbMsbBytesToLswMswWords(pPublKeyY, pSignPublKey, edwSizeBytes);
+        pPublKeyY[edwSizeWords-1] ^= (1UL << 31);
+
+        CC_CommonConvertLsbMsbBytesToLswMswWords(pEdwSignVal, &pInSign[edwSizeBytes], edwSizeBytes);
+
+        /* perform two scalar mult. with adding: ("**" - scalar mult)
+            ResPoint = pIntegrVal**PublKey + EdwSignVal**EcBasePoint */
+        err = EcEdwAddTwoScalarMult(
+                                   pResPoint,
+                                   pIntegrVal/*scalarA*/,
+                                   pPublKeyY, NULL/*pPublKeyX*/,
+                                   pEdwSignVal/*scalarB*/,
+                                   pEcDomain);
+        if (err) {
+                goto End;
+        }
+
+        /* specific verification of the Edw. signature  */
+        CC_CommonConvertLsbMsbBytesToLswMswWords(pEphPubl, pInSign, edwSizeBytes);
+
+        if (!PkiAreBuffersEqual(pResPoint, pEphPubl, edwSizeBytes)) {
+                err = CC_EC_EDW_SIGN_VERIFY_FAILED_ERROR;
+                goto End;
+        }
+
+        End:
+        if(md_info!=NULL){
+                mbedtls_md_free(p_hash_ctx);
+        }
+
+        CC_PalMemSetZero(pEcEdwTempBuff, sizeof(CCEcEdwTempBuff_t));
+
+        PkaFinishAndMutexUnlock(CC_INFINITE);
+
+        return err;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw.h
new file mode 100644
index 0000000..fd66f68
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw.h
@@ -0,0 +1,258 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EC_EDW_H_H
+#define EC_EDW_H_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ec_edw_api.h"
+#include "ec_edw_local.h"
+
+
+/*****************   Definitions    ***********************/
+
+/* Len ID for reduction HASH  */
+#define LEN_ID_EDW_REDUCE 2
+
+
+/**********   Global buffers and variables    **************/
+
+
+/*********************************************************************/
+/*!
+@brief The function performs EC Edwards key pair generation using seed.
+
+ @return CCError_t
+*/
+CCError_t EcEdwSeedKeyPair(
+                        uint8_t *pPublKey,       /*!< [out] a pointer to publickey (compressed,
+                                                       the size = ec modulus size) */
+                        uint8_t *pSecrKey,       /*!< [out] a pointer to secret key, stated as concatenation
+                                                      of seed amd public key (the size = 2 * ec modulus size) */
+                        const uint8_t  *pSeed,   /*!< [in] a pointer to the seed (the size = ec order size) */
+                        const CCEcEdwDomain_t *pEcDomain, /*!< [in] pointer to EC domain (curve). */
+                        uint32_t *pEcEdwTempBuff); /*!< [in] pointer to the temp buffer. */
+
+
+/*********************************************************************/
+/*!
+ * The function performs input/output parameters for EC Edwards
+ * scalar multiplication.
+ *
+ *         resPoint(Y,_) = k*inPoint(X,Y), where:
+ *         the point is given with LE order of the words.
+ *
+ *         Assuming:
+ *              The PKA HW is turned ON and initialized yet;
+ *
+ * \return CCError_t
+ */
+CCError_t  EcEdwScalarMultBase(
+                                uint32_t  *pResPointX,             /*!< [out] a pointer (optional) to result EC point coordinate X. */
+                                uint32_t  *pResPointY,             /*!< [out] a pointer to result EC point coordinate Y. */
+                                uint32_t  *pScalar,                /*!< [in]  a pointer to the scalar. */
+                                size_t     scalarSizeWords,        /*!< [in]  the scalar size in words. */
+                                const CCEcEdwDomain_t *pEcDomain   /*!< [in]  a pointer to EC domain (curve). */);
+
+/*********************************************************************/
+/*!
+ * The function performs input/output parameters for EC Edwards scalar
+ * multiplication for special scalars.
+ *
+ *         resPoint(Y,_) = k*inPoint(X,Y), where:
+ *         the point is given with LE order of the words.
+ *
+ *         Assuming:
+ *              The PKA HW is turned on and initialized yet;
+ *
+ * \return CCError_t
+ */
+CCError_t  EcEdwSpecialScalarMultBase(
+                                uint32_t  *pResPointX,             /*!< [out] a pointer to result EC point coordinate X. */
+                                uint32_t  *pResPointY,             /*!< [out] a pointer to result EC point coordinate Y. */
+                                uint32_t  *pScalar,                /*!< [in]  a pointer to the scalar. */
+                                size_t     scalarSizeWords,         /*!< [in]  the scalar size in words. */
+                                const CCEcEdwDomain_t *pEcDomain /*!< [in]  a pointer to EC domain (curve). */);
+
+
+
+/*********************************************************************/
+/*!
+@brief The function performs two EC Edwards scalar multiplication and adding
+       of points:  resPoint = scalarA * Point(X,Y) + scalarB * BasePointG.
+
+       Assuming: - PKA is turned on andinitialized yet (including setting N and NP in registers);
+                 - Input point may be given in uncompressed form (given both coord. X,Y)
+                   or in compressed form: coordinate Y only and LSBit of X on bit place,
+                   equalled to modulus size in bits (255 for ec25519).
+
+ @return CCError_t
+*/
+CCError_t EcEdwAddTwoScalarMult(
+                                 uint32_t *pResPoint,        /*!< [out] the pointer to the result point in compressed
+                                                                 form (coordinate Y, the size in bytes = ec modulus size). */
+                                 uint32_t *pScalarA,         /*!< [in] pointer to the scalarA, the size = ec modulus size in bytes). */
+                                 uint32_t *pPointY,          /*!< [in] a pointer to the input point coordinate Y - in uncompressed
+                                                                 form, if given coordinate X, or in compressed form if coordinate
+                                                                 X == NULL (the size of Y in bytes = ec modulus size). */
+                                 uint32_t *pPointX,          /*!< [in, optional] the pointer to input point coordinate X for uncompressed
+                                                                 form of point(the size of Y in bytes = ec modulus size). */
+                                 uint32_t *pScalarB,         /*!< [in] pointer to the scalarB, the size = ec modulus sizein bytes). */
+                                 const CCEcEdwDomain_t *pEcDomain); /*!< [in] pointer to EC domain (curve). */
+
+
+/*********************************************************************/
+/**
+ * The function createss EC Edwards detatched signature on given message
+ *
+ * Implemented algorithm of Bernstein D. etc.
+ *
+ * @return CCError_t
+ */
+CCError_t  EcEdwSign (
+                        uint8_t       *pEdwSign,             /*!< [out] - the pointer to the signature. */
+                        const uint8_t *pMsg,                 /*!< [in] - the pointer to the message. */
+                        size_t         msgSize,              /*!< [in] - the message size in bytes: it must be less, than
+                                                                  CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES. */
+                        const uint8_t *pSignSecrKey,         /*!< [in] - the pointer to the signer secret key, stated as
+                                                                  concatenation of the seed and public key) */
+                        const CCEcEdwDomain_t *pEcDomain,    /*!< [in] pointer to EDW EC domain (curve). */
+                        CCEcEdwTempBuff_t *pEcEdwTempBuff); /*!< [in] pointer to the temp buffer. */
+
+
+/*********************************************************************/
+/**
+ * The function verifies EC Edwards detatched signature on given message
+ *
+ * Implemented algorithm of Bernstein D. etc.
+ *
+ * @author reuvenl (1/21/2016)
+ *
+ * @return CCError_t
+ */
+CCError_t  EcEdwSignVerify (
+                        const uint8_t *pInSign,               /*!< [in] - the pointer to input signature. */
+                        const uint8_t *pMsg,                  /*!< [in] - the pointer to the message. */
+                        size_t         msgSize,               /*!< [in] - the message size in bytes: it must be not
+                                                                   great than CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES. */
+                        const uint8_t *pSignPublKey,          /*!< [in] - the pointer to the signer public key, stated
+                                                                   in compressed form of coordinate Y */
+                        const CCEcEdwDomain_t *pEcDomain,    /*!< [in] pointer to EDW EC domain (curve). */
+                        CCEcEdwTempBuff_t *pEcEdwTempBuff); /*!< [in] pointer to the temp buffer. */
+
+/**
+ * The function calculates uncompressed coordinate X of EC point,
+ * using the given compressed coordinates Y.
+ *
+ * Implemented algorithm Bernstain D. etc (stated by Klimov A.).
+ *
+ * @author reuvenl (1/11/2016)
+ *
+ * Imlicit parametrs
+ * @param  [out] rX - ID of PKA register for output decompressed coordinate X.
+ * @param  [in/out] rY - ID of PKA register, containing compressed/decompressed coordinate Y.
+ * @param  [in] isOddX - indication: "Is the coordinate X odd".
+ *
+ */
+void PkaEcEdwDecompress(uint32_t rX, uint32_t rY,
+                        uint32_t isOddX) /*!< one bit indication: "Is the coordinate X odd" */;
+
+
+/**
+ * The function performs multiplication of base point by any scalar > 0:
+ *        P(x,y) = k*G(x,y), whre G - EC base point.
+ *
+ *  Implemented algorithm, enhanced by A.Klimov.
+ *
+ *  Assuming:
+ *  1. PKA registers are implicitly defined in pka_ec_edw_glob_regs_def.h file,
+ *     in partial: output point P(x,y) is stated by registers (EDW_REG_XS,
+ *     EDW_REG_YS).
+ *  2. All needed data must be loaded into PKA registers in caller function.
+ *  3. PKA registers are defined in pka_ec_edw_glob_regs_defh file, in partial:
+ *      - output point R(x,y) shall be registers (rXR=EDW_REG_XR, rYR=EDW_REG_YR),
+ *      - input point P(X,Y) by (rXP=EDW_REG_XP, rYP=EDW_REG_YP).
+ *
+ * @author reuvenl (11/25/2015)
+ *
+ * @return CC_OK or an error according to mbedtls_cc_ec_mont_edw_error.h definitions.
+ */
+CCError_t PkaEcEdwScalarMultBase(
+                                uint32_t *pScalar,         /*!< [in] the pointer to the scalsr (LS word is
+                                                               leftmost one, MS word - rightmost). */
+                                size_t    scalarSizeInBits /*!< exact size of the scalar in bits. */ );
+
+/**
+ * The function performs multiplication of base point by scalar of special form:
+ *      P(x,y) = k*G(x,y).
+ *
+ *  Implemented algorithm, enhanced by A.Klimov.
+ *
+ *  The function can work with scalars of special form: exact size is 255
+ *  bit and it is a multiple of 8 bit (as requiered in Edw. KeyGen algorithm).
+ *  Assuming:
+ *  1. PKA registers are implicitly defined in pka_ec_edw_glob_regs_def.h file,
+ *     in partial: output point P(x,y) is stated by registers (EDW_REG_XS,
+ *     EDW_REG_YS).
+ *  2. All needed data must be loaded into PKA registers in caller function.
+ *  3. PKA registers are defined in pka_ec_edw_glob_regs_defh file, in partial:
+ *      - output point R(x,y) shall be registers (rXR=EDW_REG_XR, rYR=EDW_REG_YR),
+ *      - input point P(X,Y) by (rXP=EDW_REG_XP, rYP=EDW_REG_YP).
+ *
+ * @author reuvenl (11/25/2015)
+ *
+ * @return CC_OK or an error according to mbedtls_cc_ec_mont_edw_error.h definitions.
+ */
+CCError_t PkaEcEdwSpecialScalarMultBase(
+                                uint32_t *pScalar,         /*!< [in] the pointer to the scalsr (LS word is
+                                                               leftmost one, MS word - rightmost). */
+                                size_t    scalarSizeInBits /*!< exact size of the scalar in bits. */ );
+
+/**
+ * The function performs two scalar mult. and add of input and base points simultaneously:
+ *         R(x,y) = a*P(x,y) + b*G(x,y), where P - point, G - base point.
+ *
+ *  Implemented algorithm of Bernstein D. etc. (version of A.Klimov).
+ *
+ *  PKA registers are defined in pka_ec_edw_glob_regs_defh file, in partial:
+ *      - output point R(x,y) shall be registers (rXR=EDW_REG_XR, rYR=EDW_REG_YR),
+ *      - input point P(X,Y) by (rXP=EDW_REG_XP, rYP=EDW_REG_YP).
+ *
+ * @author reuvenl (11/25/2015)
+ *
+ * @return CC_OK or an error according to mbedtls_cc_ec_mont_edw_error.h definitions.
+ */
+CCError_t PkaEcEdwAddTwoScalarMult(
+        uint32_t rXR, uint32_t rYR,       /*!< [out] the ID-s of registers, containing aff.
+                                               coordinates of result point P */
+        uint32_t rXP, uint32_t rYP,       /*!< [in] the ID-s of registers, containing aff.
+                                               coordinates of input point P */
+        uint32_t *pScalarA,               /*!< [in] the pointer to the scalsr A (LS word is
+                                               leftmost one, MS word - rightmost). */
+        size_t    scAsizeInBits,          /*!< exact size of the scalar A in bits. */
+        uint32_t *pScalarB,               /*!< [in] the pointer to the scalsr B (LS word is
+                                               leftmost one, MS word - rightmost). */
+        size_t    scBsizeInBits,          /*!< exact size of the scalar B in bits. */
+        const CCEcEdwDomain_t *pEcDomain /*!< [in] pointer to EC domain (curve). */);
+
+#ifdef __cplusplus
+}
+
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw_domain_25519.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw_domain_25519.c
new file mode 100644
index 0000000..66d9853
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw_domain_25519.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "ec_edw_local.h"
+
+
+/*!
+@file
+@brief The file contains EC Domain 25519 parameters and get-function.
+*/
+
+
+/*  EC Edwards curve domain: curve over prime fild GFp:
+    x^2 + y^2 = 1 + d*x^2*y^2 */
+
+/*!> EC Edwards domain 25519 domain parameters and auxiliary values.
+     The data is in little endian order of words: LS-Word is most left one */
+static const CCEcEdwDomain_t  EcEdwDomain25519 = {
+
+        /* Prime modulus P = {2^255 - 19) = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED */
+        {0xffffffed,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0x7fffffff},
+        /* modulus size in bits and words */
+        255, 8,
+        /* EC generator G coordinate X = 0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A  */
+        {0x8F25D51A,0xC9562D60,0x9525A7B2,0x692CC760,0xFDD6DC5C,0xC0A4E231,0xCD6E53FE,0x216936D3},
+        /* EC generator G coordinate Y = 0x6666666666666666666666666666666666666666666666666666666666666658 = 4/5 */
+        {0x66666658,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666,0x66666666},
+        /* EC_MONT generator order n =  0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED */
+        {0x5cf5d3ed,0x5812631a,0xa2f79cd6,0x14def9de,0x00000000,0x00000000,0x00000000,0x10000000},
+        253, 8, /* EC_MONT generator order size in bits and IN words */
+        8, /* EC order cofactor */
+        /* EC parameter d = 0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3 = 121665 / 121666 */
+        {0x135978A3,0x75EB4DCA,0x4141D8AB,0x00700A4D,0x7779E898,0x8CC74079,0x2B6FFE73,0x52036CEE},
+
+        /* EC generator G proective coordinates: X=  Z = 1 (there is c) */
+        /* tg = [255] 67875F0FD78B766566EA4E8E64ABE37D20F09F80775152F56DDE8AB3A5B7DDA3 */
+        {0xA5B7DDA3,0x6DDE8AB3,0x775152F5,0x20F09F80,0x64ABE37D,0x66EA4E8E,0xD78B7665,0x67875F0F},
+
+        /* Precalculated cordinates of EC points G,2G,4G,8G,16G,32G */
+        /* sg = [251] 7CF9D3A33D4BA65270B4898643D42C2CF932DC6FB8C0E192FBC93C6F58C3B85 */
+        {0xF58C3B85,0x2FBC93C6,0xFB8C0E19,0xCF932DC6,0x643D42C2,0x270B4898,0x33D4BA65,0x07CF9D3A},
+        /* dg = [255] 44FD2F9298F81267A5C18434688F8A09FD399F05D140BEB39D103905D740913E */
+        {0xD740913E,0x9D103905,0xD140BEB3,0xFD399F05,0x688F8A09,0xA5C18434,0x98F81267,0x44FD2F92},
+        /* pg = [255] 6F117B689F0C65A85A1B7DCBDD43598C26D9E823CCAAC49EABC91205877AAA68 */
+        {0x877AAA68,0xABC91205,0xCCAAC49E,0x26D9E823,0xDD43598C,0x5A1B7DCB,0x9F0C65A8,0x6F117B68},
+        /* mpg = [253] 10EE849760F39A57A5E4823422BCA673D92617DC33553B615436EDFA78855585 */
+        {0x78855585,0x5436EDFA,0x33553B61,0xD92617DC,0x22BCA673,0xA5E48234,0x60F39A57,0x10EE8497},
+        /* sg2 = [255]  */
+        {0x933C71D7,0x9224E7FC,0x7A0FF5B5,0x9F469D96,0xE1D60702,0x5AA69A65,0xA87D2E2E,0x590C063F},
+        /* dg2 = [255]  */
+        {0x42B4D5A8,0x8A99A560,0x4E60ACF6,0x8F2B810C,0xB16E37AA,0xE09E236B,0x69C92555,0x6BB595A6},
+        /* pg2 = [255]  */
+        {0xA59B7A5F,0x43FAA8B3,0x5D9ACF78,0x36C16BDD,0x0B3D6A31,0x500FA084,0x3EA50B73,0x701AF5B1},
+        /* mpg2 = [255]  */
+        {0x5A64858E,0xBC05574C,0xA2653087,0xC93E9422,0xF4C295CE,0xAFF05F7B,0xC15AF48C,0x0FE50A4E},
+        /* sg4 = [255] 680E910321E58727CA348D3DFB0A92656765C6F47DFD2538287351B98EFC099F */
+        {0x8EFC099F,0x287351B9,0x7DFD2538,0x6765C6F4,0xFB0A9265,0xCA348D3D,0x21E58727,0x680E9103},
+        /* dg4 = [254] 27933F4C7445A49AC3E8E3CD06A05073327E89715660FAA995FE050A056818BF */
+        {0x056818BF,0x95FE050A,0x5660FAA9,0x327E8971,0x06A05073,0xC3E8E3CD,0x7445A49A,0x27933F4C},
+        /* pg4 = [255] 7F9D0CBF63553E2B5DDBDCF9102B44946E9E39457B5CC1725A13FBE9C476FF09 */
+        {0xC476FF09,0x5A13FBE9,0x7B5CC172,0x6E9E3945,0x102B4494,0x5DDBDCF9,0x63553E2B,0x7F9D0CBF},
+        /* mpg4 = [247] 62F3409CAAC1D4A2242306EFD4BB6B9161C6BA84A33E8DA5EC04163B8900E4 */
+        {0x3B8900E4,0xA5EC0416,0x84A33E8D,0x9161C6BA,0xEFD4BB6B,0xA2242306,0x9CAAC1D4,0x0062F340},
+        /* sg8 = [252] 915E76061BCE52FB1339C665ED9C3236CB30377E288702C59B7596604DD3E8F */
+        {0x04DD3E8F,0x59B75966,0xE288702C,0x6CB30377,0x5ED9C323,0xB1339C66,0x61BCE52F,0x0915E760},
+        /* dg8 = [254] 3A9024A1320E01C32C2741AC6E3C23FB963D7680E1B558F9E2A75DEDF39234D9 */
+        {0xF39234D9,0xE2A75DED,0xE1B558F9,0x963D7680,0x6E3C23FB,0x2C2741AC,0x320E01C3,0x3A9024A1},
+        /* pg8 = [254] 26907C5C2ECC4E95636412190EB62A32B8A371788BCCA7D7E7C1F5D9C9A2911A */
+        {0xC9A2911A,0xE7C1F5D9,0x8BCCA7D7,0xB8A37178,0x0EB62A32,0x63641219,0x2ECC4E95,0x26907C5C},
+        /* mpg8 = [255] 596F83A3D133B16A9C9BEDE6F149D5CD475C8E8774335828183E0A26365D6ED3 */
+        {0x365D6ED3,0x183E0A26,0x74335828,0x475C8E87,0xF149D5CD,0x9C9BEDE6,0xD133B16A,0x596F83A3},
+        /* sg16 = [253] 143B1CF8AA64FE61587A3A4342D20B09B9C19F3375C6BF9C322D04A52D9021F6 */
+        {0x2D9021F6,0x322D04A5,0x75C6BF9C,0xB9C19F33,0x42D20B09,0x587A3A43,0xAA64FE61,0x143B1CF8},
+        /* dg16 = [255] 4CF210EC5A9A8883E6B5E4193288D1E7A71284CBA64878B37EC851CA553E2DF3 */
+        {0x553E2DF3,0x7EC851CA,0xA64878B3,0xA71284CB,0x3288D1E7,0xE6B5E419,0x5A9A8883,0x4CF210EC},
+        /* pg16 = [254] 21B546A3374126E1D0A7D34BEA1809755F54258E270927299F867C7D968ACAAB */
+        {0x968ACAAB,0x9F867C7D,0x27092729,0x5F54258E,0xEA180975,0xD0A7D34B,0x374126E1,0x21B546A3},
+        /* mpg16 = [255] 5E4AB95CC8BED91E2F582CB415E7F68AA0ABDA71D8F6D8D66079838269753542 */
+        {0x69753542,0x60798382,0xD8F6D8D6,0xA0ABDA71,0x15E7F68A,0x2F582CB4,0xC8BED91E,0x5E4AB95C},
+
+        /* xg2 = [254] 36AB384C9F5A046C3D043B7D1833E7AC080D8E4515D7A45F83C5A14E2843CE0E */
+        {0x2843CE0E,0x83C5A14E,0x15D7A45F,0x080D8E45,0x1833E7AC,0x3D043B7D,0x9F5A046C,0x36AB384C},
+        /* yg2 = [254] 2260CDF3092329C21DA25EE8C9A21F5697390F51643851560E5F46AE6AF8A3C9 */
+        {0x6AF8A3C9,0x0E5F46AE,0x64385156,0x97390F51,0xC9A21F56,0x1DA25EE8,0x092329C2,0x2260CDF3},
+        /* tg2 = [254] 2498A7850B2F68DC1DE55F087303B4135D79ACC9C1F72402B71A3F556D69B401 */
+        {0x6D69B401,0xB71A3F55,0xC1F72402,0x5D79ACC9,0x7303B413,0x1DE55F08,0x0B2F68DC,0x2498A785},
+        /* xg4 = [254] 203DA8DB56CFF1468325D4B87A3520F91A739EC193CE1547493AA657C4C9F870 */
+        {0xC4C9F870,0x493AA657,0x93CE1547,0x1A739EC1,0x7A3520F9,0x8325D4B8,0x56CFF146,0x203DA8DB},
+        /* yg4 = [255] 47D0E827CB1595E1470EB88580D5716C4CF22832EA2F0FF0DF38AB61CA32112F */
+        {0xCA32112F,0xDF38AB61,0xEA2F0FF0,0x4CF22832,0x80D5716C,0x470EB885,0xCB1595E1,0x47D0E827},
+        /* tg4 = [254] 22783CD8D873260C7214BA6AC67C29607195E31EB6DD07CA5F8F22F6728A1358 */
+        {0x728A1358,0x5F8F22F6,0xB6DD07CA,0x7195E31E,0xC67C2960,0x7214BA6A,0xD873260C,0x22783CD8},
+
+        /* xg32 = [254] 39CF6C6917421AF98582561D0B39567DE6033190F97852FC4FDD40F6977E4F26 */
+        {0x977E4F26,0x4FDD40F6,0xF97852FC,0xE6033190,0x0B39567D,0x8582561D,0x17421AF9,0x39CF6C69},
+        /* yg32 = [255] 4434A90EE12CCE6B7ADE93ECC0F88B78B41205E74C8C4038F92D394F3A06D269 */
+        {0x3A06D269,0xF92D394F,0x4C8C4038,0xB41205E7,0xC0F88B78,0x7ADE93EC,0xE12CCE6B,0x4434A90E},
+        /* tg32 = [255] 6DF8117912746C6DD3A384546D47A595714E56C176B8A6B523C1747F59E2C69F */
+        {0x59E2C69F,0x23C1747F,0x76B8A6B5,0x714E56C1,0x6D47A595,0xD3A38454,0x12746C6D,0x6DF81179},
+
+        /* auxiliary value d2 = 0x2406D9DC56DFFCE7198E80F2EEF3D13000E0149A8283B156EBD69B9426B2F159 = 2*d */
+        {0x26B2F159,0xEBD69B94,0x8283B156,0x00E0149A,0xEEF3D130,0x198E80F2,0x56DFFCE7,0x2406D9DC},
+        /* auxiliary value q58 = 0x0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD = (P - 5)/8 */
+        {0xFFFFFFFD,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0x0FFFFFFF},
+        /* auxiliary value = ecAuxValSqrt_1 = 0x2B8324804FC1DF0B2B4D00993DFBD7A72F431806AD2FE478C4EE1B274A0EA0B0 = sqrt(-1) */
+        {0x4A0EA0B0,0xC4EE1B27,0xAD2FE478,0x2F431806,0x3DFBD7A7,0x2B4D0099,0x4FC1DF0B,0x2B832480},
+
+        /*Barrett tags for EC modulus and order */
+#ifdef CC_SUPPORT_PKA_64_16
+        {0x00000000,0x00000000,0x00000080}, /*0x800000000000000000 - for modulus*/
+        {0xFFFFFFFF,0xFFFFFFFF,0x000000FF}, /*0x3FFFFFFFFFFFFFFFFF - for EC order*/
+#else   /* CC_SUPPORT_PKA_128_32 */
+        {0x00000000,0x00000000,0x00000000,0x00000000,0x00000080}, /*0x8000000000000000000000000000000000  - for modulus*/
+        {0x000003FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFAC8}, /*0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC8 - for EC order*/
+#endif
+        /* scalar bit setting parameters */
+        0xFFFFFFF8,  /* SCALAR_LSW_AND_VALUE (248)*/
+        0x7FFFFFFF,  /* SCALAR_MSW_AND_VALUE (127<<24)*/
+        0x40000000,  /* SCALAR_MSW_OR_VALUE (64<<24)*/
+};
+
+/*!<
+ @brief    the function returns the domain pointer if the domain is supported for the product,
+       otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcEdwDomain_t *EcEdwGetDomain25519(void)
+{
+    return &EcEdwDomain25519;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw_local.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw_local.h
new file mode 100644
index 0000000..57d4de1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/ec_edw_local.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef EC_EDW_LOCAL_H_H
+#define EC_EDW_LOCAL_H_H
+
+#include "cc_pal_types.h"
+#include "cc_pka_defs_hw.h"
+#include "cc_ec_edw_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+@file
+@brief This file contains the  APIs used for EC MONT (Montgomery Curve25519) algorithms.
+
+@note  Algorithms of Montgomery and Edwards elliptic curves cryptography are developed by
+       Daniel.J.Bernstein and described in SW library "NaCl" (Networking and
+       Cryptographic Library).
+*/
+
+
+/******************************************************************************/
+/**          EC Montgomery domain APIs:                                       */
+/******************************************************************************/
+
+/*!< EC Edwards curve domain structure type:
+     Elliptic curve over prime fild GFp: x^2 + y^2 = 1 + d*x^2*y^2 */
+typedef struct {
+        /*----   Common parameters for Mont-Edw curves ----*/
+        /*!< EC prime modulus P */
+        uint32_t ecModP[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< modulus size in bits */
+        uint32_t ecModSizeInBits;
+        /*!< modulus size in words */
+        uint32_t ecModSizeInWords;
+        /*!< EC generator G aff. coordinate X */
+        uint32_t ecGenX[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC generator G aff. coordinate Y */
+        uint32_t ecGenY[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC generator order.  */
+        uint32_t ecOrdN[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC generator order size in bits */
+        uint32_t ecOrdSizeInBits;
+        /*!< EC generator order size in words */
+        uint32_t ecOrdSizeInWords;
+        /*!< EC generator order's cofactor */
+        uint32_t ecOrdCofactor;
+        /*!< EC equation parameter D */
+        uint32_t ecParamD[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+
+        /*!< EC generator G proective coordinates:
+             X=ecGenX, Y=ecGenY, Z = 1, T=X*Y = ecGenT */
+        uint32_t ecGenT[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+
+        /*!< Precalculated cordinates (s,d,p,mp) of EC points G,4G,8G,16G */
+        /* used only in special scal.mult */
+        uint32_t sg[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t dg[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t pg[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t mpg[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /* used in both scal.mult */
+        uint32_t sg2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t dg2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t pg2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t mpg2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t sg4[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t dg4[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t pg4[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t mpg4[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /* used only in special scal.mult */
+        uint32_t sg8[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t dg8[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t pg8[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t mpg8[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t sg16[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t dg16[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t pg16[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t mpg16[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< Modified cordinates (X,Y,Z=1,T) of precalculated EC points 2G, 4G, 32G */
+        /* used only in common scal.mult */
+        uint32_t xg2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t yg2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t tg2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t xg4[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t yg4[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t tg4[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /* used only in special scal.mult */
+        uint32_t xg32[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t yg32[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        uint32_t tg32[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+
+        /*!< EC auxiliary value  d2 = 2*d */
+        uint32_t ecAuxValD2[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC auxiliary value  q58 = = (P - 5)/8 */
+        uint32_t ecAuxValQ58[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC auxiliary value sqrt_1 = square_root(-1) */
+        uint32_t ecAuxValSqrt_1[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< Barrett tag for EC modulus */
+        uint32_t ecModBarrTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+        /*!< Barrett tag for EC generator order */
+        uint32_t ecOrdBarrTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+        /*!< masks for bits setting in scalar multiplication LS/MS words */
+        uint32_t scalarLsWordAndValue;
+        uint32_t scalarMsWordAndValue;
+        uint32_t scalarMsWordOrValue;
+
+} CCEcEdwDomain_t;
+
+
+/******************************************************************************/
+/******************************************************************************/
+
+const CCEcEdwDomain_t *EcEdwGetDomain25519(void);  /*!< The function returns pointer to EC Edwards domain 25519. */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/pka_ec_edw.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/pka_ec_edw.c
new file mode 100644
index 0000000..917e22f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/pka_ec_edw.c
@@ -0,0 +1,614 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_hal_plat.h"
+#include "cc_common_math.h"
+#include "mbedtls_cc_ec_mont_edw_error.h"
+#include "cc_ec_edw_api.h"
+
+#include "ec_edw_local.h"
+#include "pka_defs.h"
+#include "pka_hw_defs.h"
+#include "pki.h"
+#include "pka.h"
+#include "ec_edw.h"
+#include "pka_error.h"
+#include "pka_ec_edw_glob_regs_def.h"
+
+
+/******             Definitions              *******/
+
+/*!> Macros for expansion of actual parameters (registers) for EC point "a" */
+#define REGS_MODIF_POINT(a) EDW_REG_X##a,EDW_REG_Y##a,EDW_REG_Z##a,EDW_REG_T##a  /*for Modified point*/
+#define REGS_PREC_POINT(a) EDW_REG_S##a,EDW_REG_D##a,EDW_REG_P##a                /*for Precalculated point*/
+#define REGS_NEG_PREC_POINT(a) EDW_REG_D##a,EDW_REG_S##a,EDW_REG_MP##a           /*for Precalculated negative point*/
+
+/**
+ * EC Edwards adding with extended (Ext) coordinates of points.
+ *    EEE: (X1,Y1,Z1,T1)  +  (X2,Y2,Z2,T2) -> (X,Y,Z,T)
+ *
+ */
+static void PkaEcEdwAddExtExtExt(
+                   uint32_t rX,  uint32_t rY,  uint32_t rZ,  uint32_t rT,  /*!< [out] - virt. pointers to PKA registers, containing
+                                                                                coordinates of result extended EC point. */
+                   uint32_t rX1, uint32_t rY1, uint32_t rZ1, uint32_t rT1, /*!< [in] - virt. pointers to PKA registers, containing
+                                                                                coordinates of inputt extended EC point1. */
+                   uint32_t rX2, uint32_t rY2, uint32_t rZ2, uint32_t rT2) /*!< [in] - virt. pointers to PKA registers, containing
+                                                                                coordinates of inputt extended EC point2. */
+{
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, EDW_REG_N_4,rX1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, EDW_REG_T3, rY1);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, EDW_REG_N_4,rX2);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, EDW_REG_T4, rY2);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T5, EDW_REG_T3, EDW_REG_T4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, rY1, rX1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, rY2, rX2);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T6, EDW_REG_T3, EDW_REG_T4);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T3, rT1, rT2);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T3, EDW_REG_T3, EDW_REG_D2);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, rZ1, rZ1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T4, EDW_REG_T4, rZ2);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, rT, EDW_REG_N_4, EDW_REG_T5);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, rT, rT, EDW_REG_T6);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T6, EDW_REG_T6, EDW_REG_T5);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5, EDW_REG_N_4, EDW_REG_T3);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5, EDW_REG_T5, EDW_REG_T4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, EDW_REG_T4, EDW_REG_T3);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, rT, EDW_REG_T5);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rY, EDW_REG_T4, EDW_REG_T6);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ, EDW_REG_T5, EDW_REG_T4);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rT, rT, EDW_REG_T6);
+        return;
+}
+
+
+/**
+ * EC Edwards doubing with extended (Ext) coordinates of point.
+ *    EE: 2*(X,Y,Z,T) -> (X,Y,Z,T)
+ *
+ */
+static void PkaEcEdwDoublExtExt(uint32_t rX, uint32_t rY, uint32_t rZ, uint32_t rT) /*!< [in/out] - virt. pointers to PKA registers, containing
+                                                                                   coordinates of input/output point. */
+{
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, EDW_REG_N_4, rX);         // hwsub(t3, n_4, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, EDW_REG_T3, rY);          // hwadd(t3, t3, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T5, EDW_REG_T3, EDW_REG_T3);  // hwmmul(t5, t3, t3, n, np);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, rY, rX);                  // hwadd(t3, y,x);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T6, EDW_REG_T3, EDW_REG_T3);  // hwmmul(t6, t3, t3, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T3, rT, rT);                  // hwmmul(t3, t, t, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T3, EDW_REG_T3, EDW_REG_D2);  // hwmmul(t3, t3, d2, n, np);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, rZ, rZ);                  // hwadd(t4, z, z);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T4, EDW_REG_T4, rZ);          // hwmmul(t4, t4, z, n, np);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, rT, EDW_REG_N_4, EDW_REG_T5);         // hwsub(t, n_4, t5);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, rT, rT, EDW_REG_T6);                  // hwadd(t, t, t6);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T6, EDW_REG_T6, EDW_REG_T5);  // hwadd(t6, t6, t5);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5, EDW_REG_N_4, EDW_REG_T3); // hwsub(t5, n_4, t3);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5, EDW_REG_T5, EDW_REG_T4);  // hwadd(t5, t5, t4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, EDW_REG_T4, EDW_REG_T3);  // hwadd(t4, t4, t3);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, rT, EDW_REG_T5);                  // hwmmul(x, t, t5, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rY, EDW_REG_T4, EDW_REG_T6);          // hwmmul(y, t4, t6, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ, EDW_REG_T5, EDW_REG_T4);          // hwmmul(z, t5, t4, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rT, rT, EDW_REG_T6);                  // hwmmul(t, t, t6, n, np);
+        return;
+}
+
+
+/**
+ * EC Edwards adding with extended (Ext) and proective (Prc) coordinates of
+ *     points:  (X1,Y1,Z1,T1) + (S2,D2,P2) -> (X,Y,Z,T)
+ *
+ */
+static void PkaEcEdwAddExtPrcExt(
+                   uint32_t rX,  uint32_t rY,  uint32_t rZ,  uint32_t rT,  /*!< [out] - virt. pointers to PKA registers,
+                                                                            containing coordinates of result extended EC point. */
+                   uint32_t rX1, uint32_t rY1, uint32_t rZ1, uint32_t rT1, /*!< [in] - virt. pointers to PKA registers,
+                                                                            containing coordinates of extended EC point1. */
+                   uint32_t rS2, uint32_t rD2, uint32_t rP2)               /*!< [in] - virt. pointers to PKA registers,
+                                                                            containing coordinates of precomputed EC point2. */
+{
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, EDW_REG_N_4, rX1);            PkiDbgPrintReg("t3: -x1     ", EDW_REG_T3);      // hwsub(t3, n_4, x1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, EDW_REG_T3, rY1);             PkiDbgPrintReg("t3: t3+y1   ", EDW_REG_T3);      // hwadd(t3, t3, y1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T5, EDW_REG_T3, rD2);             PkiDbgPrintReg("t5: t3*d2   ", EDW_REG_T5);      // hwmmul(t5, t3, d2, n, np);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, rY1, rX1);                    PkiDbgPrintReg("t3: y1+x1   ", EDW_REG_T3);      // hwadd(t3, y1, x1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T6, EDW_REG_T3, rS2);             PkiDbgPrintReg("t6: t3*s2   ", EDW_REG_T6);      // hwmmul(t6, t3, s2, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T3, rT1, rP2);                    PkiDbgPrintReg("t3: t1*p2   ", EDW_REG_T3);      // hwmmul(t3, t1, p2, n, np);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, rZ1, rZ1);                    PkiDbgPrintReg("t4: dbl(z1) ", EDW_REG_T4);      // hwadd(t4, z1, z1);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, rT, EDW_REG_N_4, EDW_REG_T5);             PkiDbgPrintReg("t: -t5      ", rT);              // hwsub(t, n_4, t5);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, rT, rT, EDW_REG_T6);                      PkiDbgPrintReg("t: t+t6     ", rT);              // hwadd(t, t, t6);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T6, EDW_REG_T6, EDW_REG_T5);      PkiDbgPrintReg("t6: t6+t5   ", EDW_REG_T6);      // hwadd(t6, t6, t5);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5, EDW_REG_N_4, EDW_REG_T3);     PkiDbgPrintReg("t5: -t3     ", EDW_REG_T5);      // hwsub(t5, n_4, t3);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T5, EDW_REG_T5, EDW_REG_T4);      PkiDbgPrintReg("t5: t5+t4   ", EDW_REG_T5);      // wadd(t5, t5, t4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, EDW_REG_T4, EDW_REG_T3);      PkiDbgPrintReg("t4: t4+t3   ", EDW_REG_T4);      // hwadd(t4, t4, t3);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, rT, EDW_REG_T5);                      PkiDbgPrintReg("x: t*t5     ", rX);              // hwmmul(x, t, t5, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rY, EDW_REG_T4, EDW_REG_T6);              PkiDbgPrintReg("y: t4*t6    ", rY);              // hwmmul(y, t4, t6, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ, EDW_REG_T5, EDW_REG_T4);              PkiDbgPrintReg("z: t5*t4    ", rZ);              // hwmmul(z, t5, t4, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rT, rT, EDW_REG_T6);                      PkiDbgPrintReg("t: t*t6     ", rT);              // hwmmul(t, t, t6, n, np);
+        return;
+}
+
+
+/**
+ * EC Edwards convert affine point (Afn) to precalculated (Prc) form of coordinates.
+ *    A2P: (X,Y) -> (S,D,P)
+ */
+void PkaEcEdwConvertAfn2Prc(
+                  uint32_t rS, uint32_t rD, uint32_t rP, /*!< virtual pointers to 3 coordinates
+                                                              of output precomputed EC pont */
+                  uint32_t rX, uint32_t rY)              /*!< virtual pointers to 2 coordinates
+                                                              of input affine point */
+{
+        /* if we have x,y,z,t regs, than is efficient to define:
+           rS->rZ, rD->rT, rP->rX */
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, rS, rY, rX);             // hwadd(s, y, x);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, rD, EDW_REG_N, rX);      // hwsub(d, n, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, rD, rD, rY);             // hwadd(d, d, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rP, EDW_REG_D2, rX);     // hwmmul(p, d2, x, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rP, rP, rY);             // hwmmul(p, p, y, n, np);
+        return;
+}
+
+
+// this SCA_RESISTANT is unrelated to SCA_PROTECTION in hardware
+/**
+ * EC Edwards convert point to affine (A) form of coordinates.
+ *    ToA: (X1,Y1,Z1) -> (X,Y)
+ *
+ * @param rX,rY       - virt. pointers to PKA registers, containing
+ *                      affine coordinates of result EC point.
+ * @param rX1,rY1,rZ1 - virt. pointers to PKA registers, containing
+ *                      coordinates of result EC point1.
+ * @param EDW_REG_Q - virt. pointer to temp PKA register.
+ *
+ */
+void PkaEcEdwPointToAfn(
+                       uint32_t rX,  uint32_t rY,
+                       uint32_t rX1, uint32_t rY1, uint32_t rZ1)
+{
+        // PKA_MOD_INV_W_EXP(rY/*q*/, rZ1, rX/*tmp*/);          // hwinv(q, z1, n, np); /* by exponent*/
+        PKA_MOD_INV(LEN_ID_N_BITS, EDW_REG_T4/*q*/, rZ1);       // PkiDbgPrintReg("rY: inv(rZ1)", rY);
+        PKA_MOD_MUL(LEN_ID_N_BITS, rX, rX1, EDW_REG_T4/*q*/);   // PkiDbgPrintReg("rX: rX1*rY", rX);
+        PKA_MOD_MUL(LEN_ID_N_BITS, rY, rY1, EDW_REG_T4/*q*/);   // PkiDbgPrintReg("rY: rY1*rY", rY);
+        // PKA_DIV(LEN_ID_N_BITS, EDW_REG_T4, rX, EDW_REG_N);   // PkiDbgPrintReg("rX: reduce", rX);
+        // PKA_DIV(LEN_ID_N_BITS, EDW_REG_T4, rY, EDW_REG_N);   // PkiDbgPrintReg("rY: reduce", rY);
+
+        return;
+}
+
+
+/**
+ * The function performs multiplication of base point by scalar:
+ *      P(x,y) = k*G(x,y).
+ *
+ *  Implemented algorithm, enhanced by A.Klimov.
+ *
+ *  The function can work with any scalar > 0 and used (for example) in Edw.
+ *  signature function.
+ *
+ *  Assuming:
+ *  PKA registers are implicitly defined in pka_ec_edw_glob_regs_def.h file, in
+ *  partial: output point P(x,y) is set in registers (EDW_REG_XS, EDW_REG_YS).
+ *  All needed data must be loaded into PKA registers in caller function.
+ *
+ * @author reuvenl (11/25/2015)
+ *
+ * @return CC_OK or an error according to mbedtls_cc_ec_mont_edw_error.h definitions.
+ */
+CCError_t PkaEcEdwScalarMultBase(
+                                uint32_t *pScalar,         /*!< [in] the pointer to the scalsr (LS word is
+                                                               leftmost one, MS word - rightmost). */
+                                size_t    scalarSizeInBits /*!< exact size of the scalar in bits. */ )
+{
+
+        /* Definitions */
+        CCError_t err = CC_OK;
+        int32_t i, carry = -1;
+        uint32_t twoBits;
+
+        if(scalarSizeInBits == 0)
+                return CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR;
+
+        /* set bits counter to scalar size, rounded up to even */
+        i = ((scalarSizeInBits + 1) & ~1) - 2;
+        twoBits = PKI_GET_TWO_BITS_FROM_WORDS_ARRAY(pScalar, i);
+
+        /*-------------------------------------------------------*/
+        /*    init point S according to MS bits of the scalar    */
+        /*-------------------------------------------------------*/
+        switch (twoBits) {
+        case 1: /* S = G2 */
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_XS, EDW_REG_XG2);
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_YS, EDW_REG_YG2);
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_TS, EDW_REG_TG2);
+                carry = -1;
+                break;
+        case 2: /* S = G2 */
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_XS, EDW_REG_XG2);
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_YS, EDW_REG_YG2);
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_TS, EDW_REG_TG2);
+                carry = 0;
+                break;
+        case 3: /* S = G4 */
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_XS, EDW_REG_XG4);
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_YS, EDW_REG_YG4);
+                PKA_COPY(LEN_ID_MAX_BITS, EDW_REG_TS, EDW_REG_TG4);
+                carry = -1;
+                break;
+        default:
+                return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+        }
+
+        /* set ZS = 1 */
+        PKA_CLEAR(LEN_ID_MAX_BITS, EDW_REG_ZS);
+        PKA_SET_BIT0(LEN_ID_N_BITS, EDW_REG_ZS, EDW_REG_ZS);
+
+        /* calculate 4N */
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_N_4, EDW_REG_N, EDW_REG_N);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_N_4, EDW_REG_N_4, EDW_REG_N_4);
+
+        /*-------------------------------------------------*/
+        /*    double/add loop according to scalar bits     */
+        /*-------------------------------------------------*/
+        for(i -= 2; i >= 0; i-= 2) {
+                int32_t swt;
+
+                /* EC doubling */
+                PkaEcEdwDoublExtExt(EDW_REG_XS, EDW_REG_YS, EDW_REG_ZS, EDW_REG_TS);
+                PkaEcEdwDoublExtExt(EDW_REG_XS, EDW_REG_YS, EDW_REG_ZS, EDW_REG_TS); // S *= 4
+
+                /* get two next MS bits of key */
+                twoBits = PKI_GET_TWO_BITS_FROM_WORDS_ARRAY(pScalar, i);
+
+                swt = carry*4 + twoBits;
+
+                /* EC points adding according to MS bits and carry */
+                switch (swt) {
+                /*negative points adding*/
+                case -4: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG4, EDW_REG_SG4, EDW_REG_MPG4);   carry =  0;   break;
+                case -3: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG2, EDW_REG_SG2, EDW_REG_MPG2);   carry = -1;   break;
+                case -2: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG2, EDW_REG_SG2, EDW_REG_MPG2);   carry =  0;   break;
+                case -1: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG,  EDW_REG_SG,  EDW_REG_MPG);    carry =  0;   break;
+                /*positive points adding*/
+                case  0: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG,  EDW_REG_DG,  EDW_REG_PG);     carry = -1;   break;
+                case  1: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG,  EDW_REG_DG,  EDW_REG_PG);     carry =  0;   break;
+                case  2: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG2, EDW_REG_DG2, EDW_REG_PG2);    carry =  0;   break;
+                case  3: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG4, EDW_REG_DG4, EDW_REG_PG4);    carry = -1;   break;
+                default:
+                        return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+                }
+
+        }
+        /* calculation of result for case that carry is -1; note: registers *
+        *  of point G4 now are used as temp registers for point S2          */
+        PkaEcEdwAddExtPrcExt(EDW_REG_SG4,EDW_REG_DG4,EDW_REG_PG4,EDW_REG_MPG4/*modif S2 -> G4*/,
+                             EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS/*modif S*/,
+                             EDW_REG_DG,EDW_REG_SG,EDW_REG_MPG/*precalc. G*/);
+        /* for afine result used registers of the point G */
+        if (carry == -1)
+                PkaEcEdwPointToAfn(EDW_REG_SG,EDW_REG_DG,  EDW_REG_SG4,EDW_REG_DG4,EDW_REG_PG4/*S2*/);
+        else // carry = 0
+                PkaEcEdwPointToAfn(EDW_REG_SG,EDW_REG_DG,  EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS/*S*/);
+
+      return err;
+}
+
+
+/**
+ * The function performs multiplication of base point by scalar of special form:
+ *      P(x,y) = k*G(x,y).
+ *
+ *  Implemented algorithm, enhanced by A.Klimov.
+ *
+ *  The function can work with scalars of special form: exact size is 255
+ *  bit and it is a multiple of 8 bit (as requiered in Edw. KeyGen algorithm).
+ *
+ *  Assuming:
+ *  1. PKA registers are implicitly defined in pka_ec_edw_glob_regs_def.h file,
+ *     in partial: output point P(x,y) is stated by registers (EDW_REG_XS,
+ *     EDW_REG_YS).
+ *  2. All needed data must be loaded into PKA registers in caller function.
+ *  3. PKA registers are defined in pka_ec_edw_glob_regs_defh file, in partial:
+ *      - output point R(x,y) shall be registers (rXR=EDW_REG_XR, rYR=EDW_REG_YR),
+ *      - input point P(X,Y) by (rXP=EDW_REG_XP, rYP=EDW_REG_YP).
+ *
+ * @author reuvenl (11/25/2015)
+ *
+ * @return CC_OK or an error according to mbedtls_cc_ec_mont_edw_error.h definitions.
+ */
+CCError_t PkaEcEdwSpecialScalarMultBase(
+                                uint32_t *pScalar,         /*!< [in] the pointer to the scalsr (LS word is
+                                                               leftmost one, MS word - rightmost). */
+                                size_t    scalarSizeInBits /*!< exact size of the scalar in bits. */ )
+{
+
+        /* Definitions */
+        CCError_t err = CC_OK;
+        int32_t carry, i, twoBits;
+        size_t  sizeInWords;
+        uint32_t word;
+
+        if(scalarSizeInBits != 255)
+                return CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR;
+
+        sizeInWords = (scalarSizeInBits + CC_BITS_IN_32BIT_WORD - 1) / CC_BITS_IN_32BIT_WORD;
+        word = pScalar[sizeInWords-1];
+
+        if((word >> 30) != 1)
+                return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+
+
+        carry = -1; // always 0 or -1
+        /* set counter to size rounded up to even */
+        i = ((scalarSizeInBits + 1) & ~1) - 2;
+
+        twoBits = PkiGetNextTwoMsBits(pScalar, &word, i);
+        /* RL ! check for EC edw25519  */
+        if (twoBits != 1)
+                return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+        i -= 2;
+
+        PKA_PRINTF("Init loop: i= %d, twoBits= %d\n", i, twoBits);
+        PKI_DBG_PRINT_REGS("S=g32: \n", EDW_REG_XS, EDW_REG_YS, EDW_REG_ZS, EDW_REG_TS);
+
+        while (1) {
+                int32_t swt;
+
+                /* get two next MS bits of key */
+                twoBits = PkiGetNextTwoMsBits(pScalar, &word, i);
+                swt = carry*4 + twoBits;
+
+                switch (swt) {
+                /*negative points add*/
+                case -4: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG16,EDW_REG_SG16,EDW_REG_MPG16);  carry =  0;   break;
+                case -3: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG8, EDW_REG_SG8, EDW_REG_MPG8);   carry = -1;   break;
+                case -2: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG8, EDW_REG_SG8, EDW_REG_MPG8);   carry =  0;   break;
+                case -1: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_DG4, EDW_REG_SG4, EDW_REG_MPG4);   carry =  0;   break;
+                /*positive points add*/
+                case  0: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG4, EDW_REG_DG4, EDW_REG_PG4);    carry = -1;   break;
+                case  1: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG4, EDW_REG_DG4, EDW_REG_PG4);    carry =  0;   break;
+                case  2: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG8, EDW_REG_DG8, EDW_REG_PG8);    carry =  0;   break;
+                case  3: PkaEcEdwAddExtPrcExt(EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS, EDW_REG_SG16,EDW_REG_DG16,EDW_REG_PG16);   carry = -1;   break;
+                default:
+                        return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+                }
+
+                PKA_PRINTF("\ni= %d b2= %02X b2c4= %3d carry= %d \n", i, twoBits, swt, carry);
+                PKI_DBG_PRINT_REGS("", EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS);
+
+                if ((i -= 2) == 0) {
+                        // RL Debug
+                        PKA_PRINTF("break: i= %d carry= %d\n", i, carry);
+                        break; /*end loop*/
+                }
+
+                /* doubling */
+                PkaEcEdwDoublExtExt(EDW_REG_XS, EDW_REG_YS, EDW_REG_ZS, EDW_REG_TS);
+                PkaEcEdwDoublExtExt(EDW_REG_XS ,EDW_REG_YS, EDW_REG_ZS, EDW_REG_TS); // s *= 4
+        }
+
+        /* check, that the LS bit pair is 00 */
+        if(PkiGetNextTwoMsBits(pScalar, &word, i) != 0) {
+                return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+        }
+
+        /* calculation of result for case that carry is -1; note: registers of *
+        *  point G16 now are used as temp registers for rXs2,rYs2,rZs2,rTs2    */
+        PkaEcEdwAddExtPrcExt(EDW_REG_SG16/*xS2*/,EDW_REG_DG16/*yS2*/,EDW_REG_PG16/*zS2*/,EDW_REG_MPG16/*tS2*/,
+                             EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS,EDW_REG_TS,  EDW_REG_DG4,EDW_REG_SG4,EDW_REG_MPG4);
+
+       if (carry == -1)
+                PkaEcEdwPointToAfn(EDW_REG_SG8,EDW_REG_DG8,  EDW_REG_SG16/*xS2*/,EDW_REG_DG16/*yS2*/,EDW_REG_PG16/*zS2*/);
+        else
+                PkaEcEdwPointToAfn(EDW_REG_SG8,EDW_REG_DG8,  EDW_REG_XS,EDW_REG_YS,EDW_REG_ZS);
+
+      return err;
+}
+
+
+
+/**
+ * The function performs two scalar mult. and add of input and base points simultaneously:
+ *         R(x,y) = a*P(x,y) + b*G(x,y), where P - point, G - base point.
+ *
+ *  Implemented algorithm of Bernstein D. etc. (version of A.Klimov).
+ *
+ *  PKA registers are defined in pka_ec_edw_glob_regs_defh file, in partial:
+ *      - output point R(x,y) shall be registers (rXR=EDW_REG_XR, rYR=EDW_REG_YR),
+ *      - input point P(X,Y) by (rXP=EDW_REG_XP, rYP=EDW_REG_YP).
+ *
+ * @author reuvenl (11/25/2015)
+ *
+ * @return CC_OK or an error according to mbedtls_cc_ec_mont_edw_error.h definitions.
+ */
+CCError_t PkaEcEdwAddTwoScalarMult(
+        uint32_t rXR, uint32_t rYR,       /*!< [out] the ID-s of registers, containing aff.
+                                               coordinates of result point P */
+        uint32_t rXP, uint32_t rYP,       /*!< [in] the ID-s of registers, containing aff.
+                                               coordinates of input point P */
+        uint32_t *pScalarA,               /*!< [in] the pointer to the scalsr A (LS word is
+                                               leftmost one, MS word - rightmost). */
+        size_t    scAsizeInBits,          /*!< exact size of the scalar A in bits. */
+        uint32_t *pScalarB,               /*!< [in] the pointer to the scalsr B (LS word is
+                                               leftmost one, MS word - rightmost). */
+        size_t    scBsizeInBits,          /*!< exact size of the scalar B in bits. */
+        const CCEcEdwDomain_t *pEcDomain /*!< [in] pointer to EC domain (curve). */)
+{
+        /* Definitions */
+        uint32_t twoBits;
+        int32_t i;
+        size_t   edwSizeWords = pEcDomain->ecModSizeInWords;
+
+        if(scAsizeInBits == 0 || scBsizeInBits == 0)
+                return CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR;
+
+        /*------------------------------------------------------------------*/
+        /* Load and calculate all EC domain and input data for scalar mult. */
+        /*------------------------------------------------------------------*/
+
+        /* set D2  */
+        PkaCopyDataIntoPkaReg(EDW_REG_D2, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecParamD, edwSizeWords);
+        PKA_MOD_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_D2, EDW_REG_D2, EDW_REG_D2);
+        /* set EDW_REG_N_4 = 4*N */
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_N_4, EDW_REG_N, EDW_REG_N);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_N_4, EDW_REG_N_4, EDW_REG_N_4);
+
+        /* set modified coordinates of EC point G  */
+        PkaCopyDataIntoPkaReg(EDW_REG_XG, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecGenX, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_YG, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecGenY, edwSizeWords);
+        PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, EDW_REG_ZG);
+        PKA_SET_BIT0(LEN_ID_N_PKA_REG_BITS, EDW_REG_ZG, EDW_REG_ZG); /*ZG = 1*/
+        PkaCopyDataIntoPkaReg(EDW_REG_TG, LEN_ID_N_PKA_REG_BITS, pEcDomain->ecGenT, edwSizeWords);
+
+        /* load EC G point in precalculated form */
+        PkaCopyDataIntoPkaReg(EDW_REG_SG1, LEN_ID_N_PKA_REG_BITS, pEcDomain->sg, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_DG1, LEN_ID_N_PKA_REG_BITS, pEcDomain->dg, edwSizeWords);
+        PkaCopyDataIntoPkaReg(EDW_REG_PG1, LEN_ID_N_PKA_REG_BITS, pEcDomain->pg, edwSizeWords);
+
+        /* convert input point P to precalculated form: sp=yp+xp; dp=yp-xp; pp=d2*xp*yp mod n */
+        PKA_MOD_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_SP, rYP, rXP);
+        //PKA_ADD(LEN_ID_N_PKA_REG_BITS, EDW_REG_DP, rYP, EDW_REG_N);
+        PKA_MOD_SUB(LEN_ID_N_PKA_REG_BITS, EDW_REG_DP, rYP, rXP);
+        PKA_MOD_MUL(LEN_ID_N_BITS, EDW_REG_PP, EDW_REG_D2, rXP);
+        PKA_MOD_MUL(LEN_ID_N_BITS, EDW_REG_PP, EDW_REG_PP, rYP);
+        // P+G
+        PkaEcEdwAddExtPrcExt(EDW_REG_XPG, EDW_REG_YPG, EDW_REG_ZPG, EDW_REG_TPG, /*modif. P+G*/
+                             EDW_REG_XG,  EDW_REG_YG,  EDW_REG_ZG,  EDW_REG_TG,  /*modif. G*/
+                             EDW_REG_SP,  EDW_REG_DP,  EDW_REG_PP );             /*precalc. P*/
+
+        /*------------------------------------------------*/
+        /* load start points according to scalars MS bits */
+        /*------------------------------------------------*/
+
+        i = CC_MAX(scAsizeInBits, scBsizeInBits) - 1;
+        twoBits = (PKI_GET_BIT_FROM_WORDS_ARRAY(pScalarA, i) << 1) +
+                  PKI_GET_BIT_FROM_WORDS_ARRAY(pScalarB, i);
+
+        switch (twoBits) {
+        case 1: // 01: r = G
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, rXR, EDW_REG_XG);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, rYR, EDW_REG_YG);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EDW_REG_ZR, EDW_REG_ZG);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EDW_REG_TR, EDW_REG_TG);
+                break;
+        case 2: // 10: r = P
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, rXR, rXP);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, rYR, rYP);
+                PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, EDW_REG_ZR);
+                PKA_SET_BIT0(LEN_ID_N_PKA_REG_BITS, EDW_REG_ZR, EDW_REG_ZR);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_TR, rXR, rYR);
+                break;
+        case 3: // 11: r = P+G
+                /* set result point R = P+G*/
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, rXR, EDW_REG_XPG);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, rYR, EDW_REG_YPG);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EDW_REG_ZR, EDW_REG_ZPG);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EDW_REG_TR, EDW_REG_TPG);
+                break;
+
+        default:
+                return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+        }
+
+        /*------------------------------------------------------------------*/
+        /*    Perform two points scalar mult. and adding simultaneously     */
+        /*------------------------------------------------------------------*/
+
+        while (--i >= 0) {
+
+                /* get two MSBits from scalars A snd B */
+                twoBits = (PKI_GET_BIT_FROM_WORDS_ARRAY(pScalarA, i) << 1) +
+                           PKI_GET_BIT_FROM_WORDS_ARRAY(pScalarB, i);
+
+                /* point doubling */
+                PkaEcEdwDoublExtExt(rXR, rYR, EDW_REG_ZR, EDW_REG_TR);
+
+                switch (twoBits) {
+                case 0:
+                        break;
+                case 1:
+                        // 10: r += G
+                        PkaEcEdwAddExtPrcExt(rXR, rYR, EDW_REG_ZR, EDW_REG_TR,
+                                             rXR, rYR, EDW_REG_ZR, EDW_REG_TR,
+                                             EDW_REG_SG1, EDW_REG_DG1, EDW_REG_PG1);
+                        break;
+                case 2:
+                        // 01: r += P
+                        PkaEcEdwAddExtPrcExt(rXR, rYR, EDW_REG_ZR, EDW_REG_TR,
+                                             rXR, rYR, EDW_REG_ZR, EDW_REG_TR,
+                                             EDW_REG_SP, EDW_REG_DP, EDW_REG_PP);
+                        break;
+                case 3:
+                        // 11: r += P+G
+                        PkaEcEdwAddExtExtExt(rXR,  rYR,  EDW_REG_ZR,  EDW_REG_TR,
+                                             rXR,  rYR,  EDW_REG_ZR,  EDW_REG_TR,
+                                             EDW_REG_XPG, EDW_REG_YPG, EDW_REG_ZPG, EDW_REG_TPG);
+                        break;
+                default:
+                        return CC_EC_EDW_INVALID_SCALAR_DATA_ERROR;
+                }
+        }
+
+        /* convert result to affine */
+        PkaEcEdwPointToAfn(rXR, rYR,/*out*/ rXR,   rYR, EDW_REG_ZR/*in*/);
+
+        return CC_OK;
+}
+
+/**
+ * The function calculated coordinate X of compressed EC point,
+ * using the given coordinate Y.
+ *
+ * Implemented algorithm Bernstain D. etc (stated by Klimov A.).
+ *
+ * @author reuvenl (1/11/2016)
+ *
+ * Imlicit parametrs
+ * @param  [out] rX - ID of PKA register for output decompressed coordinate X.
+ * @param  [in/out] rY - ID of PKA register, containing compressed/decompressed coordinate Y.
+ * @param  [in] isOddX - indication: "Is the coordinate X odd".
+ *
+ */
+void PkaEcEdwDecompress(uint32_t rX, uint32_t rY,
+                        uint32_t isOddX) /*!< one bit indication: "Is the coordinate X odd" */
+{
+        uint32_t  bit0; /*used to read values from regs. */
+
+        /* decompress: (YP) -> (XP,YP,ZP=1,TP) */
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T3, rY, rY);                 // hwmmul(t3, y, y, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T4, EDW_REG_T3, EDW_REG_D);  // hwmmul(t4, t3, ec_d, n, np);
+        PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, EDW_REG_T3, EDW_REG_T3, 1);       // hwdec(t3, t3);
+        PKA_ADD_IM(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, EDW_REG_T4, 1);       // hwinc(t4, t4);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T, EDW_REG_T4, EDW_REG_T4);  // hwmmul(t, t4, t4, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T, EDW_REG_T4, EDW_REG_T);   // hwmmul(t, t4, t, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, EDW_REG_T, EDW_REG_T);           // hwmmul(x, t, t, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, rX, EDW_REG_T4);                 // hwmmul(x, x, t4, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T5, rX, EDW_REG_T3);         // hwmmul(t5, x, t3, n, np);
+        PKA_MOD_EXP(LEN_ID_N_BITS, rX, EDW_REG_T5, EDW_REG_Q58);            // hwmexp(x, t5, q58, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, rX, EDW_REG_T3);                 // hwmmul(x, x, t3, n, np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, rX, EDW_REG_T);                  // hwmmul(x, x, t, n,np);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EDW_REG_T, rX, rX);                  // hwmmul(t, x, x, n,np);
+        PKA_MOD_MUL_ACC(LEN_ID_N_BITS, EDW_REG_T, EDW_REG_T4, EDW_REG_T, EDW_REG_T3); // hwmlap(t,t4, t, t3, n, np, 0);
+
+        PKA_DIV(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, EDW_REG_T, EDW_REG_N);
+        PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, EDW_REG_T, 0/*im.val*/, bit0/*status*/);
+        if(bit0) {
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX, rX, EDW_REG_SQRTM1);
+        }
+
+        PKA_DIV(LEN_ID_N_PKA_REG_BITS, EDW_REG_T4, rX, EDW_REG_N);
+        PKA_READ_BIT0(LEN_ID_N_PKA_REG_BITS, rX, bit0/*bit0*/);
+        if(bit0 != isOddX)
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, rX, EDW_REG_N, rX);
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/pka_ec_edw_glob_regs_def.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/pka_ec_edw_glob_regs_def.h
new file mode 100644
index 0000000..e86f1d3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_edw/pka_ec_edw_glob_regs_def.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ #ifndef PKA_EC_EDW_GLOB_REGS_DEF_H
+ #define PKA_EC_EDW_GLOB_REGS_DEF_H
+
+ /*! Note: Don't change registers ID-s ! */
+
+ /*! Define global PKA registers ID-s used in EC Edwards operations */
+
+ /*--------------------------*/
+ /* Common EC Edw. registers */
+ /*--------------------------*/
+ #define EDW_REG_N       PKA_REG_N  /* EC mod. */
+ #define EDW_REG_NP      PKA_REG_NP /* EC Barr.tag */
+ #define EDW_REG_T3      2 /* 4 temp regs. */
+ #define EDW_REG_T4      3
+ #define EDW_REG_T5      4
+ #define EDW_REG_T6      5
+ #define EDW_REG_N_4     6  /* from domain */
+ #define EDW_REG_D2      7  /* from domain */
+
+ /*---------------------------------------------*/
+ /* EC Edw. registers for ScalarMultBase        */
+ /* and Signature functions                     */
+ /*---------------------------------------------*/
+ #define EDW_REG_XS      8 /* out point s */
+ #define EDW_REG_YS      9
+ #define EDW_REG_ZS     10
+ #define EDW_REG_TS     11
+ #define EDW_REG_SG4    12 /* precalc. point g4 */
+ #define EDW_REG_DG4    13
+ #define EDW_REG_PG4    14
+ #define EDW_REG_MPG4   15
+ /* for special scal.Mult only */
+ #define EDW_REG_SG8    16 /* precalc. point g8 */
+ #define EDW_REG_DG8    17
+ #define EDW_REG_PG8    18
+ #define EDW_REG_MPG8   19
+ #define EDW_REG_SG16   20 /* precalc. point g16 */
+ #define EDW_REG_DG16   21
+ #define EDW_REG_PG16   22
+ #define EDW_REG_MPG16  23
+
+/* Registers, used in EC EDW Sign and Verify */
+ #define EDW_REG_EPH_PRIV  EDW_REG_T3
+ #define EDW_REG_INTEGR    EDW_REG_T4
+ #define EDW_REG_USER_PRIV EDW_REG_T5
+ #define EDW_REG_SIGN      EDW_REG_T6
+// #define EDW_REG_TMP       EDW_REG_N_4
+
+  /*------------------------------*/
+  /* EC Edw. common registers for */
+  /*  ScalarMultBase functions    */
+  /*------------------------------*/
+#define EDW_REG_SG    EDW_REG_SG8  /* pont g */
+#define EDW_REG_DG    EDW_REG_DG8
+#define EDW_REG_PG    EDW_REG_PG8
+#define EDW_REG_MPG   EDW_REG_MPG8
+#define EDW_REG_SG2   EDW_REG_SG16 /* pont g2 */
+#define EDW_REG_DG2   EDW_REG_DG16
+#define EDW_REG_PG2   EDW_REG_PG16
+#define EDW_REG_MPG2  EDW_REG_MPG16
+
+/* for modified points g2, g4: x,y,z=1,t */
+#define EDW_REG_XG2   EDW_REG_T3
+#define EDW_REG_YG2   EDW_REG_T4
+#define EDW_REG_TG2   EDW_REG_T5
+#define EDW_REG_XG4   EDW_REG_T6
+#define EDW_REG_YG4   28
+#define EDW_REG_TG4   29
+
+ /*-------------------------------------------------*/
+ /* EC Edw. registers for TwoScalarMultAdd function */
+ /*-------------------------------------------------*/
+ /*aff. input point P (xp,yp)*/
+ #define EDW_REG_XP      8
+ #define EDW_REG_YP      9
+ /*extended point P: sp,dp,pp*/
+ #define EDW_REG_SP     10
+ #define EDW_REG_DP     11
+ #define EDW_REG_PP     12
+
+ /*extended result point R (xr,yr,zr,tr)*/
+ #define EDW_REG_XR     13
+ #define EDW_REG_YR     14
+ #define EDW_REG_ZR     15
+ #define EDW_REG_TR     16
+ /*modified form of base point G */
+ #define EDW_REG_XG     17
+ #define EDW_REG_YG     18
+ #define EDW_REG_ZG     19
+ #define EDW_REG_TG     20
+ /*precalculated form of base point G */
+ #define EDW_REG_SG1    21
+ #define EDW_REG_DG1    22
+ #define EDW_REG_PG1    23
+ /* modified point PG=P+G*/
+ #define EDW_REG_XPG    24 /*EDW_REG_ZG */
+ #define EDW_REG_YPG    25 /*EDW_REG_TG*/
+ #define EDW_REG_ZPG    26 /*EDW_REG_XG*/
+ #define EDW_REG_TPG    27 /*EDW_REG_TG*/
+
+ /*Registers, used in decompression */
+ #define EDW_REG_T      28 /*temp reg.*/
+ /* parameters from domain */
+ #define EDW_REG_Q58    EDW_REG_XPG
+ #define EDW_REG_SQRTM1 EDW_REG_YPG
+ #define EDW_REG_D      EDW_REG_ZPG
+
+
+// #define EC_EDW_PKA_REGS_USED 28 /* besides 2 PKA temp regs. 30,31 */
+#endif
+
+// I n, np, t3, t4, t5, t6, n_4, d2, q58, sqrtm1; // 10 regs
+//I xg,yg,zg,tg, xg32,yg32,zg32,tg32; // extended coordinates of G and 32G
+//I sg, dg, pg, mpg; I sg4, dg4, pg4, mpg4; I sg8, dg8, pg8, mpg8; I sg16, dg16, pg16, mpg16; // precalculated coordinates: y+x, y-x, 2xy, -2xy of G, 4G, 8G, 16G
+//void hwsmulg(I xs, I ys, I k)
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont.c
new file mode 100644
index 0000000..6725bc1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_hal_plat.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_error.h"
+#include "cc_ec_mont_api.h"
+
+#include "pka_hw_defs.h"
+#include "pka.h"
+#include "pki.h"
+#include "pka_error.h"
+#include "ec_mont.h"
+#include "pka_ec_mont_glob_regs_def.h"
+#include "cc_int_general_defs.h"
+
+/* global data definitions */
+extern CC_PalMutex CCAsymCryptoMutex;
+
+
+/*********************************************************************/
+/*!
+@brief The function performs EC Montgomery (Curve25519) scalar multiplication:
+       resPoint = scalar * point.
+
+ @return CCError_t
+*/
+CCError_t EcMontScalarmult(
+                                uint32_t *resPoint,       /* [out] pointer to result point (compressed,
+                                                                   the size = ec modulus size) */
+                                uint32_t *scalar,         /* [in] pointer to the scalar, the size = ec order size) */
+                                uint32_t *inPoint,        /* [in] pointer to the input point (compressed,
+                                                                       the size = ec modulus size)  */
+                                const CCEcMontDomain_t *pEcDomain /* [in] pointer to EC domain (curve). */)
+{
+        CCError_t err = CC_OK;
+        uint32_t pkaRegsUsed = EC_MONT_PKA_REGS_USED;
+        uint32_t scalarSizeBits;
+
+        /* get the hardware semaphore  */
+        err = CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE);
+        if (err != CC_SUCCESS) {
+            CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* verify that the device is not in fatal error state before activating the PKA engine */
+        CC_IS_FATAL_ERR_ON(err);
+        if (err == CC_TRUE) {
+                /* release the hardware semaphore */
+                if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != CC_SUCCESS) {
+                        CC_PalAbort("Fail to release mutex\n");
+                }
+                return PKA_FATAL_ERR_STATE_ERROR;
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        err = CC_IS_WAKE;
+        if (err != CC_SUCCESS) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* init PKA, mapping and sizes tables */
+        err = PkaInitPka(pEcDomain->ecModSizeInBits, 0,
+                          &pkaRegsUsed/*regs.count*/);
+
+        if (err != CC_SUCCESS) {
+                goto End;
+        }
+
+        scalarSizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(
+                                            scalar, pEcDomain->ecOrdSizeInWords);
+
+        /* call EC scalar multiplication (with ladder) function */
+        err = EcMontPkaScalMultWithLadder(
+                        resPoint,
+                        scalar,
+                        scalarSizeBits,
+                        inPoint,
+                        pEcDomain);
+
+End:
+
+        PkaFinishAndMutexUnlock(pkaRegsUsed);
+        return err;
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont.h
new file mode 100644
index 0000000..5b2f835
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef EC_MONT_H_H
+#define EC_MONT_H_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_ec_mont_api.h"
+#include "ec_mont_local.h"
+
+
+/*****************   Definitions    ***********************/
+
+/*********************************************************************/
+/*!
+@brief The function performs EC Montgomery (Curve25519) scalar multiplication:
+       resPoint = scalar * point.
+
+       Libsodium analog: crypto_scalarmult_curve25519() function
+
+ @return CCError_t
+*/
+CCError_t EcMontScalarmult(
+                                uint32_t *resPoint,       /* [out] pointer to result point (compressed,
+                                                                   the size = ec modulus size) */
+                                uint32_t *scalar,         /* [in] pointer to the scalar, the size = ec order size) */
+                                uint32_t *inPoint,        /* [in] pointer to the input point (compressed, the
+                                                                  size = ec modulus size)  */
+                                const CCEcMontDomain_t *pEcDomain /* [in] pointer to EC domain (curve). */);
+
+/*********************************************************************/
+/*!
+ * The function performs input/output parameters in/from PKA to perform scalar
+ * multiplication of EC_MONT point (using ladder algorithm).
+ *
+ *         resPoint(X,_) = k*inPoint(X,_), where:
+ *         both points are given in compressed form (only X coordinates ) with
+ *         LE order of words.
+ *
+ *         Assuming: the PKA HW is turned on and initialized yet.
+ *
+ * \param resPointX -  the pointer to result EC_MONT point.
+ * \param scalar -     the pointer to scalar (LE order of words).
+ * \param scalarSizeBits - the size of scalar in bits.
+ * \param inPointX -   the pointer to input ECMONT point (coord. X only).
+ *
+ * \return CCError_t
+ */
+CCError_t EcMontPkaScalMultWithLadder(
+                        uint32_t  *resPoint,  /*!< [out] pointer to result EC point (coordinate X). */
+                        uint32_t  *scalar,    /*!< [in] pointer to scalar. */
+                        uint32_t   scalarSizeBits, /*!< [in] scalar size in bits. */
+                        uint32_t  *inPoint,   /*!< [in] pointer to input ECMONT point (coordinate X). */
+                        const CCEcMontDomain_t *pEcDomain); /*!< [in] pointer to EC domain (curve). */
+
+
+
+#ifdef __cplusplus
+}
+
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont_domain_curve25519.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont_domain_curve25519.c
new file mode 100644
index 0000000..1064a97
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont_domain_curve25519.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "cc_ec_mont_api.h"
+#include "ec_mont_local.h"
+
+
+/*!
+@file
+@brief The file contains Curve25519 domain parameters and get-function.
+*/
+
+
+/* EC Montgomery curve domain structure type:
+   Elliptic curve: y^2 = x^3 + Ax^2 + x over prime fild GFp
+typedef struct {
+
+        // EC prime modulus P
+        uint32_t ecModP[CC_ECMONT_EDW_MODULUS_MAX_SIZE_IN_BYTES];
+        // modulus size in bits
+        uint32 ecModSizeInBits;
+        uint32_t ecModSizeInBits;
+        // EC generator coordinates X, Y
+        uint32_t ecGenX[CC_ECMONT_EDW_MODULUS_MAX_SIZE_IN_BYTES];
+        uint32_t ecGenY[CC_ECMONT_EDW_MODULUS_MAX_SIZE_IN_BYTES];
+        // EC generator order
+        uint32_t ecOrdN[CC_ECMONT_EDW_MODULUS_MAX_SIZE_IN_BYTES];
+        // EC generator order size in bits
+        uint32_t ecOrdSizeInBits;
+        uint32_t ecOrdSizeInWords;
+        // EC generator order's cofactor
+        uint32_t ecOrdCofactor;
+        // EC equation parameter; (A+2)/4 - for Curve25519
+        uint32_t ecParam[CC_ECMONT_EDW_MODULUS_MAX_SIZE_IN_BYTES];
+        // Barrett tags for EC modulus and generator order
+        uint32_t ecModBarrTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+        uint32_t ecOrdBarrTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+        // parameters for bits setting in scalar multiplication LS/MS words
+        uint32_t scalarLsWordAndValue;
+        uint32_t scalarMsWordAndValue;
+        uint32_t scalarMsWordOrValue;
+        // EC Domain ID - enum
+        CCEcMontDomainId_t domainId;
+        // EC Domain name
+        int8_t  name[20];
+
+} CCEcEdwDomain_t;
+*/
+
+
+/*!> EC Montgomery curve25519 domain parameters.                              *
+*    The data is in little endian order of words: LS-Word is most left one    */
+static const CCEcMontDomain_t  EcMontDomainCurve25519 = {
+        /* Prime modulus P = (2^255 - 19) =                                   *
+        *  0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED */
+        {0xffffffed,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0x7fffffff},
+        /* modulus size in bits and words */
+        255, 8,
+        /* EC generator G coordinate: X = 0x9  */
+        {0x00000009},
+        /* EC generator G coordinate: Y=                           *
+        *  0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9 */
+    {0x7eced3d9,0x29e9c5a2,0x6d7c61b2,0x923d4d7e,0x7748d14c,0xe01edd2c,0xb8a086b4,0x20ae19a1},
+        /* EC_MONT generator order with cofactor 8:  *
+        *  0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED */
+        {0x5cf5d3ed,0x5812631a,0xa2f79cd6,0x14def9de,0x00000000,0x00000000,0x00000000,0x10000000},
+        253, 8, /* EC_MONT generator order size in bits and IN words */
+        8, /* EC order cofactor */
+        {0x0001db42}, /* parameter (a+2)/4 = 0x1DB42 */
+
+        /*---------------------------------------------------*/
+        /*Barrett tags for EC modulus and order */
+#ifdef CC_SUPPORT_PKA_64_16
+        {0x00000000,0x00000000,0x00000080}, /*0x800000000000000000 - for modulus*/
+        {0xFFFFFFFF,0xFFFFFFFF,0x0000003F}, /*0x3FFFFFFFFFFFFFFFFF - for EC order*/
+#else  // CC_SUPPORT_PKA_128_32
+        {0x00000000,0x00000000,0x00000000,0x00000000,0x00000080}, /*0x8000000000000000000000000000000000  - for modulus*/
+        {0x000003FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFAC8}, /*0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAC8 - for EC order*/
+#endif
+        CC_EC_MONT_DOMAIN_CURVE_25519, /* EC Domain Identifier - enum */
+        "Curve25519",  /* EC Domain name */
+        /* scalar bit setting parameters */
+        0xF8,  /* SCALAR_LSB_AND_VALUE (248)*/
+        0x7F,  /* SCALAR_MSB_AND_VALUE (127)*/
+        0x40  /* SCALAR_MSB_OR_VALUE (64)*/
+};
+
+/*!<
+ @brief    the function returns the domain pointer if the domain is supported for the product,
+       otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcMontDomain_t *EcMontGetCurve25519Domain(void)
+{
+    return &EcMontDomainCurve25519;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont_local.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont_local.h
new file mode 100644
index 0000000..f9c5f76
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/ec_mont_local.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef EC_MONT_LOCAL_H
+#define EC_MONT_LOCAL_H
+
+#include "cc_pal_types.h"
+#include "cc_pka_defs_hw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+@file
+@brief This file contains the CryptoCell APIs used for EC MONT (Montgomery Curve25519) algorithms.
+
+@note  Algorithms of Montgomery and Edwards elliptic curves cryptography are developed by
+       Daniel.J.Bernstein and described in SW library "NaCl" (Networking and
+       Cryptographic Library).
+*/
+
+
+/******************************************************************************/
+/**          EC Montgomery domain APIs:                                       */
+/******************************************************************************/
+
+/*!< EC Montgomery curve domain structure type:
+     Elliptic curve over prime fild GFp: y^2 = x^3 + Ax^2 + x */
+typedef struct {
+        /*!< EC prime modulus P */
+        uint32_t ecModP[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< modulus size in bits */
+        uint32_t ecModSizeInBits;
+        /*!< modulus size in words */
+        uint32_t ecModSizeInWords;
+        /*!< EC generator coordinates X */
+        uint32_t ecGenX[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC generator coordinates Y */
+        uint32_t ecGenY[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC generator order.  */
+        uint32_t  ecOrdN[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< EC generator order size in bits */
+        uint32_t ecOrdSizeInBits;
+        /*!< EC generator order size in words */
+        uint32_t ecOrdSizeInWords;
+        /*!< EC generator order's cofactor */
+        uint32_t ecOrdCofactor;
+        /*!< EC equation parameter; (A+2)/4 - for Curve25519 */
+        uint32_t ecParam[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+        /*!< Barrett tags for EC modulus */
+        uint32_t ecModBarrTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+        /*!< Barrett tags for EC generator order */
+        uint32_t ecOrdBarrTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+        /*!< EC Domain ID - enum */
+         CCEcMontDomainId_t domainId;
+        /*!< EC Domain name */
+        int8_t  name[20];
+        /* parameters for bits setting in scalar multiplication LS/MS words */
+        uint8_t scalarLsByteAndValue;
+        uint8_t scalarMsByteAndValue;
+        uint8_t scalarMsByteOrValue;
+} CCEcMontDomain_t;
+
+
+
+/*!<
+ @brief    the function returns the domain pointer if the domain is supported for the product,
+       otherwise return NULL
+ @return   return domain pointer or NULL
+
+*/
+const CCEcMontDomain_t *EcMontGetCurve25519Domain(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/pka_ec_mont.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/pka_ec_mont.c
new file mode 100644
index 0000000..9204f5d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/pka_ec_mont.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_hal_plat.h"
+#include "cc_common_math.h"
+#include "mbedtls_cc_ec_mont_edw_error.h"
+#include "cc_ec_mont_api.h"
+#include "ec_mont_local.h"
+
+#include "pka_hw_defs.h"
+#include "pki.h"
+#include "pka.h"
+#include "pka_error.h"
+#include "pka_ec_mont_glob_regs_def.h"
+
+
+/*!
+ * The function executes scalar multiplication by ladder algorithm and PKA HW.
+ *
+ *    Note: 1. SCA protection is not active.
+ *          2. Assumed that PKA was initialized according to EC modulus
+ *             and registers definitions in above included ...def.h file before
+ *             calling the function.
+ *          3. Scalar buffer size in words is equall to EC order (modulus) size.
+ *
+ *  Implicitly defined in/out parameters (registers ID-s):
+ *    EC_MONT_REG_RES [out] - ID of PKA register for output result point in
+ *                  compressed form (coordinate X).
+ *    EC_MONT_REG_X1 [in] - ID of PKA register, containing the input point in
+ *             compressed form (coordinate X1).
+ *
+ * \return CCError_t
+ */
+static CCError_t EcMontPkaScalarMultWithLadderExe(
+                                                   uint32_t *scalar,        /*!< [in] pointer to scalar in LE order of bytes. */
+                                                   uint32_t  scalarSizeBits /*!< [in] exact scalar size in bits. */)
+{
+        /* DEFINITIONS */
+
+        CCError_t err = CC_OK;
+        uint32_t swap = 0;
+        uint32_t tmp, currBit;
+        int32_t  i;
+        uint32_t rX2, rX3, rZ2, rZ3; /* variable regisres ID-s */
+
+        /*   FUNCTION LOGIC  */
+
+        /* set internally used registers: x2=1; z2=0; x3=x1; z3=1; */
+        rX2 = EC_MONT_REG_X2; rX3 = EC_MONT_REG_X3; rZ2 = EC_MONT_REG_Z2; rZ3 = EC_MONT_REG_Z3;
+
+        /* clean 4 registers */
+        PkaClearBlockOfRegs(rX2/*firstReg*/, 4/*countOfRegs*/, LEN_ID_N_PKA_REG_BITS);
+        /* set */
+        PKA_SET_BIT0(LEN_ID_N_PKA_REG_BITS, rX2, rX2);
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, rX3, EC_MONT_REG_X1);
+        PKA_SET_BIT0(LEN_ID_N_PKA_REG_BITS, rZ3, rZ3);
+
+        /* set EC_MONT_REG_N4 = 4*Mod */
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_N4, EC_MONT_REG_N, EC_MONT_REG_N);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_N4, EC_MONT_REG_N4, EC_MONT_REG_N4);
+
+        i = scalarSizeBits - 1;
+        tmp = scalar[(i+CC_BITS_IN_32BIT_WORD-1) / CC_BITS_IN_32BIT_WORD - 1];
+
+        for (; i >= 0; --i) {
+
+                /* get next word of scalar */
+                if ((i & (CC_BITS_IN_32BIT_WORD - 1)) == (CC_BITS_IN_32BIT_WORD - 1) ) {
+                        tmp = scalar[i / CC_BITS_IN_32BIT_WORD];
+                }
+
+                /* get next bit of scalar */
+                currBit = (tmp >> (i & (CC_BITS_IN_32BIT_WORD - 1))) & 1;
+
+                /* c of registers ID-s */
+                swap ^= currBit;                                                                // PkiDbgPrintReg("\ni=%3d b=%3d 1-swap=%3d ", i, currBit, swap);
+                PkiConditionalSecureSwapUint32(&rX2, &rX3, swap);
+                PkiConditionalSecureSwapUint32(&rZ2, &rZ3, swap);
+                swap = currBit;                                                                 // PkiDbgPrintReg("2-swap=%3d  start HW loop: \n", swap);
+
+                /* ladder: (X1,1),(X2,Z2),(X3,Z3) -> (X2,Z2),(X3,Z3) */
+
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, rZ3);            // PkiDbgPrintReg("t2: -z3 =", EC_MONT_REG_T2);
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T, rX3, EC_MONT_REG_T2);             // PkiDbgPrintReg("t: x3+t2 =", EC_MONT_REG_T);
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, rZ2);            // PkiDbgPrintReg("t2: -z2= ", EC_MONT_REG_T2);
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T1, rX2, EC_MONT_REG_T2);            // PkiDbgPrintReg("t1: x2+t2 =", EC_MONT_REG_T1);
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, rX2, rZ2, rX2);                                  // PkiDbgPrintReg("x2: z2+x2 =", rX2);
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, rZ2, rX3, rZ3);                                  // PkiDbgPrintReg("z2: x3+z3 =", rZ2);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ3, EC_MONT_REG_T, rX2);                        // PkiDbgPrintReg("z3: t*x2 =", rZ3);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ2, EC_MONT_REG_T1, rZ2);                       // PkiDbgPrintReg("z2: t1*z2 =", rZ2);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EC_MONT_REG_T, EC_MONT_REG_T1, EC_MONT_REG_T1);  // PkiDbgPrintReg("t: t1*t1 =", EC_MONT_REG_T);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, EC_MONT_REG_T1, rX2, rX2);                       // PkiDbgPrintReg("t1: x2*x2 =", EC_MONT_REG_T1);
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, rX3, rZ3, rZ2);                                  // PkiDbgPrintReg("x3: z3+z2 =", rX3);
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, rZ2);            // PkiDbgPrintReg("t2: -z2 =", EC_MONT_REG_T2);
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, rZ2, rZ3, EC_MONT_REG_T2);                       // PkiDbgPrintReg("z2: z3+t2 =", rZ2);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX2, EC_MONT_REG_T1, EC_MONT_REG_T);             // PkiDbgPrintReg("x2: t1*t =", rX2);
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T2, EC_MONT_REG_N4, EC_MONT_REG_T);  // PkiDbgPrintReg("t2: -t =", EC_MONT_REG_T2);
+                PKA_ADD(LEN_ID_N_PKA_REG_BITS, EC_MONT_REG_T1, EC_MONT_REG_T1, EC_MONT_REG_T2); // PkiDbgPrintReg("t1: t1+t2 =", EC_MONT_REG_T1);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ2, rZ2, rZ2);                                  // PkiDbgPrintReg("z2: z2*z2 =", rZ2);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rX3, rX3, rX3);                                  // PkiDbgPrintReg("x3: x3*x3 =", rX3);
+                PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, EC_MONT_REG_T, EC_MONT_REG_A24,
+                                    EC_MONT_REG_T1, EC_MONT_REG_T);                             // PkiDbgPrintReg("t: a24*t1+t= ", EC_MONT_REG_T);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ3, EC_MONT_REG_X1, rZ2);                       // PkiDbgPrintReg("z3: x1*z2 =", rZ3);
+                PKA_MOD_MUL_NFR(LEN_ID_N_BITS, rZ2, EC_MONT_REG_T1, EC_MONT_REG_T);             // PkiDbgPrintReg("z2: t1*t =", rZ2);
+        }
+        /* Swapping of registers ID-s */
+        PkiConditionalSecureSwapUint32(&rX2, &rX3, swap);
+        PkiConditionalSecureSwapUint32(&rZ2, &rZ3, swap);
+        PKA_MOD_INV_W_EXP(EC_MONT_REG_T, rZ2, rX3/*as temp*/);                                  // PkiDbgPrintReg("t: 1/z2 =", EC_MONT_REG_T);
+        PKA_MOD_MUL(LEN_ID_N_BITS, EC_MONT_REG_RES, rX2, EC_MONT_REG_T);                        // PkiDbgPrintReg("r: x2*t =", EC_MONT_REG_RES);
+// ???       PKA_REDUCE(LEN_ID_N_BITS, EC_MONT_REG_RES, EC_MONT_REG_RES);                             PkiDbgPrintReg("r: r reduced =", EC_MONT_REG_RES);
+
+        return err;
+}
+
+
+/*!
+ * The function performs input/output parameters for scalar
+ * multiplication using ladder algorithm.
+ *
+ *         resPoint(X,_) = k*inPoint(X,_), where:
+ *         both points are given in compressed form (only X coordinates ) with
+ *         LE order of the words.
+ *
+ *         Assuming: the PKA HW is turned on and initialized yet.
+ *
+ * \return CCError_t
+ */
+CCError_t EcMontPkaScalMultWithLadder(
+                                       uint32_t  *resPoint,  /*!< [out] pointer to result EC point (coordinate X). */
+                                       uint32_t  *scalar,    /*!< [in] pointer to scalar. */
+                                       uint32_t   scalarSizeBits, /*!< [in] scalar size in bits. */
+                                       uint32_t  *inPoint,   /*!< [in] pointer to input ECMONT point (coordinate X). */
+                                       const CCEcMontDomain_t *pEcDomain /*!< [in] pointer to EC domain (curve). */)
+{
+        /* Definitions */
+
+        CCError_t err = CC_OK;
+        uint32_t scalarSizeWords;
+
+        /* set scalar bits according to EC Montgomery algorithm:
+           byte[31] = (byte[31] & 127) | 64; byte[0] &= 248; */
+        scalarSizeWords = (scalarSizeBits + CC_BITS_IN_32BIT_WORD - 1) / CC_BITS_IN_32BIT_WORD;
+
+        /* ********************************************* */
+        /* load all needed data to defined pka registers */
+        /* ********************************************* */
+
+        /* EC modulus */
+        PkaCopyDataIntoPkaReg(EC_MONT_REG_N/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
+                              pEcDomain->ecModP/*src*/, pEcDomain->ecModSizeInWords);
+        /*Barr. tag.*/
+        PkaCopyDataIntoPkaReg(EC_MONT_REG_NP/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
+                              pEcDomain->ecModBarrTag/*src*/,
+                              CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS/*Barr.tag.*/);
+        /*EC parameter*/
+        PkaCopyDataIntoPkaReg(EC_MONT_REG_A24/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
+                              pEcDomain->ecParam/*src*/, pEcDomain->ecModSizeInWords/*param.size*/);
+        /* input point X1 */
+        PkaCopyDataIntoPkaReg(EC_MONT_REG_X1/*dstReg*/, LEN_ID_N_PKA_REG_BITS,
+                              inPoint/*src*/, pEcDomain->ecModSizeInWords);
+
+
+        /*--------------------------------------------------------------------*
+         * perform EC scalar multiplication:  used PKA registers defined in   *
+         *   "pka_ec_mont_glob_regs_def."h file: output is EC_MONT_REG_RES    *
+         *--------------------------------------------------------------------*/
+        err = EcMontPkaScalarMultWithLadderExe(scalar, scalarSizeBits);
+        if (err)
+                goto EndCommand;
+
+        /* output result point */
+        PkaCopyDataFromPkaReg(resPoint/*dst*/, scalarSizeWords, EC_MONT_REG_RES/*srcReg*/);
+
+EndCommand:
+        return err;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/pka_ec_mont_glob_regs_def.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/pka_ec_mont_glob_regs_def.h
new file mode 100644
index 0000000..1abcd0a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_mont/pka_ec_mont_glob_regs_def.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ #ifndef PKA_EC_MONT_GLOB_REGS_DEF_H
+ #define PKA_EC_MONT_GLOB_REGS_DEF_H
+
+ /*! Note: Don't change registers ID-s ! */
+
+ /*! Define global PKA registers ID-s used in EC Montgomry operations */
+ /* global regs. */
+ #define EC_MONT_REG_N     PKA_REG_N  /* EC mod. */
+ #define EC_MONT_REG_NP    PKA_REG_NP  /* EC Barr.tag */
+ #define EC_MONT_REG_T     2
+ #define EC_MONT_REG_T1    3
+ #define EC_MONT_REG_T2    4
+ #define EC_MONT_REG_N4    5  /* 4*mod */
+ #define EC_MONT_REG_A24   6  /* ec parameter (A+2)/4 */
+ /*! scalarmult in/out and local regs. */
+ #define EC_MONT_REG_RES   7  /* result point */
+ #define EC_MONT_REG_X1    8  /* inputt point */
+ #define EC_MONT_REG_X2    9
+ #define EC_MONT_REG_Z2   10
+ #define EC_MONT_REG_X3   11
+ #define EC_MONT_REG_Z3   12
+
+ #define EC_MONT_PKA_REGS_USED 13 /* beside 2 PKA temp regs. */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst.c
new file mode 100644
index 0000000..6540681
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pka_hw_defs.h"
+#include "cc_ecpki_types.h"
+#include "pki.h"
+#include "pka.h"
+#include "pka_error.h"
+#include "ec_wrst.h"
+#include "pka_ec_wrst.h"
+#include "ec_wrst_error.h"
+#include "pki_modular_arithmetic.h"
+#include "pki_dbg.h"
+#include "cc_common.h"
+#include "pka_point_compress_regs_def.h"
+
+/***********    EcWrstInitPubKey   function      **********************/
+/**
+ *  @brief Performs uncompression (extracts Y-coordinate) checks
+ *      and inits the public key (ANS X9.62-2005).
+ *
+ * @author reuvenl (22/09/2014)
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ *
+ */
+CCError_t  EcWrstInitPubKey(CCEcpkiPublKey_t *pPublKey,  /*!< [in/out] Pointer to the public key structure. */
+                uint8_t pointCtl)          /*!< [in] EC point control byte = (compression mode | Y-MSbit). */
+{
+    CCError_t err = CC_OK;
+    uint32_t modSizeInBits, modSizeInWords;
+    CCEcpkiDomain_t *pDomain;
+    uint32_t w;
+    bool  rootExist;
+    uint32_t pkaReqRegs = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
+
+    /* EC domain parameters */
+    pDomain = &pPublKey->domain;
+
+    modSizeInBits = pDomain->modSizeInBits;
+    modSizeInWords = CALC_FULL_32BIT_WORDS(modSizeInBits);
+
+    if (modSizeInWords > CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)
+        return CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR;
+
+    /*       lock mutex and init PKA  */
+    err = PkaInitAndMutexLock(modSizeInBits, &pkaReqRegs);
+    if (err != CC_OK) {
+        return err;
+    }
+
+    /* set modulus P and Barrett tag NP into PKA registers 0,1 */
+    PkaCopyDataIntoPkaReg(PKA_REG_N/*dstReg*/, 1, pDomain->ecP, modSizeInWords);
+
+    PkaCopyDataIntoPkaReg(PKA_REG_NP/*dstReg*/, 1, pDomain->llfBuff/*NP*/,
+        CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+    /* set public key coordinates into PKA registers  */
+    PkaCopyDataIntoPkaReg(PKA_REG_X/*dstReg*/, 1, pPublKey->x, modSizeInWords);
+
+    /* set EC params */
+    PkaCopyDataIntoPkaReg(PKA_REG_EC_A/*dstReg*/, 1, pDomain->ecA, modSizeInWords);
+    PkaCopyDataIntoPkaReg(PKA_REG_EC_B/*dstReg*/, 1, pDomain->ecB, modSizeInWords);
+
+    /* calculate  y^2 for from x */
+    PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_T/*Res*/, PKA_REG_X/*OpA*/, PKA_REG_X/*OpB*/);
+    PKA_MOD_ADD(LEN_ID_N_PKA_REG_BITS, PKA_REG_T/*Res*/, PKA_REG_T/*OpA*/, PKA_REG_EC_A/*OpB*/);
+    PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_T/*Res*/, PKA_REG_X/*OpA*/, PKA_REG_T/*OpB*/);
+    PKA_MOD_ADD(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y2/*=PKA_REG_EC_A*/, PKA_REG_T/*OpA*/, PKA_REG_EC_B/*OpB*/);
+
+    if((pointCtl & 6) != 2) {
+        /*   Partly check uncompressed key (is it on curve ?)  */
+        /* calculate y^2 directly */
+        PkaCopyDataIntoPkaReg(PKA_REG_Y/*dstReg*/, 1, pPublKey->y, modSizeInWords);
+        PKA_MOD_MUL(LEN_ID_N_BITS, PKA_REG_T, PKA_REG_Y, PKA_REG_Y);
+        PKA_COMPARE_STATUS(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y2, PKA_REG_T, w/*stat*/);
+        if(w != 1) {
+            err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+            goto End;
+        }
+    }
+    else {
+        /*    Uncompress the Y coordinate if needed            */
+                /* derive modular square root (in/out registers according to  *
+                *  included definitions file                                  */
+                /*implicit parameterss: PKA_REG_Y(PKA_REG_Y1)=3(out), PKA_REG_Y2(PKA_REG_EC_A)=4(in),      *
+                * PKA_REG_N=0(in)                                                    */
+        rootExist = PkiIsModSquareRootExists();
+
+                /* check is the root exists */
+                if(rootExist != true){
+            err = PKA_MOD_SQUARE_ROOT_NOT_EXIST_ERROR;
+            goto End;
+        }
+
+                /* check Y LS-bit and set Y = -Y if need */
+        PKA_READ_WORD_FROM_REG(w, 0, PKA_REG_Y);
+        if((w & 1) != (pointCtl & 1)) {
+            PKA_SUB(LEN_ID_N_PKA_REG_BITS, PKA_REG_Y, PKA_REG_N, PKA_REG_Y);
+        }
+
+                /* copy Y-coordinate */
+        PkaCopyDataFromPkaReg(pPublKey->y/*dst*/, modSizeInWords, PKA_REG_Y/*src reg*/);
+    }
+
+End:
+    PkaFinishAndMutexUnlock(pkaReqRegs);
+    return err;
+
+}
+
+
+/***********     EcWrstFullCheckPublKey  function      **********************/
+/**
+ * @brief  Checks that the public key is valid point belonging to EC group.
+ *
+ *       Assuming: partly check (sizes, point is on curve) of the public key
+ *                 was done previously.
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ *
+*/
+CCError_t  EcWrstFullCheckPublKey( CCEcpkiPublKey_t    *pPublKey,    /*!< [in] Pointer to the public key structure. */
+                    uint32_t             *pTempBuff) /*!< [in] Pointer to itemp buffer of size not less 2*modulusSize. */
+{
+    CCError_t err = CC_OK;
+    uint32_t ordSizeInWords, modSizeInWords, sizeBits;
+        uint32_t *outPointX, *outPointY;
+        uint32_t *pTmpForFunc;
+
+        modSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.modSizeInBits);
+        ordSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.ordSizeInBits);
+
+        /* scalar mult. resut coordinates  */
+    outPointX = pTempBuff;
+        outPointY = outPointX + modSizeInWords;
+        pTmpForFunc = outPointY + modSizeInWords;
+
+
+        /* scalar mult publ.key point by EC generator order ecR */
+        err = PkaEcWrstScalarMult(
+                                &pPublKey->domain,
+                                pPublKey->domain.ecR, /*in*/
+                                ordSizeInWords,       /*in - publ key X*/
+                                pPublKey->x,          /*in - publ key Y*/
+                                pPublKey->y,          /*in*/
+                                outPointX,            /*out*/
+                                outPointY,            /*out*/
+                                pTmpForFunc);
+        if(err) {
+                err = CC_ECPKI_INTERNAL_ERROR;
+                goto End;
+        }
+
+        /* check that out point is on infinity, i.e. X=0 && Y=0 */
+        sizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(outPointY, modSizeInWords);
+        if(sizeBits > 0){
+                err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+                goto End;
+        }
+        /* check condition for X */
+        sizeBits = CC_CommonGetWordsCounterEffectiveSizeInBits(outPointX, modSizeInWords);
+        if(sizeBits > 0){
+                err = CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR;
+                goto End;
+        }
+
+End:
+    return err;
+}
+
+
+/***********     EcWrstDhDeriveSharedSecret  function      **********************/
+/**
+ * @brief  Derives shared secrete value from provided keys. called also SVDP_DH
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ *
+*/
+CCError_t  EcWrstDhDeriveSharedSecret(CCEcpkiPublKey_t    *pPublKey,          /*!< [in] Pointer to the public key structure. */
+                    CCEcpkiPrivKey_t    *pPrivKey,        /*!< [in] Pointer to the private key structure. */
+                    uint8_t                 *pSharedSecretValue,  /*!< [out] Pointer to buffer for Shared Secret Value of size
+                                                 not less than modulusSize in words. */
+                    CCEcdhTempData_t    *pTempBuff)       /*!< [in] Pointer to temp buffer. */
+{
+    CCError_t err;
+    uint32_t ordSizeInWords, modSizeInWords, modSizeInBytes;
+        uint32_t *outPointX, *outPointY;
+        uint32_t *pTmpForFunc;
+
+        modSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.modSizeInBits);
+        ordSizeInWords = CALC_FULL_32BIT_WORDS(pPublKey->domain.ordSizeInBits);
+        modSizeInBytes = CALC_FULL_BYTES(pPublKey->domain.modSizeInBits);
+
+        /* scalar mult. resut coordinates  */
+    outPointX = (uint32_t*)pTempBuff;
+        outPointY = outPointX + modSizeInWords;
+        pTmpForFunc = outPointY + modSizeInWords;
+
+        /* scalar mult publ.key point by EC generator order ecR */
+        err = PkaEcWrstScalarMult(
+                                &pPublKey->domain,
+                                pPrivKey->PrivKey,    /*in*/
+                                ordSizeInWords,       /*in - publ key X*/
+                                pPublKey->x,          /*in - publ key Y*/
+                                pPublKey->y,          /*in*/
+                                outPointX,            /*out*/
+                                outPointY,            /*out*/
+                                pTmpForFunc);         /*in*/
+        if(err)
+                goto End;
+
+        /* Note: Because output of scalar mult result point in affine         *
+        *  form,there no need to check, that coordinates X,Y <= mod-1.        */
+        /* Check that out point is not on infinity, i.e. X,Y != 0             */
+        if(CC_CommonGetWordsCounterEffectiveSizeInBits(outPointY, modSizeInWords) == 0  ||
+           CC_CommonGetWordsCounterEffectiveSizeInBits(outPointX, modSizeInWords) == 0){
+                err = ECWRST_DH_SHARED_VALUE_IS_ON_INFINITY_ERROR;
+                goto End;
+        } else {
+                /* copy X-coordinate of SecrP to output */
+                CC_CommonReverseMemcpy(pSharedSecretValue, (uint8_t*)outPointX, modSizeInBytes);
+        }
+
+End:
+        CC_PalMemSetZero ( pTempBuff, sizeof(CCEcdhTempData_t) );
+    return err;
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst.h
new file mode 100644
index 0000000..8add9f8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PKA_ECC_EXPORT_H
+#define PKA_ECC_EXPORT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "cc_pal_types.h"
+#include "cc_rnd_common.h"
+#include "cc_ecpki_types.h"
+
+
+/* Temporary buffers used for the functions called from ECDSA */
+typedef struct{
+//! Debug : set to 10, may be less?
+    CCEcdsaSignIntBuff_t tempBuff;
+}EcWrstDsaSignDb_t;
+
+/* Temporary buffers used for the  functions called from ECDSA */
+typedef struct{
+    CCEcdsaVerifyIntBuff_t tempBuff;
+}EcWrstDsaVerifyDb_t;
+
+
+/* internal ECPKI buffer structure used on LLF and containing Barrett tags for*
+*  modulus and gen.order                                                      */
+typedef  struct {
+       uint32_t modTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+       uint32_t ordTag[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+}EcWrstDomain_t;
+
+/* affine ec-point in uint32 arrays format) */
+typedef struct{
+  uint32_t x[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+  uint32_t y[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+} EcWrstAffPoint_t;
+
+/* modified jacobian ec-point: X:x/z^2, Y:y/z^3, t:a*z^4 (uint32 arrays) */
+typedef struct{
+  uint32_t  x[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+  uint32_t  y[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+  uint32_t  z[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+  uint32_t  t[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+} EcwrstMdfPoint_t;
+
+/* EC curve (domain) structure as uint32 array */
+typedef struct{
+  uint32_t p[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];          // modulo
+  uint32_t a[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+  uint32_t b[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];          // y^2 = x^3 + a.x + b (mod p)
+  uint32_t Gx[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+  uint32_t Gy[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];         // generator
+  uint32_t n[CC_ECPKI_ORDER_MAX_LENGTH_IN_WORDS];          // ord(G) = n
+  uint32_t h[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];          // cofactor: #E = n.h
+  uint32_t np[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];  // Barrett tag for modulus
+  uint32_t nn[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];  // Barrett tag for order
+} EcwrstCurve_t;
+
+void EcWrstDsaTruncateMsg(uint32_t *pMsgOut,
+            uint8_t *pMsgIn,
+            uint32_t outSizeBits);
+
+
+
+CCError_t  EcWrstInitPubKey(CCEcpkiPublKey_t *pPublKey,
+                  uint8_t pointCtl);
+
+
+CCError_t  EcWrstFullCheckPublKey(CCEcpkiPublKey_t    *pPublKey,
+                    uint32_t            *pTempBuff);
+
+/* EC WRST DSA */
+CCError_t EcWrstDsaSign(CCRndContext_t   *pRndContext,
+                        CCEcpkiPrivKey_t *pSignPrivKey,
+                        uint32_t             *pMsgRepres,
+                        uint32_t              isEphemerKeyInternal,
+                        uint32_t             *pEphemKey,
+                        uint32_t             *pSignC,
+                        uint32_t             *pSignD,
+                        uint32_t             *pTempBuff);
+
+CCError_t EcWrstDsaVerify(CCEcpkiPublKey_t *signPublKey,
+                    uint32_t  *messageRepresent,
+                    uint32_t   messRepresSizeWords,
+                    uint32_t  *signC,
+                    uint32_t  *signD);
+
+
+
+/* EC WRST DH */
+CCError_t  EcWrstDhDeriveSharedSecret(CCEcpkiPublKey_t    *pPublKey,
+                        CCEcpkiPrivKey_t    *pPrivKey,
+                        uint8_t                 *pSharedSecretValue,
+                        CCEcdhTempData_t    *pTempBuff);
+
+
+
+
+/* EC WRST Key Generate */
+CEXPORT_C CCError_t EcWrstGenKeyPair(const CCEcpkiDomain_t  *pDomain,
+                        CCEcpkiUserPrivKey_t   *pUserPrivKey,
+                        CCEcpkiUserPublKey_t   *pUserPublKey,
+                        CCEcpkiKgTempData_t    *pTempBuff);
+
+/* EC WRST Key Generate with configurable base point */
+CEXPORT_C CCError_t EcWrstGenKeyPairBase(const CCEcpkiDomain_t  *pDomain,
+                        const uint32_t         ecX [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS],
+                        const uint32_t         ecY [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS],
+                        CCEcpkiUserPrivKey_t   *pUserPrivKey,
+                        CCEcpkiUserPublKey_t   *pUserPublKey,
+                        CCEcpkiKgTempData_t    *pTempBuff);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_dsa.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_dsa.c
new file mode 100644
index 0000000..4a70967
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_dsa.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pka_hw_defs.h"
+#include "pki.h"
+#include "pka.h"
+#include "ec_wrst.h"
+#include "ec_wrst_error.h"
+#include "pka_ec_wrst.h"
+#include "pka_ec_wrst_glob_regs.h"
+#include "pka_ec_wrst_dsa_verify_regs.h"
+#include "cc_rnd_local.h"
+
+
+/* canceling the lint warning:
+  Info 740: Unusual pointer cast
+  (incompatible indirect types) */
+/*lint --e{740} */
+
+/* canceling the lint warning:
+   Info 826: Suspicious pointer-to-pointer conversion
+   (area too small) */
+/*lint --e{826} */
+
+/* canceling the lint warning:
+Info 716: while(1) */
+/*lint --e{716} */
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+/***********      CalcSignature function      **********************/
+/**
+ * @brief Sets data into SRAM and calculates ECDSA Signature.
+ *
+ * @author reuvenl (3/29/2015)
+ *
+ * Note: All data in is given with LE order of words (LS word is left most).
+ *       Algorithm - according ANS X9.62 denoted [1].
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t CalcSignature(const CCEcpkiDomain_t *pDomain, /*!< [in] Pointer to EC domain structure. */
+                uint32_t  *pSignPrivKey,             /*!< [in] Pointer to signer privatekey structure. */
+                uint32_t  *pMsgRepres,               /*!< [in] The pointer to the message representative buffer.*/
+                uint32_t  *pEphemPrivKey,            /*!< [in] pointer to private Ephemeral key buff. */
+                uint32_t  *pEphemPublX,              /*!< [in] Pointer to X-coordinate of Ephemeral public. */
+                uint32_t  *pSignC,                   /*!< [in] Pointer to C-part of the signature (called also R-part). */
+                uint32_t  *pSignD)                   /*!< [in] Pointer to D-part of the signature (called also S-part). */
+{
+        CCError_t err = CC_OK;
+        uint32_t status;
+        uint32_t ordSizeInWords, modSizeInWords;
+    uint32_t pkaReqRegs = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
+
+        /* define regs (ECC_REG_N=0, ECC_REG_NP=1) */
+    uint8_t rC    = regTemps[2]; /*C (zR) - signC*/
+    uint8_t rM    = regTemps[3]; /*message (zF)*/
+    uint8_t rEphK = regTemps[4]; /*ephemer.priv.key*/
+    uint8_t rK    = regTemps[5]; /*priv. key (zD)*/
+    uint8_t rKinv = regTemps[6];
+    uint8_t rD    = regTemps[7]; /*D (zS)- signD*/
+    uint8_t rT    = regTemps[8];
+
+
+         /* set EC modulus and order sizes */
+        ordSizeInWords = CALC_FULL_32BIT_WORDS(pDomain->ordSizeInBits);
+        modSizeInWords = CALC_FULL_32BIT_WORDS(pDomain->modSizeInBits);
+        if ((ordSizeInWords > (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1)) ||
+            (modSizeInWords > CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)) {
+            return ECWRST_SCALAR_MULT_INVALID_MOD_ORDER_SIZE_ERROR;
+        }
+
+        /*  Init PKA for operations with EC order */
+        err = PkaInitAndMutexLock(pDomain->ordSizeInBits , &pkaReqRegs); // RL Count regs to clean 9!
+        if (err != CC_OK) {
+                return err;
+        }
+
+
+        /*   Set data into PKA registers  */
+        /* Note: ignore false positive KW warning about explicit offset:      *
+           sizes, given in the EC Domain, must be right                      */
+        PkaCopyDataIntoPkaReg(ECC_REG_N, 1, pDomain->ecR/*src_ptr*/, ordSizeInWords);
+        PkaCopyDataIntoPkaReg(ECC_REG_NP, 1, ((EcWrstDomain_t*)&(pDomain->llfBuff))->ordTag,
+                               CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+        PkaCopyDataIntoPkaReg(rC, 1, pEphemPublX, modSizeInWords);
+        PkaCopyDataIntoPkaReg(rM, 1, pMsgRepres, ordSizeInWords);
+        PkaCopyDataIntoPkaReg(rEphK, 1, pEphemPrivKey, ordSizeInWords);
+        PkaCopyDataIntoPkaReg(rK, 1, pSignPrivKey, ordSizeInWords);
+
+        /* Calculate Signature  */
+        /* [1] 7.3. calc. rEphK mod ECC_REG_N and check that it > 0 */
+        PKA_DIV(LEN_ID_MAX_BITS, rT/*not used*/, rEphK, ECC_REG_N);
+        PKA_COMPARE_IM_STATUS(LEN_ID_MAX_BITS, rEphK, 0, status);
+        if(status == 1){
+                err = ECWRST_DSA_SIGN_BAD_EPHEMER_KEY_TRY_AGAIN_ERROR;
+                goto End;
+        }
+
+        /* check rKinv != 0  (ANS X9.62 7.3) */
+        PKA_MOD_INV_W_EXP(rKinv, rEphK, rT/*temp*/); /* RL to inv_fast */
+        PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rKinv, 0, status);
+        if(status == 1) {
+                err = ECWRST_DSA_SIGN_BAD_EPHEMER_KEY_TRY_AGAIN_ERROR;
+                goto End;
+        }
+        PKA_MOD_MUL(LEN_ID_N_BITS, rD, rK, rC);
+        PKA_REDUCE(LEN_ID_N_BITS,rM, rM);
+        PKA_MOD_ADD(LEN_ID_N_PKA_REG_BITS, rD, rD, rM);
+        PKA_MOD_MUL(LEN_ID_N_BITS, rD, rD, rKinv);
+        /* check rD != 0  (ANS X9.62 7.3) */
+        PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rD, 0, status);
+        if(status == 1) {
+                err = ECWRST_DSA_SIGN_BAD_EPHEMER_KEY_TRY_AGAIN_ERROR;
+                goto End;
+        }
+        /* if status == 0 then copy the signature to the output */
+        if(status == 0) {
+                PkaCopyDataFromPkaReg(pSignC, ordSizeInWords, rC);
+                PkaCopyDataFromPkaReg(pSignD, ordSizeInWords, rD);
+        }
+
+End:
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+        return err;
+
+}
+
+
+/***********    EcWrstDsaTruncateMsg   function      **********************/
+/**
+ * @brief Truncates the message to given count of LS bits.
+ *
+ * @author reuvenl (8/19/2014)
+ *
+ * @return no return value.
+ */
+void EcWrstDsaTruncateMsg(
+                uint32_t *pMsgOut,    /*!< [out] Pointer to truncated message output.
+                                            Output format: bytes, LS byte is left most one. */
+                uint8_t *pMsgIn,      /*!< [in] Pointer to input message in bytes. */
+                uint32_t outSizeBits) /*!< [in] Exact size of truncated message in bits. */
+{
+    uint32_t i, shift;
+    uint32_t outSizeBytes = CALC_FULL_BYTES(outSizeBits);
+    uint32_t outSizeWords = CALC_FULL_32BIT_WORDS(outSizeBits);
+
+    pMsgOut[outSizeWords-1] = 0; /* zeroing high word of output */
+    /* reverse copy only a needed bytes of the message */
+    CC_CommonReverseMemcpy((uint8_t*)pMsgOut, pMsgIn, outSizeBytes);
+
+    /* shift right by redundant bits */
+    shift = (8 - (outSizeBits & 7UL)) & 7UL;
+    if (shift) {
+        for (i = 0; i < CALC_FULL_32BIT_WORDS(outSizeBits) - 1; i++) {
+            pMsgOut[i] = (pMsgOut[i] >> shift) |
+            (pMsgOut[i+1] << (32-shift));
+        }
+        pMsgOut[i] = pMsgOut[i] >> shift;
+        }
+    return;
+}
+
+
+
+/***********      EcWrstDsaSign function      **********************/
+/**
+ * @brief Generates aphemeral key, if needed and
+ *  calls specific Signature function.
+ *
+ * @author reuvenl (3/29/2015)
+ *
+ * Note: All data in buffers given with LE order of bytes and word and their sizes
+ *       must be EC modulus size in words (with leading zeros)
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t EcWrstDsaSign(CCRndContext_t   *pRndContext,          /*!< [in/out] Pointer to the RND context buffer. */
+        CCEcpkiPrivKey_t *pSignPrivKey,         /*!< [in] Pointer to to signer privatekey structure. */
+        uint32_t             *pMsgRepres,           /*!< [in] The pointer to the message representative buffer.*/
+        uint32_t              isEphemerKeyInternal, /*!< [in] boolean indicating internal (=1) or external (=0) ephemeral key. */
+        uint32_t             *pEphemKey,      /*!< [in] Pointer to to private Ephemeral key buff. */
+        uint32_t             *pSignC,               /*!< [in] Pointer to C-part of the signature (called also R-part). */
+        uint32_t             *pSignD,               /*!< [in] Pointer to D-part of the signature (called also S-part). */
+        uint32_t             *pTempBuff)      /*!< [in] Pointer to temp buffer. the buffer size must be
+                                           not less than (3*ModulusSizeInWords +
+                                           CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS)*/
+{
+    CCError_t err = CC_OK;
+    const CCEcpkiDomain_t *pDomain = &pSignPrivKey->domain;
+    uint32_t ordSizeInBits, ordSizeInWords, modSizeInWords;
+    /* pointers to result EC point coordinates x, y */
+    uint32_t *pEphemPublX, *pEphemPublY, *pEphemKeyBuf, *pMaxVect;
+    uint32_t *funcTmpBuff;
+    uint32_t countTries = 0;
+
+
+    /* set EC domain parameters modulus and EC order sizes */
+    ordSizeInBits  = pDomain->ordSizeInBits;
+    ordSizeInWords = CALC_FULL_32BIT_WORDS(ordSizeInBits);
+    modSizeInWords = CALC_FULL_32BIT_WORDS(pDomain->modSizeInBits);
+    if ((ordSizeInWords > (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1)) ||
+            (modSizeInWords > CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)) {
+        return ECWRST_SCALAR_MULT_INVALID_MOD_ORDER_SIZE_ERROR;
+    }
+
+
+    pEphemPublX = pTempBuff; //?? use pSignC to save mem
+    pEphemKeyBuf = pEphemPublX + modSizeInWords;
+    pEphemPublY = pEphemKeyBuf + ordSizeInWords;
+    pMaxVect = pEphemPublY + modSizeInWords;
+
+    while (1) {
+        /*  Generate random ephemeral key   *
+         * Note: Checking, that private ephemer.key  0 < k < EC order *
+         * performed on LLF during scalar multiplication             */
+        if(isEphemerKeyInternal) {
+            /* Set bytes MaxVect= EcOrder. */
+            pMaxVect[ordSizeInWords-1] = 0; /*zero MSWord of maxVect*/
+            CC_PalMemCopy(pMaxVect, pDomain->ecR, sizeof(uint32_t)*ordSizeInWords);
+            pEphemKeyBuf[ordSizeInWords-1] = 0; /*zero MSWord*/
+            err = CC_RndGenerateVectorInRange(
+                    pRndContext, pDomain->ordSizeInBits, (uint8_t*)pMaxVect/* maxVect*/, (uint8_t*)pEphemKeyBuf);
+            if (err) {
+                goto End;
+            }
+        }
+        /* copy external key if provided */
+        else {
+            /* Note: Checking of range of the ephemeral key       *
+             *  performed in PkaEcWrstScalarMult                  */
+            CC_PalMemCopy(pEphemKeyBuf, pEphemKey, sizeof(uint32_t)*ordSizeInWords);
+        }
+
+        /* Calculate ephemeral public key               */
+        funcTmpBuff = pMaxVect; /* because pMaxVect not needed yet */
+        err = PkaEcWrstScalarMult(pDomain,
+                pEphemKeyBuf/*scalar*/, ordSizeInWords, /*scalar size*/
+                (uint32_t*)&pDomain->ecGx, (uint32_t*)&pDomain->ecGy, /*in point coordinates*/
+                pEphemPublX/*C*/, pEphemPublY,  /*out point coordinates*/
+                funcTmpBuff);
+        if (err) {
+            goto End;
+        }
+
+
+        /*  Calculate Signature S  */
+        err = CalcSignature(pDomain, pSignPrivKey->PrivKey,
+                pMsgRepres, pEphemKeyBuf, pEphemPublX,
+                pSignC, pSignD);
+
+        /* exit the programm if an error occurs, beside the case of   *
+         *  returned error message to try a new Ephemeral Key          */
+        if(err && (err != ECWRST_DSA_SIGN_BAD_EPHEMER_KEY_TRY_AGAIN_ERROR || !isEphemerKeyInternal)) {
+            goto End;
+        }
+
+        /* if error is OK or count of tries > 100, then end the loop*/
+        if((err == 0) || (countTries > 100)) {
+            goto End;
+        } else {
+            countTries++;
+        }
+    } /* End of while() */
+
+    End:
+    return err;
+}
+
+
+/***********      EcWrstDsaVerify function      **********************/
+/**
+ * @brief Verifies the signature.
+ *
+ * @author reuvenl (8/7/2014)
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t EcWrstDsaVerify(CCEcpkiPublKey_t *pSignPublKey,   /*!< [in] Pointer to signer public key structure. */
+                uint32_t  *pMsgRepres,         /*!< [in] The pointer to the message representative buffer.*/
+                uint32_t   msgRepresSizeWords, /*!< [in] Size of the message representative buffer in words.*/
+                uint32_t  *pSignC,          /*!< [in] Pointer to C-part of the signature (called also R-part). */
+                uint32_t  *pSignD)          /*!< [in] Pointer to D-part of the signature (called also S-part). */
+{
+    CCError_t err = CC_OK;
+    const CCEcpkiDomain_t *domain = &pSignPublKey->domain;
+    EcWrstDomain_t *llfBuff = (EcWrstDomain_t*)&pSignPublKey->domain.llfBuff;
+    int32_t modSizeInBits, modSizeInWords, ordSizeInBits, ordSizeInWords;
+    uint32_t pkaReqRegs = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
+
+
+    /* set domain parameters */
+    modSizeInBits  = domain->modSizeInBits;
+    modSizeInWords = CALC_FULL_32BIT_WORDS(modSizeInBits);
+    ordSizeInBits  = domain->ordSizeInBits;
+    ordSizeInWords = CALC_FULL_32BIT_WORDS(ordSizeInBits);
+    if ((ordSizeInWords > (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1)) ||
+        (modSizeInWords > CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)) {
+        return ECWRST_SCALAR_MULT_INVALID_MOD_ORDER_SIZE_ERROR;
+    }
+
+        /*  Init PKA for modular operations with EC modulus or EC order and   *
+        *   registers size according to maximal of them                       */
+    err = PkaInitAndMutexLock(CC_MAX(ordSizeInBits, modSizeInBits), &pkaReqRegs);
+    if (err != CC_OK) {
+        return err;
+    }
+        /* set order and modulus mod sizes */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), ordSizeInBits);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L2), modSizeInBits);
+
+    /* Set input data into PKA registers */
+        /* EC order and its Barrett tag */
+    PkaCopyDataIntoPkaReg(ECC_REG_N/*dest_reg*/, 1, domain->ecR/*src_ptr*/, ordSizeInWords);
+    PkaCopyDataIntoPkaReg(ECC_REG_NP, 1, llfBuff->ordTag, CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+    /* signature C, D */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_C, 1, pSignC, ordSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_D, 1, pSignD, ordSizeInWords);
+    /* message representative EC_VERIFY_REG_F */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_F, 1, pMsgRepres, msgRepresSizeWords);
+    /* Load modulus and its Barrett tag */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_TMP_N, 1, domain->ecP, modSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_TMP_NP, 1, llfBuff->modTag, CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+    /* set pG */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_GX, 1, domain->ecGx, modSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_GY, 1, domain->ecGy, modSizeInWords);
+    /* set pW */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_WX, 1, pSignPublKey->x, modSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_WY, 1, pSignPublKey->y, modSizeInWords);
+    PkaCopyDataIntoPkaReg(ECC_REG_EC_A, 1, domain->ecA, modSizeInWords);
+
+    /* Verify */
+    err = PkaEcdsaVerify();
+
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+    return err;
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_dsa_verify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_dsa_verify.c
new file mode 100644
index 0000000..e82f9c0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_dsa_verify.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_mem.h"
+#ifndef ARM_DSM
+#include "cc_pal_mutex.h"
+#endif
+#include "cc_pal_abort.h"
+#include "cc_hal.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pka_hw_defs.h"
+#include "cc_ecpki_types.h"
+#include "pki.h"
+#include "pka.h"
+#include "ec_wrst.h"
+#include "ec_wrst_error.h"
+#include "pka_ec_wrst_dsa_verify_regs.h"
+#include "pka_ec_wrst_glob_regs.h"
+
+
+/***********      EcWrstDsaVerify function      **********************/
+/**
+ * @brief Verifies the signature.
+ *
+ * @author reuvenl (8/7/2014)
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t EcWrstDsaVerify(CCEcpkiPublKey_t *pSignPublKey,   /*!< [in] Pointer to signer public key structure. */
+                uint32_t  *pMsgRepres,         /*!< [in] The pointer to the message representative buffer.*/
+                uint32_t   msgRepresSizeWords, /*!< [in] Size of the message representative buffer in words.*/
+                uint32_t  *pSignC,          /*!< [in] Pointer to C-part of the signature (called also R-part). */
+                uint32_t  *pSignD)          /*!< [in] Pointer to D-part of the signature (called also S-part). */
+{
+    CCError_t err = CC_OK;
+    const CCEcpkiDomain_t *domain = &pSignPublKey->domain;
+    EcWrstDomain_t *llfBuff = (EcWrstDomain_t*)&pSignPublKey->domain.llfBuff;
+    int32_t modSizeInBits, modSizeInWords, ordSizeInBits, ordSizeInWords;
+    uint32_t pkaReqRegs = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
+
+
+    /* set domain parameters */
+    modSizeInBits  = domain->modSizeInBits;
+    modSizeInWords = CALC_FULL_32BIT_WORDS(modSizeInBits);
+    ordSizeInBits  = domain->ordSizeInBits;
+    ordSizeInWords = CALC_FULL_32BIT_WORDS(ordSizeInBits);
+
+        /*  Init PKA for modular operations with EC modulus or EC order and   *
+        *   registers size according to maximal of them                       */
+    err = PkaInitAndMutexLock(CC_MAX(ordSizeInBits, modSizeInBits), &pkaReqRegs);
+    if (err != CC_OK) {
+        return err;
+    }
+        /* set order and modulus mod sizes */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), ordSizeInBits);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L2), modSizeInBits);
+
+    /* Set input data into PKA registers */
+        /* EC order and its Barrett tag */
+    PkaCopyDataIntoPkaReg(ECC_REG_N/*dest_reg*/, 1, domain->ecR/*src_ptr*/, ordSizeInWords);
+    PkaCopyDataIntoPkaReg(ECC_REG_NP, 1, llfBuff->ordTag, CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+    /* signature C, D */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_C, 1, pSignC, ordSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_D, 1, pSignD, ordSizeInWords);
+    /* message representative EC_VERIFY_REG_F */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_F, 1, pMsgRepres, msgRepresSizeWords);
+    /* Load modulus and its Barrett tag */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_TMP_N, 1, domain->ecP, modSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_TMP_NP, 1, llfBuff->modTag, CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+    /* set pG */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_GX, 1, domain->ecGx, modSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_GY, 1, domain->ecGy, modSizeInWords);
+    /* set pW */
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_WX, 1, pSignPublKey->x, modSizeInWords);
+    PkaCopyDataIntoPkaReg(EC_VERIFY_REG_P_WY, 1, pSignPublKey->y, modSizeInWords);
+    PkaCopyDataIntoPkaReg(ECC_REG_EC_A, 1, domain->ecA, modSizeInWords);
+
+    /* Verify */
+    err = PkaEcdsaVerify();
+
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+    return err;
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_error.h
new file mode 100644
index 0000000..3287204
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_error.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+ #ifndef LLF_ECPKI_ERROR_H
+#define LLF_ECPKI_ERROR_H
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* base address: LLF_ECPKI_MODULE_ERROR_BASE = 0x00F10800 */
+
+/* The PkaEcdsaVerify related functions errors */
+#define  ECWRST_DSA_VERIFY_CALC_SIGN_C_INVALID_ERROR        (LLF_ECPKI_MODULE_ERROR_BASE + 0x01UL)
+#define  ECWRST_DSA_VERIFY_CALC_SIGN_D_INVALID_ERROR        (LLF_ECPKI_MODULE_ERROR_BASE + 0x02UL)
+#define  ECWRST_DSA_VERIFY_CALC_SIGNATURE_IS_INVALID            (LLF_ECPKI_MODULE_ERROR_BASE + 0x03UL)
+#define  ECWRST_DSA_VERIFY_2MUL_FIRST_B2_ERROR              (LLF_ECPKI_MODULE_ERROR_BASE + 0x04UL)
+#define  ECWRST_DSA_VERIFY_2MUL_NEXT_B2_ERROR               (LLF_ECPKI_MODULE_ERROR_BASE + 0x05UL)
+#define  ECWRST_DSA_VERIFY_2MUL_FACTOR_A_NULL_ERROR             (LLF_ECPKI_MODULE_ERROR_BASE + 0x06UL)
+#define  ECWRST_DSA_VERIFY_2MUL_FACTOR_B_NULL_ERROR             (LLF_ECPKI_MODULE_ERROR_BASE + 0x07UL)
+/* The CalcSignature function errors */
+#define  ECWRST_DSA_SIGN_BAD_EPHEMER_KEY_TRY_AGAIN_ERROR        (LLF_ECPKI_MODULE_ERROR_BASE + 0x10UL)
+#define  ECWRST_DSA_SIGN_CALC_CANNOT_CREATE_SIGNATURE       (LLF_ECPKI_MODULE_ERROR_BASE + 0x11UL)
+
+/* The EcWrstDhDeriveSharedSecret function errors */
+#define ECWRST_DH_SHARED_VALUE_IS_ON_INFINITY_ERROR     (LLF_ECPKI_MODULE_ERROR_BASE + 0x20UL)
+
+/* The PkaEcWrstScalarMult function errors */
+#define ECWRST_SCALAR_MULT_INVALID_SCALAR_VALUE_ERROR           (LLF_ECPKI_MODULE_ERROR_BASE + 0x30UL)
+#define ECWRST_SCALAR_MULT_INVALID_MOD_ORDER_SIZE_ERROR         (LLF_ECPKI_MODULE_ERROR_BASE + 0x31UL)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_genkey.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_genkey.c
new file mode 100644
index 0000000..617e493
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/ec_wrst_genkey.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_mem.h"
+#include "cc_rnd_common.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pki.h"
+#include "pka_ec_wrst.h"
+
+/***************  EcWrstGenKeyPairBase function  **************/
+/**
+ * @brief Generates a pair of private and public keys
+ *        in little endian ordinary (non-Montgomery) form using a cofigurable base point.
+ *
+ *    The function performs the following:
+ *      1. Checks the validity of all of the function inputs. If one of the received
+ *         parameters is not valid, it returns an error.
+ *      2. Cleans buffers and generates random private key.
+ *      3. Calls the low level function PkaEcWrstScalarMult to generate EC public key.
+ *      4. Outputs the user public and private key structures in little endian form.
+ *      5. Cleans temporary buffers.
+ *      6. Exits.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+*/
+CEXPORT_C CCError_t EcWrstGenKeyPairBase(const CCEcpkiDomain_t  *pDomain,
+                                         const uint32_t         ecX [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS],
+                                         const uint32_t         ecY [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS],
+                                         CCEcpkiUserPrivKey_t   *pUserPrivKey,
+                                         CCEcpkiUserPublKey_t   *pUserPublKey,
+                                         CCEcpkiKgTempData_t    *pTempBuff)
+{
+    CCError_t err = CC_OK;
+    CCEcpkiPrivKey_t *pPrivKey;
+    CCEcpkiPublKey_t *pPublKey;
+    uint32_t  orderSizeInWords;
+
+    if (pDomain == NULL)
+        return CC_ECPKI_DOMAIN_PTR_ERROR;
+
+    if (pUserPrivKey == NULL)
+        return CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR;
+
+    if (pUserPublKey == NULL)
+        return CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR;
+
+    if (pTempBuff == NULL)
+        return CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR;
+
+    if (NULL == ecX || NULL == ecY)
+        return CC_ECPKI_INVALID_BASE_POINT_PTR_ERROR;
+
+    /* the pointer to the key database */
+    pPrivKey = (CCEcpkiPrivKey_t *)&pUserPrivKey->PrivKeyDbBuff;
+    pPublKey = (CCEcpkiPublKey_t *)&pUserPublKey->PublKeyDbBuff;
+
+    orderSizeInWords = (pDomain->ordSizeInBits+CC_BITS_IN_32BIT_WORD-1)/CC_BITS_IN_32BIT_WORD;
+
+    /* calculate public key point coordinates */
+    err = PkaEcWrstScalarMult(pDomain,
+                              pPrivKey->PrivKey/*scalar*/, orderSizeInWords, /*scalar size*/
+                              ecX, ecY, /*in point coordinates*/
+                              pPublKey->x, pPublKey->y,  /*out point coordinates*/
+                              (uint32_t*)pTempBuff);
+    if(err) {
+        err = CC_ECPKI_INTERNAL_ERROR;
+        goto End;
+    }
+
+    if(CC_OK == err) {
+        /*     set the EC domain and  keys valid tags        */
+        CC_PalMemCopy((uint8_t*)&pPrivKey->domain, (uint8_t*)pDomain, sizeof(pPrivKey->domain));
+        pUserPrivKey->valid_tag  = CC_ECPKI_PRIV_KEY_VALIDATION_TAG;
+
+        CC_PalMemCopy((uint8_t*)&pPublKey->domain, (uint8_t*)pDomain, sizeof(pPublKey->domain));
+        pUserPublKey->valid_tag  = CC_ECPKI_PUBL_KEY_VALIDATION_TAG;
+        return err;
+    }
+
+End:
+    pUserPrivKey->valid_tag  = 0;
+    pUserPublKey->valid_tag  = 0;
+    CC_PalMemSet(pPrivKey, 0, sizeof(pPrivKey->PrivKey));
+    CC_PalMemSet(pPublKey, 0, 2*sizeof(pPublKey->x));
+    return err;
+
+}
+
+/***************  EcWrstGenKeyPair function  **************/
+/**
+ * @brief Generates a pair of private and public keys
+ *        in little endian ordinary (non-Montgomery) form.
+ *
+ *    The function performs the following:
+ *      1. Checks the validity of all of the function inputs. If one of the received
+ *         parameters is not valid, it returns an error.
+ *      2. Cleans buffers and generates random private key.
+ *      3. Calls the low level function PkaEcWrstScalarMult to generate EC public key.
+ *      4. Outputs the user public and private key structures in little endian form.
+ *      5. Cleans temporary buffers.
+ *      6. Exits.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+*/
+CEXPORT_C CCError_t EcWrstGenKeyPair(const CCEcpkiDomain_t  *pDomain,      /*!< [in] Pointer to current EC domain.*/
+                    CCEcpkiUserPrivKey_t   *pUserPrivKey, /*!< [out] Pointer to the generated private key structure.*/
+                    CCEcpkiUserPublKey_t   *pUserPublKey, /*!< [out] Pointer to the generated public key structure.*/
+                    CCEcpkiKgTempData_t   *pTempBuff)    /*!< [in] Pointer to temporary buffer.*/
+{
+
+    if (pDomain == NULL)
+        return CC_ECPKI_DOMAIN_PTR_ERROR;
+
+    return EcWrstGenKeyPairBase(pDomain, pDomain->ecGx, pDomain->ecGy, pUserPrivKey, pUserPublKey, pTempBuff);
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst.c
new file mode 100644
index 0000000..84bada7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_hal_plat.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_error.h"
+#include "pka_hw_defs.h"
+#include "pka_error.h"
+#include "pki.h"
+#include "pka.h"
+#include "pka_ec_wrst.h"
+#include "ec_wrst.h"
+#include "ec_wrst_error.h"
+#include "pki_modular_arithmetic.h"
+#include "pki_dbg.h"
+#include "pka_ec_wrst_glob_regs.h"
+#include "pka_ec_wrst_dsa_verify_regs.h"
+
+
+/***********   PkaDoubleMdf2Mdf    function      **********************/
+/**
+ * @brief EC point doubling: p = 2*p1  modified-modified.
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ */
+void PkaDoubleMdf2Mdf(
+             const uint32_t x,  const uint32_t y,  const uint32_t z,  const uint32_t t,  /*!< [out] Output modified point coordinates. */
+             const uint32_t x1, const uint32_t y1, const uint32_t z1, const uint32_t t1) /*!< [in] Input modified point coordinates. */
+{
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, y1, y1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, ECC_REG_T4, z1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y1, y1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, x1, x1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, ECC_REG_T4, ECC_REG_T4);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T4, y, ECC_REG_T4);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x1, x1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, ECC_REG_T2);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, ECC_REG_T2, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, t1, ECC_REG_T2);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, ECC_REG_N4, ECC_REG_T4);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T2, ECC_REG_T2, ECC_REG_T4);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T4, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, x, ECC_REG_T4);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T3, ECC_REG_N12, ECC_REG_T4);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, y);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T4, y, y);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T4, ECC_REG_T4, t1);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N8, y);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T3, ECC_REG_T2, y);
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, t, ECC_REG_T4);
+    return;
+}
+
+/***********    PkaDoubleMdf2Jcb   function      **********************/
+/**
+ * @brief EC point doubling: p = 2*p1  p1 is modified, output is Jacobian
+ *
+ * @return  - no return value.
+ */
+void PkaDoubleMdf2Jcb(
+             const uint32_t x,  const uint32_t y,  const uint32_t z, /*!< [out] EC point jacobian coordinates. */
+             const uint32_t x1, const uint32_t y1, const uint32_t z1, const uint32_t t1)/*!< [in] EC point modified coordinates. */
+{
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, y1, y1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, ECC_REG_T, z1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y1, y1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, x1, x1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, ECC_REG_T, ECC_REG_T);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T, y, ECC_REG_T);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x1, x1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, ECC_REG_T2);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, ECC_REG_T2, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, t1, ECC_REG_T2);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, ECC_REG_N4, ECC_REG_T);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T2, ECC_REG_T2, ECC_REG_T);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, x, ECC_REG_T);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T3, ECC_REG_N12, ECC_REG_T);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, y);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N8, y);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T3, ECC_REG_T2, y);
+    return;
+}
+
+/***********    PkaAddJcbAfn2Mdf   function      **********************/
+/**
+ * @brief  Performs adding of EC points p= p2+p1: affine+jacobian=modified.
+ *
+ * @return  - no return value.
+ */
+void PkaAddJcbAfn2Mdf(
+             const uint32_t x,  const uint32_t y,  const uint32_t z, const uint32_t t, /*!< [out] EC point modified coordinates. */
+             const uint32_t x1, const uint32_t y1, const uint32_t z1,  /*!< [in] EC point jacobian coordinates. */
+             const uint32_t x2, const uint32_t y2) /*!< [in] EC point affine coordinates. */
+{
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z1, z1);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_N12, x1);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, ECC_REG_T1, x2, t, x);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z1, t);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, y2, t);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, t, ECC_REG_N4, t);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, t, y1, t);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, z1, ECC_REG_T1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, ECC_REG_T1, ECC_REG_T1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T1, ECC_REG_T1, ECC_REG_T2);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T1, ECC_REG_N4, ECC_REG_T1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, ECC_REG_T1, y1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x, ECC_REG_T2);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, t, t, ECC_REG_T1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, x, ECC_REG_T2);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, t, ECC_REG_T2, y);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z, z);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, t, t);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, ECC_REG_EC_A, t);
+    return;
+}
+
+/***********    PkaJcb2Afn   function      **********************/
+/**
+ * @brief Converts the jacobian EC point to affine representation:
+ *   p(x,y,z) -> p(x,y)
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ */
+void PkaJcb2Afn(
+           CCEcpkiScaProtection_t scaProtect,  /*!< [in] Flag defining if SCA protection needed (1) or not (0). */
+           const uint32_t x, const uint32_t y, /*!< [in/out] as input - EC point jacobian coordinates;
+                                   as output - EC point affine coordinates */
+           const uint32_t z) /*!< [in] EC point jacobian coordinates. */
+{
+// RL check is the pka_inv_fast works right and delete compilation dependence
+#ifndef INV_FAST_ALLOWED
+    scaProtect = SCAP_Active;
+#endif
+    if (scaProtect == SCAP_Inactive) {
+        PKA_MOD_INV(LEN_ID_N_BITS, ECC_REG_AQ, z); // no SCA protect
+    } else {
+        PKA_MOD_INV_W_EXP(ECC_REG_AQ, z, ECC_REG_A_NM2); // SCA protect
+    }
+
+    /* ecc-to-affine */
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, ECC_REG_AQ);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_AQ, ECC_REG_AQ, ECC_REG_AQ);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, x, x, ECC_REG_AQ);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, ECC_REG_AQ);
+
+    PKA_REDUCE(LEN_ID_N_BITS,x, x);
+    PKA_REDUCE(LEN_ID_N_BITS,y, y);
+
+    return;
+}
+
+
+/***********    PkaAddAff   function      **********************/
+/**
+ * @brief pka ecc points adding: affine+affine=affine
+ *
+ * @return  - No return value
+ */
+void PkaAddAff(
+          const uint32_t x,  const uint32_t y,  /*!< [out] EC point Affine coordinates. */
+          const uint32_t x1, const uint32_t y1, /*!< [in] EC point Affine coordinates. */
+          const uint32_t x2, const uint32_t y2) /*!< [in] EC point Affine coordinates. */
+{
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_N1, x1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_AAA_Z, x, x2);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, ECC_REG_N1, y2);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T, y1, ECC_REG_T);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, ECC_REG_AAA_Z, ECC_REG_AAA_Z);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T1, ECC_REG_AAA_Z, ECC_REG_T2);
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T1, ECC_REG_N4, ECC_REG_T1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, ECC_REG_T1, y1);
+    PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x, ECC_REG_T2);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T, ECC_REG_T, ECC_REG_T1);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, x, ECC_REG_T2);
+    PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T, ECC_REG_T2, y);
+    PkaJcb2Afn(SCAP_Inactive, x, y, ECC_REG_AAA_Z);
+
+    return;
+}
+
+/***********    PkaSum2ScalarMullt   function      **********************/
+/**
+ * @brief The function calculates simultaneously summ of two scalar
+ * multiplications of EC points.
+ *
+ * Used the Strauss algorithm, optimized by A.Klimow:
+ *     R = a*P + b*Q, where R,P,Q - EC points, a,b - scalars.
+ *
+ * @author reuvenl (8/26/2014)
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ */
+uint32_t PkaSum2ScalarMullt(
+               const uint32_t xr, const uint32_t yr, /*!< [out] Pka register holding R coordinates. */
+               const uint32_t a,             /*!< [in] Pka register holding scalar a. */
+               const uint32_t xp, const uint32_t yp, /*!< [in] Pka register holding P coordinates. */
+               const uint32_t b,             /*!< [in] Pka register holding scalar b. */
+               const uint32_t xq, const uint32_t yq) /*!< [in] Pka register holding Q coordinates. */
+{
+    uint32_t wA, wB, err = 0;
+    uint32_t stat;
+    int32_t b2, i;
+    uint32_t isNewA=true, isNewB=true;
+
+    /* check that a>0 and b>0 */
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, a, 0, stat);
+    if (stat == 1) {
+        err = ECWRST_DSA_VERIFY_2MUL_FACTOR_A_NULL_ERROR;
+        goto End;
+    }
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, b, 0, stat);
+    if (stat == 1) {
+        err = ECWRST_DSA_VERIFY_2MUL_FACTOR_B_NULL_ERROR;
+        goto End;
+    }
+
+    /* get max effective size of factors minus 1 */
+    i = CC_MAX(PkaGetRegEffectiveSizeInBits(a), PkaGetRegEffectiveSizeInBits(b)) - 1;
+
+    PkaAddAff(EC_VERIFY_REG_XPQ, EC_VERIFY_REG_YPQ, xp,yp, xq,yq); // p+q
+
+#ifdef ARM_DSM
+    *((volatile uint32_t *)(uint32_t)(0x44440000)) = i;
+#endif
+
+    b2 = PkaGetNextMsBit(a, i, &wA, &isNewA)*2 + PkaGetNextMsBit(b, i, &wB, &isNewB);
+    switch (b2) {
+    case 1:
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, xr, xq);
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, yr, yq);
+        break; // 01: r = q
+    case 2:
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, xr, xp);
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, yr, yp);
+        break; // 10: r = p
+    case 3:
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, xr, EC_VERIFY_REG_XPQ);
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, yr, EC_VERIFY_REG_YPQ);
+        break; // 11: r = p+q
+    default:
+        err = ECWRST_DSA_VERIFY_2MUL_FIRST_B2_ERROR;
+        goto End;
+    }
+    PKA_SET_VAL(EC_VERIFY_REG_ZR, 1);
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TR, ECC_REG_EC_A);
+
+    while (--i >= 0) {
+#ifdef ARM_DSM
+        *((volatile uint32_t *)(uint32_t)(0x44440000)) = i;
+#endif
+        b2 = PkaGetNextMsBit(a, i, &wA, &isNewA)*2 + PkaGetNextMsBit(b, i, &wB, &isNewB);
+        if (b2 == 0) {
+            PkaDoubleMdf2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR);
+        } else {
+            PkaDoubleMdf2Jcb(xr,yr,EC_VERIFY_REG_ZR, xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR);
+            switch (b2) {
+            case 1:
+                PkaAddJcbAfn2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR, xq,yq);
+                break; // 01: r += p
+            case 2:
+                PkaAddJcbAfn2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR, xp,yp);
+                break; // 10: r += q
+            case 3:
+                PkaAddJcbAfn2Mdf(xr,yr,EC_VERIFY_REG_ZR,EC_VERIFY_REG_TR, xr,yr,EC_VERIFY_REG_ZR, EC_VERIFY_REG_XPQ,EC_VERIFY_REG_YPQ);
+                break; // 11: r += p+q
+            default:
+                err = ECWRST_DSA_VERIFY_2MUL_NEXT_B2_ERROR;
+                goto End;
+            }
+        }
+    }
+    PkaJcb2Afn(SCAP_Inactive, xr, yr, EC_VERIFY_REG_ZR);
+
+    End:
+    return err;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst.h
new file mode 100644
index 0000000..0fe7e8b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PKA_ECC_H_H
+#define PKA_ECC_H_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "cc_ecpki_types.h"
+#include "pka_hw_defs.h"
+#include "pka.h"
+#include "ec_wrst.h"
+
+
+#define PKA_ECC_MAX_OPERATION_SIZE_BITS        640  /*for EC 521-bit*/
+
+/* maximal size of extended register in "big PKA words" and in 32-bit words:  *
+   the size defined according to RSA as more large, and used to define some   *
+*  auxiliary buffers sizes                                */
+#define PKA_ECC_MAX_REGISTER_SIZE_IN_PKA_WORDS ((PKA_ECC_MAX_OPERATION_SIZE_BITS+PKA_EXTRA_BITS+CC_PKA_WORD_SIZE_IN_BITS-1)/CC_PKA_WORD_SIZE_IN_BITS)
+#define PKA_ECC_MAX_REGISTER_SIZE_WORDS  (PKA_ECC_MAX_REGISTER_SIZE_IN_PKA_WORDS*(CC_PKA_WORD_SIZE_IN_BITS/32))
+
+
+/* affine ec-point (in PKA format) */
+typedef struct{
+  uint32_t x;
+  uint32_t y;
+} PkaRegAffPoint_t;
+
+/* jacobian ec-point: X:x/z^2, Y:y/z^3, t:a*z^4 (in PKA format) */
+typedef struct{
+  uint32_t x;
+  uint32_t y;
+  uint32_t z;
+} PkaRegJcbPoint_t;
+
+
+/* modified jacobian ec-point: X:x/z^2, Y:y/z^3, t:a*z^4 (in PKA format) */
+typedef struct{
+  uint32_t x;
+  uint32_t y;
+  uint32_t z;
+  uint32_t t;
+} PkaRegMdfPoint_t;
+
+
+/* EC double: modified-modified */
+void PkaDoubleMdf2Mdf(
+    const uint32_t x,  const uint32_t y,  const uint32_t z,  const uint32_t t,
+    const uint32_t x1, const uint32_t y1, const uint32_t z1, const uint32_t t1);
+
+/* EC double: modified-jacobi */
+void PkaDoubleMdf2Jcb(
+    const uint32_t x,  const uint32_t y,  const uint32_t z,
+    const uint32_t x1, const uint32_t y1, const uint32_t z1, const uint32_t t1);
+
+/* EC add: affine-jacobi-modified */
+void PkaAddJcbAfn2Mdf(
+    const uint32_t x,  const uint32_t y,  const uint32_t z, const uint32_t t,
+    const uint32_t x1, const uint32_t y1, const uint32_t z1,
+    const uint32_t x2, const uint32_t y2);
+
+/* convert to affine */
+void PkaJcb2Afn(
+    CCEcpkiScaProtection_t fr,
+    const uint32_t x, const uint32_t y, const uint32_t z);
+
+/* EC add: affine-affine-affine */
+void PkaAddAff(
+    const uint32_t x,  const uint32_t y,
+    const uint32_t x1, const uint32_t y1,
+    const uint32_t x2, const uint32_t y2);
+
+/* double EC scalar multiplication: R = a*p + b*q */
+uint32_t PkaSum2ScalarMullt(
+    const uint32_t xr, const uint32_t yr, const uint32_t a,
+    const uint32_t xp, const uint32_t yp, const uint32_t b,
+    const uint32_t xq, const uint32_t yq);
+
+
+CCError_t PkaEcWrstScalarMult(const CCEcpkiDomain_t *pDomain,
+                             const uint32_t       *scalar,
+                             uint32_t             scalSizeInWords,
+                             const uint32_t       *inPointX,
+                             const uint32_t       *inPointY,
+                             uint32_t             *outPointX,
+                             uint32_t             *outPointY,
+                             uint32_t             *tmpBuff);
+
+CCError_t PkaEcdsaVerify(void);
+
+
+#ifdef __cplusplus
+}
+
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_sign_regs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_sign_regs.h
new file mode 100644
index 0000000..553b4e2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_sign_regs.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef PKA_ECDSA_SIGN_REGS_DEF_H
+#define PKA_ECDSA_SIGN_REGS_DEF_H
+
+  /* PkaScalarMultSca regs */
+  #define EC_SIGN_REG_X2  12
+  #define EC_SIGN_REG_Y2  13
+  #define EC_SIGN_REG_Z2  14
+  #define EC_SIGN_REG_T2  15
+  #define EC_SIGN_REG_X4  16
+  #define EC_SIGN_REG_Y4  17
+  #define EC_SIGN_REG_Z4  18
+  #define EC_SIGN_REG_T4  19
+  #define EC_SIGN_REG_XS  20
+  #define EC_SIGN_REG_YS  21
+  #define EC_SIGN_REG_ZS  22
+  #define EC_SIGN_REG_TS  23
+  #define EC_SIGN_REG_ZP  24
+  #define EC_SIGN_REG_TP  25
+  #define EC_SIGN_REG_ZR  26
+  /* k, p[in/out] */
+  #define EC_SIGN_REG_ORD 26 /*=EC_SIGN_REG_ZR, used for EC order*/
+  #define EC_SIGN_REG_RK  27 /*scalar*/
+  #define EC_SIGN_REG_XP  28 /*in/out*/
+  #define EC_SIGN_REG_YP  29 /*in/out*/
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_verify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_verify.c
new file mode 100644
index 0000000..4a0c5a9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_verify.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pka_hw_defs.h"
+#include "pki.h"
+#include "pka.h"
+#include "pka_ec_wrst.h"
+#include "ec_wrst_error.h"
+#include "pka_ec_wrst_dsa_verify_regs.h"
+#include "pka_ec_wrst_glob_regs.h"
+
+extern const CCEcpkiDomain_t gEcDomans[];
+
+/***********    PkaEcdsaVerify   function      **********************/
+/**
+ * @brief This function performs verification of ECDSA signature using PKA.
+ *
+ * 1. Compute  h = d^-1,  h1 = f*h mod r,  h2 = c*h mod r.
+ * 2. Compute  P(Xp,Yp) =  h1*G  + h2*W; c1 = Px mod r
+ * 3. Compare  If  c1 != c,  then output "Invalid", else - "valid".
+ *
+ * Assuming: - PKA is initialized, all data is set into SRAM.
+ *
+ * @author reuvenl (8/7/2014)
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ */
+CCError_t PkaEcdsaVerify(void)
+{
+    CCError_t err = CC_OK;
+    int32_t modSizeInBits, ordSizeInBits;
+    uint32_t status1, status2;
+
+    /* Get sizes */
+    ordSizeInBits = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0));
+    modSizeInBits = CC_HAL_READ_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L2));
+
+    /*  1. If  C or D are not in interval [1,r-1] then output "invalid"        */
+    /* temporary set ECC_REG_N = ECC_REG_N - 1 for the following checking */
+    PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, ECC_REG_N, ECC_REG_N);
+
+    /* check C */
+    PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, EC_VERIFY_REG_C, 1/*imm*/);
+    PKA_GET_STATUS_CARRY(status1); /* if EC_VERIFY_REG_C >= 1, then status = 0 */
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, ECC_REG_N, EC_VERIFY_REG_C);
+    PKA_GET_STATUS_CARRY(status2); /* if EC_VERIFY_REG_C <= ECC_REG_N, then status = 1 */
+    if (status1 == 0 || status2 == 0) {
+        err = ECWRST_DSA_VERIFY_CALC_SIGN_C_INVALID_ERROR;
+        goto End;
+    }
+
+    /* check D */
+    PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, EC_VERIFY_REG_D, 1/*imm*/);
+    PKA_GET_STATUS_CARRY(status1); /* if EC_VERIFY_REG_D >= 1, then status = 0 */
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, ECC_REG_N, EC_VERIFY_REG_D);
+    PKA_GET_STATUS_CARRY(status2); /* if EC_VERIFY_REG_D <= EC_VERIFY_REG_R, then status = 1 */
+    if (status1 == 0 || status2 == 0) {
+        err = ECWRST_DSA_VERIFY_CALC_SIGN_D_INVALID_ERROR;
+        goto End;
+    }
+
+    /* restore ECC_REG_N  */
+    PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, ECC_REG_N, ECC_REG_N);
+
+    /* 2. Calculate h, h1, h2 and normalize EC_VERIFY_REG_F     */
+    /* 2.1. h = d^-1  mod r */
+    PKA_MOD_INV_W_EXP(EC_VERIFY_REG_H, EC_VERIFY_REG_D, EC_VERIFY_REG_TMP);
+
+    PKA_DIV(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP, EC_VERIFY_REG_F/*rem*/, ECC_REG_N/*div*/);
+    /* 2.2. h1 = f*h  mod r */
+    PKA_MOD_MUL(LEN_ID_N_BITS, EC_VERIFY_REG_H1/*Res*/, EC_VERIFY_REG_F/*OpA*/, EC_VERIFY_REG_H/*OpB*/);
+    /* 2.3. h2 = c*h mod r  */
+    PKA_MOD_MUL(LEN_ID_N_BITS, EC_VERIFY_REG_H2/*Res*/, EC_VERIFY_REG_C/*OpA*/, EC_VERIFY_REG_H/*OpB*/);
+
+    /* set PKA for operations according to ECC modulus    */
+    PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, PKA_REG_T0);
+    PKA_CLEAR(LEN_ID_N_PKA_REG_BITS, PKA_REG_T1);
+    PKA_WAIT_ON_PKA_DONE();
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), modSizeInBits);
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP, ECC_REG_N);
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, ECC_REG_N, EC_VERIFY_REG_TMP_N);
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP_N, EC_VERIFY_REG_TMP); //swap mod<->ord
+    PKA_COPY(LEN_ID_N_PKA_REG_BITS, ECC_REG_NP, EC_VERIFY_REG_TMP_NP);
+
+        /* Auxiliary values: rn_X = X*ECC_REG_N */
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N,   ECC_REG_N  );
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N4, ECC_REG_N4);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N8 , ECC_REG_N4, ECC_REG_N4);
+    PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N12, ECC_REG_N8, ECC_REG_N4);
+
+    /* 3. Compute EC point  P1 =  h1*G + h2*W by mod P    */
+    err = PkaSum2ScalarMullt(EC_VERIFY_REG_P_RX,
+        EC_VERIFY_REG_P_RY,
+        EC_VERIFY_REG_H1,
+        EC_VERIFY_REG_P_GX,
+        EC_VERIFY_REG_P_GY,
+        EC_VERIFY_REG_H2,
+        EC_VERIFY_REG_P_WX,
+        EC_VERIFY_REG_P_WY);
+    if(err)
+        goto End;
+
+    /* 4. Normalize: C' = pRx mod r. Compare C' == C              */
+    PKA_WAIT_ON_PKA_DONE();
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), ordSizeInBits);
+    PKA_DIV(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_TMP, EC_VERIFY_REG_P_RX/*rem*/, EC_VERIFY_REG_TMP_N/*div*/);
+    PKA_COMPARE_STATUS(LEN_ID_N_PKA_REG_BITS, EC_VERIFY_REG_P_RX, EC_VERIFY_REG_C, status1);
+    if (status1 != 1) {
+        err = ECWRST_DSA_VERIFY_CALC_SIGNATURE_IS_INVALID;
+    }
+End:
+    return err;
+
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_verify_regs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_verify_regs.h
new file mode 100644
index 0000000..bd4d5f4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_dsa_verify_regs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PKA_ECDSA_VERIFY_REGS_DEF_H
+#define PKA_ECDSA_VERIFY_REGS_DEF_H
+
+/* Definition of ECDSA Verify specific registers */
+#define EC_VERIFY_REG_R     PKA_REG_N
+#define EC_VERIFY_REG_NR    PKA_REG_NP
+#define EC_VERIFY_REG_F     2
+#define EC_VERIFY_REG_D     3
+#define EC_VERIFY_REG_H     4
+#define EC_VERIFY_REG_TMP   5
+#define EC_VERIFY_REG_XPQ 14
+#define EC_VERIFY_REG_YPQ 15
+#define EC_VERIFY_REG_ZR  16
+#define EC_VERIFY_REG_TR  17
+#define EC_VERIFY_REG_H1   18
+#define EC_VERIFY_REG_H2   19
+#define EC_VERIFY_REG_P_GX  20
+#define EC_VERIFY_REG_P_GY  21
+#define EC_VERIFY_REG_P_WX  22
+#define EC_VERIFY_REG_P_WY  23
+#define EC_VERIFY_REG_P_RX  24
+#define EC_VERIFY_REG_P_RY  25
+#define EC_VERIFY_REG_TMP_N  26
+#define EC_VERIFY_REG_TMP_NP 27
+#define EC_VERIFY_REG_C    28
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_glob_regs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_glob_regs.h
new file mode 100644
index 0000000..f64fa25
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_glob_regs.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ #ifndef PKA_ECC_GLOB_REGS_DEF_H
+ #define PKA_ECC_GLOB_REGS_DEF_H
+
+ /* Define global PKA registers pointers */
+ #define ECC_REG_N     PKA_REG_N
+ #define ECC_REG_N1    PKA_REG_N
+ #define ECC_REG_NP    PKA_REG_NP
+ #define ECC_REG_T     2
+ #define ECC_REG_T1    3
+ #define ECC_REG_T2    4
+ #define ECC_REG_T3    5
+ #define ECC_REG_AQ   6
+ #define ECC_REG_A_NM2 7
+ #define ECC_REG_N4   8
+ #define ECC_REG_N8   9
+ #define ECC_REG_N12  10
+ #define ECC_REG_EC_A  11
+ #define ECC_REG_T4    12
+ #define ECC_REG_AAA_Z 13
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_smul_no_scap.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_smul_no_scap.c
new file mode 100644
index 0000000..2bf7ee6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_smul_no_scap.c
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pka_hw_defs.h"
+#include "pki.h"
+#include "pka.h"
+#include "pka_error.h"
+#include "ec_wrst.h"
+#include "ec_wrst_error.h"
+#include "pka_ec_wrst.h"
+#include "pka_ec_wrst_glob_regs.h"
+
+
+//! RL Temporary for ECDSA Verify testing
+#include "pki_dbg.h"
+
+/* canceling the lint warning:
+   Info 717: do ... while(0) */
+/*lint --e{717} */
+
+/* canceling the lint warning:
+   Use of goto is deprecated */
+/*lint --e{801} */
+
+/* canceling the lint warning:
+Info 716: while(1) ... */
+/*lint --e{716} */
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+
+/***********    EcWrstDivideVectorBy2   function      **********************/
+/**
+ * @brief Divides a vector by 2 - in a secured way
+ *
+ *        The LSB of the vector is stored in the first cell in the array.
+ *
+ *        for example:
+ *
+ *        a vector of 128 bit : the value is :
+ *
+ *        word[3] << 96 | word[2] << 64 ............ word[1] << 32 | word[0]
+ *
+ * @return - no return value.
+ */
+
+static void EcWrstDivideVectorBy2(uint32_t *pVecBuff, /*!< [in] Vector buffer. */
+    uint32_t SizeInWords)/*!< [in] Size of vecrot in Words. */
+{
+        uint32_t i;
+        uint32_t Temp;
+
+        /* for loop for dividing the vectors arrays by 2 */
+        for (i=0;i < (SizeInWords)-1 ;i++) {
+                pVecBuff[i]=pVecBuff[i] >> 1;
+                Temp=pVecBuff[i+1]&1UL;
+                pVecBuff[i]=pVecBuff[i] | Temp<<(32-1);
+        }
+
+        /* dividing the MS word */
+        pVecBuff[SizeInWords-1]=pVecBuff[SizeInWords-1]>>1;
+
+        return;
+
+}
+
+
+/***********    PkaScalarMultAff   function      **********************/
+/**
+ * @brief Performs EC scalar multiplication p = k*p, not SCA-resistant
+ *
+ *  Implemented the algorithm, enhanced by A.Klimov
+ *
+ * @author reuvenl (03/19/2015)
+ *
+ * @return  - No return value.
+ */
+/* static */ void PkaScalarMultAff(
+              const uint32_t xr, const uint32_t yr, /*!< [in/out] Virtual registers containing coordinates of result EC point. */
+              const char *k,  /*!< [in] Virtual registers containing scalar. */
+              const uint32_t xp, const uint32_t yp) /*!< [in] Virtual registers containing coordinates of input EC point. */
+{
+        uint8_t tp = regTemps[14];
+        uint8_t zr = regTemps[15];
+        uint8_t tr = regTemps[16];
+
+        /* calculate auxiliary values */
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N,   ECC_REG_N  );
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N4, ECC_REG_N4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N8 , ECC_REG_N4, ECC_REG_N4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N12, ECC_REG_N8, ECC_REG_N4);
+
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, tp, ECC_REG_N4, yp); // ry of -p
+        //! RL may be changed to return error
+        PKA_ASSERT(*k == '+', "*k == '+'\n");
+
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, xr, xp);
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, yr, yp); // r = p
+        PKA_SET_VAL(zr, 1);
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, tr, ECC_REG_EC_A);
+
+        while (*++k) {
+                if (*k == '0') {
+                        PkaDoubleMdf2Mdf(xr,yr,zr,tr, xr,yr,zr,tr);     // *k = '0'
+                } else {
+                        PkaDoubleMdf2Jcb(xr,yr,zr, xr,yr,zr,tr);
+                        if (*k == '+') {
+                                PkaAddJcbAfn2Mdf(xr,yr,zr,tr, xr,yr,zr, xp,yp); // *k = '+'
+                        } else {
+                                PkaAddJcbAfn2Mdf(xr,yr,zr,tr, xr,yr,zr, xp,tp); // *k = '-'
+                        }
+                }
+        }
+
+        /* convert to affine */
+        PkaJcb2Afn(SCAP_Inactive, xr,yr,zr);
+
+        return;
+}
+
+
+/***********    PkaBuildNaf   function      **********************/
+/**
+ * @brief Transforms integer buffer K to NAF string.
+ *
+ * @author reuvenl (6/20/2014)
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ */
+/* static */CCError_t PkaBuildNaf(char **pNaf,     /*!< [out] Pointer to NAF key buffer (msb->lsb). */
+            uint32_t *pNafSz,  /*!< [in/out] size in bytes of the NAF output.
+                        Input - size of user given buffer, output - actual size of NAF key. */
+                        uint32_t *pK,      /*!< [in] Pointer to key buffer. */
+            uint32_t keySzBit) /*!< [in] Size of key in bits. */
+{
+        CCError_t err = CC_OK;
+        uint32_t wK, i = 0;
+        char *p; /* a pointer to the current NAF digit */
+
+        if (keySzBit == 0 || (keySzBit+2) > *pNafSz) {
+                err = PKA_NAF_KEY_SIZE_ERROR;
+                goto End;
+        }
+        /* MSBit must be 1 */
+        if ((pK[(keySzBit-1)/32] >> ((keySzBit-1)&0x1F)) != 1) {
+                err = PKA_NAF_KEY_SIZE_ERROR;
+                goto End;
+        }
+
+        /* set initial values */
+        *pNafSz = 0; /*NAF size in bytes*/
+        p = *pNaf + keySzBit + 1; /* start from the last byte */
+        *p = 0;
+        wK = CALC_FULL_32BIT_WORDS(keySzBit)/*+1*/; /*key size + extra word*/
+
+        /* zeroing extra word of key buffer */
+        pK[wK] = 0;
+
+        /* scan key bits and convert to NAF */
+        while (keySzBit) {
+                uint32_t carry, msBit;
+
+                i++;
+                (*pNafSz)++;
+                --p;
+                /* check overflow */
+                if (p < *pNaf) {
+                        err = PKA_NAF_KEY_SIZE_ERROR;
+                        goto End;
+                }
+                /* set NAF digit */
+                *p = (pK[0] & 1) ? ((pK[0] & 2) ? '-' : '+') : '0';
+
+                msBit = pK[wK-1] >> ((keySzBit%32)-1);
+                if (*p == '-') {
+                        carry = CC_CommonIncLsbUnsignedCounter(pK, 1, wK); // k += 1
+                        if (carry) {
+                                pK[wK] = 1;
+                                keySzBit++;
+                        } else if ((pK[wK-1] >> ((keySzBit%32)-1)) > msBit) {
+                                keySzBit++;
+                        }
+                }
+
+                EcWrstDivideVectorBy2(pK, wK+1); // k >>= 1
+                keySzBit--;
+
+                /* if MSbit is zeroed set new size value */
+                wK = (CALC_FULL_32BIT_WORDS(keySzBit));
+        }
+
+        /* actual NAF vector begin */
+        *pNaf = p;
+
+End:
+        return err;
+}
+
+
+/***********    ScalarMultAff   function      **********************/
+/**
+ * @brief EC scalar multiplication p = k*p, without SCA-protection features.
+ *
+ *  The function is more fast, than SCA protected function and performs:
+ *  - PKA init,
+ *  - setting input data into PKA registers,
+ *  - calls PkaScalarMultAff() and then output of result data from PKA.
+ *
+ * @author reuvenl (03/19/2015)
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ *
+ */
+static CCError_t ScalarMultAff(
+                         const CCEcpkiDomain_t *domain,            /*!< [in] Pointer to EC domain. */
+                         uint32_t *bxr, uint32_t *byr,             /*!< [out] Pointers to coordinates of result EC point.
+                                                                         The size of each of buffers must be not less, than
+                                                                         EC modulus size (in words). */
+                         const uint32_t *k, uint32_t kSizeBit,     /*!< [in] Pointer to the scalar and its size. */
+                         const uint32_t *bxp, const uint32_t *byp, /*!< [in] Pointer to coordinates of input EC point. */
+                         uint32_t *tmpBuff)                        /*!< [in] Pointer to temp buffer of size
+                                                                             not less than (2*ecOrderSizeInBits+1) in bytes. */
+{
+        CCError_t err = CC_OK;
+        uint32_t nafSz;
+        uint32_t modSizeInBits, modSizeInWords, ordSizeInWords;
+        uint32_t *kt = tmpBuff;
+        char *naf;
+        uint32_t pkaReqRegs = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
+            /* Define pka registers used*/
+        uint8_t  xp = regTemps[18];
+        uint8_t  yp = regTemps[19];
+        uint8_t  xr = regTemps[20];
+        uint8_t  yr = regTemps[21];
+
+        /* set domain parameters */
+        modSizeInBits  = domain->modSizeInBits;
+        modSizeInWords = CALC_FULL_32BIT_WORDS(modSizeInBits);
+        ordSizeInWords = CALC_FULL_32BIT_WORDS(domain->ordSizeInBits);
+
+    if ((ordSizeInWords > (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1)) ||
+        (modSizeInWords > CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)) {
+        return ECWRST_SCALAR_MULT_INVALID_MOD_ORDER_SIZE_ERROR;
+    }
+
+        /* temp key buf + 1 word */
+        kt[ordSizeInWords] = 0; kt[ordSizeInWords-1] = 0;
+        CC_PalMemCopy(kt, k, sizeof(uint32_t)*ordSizeInWords);
+        /* Naf buffer */
+        naf = (char*)(kt+ordSizeInWords+1);
+        nafSz = (ordSizeInWords+1)*32; /*NAF size in bytes*/
+        CC_PalMemSet(naf, 0, nafSz);
+
+        /* build NAF */
+        err = PkaBuildNaf(&naf, &nafSz, kt, kSizeBit);
+        if (err)
+                goto End;
+
+        /*  Init PKA for modular operations */
+        err = PkaInitAndMutexLock(modSizeInBits, &pkaReqRegs);
+        if (err != CC_OK) {
+                return err;
+        }
+
+        /*   Set data into PKA registers  */
+        /* set EC parameters */
+        PkaCopyDataIntoPkaReg(ECC_REG_N, 1, domain->ecP/*src_ptr*/, modSizeInWords);
+        PkaCopyDataIntoPkaReg(ECC_REG_NP, 1, ((EcWrstDomain_t*)&domain->llfBuff)->modTag,
+                               CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+        PkaCopyDataIntoPkaReg(ECC_REG_EC_A, 1, domain->ecA, modSizeInWords);
+        /* set point */
+        PkaCopyDataIntoPkaReg(xp, 1, bxp, modSizeInWords);
+        PkaCopyDataIntoPkaReg(yp, 1, byp, modSizeInWords);
+
+        /* Call scalar mult */
+        PkaScalarMultAff(xr, yr, naf,  xp,  yp);
+
+        /*  Output data from PKA registers  */
+        PkaCopyDataFromPkaReg(bxr, modSizeInWords, xr);
+        PkaCopyDataFromPkaReg(byr, modSizeInWords, yr);
+
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+ End:
+
+        /* zeroing of kt and naf buffers */
+        // RL NAF size according to NAF representation
+        CC_PalMemSetZero(tmpBuff, (ordSizeInWords+1)*sizeof(uint32_t) + (ordSizeInWords+1)*32/*NAF buff size in bytes*/);
+        return err;
+}
+
+
+
+/***********    PkaEcWrstScalarMult   function      **********************/
+/**
+ * @brief ECC scalar multiplication without SCA protection
+ *          features (NoScap).
+ *               outPoint = scalsr * inPoint.
+ *       1. Checks the validity of input parameters.
+ *       3. Calls the low level functions: ScalarMultAff according to SCA protection mode, to generate EC public key.
+ *       4. Outputs the user public and private key structures in little endian form.
+ *       5. Cleans temporary buffers.
+ *       6. Exits.
+ *     Mote: All buffers are given as 32-bit words arrays, where LSWord is a leftmost one.
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ */
+CCError_t PkaEcWrstScalarMult(const CCEcpkiDomain_t *pDomain,   /*!< [in] Pointer to current EC domain. */
+                             const uint32_t       *scalar,         /*!< [in] Pointer to the scalar buffer. */
+                             uint32_t             scalSizeInWords,/*!< [in] The exact size of the scalsr in words. */
+                             const uint32_t       *inPointX,       /*!< [in] Pointer to the point X coordinate. */
+                             const uint32_t       *inPointY,       /*!< [in] Pointer to the point Y coordinate. */
+                             uint32_t             *outPointX,      /*!< [out] Pointer to the point X coordinate. */
+                             uint32_t             *outPointY,      /*!< [out] Pointer to the point Y coordinate. */
+                             uint32_t             *tmpBuff)        /*!< [in] The pointer to the temp buffer of size not less,
+                                                                             than CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS. */
+{
+        CCError_t err = CC_OK;
+        uint32_t scalarSizeInBits;
+        CCCommonCmpCounter_t cmp;
+
+        /* get exact size of scalar */
+        scalarSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(scalar, scalSizeInWords);
+
+        /* compare scalar to EC generator order (0 < scalar < EC order) */
+        cmp = CC_CommonCmpLsWordsUnsignedCounters(scalar, scalSizeInWords,
+                                                     pDomain->ecR, CALC_FULL_32BIT_WORDS(pDomain->ordSizeInBits));
+
+        if ((scalarSizeInBits == 0) || (cmp == CC_COMMON_CmpCounter1GreaterThenCounter2)) {
+                return ECWRST_SCALAR_MULT_INVALID_SCALAR_VALUE_ERROR;
+        }
+
+        /* call scalar mult. function with affine coordinates, no SCAP */
+        err = ScalarMultAff(pDomain,
+                            outPointX, outPointY,
+                            scalar, scalarSizeInBits,
+                            inPointX, inPointY,
+                            tmpBuff);
+        /* Note: ScalarMultAff has zeroing the tmpBuff */
+
+        return err;
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_smul_scap.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_smul_scap.c
new file mode 100644
index 0000000..2150688
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/ec_wrst/pka_ec_wrst_smul_scap.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_common_math.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+#include "cc_ecpki_local.h"
+#include "pka_ec_wrst.h"
+#include "pki.h"
+#include "ec_wrst_error.h"
+#include "ec_wrst.h"
+#include "pka_ec_wrst_glob_regs.h"
+#include "pka_ec_wrst_dsa_sign_regs.h"
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+/***********    DoubleMdf2Mdf   function      **********************/
+/**
+ * @brief EC point doubling: p = 2*p1  modified-modified.
+ *
+ * All parameters are ID-s of PKA registers, containing the data.
+ *
+ * Part of PKA registers are implicitly defined in pka_ec_wrst_glob_regs.h file
+*
+ * \param x,y,z,t - output point coordinates
+*  \param x,y,z,t - input point coordinates
+*
+ * @return  - On success CC_OK is returned, on failure an error code.
+ */
+/* static */void DoubleMdf2Mdf(
+           const uint32_t x,  const uint32_t y,  const uint32_t z,  const uint32_t t,  /*!< [in] Pointer to the public key structure. */
+           const uint32_t x1, const uint32_t y1, const uint32_t z1, const uint32_t t1) /*!< [in] Pointer to the public key structure. */
+{ // t cannot be aliased
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, t, y1, y1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, t, z1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y1, y1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, t, x1, x1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, t, t, t);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, y, t);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x1, x1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, ECC_REG_T2);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, ECC_REG_T2, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, t1, ECC_REG_T2);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, t, ECC_REG_N4, t);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T2, ECC_REG_T2, t);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, t, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, t, x, t);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T3, ECC_REG_N12, t);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y, y);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, y, y, y);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, t, y, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, t, t1);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N8, y);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T3, ECC_REG_T2, y);
+        return;
+}
+
+/***********    PkaAddJcbJcb2Mdf   function      **********************/
+/**
+ * @brief pka ecc points adding: jacobian+jacobian=modified
+ *
+ * All parameters are ID-s of PKA registers, containing the data.
+ *
+ * @return  - no return code.
+ */
+/* static */void PkaAddJcbJcb2Mdf(
+            const uint32_t x,  const uint32_t y,  const uint32_t z, const uint32_t t,  /*!< [out] EC point modified coordinates. */
+            const uint32_t x1, const uint32_t y1, const uint32_t z1, /*!< [in] EC point jacobian coordinates. */
+            const uint32_t x2, const uint32_t y2, const uint32_t z2) /*!< [in] EC point jacobian coordinates. */
+{
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z2, z2);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, x, x1, t);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_N4, x);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z2, t);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y1, t);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N4, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z1, z1);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, ECC_REG_T1, x2, t, x);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z1, t);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, t, y2, t, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, z1, z2);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, z, ECC_REG_T1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, ECC_REG_T1, ECC_REG_T1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T1, ECC_REG_T1, ECC_REG_T2);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T1, ECC_REG_N4, ECC_REG_T1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, ECC_REG_T1, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x, ECC_REG_T2);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, t, t, ECC_REG_T1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, x, ECC_REG_T2);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, t, ECC_REG_T2, y);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N4, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, z, z);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, t, t);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, t, ECC_REG_EC_A, t);
+        return;
+}
+
+
+/***********    PkaAddJcbJcb2Jcb   function      **********************/
+/**
+ * @brief pka ecc points adding: jacob+jacob=jacob
+ *
+ * @return  - no return code.
+ */
+/* static */void PkaAddJcbJcb2Jcb(
+            const uint32_t x,  const uint32_t y,  const uint32_t z,  /*!< [out] EC point jacobian coordinates. */
+            const uint32_t x1, const uint32_t y1, const uint32_t z1, /*!< [in] EC point jacobian coordinates. */
+            const uint32_t x2, const uint32_t y2, const uint32_t z2) /*!< [in] EC point jacobian coordinates. */
+{
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T, z2, z2);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, x, x1, ECC_REG_T);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_N4, x);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T, z2, ECC_REG_T);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, y1, ECC_REG_T);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N4, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T, z1, z1);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, ECC_REG_T1, x2, ECC_REG_T, x);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T, z1, ECC_REG_T);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, ECC_REG_T, y2, ECC_REG_T, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, z1, z2);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, z, z, ECC_REG_T1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, ECC_REG_T1, ECC_REG_T1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T1, ECC_REG_T1, ECC_REG_T2);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, ECC_REG_T1, ECC_REG_N4, ECC_REG_T1);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, y, ECC_REG_T1, y);
+        PKA_MOD_MUL_NFR(LEN_ID_N_BITS, ECC_REG_T2, x, ECC_REG_T2);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, x, ECC_REG_T, ECC_REG_T, ECC_REG_T1);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, x, ECC_REG_T2, x);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_T2, x, ECC_REG_T2);
+        PKA_MOD_MUL_ACC_NFR(LEN_ID_N_BITS, y, ECC_REG_T, ECC_REG_T2, y);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, y, ECC_REG_N4, y);
+        return;
+}
+
+
+/***********    PkaScalarMultSca   function      **********************/
+/**
+ * @brief EC scalar multiplication p = k*p, SCA-resistant
+ *
+ *  Implemented algorithm, enhanced by A.Klimov
+ *
+ * @return  - no return code.
+ */
+/* static */void PkaScalarMultSca(void)
+{
+        uint32_t isK;
+        uint32_t sz1, sz2, sz, b2;
+        uint32_t W;
+        int32_t i, carry = 0; // always 0 or -1
+        uint32_t isNew;
+
+        /* calc. globals */
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N,   ECC_REG_N  );
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N4 , ECC_REG_N4, ECC_REG_N4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N8 , ECC_REG_N4, ECC_REG_N4);
+        PKA_ADD(LEN_ID_N_PKA_REG_BITS, ECC_REG_N12, ECC_REG_N8, ECC_REG_N4);
+
+        // To mask the size of k we calculate either k*p or -(-k)*p
+        PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_TP, EC_SIGN_REG_RK);
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_ZP, EC_SIGN_REG_ORD, EC_SIGN_REG_TP); // EC_SIGN_REG_ZP is -k
+        sz1 = PkaGetRegEffectiveSizeInBits(EC_SIGN_REG_RK);
+        sz2 = PkaGetRegEffectiveSizeInBits(EC_SIGN_REG_ZP);
+        /* chose k or -k to mask size of scalar */
+        if (sz1 > sz2) {
+                sz = sz1;
+                isK = 1;
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_RK, EC_SIGN_REG_TP); // Used k
+        } else {
+                sz = sz2;
+                isK = 0;
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_RK, EC_SIGN_REG_ZP); // Used -k
+        }
+
+        PKA_SET_VAL(EC_SIGN_REG_ZP, 1); // or random and adjust EC_SIGN_REG_XP, EC_SIGN_REG_YP, EC_SIGN_REG_TP
+
+        DoubleMdf2Mdf(EC_SIGN_REG_X2,EC_SIGN_REG_Y2,EC_SIGN_REG_Z2,EC_SIGN_REG_T2, EC_SIGN_REG_XP,EC_SIGN_REG_YP,EC_SIGN_REG_ZP,ECC_REG_EC_A); // 2p
+        DoubleMdf2Mdf(EC_SIGN_REG_X4,EC_SIGN_REG_Y4,EC_SIGN_REG_Z4,EC_SIGN_REG_T4, EC_SIGN_REG_X2,EC_SIGN_REG_Y2,EC_SIGN_REG_Z2,EC_SIGN_REG_T2);    // 4p
+
+        i = ((sz+1) & ~1) - 2; // round size up to even
+
+        isNew = 1;
+        b2 = PkaGet2MsBits(EC_SIGN_REG_RK, i, &W, &isNew);
+
+        switch (b2) {
+        case 1:
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_XS, EC_SIGN_REG_X2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_YS, EC_SIGN_REG_Y2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_ZS, EC_SIGN_REG_Z2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_TS, EC_SIGN_REG_T2);
+                carry = -1; /*pnt=2;*/
+                break;
+        case 2:
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_XS, EC_SIGN_REG_X2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_YS, EC_SIGN_REG_Y2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_ZS, EC_SIGN_REG_Z2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_TS, EC_SIGN_REG_T2);
+                carry =  0; /*pnt=2;*/
+                break;
+        case 3:
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_XS, EC_SIGN_REG_X4);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_YS, EC_SIGN_REG_Y4);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_ZS, EC_SIGN_REG_Z4);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_TS, EC_SIGN_REG_T4);
+                carry = -1; /*pnt=4;*/
+                break;
+        default: ASSERT(0);
+        }
+
+        // t of p,2,4 are no longer needed, let us use them for -ry
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_TP, ECC_REG_N4, EC_SIGN_REG_YP); // ry of -p
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_T2, ECC_REG_N4, EC_SIGN_REG_Y2); // ry of -2p
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_T4, ECC_REG_N4, EC_SIGN_REG_Y4); // ry of -4p
+
+        for (i -= 2; i >= 0; i -= 2) {
+                int32_t swt;
+        // EC_SIGN_REG_ZR as a temporary
+                DoubleMdf2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_ZR, EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS);
+                PkaDoubleMdf2Jcb(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_ZR); // s *= 4
+
+                /* get next two bits of key */
+                b2 = PkaGet2MsBits(EC_SIGN_REG_RK, i, &W, &isNew);
+                swt = carry*4+b2;
+                /* choose which point to add or subtract and update the carry*/
+                switch (swt) {
+                case (uint32_t)-4:
+            PkaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_X4,EC_SIGN_REG_T4,EC_SIGN_REG_Z4);
+            carry =  0;
+            break;
+                case (uint32_t)-3:
+            kaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_X2,EC_SIGN_REG_T2,EC_SIGN_REG_Z2);
+            carry = -1;
+            break;
+                case (uint32_t)-2:
+            PkaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_X2,EC_SIGN_REG_T2,EC_SIGN_REG_Z2);
+            carry =  0;
+            break;
+                case (uint32_t)-1:
+            PkaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_XP,EC_SIGN_REG_TP,EC_SIGN_REG_ZP);
+            carry =  0;
+            break;
+                case  0:
+            PkaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_XP,EC_SIGN_REG_YP,EC_SIGN_REG_ZP);
+            carry = -1;
+            break;
+                case +1:
+            PkaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_XP,EC_SIGN_REG_YP,EC_SIGN_REG_ZP);
+            carry =  0;
+            break;
+                case +2:
+            PkaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_X2,EC_SIGN_REG_Y2,EC_SIGN_REG_Z2);
+            carry =  0;
+            break;
+                case +3:
+            PkaAddJcbJcb2Mdf(EC_SIGN_REG_XS,EC_SIGN_REG_YS,EC_SIGN_REG_ZS,EC_SIGN_REG_TS, EC_SIGN_REG_XS,
+                EC_SIGN_REG_YS,EC_SIGN_REG_ZS, EC_SIGN_REG_X4,EC_SIGN_REG_Y4,EC_SIGN_REG_Z4);
+            carry = -1;
+            break;
+                default:
+            ASSERT(0);
+                }
+        }
+
+        PkaAddJcbJcb2Jcb(EC_SIGN_REG_X2,EC_SIGN_REG_Y2,EC_SIGN_REG_Z2, EC_SIGN_REG_XS,EC_SIGN_REG_YS,
+        EC_SIGN_REG_ZS, EC_SIGN_REG_XP,EC_SIGN_REG_TP,EC_SIGN_REG_ZP); // used only then carry is -1
+
+        if (carry == -1) {
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_T2, ECC_REG_N4, EC_SIGN_REG_Y2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_XP, EC_SIGN_REG_X2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_YP, isK == 1 ? EC_SIGN_REG_Y2 : EC_SIGN_REG_T2);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_ZP, EC_SIGN_REG_Z2);
+        } else {
+                PKA_SUB(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_TS, ECC_REG_N4, EC_SIGN_REG_YS);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_XP, EC_SIGN_REG_XS);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_YP, isK == 1 ? EC_SIGN_REG_YS : EC_SIGN_REG_TS);
+                PKA_COPY(LEN_ID_N_PKA_REG_BITS, EC_SIGN_REG_ZP, EC_SIGN_REG_ZS);
+        }
+        // convert to affine
+        PkaJcb2Afn(SCAP_Active, EC_SIGN_REG_XP, EC_SIGN_REG_YP, EC_SIGN_REG_ZP);
+
+        return;
+}
+
+
+/***********    ScalarMultSca   function      **********************/
+/**
+ * @brief EC scalar multiplication p = k*p, with SCA-protection features.
+ *
+ *  The function performs:
+ *  - PKA init,
+ *  - setting input data into PKA registers,
+ *  - calls pkaSmul function and then output result data from PKA.
+ *
+ * @author reuvenl (03/19/2015)
+ *
+ * @return  - On success CC_OK is returned, on failure an error code.
+ *
+ */
+static CCError_t ScalarMultSca(const CCEcpkiDomain_t *domain,   /*!< [in] Pointer to EC domain. */
+                 uint32_t *bxr, uint32_t *byr,        /*!< [out] Pointer to coordinates of result EC point. */
+                 const uint32_t *k, uint32_t kSizeBit,/*!< [in] Pointer to the scalar and its size. */
+                 const uint32_t *bxp, const uint32_t *byp)        /*!< [in] Pointer to the of input EC point. */
+{
+        uint8_t ord = regTemps[26];
+        uint8_t rk  = regTemps[27];
+        uint8_t rxp = regTemps[28];
+        uint8_t ryp = regTemps[29];
+
+        uint32_t err;
+        uint32_t modSizeInBits, modSizeInWords;
+        uint32_t pkaReqRegs = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
+
+        /* set domain parameters */
+        modSizeInBits  = domain->modSizeInBits;
+        modSizeInWords = CALC_FULL_32BIT_WORDS(modSizeInBits);
+
+        /*  Init PKA for modular operations: regs mappimg according to max.   *
+        *   size of order or modulus                                          */
+        err = PkaInitAndMutexLock(CC_MAX(modSizeInBits, domain->ordSizeInBits), &pkaReqRegs);
+        if (err != CC_OK) {
+                return err;
+        }
+        /* Set modulus sizes to L0, L1 and order sizes in L2, L3 */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET (CRY_KERNEL, PKA_L0), modSizeInBits);
+
+        /*   Set data into PKA registers  */
+        /* set EC parameters */
+        PkaCopyDataIntoPkaReg(ECC_REG_N, 1, domain->ecP/*src_ptr*/, modSizeInWords);
+        PkaCopyDataIntoPkaReg(ECC_REG_NP, 1, ((EcWrstDomain_t*)&domain->llfBuff)->modTag,
+                               CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+        PkaCopyDataIntoPkaReg(ECC_REG_EC_A, 1, domain->ecA, modSizeInWords);
+        PkaCopyDataIntoPkaReg(ord, 1, domain->ecR, CALC_FULL_32BIT_WORDS(domain->ordSizeInBits));
+        /* set point */
+        PkaCopyDataIntoPkaReg(rxp, 1, bxp, modSizeInWords);
+        PkaCopyDataIntoPkaReg(ryp, 1, byp, modSizeInWords);
+        /* set key */
+        PkaCopyDataIntoPkaReg(rk, 1, k, CALC_FULL_32BIT_WORDS(kSizeBit));
+
+        /* Call scalar mult */
+        PkaScalarMultSca();
+
+        /*  Output data from PKA registers  */
+        PkaCopyDataFromPkaReg(bxr, modSizeInWords, rxp);
+        PkaCopyDataFromPkaReg(byr, modSizeInWords, ryp);
+
+        /*   Finish the function and clear PKA regs.  */
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+        return err;
+}
+
+/***********    PkaEcWrstScalarMult   function      **********************/
+/**
+ *@brief ECC scalar multiplication function, with SCA protection
+ *        features (NoScap).
+ *             outPoint = scalsr * inPoint.
+ *
+ *   The function performs the following:
+ *     1. Checks the validity of input parameters.
+ *     2. Calls the low level functions: ScalarMultSca (with SCA protection) to generate EC public key.
+ *     3. Outputs the user public and private key structures in little endian form.
+ *     4. Cleans temporary buffers.
+ *     5. Exits.
+ *
+ *   Mote: All buffers are given as 32-bit words arrays, where LSWord is a leftmost one.
+ *         Sizes of buffers of in/out points coordinates are equal to EC modulus
+ *         size.
+ *
+ *  @return  - On success CC_OK is returned, on failure an error code.
+ *
+*/
+CCError_t PkaEcWrstScalarMult(const CCEcpkiDomain_t *pDomain,   /*!< [in] Pointer to EC domain. */
+                             const uint32_t       *scalar,         /*!< [in] Pointer to the scalsr buffer. */
+                             uint32_t             scalSizeInWords,/*!< [in] Size of the scalsr in 32-bit words. */
+                             uint32_t             *inPointX,       /*!< [in] Pointer to input point X coordinate. */
+                             const uint32_t       *inPointY,       /*!< [in] Pointer to input point Y coordinate. */
+                             const uint32_t       *outPointX,      /*!< [out] Pointer to output point X coordinate. */
+                             uint32_t             *outPointY,      /*!< [out] Pointer to output point Y coordinate. */
+                             uint32_t             *tmpBuff)        /*!< [in] Pointer to temporary buffer. */
+{
+        CCError_t err = CC_OK;
+        uint32_t scalarSizeInBits;
+        CCCommonCmpCounter_t cmp;
+
+        CC_UNUSED_PARAM(tmpBuff); // remove compilation warning
+
+        /* get exact size of scalar */
+        scalarSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(scalar, scalSizeInWords);
+
+        /* compare scalar to EC generator order (0 < scalar < order) */
+        cmp = CC_CommonCmpLsWordsUnsignedCounters(scalar, scalSizeInWords,
+                                                     pDomain->ecR, CALC_FULL_32BIT_WORDS(pDomain->ordSizeInBits));
+
+        if (scalarSizeInBits == 0 || cmp == CC_COMMON_CmpCounter1GreaterThenCounter2)
+                return ECWRST_SCALAR_MULT_INVALID_SCALAR_VALUE_ERROR;
+
+        /* perform scalar mult. with SCA protect features */
+        err = ScalarMultSca(pDomain,
+                        outPointX, outPointY,
+                        scalar, scalarSizeInBits,
+                        inPointX, inPointY);
+
+        return err;
+
+}
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/poly/poly.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/poly/poly.c
new file mode 100644
index 0000000..c0e2c95
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/poly/poly.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "pka.h"
+#include "pka_error.h"
+#include "pka_hw_defs.h"
+#include "mbedtls_cc_poly.h"
+#include "mbedtls_cc_poly_error.h"
+#include "cc_common.h"
+#include "poly.h"
+
+
+/* PKA registers*/
+
+#define  PRIME_REG  regTemps[0]
+#define  NP_REG     regTemps[1]
+#define  ACC_REG    regTemps[2]
+#define  KEY_R_REG  regTemps[3]
+#define  KEY_S_REG  regTemps[4]
+#define  DATA_REG   regTemps[5]
+#define  POLY_PKA_REGS_NUM (6+2) // +2 temp registers
+
+/* Macro for read non aligned word from RAM */
+#define GET_NON_ALIGNED_WORD(m_w0, m_w1, m_shift, m_shift_)    (((m_w0)>>(m_shift)) | ((m_w1)<<(m_shift_)))
+
+/* Global buffers  */
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+/* Mask for Key "r" buffer: clearing 4 high bits of indexes 3, 7, 11, 15; clearing low 2 bits of indexes 4,8,12 */
+static const uint32_t g_PolyMaskKeyR[CC_POLY_KEY_SIZE_IN_WORDS/2] = {0x0fffffff,0x0ffffffc,0x0ffffffc,0x0ffffffc};
+/* POLY PRIME  3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB */
+static const uint32_t g_PolyPrime[POLY_PRIME_SIZE_IN_WORDS] = {0xfffffffb,0xffffffff,0xffffffff,0xffffffff,0x3};
+/* Barrett tag Np = 800000000 00000000*/
+static const uint32_t g_PolyNp[] = {0x00000000,0x00000000,0x00000080};
+
+
+/**
+ * The function loads  remaining bytes (not full block) of data together with
+ * setting of rxtra bit according to Poly1305 algorithm.
+ *
+ * Assuming register size is 128+64 bits according to PKA multiplier 64x!6
+ * Note - this function assumes the PKA engine is already working
+ *
+ */
+static void PolyAccRemainBlock(
+        const uint8_t *pSrc,     /*!< [in] Pointer to source (little endian) buffer, aligned down to 32-bit word . */
+        uint32_t sizeBytes,      /*!< [in] Size of remaining data in words, should be in range [1...4]. */
+        bool isPolyAeadMode,     /*!< [in] Flag indicating padding 0's to short buffer */
+        const uint32_t dataRegSramAddr)/*!< [in] SRAM address of DATA_REG (not changed during calculations) */
+{
+    uint32_t  tmp[CC_POLY_BLOCK_SIZE_IN_WORDS+2] = {0};
+    uint32_t  i;
+
+    /* load block into words buffer and set high bit 1 */
+    CC_PalMemCopy((uint8_t*)tmp, pSrc, sizeBytes);
+    if(isPolyAeadMode) {
+        sizeBytes = CC_POLY_BLOCK_SIZE_IN_BYTES;
+    }
+    ((uint8_t*)tmp)[sizeBytes] = 1;
+
+    /* set address */
+    PKA_WAIT_ON_PKA_DONE();
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), dataRegSramAddr);
+
+    /* load block into PKA reg. */
+    for(i = 0; i < CC_POLY_BLOCK_SIZE_IN_WORDS+2; i++) {
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), tmp[i]);
+    }
+
+    /* acumulate the data and do modular multiplication by keyR */
+    PKA_MOD_ADD(LEN_ID_N_BITS, ACC_REG, ACC_REG, DATA_REG);
+    PKA_MOD_MUL(LEN_ID_N_BITS, ACC_REG, ACC_REG, KEY_R_REG);
+
+    return;
+}
+
+
+
+/***********    PolyAccCalc   function      **********************/
+
+/**
+ * @brief performs internal opeartions on PKA buffer to calculate the POLY accumulator.
+ *  Acc = ((Acc+block)*r) % p.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static uint32_t PolyAccCalc(const uint8_t *pSrc,     /*!< [in] The pointer to the data buff. */
+                            size_t   size,      /*!< [in] The size in bytes of data. */
+                            bool     isPolyAeadMode)      /*!< [in] Flag indicating padding 0's to short buffer */
+{
+    uint32_t shift, shift_; /* shift left (in bits) needed for aligning data to 32-bit words */
+    uint32_t remSize, blocksCount;
+    uint32_t *pSrc32;
+    uint32_t i;
+    uint32_t dataRegSramAddr;
+    uint32_t word0 = 0;
+
+    /* count of full blocks */
+    blocksCount = size / CC_POLY_BLOCK_SIZE_IN_BYTES;
+    /* remining data: count of bytes in not full 32-bit word */
+    remSize = size % CC_POLY_BLOCK_SIZE_IN_BYTES;
+
+    /* count of non aligned bytes and aligned pointer */
+    shift = (size_t)pSrc % CC_32BIT_WORD_SIZE;
+    shift_ = CC_32BIT_WORD_SIZE - shift;
+    pSrc32 = (uint32_t*)((uint32_t)pSrc - shift);
+
+
+    /* set first non aligned bytes into word0 */
+    if(shift) {
+
+        word0 = (uint32_t)pSrc[0];
+        if(shift_ > 1){
+            word0 |= ((uint32_t)pSrc[1] << 8);
+        }
+        if(shift_ > 2){
+            word0 |= ((uint32_t)pSrc[2] << 16);
+        }
+
+        shift = shift << 3; /*now shift is in bits*/
+        shift_ = shift_ << 3;
+        word0 <<= shift;
+    }
+
+    /*---------------------*/
+    /* process full blocks */
+    /*---------------------*/
+
+    /* get DATA_REG address */
+    PKA_GET_REG_ADDRESS(DATA_REG, dataRegSramAddr/*reg.addr*/);
+
+    for(i = 0; i < blocksCount; i++) {
+
+        /* set address of DATA_REG PKA register */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_ADDR), dataRegSramAddr);
+        PKA_WAIT_ON_PKA_DONE();
+
+        /* load block of 4 words */
+        if(shift) {
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA),
+                                  (uint32_t)GET_NON_ALIGNED_WORD(word0,     pSrc32[1], shift, shift_));
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA),
+                                  (uint32_t)GET_NON_ALIGNED_WORD(pSrc32[1], pSrc32[2], shift, shift_));
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA),
+                                  (uint32_t)GET_NON_ALIGNED_WORD(pSrc32[2], pSrc32[3], shift, shift_));
+            word0  = pSrc32[4];
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA),
+                                  (uint32_t)GET_NON_ALIGNED_WORD(pSrc32[3], word0, shift, shift_));
+        } else {
+            /* write data block */
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), pSrc32[0]);
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), pSrc32[1]);
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), pSrc32[2]);
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), pSrc32[3]);
+        }
+        pSrc32 += CC_POLY_BLOCK_SIZE_IN_WORDS;
+
+        /* set MSBit 129 and zeroe other high bits of register */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), 1UL);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, PKA_SRAM_WDATA), 0UL);
+
+        /* acumulate the data and do modular multiplication by keyR */
+        PKA_MOD_ADD(LEN_ID_N_BITS, ACC_REG, ACC_REG, DATA_REG);
+        PKA_MOD_MUL(LEN_ID_N_BITS, ACC_REG, ACC_REG, KEY_R_REG);
+    }
+
+    /*-----------------------------------*/
+    /* process remainig (not full) block */
+    /*-----------------------------------*/
+    if(remSize) {
+        PolyAccRemainBlock(pSrc + blocksCount*CC_POLY_BLOCK_SIZE_IN_BYTES,
+                           remSize, isPolyAeadMode, dataRegSramAddr);
+    }
+    return CC_OK;
+}
+
+
+
+/***********    PolyMacCalc   function      **********************/
+/**
+ * @brief Generates the POLY mac according to RFC 7539 section 2.5.1
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t PolyMacCalc(mbedtls_poly_key  key,        /*!< [in] Poniter to 256 bits of KEY. */
+                      const uint8_t         *pAddData,  /*!< [in] Optional - pointer to additional data if any */
+                      size_t            addDataSize,    /*!< [in] The size in bytes of the additional data */
+                      const uint8_t     *pDataIn,   /*!< [in] Pointer to data buffer to calculate MAC on */
+                      size_t            dataInSize, /*!< [in] The size in bytes of the additional data */
+                      mbedtls_poly_mac  macRes,     /*!< [out] The calculated MAC */
+                      bool              isPolyAeadMode)  /*!< [in] Boolean indicating if the Poly MAC operation is part of AEAD or just poly */
+
+{
+    uint32_t  rc = CC_OK;
+    uint32_t  *pKeyR = key;
+    uint32_t  lastBlock[CC_POLY_BLOCK_SIZE_IN_WORDS];
+    uint32_t  i = 0;
+    uint32_t pkaRegsNum = POLY_PKA_REGS_NUM;
+
+    // verify inputs
+    if ((key == NULL) ||
+        ((pDataIn == NULL) ^ (dataInSize == 0)) ||
+        (macRes == NULL) ||
+        ((pAddData == NULL) ^ (addDataSize == 0))) {
+        return CC_POLY_DATA_INVALID_ERROR;
+    }
+
+    /* clamp "KeyR"  */
+    for (i = 0; i < CC_POLY_KEY_SIZE_IN_WORDS/2; i++) {
+        pKeyR[i] = pKeyR[i] & g_PolyMaskKeyR[i];
+    }
+
+    /* initialize the PKA engine on default mode with size of modulus  */
+    rc = PkaInitAndMutexLock(POLY_PRIME_SIZE_IN_BITS, &pkaRegsNum);
+    if (rc != CC_OK) {
+        return rc;
+    }
+    // clear ACC_REG registers
+    PKA_CLEAR(LEN_ID_MAX_BITS, ACC_REG );
+
+    // set values in PKA register for the MAC operation:
+    // 1. set the prime number to ((1<<130) -5)
+    PkaCopyDataIntoPkaReg(PRIME_REG, LEN_ID_MAX_BITS, g_PolyPrime, CALC_32BIT_WORDS_FROM_BYTES(sizeof(g_PolyPrime)));
+
+    // 2. calculate NP for modulus operation
+    PkaCopyDataIntoPkaReg(NP_REG, LEN_ID_MAX_BITS, g_PolyNp, CALC_32BIT_WORDS_FROM_BYTES(sizeof(g_PolyNp)));
+
+    // 3. Copy pKeyR to PKA register #2
+    PkaCopyDataIntoPkaReg(KEY_R_REG, LEN_ID_MAX_BITS, pKeyR, CC_POLY_KEY_SIZE_IN_WORDS/2);
+    // 4. Copy pKeyS to PKA register #3
+    PkaCopyDataIntoPkaReg(KEY_S_REG, LEN_ID_MAX_BITS, pKeyR + CC_POLY_KEY_SIZE_IN_WORDS/2, CC_POLY_KEY_SIZE_IN_WORDS/2);
+
+    /* clear some registers  */
+    PKA_CLEAR(LEN_ID_MAX_BITS, DATA_REG);
+    PKA_CLEAR(LEN_ID_MAX_BITS, ACC_REG);
+    PKA_CLEAR(LEN_ID_MAX_BITS, PKA_REG_T0);
+    PKA_CLEAR(LEN_ID_MAX_BITS, PKA_REG_T1);
+
+    /* 5. Process the input data               */
+    /*-----------------------------------------*/
+    /* process the additional Data */
+    if(addDataSize) {
+        rc = PolyAccCalc(pAddData, addDataSize, isPolyAeadMode);
+        if (rc != CC_OK) {
+            goto end_func;
+        }
+    }
+    /*  process the DataIn  input */
+    if(dataInSize) {
+        rc = PolyAccCalc(pDataIn, dataInSize, isPolyAeadMode);
+        if (rc != CC_OK) {
+            goto end_func;
+        }
+    }
+
+    /* on Chacha-Poly mode process the sizes  */
+    // RL change name isPolyAeadMode to chaChaPolyMode
+    if (isPolyAeadMode) {
+        /* Fill lastBlock with 64-bit LE words: addDataSize | dataInSize */
+        lastBlock[0] = addDataSize;
+        lastBlock[1] = 0;
+        lastBlock[2] = dataInSize;
+        lastBlock[3] = 0;
+
+        rc = PolyAccCalc((uint8_t*)lastBlock, CC_POLY_BLOCK_SIZE_IN_BYTES, false/*isPolyAeadMode*/);
+        if (rc != 0) {
+            goto end_func;
+        }
+    }
+
+    //6. acc = acc+pkeyS
+    PKA_ADD(LEN_ID_N_BITS, ACC_REG, ACC_REG, KEY_S_REG);
+
+    //7. copy acc into macRes
+    PkaCopyDataFromPkaReg(macRes, CC_POLY_MAC_SIZE_IN_WORDS, ACC_REG);
+
+    end_func:
+    PkaFinishAndMutexUnlock(pkaRegsNum);
+    return rc;
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/poly/poly.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/poly/poly.h
new file mode 100644
index 0000000..a38bf94
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/poly/poly.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef POLY_H
+#define POLY_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#include "cc_error.h"
+#include "mbedtls_cc_poly.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! The POLY block size in 32-bit words */
+#define CC_POLY_BLOCK_SIZE_IN_WORDS  4
+#define CC_POLY_BLOCK_SIZE_IN_BYTES  (CC_POLY_BLOCK_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE)
+
+#define POLY_PRIME_SIZE_IN_BITS   130
+#define POLY_PRIME_SIZE_IN_WORDS  CALC_FULL_32BIT_WORDS(POLY_PRIME_SIZE_IN_BITS)
+
+/*! The POLY PKA registers size in 32-bit words */
+#define CC_POLY_PKA_REG_SIZE_IN_PKA_WORDS  4
+#define CC_POLY_PKA_REG_SIZE_IN_WORDS  (CC_POLY_PKA_REG_SIZE_IN_PKA_WORDS * (CALC_FULL_32BIT_WORDS(CC_PKA_WORD_SIZE_IN_BITS)))
+#define CC_POLY_PKA_REG_SIZE_IN_BYTES  (CC_POLY_PKA_REG_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE)
+
+
+/**
+ * @brief Generates the POLY mac according to RFC 7539 section 2.5.1
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t PolyMacCalc(mbedtls_poly_key  key,        /*!< [in] Poniter to 256 bits of KEY. */
+            const uint8_t       *pAddData,  /*!< [in] Optional - pointer to additional data if any */
+            size_t          addDataSize,    /*!< [in] The size of the additional data */
+            const uint8_t       *pDataIn,   /*!< [in] Pointer to data buffer to calculate MAC on */
+            size_t          dataInSize, /*!< [in] The size of the additional data */
+            mbedtls_poly_mac        macRes,     /*!< [out] The calculated MAC */
+            bool     isPolyAeadMode);  /*!< [in] Boolean indicating if the Poly MAC operation is part of AEAD or just poly */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //POLY_H
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa.h
new file mode 100644
index 0000000..76ef090
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef LLF_RSA_H
+#define LLF_RSA_H
+
+
+#include "cc_rsa_types.h"
+#include "cc_rnd_common.h"
+#ifdef FIPS_CERTIFICATION
+#include "fips_tests_rsa_def.h"
+#include "cc_common.h"
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+#define PKA_MAX_RSA_KEY_GENERATION_SIZE_BITS   CC_RSA_MAX_KEY_GENERATION_SIZE_BITS
+/* max allowed size of pprimes P, Q in RSA KG */
+#define PKA_RSA_KG_MAX_PQ_SIZE_BITS  (PKA_MAX_RSA_KEY_GENERATION_SIZE_BITS/2)
+/* max. total count of avaliable PKA registers in RSA KG */
+#define PKA_RSA_KG_MAX_COUNT_REGS  \
+        CC_MIN(PKA_MAX_COUNT_OF_PHYS_MEM_REGS, \
+                (8*CC_SRAM_PKA_SIZE_IN_BYTES) / (PKA_RSA_KG_MAX_PQ_SIZE_BITS + CC_PKA_WORD_SIZE_IN_BITS))
+/* max. count of avaliable registers in RSA KG without auxiliary regs. 30,31  */
+#define PKA_RSA_KG_MAX_REG_ID (PKA_RSA_KG_MAX_COUNT_REGS - 2)
+
+/* define size of auxiliary prime numbers for RSA  *
+*  (see FIPS 186-4 C3 tab.C3)                      */
+#define PKA_RSA_KEY_1024_AUX_PRIME_SIZE_BITS   104   /* for P,Q size 1024 bit aux.size > 100 bits */
+#define PKA_RSA_KEY_2048_AUX_PRIME_SIZE_BITS   144   /* for P,Q size 2048 bit aux.size > 140 bits */
+#define PKA_RSA_KEY_3072_AUX_PRIME_SIZE_BITS   176   /* for P,Q size 3072 bit aux.size > 170 bits */
+
+#define PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS 8 /* max size of temp buffer for auxiliary prime */
+
+/* define count of Miller-Rabin tests for P,Q and  auxiliary prime numbers *
+*  for RSA key generation (see FIPS 186-4 C3 tab.C3)                       */
+#define PKA_RSA_KEY_1024_AUX_PRIME_RM_TST_COUNT 38
+#define PKA_RSA_KEY_1024_PQ_PRIME_RM_TST_COUNT   7
+#define PKA_RSA_KEY_2048_AUX_PRIME_RM_TST_COUNT 32
+#define PKA_RSA_KEY_2048_PQ_PRIME_RM_TST_COUNT   4
+#define PKA_RSA_KEY_3072_AUX_PRIME_RM_TST_COUNT 27
+#define PKA_RSA_KEY_3072_PQ_PRIME_RM_TST_COUNT   3
+
+#define CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_WORDS        CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / CC_BITS_IN_32BIT_WORD
+
+#define LLF_PKI_PKA_DEBUG 1
+
+#ifdef FIPS_CERTIFICATION
+rsaKgInternalDataStruct_t rsaKgOutParams;
+#endif
+
+
+/*  RSA   key generation parameters structure */
+typedef struct
+{
+    uint32_t auxPrimesSizeInBits;
+    uint32_t pqPrimesMilRabTestsCount;
+    uint32_t auxPrimesMilRabTestsCount;
+}RsaKgParams_t;
+
+/*  RSA   Barrett tags for modular operations with N, P, Q */
+typedef struct
+{
+    uint32_t tmpBuf[3*CC_PKA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t barN[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS]; /*!< Barrett tag for modulus N */
+    uint32_t barP[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS]; /*!< Barrett tag for modulus P */
+    uint32_t barQ[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS]; /*!< Barrett tag for modulus Q */
+}RsaKgIntBuff_t;
+
+CCError_t RsaGenPandQ(CCRndContext_t *rndContext_ptr,
+                 size_t          KeySize,
+                 uint32_t        eSizeInBits,
+                 uint32_t       *pPubExp,
+                 CCRsaKgData_t  *KeyGenData_ptr);
+
+CCError_t RsaPrimeTestCall(CCRndContext_t *rndContext_ptr,
+                 uint32_t *P_ptr,
+                 int32_t   sizeWords,
+                 int32_t   rabinTestsCount,
+                 int8_t   *isPrime_ptr,
+                 uint32_t *TempBuff_ptr,
+                 CCRsaDhPrimeTestMode_t primeTestMode);
+
+CCError_t RsaCalculateNandD(CCRsaPubKey_t    *pCcPubKey, /*!< [in] pointer to the public key structure */
+                CCRsaPrivKey_t   *pCcPrivKey, /*!< [in] pointer to the private key structure */
+                CCRsaKgData_t    *KeyGenData_ptr, /*!< [in] pointer to a structure required for the KeyGen operation, holding P and Q */
+                            uint32_t          primeSizeInBits); /*!< [in] Size of the prime factors in bits. */
+
+
+CCError_t RsaCalculateCrtParams(uint32_t *pPubExp,      /*!< [in]  Pointer to the public exponent. */
+                                         uint32_t eSizeInBits,  /*!< [in]  Public exponent size in bits. */
+                                         uint32_t nSizeInBits,  /*!< [in]  Size of the key modulus in bits. */
+                                         uint32_t *pPrimeP,     /*!< [out]  First factor pointer - p. */
+                                         uint32_t *pPrimeQ,     /*!< [out]  Second factor pointer - Q. */
+                                         uint32_t *pPrivExp1dp, /*!< [out]  Private exponent for first factor - dP. */
+                                         uint32_t *pPrivExp2dq, /*!< [out]  Private exponent for second factor - dQ. */
+                                         uint32_t *pQInv);
+
+
+//#if (defined RSA_KG_FIND_BAD_RND || defined RSA_KG_NO_RND) && defined DEBUG
+extern uint8_t   RSA_KG_debugPvect[CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2];
+extern uint8_t   RSA_KG_debugQvect[CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2];
+extern uint8_t PQindex;
+extern uint8_t  rBuff1[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS * sizeof(uint32_t) ];
+extern uint8_t  rBuff2[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS * sizeof(uint32_t) ];
+extern uint8_t  rBuff3[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS * sizeof(uint32_t) ];
+extern uint8_t  rBuff4[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS * sizeof(uint32_t) ];
+/* temp buffers for output results of generation P1,P2 for P and Q  */
+extern uint32_t P1pR[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+extern uint32_t P2pR[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+extern uint32_t P1qR[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+extern uint32_t P2qR[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+/* final values of P1,P2 for P and Q */
+extern uint32_t P1pPr[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+extern uint32_t P2pPr[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+extern uint32_t P1qPr[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+extern uint32_t P2qPr[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS];
+extern uint32_t *P1R_ptr;
+extern uint32_t *P2R_ptr;
+extern uint32_t *P1Pr_ptr;
+extern uint32_t *P2Pr_ptr;
+
+/* temp buffers and pointer for output the P,Q  after generation */
+extern uint32_t rBuffP[CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_WORDS / 2];
+extern uint32_t rBuffQ[CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_WORDS / 2];
+extern uint32_t  *PQ_ptr;
+//#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_genkey.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_genkey.c
new file mode 100644
index 0000000..51369bb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_genkey.c
@@ -0,0 +1,1939 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_pal_types.h"
+#include "cc_rsa_types.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_local.h"
+#include "cc_common_math.h"
+#include "cc_rnd_common.h"
+#include "cc_rnd_error.h"
+#include "pka.h"
+#include "pka_error.h"
+#include "pki.h"
+#include "pka_hw_defs.h"
+#include "cc_pal_mem.h"
+#include "rsa_public.h"
+#include "rsa_private.h"
+#include "rsa.h"
+#ifdef FIPS_CERTIFICATION
+#include "fips_tests_rsa_def.h"
+#include "cc_common.h"
+#endif
+
+/* canceling the lint warning:
+Info 716: while(1) ... */
+/*lint --e{716} */
+/* canceling the lint warning: Constant value Boolean
+Warning 506 regarding while(1) ... */
+/*lint --e{506} */
+
+/* canceling the lint warning:
+Info 506: Constant value Boolean ... */
+/*lint --e{506} */
+
+/* canceling the lint warning:
+Info 774: Boolean within 'if' always evaluates to False */
+/*lint --e{774} */
+
+/************************ Defines ******************************/
+
+#define RSA_QUICK_PRIME_TEST_DIVISIONS_COUNT  128
+
+#define CALC_PRIME_PRODUCT_NUM ( CC_MIN(CALC_FULL_32BIT_WORDS(CC_RSA_MAX_KEY_GENERATION_SIZE_BITS),CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS) )
+#define PRIME_PRODUCT_BUFF_SIZE ( CC_MAX(CALC_FULL_32BIT_WORDS(CC_RSA_MAX_KEY_GENERATION_SIZE_BITS),CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS) )
+#define PRIME_NUM 256
+
+#define CALC_PRIME_PRODUCT   (CALC_PRIME_PRODUCT_NUM/2 - 3)
+
+#if (CALC_PRIME_PRODUCT > (CC_PKA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS-6))
+        #error ("CALC_PRIME_PRODUCT > (CC_PKA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS-6)")
+#endif
+
+
+/************************ Global Data ******************************/
+#ifdef FIPS_CERTIFICATION
+rsaKgInternalPrime_t prim1Int;
+rsaKgInternalPrime_t prim2Int;
+extern rsaKgInternalDataStruct_t rsaKgOutParams;
+rsaKgInternalPrime_t  *primeInt = NULL;
+#endif
+
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+const uint32_t g_PrimeProduct[PRIME_PRODUCT_BUFF_SIZE] = {
+        3234846615UL,95041567UL,907383479,4132280413UL,121330189,257557397UL,490995677,842952707,
+        1314423991UL,2125525169UL,3073309843UL,16965341,20193023,23300239,29884301,35360399,
+        42749359UL,49143869,56466073,65111573,76027969,84208541,94593973,103569859,119319383,133390067UL,
+        154769821UL,178433279,193397129,213479407,229580147,250367549,271661713,293158127,319512181,
+        357349471UL,393806449,422400701,452366557,507436351,547978913,575204137,627947039,666785731,
+        710381447UL,777767161UL,834985999UL,894826021UL,951747481UL,1019050649UL,1072651369UL,1125878063UL,1185362993UL,
+        1267745273UL,1322520163UL,1391119619UL,1498299287UL,1608372013UL,1700725291UL,1805418283UL,1871456063UL,
+        2008071007UL,2115193573UL,2178429527UL,2246284699UL,2385788087UL
+};
+
+const uint16_t g_SmallPrime[PRIME_NUM] =
+{
+        3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,
+        113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,
+        229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,
+        359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,
+        487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,
+        619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,
+        761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,
+        911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,
+        1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,
+        1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,
+        1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,
+        1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,
+        1579,1583,1597,1601,1607,1609,1613,1619,1621
+};
+
+const uint16_t g_LastProductPrime[PRIME_PRODUCT_BUFF_SIZE] =
+{
+        9,14,19,24,28,32,36,40,44,48,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,
+        115,118,121,124,127,130,133,136,139,142,145,148,151,154,157,160,163,166,169,172,175,178,181,
+        184,187,190,193,196,199,202,205,208,211,214,217
+
+};
+
+
+extern CCError_t RndGenerateWordsArrayInRange(CCRndContext_t *pRndContext,
+                                                     uint32_t   rndSizeInBits,
+                                                     uint32_t  *maxVect_ptr,
+                                                     uint32_t  *rndVect_ptr,
+                                                     uint32_t  *tmp_ptr);
+
+/***********    PkaRsaKgX931Jacobi   function      **********************/
+/**
+ * @brief Calculates Jacobi index.
+ *  If there is such a vector b, that satisfies the condition b^2 = a mod p, the result is 1.
+ *  If there is no such vector, the result is -1.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t PkaRsaKgX931Jacobi (uint32_t  lenId,       /*!< [in]  The RegsSizesTable entry, containing the exact size of vector p in bits. */
+                                       int8_t    rA,          /*!< [in]  Virtual pointer to the base vector. */
+                                       int8_t    rP,          /*!< [in]  Virtual pointer to the prime to be tested (the modulos). */
+                                       int32_t   *pJacobiRes, /*!< [out]  Pointer to the result var (1,0,-1) as described in the description. */
+                                       int8_t    rA1,         /*!< [in]  virtual pointers to temp PKA registers. */
+                                       int8_t    rP1,         /*!< [in]  virtual pointers to temp PKA registers. */
+                                       int8_t    rT)          /*!< [in]  virtual pointers to temp PKA registers. */
+{
+        int32_t    k, s;
+        uint32_t   residue;
+        uint32_t bitVal;
+        uint32_t status;
+        /* low words of A1 and P1 */
+        uint32_t A1_0, P1_0;
+        /* temp swap value */
+        int8_t  rSw;
+
+        /* copy the input vectors with extension */
+        PKA_COPY(LEN_ID_MAX_BITS, rA1/*dest*/, rA/*src*/);
+        PKA_COPY(LEN_ID_MAX_BITS, rP1/*dest*/, rP/*src*/);
+
+        /* initialize the result as 1 ( default ) */
+        *pJacobiRes = 1;
+
+        /* step 3.  if a1 == 1, return - we have done */
+        PKA_COMPARE_IM_STATUS(lenId+1, rA1/*OpA*/, 1/*OpB*/, status);
+        if (status == 1) {
+                return CC_OK;
+        }
+
+
+        // do loop for finding the jacobi
+        do {
+                // Step 1.  If a == 0, return the result 0
+                PKA_COMPARE_IM_STATUS(lenId+1, rA1/*OpA*/, 0/*OpB*/, status);
+                if (status == 1) {
+                        *pJacobiRes = 0;
+                        return CC_OK;
+                }
+
+
+                // Step 2. Find out larger power of two for A1
+                k = 0;
+
+                /* check parity of A1 */
+                PKA_READ_BIT0(lenId+1, rA1/*OpA*/, bitVal);
+                while (bitVal == 0) {
+                        /* divide by 2 */
+                        PKA_SHR_FILL0(lenId+1, rA1/*Res*/, rA1/*OpA*/, 1-1/*S*/);
+                        PKA_READ_BIT0(lenId+1, rA1/*OpA*/, bitVal);
+                        k++;
+                }
+
+                // get low bytes of A1 and P1
+                PKA_READ_WORD_FROM_REG(A1_0, 0, rA1);
+                PKA_READ_WORD_FROM_REG(P1_0, 0, rP1);
+
+                /* initialize s as 0 */
+                s = 0;
+
+                // step 3.  if k is even set s=1
+                if ((k & 1) == 0) {
+                        s = 1;
+                } else {
+                        /* else set s=1 if p = 1 or 7 (mod 8) or s=-1 if p = 3 or 5 (mod 8) */
+                        residue = P1_0 & 7;
+
+                        if (residue == 1 || residue == 7) {
+                                s = 1;
+                        } else if (residue == 3 || residue == 5) {
+                                s = -1;
+                        }
+                }
+
+                // Step 4.  If p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s
+                if (((P1_0 & 3) == 3) && ((A1_0 & 3) == 3)) {
+                        s = -s;
+                }
+
+                /* Step 5 : Update the result                   */
+                *pJacobiRes *= s;
+
+
+                // Step 6.  If a1 == 1, return - done
+                PKA_COMPARE_IM_STATUS(lenId+1, rA1/*OpA*/, 1/*OpB*/, status);
+                if (status == 1) {
+                        return CC_OK;
+        }
+
+                /* p1 = p1 mod a1 - the result is at rP1 register  */
+                PKA_DIV(lenId+1 , rT/*ResNotUsed*/, rP1/*OpA*/, rA1/*OpB*/);
+
+                // Step 7.  Exchange P1 & A1
+                rSw = rP1;
+                rP1   = rA1;
+                rA1   = rSw;
+
+        }while (1); /* end of do loop */
+}
+
+
+
+/***********    PkaRsaKgX931MillerRabinTest   function      **********************/
+/**
+ * @brief Executes the rabin miller test according to the the ANS X9.31 standard.
+ *
+ *    Algorithm:
+ *        1. Let: prime candidate P = 1 + 2^a * m, where: m is odd and a > 0.
+ *        2. For( i = 0; i < countTests; i++ ) do
+ *             2.1. Generate random number b in range  1 < b < P.
+ *             2.2. Calculate z = b^m mod P.
+ *             2.3. If z = 1, or z = P-1, then goto st.6.
+ *             2.4. For(j = 1; j < a; j++ ) do
+ *                   2.4.1.  set z = z^2 mod P
+ *                   2.4.2. If  z = P-1, then goto st.6.
+ *                   2.4.3. If  z = 1, then output "composite" and stop.
+ *                  End for //2.4.
+ *             2.5. Output "composite". Stop.
+ *           End for //2.
+ *        3. Output P is "probable prime". Stop.
+ *
+ *       Assumings: - PKA is initialised on default mode for prime P as modulus (see near);
+ *                  - the registers sizes table and mapping table are set on default mode,
+ *                    according to exact P size, that means:
+ *                      -- registers sizes table entries are set by default as follows:
+ *                           lenId - P_sizeBits, lenId+1 - (32*P_sizeWords + 32 bit);
+ *                  - the prime candidate P is inserted in the modulus register PKA_REG_N;
+ *                  - the Barrett tag NP for P is inserted into register 1;
+ *                  - the PKA clocks are initialized.
+ *
+ *       NOTE: - It uses 7 PKA data registers: PKA_REG_N,PKA_REG_NP,30,31, and 3 temp registers.
+ *
+ *  Assumptions : the max size supported is 2112 bits.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static  CCError_t PkaRsaKgX931MillerRabinTest(CCRndContext_t *pRndContext, /*!< [in/out]  Pointer to the RND context buffer. */
+                                               uint32_t  lenId,           /*!< [in]  The ID of entry in RegsSizesTable, containing modulusSizeInBits. */
+                                               uint32_t  modulusSizeInBits,  /*!< [in]  The prime candidate size. */
+                                               int8_t   *pSuccessCode,    /*!< [out]  the success code : 0 - the test failed , 1 the test passed. */
+                                               uint8_t   testsCount,      /*!< [in]  Count of exponentiations in test. If CountTests = 0, then
+                                              CountTests will be set automatically according to prime size. */
+                                               int8_t    rT0,         /*!< [in]  Virtual pointer to the base vector. */
+                                               int8_t    rT1,         /*!< [in]  Virtual pointer to the base vector. */
+                                               int8_t    rT2,         /*!< [in]  Virtual pointer to the base vector. */
+                                               uint32_t  *pTempBuff)      /*!< [in]   pointer to temp buffer of size 3*modulusSizeInWords. */
+{
+        CCError_t error = CC_OK;
+        uint32_t  i, j;
+        uint32_t aValue, pSizeInWords;
+        uint32_t status;
+        uint32_t bitVal;
+        uint32_t *pTempP, *pTempB;
+
+        /* prime size in words */
+        pSizeInWords = CALC_FULL_32BIT_WORDS(modulusSizeInBits);
+
+        // first pSizeInWords of pTempBuff is used as temprary buffer by RndGenerateWordsArrayInRange
+        pTempP = &pTempBuff[pSizeInWords];
+        pTempB = &pTempBuff[2*pSizeInWords];
+
+        /* clearing the temp registers */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rT0/*regNum*/);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rT1/*regNum*/);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rT2/*regNum*/);
+
+        // St. 1.2. Calculate a and m such, that P = 1 + 2^a * m ; m=>rT0, a=>aValue
+        /* copy P into register rT0 */
+        PKA_COPY(LEN_ID_MAX_BITS, rT0/*dst*/, PKA_REG_N/*src=P*/);
+
+        /* rT0 = P - 1 */
+        PKA_SUB_IM( lenId+1, rT0/*Res*/, rT0/*P*/, 1/*imm*/);
+
+        /* set P-1 in tempP buff */
+        PkaCopyDataFromPkaReg(pTempP, pSizeInWords, rT0/*srcReg*/);
+
+        /* a = 1 */
+        aValue = 1;
+
+        while (1) {
+                /* divide: rT0 = rT0 / 2 */
+                PKA_SHR_FILL0(lenId+1, rT0/*Res*/, rT0/*P*/, 1-1/*OpB*/);
+
+                /* test parity of rT0 */
+                PKA_READ_BIT0(lenId+1, rT0/*P*/, bitVal);
+                if (bitVal == 0) {
+                        aValue++;
+                } else {
+                        break;
+                }
+        }
+
+        // St. 2. Rabin-Miller test main loop
+        *pSuccessCode = CC_TRUE;
+
+        for (i = 0 ; i < testsCount ; ++i) {
+                // St. 2.1. Prepare a random number b, used for the Rabin-Miller test  */
+                //          as the Base of exponentiation. The number must be not larger, than
+
+                /* generate a random number b=>rT1 for testing the primality of P by  *
+                *  exponentiation                                 */
+                CC_PalMemSetZero(pTempB, sizeof(uint32_t)*pSizeInWords);
+                error = RndGenerateWordsArrayInRange(
+                                                         pRndContext,
+                                                         modulusSizeInBits,
+                                                         pTempP/*(P-1) - maxVect*/,
+                                                         pTempB/*Rnd*/,
+                                                         pTempBuff/*temp buff*/);
+                if (error != CC_OK) {
+                        return error;
+                }
+
+                PkaCopyDataIntoPkaReg( rT1/*dstReg*/, LEN_ID_MAX_BITS, pTempB/*src_ptr*/, pSizeInWords);
+
+                // St. 2.2. Calculate: z = rT1 = z^m mod P; Set j = 0.
+                PKA_MOD_EXP( lenId, rT1/*Res=z*/, rT1/*opA=b*/, rT0/*OpB=m*/);
+
+        // St. 2.3. Check; if z = 1 or z = P-1, then generate next B
+                /* z == 1 ? */
+                PKA_COMPARE_IM_STATUS(lenId+1, rT1/*z*/, 1/*OpB*/, status);
+                if (status == 1) {
+                        goto passed_this_iteration;
+                }
+
+                /* rT2 = P - 1 */
+                PKA_SUB_IM( lenId+1, rT2/*Res*/, PKA_REG_N/*P*/, 1/*OpB*/);
+
+                /* z == P-1 ? */
+                PKA_COMPARE_STATUS(lenId+1, rT2/*P*/, rT1/*OpB*/, status);
+                if (status == 1) {
+                        goto passed_this_iteration;
+                }
+
+                // St. 2.4. Loop: do while not meet conditions
+                //        (j == 0 && z == 1) or (z== P-1 )
+                for (j = 1; j < aValue; j++) {
+                        /* St. 2.4.1. z= z^2 mod m  */
+                        PKA_MOD_MUL( lenId, rT1/*Res*/, rT1/*P*/, rT1/*OpB*/);
+
+                        /* St. 2.4.2. if z == P-1, then break and next i */
+                        PKA_COMPARE_STATUS(lenId+1, rT2/*P*/, rT1/*OpB*/, status);
+                        if (status == 1) {
+                                goto passed_this_iteration;
+                        }
+
+                        /* St. 2.4.3. if z == 1, then output composite and stop */
+                        PKA_COMPARE_IM_STATUS(lenId+1, rT1/*P*/, 1/*OpB*/, status);
+                        if (status == 1) {
+                                *pSuccessCode = CC_FALSE;
+                                goto End;
+                        }
+
+                }/* end for */
+
+                *pSuccessCode = CC_FALSE;
+                goto End;
+
+                passed_this_iteration: ;
+
+        } /* end main for */
+End:
+
+        /* delete secure sensitive data and exit */
+        aValue = 0;
+        /* clear temp and tempP */
+        CC_PalMemSetZero(pTempBuff, 3*sizeof(uint32_t)*pSizeInWords);
+
+        return error;
+}
+
+
+/***********    PkaRsaKgX931LucasPrimeTest   function      **********************/
+/**
+ * @brief Executes the Lucas test according to the the X931 standard.
+ *
+ *  Assumptions : the max size supported is 2112 bits.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t PkaRsaKgX931LucasPrimeTest(uint32_t  lenId,          /*!< [in]  The ID of entry in RegsSizesTable, containing exact size of P in bits. */
+                                             int8_t   *pSuccessCode,    /*!< [out] Success code : 0 - the test failed , 1 the test passed. */
+                                             const int8_t  *pRegTemps,  /*!< [in]  Pointer to temp registers list - 7 registers. */
+                                             uint32_t  tempsCount)      /*!< [in]  Count of temp registers in the list. */
+{
+        CCError_t error;
+        uint32_t kSizeInBits;
+        uint32_t d_abs;
+        int8_t d_is_positive;
+        int32_t JacobiRes;
+        int32_t i;
+        uint32_t status;
+        /* virtual pointers to registers */
+        int8_t rP, rD, rK, rU, rV, rUnew, rVnew, rT;
+
+        /* check temp registers count */
+#ifdef LLF_PKI_PKA_DEBUG
+        if (tempsCount < 7)
+                return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
+#else
+        tempsCount= tempsCount;
+#endif
+
+        rP = PKA_REG_N;  /* already is initialized by P */
+        rD = pRegTemps[0];
+        rK = pRegTemps[1];
+        rU = pRegTemps[2];
+        rV = pRegTemps[3];
+        rUnew = pRegTemps[4];
+        rVnew = pRegTemps[5];
+        rT = pRegTemps[6];
+
+
+        // setting the d vector
+        /*  clear the temp buffer  */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rD/*regNum*/);
+
+        for (d_abs = 5 , d_is_positive = 1 ; ; d_abs+=2 , d_is_positive = !d_is_positive) {
+                /* set D = d_abs  */
+                PKA_WRITE_WORD_TO_REG(d_abs, 0, rD);
+
+                /* if D is negative set D = P - D */
+                if (d_is_positive == 0) {
+                        PKA_SUB( lenId+1, rD/*Res*/, rP/*P*/, rD/*OpB*/);
+                }
+
+                error = PkaRsaKgX931Jacobi( lenId, rD, rP, &JacobiRes,
+                                            rU/*temp*/, rV/*temp*/, rT/*temp*/);
+
+                if (error != CC_OK) {
+                        return error;
+                }
+
+                if (JacobiRes == -1) {
+                        break;
+                }
+
+        }/* end of loop for finding d */
+
+
+        // init vectors for the test loop
+        /* K = P + 1 */
+        PKA_ADD_IM( lenId+1, rK/*Res*/, rP/*P*/, 1/*OpB*/);
+
+        /* set the size of K in bits */
+        kSizeInBits = PkaGetRegEffectiveSizeInBits(rK/*reg*/);
+
+        /* init U and V to 1 */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rU/*regNum*/);
+        PKA_SET_BIT0(lenId+1, rU/*Res*/, rU/*regNum*/);
+        PKA_COPY(LEN_ID_MAX_BITS, rV/*dest*/, rU/*src*/);
+
+
+        // the main test loop
+        for (i = (int32_t)(kSizeInBits - 2) ; i >= 0 ; --i) {
+                /* a bit value */
+                uint32_t bit;
+
+                /* Unew = U*V mod P */
+                PKA_MOD_MUL( lenId, rUnew/*Res*/, rU/*OpA*/, rV/*OpB*/);
+
+                /* Vnew = V^2 mod P */
+                PKA_MOD_MUL( lenId, rVnew/*Res*/, rV/*OpA*/, rV/*OpB*/);
+
+                /* rT = U^2 */
+                PKA_MOD_MUL( lenId, rT/*Res*/, rU/*OpA*/, rU/*OpB*/);
+
+                /* rT= D * U^2 */
+                PKA_MOD_MUL( lenId, rT/*Res*/, rD/*OpA*/, rT/*OpB*/);
+
+                /* Vnew = (V^2 + D*U^2) */
+                PKA_ADD( lenId+1, rVnew/*Res*/, rT/*OpA*/, rVnew/*OpB*/);
+                /* modular division by 2 */
+                PkaModDivideBy2( lenId, rVnew, rP/*mod*/, rVnew);
+
+                /* swap V,Vnew and U,Unew */
+                SWAP_INT8(rVnew,rV);
+                SWAP_INT8(rUnew,rU);
+
+                /* get bit i from register K */
+                bit = PkaGetBitFromPkaReg( rK, lenId, i, rT);
+
+                if (bit != 0) {
+                        /* Unew = (U+V)/2 */
+                        PKA_ADD( lenId+1, rUnew/*Res*/, rV/*OpA*/, rU/*OpB*/);
+                        /* modular division by 2 */
+                        PkaModDivideBy2( lenId, rUnew, rP/*mod*/, rUnew);
+
+                        /* Vnew = (U*D+V)/2 */
+                        PKA_MOD_MUL( lenId, rVnew/*Res*/, rD/*OpA*/, rU/*OpB*/);
+                        PKA_ADD( lenId+1, rVnew/*Res*/, rV/*OpA*/, rVnew/*OpB*/);
+                        PkaModDivideBy2( lenId, rVnew, rP/*mod*/, rVnew);
+
+                        /* swap V,Vnew and U,Unew */
+                        SWAP_INT8(rVnew,rV);
+                        SWAP_INT8(rUnew,rU);
+
+                }
+        }
+
+        /* U = U mod P */
+        PKA_DIV( lenId+1, rT/*ResNotUsed*/, rU/*OpA*/, rP/*OpB*/);
+
+        // If U is equal to 0 return success code = 1, else 0
+        PKA_COMPARE_IM_STATUS( lenId+1, rU/*OpA*/, 0/*OpB immed*/, status);
+        if (status == 1) {
+                *pSuccessCode = 1;
+        } else {
+                *pSuccessCode = 0;
+        }
+
+
+        return error;
+
+}
+
+
+/***********    PkaRsaKgX931FindPrime1   function      **********************/
+/**
+ * @brief Finds a small auxiliary prime (104...176 bits)
+ *        for the Key Generation under the X931 standard.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t PkaRsaKgX931FindPrime1(CCRndContext_t *pRndContext, /*!< [in/out]  Pointer to the RND context buffer. */
+                                         int8_t  rP,                 /*!< [in/out]  Virtual pointer to the prime buff. */
+                                         RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in]  Pointer to primality testing parameters structure. */
+                                         const int8_t *pRegTemps,            /*!< [in]  Pointer to temp PKA registers list (5 single registers). */
+                                         uint32_t   tempsCount,          /*!< [in]  Count of temp registers in the list. */
+                                         uint32_t  *pTempBuff)           /*!< [in]  Temp buffer of size 2 max RSA buffer size. */
+{
+        CCError_t error = CC_OK;
+        uint32_t i, c, d;
+        uint32_t  *pTempRem = NULL;
+        uint32_t r;
+        /* the reminder and prime product virtual pointers */
+        int8_t rPrimeProduct;
+        /* temp register */
+        int8_t rT, rT1, rT2;
+        /* the rabin miller success code */
+        int8_t successCode;
+
+        /* check temp registers count */
+#ifdef LLF_PKI_PKA_DEBUG
+        if (tempsCount < 4)
+                return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
+#else
+        tempsCount = tempsCount;
+#endif
+
+
+        /* allocation of the temp registers */
+        rPrimeProduct = pRegTemps[0];
+        rT  = pRegTemps[1];
+        rT1 = pRegTemps[2];
+        rT2 = pRegTemps[3];
+
+
+        /*  clearing the extended temp registers  */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rPrimeProduct/*regNum*/);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rT/*regNum*/);
+
+        /* set the LSB of the prime to insure it is an odd number: rP_ptr[0] |= 1 */
+        PKA_SET_BIT0( LEN_ID_PQ_PKA_REG_BITS/*lenId*/, rP/*Res*/, rP/*OpA*/);
+
+        //  calculating the prime reminder
+        pTempRem = &pTempBuff[0];
+        for (i = 0; i < CALC_PRIME_PRODUCT ; ++i) {
+                /* load the current prime product into PKA register */
+                PKA_WRITE_WORD_TO_REG(g_PrimeProduct[i], 0, rPrimeProduct);
+
+                /* copy rP=>rT and calculate the reminder */
+                PKA_COPY(LEN_ID_MAX_BITS, rT/*dest*/, rP/*src*/);
+                PKA_DIV(LEN_ID_PQ_PKA_REG_BITS, rT1/*resNotUsed*/, rT/*OpA*/, rPrimeProduct/*OpB*/);
+
+                /* read result rT word[0] and load it into reminder word[i] */
+                PKA_READ_WORD_FROM_REG(pTempRem[i], 0, rT);
+
+        }/* end of loop for calculating the reminders */
+
+
+        // the main loop for finding a prime
+        for (d = 0; ; d += 2) {
+
+                PKA_2CLEAR(LEN_ID_MAX_BITS, rT/*regNum*/);
+
+                // finding a candidate for a prime
+                for (c = 0, i = 0; i < CALC_PRIME_PRODUCT; ++i) {
+                        if (pTempRem[i] + d < d) {        /* remark: [*] */
+                                pTempRem[i] -= g_PrimeProduct[i];
+                        }
+
+                        r = pTempRem[i] + d;
+
+                        for (; c < g_LastProductPrime[i]; ++c) {
+                                if (r % g_SmallPrime[c] == 0)
+                                        goto Next_d;
+                        }
+                }
+
+                /* calculate P = P + d.  */
+                /* load d into register rT. Note: rT already cleared, except the LS word  */
+                PKA_WRITE_WORD_TO_REG(d, 0, rT);
+                PKA_ADD( LEN_ID_PQ_PKA_REG_BITS, rP/*Res*/, rP/*OpA*/, rT/*OpB*/);
+
+
+                //  initialization of modular operations
+                /* copy P into modulus register r0 */
+                if (rP != PKA_REG_N) {
+                        PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*dst*/, rP/*src*/);
+                }
+
+                /* initialization of modular operations, the "modulus" in this case is P or Q which is 1/2 modulus size.*
+                *  that's the reason we use PQ Len ID                                 */
+                PkaCalcNpIntoPkaReg(LEN_ID_AUX_PRIME_BITS,
+                                     rsaKgPrimeTestParams->auxPrimesSizeInBits,
+                                     PKA_REG_N, PKA_REG_NP, rT, rT1);
+
+                //  executing the Miller-Rabin test
+                error = PkaRsaKgX931MillerRabinTest(pRndContext,
+                                                    LEN_ID_AUX_PRIME_BITS,
+                                                    rsaKgPrimeTestParams->auxPrimesSizeInBits,
+                                                    &successCode, /*out*/
+                                                    rsaKgPrimeTestParams->auxPrimesMilRabTestsCount, /*in*/
+                                                    rT, rT1, rT2,  /*temp registers*/
+                                                    pTempBuff+CALC_PRIME_PRODUCT);
+                if (error != CC_OK) {
+                        return error;
+                }
+
+                /* on sucess return CC_OK we have found a prime */
+                if (successCode == CC_TRUE) {
+                        return CC_OK;
+                }
+
+                /* update d and reminder to avoid overflow of d (unlikely event) */
+                for (i = 0; i < CALC_PRIME_PRODUCT; ++i) {
+                        pTempRem[i] += d; /* remark: since [*] passed, there is no need to recheck */
+                }
+
+                d = 0;
+
+                Next_d:
+                continue;
+
+        }/* end of main loop for finding a prime */
+}
+
+
+/***********    PkaRsaKgX931FindPrime2   function      **********************/
+/**
+ * @brief Finds a valid prime2 (second stage prime) for the Key Gen under the X9.31 standard .
+ *
+ *      Assumptions : supports a fixed size of 101 bits as required in the standard.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t PkaRsaKgX931FindPrime2(CCRndContext_t *pRndContext, /*!< [in/out]  Pointer to the RND context buffer. */
+                                          int8_t    rP,                /*!< [in/out] Virtual pointer to the prime P (P or Q in RSA). */
+                                          int8_t    rDelta,            /*!< [in]  Virtual pointer to the delta factor. */
+                                          int8_t    rE,            /*!< [in]  Virtual pointer to public exponent. */
+                                          uint32_t  modulusSizeInBits, /*!< [in]  Size of prime to be generated. */
+                                          RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in]  Pointer to primality testing parameters structure. */
+                                          const int8_t   *pRegTemps,   /*!< [in]  Pointer to temp PKA registers list. */
+                                          uint32_t  tempsCount,        /*!< [in]  Count of temp registers in the list (6 single registers). */
+                                          uint32_t *pTempBuff)         /*!< [in]  Temp buffer of size 2 max RSA buffer size. */
+{
+        CCError_t error = CC_OK;
+        int8_t successCode;
+        uint32_t i, c;
+        uint32_t status;
+        uint32_t bitVal;
+        uint32_t  *pTempRem = NULL;
+        uint32_t  *pTempDelta = NULL;
+        /* the reminder and prime product virtual pointers */
+        int8_t rPrimeProduct;
+        /* temp register */
+        int8_t rT, rT1, rT2;
+
+        /* check temp registers count */
+#ifdef LLF_PKI_PKA_DEBUG
+        if (tempsCount < 4)
+                return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
+#endif
+
+
+        /* allocation of the reminder and product on temp registers */
+        rPrimeProduct = pRegTemps[0];
+        rT  = pRegTemps[1];
+        rT1 = pRegTemps[2];
+        rT2 = pRegTemps[3];
+
+        // calculating the prime reminder
+        /*  clearing the temp registers (extended) */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rPrimeProduct/*regNum*/);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rT/*regNum*/);
+
+        // calculate Rdelta and the Reminder
+        /* if the prime candidate P is even add the delta */
+        PKA_READ_BIT0(LEN_ID_PQ_PKA_REG_BITS, rP/*OpA*/, bitVal);
+        if (bitVal == 0) {
+                PKA_ADD( LEN_ID_PQ_PKA_REG_BITS/*lenId*/, rP/*Res*/, rP/*OpA*/, rDelta/*OpB*/);
+        }
+
+        /* multiply delta by 2 */
+        PKA_ADD( LEN_ID_PQ_PKA_REG_BITS/*lenId*/, rDelta/*Res*/, rDelta/*OpA*/, rDelta/*OpB*/);
+
+        // loop for calculating the products
+        pTempRem = &pTempBuff[0];
+        pTempDelta = &pTempBuff[CALC_PRIME_PRODUCT];
+
+        for (i = 0; i < CALC_PRIME_PRODUCT ; ++i) {
+                /* load the current rPrimeProduct[0] = g_PrimeProduct[i] */
+                PKA_WRITE_WORD_TO_REG(g_PrimeProduct[i], 0, rPrimeProduct);
+
+                /* copy rP=>rT and calculate the reminder in reg rT */
+                PKA_COPY(LEN_ID_MAX_BITS, rT/*dest*/, rP/*src*/);
+                PKA_DIV( LEN_ID_PQ_PKA_REG_BITS, rT1/*ResNotUsed*/, rT/*OpA*/, rPrimeProduct/*OpB*/);
+
+                /* load the next word of reminder: rRem[i] = rT[0] */
+                PKA_READ_WORD_FROM_REG(pTempRem[i], 0, rT);
+
+                /* calculate the Rdelta */
+                PKA_COPY(LEN_ID_MAX_BITS, rT/*dest*/, rDelta/*src*/);
+                PKA_DIV( LEN_ID_PQ_PKA_REG_BITS, rT1/*ResNotUsed*/, rT/*OpA*/, rPrimeProduct/*OpB*/);
+
+                /* load the Rdelta with the result rRdeltam[i] = rT[0]*/
+                PKA_READ_WORD_FROM_REG(pTempDelta[i], 0, rT);
+
+        }/* end of loop for calculating the reminders */
+
+        /*  main loop for finding the prime  */
+        while (1) {
+                //WATCH_DOG_RESET(); // obsolete. Watchdog should be fed by dedicated task
+
+                /* checking if the current prime should be tested */
+                for (c=0 , i=0 ; i < CALC_PRIME_PRODUCT ; i++) {
+                        for (; c < g_LastProductPrime[i] ; c++) {
+                                if ((pTempRem[i] % g_SmallPrime[c]) == 0) {
+
+                                        goto NextPrime;
+                                }
+                        }
+                }
+
+                /*  execute rT = GCD(e,P-1)  */
+                PKA_SUB_IM( LEN_ID_PQ_PKA_REG_BITS,  rT/*Res*/, rP/*OpA*/, 1/*imm*/);   /* rP= rP-1 */
+                PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*dest*/, rE/*src*/);
+
+                /* rT = GCD */
+                PKA_MOD_INV( LEN_ID_PQ_BITS, rT1/*Res*/, rT/*OpA*/);
+
+                /* if the GCD != 1, go to the next prime */
+                PKA_COMPARE_IM_STATUS(LEN_ID_PQ_PKA_REG_BITS, rT/*OpA*/, 1/*OpB*/, status);
+                if (status != 1) {
+                        goto NextPrime;
+                }
+
+                /*  initialization of modular operations for modulus P */
+                /* reset modulus in register r0 = rP */
+                PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*dst*/, rP/*src*/);
+
+                /* initialization of modular operations */
+                PkaCalcNpIntoPkaReg(LEN_ID_PQ_BITS, modulusSizeInBits, PKA_REG_N, PKA_REG_NP, rT, rT1);
+
+
+                /*   perform primality tests   */
+                /* init lhe test flag to FALSE */
+                successCode = CC_FALSE;
+
+                /* execute the Miller-Rabin test */
+                error = PkaRsaKgX931MillerRabinTest(pRndContext,
+                                                    LEN_ID_PQ_BITS,
+                                                    modulusSizeInBits,
+                                                    &successCode,    /*out*/
+                                                    rsaKgPrimeTestParams->pqPrimesMilRabTestsCount, /*count R-M Tests */
+                                                    rT, rT1, rT2,    /*temp registers*/
+                                                    pTempBuff+2*CALC_PRIME_PRODUCT);
+                if (error != CC_OK) {
+                        goto End; //LR goto ClearAndReturn
+                }
+
+                /* if the previous test succeeded, execute the Lucas test */
+                if (successCode == CC_TRUE) {
+                        error = PkaRsaKgX931LucasPrimeTest(
+                                                          LEN_ID_PQ_BITS,
+                                                          &successCode,     /*out*/
+                                                          pRegTemps + 3, /*temp registers list*/
+                                                          tempsCount-3);
+                        if (error != CC_OK) {
+                                goto End;  //LR goto ClearAndReturn
+                        }
+                }
+
+                /* if both tests are passed, exit - we have finded a prime */
+                if (successCode == CC_TRUE) {
+                        return CC_OK;
+                }
+
+                /*    finding the next prime candidate        */
+                NextPrime:
+
+                /* updating of remainders Rem[i] */
+                for (i = 0 ; i < CALC_PRIME_PRODUCT ; i++) {
+                        pTempRem[i] += pTempDelta[i];
+                        if (pTempRem[i] < pTempDelta[i]) {
+                                pTempRem[i] -= g_PrimeProduct[i];
+                        }
+
+                }
+
+        //find new P if previous one isn't correct
+                /* the new prime candidate: P = P + Delta */
+                PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rP/*Res*/, rP/*OpA*/, rDelta/*OpB*/);
+
+        }/* end of searching for a prime loop */
+
+End:
+        // RL  Check and ddd Clearing temp buffers if need !!!!
+        return error;
+
+}
+
+/***********    RsaKgX931FindPrime   function      **********************/
+/**
+ * @brief Finds a valid prime for the Key Gen under the X931 standard .
+ *
+ *     Assumes: - the PKA is initialized on default mode according to modulusSizeInBits,
+ *              - the modulusSizeInBits is set into lenId RegsSizesTable,
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t RsaKgX931FindPrime(CCRndContext_t *pRndContext, /*!< [in/out]  Pointer to the RND context buffer. */
+                                      int8_t    rP1,          /*!< [in]  Virtual pointers to PKA registers of auxiliary primes p1. */
+                                      int8_t    rP2,          /*!< [in]  Virtual pointers to PKA registers of auxiliary primes p2. */
+                                      int8_t    rP,           /*!< [in/out]  Virtual pointer to the register containing P prime. */
+                                      uint32_t  modulusSizeInBits, /*!< [in]  Size of the prime P. */
+                                      uint32_t  rE,           /*!< [in]  Virtual pointer to public exponent. */
+                                      RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in]  Pointer to primality testing parameters structure. */
+                                      const int8_t   *pRegTemps, /*!< [in]  Pointer to temp PKA registers list (5 single registers). */
+                                      uint32_t  tempsCount,      /*!< [in]  Count of temp registers in the list. */
+                                      uint32_t *pTempBuff)       /*!< [in]  Pointer to the temp buffer of size 2 max RSA buffer size. */
+{
+        CCError_t error = CC_OK;
+        uint32_t status, flag;
+        /* virtual pointers to PKA registers */
+        int8_t    rP12, rPmodP12, rR1, rR2;
+        /* virtual pointers to temp PKA registers */
+        int8_t rT1;
+
+        /* allocation of registers */
+        rP12 = pRegTemps[0];
+        rPmodP12 = pRegTemps[1];
+        rR1 = pRegTemps[2];
+        rR2 = pRegTemps[3];
+        rT1 = pRegTemps[4];
+
+
+        /* check temp registers count */
+#ifdef LLF_PKI_PKA_DEBUG
+        if (tempsCount < 5)
+                return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
+#endif
+
+        /* find the first primes P1, P2  of size 101 bit */
+        /* p1 */
+        error = PkaRsaKgX931FindPrime1( pRndContext,
+                                        rP1,
+                                        rsaKgPrimeTestParams,
+                                        pRegTemps, tempsCount,
+                                        pTempBuff);
+        if (error != CC_OK)
+                return error;
+
+        /* p2 */
+        error = PkaRsaKgX931FindPrime1( pRndContext,
+                                        rP2,
+                                        rsaKgPrimeTestParams,
+                                        pRegTemps, tempsCount,
+                                        pTempBuff);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        /* Debug */
+#ifdef LLF_PKI_PKA_DEBUG
+        PKA_COPY(LEN_ID_MAX_BITS, rP1/*dst*/, rP1/*src*/);
+        PKA_COPY(LEN_ID_MAX_BITS, rP2/*dst*/, rP2/*src*/);
+#endif
+
+        /*  find P12 = P1*P2 , pModP12 = P mod P12 (operations size from lenId) */
+        /*     Note: modulusSizeInBits must be set into lenId entry                   */
+        /* P12 = P1 * P2 */
+        PKA_MUL_LOW(LEN_ID_PQ_PKA_REG_BITS, rP12/*Res*/, rP1/*OpA*/, rP2/*OpB*/);
+
+        /* PmodP12 = P mod P12 */
+        PKA_COPY(LEN_ID_MAX_BITS, rPmodP12/*dst*/, rP/*src*/);
+        PKA_DIV( LEN_ID_PQ_PKA_REG_BITS, rT1/*ResNotUsed*/, rPmodP12/*OpA*/, rP12/*OpB*/);
+
+
+        /* find; R1= (1/P2 mod P1)*P2 - (1/P1 mod P2)*P1; R2= ... similary   .. */
+        /* calculate R1 = (1/P2 mod P1)*P2 */
+        PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*mod reg*/, rP1/*src*/);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rT1/*dst*/);
+        PKA_COPY(LEN_ID_MAX_BITS, rT1/*dst*/, rP2/*src*/);
+
+        /* if P1 > P2 set flag = 1, else flag = 0 */
+        PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, RES_DISCARD, rP2/*OpA*/, rP1/*OpB*/);
+        PKA_GET_STATUS_CARRY(status);
+        if (status == 0) {
+                flag = 1;
+        } else {
+                /* set rT1 = P2 mod P1 = rT1 - rP1 */
+                flag = 0;
+                PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rT1/*Res*/, rT1/*OpA*/, rP1/*OpB*/);
+        }
+
+        /* R1 = (1/P2 mod P1) */
+        /* we know PKA_REG_N - rP1 is prime, so we can use ModInv with the odd number*/
+        /* we do not check GCD, since PKA_REG_N is prime and rT1 < PKA_REG_N. therfore GCD must be 1 */
+        PKA_MOD_INV(LEN_ID_PQ_BITS, rR1/*Res*/, rT1/*OpB*/);
+
+        PKA_MUL_LOW( LEN_ID_PQ_PKA_REG_BITS, rR1/*Res*/, rR1/*OpA*/, rP2/*OpB*/);
+
+        /* calculate R2 = (1/P1 mod P2)*P1 */
+        PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*mod reg*/, rP2/*src*/);
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rT1/*dst*/);
+        PKA_COPY(LEN_ID_MAX_BITS, rT1/*dst*/, rP1/*src*/);
+
+        /* if flag == 1, i.e. P2 >= P1, then set rT1 = P1 mod P2 = P1 - P2 */
+        if (flag == 1) {
+                PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rT1/*Res*/, rT1/*OpA*/, rP2/*OpB*/);
+        }
+
+        /* we know PKA_REG_N = rP2 is prime, so we can use ModInv with the odd number*/
+        PKA_MOD_INV(LEN_ID_PQ_BITS, rR2/*Res*/, rT1/*OpB*/);
+
+        PKA_MUL_LOW( LEN_ID_PQ_PKA_REG_BITS, rR2/*Res*/, rR2/*OpA*/, rP1/*OpB*/);
+
+
+        /* R=R1-R2; if(R <0) R= R+P12; */
+        /* R1 and R2 are max 202 bits each, so LEN_ID_PQ_BITS should be enought to hold negative number*/
+        PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rR2/*OpB*/);
+        PKA_GET_STATUS_CARRY(status);
+        if (status == 0) {
+                PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rP12/*OpB*/);
+        }
+
+        /* R=R-PmodP12; if(R<0) R=R+P12; */
+        PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rPmodP12/*OpB*/);
+        PKA_GET_STATUS_CARRY(status);
+        if (status == 0) {
+                PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rP12/*OpB*/);
+        }
+
+        /* add P = P + R */
+        PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rP/*res*/, rP/*OpA*/, rR1/*OpB*/);
+
+    //now in rP is a number with new conditions
+
+        /* find the prime P */
+        error = PkaRsaKgX931FindPrime2( pRndContext, rP, rP12/*rDelta*/, rE,
+                                        modulusSizeInBits,
+                                        rsaKgPrimeTestParams,
+                                        pRegTemps + 1, tempsCount-1,
+                                        pTempBuff);
+
+        return error;
+
+}
+
+
+/***********    RsaKgQuickPrimeTest   function      **********************/
+/**
+ * @brief Checks primality of big number relating to set of small prime numbers.
+ *
+ *   Notes:  - 3 PKA registers used: rP, rModRes, rSmallNum,
+ *           - the PKA must be initialized according tp P size,
+ *           - lenId+1 entry containing the extended register size.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static int32_t RsaKgQuickPrimeTest(uint8_t    lenId,    /*!< [in]  The SizesTable entry, containing the exact P size in bits. */
+                                   int8_t     rP,       /*!< [in]  The virtual pointer to big number P register to be checked. */
+                                   int8_t     rModRes,     /*!< [in]  Virtual pointers to temp registers. */
+                                   int8_t     rSmallPrime, /*!< [in]  Virtual pointers to temp registers. */
+                                   int8_t     rT,          /*!< [in]  Virtual pointers to temp registers. */
+                                   uint32_t   divCount)    /*!< [in]  . */
+{
+        uint32_t i;
+        uint32_t status;
+
+        /* set pointer smallPrime_ptr to PKA register low word */
+        /* clear rSmallPrime register (with extension) */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rSmallPrime/*OpA*/);
+
+        /* Check primality by dividing P by small primes */
+        for (i = 0; i < divCount; i++) {
+                /* copy rP into rModReg for dividing */
+                PKA_COPY(LEN_ID_MAX_BITS, rModRes/*dst*/, rP/*src*/);
+
+                /* set the next small prime into PKA register */
+                PKA_WRITE_WORD_TO_REG(g_SmallPrime[i], 0, rSmallPrime);
+
+                /* calculate remainder: rModReg = rP % smallPrime */
+                PKA_DIV( lenId+1, rT/*ResNotUsed*/, rModRes/*OpA*/, rSmallPrime/*OpB*/);
+
+                /* check is the remainder equaled to 0 by add operation */
+                PKA_ADD_IM( lenId+1, RES_DISCARD/*discard Res*/, rModRes/*OpA*/, 0/*OpB*/);
+                PKA_GET_STATUS_ALU_OUT_ZERO(status);
+                if (status) {
+                        return CC_FALSE;
+                }
+        }
+
+        return CC_TRUE;
+}
+
+
+/***********    PkaRsaKgFindPrime   function      **********************/
+/**
+ * @brief Finds a valid prime for the Key Gen.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t PkaRsaKgFindPrime(CCRndContext_t *pRndContext,  /*!< [in/out]  Pointer to the RND context buffer. */
+                                     int8_t    rP,            /*!< [in/out]  Virtual pointer to the prime P register. */
+                                     uint32_t  modulusSizeInBits, /*!< [in]  Prime size in bits. */
+                                     int8_t    rE,            /*!< [in]  Virtual pointer to the public exponent register. */
+                                     RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in]  Pointer to primality testing parameters structure. */
+                                     const int8_t   *pRegTemps,  /*!< [in]  Pointer to temp PKA registers list. */
+                                     uint32_t  tempsCount,       /*!< [in]  Count of temp registers in the list (9). */
+                                     uint32_t *pTempBuff)        /*!< [in]  Temp buffer of size 2 max RSA buffer size. */
+{
+        CCError_t error = CC_OK;
+#if !defined RSA_KG_NO_RND
+        CCRndState_t *rndState_ptr;
+#endif
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+        /* virtual pointers to PKA data registers */
+        int8_t rP1, rP2;
+
+        /* temp buffer for auxiliary random number / big end
+           1E05B8F18D807DB7A47EF53567 nearest random is: 1E 05 B8 F1 8D 80 7D
+           B7 A4 7E F5 35 99*/
+        uint32_t rBuff[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS] = {0};
+        uint32_t auxPrimeSizeInBytes, auxPrimeSizeInWords;
+        uint32_t mask, msBit;
+
+        if (pRndContext == NULL) {
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+        }
+
+#if !defined RSA_KG_NO_RND
+        rndState_ptr = (CCRndState_t *)(pRndContext->rndState);
+#endif
+        RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
+
+        if (RndGenerateVectFunc == NULL) {
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+        }
+
+#ifdef LLF_PKI_PKA_DEBUG
+        if (tempsCount < 9)
+                return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
+#endif
+
+        /* allocate virtual pointers on temp registers */
+        rP1 = pRegTemps[0];
+        rP2 = pRegTemps[1];
+
+        /* calculate size of aux. primes in bytes and words */
+        auxPrimeSizeInBytes = CALC_FULL_BYTES(rsaKgPrimeTestParams->auxPrimesSizeInBits);
+        auxPrimeSizeInWords = CALC_FULL_32BIT_WORDS(rsaKgPrimeTestParams->auxPrimesSizeInBits);
+
+#if defined RSA_KG_NO_RND
+#ifdef LLF_PKI_PKA_DEBUG
+        if (PQindex == 0) {
+                CC_PalMemCopy( rBuff, rBuff1, auxPrimeSizeInBytes); /*for P*/
+        } else {
+                CC_PalMemCopy( rBuff, rBuff3, auxPrimeSizeInBytes); /*for Q*/
+        }
+
+
+#ifdef BIG__ENDIAN
+        CC_COMMON_INVERSE_UINT32_IN_ARRAY(rBuff, auxPrimeSizeInWords);
+#endif
+#endif
+
+#else
+        /* get a random auxiliary number P1      */
+        error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char*)rBuff, (size_t)auxPrimeSizeInBytes );
+        if (error != CC_OK) {
+                return error;
+        }
+#endif
+
+      /* calculate mask for aux.prime candidate */
+        mask = (~0UL >> (32 - (rsaKgPrimeTestParams->auxPrimesSizeInBits & 0x1F)));
+        msBit = 1UL << ((rsaKgPrimeTestParams->auxPrimesSizeInBits & 0x1F)-1);
+
+    /* calculate mask and set MS bit of aux.prime candidate */
+        rBuff[auxPrimeSizeInWords-1] &= mask;
+        rBuff[auxPrimeSizeInWords-1] |= msBit;
+        /* set LSBit = 1 to ensure the odd number */
+        rBuff[0] |= 1UL;
+
+    #ifdef FIPS_CERTIFICATION
+    primeInt->bitlen1 = rsaKgPrimeTestParams->auxPrimesSizeInBits;
+    CC_CommonReverseMemcpy(primeInt->xPrime1, (uint8_t*)rBuff, auxPrimeSizeInBytes);
+    #endif
+
+#ifdef LLF_PKI_PKA_DEBUG
+#if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
+        /* set pointers for extern P,Q and aux.primes buffers*/
+        if (PQindex == 0) {
+                P1R_ptr = P1pR; P2R_ptr = P2pR;
+                P1Pr_ptr = P1pPr; P2Pr_ptr = P2pPr;
+                PQ_ptr = rBuffP;
+        } else {
+                P1R_ptr = P1qR; P2R_ptr = P2qR;
+                P1Pr_ptr = P1qPr; P2Pr_ptr = P2qPr;
+                PQ_ptr = rBuffQ;
+        }
+
+        CC_PalMemCopy((uint8_t*)P1R_ptr, (uint8_t*)rBuff, auxPrimeSizeInBytes); /*for P*/ //xp1
+
+#endif
+#endif
+
+        /* copy random number into PKA register rP1 */
+        PkaCopyDataIntoPkaReg( rP1/*dstReg*/, LEN_ID_MAX_BITS, rBuff/*src_ptr*/, auxPrimeSizeInWords);
+
+#ifdef RSA_KG_NO_RND
+#ifdef LLF_PKI_PKA_DEBUG
+        CC_PalMemSetZero(rBuff, sizeof(rBuff));
+        if (PQindex == 0) {
+                CC_PalMemCopy( rBuff, rBuff2, auxPrimeSizeInBytes); /*for P*/
+        } else {
+                CC_PalMemCopy( rBuff, rBuff4, auxPrimeSizeInBytes); /*for Q*/
+        }
+
+#ifdef BIG__ENDIAN
+        CC_COMMON_INVERSE_UINT32_IN_ARRAY( rBuff, auxPrimeSizeInWords );
+#endif
+#endif
+
+#else
+
+        /* get a random auxiliary number P2     */
+        CC_PalMemSetZero(rBuff, sizeof(rBuff));
+        error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char *)rBuff, (size_t)auxPrimeSizeInBytes );
+        if (error != CC_OK) {
+                return error;
+        }
+
+#endif
+    /* set MS bit of P2*/
+        rBuff[auxPrimeSizeInWords-1] &= mask;
+        rBuff[auxPrimeSizeInWords-1] |= msBit;
+        /* set LSBit = 1 to ensure the odd number */
+        rBuff[0] |= 1UL;
+
+#ifdef FIPS_CERTIFICATION
+    primeInt->bitlen2 = rsaKgPrimeTestParams->auxPrimesSizeInBits;
+    CC_CommonReverseMemcpy(primeInt->xPrime2, (uint8_t*)rBuff, auxPrimeSizeInBytes);
+#endif
+        /*  Debug  */
+#ifdef LLF_PKI_PKA_DEBUG
+#if defined RSA_KG_FIND_BAD_RND
+        CC_PalMemCopy( (uint8_t*)P2R_ptr, (uint8_t*)rBuff, auxPrimeSizeInBytes); /*for P*/ //xp2
+#endif
+#endif
+
+        /* copy random number P2 into PKA register rP2 */
+        PkaCopyDataIntoPkaReg( rP2/*dstReg*/, LEN_ID_MAX_BITS, rBuff/*src_ptr*/, auxPrimeSizeInWords);
+
+    //at the end of this function rP includes P value
+        /* find the primes P1,P2, P */
+        error = RsaKgX931FindPrime(pRndContext,
+                                      rP1, rP2, /*aux.primes*/
+                                      rP, /*prime*/
+                                      modulusSizeInBits,
+                                      rE, /*exp*/
+                                      rsaKgPrimeTestParams,
+                                      pRegTemps + 2, tempsCount-2,
+                                      pTempBuff);
+
+        /* Debug */
+#ifdef LLF_PKI_PKA_DEBUG
+#if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
+        /* save found results: rP1,rP2,rP for P and Q accordingly */
+        PkaCopyDataFromPkaReg( P1Pr_ptr/*dst_ptr*/, auxPrimeSizeInWords, rP1/*srcReg*/);
+
+        PkaCopyDataFromPkaReg( P2Pr_ptr/*dst_ptr*/, auxPrimeSizeInWords, rP2/*srcReg*/);
+
+        PkaCopyDataFromPkaReg( PQ_ptr/*dst_ptr*/, modulusSizeInBits/32, rP/*srcReg*/);
+#endif
+#endif
+
+        return error;
+
+}
+
+
+/***********    RsaKgPrimeTest   function      **********************/
+/**
+ * @brief Performs assigned count of Rabin-Miller tests and one Lucas-Lehmer
+ *        test according to testing mode:
+ *              - for RSA according to ANSI X9.31 standard.
+ *              - for DH  according to ANSI X9.42 standard.
+ *
+ *         NOTE:  For using in RSA module  size of each temp buffer must be of minimum size
+ *                of prime number P in words.
+ *                For using in ANSI X9.42 standard (DH,DSA algorithms) size of each temp buffer
+ *            must be minimum of two size of prime number P in words.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t RsaKgPrimeTest(CCRndContext_t *pRndContext, /*!< [in/out]  Pointer to the RND context buffer. */
+                                  uint32_t *pPrimeP,         /*!< [in]  Pointer to the prime buff. */
+                                  int32_t   sizeWords,       /*!< [in]  Prime size in words. */
+                                  int32_t   rabinTestsCount, /*!< [in]  Count of Rabin-Miller tests repetition. */
+                                  int8_t   *pIsPrime,        /*!< [in]  The flag indicates primality: not prime - CC_FALSE, otherwise - CC_TRUE. */
+                                  CCRsaDhPrimeTestMode_t primeTestMode, /*!< [in]  Primality testing mode (RSA or DH - defines how are performed some
+                                            operations on temp buffers. */
+                                  uint32_t *pTempBuff) /*!< [in]  Temp buffer of size 3*ModSizeWords. */
+{
+        CCError_t error = CC_OK;
+        uint32_t   modulusSizeInBits;
+        uint32_t   divCount;
+        uint32_t  pkaReqRegs = 11;
+
+        /* virtual pointers to PKA regs*/
+        /* set registers pointers, note: r0=PKA_REG_N, r1=PKA_REG_NP by default reserved for N and NP */
+        uint8_t rT2 = regTemps[2];
+        uint8_t rT3 = regTemps[3];
+        uint8_t rT4 = regTemps[4]; /* temp registers */
+
+        /* exact size of P */
+        modulusSizeInBits = CC_BITS_IN_32BIT_WORD * sizeWords;
+
+        /* initialize the PKA engine on default mode with size of registers       */
+        /* according to operation size = max(Asize,Bsize)                         */
+        error = PkiCalcNp(pTempBuff, pPrimeP, modulusSizeInBits);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        error = PkaInitAndMutexLock(modulusSizeInBits, &pkaReqRegs);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        /* set modulus into PKA register r0 */
+        PkaCopyDataIntoPkaReg( PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*lenId*/, pPrimeP/*src_ptr*/, sizeWords);
+
+        /* copy Np to PKA register #1*/
+        PkaCopyDataIntoPkaReg( PKA_REG_NP/*dstReg*/, LEN_ID_MAX_BITS/*lenId*/, pTempBuff/*src_ptr*/,
+                                CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+        /*   execute primality tests       */
+        /* count of small primes (each one is DxUint16) to check:
+            - for DH algorithm use predefined value,
+              else use maximal value  */
+
+        if (primeTestMode == CC_DH_PRIME_TEST_MODE) {
+                divCount = RSA_QUICK_PRIME_TEST_DIVISIONS_COUNT;
+        } else {
+                divCount = sizeof(g_SmallPrime) / sizeof(uint16_t);
+        }
+
+        /* test by small prime numbers */
+        *pIsPrime = (int8_t)RsaKgQuickPrimeTest(
+                                                     LEN_ID_N_BITS/*lenId*/,
+                                                     PKA_REG_N /*prime P*/,
+                                                     rT2, rT3, rT4/*temp regs*/,
+                                                     divCount);
+
+        /* the Miller-Rabin test */
+        if (*pIsPrime == CC_TRUE) {
+                error = PkaRsaKgX931MillerRabinTest(pRndContext,
+                                                    LEN_ID_N_BITS /*lenId*/,
+                                                    modulusSizeInBits,
+                                                    pIsPrime, /*out*/
+                                                    rabinTestsCount,
+                                                    rT2, rT3, rT4/*temp regs*/,
+                                                    pTempBuff);
+                if (error != CC_OK) {
+                        goto End;
+                }
+        }
+
+        /* the Lucas test  */
+        if (*pIsPrime == CC_TRUE) {
+                error = PkaRsaKgX931LucasPrimeTest(
+                                                  LEN_ID_N_BITS     /*lenId*/,
+                                                  pIsPrime, /*out*/
+                                                  regTemps+2,
+                                                  7 /*tempsCount*/);
+        }
+        End:
+        PkaFinishAndMutexUnlock(pkaReqRegs);
+
+        return error;
+
+}
+
+
+/***********    RsaCalculateNandD   function      **********************/
+/**
+ * @brief Calculates RSA modulus and private key in NonCRT mode.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t RsaCalculateNandD(CCRsaPubKey_t *pCcPubKey, /*!< [in] pointer to the public key structure */
+                        CCRsaPrivKey_t *pCcPrivKey,   /*!< [in] pointer to the private key structure */
+                        CCRsaKgData_t  *pKeyGenData,  /*!< [in] pointer to a structure required for the KeyGen operation, holding P and Q */
+                        uint32_t        primeSizeInBits) /*!< [in] Size of the prime factors in bits. */
+{
+    uint32_t  primeSizeInWords, i;
+    uint32_t  pkaRegsCount = 8;
+    CCError_t error=CC_OK;
+    /* define virtual pointers to PKA registers */
+    uint32_t r0   = PKA_REG_N; /*mod*/
+    uint32_t rLcm = 1;
+    uint32_t rP   = 2;
+    uint32_t rQ   = 3;
+    uint32_t rD   = 4;
+    uint32_t rT   = 5;
+    uint32_t *pPrivExp = pCcPrivKey->PriveKeyDb.NonCrt.d;
+
+
+    /* setting the primes P,Q length in bytes */
+    primeSizeInWords = CALC_FULL_32BIT_WORDS(primeSizeInBits);
+    /*Mutex lock and PKA init*/
+    error = PkaInitAndMutexLock(2*primeSizeInBits, &pkaRegsCount );
+    if (error != CC_SUCCESS) {
+        return error;
+    }
+    /* RL  clean the n-buffer */
+    CC_PalMemSetZero( pCcPubKey->n, CC_32BIT_WORD_SIZE*CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS );
+
+    PkaSetLenIds(primeSizeInBits, LEN_ID_PQ_BITS);
+    PkaSetLenIds(GET_FULL_OP_SIZE_BITS(primeSizeInBits), LEN_ID_PQ_PKA_REG_BITS);
+
+    /* clear pka memory for new using */
+    PkaClearBlockOfRegs(r0/*firstReg*/, pkaRegsCount, LEN_ID_MAX_BITS);
+
+
+    /*  copy P, Q into PKA registers. Note: now size of registers is full.  */
+    PkaCopyDataIntoPkaReg(rP/*dstReg*/, LEN_ID_MAX_BITS, pKeyGenData->KGData.p/*src_ptr*/,
+                          primeSizeInWords);
+
+    PkaCopyDataIntoPkaReg(rQ/*dstReg*/, LEN_ID_MAX_BITS, pKeyGenData->KGData.q/*src_ptr*/,
+                          primeSizeInWords);
+
+    /*******************************************************************************************/
+    /*                     CALCULATIONS WITH LONG REGISTERS                                    */
+    /*  Init the PKA again on default mode according to N operation size.                      */
+    /*  Note: All PKA memory shall be cleaned, nSizeInBits=> entry 0, nSizeInBits+CC_PKA_WORD_SIZE_IN_BITS=> entry 1 */
+    /*******************************************************************************************/
+    /*     N= r0= P*Q. lenId = 0 for full reg size   */
+    PKA_MUL_LOW(LEN_ID_N_BITS, r0, rP/*OpA*/, rQ/*OpB*/);   // use LEN_ID_N_BITS, since its size is 2*primeSizeInBits
+
+    /* output the modulus N */
+    PkaCopyDataFromPkaReg(pCcPubKey->n,  2*primeSizeInWords, r0/*srcReg*/);
+    CC_PalMemCopy(pCcPrivKey->n, pCcPubKey->n, pCcPubKey->nSizeInBits / CC_BITS_IN_BYTE);
+
+        if (pCcPrivKey->OperationMode == CC_RSA_NoCrt) {
+                bool isTrue = false;
+                uint32_t  stat;
+                uint32_t rGcd;
+                uint32_t bit0P, bit0Q;
+
+
+        /*    calculate D = E^-1 mod LCM(P-1)*(Q-1)   */
+        PKA_FLIP_BIT0(LEN_ID_N_BITS, rP/*Res*/, rP/*OpA*/);
+        PKA_FLIP_BIT0(LEN_ID_N_BITS, rQ/*Res*/, rQ/*OpA*/);
+
+        /* remove common factors 2 from P-1, Q-1 to find odd */
+        i = 0;
+        do {
+            PKA_SHR_FILL0(LEN_ID_N_BITS, rP, rP, 0/*shift-1*/);
+            PKA_SHR_FILL0(LEN_ID_N_BITS, rQ, rQ, 0/*shift-1*/);
+            PKA_READ_BIT0(LEN_ID_N_BITS, rP, bit0P);
+            PKA_READ_BIT0(LEN_ID_N_BITS, rQ, bit0Q);
+            i++;
+        } while (bit0P == 0 && bit0Q == 0);
+
+
+        /* D = (P-1) * (Q-1) / 2^i (removed only common divider 2^i) */
+        PKA_2CLEAR(LEN_ID_MAX_BITS, rD); // ? RL
+        PKA_MUL_LOW(LEN_ID_N_BITS, rD/*Res*/, rP/*OpA*/, rQ/*OpB*/);
+        PKA_SHL_FILL0(LEN_ID_N_BITS, rD, rD, i-1);
+
+        /* chose odd number as modulus for ModInv operation */
+        if (bit0P == 1) {
+            PKA_COPY(LEN_ID_N_BITS, r0/*dst*/, rP);
+            rGcd = rQ;
+        } else {
+            PKA_COPY(LEN_ID_N_BITS, r0/*dst*/, rQ);
+            rGcd = rP;
+        }
+
+        /* calculate GCD(rP,rQ) */
+        PKA_MOD_INV(LEN_ID_N_BITS, rT/*temp*/, rGcd);
+        /* LCM = ((P-1)*(Q-1) / GCD) = rD/rGcd */
+        PKA_DIV(LEN_ID_N_BITS, rLcm/*res: LCM*/, rD, rGcd);
+
+
+        // Because LCM may be even, but HW ModInw operation works only with odd modulus,
+        // we use reverse calculation as follows: D =  1/E mod LCM = LCM - ((1/LCM mod E)*LCM - 1) / E
+
+        /* copy public exp E into r0 register */
+        PkaCopyDataIntoPkaReg(r0/*dstReg*/, LEN_ID_MAX_BITS, pCcPubKey->e/*src_ptr*/,
+                              CALC_FULL_32BIT_WORDS(pCcPubKey->eSizeInBits));
+
+        /* calc rT = 1/LCM mod E */
+        PKA_COPY(LEN_ID_N_BITS, rP/*dst*/, rLcm/*LCM*/); /*rP used as temp*/
+        PKA_DIV(LEN_ID_N_BITS, rQ/*Res not used*/, rP/*OpA=LCM*/, r0/*OpB=E*/); /*rP = LCM mod E*/
+
+        PKA_MOD_INV(LEN_ID_N_BITS, rT/*Res*/, rP/*OpB*/); /* rT = 1/LCM mod E (E - odd, gcd(LCM,E)=1) */
+        /* RL additional check need if E is not prime */
+        PKA_COMPARE_IM_STATUS(LEN_ID_N_BITS, rP, 1/*im*/, stat);
+        if (stat != 1) {
+            error = PKA_INTERNAL_ERROR;
+            goto End;
+        }
+
+        /* rK = (rT*LCM - 1) / r0=E  */
+        PKA_MUL_LOW(LEN_ID_N_PKA_REG_BITS, rT/*Res*/, rT/*OpA*/, rLcm/*OpB*/); /* Note: size of result < register size, because E is small */
+        PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, rT/*Res*/, rT/*OpA*/, 1/*OpB*/);
+        PKA_DIV(LEN_ID_N_PKA_REG_BITS, rD/*Res*/, rT/*OpA*/, r0/*OpB*/); /*rT = rT / e*/
+        PKA_SUB(LEN_ID_N_PKA_REG_BITS, rD/*Res*/, rLcm/*OpA*/, rD/*OpB*/);
+
+        /*    output the result value D */
+        PkaCopyDataFromPkaReg(pPrivExp, 2*primeSizeInWords, rD/*srcReg*/);
+
+        /* check that d > 2^(nlen/2) [FIPS 186-4, B.3.1] - very rare  *
+         *  case.                                                      */
+        for (i = 2*primeSizeInWords - 1; i >= primeSizeInWords; i--) {
+            isTrue = isTrue || (pPrivExp[i] != 0);
+        }
+        if (!isTrue) {
+            CC_PalMemSetZero(pPrivExp, 2*primeSizeInWords);
+            error = CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW;
+        }
+
+        /* set the length of d in bits */
+        pCcPrivKey->PriveKeyDb.NonCrt.dSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.NonCrt.d,
+                                                    (uint16_t)(CALC_FULL_32BIT_WORDS(pCcPubKey->nSizeInBits)));
+        }
+
+    End:
+
+    PkaFinishAndMutexUnlock( pkaRegsCount );
+
+    return error;
+}
+
+
+/***********    RsaKgFindPrime   function      **********************/
+/**
+ * @brief The RsaKgFindPrime generates a prime for RSA keys.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t RsaKgFindPrime(
+                    CCRndContext_t *pRndContext, /*!< [in/out]  Pointer to the RND context buffer. */
+                    uint32_t *pPubExp,     /*!< [in]  Pointer to the public exponent. */
+                    uint32_t  eSizeInBits, /*!< [in/out]  Size of public exponent in bits. */
+                    uint32_t  nSizeInBits, /*!< [in/out]  Required size of the key in bits. */
+                    uint32_t *pSuccess,    /*!< [out]  Pointer to the flag of success generation of P,Q.*/
+                    uint32_t *pPrime,      /*!< [out]  Pointer to the first factor - P. */
+                    uint32_t *pTempBuff)   /*!< [out]  Temp buffer for internal use. */
+{
+    CCError_t error=CC_OK;
+    uint32_t primeSizeInBits, primeSizeInWords;
+    RsaKgParams_t rsaKgPrimeTestParams;
+    /* virtual pointers to PKA registers of single size */
+    int8_t   rE, rP;
+    /* virtual pointers to single temp PKA registers */
+    uint32_t  status, maxCountRegs = 20;
+
+    // setting the primes P,Q length ; Note: the size of the modulus n is even
+    primeSizeInBits = nSizeInBits / 2;
+    primeSizeInWords = CALC_FULL_32BIT_WORDS(primeSizeInBits);
+
+    /*Initialize PKA and mutex lock*/
+    error = PkaInitAndMutexLock(primeSizeInBits,  &maxCountRegs);
+    if (error != CC_SUCCESS) {
+        return error;
+    }
+
+    *pSuccess = CC_FALSE;
+
+    // set virtual registers pointers
+    rE =regTemps[2]; /*2*/
+    rP =regTemps[3]; /*3*/
+
+    /* Set size if P, Q and auxiliary primes p1,p2,q1,q2 according  *
+     *   to keysize. The following settings meet to  FIPS 186-4:    *
+     *   5.1, C.3: Tab.C3.                                          */
+    if (nSizeInBits <= CC_RSA_FIPS_KEY_SIZE_1024_BITS) {
+        rsaKgPrimeTestParams.auxPrimesSizeInBits = PKA_RSA_KEY_1024_AUX_PRIME_SIZE_BITS;
+        rsaKgPrimeTestParams.auxPrimesMilRabTestsCount = PKA_RSA_KEY_1024_AUX_PRIME_RM_TST_COUNT /*38*/;
+        rsaKgPrimeTestParams.pqPrimesMilRabTestsCount  = PKA_RSA_KEY_1024_PQ_PRIME_RM_TST_COUNT  /* 7*/;
+    } else if (nSizeInBits <= CC_RSA_FIPS_KEY_SIZE_2048_BITS) {
+        rsaKgPrimeTestParams.auxPrimesSizeInBits = PKA_RSA_KEY_2048_AUX_PRIME_SIZE_BITS;
+        rsaKgPrimeTestParams.auxPrimesMilRabTestsCount = PKA_RSA_KEY_2048_AUX_PRIME_RM_TST_COUNT /*32*/;
+        rsaKgPrimeTestParams.pqPrimesMilRabTestsCount  = PKA_RSA_KEY_2048_PQ_PRIME_RM_TST_COUNT  /* 4*/;
+    } else {/* if key size > 2048 */
+        rsaKgPrimeTestParams.auxPrimesSizeInBits = PKA_RSA_KEY_3072_AUX_PRIME_SIZE_BITS;
+        rsaKgPrimeTestParams.auxPrimesMilRabTestsCount = PKA_RSA_KEY_3072_AUX_PRIME_RM_TST_COUNT /*27*/;
+        rsaKgPrimeTestParams.pqPrimesMilRabTestsCount  = PKA_RSA_KEY_3072_PQ_PRIME_RM_TST_COUNT  /* 3*/;
+    }
+
+    /**********************************************************************************/
+    /*                     CALCULATIONS WITH SHORT REGISTERS                          */
+    /* init PKA on default mode according to P,Q operation size for creating P and Q. */
+    /*  Note: All PKA memory shall be cleaned, insert nSizeInBits/2 => entry 0,       */
+    /*        nSizeInBits/2+CC_PKA_WORD_SIZE_IN_BITS => entry 1                     */
+    /**********************************************************************************/
+
+    /* set additional sizes into RegsSizesTable: */
+    PkaSetLenIds(nSizeInBits/2, LEN_ID_PQ_BITS);
+    PkaSetLenIds(GET_FULL_OP_SIZE_BITS(nSizeInBits/2), LEN_ID_PQ_PKA_REG_BITS);
+    PkaSetLenIds(rsaKgPrimeTestParams.auxPrimesSizeInBits, LEN_ID_AUX_PRIME_BITS);
+
+    /* inforcing the prime candidates P,Q so the size of they is keySize/2 */
+    pPrime[primeSizeInWords - 1] |= 0x80000000;
+    pPrime[primeSizeInWords] = 0;
+    pPrime[0] |= 0x01;
+#ifdef FIPS_CERTIFICATION
+    CC_CommonReverseMemcpy(primeInt->xPrime, (uint8_t *)pPrime, primeSizeInBits/CC_BITS_IN_BYTE);
+#endif
+
+    /* copy P,E buffers into PKA registers */
+    PkaCopyDataIntoPkaReg(rP/*dstReg*/, LEN_ID_MAX_BITS, pPrime/*src_ptr*/, primeSizeInWords);
+    PkaCopyDataIntoPkaReg(rE/*dstReg*/, LEN_ID_MAX_BITS, pPubExp/*src_ptr*/, CALC_FULL_32BIT_WORDS(eSizeInBits));
+
+    /* find the prime vector  */
+    error = PkaRsaKgFindPrime( pRndContext, rP, primeSizeInBits,
+                               rE,
+                               &rsaKgPrimeTestParams,
+                               regTemps+5, maxCountRegs-5/*tempsCount*/,
+                               pTempBuff);
+
+
+    if (error != CC_OK) {
+            goto End;
+    }
+
+    /* temp for debug */
+#if defined LLF_PKI_PKA_DEBUG && defined DEBUG
+#if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
+    PQindex = 1;
+#endif
+#endif
+
+    PkaCopyDataFromPkaReg( pPrime/*dst_ptr*/, primeSizeInWords, rP/*srcReg*/ );
+
+    /* Because now we use only a prime e it's enough to check that (p-1) / e has a residue.
+    *  Divide:  rE = (public exponent) mod (generated prime)
+    *  NOTE: if e generated as random odd number - it is required to test that GCD(e,p-1)=1, instead of divison*/
+    PKA_SUB_IM(LEN_ID_MAX_BITS, rP, rP, 1);
+    PKA_DIV(LEN_ID_MAX_BITS, RES_DISCARD/*Res not used*/, rP/*OpA*/, rE/*OpB*/);
+    PKA_COMPARE_IM_STATUS(LEN_ID_MAX_BITS, rP/*(p-1) mod e*/, 0, status)
+
+    if (status == 0){ //if rP==0 than status =1
+        *pSuccess = CC_TRUE;
+    }
+
+End:
+    /* Finish PKA operations (waiting PKI done and close PKA clocks) */
+    PkaFinishAndMutexUnlock(maxCountRegs);
+
+    return error;
+
+
+}
+
+
+
+/***********    RsaCalculateCrtParams   function      **********************/
+/**
+ * @brief Calculates a private key on CRT mode
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+ CCError_t RsaCalculateCrtParams(uint32_t *pPubExp,      /*!< [in]  Pointer to the public exponent. */
+                                         uint32_t eSizeInBits,  /*!< [in]  Public exponent size in bits. */
+                                         uint32_t nSizeInBits,  /*!< [in]  Size of the key modulus in bits. */
+                                         uint32_t *pPrimeP,     /*!< [out]  First factor pointer - p. */
+                                         uint32_t *pPrimeQ,     /*!< [out]  Second factor pointer - Q. */
+                                         uint32_t *pPrivExp1dp, /*!< [out]  Private exponent for first factor - dP. */
+                                         uint32_t *pPrivExp2dq, /*!< [out]  Private exponent for second factor - dQ. */
+                                         uint32_t *pQInv)       /*!< [out]  The modular inverse of q relatively to modulus p - qInv. */
+{
+     CCError_t error=CC_OK;
+     uint32_t primeSizeInWords;
+     /* virtual pointers to PKA registers of single size */
+     int8_t  r0, rP, rdP, rQ, rdQ, rQinv, rE;
+     /* virtual pointers to single temp PKA registers */
+     int8_t rT1, rT2, rT3, rT4, rT5;
+     uint32_t maxCountRegs = 15;
+
+     /* setting the primes P,Q length ; Note: the size of the modulus n is even */
+     primeSizeInWords = CALC_FULL_32BIT_WORDS(nSizeInBits/2);
+
+     error = PkaInitAndMutexLock(primeSizeInWords*CC_BITS_IN_32BIT_WORD, &maxCountRegs );
+     if (error != CC_SUCCESS) {
+         return error;
+     }
+
+     // set virtual registers pointers
+     r0 = regTemps[0]; /* PKA_REG_N */
+     rE = regTemps[2]; /*2*/
+     rP = regTemps[3]; /*3*/
+     rQ = regTemps[4]; /*4*/
+     rdP = regTemps[5]; /*5*/
+     rdQ = regTemps[6]; /*6*/
+     rQinv = regTemps[7]; /*7*/
+     rT1 = regTemps[8]; /*8*/
+     rT2 = regTemps[9]; /*9*/
+     rT3 = regTemps[10]; /*10*/
+     rT4 = regTemps[11]; /*11*/
+     rT5 = regTemps[12]; /*12*/
+
+     // copy data into PKA registers
+     PkaCopyDataIntoPkaReg(rE/*dstReg*/, LEN_ID_MAX_BITS, pPubExp/*src_ptr*/, CALC_FULL_32BIT_WORDS(eSizeInBits));
+     PkaCopyDataIntoPkaReg(rP/*dstReg*/, LEN_ID_MAX_BITS, pPrimeP/*src_ptr*/, primeSizeInWords);
+     PkaCopyDataIntoPkaReg(rQ/*dstReg*/, LEN_ID_MAX_BITS, pPrimeQ/*src_ptr*/, primeSizeInWords);
+
+     // dQ = E^-1 mod (Q-1);
+     // dQ: set mod register r0=Q-1 and perform ModInv operation
+     PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, r0/*res*/, rQ/*opA*/);
+     PKA_COPY(LEN_ID_MAX_BITS, rT1/*ds*/, rE/*src*/);
+     error = PkaExecFullModInv( rT1/*OpB*/, rdQ/*Res*/, rT2, rT3, rT4, rT5);
+     if (error != CC_OK) {
+         goto End;
+     }
+
+
+     // dP = E^-1 mod (P-1);
+     // dP: set mod register r0<=P-1 and perform ModInv operation
+     PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, r0/*res*/, rP/*dst*/);
+     PKA_COPY(LEN_ID_MAX_BITS, rT1/*ds*/, rE/*src*/);
+     error = PkaExecFullModInv( rT1/*OpB*/, rdP/*Res*/, rT2, rT3, rT4, rT5);
+     if (error != CC_OK) {
+         goto End;
+     }
+
+     // qInv = Q^-1 mod P;
+     // Qinv: set mod register r0<=P and perform ModInv operation
+     PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, r0/*Res*/, r0/*OpA*/); /* r0= P */
+     PKA_COPY(LEN_ID_MAX_BITS, rT1/*dst*/, rQ/*src*/);
+     PKA_MOD_INV(LEN_ID_N_BITS, rQinv/*Res*/, rT1/*OpB*/);
+
+
+     //    output of the result values dP,dQ,qInv
+     PkaCopyDataFromPkaReg(pPrivExp1dp, primeSizeInWords, rdP/*srcReg*/);
+     PkaCopyDataFromPkaReg(pPrivExp2dq, primeSizeInWords, rdQ/*srcReg*/);
+     PkaCopyDataFromPkaReg(pQInv, primeSizeInWords, rQinv/*srcReg*/);
+ End:
+     PkaFinishAndMutexUnlock(maxCountRegs);
+     return error;
+
+}
+
+
+
+
+
+
+/***********    RsaPrimeTestCall   function      **********************/
+/**
+ * @brief Test a primality according to ANSI X9.42 standard by
+ *  calling the RsaKgPrimeTest() which performs said algorithm.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t RsaPrimeTestCall(CCRndContext_t *pRndContext,          /*!< [in/out]  Pointer to the RND context buffer. */
+                             uint32_t *pPrimeP,                        /*!< [in] The pointer to the prime buff. */
+                             int32_t   sizeWords,                  /*!< [in] The prime size in words. */
+                             int32_t   rabinTestsCount,            /*!< [in] The count of Rabin-Miller tests repetition. */
+                             int8_t   *pIsPrime,               /*!< [in] TThe flag indicates primality:
+                                        if is not prime - CC_FALSE, otherwise - CC_TRUE. */
+                             uint32_t *pTempBuff,                  /*!< [in] The temp buffer of minimum size:
+                                        - on HW platform  3*MaxModSizeWords,
+                                        - on SW platform  41*MaxModSizeWords. */
+                             CCRsaDhPrimeTestMode_t primeTestMode)/*!< [in] primality testing mode (RSA or DH - defines how are performed some
+                                        operations on temp buffers. */
+{
+        CCError_t error;
+
+    error =  RsaKgPrimeTest(
+                                  pRndContext,
+                                  pPrimeP,
+                                  sizeWords,
+                                  rabinTestsCount,
+                                  pIsPrime,
+                                  primeTestMode,
+                                  pTempBuff);
+
+
+    return error;
+
+}
+
+
+/***********    RsaGenPandQ   function      **********************/
+/**
+ * @brief Generates P and Q primes for RSA key
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t RsaGenPandQ(
+                    CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
+                    size_t          KeySize,        /* key size in bits */
+                    uint32_t        eSizeInBits,
+                    uint32_t       *pPubExp,
+                    CCRsaKgData_t  *pKeyGenData) /*!< [in] Temporary buffer for internal use. */
+{
+
+    /* the error identifier */
+    CCError_t error = CC_OK;
+
+    uint32_t *pPrimeP, *pPrimeQ;
+    uint32_t pqSizeWords;
+    uint32_t success = 0;
+#if ((!defined RSA_KG_FIND_BAD_RND && !defined RSA_KG_NO_RND) || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
+    uint32_t buffXp[4]; //buffer for 4 MSB words of Xq
+#endif
+    uint32_t distPQ , tempSwap, i;
+    CCCommonCmpCounter_t cmpRes;
+
+    pPrimeP = pKeyGenData->KGData.p;
+    pPrimeQ = pKeyGenData->KGData.q;
+    pqSizeWords = CALC_FULL_32BIT_WORDS(KeySize/2);
+#if (defined RSA_KG_FIND_BAD_RND && defined DEBUG)
+    CC_PalMemCopy( RSA_KG_debugPvect, (uint8_t*)pKeyGenData->KGData.p, KeySize/(2*CC_BITS_IN_BYTE) );
+    CC_PalMemCopy( RSA_KG_debugQvect, (uint8_t*)pKeyGenData->KGData.q, KeySize/(2*CC_BITS_IN_BYTE) );
+#endif
+
+#if (defined RSA_KG_NO_RND && defined DEBUG)
+    CC_PalMemCopy( (uint8_t*)pKeyGenData->KGData.p, RSA_KG_debugPvect, KeySize/(2*CC_BITS_IN_BYTE) );
+    CC_PalMemCopy( (uint8_t*)pKeyGenData->KGData.q, RSA_KG_debugQvect, KeySize/(2*CC_BITS_IN_BYTE) );
+#endif
+#if ((defined RSA_KG_FIND_BAD_RND || defined RSA_KG_NO_RND) && defined DEBUG)
+#ifdef BIG__ENDIAN
+    /* for big endiannes machine reverse bytes order in words according to Big Endian  */
+    CC_COMMON_INVERSE_UINT32_IN_ARRAY( pKeyGenData->KGData.p, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
+    CC_COMMON_INVERSE_UINT32_IN_ARRAY( pKeyGenData->KGData.q, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
+#endif
+#endif
+
+
+
+    /* ................ Generate the 1st prime ................................. */
+    /* ------------------------------------------------------------------------- */
+    do{
+        /* clean the word adjacent to the old P (in case there's garbage in it) */
+        pPrimeP[pqSizeWords]=0;
+
+        /*Generate Xp*/
+#if ((!defined RSA_KG_FIND_BAD_RND && !defined RSA_KG_NO_RND) || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
+        error = CC_RsaGenerateVectorInRangeX931(pRndContext, pqSizeWords, pPrimeP);
+        if (error != CC_OK){
+            goto End;
+        }
+
+        /*save 4 MSB of Xp to temporary buffer for checking it's distance from Xq*/
+        CC_PalMemCopy(buffXp, pPrimeP, 4 *CC_32BIT_WORD_SIZE );
+
+#ifdef FIPS_CERTIFICATION
+        rsaKgOutParams.pP_PrimeInt = &prim1Int;
+        rsaKgOutParams.pQ_PrimeInt = &prim2Int;
+        primeInt = &prim1Int;
+#endif
+
+#endif
+        /* for debug */
+#if (defined RSA_KG_FIND_BAD_RND && defined DEBUG)
+        CC_PalMemCopy( RSA_KG_debugPvect, (uint8_t*)pPrimeP, KeySize/(2*CC_BITS_IN_BYTE) );
+        CC_PalMemCopy( RSA_KG_debugQvect, (uint8_t*)pPrimeQ, KeySize/(2*CC_BITS_IN_BYTE) );
+#endif
+#if ((defined RSA_KG_FIND_BAD_RND || defined RSA_KG_NO_RND) && defined DEBUG)
+#ifdef BIG__ENDIAN
+        /* for big endiannes machine reverse bytes order in words according to Big Endian  */
+        CC_COMMON_INVERSE_UINT32_IN_ARRAY( pPrimeP, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
+        CC_COMMON_INVERSE_UINT32_IN_ARRAY( pPrimeQ, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
+#endif
+#if defined LLF_PKI_PKA_DEBUG
+        PQindex = 0;
+#endif
+#endif
+        /*Generate P:*/
+
+        error = RsaKgFindPrime(
+                pRndContext,
+                pPubExp,  eSizeInBits,
+                KeySize,
+                &success,
+                pPrimeP,
+                pKeyGenData->KGData.kg_buf.ccRSAKGDataIntBuff);
+        if (error != CC_OK){
+            goto End;
+        }
+
+    }while(!success); /* End of loop for generating  P */
+
+    /* ................ Generate the 2nd prime ................................. */
+    /* ------------------------------------------------------------------------- */
+    while(1){
+        /* clean the word adjacent to the old Q (in case there's garbage in it) */
+        pPrimeQ[pqSizeWords]=0;
+
+#if ((!defined RSA_KG_FIND_BAD_RND && !defined RSA_KG_NO_RND) || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
+        while(1){/*Generate Xq*/
+            error = CC_RsaGenerateVectorInRangeX931(pRndContext, pqSizeWords, pPrimeQ); /*Xq Generation*/
+            if (error != CC_OK){
+                goto End;
+            }
+
+            /*check |Xp - Xq|<= 2^(keySize/2-100):
+             * compare 100 MS bits (3 words + 4 bits) of XP and XQ if they are equall, then
+             * generate new Xq*/
+            distPQ = (buffXp[3] - pPrimeQ[pqSizeWords-1]) != 0 ||
+                     (buffXp[2] - pPrimeQ[pqSizeWords-2]) != 0 ||
+                     (buffXp[1] - pPrimeQ[pqSizeWords-3]) != 0 ||
+                    ((buffXp[0] - pPrimeQ[pqSizeWords-4]) & 0xF0000000) != 0;
+            if (distPQ)
+            {
+                break;
+            }
+        } /* Generation of Xq is done - pPrimeQ points to Xq */
+#endif
+
+        /*Generate Q*/
+#if defined LLF_PKI_PKA_DEBUG && defined DEBUG
+#if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
+        PQindex = 1;
+#endif
+#endif
+#ifdef FIPS_CERTIFICATION
+        primeInt = &prim2Int;
+#endif
+        error = RsaKgFindPrime(
+                pRndContext,
+                pPubExp,  eSizeInBits,
+                KeySize,
+                &success,
+                pPrimeQ,
+                pKeyGenData->KGData.kg_buf.ccRSAKGDataIntBuff);
+        if (error != CC_OK){
+            goto End;
+        }
+
+
+        if(success)
+        {
+            distPQ = (pPrimeP[3] - pPrimeQ[pqSizeWords-1]) != 0 ||
+                     (pPrimeP[2] - pPrimeQ[pqSizeWords-2]) != 0 ||
+                     (pPrimeP[1] - pPrimeQ[pqSizeWords-3]) != 0 ||
+                    ((pPrimeP[0] - pPrimeQ[pqSizeWords-4]) & 0xF0000000) != 0;
+
+            if (distPQ){
+                break;
+            }
+            else {
+                /* In case the distance between P and Q is too small, generate a new prime.
+                 * The smaller prime should be discarded and generated again.
+                 * If Q is larger then P set P=Q. */
+
+                cmpRes = CC_CommonCmpLsWordsUnsignedCounters(pPrimeP,pqSizeWords,pPrimeQ,pqSizeWords);
+                if (cmpRes != CC_COMMON_CmpCounter1GreaterThenCounter2) {  /* if Q > P */
+                    CC_PalMemCopy(pPrimeP/*dest*/, pPrimeQ/*src*/, pqSizeWords*CC_32BIT_WORD_SIZE);
+#ifdef FIPS_CERTIFICATION
+                    rsaKgOutParams.pP_PrimeInt = &prim2Int;
+                    rsaKgOutParams.pQ_PrimeInt = &prim1Int;
+#endif
+                }
+            }
+        }
+    }/* End of loop for generating  Q - pPrimeQ points to Q */
+
+    /* if Q is larger then P exchange the vectors - we want to have P > Q */
+    /* copy P,Q, buffers into PKA registers */
+    cmpRes = CC_CommonCmpLsWordsUnsignedCounters(pPrimeP, pqSizeWords, pPrimeQ, pqSizeWords);
+
+    if (cmpRes != CC_COMMON_CmpCounter1GreaterThenCounter2) {  /* Q > P */
+        /* swap P/Q */
+        for(i=0 ; i<pqSizeWords ; i++){
+            tempSwap = pKeyGenData->KGData.p[i];
+            pKeyGenData->KGData.p[i] = pKeyGenData->KGData.q[i];
+            pKeyGenData->KGData.q[i] = tempSwap;
+        }
+
+#ifdef FIPS_CERTIFICATION
+        rsaKgOutParams.pP_PrimeInt = &prim2Int;
+        rsaKgOutParams.pQ_PrimeInt = &prim1Int;
+#endif
+    }
+
+#if  (defined LLF_PKI_PKA_DEBUG || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
+End:
+#endif
+    return error;
+}
+
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_private.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_private.c
new file mode 100644
index 0000000..38df148
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_private.c
@@ -0,0 +1,357 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+
+/************* Include Files ****************/
+
+#include "cc_rsa_error.h"
+#include "cc_rsa_types.h"
+#include "pka.h"
+#include "pki.h"
+#include "cc_pal_mutex.h"
+#include "pka_error.h"
+#include "rsa.h"
+#include "rsa_private.h"
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+
+/***********     RsaExecPrivKeyExpNonCrt  function      **********************/
+/**
+ * @brief Executes the RSA primitive: private key CRT exponent
+ *
+ *    Algorithm [PKCS #1 v2.1]:
+ *
+ *     1. If NonCRT exponent, then  M  =  C^D  mod N.
+ *
+ *     Where: M- message representative, C- ciphertext, D- priv.exponent, N- modulus,
+ *            ^ - exponentiation symbol.
+ *
+ *     Note: PKA registers used: r0,r1,r2,r3,r4,  r30,r31.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t RsaExecPrivKeyExpNonCrt(CCRsaPrivKey_t    *pPrivKey , /*!< [in]  Private key database. */
+                     CCRsaPrimeData_t *pPrivData)       /*!< [in/out]  Containing DataIn and DataOut buffers. */
+{
+    CCError_t error = CC_OK;
+    uint32_t modSizeWords, dSizeInWords;
+    uint32_t pkaReqRegs = 7;
+    /* set virtual registers pointers  */
+    uint8_t rT2= regTemps[2]; /*2*/
+    uint8_t rT3 = regTemps[3]; /*3*/
+    uint8_t rT4 = regTemps[4]; /*4*/
+
+    /* modulus N size in bytes */
+    modSizeWords = CALC_FULL_32BIT_WORDS(pPrivKey->nSizeInBits);
+    if (modSizeWords > CALC_FULL_32BIT_WORDS(CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS)) {
+        return CC_RSA_INVALID_MODULUS_SIZE;
+    }
+
+    /* priv. exponent size in bytes */
+    dSizeInWords = CALC_FULL_32BIT_WORDS(pPrivKey->PriveKeyDb.NonCrt.dSizeInBits);
+
+    error = PkaInitAndMutexLock(pPrivKey->nSizeInBits,&pkaReqRegs);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    /*      copy the N, Np DataIn and D into PKA registers                  */
+    /* N => r0 */
+    /* copy modulus N into PKA register: N=>r0 */
+    PkaCopyDataIntoPkaReg(PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivKey->n/*srcPtr*/,modSizeWords);
+
+    /* copy the NP into r1 register NP */
+    PkaCopyDataIntoPkaReg(PKA_REG_NP/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/,
+                   ((RsaPrivKeyDb_t*)(pPrivKey->ccRSAPrivKeyIntBuff))->NonCrt.NP/*srcPtr*/,
+                   CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+    /* copy input data into PKI register: DataIn=>r2 */
+    PkaCopyDataIntoPkaReg( rT2/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivData->DataIn, modSizeWords);
+
+    /* copy input data into PKI register: DataIn=>r2 */
+    PkaCopyDataIntoPkaReg( rT3/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivKey->PriveKeyDb.NonCrt.d, dSizeInWords);
+
+
+    /* .. calculate the exponent Res = DataIn^D mod N;                  ... */
+    PKA_MOD_EXP(LEN_ID_N_BITS/*LenID*/, rT4/*Res*/, rT2/*OpA*/, rT3/*OpB*/);
+
+
+    /*  Finish PKA and copy result */
+    /* copy result into output buffer */
+    /* copy result into output: r4 =>DataOut */
+    PkaCopyDataFromPkaReg(pPrivData->DataOut, modSizeWords, rT4/*srcReg*/);
+
+    PkaFinishAndMutexUnlock(pkaReqRegs);
+
+    return error;
+
+}
+
+
+/***********    RsaExecPrivKeyExpCrt   function      **********************/
+/**
+ * @brief This function executes the RSA primitive: private key CRT exponent.
+ *        adapted for Keys up to 2K bits size.
+ *
+ *    Algorithm [PKCS #1 v2.1]:
+ *
+ *   CRT exponentiation algorithm:
+ *        1. Mq  =  C^dQ mod Q;
+ *        2. Mp  =  C ^dP mod P,
+ *        3  h = (Mp-Mq)*qInv mod P;
+ *        4. M = Mq + Q * h.
+ *
+ *     Where: M- message representative, C- ciphertext, D- priv.exponent, N- modulus,
+ *            P,Q,dP,dQ, qInv - CRT private key parameters;
+ *            ^ - exponentiation symbol.
+ *
+ *     Note: 9 PKA registers are used: r0-r6,  r30,r31.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+static CCError_t RsaExecPrivKeyExpCrt(CCRsaPrivKey_t    *pPrivKey , /*!< [in]  Private key database. */
+                  CCRsaPrimeData_t *pPrivData)        /*!< [in/out]  Containing DataIn and DataOut buffers. */
+
+{
+    CCError_t error = CC_OK;
+    uint32_t  modSizeWords, pqSizeInWords;
+    uint32_t pkaReqRegs = 10;
+
+    /* virtual registers pointers
+       Note: don't change rQ = 6  */
+    int8_t  rN  = PKA_REG_N;
+    int8_t  rNP = PKA_REG_NP;
+    int8_t  rD  = regTemps[2];
+    int8_t  rT  = regTemps[3];
+    int8_t  rT1 = regTemps[4];
+    int8_t  rMq = regTemps[5];
+    int8_t  rQ  = regTemps[6];
+    int8_t  rqInv = regTemps[7];
+
+
+    /* modulus N size in bytes */
+    modSizeWords = CALC_FULL_32BIT_WORDS(pPrivKey->nSizeInBits);
+    if (modSizeWords > CALC_FULL_32BIT_WORDS(CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS)) {
+        return CC_RSA_INVALID_MODULUS_SIZE;
+    }
+
+    error = PkaInitAndMutexLock(pPrivKey->nSizeInBits, &pkaReqRegs);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    /*  set Sizes table: 0- Nsize, 1- Nsize+1w (is done), 2- Psize  */
+    PkaSetLenIds(pPrivKey->PriveKeyDb.Crt.PSizeInBits, LEN_ID_PQ_BITS);
+
+    /* P and Q size in bytes */
+    pqSizeInWords = CALC_FULL_32BIT_WORDS(pPrivKey->PriveKeyDb.Crt.PSizeInBits);
+
+    /* PKA modular operations  according to modulus Q:              */
+
+    /* copy CRT parametersrs Q, dQ, QP into PKA registers */
+    PkaCopyDataIntoPkaReg( rN/*0 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivKey->PriveKeyDb.Crt.Q/*src_ptr*/, pqSizeInWords);
+
+    PkaCopyDataIntoPkaReg( rD/*2 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivKey->PriveKeyDb.Crt.dQ/*src_ptr*/, pqSizeInWords);
+
+    PkaCopyDataIntoPkaReg( rNP/*1 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, ((RsaPrivKeyDb_t*)(pPrivKey->ccRSAPrivKeyIntBuff))->Crt.QP/*src_ptr*/,
+                CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS );
+    /* copy DataIn into rT and rT! */
+    PkaCopyDataIntoPkaReg(rT/*3 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivData->DataIn/*src_ptr*/, modSizeWords );
+    PKA_COPY(LEN_ID_MAX_BITS/*LenID*/, rT1/*4 dest*/, rT/*3 src*/);
+
+    /*  Calculation of Mq          */
+    /* reduction of the input data by modulus Q  rT = rT mod Q */
+    PKA_DIV(LEN_ID_N_PKA_REG_BITS/*LenID*/, rQ/*6 Res not used*/, rT/*3 OpA*/, rN/*0 OpB=rN=Q*/);
+
+    /* operation changes from p/q size to N size, need clearing rT high bits */
+
+    /*  calculate of Mq = DataIn^dQ mod Q: Mq = rT^rD mod rN        */
+    PKA_MOD_EXP(LEN_ID_PQ_BITS/*LenID*/, rMq/*5 Res*/, rT/*3 OpA*/, rD/*2 OpB*/);
+
+    /* PKA modular operations  according to modulus P:              */
+    /* copy prime factor P into rQ for swapping with rN */
+    PkaCopyDataIntoPkaReg(rQ/*6 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivKey->PriveKeyDb.Crt.P/*src_ptr*/, pqSizeInWords);
+    /* swap rQ <-> rN so that Q->rQ and P->rN */
+    rQ = PKA_REG_N; rN = 6;
+
+    /* set new value to N_NP_TO_T1 register according N->6, Np->1,T0->30,T1->31: 0x000FF826*/
+    PKA_SET_N_NP_T0_T1_REG(rN, PKA_REG_NP, PKA_REG_T0, PKA_REG_T1);
+
+
+    /* copy Barrett tag PP: PP=>NP */
+    PkaCopyDataIntoPkaReg(rNP/*1 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, ((RsaPrivKeyDb_t*)(pPrivKey->ccRSAPrivKeyIntBuff))->Crt.PP/*src_ptr*/,
+                   CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+    /* copy priv. exponent factor dP: dP=>rD */
+    PkaCopyDataIntoPkaReg(rD/*2 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivKey->PriveKeyDb.Crt.dP/*src_ptr*/, pqSizeInWords);
+
+    /* copy qInv coefficient: qInv=>rqInv   */
+    PkaCopyDataIntoPkaReg(rqInv/*7 dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pPrivKey->PriveKeyDb.Crt.qInv/*src_ptr*/, pqSizeInWords );
+
+    /*  Calculation of Mp          */
+    /* reduction of input data by modulus P:  rT = rT1 mod P  */
+    PKA_DIV(LEN_ID_N_PKA_REG_BITS/*LenID*/, rT/*3 res not used*/, rT1/*4 OpA and remainder*/, rN/*0 OpB*/);
+
+    /* operation changes from p/q size to N size, need clearing registers high bits */
+
+    /* calculate exponent Mp = DataIn^dP mod P , i.e: rT = rT1^rD mod rP  */
+    PKA_MOD_EXP(LEN_ID_PQ_BITS/*LenID*/, rT/*3 Res*/, rT1/*4 OpA*/, rD/*2 exp*/);
+
+    /* Calculation of  h = (Mp-Mq)*qInv mod P    */
+    /* rT1 = Mq mod P - needed for right calculating in next operation if Mq>P */
+    PKA_MOD_ADD_IM(LEN_ID_PQ_BITS/*LenID*/, rT1/*Res*/, rMq/*5 OpA*/, 0/*immed OpB*/);
+
+    /* rT = Mp - Mq mod P */
+    PKA_MOD_SUB(LEN_ID_PQ_BITS/*LenID*/, rT/*Res*/, rT/*OpA*/, rT1/*OpB*/);
+
+    /* rT1 = h = (Mp - Mq)*qInv mod P */
+    PKA_MOD_MUL(LEN_ID_PQ_BITS/*LenID*/, rT1/*Res*/, rT/*OpA*/, rqInv/*rqInv*/);
+
+    /*       M = Mq + Q*h;         */
+    /*  OpSize according Nsize     */
+    /* operation changes from p/q size to N size, need clearing rT high bits */
+    PkaClearPkaRegWords(rT1, pqSizeInWords);
+    PkaClearPkaRegWords(rT, pqSizeInWords);
+    PkaClearPkaRegWords(rQ, pqSizeInWords);
+    PkaClearPkaRegWords(rMq, pqSizeInWords);
+
+    /* copy rT1 and Mq in other registers for clearing junk from registers high part  */
+    PKA_2CLEAR(LEN_ID_MAX_BITS/*LenID*/, PKA_REG_T0/*dest*/);
+    PKA_COPY(LEN_ID_MAX_BITS/*LenID*/, rT/*dest*/, rT1/*src*/);
+    PKA_2CLEAR(LEN_ID_MAX_BITS/*LenID*/, PKA_REG_T0/*dest*/);
+    PKA_COPY(LEN_ID_MAX_BITS/*LenID*/, rT1/*dest*/, rMq/*src*/);
+
+    /* Q*h => rT = rQ*rT */
+    PKA_MUL_LOW(LEN_ID_N_PKA_REG_BITS/*LenID*/, rT/*Res*/, rT/*OpA*/, rQ/*OpB*/);
+
+    PkaClearPkaRegWords(rT, pPrivKey->nSizeInBits);
+
+    /* M = rT1 = rMq + rT */
+    PKA_ADD(LEN_ID_N_BITS/*LenID*/, rT/*Res*/, rT1/*OpA*/, rT/*OpB*/);
+
+    /*  Finish PKA and copy result */
+    PkaCopyDataFromPkaReg(pPrivData->DataOut,  modSizeWords, rT/*srcReg*/);
+
+    PkaFinishAndMutexUnlock(pkaReqRegs);
+
+    return error;
+
+}
+
+
+/***********     RsaInitPrivKeyDb  function      **********************/
+/**
+ * @brief This function initializes the low level key database private structure.
+ *        On the HW platform the Barrett tag is initialized
+ *
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t RsaInitPrivKeyDb( CCRsaPrivKey_t *pPrivKey )  /*!< [in]  Private key database. */
+{
+    CCError_t error = CC_OK;
+
+    /* calculate NP on NonCRT mode  */
+    if (pPrivKey->OperationMode == CC_RSA_NoCrt) {
+        /* check key size */
+        if (pPrivKey->nSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS) {
+            error = PKA_KEY_ILLEGAL_SIZE_ERROR;
+            goto END;
+        }
+
+        /* calculate Barrett tag NP by initialization PKA for modular operations.
+           Default settings: N=PKA_REG_N, NP=PKA_REG_NP, T0=30, T1=31.
+           Our settings for temps: rT0=2, rT1=3, rT2=4 */
+        error = PkiCalcNp( ((RsaPrivKeyDb_t *)(pPrivKey->ccRSAPrivKeyIntBuff))->NonCrt.NP,   /*out*/
+                    pPrivKey->n,     /*in*/
+                    pPrivKey->nSizeInBits); /*in*/
+
+
+    } else {
+        /* on CRT mode calculate the Barrett tags  */
+        /*    PP and PQ for P and Q factors        */
+        /* check key sizes */
+        if (pPrivKey->PriveKeyDb.Crt.PSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS/2 ||
+            pPrivKey->PriveKeyDb.Crt.QSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS/2) {
+            error = PKA_KEY_ILLEGAL_SIZE_ERROR;
+            goto END;
+        }
+        /* calculate Barrett tag PP by initialization PKA for modular operations */
+        error = PkiCalcNp( ((RsaPrivKeyDb_t *)(pPrivKey->ccRSAPrivKeyIntBuff))->Crt.PP,   /*out*/
+                    pPrivKey->PriveKeyDb.Crt.P, /*in*/
+                    pPrivKey->PriveKeyDb.Crt.PSizeInBits);
+        if (error != CC_SUCCESS) {
+            goto END;
+        }
+
+        /* calculate Barrett tag PP by initialization PKA for modular operations */
+        error = PkiCalcNp( ((RsaPrivKeyDb_t *)(pPrivKey->ccRSAPrivKeyIntBuff))->Crt.QP,   /*out*/
+                    pPrivKey->PriveKeyDb.Crt.Q, /*in*/
+                    pPrivKey->PriveKeyDb.Crt.QSizeInBits);
+        if (error != CC_SUCCESS) {
+            goto END;
+        }
+
+
+    }/* end of CRT case */
+
+    END:
+    return error;
+}
+
+
+
+/***********     RsaExecPrivKeyExp  function      **********************/
+/**
+ * @brief This function executes the RSA private key exponentiation
+ *
+ *    Algorithm [PKCS #1 v2.1]:
+ *
+ *     1. If NonCRT exponent, then  M  =  C^D  mod N.
+ *
+ *     2. If CRT exponent, then:
+ *        2.1. M1  =  C^dP mod P,
+ *        2.2. M2  =  C^dQ mod Q;
+ *        2.3  h = (M1-M2)*qInv mod P;
+ *        2.4. M = M2 + Q * h.
+ *
+ *     Where: M- message representative, C- ciphertext, N- modulus,
+ *            P,Q,dP,dQ, qInv - CRT private key parameters;
+ *            ^ - exponentiation symbol.
+ *
+ *     Note: PKA registers used: NonCrt: r0-r4,   r30,r31, size of registers - Nsize;
+ *                               Crt:    r0-r10,  r30,r31, size of registers - Nsize;
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t RsaExecPrivKeyExp( CCRsaPrivKey_t    *pPrivKey ,   /*!< [in]  Private key database. */
+                    CCRsaPrimeData_t *pPrivData )   /*!< [in/out]  Containing DataIn and DataOut buffers. */
+{
+    CCError_t error = CC_OK;
+
+    /*         1.  NonCRT  case                     */
+    if (pPrivKey->OperationMode == CC_RSA_NoCrt) {
+        error = RsaExecPrivKeyExpNonCrt(pPrivKey, pPrivData );
+    } else {
+        /*         2.  CRT  case                         */
+        error = RsaExecPrivKeyExpCrt(pPrivKey, pPrivData );
+    }
+
+    return error;
+}
+
+#endif/* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_private.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_private.h
new file mode 100644
index 0000000..bef3595
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_private.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef LLF_RSA_PRIVATE_H
+#define LLF_RSA_PRIVATE_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#include "cc_error.h"
+#include "cc_rsa_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+typedef union {
+    struct {
+/* the Barrett mod N tag  NP for N-modulus - used in the modular multiplication and
+  exponentiation, calculated in CC_RsaPrivKeyBuild function */
+        uint32_t NP[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+
+    }NonCrt;
+
+    struct {
+/* the Barrett mod P tag  PP for P-factor - used in the modular multiplication and
+  exponentiation, calculated in CC_RsaPrivKeyBuild function */
+        uint32_t PP[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+
+/* the Barrett mod Q tag  QP for Q-factor - used in the modular multiplication and
+  exponentiation, calculated in CC_RsaPubKeyBuild function */
+        uint32_t QP[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+
+    }Crt;
+
+}RsaPrivKeyDb_t;
+
+CCError_t RsaInitPrivKeyDb(CCRsaPrivKey_t *pPrivKey);
+
+CCError_t RsaExecPrivKeyExp(CCRsaPrivKey_t    *pPrivKey,
+            CCRsaPrimeData_t *pPrivData);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_public.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_public.c
new file mode 100644
index 0000000..0752d3d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_public.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+
+/************* Include Files ****************/
+
+#include "cc_rsa_error.h"
+#include "rsa_public.h"
+#include "cc_rsa_types.h"
+#include "pka.h"
+#include "pki.h"
+#include "cc_pal_mutex.h"
+#include "pka_error.h"
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+/***********    RsaInitPubKeyDb   function      **********************/
+/**
+ * @brief Initializes the low level key database public structure.
+ *        On the HW platform the Barrett tag is initialized
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+CCError_t RsaInitPubKeyDb(CCRsaPubKey_t *pPubKey)  /*!< [in]  Public key structure. */
+{
+    CCError_t error = CC_OK;
+
+    if (pPubKey == NULL) {
+        return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+    }
+
+    /* calculate Barrett tag NP by initialization PKA for modular operations.
+       Default settings: N=PKA_REG_N, NP=PKA_REG_NP, T0=30, T1=31.
+       Our settings for temps: rT0=2, rT1=3, rT2=4 */
+    error = PkiCalcNp( ((RsaPubKeyDb_t*)(pPubKey->ccRSAIntBuff))->NP, /*out*/
+                pPubKey->n,          /*in*/
+                pPubKey->nSizeInBits);
+
+    return error;
+
+
+}
+
+/***********     RsaExecPubKeyExp  function      **********************/
+/**
+ * @brief Executes the RSA primitive public key exponent :
+ *
+ *    pPubData->DataOut =  pPubData->DataIn ** pPubKey->e  mod  pPubKey->n,
+ *    where: ** - exponent symbol.
+ *
+ *    Note: PKA registers used: r0-r4,   r30,r31, size of registers - Nsize.
+ *
+ * @return  CC_OK On success, otherwise indicates failure
+ */
+
+CCError_t RsaExecPubKeyExp( CCRsaPubKey_t     *pPubKey,     /*!< [in]  Public key structure. */
+                       CCRsaPrimeData_t *pPubData )   /*!< [in]  Containing input data and output buffer. */
+{
+    CCError_t error = CC_OK;
+    uint32_t  nSizeInWords, eSizeInWords;
+    uint32_t  pkaReqRegs = 7;
+
+    uint8_t rT2 = regTemps[2];
+    uint8_t rT3 = regTemps[3];
+    uint8_t rT4 = regTemps[4];
+
+    /* modulus size in bytes */
+    nSizeInWords = CALC_FULL_32BIT_WORDS(pPubKey->nSizeInBits);
+    eSizeInWords = CALC_FULL_32BIT_WORDS(pPubKey->eSizeInBits);
+    if (nSizeInWords > CALC_FULL_32BIT_WORDS(CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS)) {
+        return CC_RSA_INVALID_MODULUS_SIZE;
+    }
+
+    error = PkaInitAndMutexLock(pPubKey->nSizeInBits, &pkaReqRegs);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    /* copy modulus N into r0 register */
+    PkaCopyDataIntoPkaReg(PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/,  pPubKey->n/*srcPtr*/,
+                   nSizeInWords);
+
+    /* copy the NP into r1 register NP */
+    PkaCopyDataIntoPkaReg(PKA_REG_NP/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, ((RsaPubKeyDb_t*)(pPubKey->ccRSAIntBuff))->NP/*srcPtr*/,
+                   CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+
+    /* copy input data into PKI register: DataIn=>r2 */
+    PkaCopyDataIntoPkaReg( rT2/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/,
+                pPubData->DataIn, nSizeInWords);
+
+    /* copy exponent data PKI register: e=>r3 */
+    PkaCopyDataIntoPkaReg(rT3/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/,
+                   pPubKey->e, eSizeInWords);
+
+    /* .. calculate the exponent Res = OpA**OpB mod N; */
+    PKA_MOD_EXP(LEN_ID_N_BITS/*LenID*/, rT4/*Res*/, rT2/*OpA*/, rT3/*OpB*/);
+
+    /* copy result into output: r4 =>DataOut */
+    PkaCopyDataFromPkaReg(pPubData->DataOut, nSizeInWords, rT4/*srcReg*/);
+
+    PkaFinishAndMutexUnlock(pkaReqRegs);
+
+
+    return error;
+}
+
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_public.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_public.h
new file mode 100644
index 0000000..bda21c7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/rsa/rsa_public.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef LLF_RSA_PUBLIC_H
+#define LLF_RSA_PUBLIC_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#include "cc_error.h"
+#include "cc_rsa_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+typedef struct {
+    /* the Barrett mod tag  NP for N-modulus - used in the modular multiplication and
+       exponentiation, calculated in CC_RsaPrivKeyBuild function */
+    uint32_t NP[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+}RsaPubKeyDb_t;
+
+CCError_t RsaExecPubKeyExp(CCRsaPubKey_t     *pPubKey,
+                CCRsaPrimeData_t *pPubData );
+
+CCError_t RsaInitPubKeyDb(CCRsaPubKey_t *pPubKey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/srp/srp.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/srp/srp.c
new file mode 100644
index 0000000..af407b2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/srp/srp.c
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "mbedtls_cc_srp.h"
+#include "mbedtls_cc_srp_error.h"
+#include "pka.h"
+
+
+extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
+
+#define SRP_NP_VALID 1
+
+// v=g^x%N
+uint32_t  SrpPwdVerifierCalc(mbedtls_srp_digest xBuff,
+                             mbedtls_srp_modulus    pwdVerifier,
+                             mbedtls_srp_context    *pCtx)
+{
+    CCError_t   rc = 0;
+    uint32_t    genWord;
+    uint32_t    pkaRegCount = 7; // adding 2 for HW temp regs PKA_REG_T0 & PKA_REG_T1
+    /* usage of PKA registers */
+    int8_t  rN = PKA_REG_N;
+    int8_t  rNp = PKA_REG_NP;
+    int8_t  rT2 = regTemps[2];
+    int8_t  rT3 = regTemps[3];
+    int8_t  rT4 = regTemps[4];
+
+    // Verify input
+    if ((pCtx == NULL) ||
+            (xBuff == NULL) ||
+            (pwdVerifier == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    genWord = pCtx->groupParam.gen;
+    rc = PkaInitAndMutexLock(pCtx->groupParam.modSizeInBits, &pkaRegCount);
+    if (rc != 0) {
+        return rc;
+    }
+    // first copy N and calculate Np
+    PkaCopyBeByteBuffIntoPkaReg(rN, LEN_ID_MAX_BITS, pCtx->groupParam.modulus, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    rc = PkaCalcNpIntoPkaReg(LEN_ID_N_BITS, pCtx->groupParam.modSizeInBits, rN, rNp, rT2, rT3);
+    if (rc != 0) {
+        goto end;
+    }
+    pCtx->groupParam.validNp = SRP_NP_VALID;
+    // save Np into pCtx
+    PkaCopyDataFromPkaReg(pCtx->groupParam.Np, CALC_32BIT_WORDS_FROM_BYTES(sizeof(pCtx->groupParam.Np)), rNp);
+
+    // calculate v=g^x%N
+    PkaCopyDataIntoPkaReg(rT2, LEN_ID_MAX_BITS, &genWord, CALC_32BIT_WORDS_FROM_BYTES(sizeof(genWord)));
+    PkaCopyBeByteBuffIntoPkaReg(rT3, LEN_ID_MAX_BITS, xBuff, CALC_32BIT_WORDS_FROM_BYTES(pCtx->hashDigestSize));
+    PKA_MOD_EXP(LEN_ID_N_BITS, rT4, rT2/*g*/, rT3 /*x*/);
+    // copy the verifier
+    PkaCopyPkaRegIntoBeByteBuff(pwdVerifier, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits), rT4);
+
+    end:
+    PkaFinishAndMutexUnlock(pkaRegCount);
+    return rc;
+}
+
+/* calculates S=(((A*v^u)^b)%N */
+uint32_t   SrpHostSharedSecretCalc(mbedtls_srp_modulus   userPubKeyA,
+                                   mbedtls_srp_modulus pwdVerifier,
+                                   mbedtls_srp_digest uScramble,
+                                   mbedtls_srp_modulus  sharedSecret,
+                                   mbedtls_srp_context  *pCtx)
+{
+    CCError_t   rc = 0;
+    uint32_t    status;
+    uint32_t    pkaRegCount = 8; // adding 2 for HW temp regs PKA_REG_T0 & PKA_REG_T1
+    /* usage of PKA registers */
+    int8_t  rN = PKA_REG_N;
+    int8_t  rNp = PKA_REG_NP;
+    int8_t  rT2 = regTemps[2];
+    int8_t  rT3 = regTemps[3];
+    int8_t  rT4 = regTemps[4];
+    int8_t  rT5 = regTemps[5];
+
+    // Verify input
+    if ((pCtx == NULL) ||
+            (pwdVerifier == NULL) ||
+            (userPubKeyA == NULL) ||
+            (uScramble == NULL) ||
+            (sharedSecret == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    if (pCtx->groupParam.validNp != SRP_NP_VALID) {
+        return CC_SRP_STATE_UNINITIALIZED_ERROR;
+    }
+    rc = PkaInitAndMutexLock(pCtx->groupParam.modSizeInBits, &pkaRegCount);
+    if (rc != 0) {
+        return rc;
+    }
+    // firt copy buffers into PKA reg
+    PkaCopyBeByteBuffIntoPkaReg(rN, LEN_ID_MAX_BITS, pCtx->groupParam.modulus, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    PkaCopyDataIntoPkaReg(rNp, LEN_ID_MAX_BITS, pCtx->groupParam.Np, CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
+    PkaCopyBeByteBuffIntoPkaReg(rT2, LEN_ID_MAX_BITS, pwdVerifier, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    PkaCopyBeByteBuffIntoPkaReg(rT3, LEN_ID_MAX_BITS, uScramble, CALC_32BIT_WORDS_FROM_BYTES(pCtx->hashDigestSize));
+    PkaCopyBeByteBuffIntoPkaReg(rT4, LEN_ID_MAX_BITS, userPubKeyA, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    PkaCopyBeByteBuffIntoPkaReg(rT5, LEN_ID_MAX_BITS, pCtx->ephemPriv, CALC_32BIT_WORDS_FROM_BYTES(pCtx->ephemPrivSize));
+
+    // verify 0 < userPubKeyA < N
+    /* if userPubKeyA == 0, return with error */
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT4, 0, status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+    /* if userPubKeyA > N, return with error */
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, rT4, rN);
+    PKA_GET_STATUS_CARRY(status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+
+    // calculate rT2 = (v^u)%N
+    PKA_MOD_EXP(LEN_ID_N_BITS, rT2, rT2/*v*/, rT3 /*u*/);
+    // calculate rT4 = (A*(v^u))%N
+    PKA_MOD_MUL(LEN_ID_N_BITS, rT4, rT4/*A*/, rT2 /*v^u*/);
+
+    // verify (A*(v^u)) != 0
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT4, 0, status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+    // verify (A*(v^u)) != 1
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT4, 1, status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+    // verify (A*(v^u)) != -1
+    PKA_ADD_IM(LEN_ID_N_BITS, rT2, rT4, 1);
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT2, 0, status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+
+    // calculate rT4 = (rT4 ^ b)%N
+    PKA_MOD_EXP(LEN_ID_N_BITS, rT4, rT4/*(A*(v^u))*/, rT5 /*(b)*/);
+    // copy the generated shared secret
+    PkaCopyPkaRegIntoBeByteBuff(sharedSecret, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits), rT4);
+    end:
+    PkaFinishAndMutexUnlock(pkaRegCount);
+    return rc;
+}
+
+
+// Use PKA to calculate S=((B-g^x)^(a+u*x))%N
+uint32_t   SrpUserSharedSecretCalc(mbedtls_srp_modulus   hostPubKeyB,
+                                   mbedtls_srp_digest   xBuff,
+                                   mbedtls_srp_digest   uScramble,
+                                   mbedtls_srp_modulus  sharedSecret,
+                                   mbedtls_srp_context  *pCtx)
+{
+    CCError_t   rc = 0;
+    uint32_t    status;
+    uint32_t    genWord;
+    // For 4KBytes PKA we have 10 PKA registers that supports 3072 bit modulus
+    uint32_t    pkaRegCount = 10; // adding 2 for HW temp regs PKA_REG_T0 & PKA_REG_T1
+    /* usage of PKA registers */
+    int8_t  rN = PKA_REG_N;
+    int8_t  rNp = PKA_REG_NP;
+    int8_t  rT2 = regTemps[2];
+    int8_t  rT3 = regTemps[3];
+    int8_t  rT4 = regTemps[4];
+    int8_t  rT5 = regTemps[5];
+    int8_t  rT6 = regTemps[6];
+    int8_t  rT7 = regTemps[7];
+
+    // Verify input
+    if ((pCtx == NULL) ||
+            (hostPubKeyB == NULL) ||
+            (xBuff == NULL) ||
+            (uScramble == NULL) ||
+            (sharedSecret == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    if (pCtx->groupParam.validNp != SRP_NP_VALID) {
+        return CC_SRP_STATE_UNINITIALIZED_ERROR;
+    }
+
+    genWord = pCtx->groupParam.gen;
+    rc = PkaInitAndMutexLock(pCtx->groupParam.modSizeInBits, &pkaRegCount);
+    if (rc != 0) {
+        return rc;
+    }
+    // firt copy buffers into PKA reg
+    PkaCopyBeByteBuffIntoPkaReg(rN, LEN_ID_MAX_BITS, pCtx->groupParam.modulus, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    PkaCopyDataIntoPkaReg(rNp, LEN_ID_MAX_BITS, pCtx->groupParam.Np, CALC_32BIT_WORDS_FROM_BYTES(sizeof(pCtx->groupParam.Np)));
+    PkaCopyDataIntoPkaReg(rT2, LEN_ID_MAX_BITS, &genWord, CALC_FULL_32BIT_WORDS(sizeof(genWord)));
+    PkaCopyBeByteBuffIntoPkaReg(rT3, LEN_ID_MAX_BITS, xBuff, CALC_32BIT_WORDS_FROM_BYTES(pCtx->hashDigestSize));
+    PkaCopyBeByteBuffIntoPkaReg(rT4, LEN_ID_MAX_BITS, hostPubKeyB, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    PkaCopyBeByteBuffIntoPkaReg(rT5, LEN_ID_MAX_BITS, uScramble, CALC_32BIT_WORDS_FROM_BYTES(pCtx->hashDigestSize));
+    PkaCopyBeByteBuffIntoPkaReg(rT6, LEN_ID_MAX_BITS, pCtx->ephemPriv, CALC_32BIT_WORDS_FROM_BYTES(pCtx->ephemPrivSize));
+
+    // verify 0 < hostPubKeyB < N
+    /* if hostPubKeyB % N == 0, return with error */
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT4, 0, status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+    /* if hostPubKeyB > N, return with error */
+    PKA_SUB(LEN_ID_N_PKA_REG_BITS, RES_DISCARD, rT4, rN);
+    PKA_GET_STATUS_CARRY(status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+    PkaCopyBeByteBuffIntoPkaReg(rT7, LEN_ID_MAX_BITS, pCtx->kMult, CALC_32BIT_WORDS_FROM_BYTES(pCtx->hashDigestSize));
+
+    // calculate rT2 = (g^x)%N
+    PKA_MOD_EXP(LEN_ID_N_BITS, rT2, rT2/*g*/, rT3 /*x*/);
+    // calculate rT2 = (k*rT2)%N
+    PKA_MOD_MUL(LEN_ID_N_BITS, rT2, rT7/*k*/, rT2 /*g^x*/);
+    // calculate rT2 = (B-rT2)%N
+    PKA_MOD_SUB(LEN_ID_N_BITS, rT2, rT4/*B*/, rT2 /*g^x*/);
+    // calculate rT5 = (u*x)%N
+    PKA_MOD_MUL(LEN_ID_N_BITS, rT5, rT5/*u*/, rT3 /*x*/);
+    // calculate rT5 = (a + rT5)%N
+    PKA_MOD_ADD(LEN_ID_N_BITS, rT5, rT6/*(a)*/, rT5 /*(u*x)*/);
+    // calculate rT5 = (rT2^rT5)%N
+    PKA_MOD_EXP(LEN_ID_N_BITS, rT5, rT2/*(B-k*g^x)*/, rT5 /*(a+u*x)*/);
+    // copy the generated session key
+    PkaCopyPkaRegIntoBeByteBuff(sharedSecret, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits), rT5);
+    end:
+    PkaFinishAndMutexUnlock(pkaRegCount);
+    return rc;
+}
+
+
+/* calculates B = (k*v+ g^b)%N */
+uint32_t  SrpHostPublicKeyCalc(mbedtls_srp_modulus  pwdVerifier,    // in
+                               mbedtls_srp_modulus  hostPubKeyB,    // out
+                               mbedtls_srp_context  *pCtx)      // in
+{
+    CCError_t   rc = 0;
+    uint32_t    status;
+    uint32_t    genWord;
+    uint32_t    pkaRegCount = 8; // adding 2 for HW temp regs PKA_REG_T0 & PKA_REG_T1
+    /* usage of PKA registers */
+    int8_t  rN = PKA_REG_N;
+    int8_t  rNp = PKA_REG_NP;
+    int8_t  rT2 = regTemps[2];
+    int8_t  rT3 = regTemps[3];
+    int8_t  rT4 = regTemps[4];
+    int8_t  rT5 = regTemps[5];
+
+    // Verify input
+    if ((pCtx == NULL) ||
+            (pwdVerifier == NULL) ||
+            (hostPubKeyB == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+    genWord = pCtx->groupParam.gen;
+    rc = PkaInitAndMutexLock(pCtx->groupParam.modSizeInBits, &pkaRegCount);
+    if (rc != 0) {
+        return rc;
+    }
+    // firt copy buffers into PKA reg
+    PkaCopyBeByteBuffIntoPkaReg(rN, LEN_ID_MAX_BITS, pCtx->groupParam.modulus, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    if (pCtx->groupParam.validNp != SRP_NP_VALID) {
+        rc = PkaCalcNpIntoPkaReg(LEN_ID_N_BITS, pCtx->groupParam.modSizeInBits, rN, rNp, rT2, rT3);
+        if (rc != 0) {
+            goto end;
+        }
+        // save Np into pCtx
+        PkaCopyDataFromPkaReg(pCtx->groupParam.Np, CALC_32BIT_WORDS_FROM_BYTES(sizeof(pCtx->groupParam.Np)), rNp);
+        pCtx->groupParam.validNp = SRP_NP_VALID;
+    } else {
+        PkaCopyDataIntoPkaReg(rNp, LEN_ID_MAX_BITS, pCtx->groupParam.Np, CALC_32BIT_WORDS_FROM_BYTES(sizeof(pCtx->groupParam.Np)));
+    }
+    PkaCopyBeByteBuffIntoPkaReg(rT2, LEN_ID_MAX_BITS, pCtx->kMult, CALC_32BIT_WORDS_FROM_BYTES(pCtx->hashDigestSize));
+    PkaCopyBeByteBuffIntoPkaReg(rT3, LEN_ID_MAX_BITS, pwdVerifier, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    PkaCopyDataIntoPkaReg(rT4, LEN_ID_MAX_BITS, &genWord, CALC_FULL_32BIT_WORDS(sizeof(genWord)));
+    PkaCopyBeByteBuffIntoPkaReg(rT5, LEN_ID_MAX_BITS, pCtx->ephemPriv, CALC_32BIT_WORDS_FROM_BYTES(pCtx->ephemPrivSize));
+
+    // calculate rT2 = (k*v)%N
+    PKA_MOD_MUL(LEN_ID_N_BITS, rT2, rT2/*k*/, rT3 /*v*/);
+    // calculate rT4 = (g^b)%N
+    PKA_MOD_EXP(LEN_ID_N_BITS, rT4, rT4/*g*/, rT5 /*b*/);
+    // calculate rT4 = (rT2 + rT4)%N
+    PKA_MOD_ADD(LEN_ID_N_BITS, rT4, rT2/*(k*v)*/, rT4 /*(g^b)*/);
+
+    // verify hostPubKeyB
+    /* if hostPubKeyB % N == 0, return with error */
+    PKA_MOD_ADD_IM(LEN_ID_N_BITS, rT5, rT4, 0);
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT5, 0, status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+
+    // copy the generated Host public key
+    PkaCopyPkaRegIntoBeByteBuff(hostPubKeyB, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits), rT4);
+    end:
+    PkaFinishAndMutexUnlock(pkaRegCount);
+    return rc;
+}
+
+/* calculates A = (g^a)%N */
+uint32_t  SrpUserPublicKeyCalc(mbedtls_srp_modulus  userPubKeyA,    // out
+                               mbedtls_srp_context  *pCtx)      // in
+{
+    CCError_t   rc = 0;
+    uint32_t    status;
+    uint32_t    genWord;
+    uint32_t    pkaRegCount = 6; // adding 2 for HW temp regs PKA_REG_T0 & PKA_REG_T1
+    /* usage of PKA registers */
+    int8_t  rN = PKA_REG_N;
+    int8_t  rNp = PKA_REG_NP;
+    int8_t  rT2 = regTemps[2];
+    int8_t  rT3 = regTemps[3];
+
+    // Verify input
+    if ((userPubKeyA == NULL) ||
+            (pCtx == NULL)) {
+        return CC_SRP_PARAM_INVALID_ERROR;
+    }
+
+    genWord = pCtx->groupParam.gen;
+    rc = PkaInitAndMutexLock(pCtx->groupParam.modSizeInBits, &pkaRegCount);
+    if (rc != 0) {
+        return rc;
+    }
+    // firt copy buffers into PKA reg
+    PkaCopyBeByteBuffIntoPkaReg(rN, LEN_ID_MAX_BITS, pCtx->groupParam.modulus, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits));
+    if (pCtx->groupParam.validNp != SRP_NP_VALID) {
+        rc = PkaCalcNpIntoPkaReg(LEN_ID_N_BITS, pCtx->groupParam.modSizeInBits, rN, rNp, rT2, rT3);
+        if (rc != 0) {
+            goto end;
+        }
+        // save Np into pCtx
+        PkaCopyDataFromPkaReg(pCtx->groupParam.Np, CALC_32BIT_WORDS_FROM_BYTES(sizeof(pCtx->groupParam.Np)), rNp);
+        pCtx->groupParam.validNp = SRP_NP_VALID;
+    } else {
+        PkaCopyDataIntoPkaReg(rNp, LEN_ID_MAX_BITS, pCtx->groupParam.Np, CALC_32BIT_WORDS_FROM_BYTES(sizeof(pCtx->groupParam.Np)));
+    }
+    PkaCopyDataIntoPkaReg(rT2, LEN_ID_MAX_BITS, &genWord, CALC_FULL_32BIT_WORDS(sizeof(genWord)));
+    PkaCopyBeByteBuffIntoPkaReg(rT3, LEN_ID_MAX_BITS, pCtx->ephemPriv, CALC_32BIT_WORDS_FROM_BYTES(pCtx->ephemPrivSize));
+
+    // calculate rT4 = (g^b)%N
+    PKA_MOD_EXP(LEN_ID_N_BITS, rT2, rT2/*g*/, rT3 /*a*/);
+
+    // verify userPubKeyA
+    /* if userPubKeyA % N == 0, return with error */
+    PKA_MOD_ADD_IM(LEN_ID_N_BITS, rT3, rT2, 0);
+    PKA_COMPARE_IM_STATUS(LEN_ID_N_PKA_REG_BITS, rT3, 0, status);
+    if (status == 1) {
+        rc = CC_SRP_PARAM_ERROR;
+        goto end;
+    }
+    // copy the generated User public key
+    PkaCopyPkaRegIntoBeByteBuff(userPubKeyA, CALC_FULL_32BIT_WORDS(pCtx->groupParam.modSizeInBits), rT2);
+    end:
+    PkaFinishAndMutexUnlock(pkaRegCount);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/srp/srp.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/srp/srp.h
new file mode 100644
index 0000000..516fb42
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/pki/srp/srp.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CC_API
+
+#ifndef _SRP_H
+#define _SRP_H
+
+#include "mbedtls_cc_srp.h"
+
+
+
+uint32_t  SrpPwdVerifierCalc(mbedtls_srp_digest xBuff,
+        mbedtls_srp_modulus pwdVerifier,
+        mbedtls_srp_context *pCtx);
+
+/* calculates S=(((A*v^u)^b)%N */
+uint32_t   SrpHostSharedSecretCalc(mbedtls_srp_modulus   userPubKeyA,
+        mbedtls_srp_modulus pwdVerifier,
+        mbedtls_srp_digest uScramble,
+                mbedtls_srp_modulus  sessionKey,
+                mbedtls_srp_context  *pCtx);
+
+
+// Use PKA to calculate S=((B-g^x)^(a+u*x))%N
+uint32_t   SrpUserSharedSecretCalc(mbedtls_srp_modulus  hostPubKeyB,
+        mbedtls_srp_digest    xBuff,
+        mbedtls_srp_digest    uScramble,
+                mbedtls_srp_modulus   sessionKey,
+                mbedtls_srp_context   *pCtx);
+
+/* calculates B = (k*v+ g^b)%N */
+uint32_t  SrpHostPublicKeyCalc(mbedtls_srp_modulus  pwdVerifier,    // in
+        mbedtls_srp_modulus hostPubKey,     // out
+        mbedtls_srp_context *pCtx);
+
+/* calculates A = (g^a)%N */
+uint32_t  SrpUserPublicKeyCalc(mbedtls_srp_modulus  userPubKeyA,    // out
+        mbedtls_srp_context *pCtx);
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/cc_rnd_common.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/cc_rnd_common.c
new file mode 100644
index 0000000..7bdd811
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/cc_rnd_common.c
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_log.h"
+#include "cc_rng_plat.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_rnd_common.h"
+#include "cc_rnd_error.h"
+#include "cc_rnd_local.h"
+#include "llf_rnd.h"
+#include "llf_rnd_trng.h"
+#include "llf_rnd_error.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mutex.h"
+#include "cc_fips_defs.h"
+#include "cc_util_pm.h"
+#ifdef CC_IOT
+#include "ctr_drbg.h"
+#include "entropy.h"
+#endif
+
+/* CC RND module version compliant to NIST 800-90 standard. Based on CTR DRBG Block Cipher (AES) */
+
+/************************ Defines ******************************/
+
+/*********************************** Enums ******************************/
+
+/*********************************Typedefs ******************************/
+/* rotate 32-bits word by 16 bits */
+#define RND_ROT32(x) ( (x) >> 16 | (x) << 16 )
+
+/* inverse the bytes order in a word */
+#define RND_REVERSE32(x)  ( ((RND_ROT32((x)) & 0xff00ff00UL) >> 8) | ((RND_ROT32((x)) & 0x00ff00ffUL) << 8) )
+
+/**************** Global Data to be read by RNG function ****************/
+
+/************************************************************************************/
+/***********************           Private functions            *********************/
+/************************************************************************************/
+
+/********************************************************************************
+  @brief This function subtracts a value from a large vector presented in the buffer.
+         The LSB of the counter is stored in the left most cell.
+
+  @return signed value of carry (borrow)
+ */
+
+static uint8_t AddInt8ValueToUin8Vector(uint8_t  *vect, /*! [in]  vect - the buffer containing the vector. */
+                    int8_t    val,  /*! [in]  val  - the value to add/subtract (according to its sign). */
+                    uint32_t  vectSizeInBytes) /*! [in]  vectSizeInBytes - the vector size in bytes. */
+{
+        /* DECLARATIONS */
+
+        /* loop index */
+    uint32_t i;
+    int32_t temp;
+
+    /* FUNCTION LOGIC */
+
+    temp = val;
+
+        for (i = 0; i < vectSizeInBytes; i++) {
+                temp = vect[i] + val;
+                vect[i] = (uint32_t)temp & 0xFF;
+                val = (temp >> 8) & 0xFF;
+    }
+
+    return val;
+
+}/* End of AddInt8ValueToUin8Vector() */
+
+
+
+
+
+/****************************************************************************************/
+/*****************************       Public Functions      ******************************/
+/****************************************************************************************/
+
+
+/****************************************************************************************/
+/**
+
+  @brief The function set the RND Generate vector function, provided by the User.
+
+  @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+  @param [in] rndGenerateVectFunc - The pointer to RND Generate vector function.
+
+  @return CCError_t - no return value
+ */
+CCError_t CC_RndSetGenerateVectorFunc(CCRndContext_t *rndContext_ptr,
+                       CCRndGenerateVectWorkFunc_t rndGenerateVectFunc)
+{
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* check parameters */
+        if (rndContext_ptr == NULL)
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+        if (rndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+
+        rndContext_ptr->rndGenerateVectFunc = rndGenerateVectFunc;
+
+        return 0;
+}
+
+
+
+
+
+
+#ifndef _INTERNAL_CC_ONE_SEED
+
+
+/**********************************************************************************************************/
+/**
+  @brief The function generates a random vector Rand in range  1 < RandVect < MaxVect
+              by testing candidates (described and used in FIPS 186-4: B.1.2, B.4.2 etc.):
+         The function performs the following:
+         1.  Check input parameters, in partial, check that value of max. vector > 3 (our requirement).
+         2.  If maxVect != 0 (maxVect is provided), then calculate required size of random
+             equaled to actual bit size of MaxVector, else set it = rndSizeInBits.
+         3.  Calls the CC_RndGenerateVector() function for generating random vector
+             RndVect of required size.
+         4.  If maxVect is provided, then:
+              4.0. Subtract maxVect  -= 2;
+              4.1. Sets all high bits of RndVect, greatest than MSBit of MaxVector, to 0.
+              4.2. If size of random vector > 16 bytes, then:
+                      4.2.1. Compares high 16 bytes of randVect to maxVect.
+                      4.2.2. If condition is not satisfied, then generate new high 16 bytes
+                             of rndVect and go to step 4.2.1.
+              4.3. Compare the full RndVect with MaxVector. If condition is not satisfied,
+                   then generate new random RndVect and go to step 4.1, else go to 6.
+         5. Else if maxVect is not provided, then set MSBit of rndVect to 1.
+         6. Output the result and Exit.
+
+          Note: Random and Max vectors are given as sequence of bytes, where LSB is most left byte
+                and MSB = most right one.
+
+  @param rndContext_ptr [in/out] - Pointer to the RND context buffer.
+  @param rndSizeInBits [in]   - If maxVect_ptr is not given, then rndSizeInBits defining the exact size (in bits)
+                         of generated random vector. If maxVect is given, then it defines the
+                      size (rounded up to bytes) of the maxVect_ptr buffer.
+  @param maxVect_ptr [in]     - The pointer to vector defining a high limit
+                         of random vector.
+  @param rndVect_ptr [in,out] - The output buffer for the random vector.
+
+  @return CCError_t  - On success CC_OK is returned, on failure - a value,
+              defined in cc_rnd_error.h.
+ */
+CEXPORT_C CCError_t CC_RndGenerateVectorInRange(
+                                                    CCRndContext_t *rndContext_ptr,
+                                                    size_t   rndSizeInBits,
+                                                    uint8_t  *maxVect_ptr,
+                                                    uint8_t  *rndVect_ptr )
+{
+        /* FUNCTION DECLARATIONS */
+
+        CCError_t Error = CC_OK;
+        int32_t   k, extraBytes;
+        int8_t    shift;
+        uint8_t   mask;
+        uint32_t   rndSizeInBytes, checkingSizeBytes = 0;
+        uint32_t   maxVectSizeBits;
+        uint32_t   maxVectSizeBytes = 0;
+        CCCommonCmpCounter_t CompRes;
+        /* RND state and function pointers */
+        CCRndState_t   *rndState_ptr;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+        /* FUNCTION LOGIC */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /*  Check input parameters */
+        if (rndVect_ptr == NULL)
+                return CC_RND_VECTOR_OUT_PTR_ERROR;
+
+    /* verify that rndSizeInBits is not greater than 2^19 -1 */
+    if (rndSizeInBits > 0x7FFFF)
+        return CC_RND_VECTOR_OUT_SIZE_ERROR;
+
+    /* given size of random vector in bytes */
+    rndSizeInBytes = CALC_FULL_BYTES(rndSizeInBits);
+
+    if (rndSizeInBits <= 1 || (uint32_t)rndSizeInBytes > CC_RND_MAX_GEN_VECTOR_SIZE_BYTES)
+            return CC_RND_VECTOR_OUT_SIZE_ERROR;
+
+    /* check parameters */
+    if (rndContext_ptr == NULL)
+            return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+
+    rndState_ptr = (CCRndState_t *)(rndContext_ptr->rndState);
+    RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+    if (RndGenerateVectFunc == NULL)
+            return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+
+    /*--------------------------------------*/
+    /* generation in case of exact bit size */
+    /*--------------------------------------*/
+
+    if (maxVect_ptr == NULL) {
+
+            Error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char *)rndVect_ptr, (size_t)rndSizeInBytes);
+
+            if (Error != CC_OK)
+                    goto End;
+
+            /* swap from big endian to little*/
+            CC_CommonReverseMemcpy(rndVect_ptr, rndVect_ptr, rndSizeInBytes);
+
+            /* correction of bit size */
+            rndVect_ptr[rndSizeInBytes-1] |= 0x80;
+            if (rndSizeInBits%8 != 0) {
+                    rndVect_ptr[rndSizeInBytes-1] >>= (8 - (rndSizeInBits&0x7))&0x7;
+            }
+
+            goto End;
+        }
+
+        /*------------------------------------------*/
+        /* generation in case of given max. vector  */
+        /*------------------------------------------*/
+
+        /* calculate actual size of MaxVector in bits*/
+        maxVectSizeBits = CC_CommonGetBytesCounterEffectiveSizeInBits(
+                                                                        maxVect_ptr, (uint16_t)rndSizeInBytes);
+        /* if maxVect < 4 then return an error */
+        if (maxVectSizeBits < 3 || (maxVectSizeBits == 3 && maxVect_ptr[0] < 4)) {
+                Error = CC_RND_MAX_VECTOR_IS_TOO_SMALL_ERROR;
+        goto End;
+    }
+
+        /* temporary subtract 2 from maxVect */
+        AddInt8ValueToUin8Vector(maxVect_ptr, -2/*val*/, maxVectSizeBytes);
+
+        maxVectSizeBytes = CALC_FULL_BYTES(maxVectSizeBits);
+
+        /* calculate count of extra 0-bytes in maxVector */
+        extraBytes = rndSizeInBytes - maxVectSizeBytes;
+
+        /* zeroing 0-bytes in rndVect_ptr buffer */
+        CC_PalMemSetZero(rndVect_ptr + maxVectSizeBytes, extraBytes);
+
+        /* calc. intermediate checking size */
+        if ((uint32_t)maxVectSizeBytes > CC_AES_BLOCK_SIZE_IN_BYTES) {
+                checkingSizeBytes = CC_AES_BLOCK_SIZE_IN_BYTES;
+        } else {
+                checkingSizeBytes = maxVectSizeBytes;
+        }
+
+        /* calculate count of extra 0-bits for mask shifting */
+        shift = (int8_t)(8 - (maxVectSizeBits & 7))&7;
+        mask = 0xFF >> shift;
+
+        /* main loop for generating random number    */
+        /*-------------------------------------------*/
+        k = 0;
+
+        while (k < 0xFFFF) {
+                /* generate full size random vector */
+                Error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char *)rndVect_ptr, (size_t)maxVectSizeBytes);
+
+                if (Error != CC_OK)
+                        goto End;
+
+                /* swap from big endian to little*/
+                CC_CommonReverseMemcpy(rndVect_ptr, rndVect_ptr, maxVectSizeBytes);
+
+                /* mask the non significant high bits */
+                rndVect_ptr[maxVectSizeBytes - 1] &= mask;
+
+                /* step1 check high part of random */
+                if (checkingSizeBytes == CC_AES_BLOCK_SIZE_IN_BYTES) {
+                        while (1) {
+                                CompRes = CC_CommonCmpLsbUnsignedCounters(
+                                                                            rndVect_ptr + maxVectSizeBytes - CC_AES_BLOCK_SIZE_IN_BYTES,
+                                                                            CC_AES_BLOCK_SIZE_IN_BYTES,
+                                                                            maxVect_ptr + maxVectSizeBytes - CC_AES_BLOCK_SIZE_IN_BYTES,
+                                                                            CC_AES_BLOCK_SIZE_IN_BYTES);
+
+                                if (CompRes == CC_COMMON_CmpCounter2GreaterThenCounter1) {
+                                        goto End;  /* random is found */
+                                } else if (CompRes == CC_COMMON_CmpCounter1AndCounter2AreIdentical)
+                                        break; /* go to check full size */
+
+                                /* generate new 16 random high bytes - without*
+                                *  repeat the same Additional Data            */
+                                Error = RndGenerateVectFunc((void *)rndState_ptr,
+                                                            (unsigned char *)rndVect_ptr + maxVectSizeBytes - CC_AES_BLOCK_SIZE_IN_BYTES,
+                                                            CC_AES_BLOCK_SIZE_IN_BYTES);
+                                if (Error != CC_OK)
+                                        goto End;
+
+                                /* mask the non significant high bits */
+                                rndVect_ptr[maxVectSizeBytes - 1] &= mask;
+                        }
+                }
+
+                /* check full size relating to max vector */
+                CompRes = CC_CommonCmpLsbUnsignedCounters(rndVect_ptr, (uint16_t)maxVectSizeBytes,
+                                                             maxVect_ptr, (uint16_t)maxVectSizeBytes);
+
+                if (CompRes == CC_COMMON_CmpCounter2GreaterThenCounter1) {
+                        goto End;
+                }
+
+                /* increment counter and continue the loop */
+                k++;
+        }
+
+        /* if all tries are Fail, then return the Error */
+        Error = CC_RND_CAN_NOT_GENERATE_RAND_IN_RANGE;
+
+End:
+
+    if (Error != CC_OK) {
+        CC_PalMemSetZero(rndVect_ptr, rndSizeInBytes);
+                return Error;
+    }
+
+
+        if (maxVect_ptr != NULL) {
+            /* reset the maxVect to (original value -1) */
+            AddInt8ValueToUin8Vector(maxVect_ptr, 1/*val*/, maxVectSizeBytes);
+
+            if (CC_CommonGetBytesCounterEffectiveSizeInBits(rndVect_ptr, maxVectSizeBytes) < 2) { /* vect == 1*/
+                /* replace 1 with(maxVect -1) */
+                    CC_PalMemCopy(rndVect_ptr, maxVect_ptr, maxVectSizeBytes);
+            }
+            /* reset the maxVect to original value */
+            AddInt8ValueToUin8Vector(maxVect_ptr, 1/*val*/, maxVectSizeBytes);
+
+        }
+
+        return Error;
+
+} /* End of CC_RndGenerateVectorInRange function */
+
+#endif /*_INTERNAL_CC_ONE_SEED*/
+
+
+/**********************************************************************************************************/
+/**
+ * @brief The RndGenerateWordsArrayInRange function generates a random words vector in range:
+ *            1 < RndVect < MaxVect,   using the FIPS-PUB 186-2 standard appendix 3 :
+ *
+ *        The function generates random array  using CC_RndGenerateVectorInRange function and
+ *        conversion of bytes to words.
+ *
+ *         Note: RndVect and MaxVect arrayss are given as sequence of words, where LSWord is most left byte
+ *               and MSWord - most right.
+ *
+ * @param rndContext_ptr [in/out]  - Pointer to the RND context buffer.
+ * @param rndSizeInBits [in]   - If maxVect_ptr is not given, then rndSizeInBits defining the exact size (in bits)
+ *                        of generated random vector. If maxVect is given, then it defines the
+ *                    size (rounded up to words) of the maxVect_ptr buffer. The size must be not greate
+ *                than CC_RND_MAX_SIZE_OF_OUTPUT_BYTES/4
+ * @param maxVect_ptr [in]     - The pointer to vector defining a high limit of random vector.
+ * @param rndVect_ptr [out]    - The output buffer for the random vector.
+ * @param tmp_ptr [int]        - The temp buffer for the random generation. The size must be not
+ *                less, than rndSizeInBits converted to words (rounded up).
+ *
+ * @return CCError_t  - On success CC_OK is returned, on failure - a value,
+ *                defined in cc_rnd_error.h.
+ */
+CCError_t RndGenerateWordsArrayInRange(CCRndContext_t *rndContext_ptr,
+                                       uint32_t   rndSizeInBits,
+                                       uint32_t  *maxVect_ptr,
+                                       uint32_t  *rndVect_ptr,
+                                       uint32_t  *tmp_ptr)
+{
+        /* FUNCTION DECLARATIONS */
+
+        CCError_t err;
+        uint32_t rndSizeInWords = CALC_FULL_32BIT_WORDS(rndSizeInBits);
+
+
+        /* check parameters */
+        if (rndVect_ptr == NULL)
+                return CC_RND_DATA_OUT_POINTER_INVALID_ERROR;
+
+        /* given size of random vector in bytes */
+        if (rndSizeInBits == 0 || rndSizeInWords*4 > CC_RND_MAX_GEN_VECTOR_SIZE_BYTES)
+                return CC_RND_VECTOR_SIZE_ERROR;
+
+        /* copy the maxVector into temp buffer and set endiannes as LE bytes  *
+        *  array                                  */
+        CC_PalMemMove((uint8_t*)tmp_ptr, (uint8_t*)maxVect_ptr, rndSizeInWords*sizeof(uint32_t));
+
+#ifdef BIG__ENDIAN
+        CC_COMMON_INVERSE_UINT32_IN_ARRAY(tmp_ptr, rndSizeInWords);
+#endif
+        /* generate vector in range [1...MaxVect] as LE bytes array */
+        rndVect_ptr[rndSizeInWords-1] = 0;
+        err = CC_RndGenerateVectorInRange(rndContext_ptr, rndSizeInBits, (uint8_t*)tmp_ptr, (uint8_t*)rndVect_ptr);
+
+        if (err)
+                return err;
+
+        /* set endianness in output words according to LE words array */
+#ifdef BIG__ENDIAN
+        CC_COMMON_INVERSE_UINT32_IN_ARRAY(rndVect_ptr, rndSizeInWords);
+#endif
+
+        return err;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd.c
new file mode 100644
index 0000000..2086f0a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+
+#include "dx_rng.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_rng_plat.h"
+#include "dx_crys_kernel.h"
+#include "cc_hal.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_rnd_local.h"
+#include "cc_rnd_error.h"
+#include "llf_rnd_hwdefs.h"
+#include "llf_rnd.h"
+#include "llf_rnd_error.h"
+#include "cc_sram_map.h"
+#include "cc_address_defs.h"
+#include "llf_rnd_trng.h"
+#include "cc_aes_defs.h"
+
+
+/********************************* Defines ******************************/
+#ifndef max
+#define max(a,b) (a) > (b) ? (a) : (b)
+#endif
+
+/* definitions used in the Entropy Estimator functions */
+#define S(a,n) ((uint32_t)((a) * (1<<(n)))) /* a scaled by n: a \times 2^n */
+#define U(a,n) ((uint32_t)(a) >> (n)) /* unscale unsigned: a / 2^n */
+#define SQR(x) (((x)&0xffff)*((x)&0xffff))
+
+/* macros for updating histogram for any separate bit;
+   where x represents cw  or e1 */
+#define   LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, x ) \
+    h_ptr[x & 0xff]++;  \
+    ec_ptr[x & 0x7f] = ((ec_ptr[x & 0x7f] & 1) == ((x & 0xff) >> 7)) ? ec_ptr[x & 0x7f] + 2 : ec_ptr[x & 0x7f] ^ 1; \
+    x >>= 1;
+
+/* Entropy estimation histogram width (prefix size + 1) */
+#define LLF_RND_nb   CC_RND_nb
+#define LLF_RND_NB   CC_RND_NB
+#define halfNB   (LLF_RND_NB / 2)
+#define ROSC_INIT_START_BIT   0x80000000
+
+
+/*********************************** Enums ******************************/
+/*********************************Typedefs ******************************/
+
+/**************** Global Data to be read by RNG function ****************/
+
+
+/* test variables */
+#ifdef RND_TEST_TRNG_WITH_ESTIMATOR
+uint32_t  gEntrSize[4];
+#endif
+
+
+/******************************************************************************/
+/***************   Prototypes and Private functions    ************************/
+/******************************************************************************/
+/****************************************************************************/
+/***********         Functions used for Entropy estimation      *************/
+/****************************************************************************/
+/**
+ * The function calculates low half of 32*32 bits multiplication result
+ *
+ * @param a
+ * @param b
+ *
+ * @return uint64_t
+ */
+uint64_t Mult32x32(uint32_t a, uint32_t b)
+{
+    uint64_t res=0;
+
+    res = (((a>>16)*(b>>16)) + (((a>>16)*(b&0xffff))>>16) + (((b>>16)*(a&0xffff))>>16));
+    res <<= 32;
+    res += (uint64_t)((a&0xffff)*(b&0xffff)) + (((a>>16)*(b&0xffff))<<16) + (((b>>16)*(a&0xffff))<<16);
+
+    return res;
+}
+
+/* Calculate 48*16 bits multiple using 16*16 bit multiplier */
+/* Code ASM takes 62 bytes */
+uint64_t Mult48x16(uint64_t a, uint32_t b)
+{
+    uint32_t a3 = (a >> 32), a2 = (a >> 16) & 0xffff, a1 = a & 0xffff;
+    uint32_t b1 = (b & 0xffff);
+    uint32_t r31 = a3*b1, r21 = a2*b1, r11 = a1*b1;
+    return(((uint64_t)r31) << 32) +
+    (((uint64_t)r21) << 16) +
+    ((uint64_t)r11);
+}
+
+
+/* approximation of entropy  */
+/**
+ * @brief The function approximates the entropy for separate prefix
+ *        ae = n * log2(n/m).
+ *
+ *    Implementation according A.Klimov algorithm uses approximation by
+ *    polynomial: ae = (n-m)*(A1 + A2*x + A3*x^2), where x = (n-m)/n <= 0.5 .
+ *    The coefficients are defined above in this file.
+ *
+ * @param[in] n - The summ of  0-bits and 1-bits in the test.
+ * @param[in] m - The maximal from the two above named counts.
+ *
+ * @return - result value of entropy ae.
+ */
+static uint32_t ae(uint32_t n, uint32_t m)
+{
+    /* logarithm calculation constants */
+    #define A1 1.4471280
+    #define A2 0.6073851
+    #define A3 0.9790318
+
+
+    uint32_t d = n-m,
+    x = S(d,16) / n,         /* x; 16 */
+        a = S(A3,14) * x,            /* x*A3; 30 */
+        b = U(S(A2,30) + a, 16) * x,     /* x*(A2 + x*A3); 30 */
+            c = (S(A1,30) + b),          /* (A1 + x*(A2 + x*A3)); 30 */
+            r = d * U(c,14);         /* result: 16 bits scaled */
+
+    return r;
+
+}
+
+/*****************************************************************************/
+/**
+ * @brief The function calculates a histogram of 0-s and 1-s distribution
+ *        depending on forgouing bits combination - prefix.
+ *
+ *     Implementation according A.Klimov algorithm modified by A.Ziv
+ *
+ * @param[in]  h_ptr - The pointer to the histogramm h buffer.
+ * @param[in]  ec_ptr - The pointer to the histogramm equality counter (ec) buffer.
+ * @param[in]  r_ptr - The pointer to Entropy source.
+ * @param[in]  nr    - The size of Entropy source in words.
+ * @param[in/out] pref_ptr - The pointer to last saved prefix.
+ * @param[in]  snp_ptr   - The pointer to the flag defining whether the new prefix should be set.
+ *
+ * @return CCError_t - no return value
+ */
+static void LLF_RND_HistogramUpdate(
+                   uint32_t   *h_ptr,     /* in/out */
+                   uint32_t   *ec_ptr,  /* in/out */
+                   uint32_t   *r_ptr,     /* in - input sequence */
+                   uint32_t     nr)    /* in - input sequence size in words */
+{
+    int32_t   i;
+    uint32_t j = 0;
+    uint32_t  cW;   /*current word of sequence*/
+    uint32_t  pref;
+
+    /* FUNCTION  LOGIC  */
+
+    /*------------------------------------------------------*/
+    /* update for first word of sequence: begin new prefix  */
+    /*------------------------------------------------------*/
+    cW = r_ptr[0];
+    /* 25 sequences are purely from new bits */
+    for (i = 0; i < 5; i++) {
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+    }
+
+    pref = cW;
+    j = 1;
+
+    /*-----------------------------------------------------------------------*/
+    /* update for remaining words of sequence: continue with previous prefix */
+    /*-----------------------------------------------------------------------*/
+    for (; j < nr; j++) {
+        uint32_t e1;
+
+        /*current word of random sequence*/
+        cW = r_ptr[j];
+        /* concatenation of previous saved prefix and new bits */
+        e1 = (cW << 7) | pref;
+
+        /* first 7 sequences are combined from previous prefix and new bits  */
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
+        LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, e1 );
+
+        /* next 25 sequences are purely from new bits */
+        for (i = 0; i < 5; i++) {
+            LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+            LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+            LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+            LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+            LLF_RND_UpdateHistOneBit( h_ptr, ec_ptr, cW );
+        }
+
+        pref = cW;
+    }
+
+} /* End of LLF_RND_HistogramUpdate() */
+
+
+/*****************************************************************************/
+/**
+ * @brief The function calculates estimation of entropy, generated by TRNG and
+ *        used for control the TRNG work.
+ *
+ *   Implementation based on algorithm developed by A.Klimov.
+ *
+ * @param[in] h - The pointer to the h-buffer (counts of 0-s and 1-s for each prefix).
+ * @param[in] ec - The pointer to the ec-buffer (equality counters).
+ * @param[out] e_ptr - The pointer to count of accumulated Entropy (bits multiplied by 2^16).
+ *
+ * @return CCError_t - according to module definitions
+ */
+static CCError_t LLF_RND_EntropyEstimate(
+                      uint32_t *h, /*in/out*/
+                      uint32_t *ec,
+                      uint32_t *e_ptr ) /* out - result Entropy size */
+{
+
+    uint64_t t = 0;        /* total entropy */
+    uint32_t i, ac = 0;        /* number of active prefixes */
+
+
+    /*-------------  calculate entropy -----------------*/
+
+    for (i = 0; i < halfNB; ++i) {
+
+        uint32_t n = h[i] + h[i+halfNB], m = max(h[i], h[i+halfNB]);
+
+        /* check that n < 2^16, else return overflow error */
+        if (n >= (1UL<<16))
+            return LLF_RND_TRNG_ENTR_ESTIM_SIZE_EXCEED_ERROR;
+
+        if (n != m) { /* if active prefix */
+            uint32_t n2, pp, od;
+            uint64_t od2, od2n, var;
+
+            /* increment count of active prefixes */
+            ++ac;
+
+            pp = SQR(m) + SQR(n-m);       /* related to theoretical "autocorrelation" probability */
+            n2 = Mult16x16((ec[i]>>1),n); /* n2 used as temp */
+
+            /* value, related to observed deviation of autocorrelation */
+            if (n2 > pp)
+                od = n2 - pp;
+            else
+                od = pp - n2;
+
+            /* theoretical variance of B(n, pp): always > 0 */
+            n2 = SQR(n);
+            var = Mult32x32(pp,(n2-pp));
+
+            /* if  n*od^2 < var then accumulate entropy, else return Error;
+               Note: that this condition is True only if od < 2^32 */
+            if (od != CC_MAX_UINT32_VAL) {
+                od2 = Mult32x32(od, od);
+
+                /* scale variables */
+                if (od2 > ((uint64_t)1ULL << 48)) {
+                    od2 /= (1UL<<16);
+                    var /= (1UL<<16);
+                }
+
+                od2n = Mult48x16(od2, n);
+
+                if (od2n < var)
+                    t += ae(n, m);
+            }
+        }
+    }
+
+    /* output entropy size value in bits (rescaled) */
+
+    *e_ptr = ac > 3 ? (t / (1UL << 16)) : 0;
+
+    return CC_OK;
+
+} /* End of LLF_RND_EntropyEstimate */
+
+/*****************************************************************************/
+/**
+ * @brief The function calculates estimation of entropy, generated by 4 ROSCs
+ *
+ * @param[in] ramAddr - The pointer to random source.
+ * @param[in] blockSizeWords - The size of each block of random source in words.
+ * @param[in] countBlocks - The blocks count (according to given ROSCS).
+ * @param[in] h_ptr - The pointer to the h-buffer (counts of 0-s and 1-s for each prefix).
+ * @param[in] ec_ptr - The pointer to the ec-buffer (equality counters).
+ * @param[out] entrSize_ptr - The pointer to count of accumulated Entropy in bits.
+ * @param[in] rndContext_ptr - The pointer to random State.
+ *
+ * @return CCError_t - according to module definitions
+ */
+CCError_t LLF_RND_EntropyEstimateFull(
+              uint32_t *ramAddr,      /*in*/
+              uint32_t  blockSizeWords, /*in*/
+              uint32_t  countBlocks,      /*in*/
+              uint32_t *entrSize_ptr,     /*out*/
+              uint32_t  *rndWorkBuff_ptr)   /*in*/
+{
+
+    CCError_t error = 0;
+    uint32_t i, totalEntr = 0, currEntr;
+    uint32_t *h_ptr, *ec_ptr;
+    uint32_t *eachRoscEntr_ptr = rndWorkBuff_ptr + CC_RND_WORK_BUFF_TMP2_OFFSET;
+
+
+    /* Initialization */
+
+    h_ptr  = rndWorkBuff_ptr + CC_RND_H_BUFF_OFFSET;
+    ec_ptr = rndWorkBuff_ptr + CC_RND_EC_BUFF_OFFSET;
+
+    /* estimate entropy for given blocks (ROSCs) */
+    for (i = 0; i < countBlocks; i++) {
+
+        /* Zeroe working buffer for entr. estimator */
+        CC_PalMemSetZero(h_ptr, H_BUFF_SIZE_WORDS*4);
+        CC_PalMemSetZero(ec_ptr, EC_BUFF_SIZE_WORDS*4);
+
+        LLF_RND_HistogramUpdate(
+                       h_ptr, ec_ptr,
+                       ramAddr + i*blockSizeWords,
+                       blockSizeWords);
+
+        error = LLF_RND_EntropyEstimate(
+                           h_ptr, ec_ptr,
+                           &currEntr);   /* out - result Entropy size */
+
+        if (error)
+            goto End;
+
+        /*total entropy and separate ROSCs entropy*/
+        totalEntr += currEntr;
+        eachRoscEntr_ptr[i] = currEntr;
+    }
+
+    /* entropy correction: down ~1.5% */
+    totalEntr  -= totalEntr >> 6;
+
+    *entrSize_ptr = totalEntr;
+
+    End:
+    return error;
+}
+
+/****************************************************************************************/
+/***********************      Auxiliary Functions              **************************/
+/****************************************************************************************/
+
+
+/************************************************************************************/
+/*!
+ * Busy wait upon RNG Interrupt signals.
+ *
+ * This function waits RNG interrupt and then disables RNG source.
+ * It uses CC_HalWaitInterrupt function
+ * to receive common RNG interrupt and then reads and
+ * outputs the RNG ISR (status) register.
+ *
+ *
+ * \return uint32_t RNG Interrupt status.
+ */
+CCError_t LLF_RND_WaitRngInterrupt(uint32_t *isr_ptr)
+{
+    uint32_t tmp = 0;
+    CCError_t error = CC_OK;
+    /* busy wait upon RNG IRR signals */
+    CC_REG_FLD_SET(HOST_RGF, HOST_IRR, RNG_INT, tmp, 1);
+    /* wait for watermark signal */
+    error = CC_HalWaitInterruptRND(tmp);
+    if (error != CC_OK){
+        /* stop DMA and the RNG source */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_DMA_ENABLE), 0);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), 0);
+        return error;
+    }
+    /* stop DMA and the RNG source */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_DMA_ENABLE), 0);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), 0);
+
+    /* read specific RNG interrupt status */
+    *isr_ptr = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, RNG_ISR));
+
+    /* clear RNG interrupt status besides HW errors */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_ICR), *isr_ptr);
+        /* clear again HOST_IRR, since it must be cleared after RNG_ISR */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), tmp);
+    return error;
+}
+
+/*****************************************************************/
+
+CCError_t LLF_RND_GetRoscSampleCnt(uint32_t rosc, CCRndParams_t *pTrngParams)
+{
+    switch (rosc) {
+    case 0x1:
+        pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio1;
+        break;
+    case 0x2:
+        pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio2;
+        break;
+    case 0x4:
+        pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio3;
+        break;
+    case 0x8:
+        pTrngParams->SubSamplingRatio = pTrngParams->userParams.SubSamplingRatio4;
+        break;
+    default:
+        return LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
+    }
+
+    return CC_OK;
+}
+
+/**
+ * The function gets next allowed rosc
+ *
+ * @author reuvenl (9/12/2012)
+ *
+ * @param trngParams_ptr - a pointer to params structure.
+ * @param rosc_ptr - a pointer to previous rosc /in/, and
+ *          to next rosc /out/.
+ * @param isNext - defines is increment of rosc ID needed or not.
+ *             if isNext = TRUE - the function shifts rosc by one bit; Then
+ *             the function checks is this rosc allowed, if yes - updates
+ *             the rosc, else repeats previous steps. If no roscs allowed -
+ *             returns an error.
+ *
+ *
+ * @return CCError_t
+ */
+CCError_t LLF_RND_GetFastestRosc(
+                  CCRndParams_t *trngParams_ptr,
+                  uint32_t *rosc_ptr     /*in/out*/)
+{
+    /* setting rosc */
+    do {
+
+        if (*rosc_ptr & trngParams_ptr->RoscsAllowed) {
+            return CC_OK;
+        } else {
+            *rosc_ptr <<= 1;
+        }
+
+    }while (*rosc_ptr <= 0x08);
+
+    return LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
+
+}
+
+
+/**
+ * The macros calculates count ROSCs to start, as count of bits "1" in allowed
+ * roscToStart parameter.
+ *
+ * @author reuvenl (9/20/2012)
+ *
+ * @param roscsAllowed
+ * @param roscToStart
+ *
+ * @return uint32_t
+ */
+uint32_t LLF_RND_GetCountRoscs(
+                       uint32_t roscsAllowed,
+                       uint32_t roscToStart)
+{
+    uint32_t countRoscs = 0;
+
+    roscToStart &= roscsAllowed;
+    while (roscToStart) {
+        countRoscs += (roscToStart & 1UL);
+        roscToStart >>= 1;
+    }
+
+    return countRoscs;
+}
+
+/****************************************************************************************/
+/*****************************       Public Functions      ******************************/
+/****************************************************************************************/
+
+
+/************************************************************************************/
+/**
+ * @brief The LLF_RND_TurnOffTrng stops the hardware random bits collection
+ *        closes RND clocks and releases HW semaphore.
+ *
+ *
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+void LLF_RND_TurnOffTrng(void)
+{
+    /* LOCAL DECLARATIONS */
+
+    uint32_t temp = 0;
+
+
+    /* FUNCTION LOGIC */
+
+    /* disable the RND source  */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_DISABLE_VAL);
+
+    /* close the Hardware clock */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_DISABLE_VAL);
+
+    /* clear RNG interrupts */
+    CC_REG_FLD_SET(HOST_RGF, HOST_ICR, RNG_INT_CLEAR, temp, 1);                                               \
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), temp);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG,RNG_ICR), 0xFFFFFFFF);
+
+
+    return;
+
+}/* END OF LLF_RND_TurnOffTrng*/
+
+
+/**
+* @brief: The function performs CPRNGT (Continued PRNG Test) according
+*         to NIST 900-80 and FIPS (if defined) standards.
+*
+* @param[in] prev_ptr - The pointer to previous saved generated random
+*                       value of size 16 bytes.
+* @param[in] buff_ptr - The pointer to generated random buffer.
+* @param[in] last_ptr - The pointer to last generated random block
+*                       of size 16 bytes used for output last bytes.
+* @param[in] countBlocks - The count of generated random blocks, including
+*                          the last block. Assumed countBlocks > 0.
+*
+* @return CCError_t - On success CC_OK is returned, on failure a
+*                        value MODULE_* as defined in cc_error.h
+*/
+CCError_t LLF_RND_RndCprngt(uint8_t            *prev_ptr,        /*in*/
+                  uint8_t            *buff_ptr,        /*in*/
+                  uint8_t            *last_ptr,        /*in*/
+                  int32_t             countBlocks)   /*in*/
+{
+        /* LOCAL DECLARATIONS */
+
+        CCError_t error = CC_OK;
+        int32_t  i;
+
+        /*  FUNCTION LOGIC */
+
+    /* compare the previous Value and last block */
+    if (countBlocks == 1) {
+        if (CC_PalMemCmp(prev_ptr, /*prev*/
+                   last_ptr,/*last block*/
+                   CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
+            error =  CC_RND_CPRNG_TEST_FAIL_ERROR;
+            goto End;
+        }
+    } else { /* countBlocks > 1, compare first and last blocks */
+        if (CC_PalMemCmp(prev_ptr,  /*prev*/
+                   buff_ptr, /*first block*/
+                   CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
+            error =  CC_RND_CPRNG_TEST_FAIL_ERROR;
+            goto End;
+        }
+
+        if (CC_PalMemCmp(buff_ptr + (countBlocks-2)*CC_AES_BLOCK_SIZE_IN_BYTES, /*prev*/
+                   last_ptr,/*last block*/
+                   CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
+            error =  CC_RND_CPRNG_TEST_FAIL_ERROR;
+            goto End;
+        }
+    }
+    /* compare intermediate blocks */
+    if (countBlocks > 2 && error == CC_OK) {
+        for (i = 0; i < countBlocks-2; i++) {
+            /* compare all current with previous blocks */
+            if (CC_PalMemCmp(buff_ptr + i*CC_AES_BLOCK_SIZE_IN_BYTES,
+                       buff_ptr + (i+1)*CC_AES_BLOCK_SIZE_IN_BYTES,
+                       CC_AES_BLOCK_SIZE_IN_BYTES) == 0) {
+                error = CC_RND_CPRNG_TEST_FAIL_ERROR;
+                goto End;
+            }
+        }
+    }
+
+        End:
+
+
+        return error;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd.h
new file mode 100644
index 0000000..8689234
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd.h
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef LLF_RND_H
+#define LLF_RND_H
+
+#include "cc_rnd_local.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+/************************ Defines ******************************/
+
+/* Definitions describing the TRNG Entropy estimator parameters:
+width of bits prefix and correlation table size */
+#define CC_RND_nb   8
+#define CC_RND_NB  (1 << CC_RND_nb)
+#define H_BUFF_SIZE_WORDS  CC_RND_NB
+#define EC_BUFF_SIZE_WORDS (CC_RND_NB/2)
+
+
+/* macro for calculation max. allowed time for */
+#define LLF_RND_CalcMaxTrngTime(ehrSamples, SubSamplingRatio) \
+    (((ehrSamples) * LLF_RND_TRNG_MAX_TIME_COEFF * \
+    LLF_RND_TRNG_VON_NEUMAN_COEFF * \
+    LLF_RND_HW_TRNG_EHR_WIDTH_IN_BITS * \
+    (SubSamplingRatio)) >> LLF_RND_TRNG_MAX_TIME_SCALE)
+
+/* Macro defining Multiplication  using 16x16 multiplier  */
+#define    Mult16x16(a, b) (((a)&0xffff)*((b)&0xffff))
+uint64_t Mult32x32(uint32_t a, uint32_t b);
+uint64_t Mult48x16(uint64_t a, uint32_t b);
+
+
+/************************ Enums ********************************/
+/************************ Typedefs  ****************************/
+/************************ Structs  *****************************/
+/* structure containing parameters and buffers for entropy estimator */
+typedef struct
+{
+   /* estimated entropy size */
+   uint32_t EstimEntropySizeBits;
+   /* estimated error of entropy size */
+   uint32_t EstimEntropySizeErrorInBits;
+
+   /* special buffers */
+   uint32_t h[CC_RND_NB];         /* histogram */
+   uint32_t ec[CC_RND_NB/2];      /* equality counter for prefix */
+
+}LLF_rnd_entr_estim_db_t;
+
+/******************** Public Functions *************************/
+
+/**
+ * @brief The LLF_RND_GetRngBytes returns size of random source needed for collection
+ *        required entropy .
+ *
+ *        The function returns size of source needed for required entropy.
+ *
+ * @param[in/out] trngParams - The pointer to structure, containing TRNG parameters.
+ * @entropySizeWords[in/out] - The pointer to size of random source. The user sets
+ *                    size of entropy that is required and the function returns
+ *                    the actual size of source needed for this count of entropy.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+CCError_t LLF_RND_GetEntropySourceSize(
+                                 CCRndParams_t    *trngParams, /*in*/
+                                 uint16_t   *entropySizeWords_ptr);   /*in/out*/
+
+
+/****************************************************************************************/
+/**
+ * @brief The function gets user provided parameters of RNG HW.
+ *
+ *   This implementation is in user competence. Temporary a pseudo function
+ *   is implemented for testing goals. To use this implementation the user must define
+ *   compilation flag "CC_RND_TEST_MODE", otherwise
+ *
+ *   Note: In temporary implementation assumed, that users parameters are placed
+ *         in global structure UserRngParameters (now placed in ATP tests).
+ *
+ * @param[in] KeySizeWords - The key size: 4 or 8 words according to security
+ *                           strength 128 bits or 256 bits;
+ * @param[in] TrngMode -  TRNG mode: 0 - SWEE mode, 1 - FE mode.
+ * @param[in] RoscsAllowed - Ring oscillator length level: should be set
+ *            as 2 bits value: 0,1,2,3.
+ * @param[in] SampleCount - The sampling count - count of RND blocks of RNG HW
+ *            output, required for needed entropy accumulation:
+ *              - in "fe" mode a possible values are 4095 to 65535, in steps of 4096;
+ *              - in "swee" mode, sampling counter limit is set to a low value -
+ *                typically 1 or 2.
+ * @param[in] MaxTrngTimeCoeff - coefficient defining relation between maximal allowed and expected
+ *                  time for random generation (in percents).
+ *
+ * @return CCError_t - CC_OK
+ */
+ CCError_t  LLF_RND_GetRngParams(
+            uint32_t  *KeySizeWords,
+            uint32_t  *TrngMode,
+            uint32_t  *RoscsAllowed,
+            uint32_t  *SampleCount,
+            uint32_t  *MaxTrngTimeCoeff);
+
+
+/************************************************************************************/
+/**
+ * @brief The LLF_RND_TurnOffTrng stops the hardware random bits collection
+ *        closes RND clocks and releases HW semaphore.
+ *
+ *
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+void LLF_RND_TurnOffTrng(void);
+
+
+CCError_t LLF_RND_GetFastestRosc(
+                                         CCRndParams_t *trngParams_ptr,
+                                         uint32_t *rosc_ptr    /*in/out*/);
+
+CCError_t LLF_RND_GetRoscSampleCnt(
+                     uint32_t rosc,
+                     CCRndParams_t *pTrngParams);
+
+CCError_t LLF_RND_WaitRngInterrupt(uint32_t *isr_ptr);
+
+uint32_t LLF_RND_GetCountRoscs(
+                                       uint32_t roscsAllowed,
+                                       uint32_t roscToStart);
+
+void LLF_RND_TurnOffTrng(void);
+
+CCError_t LLF_RND_EntropyEstimateFull(
+              uint32_t *ramAddr,      /*in*/
+              uint32_t  blockSizeWords, /*in*/
+              uint32_t  countBlocks,      /*in*/
+              uint32_t *entrSize_ptr,     /*out*/
+              uint32_t  *rndWorkBuff_ptr);   /*in*/
+
+/**
+* @brief: The function performs CPRNGT (Continued PRNG Test) according
+*         to NIST 900-80 and FIPS (if defined) standards.
+*
+* @param[in] prev_ptr - The pointer to previous saved generated random
+*                       value of size 16 bytes.
+* @param[in] buff_ptr - The pointer to generated random buffer.
+* @param[in] last_ptr - The pointer to last generated random block
+*                       of size 16 bytes used for output last bytes.
+* @param[in] countBlocks - The count of generated random blocks, including
+*                          the last block. Assumed countBlocks > 0.
+*
+* @return CCError_t - On success CC_OK is returned, on failure a
+*                        value MODULE_* as defined in cc_error.h
+*/
+CCError_t LLF_RND_RndCprngt(uint8_t            *prev_ptr,        /*in*/
+                  uint8_t            *buff_ptr,        /*in*/
+                  uint8_t            *last_ptr,        /*in*/
+                  int32_t             countBlocks);   /*in*/
+
+
+
+
+#ifdef __cplusplus
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_error.h
new file mode 100644
index 0000000..e1cf52b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_error.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef LLF_RND_ERROR_H
+#define LLF_RND_ERROR_H
+
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+/** RND module on the LLF layer base address -  0x00F10C00     */
+
+#define LLF_RND_HW_VERSION_NOT_CORRECT_ERROR        (LLF_RND_MODULE_ERROR_BASE + 0x0UL)
+#define LLF_RND_CPRNG_TEST_FAIL_ERROR           (LLF_RND_MODULE_ERROR_BASE + 0x1UL)
+#define LLF_RND_CRNGT_TEST_FAIL_ERROR           (LLF_RND_MODULE_ERROR_BASE + 0x2UL)
+#define LLF_RND_STATE_PTR_INVALID_ERROR         (LLF_RND_MODULE_ERROR_BASE + 0x3UL)
+#define LLF_RND_AES_256_NOT_SUPPORTED_ERROR             (LLF_RND_MODULE_ERROR_BASE + 0x4UL)
+
+#define LLF_RND_TRNG_TIME_LIMIT_EXCEEDED_ERROR          (LLF_RND_MODULE_ERROR_BASE + 0x20UL)
+#define LLF_RND_TRNG_ENTR_ESTIM_SIZE_EXCEED_ERROR       (LLF_RND_MODULE_ERROR_BASE + 0x21UL)
+
+#define LLF_RND_TRNG_PREVIOUS_PARAMS_NOT_MATCH_ERROR    (LLF_RND_MODULE_ERROR_BASE + 0x30UL)
+#define LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR   (LLF_RND_MODULE_ERROR_BASE + 0x31UL)
+#define LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR     (LLF_RND_MODULE_ERROR_BASE + 0x32UL)
+#define LLF_RND_TRNG_LOW_ENTROPY_ERROR              (LLF_RND_MODULE_ERROR_BASE + 0x33UL)
+#define LLF_RND_TRNG_NULL_ENTROPY_ERROR             (LLF_RND_MODULE_ERROR_BASE + 0x34UL)
+#define LLF_RND_TRNG_ILLEGAL_PTR_ERROR              (LLF_RND_MODULE_ERROR_BASE + 0x35UL)
+#define LLF_RND_TRNG_REPETITION_COUNTER_ERROR           (LLF_RND_MODULE_ERROR_BASE + 0x36UL)
+#define LLF_RND_TRNG_ADAPTION_PROPORTION_ERROR          (LLF_RND_MODULE_ERROR_BASE + 0x37UL)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_fetrng.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_fetrng.c
new file mode 100644
index 0000000..895fa0a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_fetrng.c
@@ -0,0 +1,504 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include "dx_rng.h"
+#include "cc_pal_mem.h"
+#include "cc_rng_plat.h"
+#include "dx_crys_kernel.h"
+#include "cc_hal.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_rnd_local.h"
+#include "cc_rnd_error.h"
+#include "llf_rnd_hwdefs.h"
+#include "llf_rnd.h"
+#include "llf_rnd_error.h"
+#include "cc_sram_map.h"
+#include "cc_plat.h"
+#include "llf_rnd_trng.h"
+#include "cc_int_general_defs.h"
+#ifndef CMPU_UTIL
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_util_pm.h"
+#endif
+#define ROSC_INIT_START_BIT   0x80000000
+
+#if !defined(CMPU_UTIL) && !defined(SC_TEST_MODE)
+extern CC_PalMutex *pCCRndCryptoMutex;
+
+#define MUTEX_LOCK_AND_RETURN_UPON_ERROR(pmutex) \
+        if (CC_PalMutexLock(pmutex, CC_INFINITE) != CC_SUCCESS) { \
+            CC_PalAbort("Fail to acquire mutex\n"); \
+        }
+
+#define MUTEX_UNLOCK(pmutex) \
+        if (CC_PalMutexUnlock(pmutex) != CC_SUCCESS) { \
+            CC_PalAbort("Fail to release mutex\n"); \
+        }
+
+#define DECREASE_CC_COUNTER \
+        if (CC_IS_IDLE != CC_SUCCESS) { \
+            CC_PalAbort("Fail to decrease PM counter\n"); \
+        }
+
+#define INCREASE_CC_COUNTER \
+        if (CC_IS_WAKE != CC_SUCCESS) { \
+            CC_PalAbort("Fail to increase PM counter\n"); \
+        }
+
+#else
+#define MUTEX_LOCK_AND_RETURN_UPON_ERROR(mutex)
+#define MUTEX_UNLOCK(mutex)
+#define DECREASE_CC_COUNTER
+#define INCREASE_CC_COUNTER
+#endif
+
+
+/*********************************** Enums ******************************/
+/*********************************Typedefs ******************************/
+
+/**************** Global Data to be read by RNG function ****************/
+
+/* test variables */
+#ifdef RND_TEST_TRNG_WITH_ESTIMATOR
+uint32_t  gEntrSize[4];
+#endif
+
+
+/************************************************************************************/
+/**
+ * The function checks that parameters, loaded in the TRNG HW
+ * are match to parameters, required by trngParams_ptr structures.
+ *
+ * @author reuvenl (6/25/2012)
+ *
+ * @param trngParams_ptr
+ *
+ * @return CCError_t
+ */
+static CCError_t LLF_RND_TRNG_CheckHwParams(CCRndParams_t *trngParams_ptr)
+{
+    uint32_t temp;
+    CCBool_t isTrue = CC_TRUE;
+
+    /* check Debug control - masked TRNG tests according to mode */
+    temp = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, TRNG_DEBUG_CONTROL));
+    isTrue &= (temp == LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_FE_MODE);
+    /* check samplesCount */
+    temp = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG,SAMPLE_CNT1));
+    isTrue &= (temp == trngParams_ptr->SubSamplingRatio);
+
+    /* if any parameters are not match return an Error */
+        if (isTrue == CC_FALSE) {
+                return LLF_RND_TRNG_PREVIOUS_PARAMS_NOT_MATCH_ERROR;
+        }
+        else {
+                return CC_OK;
+        }
+}
+
+static uint32_t LLF_RND_TRNG_RoscMaskToNum(uint32_t mask)
+{
+        return (mask == LLF_RND_HW_TRNG_ROSC3_BIT) ? LLF_RND_HW_TRNG_ROSC3_NUM :
+                (mask == LLF_RND_HW_TRNG_ROSC2_BIT) ? LLF_RND_HW_TRNG_ROSC2_NUM :
+                (mask == LLF_RND_HW_TRNG_ROSC1_BIT) ? LLF_RND_HW_TRNG_ROSC1_NUM :
+                LLF_RND_HW_TRNG_ROSC0_NUM;
+}
+
+static void LLF_RND_TRNG_EnableRngSourceAndWatchdog(CCRndParams_t *trngParams_ptr)
+{
+        uint32_t maxCycles;
+        uint32_t ehrSamples;
+
+        /* set EHR samples = 2 /384 bit/ for both AES128 and AES256 */
+        ehrSamples = LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE;
+
+        /* Set watchdog threshold to maximal allowed time (in CPU cycles) */
+        maxCycles = LLF_RND_CalcMaxTrngTime(ehrSamples, trngParams_ptr->SubSamplingRatio);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_WATCHDOG_VAL), maxCycles);
+
+        /* enable the RND source */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_ENABLE_VAL);
+}
+
+static CCError_t LLF_RND_TRNG_ReadEhrData(uint32_t *pSourceOut, bool isFipsSupported)
+{
+        CCError_t error = CC_OK;
+        uint32_t isr = 0;
+        uint32_t i;
+
+
+
+        /* wait RNG interrupt: isr signals error bits */
+        error = LLF_RND_WaitRngInterrupt(&isr);
+        if (error != CC_OK){
+                return error;
+        }
+
+        error = LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
+        if (CC_REG_FLD_GET(0, RNG_ISR, EHR_VALID, isr)) {
+                error = CC_OK;
+        }
+        if (CC_REG_FLD_GET(0, RNG_ISR, CRNGT_ERR, isr) && isFipsSupported) {
+                /* CRNGT requirements for FIPS 140-2. Should not try the next ROSC in FIPS mode. */
+                error = LLF_RND_CRNGT_TEST_FAIL_ERROR;
+        }
+
+        /* in case of AUTOCORR_ERR or RNG_WATCHDOG, keep the default error value. will try the next ROSC. */
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_ICR), 0xFFFFFFFF);
+
+        if (error == CC_OK) {
+                for (i = 0; i < LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS; i++)
+                {
+                        /* load the current random data to the output buffer */
+                        *(pSourceOut++) = CC_HAL_READ_REGISTER(DX_EHR_DATA_0_REG_OFFSET + (i*sizeof(uint32_t)));
+                }
+                CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, RNG_ISR));
+        }
+
+        return error;
+}
+
+/****************************************************************************************/
+/*****************************       Public Functions      ******************************/
+/****************************************************************************************/
+
+
+CCError_t LLF_RND_StartTrngHW(
+        CCRndState_t  *rndState_ptr,
+        CCRndParams_t *trngParams_ptr,
+        CCBool_t           isRestart,
+        uint32_t         *roscsToStart_ptr)
+{
+        /* LOCAL DECLARATIONS */
+
+        CCError_t error = CC_OK;
+        uint32_t tmpSamplCnt = 0;
+        uint32_t roscNum = 0;
+#ifdef CC_IOT
+        uint32_t mask = 0;
+#endif
+        /* FUNCTION LOGIC */
+
+        /* Check pointers */
+        if ((rndState_ptr == NULL) || (trngParams_ptr == NULL) ||
+                (roscsToStart_ptr == NULL))
+                return LLF_RND_TRNG_ILLEGAL_PTR_ERROR;
+
+
+        /*--------------------------------------------------------------*/
+        /* 1. If full restart, get semaphore and set initial ROSCs      */
+        /*--------------------------------------------------------------*/
+        if (isRestart) {
+                /* set ROSC to 1 (fastest)  */
+                *roscsToStart_ptr = 1UL;
+
+                /* init rndState flags to zero */
+                rndState_ptr->TrngProcesState = 0;
+        }
+
+
+        if (*roscsToStart_ptr == 0)
+                return LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
+
+        /* FE mode  */
+        /* Get fastest allowed ROSC */
+        error = LLF_RND_GetFastestRosc(
+                trngParams_ptr,
+                roscsToStart_ptr     /*in/out*/);
+        if (error)
+                return error;
+
+        error = LLF_RND_GetRoscSampleCnt(*roscsToStart_ptr, trngParams_ptr);
+        if (error)
+                return error;
+
+        roscNum = LLF_RND_TRNG_RoscMaskToNum(*roscsToStart_ptr);
+
+        /*--------------------------------------------------------------*/
+        /* 2. Restart the TRNG and set parameters                   */
+        /*--------------------------------------------------------------*/
+        /* RNG Block HW Specification (10 Programming Reference)        */
+
+        /* enable the HW RND clock   */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_ENABLE_VAL);
+
+        /* do software reset */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_SW_RESET), 0x1);
+        /* in order to verify that the reset has completed the sample count need to be verified */
+        do {
+                /* enable the HW RND clock   */
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_ENABLE_VAL);
+
+                /* set sampling ratio (rng_clocks) between consecutive bits */
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, SAMPLE_CNT1), trngParams_ptr->SubSamplingRatio);
+
+                /* read the sampling ratio  */
+                tmpSamplCnt = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, SAMPLE_CNT1));
+
+        } while (tmpSamplCnt != trngParams_ptr->SubSamplingRatio);
+
+
+        /* disable the RND source for setting new parameters in HW */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_DISABLE_VAL);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_ICR), 0xFFFFFFFF);
+
+        /* set interrupt mask */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_IMR), LLF_RNG_INT_MASK_ON_FETRNG_MODE);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, TRNG_CONFIG), roscNum);
+
+#ifdef CC_IOT
+        /* mask RNG_INT - this interrupt should be polled upon,
+         * and not handled by the operating system's interrupt handler. */
+        mask = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, RNG_INT_MASK, mask, 1);
+        CC_HalMaskInterrupt(mask);
+#endif
+        /* Debug Control register: set to 0 - no bypasses */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, TRNG_DEBUG_CONTROL), LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_FE_MODE);
+
+        LLF_RND_TRNG_EnableRngSourceAndWatchdog(trngParams_ptr);
+
+        /* set indication about current started ROSCs:  */
+        /*new started*/
+        rndState_ptr->TrngProcesState = (rndState_ptr->TrngProcesState & 0x00ffffff) | (*roscsToStart_ptr << 24);
+        /*total started*/
+        rndState_ptr->TrngProcesState |= (*roscsToStart_ptr << 8);
+
+        return error;
+}
+
+
+CCError_t LLF_RND_GetTrngSource(
+        CCRndState_t  *rndState_ptr,        /*in/out*/
+        CCRndParams_t  *trngParams_ptr,     /*in/out*/
+        CCBool_t            isContinued,    /*in*/
+        uint32_t         *entropySize_ptr,      /*in/out*/
+        uint32_t        **sourceOut_ptr_ptr,    /*out*/
+        uint32_t         *sourceOutSize_ptr,    /*in/out*/
+        uint32_t         *rndWorkBuff_ptr,      /*in*/
+        bool              isFipsSupported)      /*in*/
+{
+        /* LOCAL DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t error = 0;
+        int32_t  i;
+#ifndef USE_MBEDTLS_CRYPTOCELL
+        uint32_t tmp;
+#endif
+        uint32_t roscToStart;
+        uint32_t *ramAddr;
+        uint32_t trngBuff[LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE * LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS] = { 0 }; /* 2 EHR required */
+        CC_UNUSED_PARAM(entropySize_ptr);
+
+        /* Lock mutex, check fatal err, and increase cc counter*/
+        MUTEX_LOCK_AND_RETURN_UPON_ERROR(pCCRndCryptoMutex);
+
+        CC_IS_FATAL_ERR_ON(error);
+        if (error == CC_TRUE) {
+                error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
+                goto EndUnlockMutex;
+        }
+
+        INCREASE_CC_COUNTER
+        /* FUNCTION LOGIC */
+
+        /* ............... local initializations .............................. */
+        /* -------------------------------------------------------------------- */
+
+        /* initializing the Error to O.K */
+        error = CC_OK;
+
+        /* Set source RAM address with offset 8 bytes from sourceOut address in
+          order to remain empty bytes for CC operations */
+        *sourceOut_ptr_ptr = rndWorkBuff_ptr;
+        ramAddr = *sourceOut_ptr_ptr + CC_RND_TRNG_SRC_INNER_OFFSET_WORDS;
+        /* init to 0 for FE mode */
+        *sourceOutSize_ptr = 0;
+#ifndef USE_MBEDTLS_CRYPTOCELL
+        /* Case of RND KAT or TRNG KAT testing  */
+        if ((rndState_ptr->StateFlag & CC_RND_KAT_DRBG_Mode) ||
+                (rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode)) {
+                /* set source sizes given by the user in KAT test and placed
+                   in the rndWorkBuff with offset CC_RND_SRC_BUFF_OFFSET_WORDS */
+                *sourceOutSize_ptr = (*sourceOut_ptr_ptr)[0];
+                if (*sourceOutSize_ptr == 0) {
+                        error = CC_RND_KAT_DATA_PARAMS_ERROR;
+                        goto End;
+                }
+
+                /* Go to Estimator */
+                if (rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode) {
+                        /* Assumed, that KAT data is set in the rnd Work      *
+                           buffer as follows:                     *
+                           - full source size set in buffer[0],           *
+                           - count blocks set in buffer[1],               *
+                           *  - KAT source begins from buffer[2].         */
+                        tmp = (*sourceOut_ptr_ptr)[1]; /*count blocks for estimation*/
+                        if (tmp == 0) {
+                                error = CC_RND_KAT_DATA_PARAMS_ERROR;
+                                goto End;
+                        }
+                        error = CC_RND_TRNG_KAT_NOT_SUPPORTED_ERROR;
+                        goto End;
+                        //goto Estimator;
+                }
+                else {
+                        goto End;
+                }
+        }
+#endif
+        /* If not continued mode, set TRNG parameters and restart TRNG  */
+        /*--------------------------------------------------------------*/
+        if (isContinued == CC_FALSE) {
+#ifndef USE_MBEDTLS_CRYPTOCELL
+                /* Set instantiation, TRNG errors and time   *
+                * exceeding bits of State to 0           */
+                rndState_ptr->StateFlag &= ~(CC_RND_INSTANTIATED |
+                        CC_RND_INSTANTRESEED_AUTOCORR_ERRORS |
+                        CC_RND_INSTANTRESEED_TIME_EXCEED |
+                        CC_RND_INSTANTRESEED_LESS_ENTROPY);
+#endif
+                /* Full restart TRNG */
+                error = LLF_RND_StartTrngHW(
+                        rndState_ptr,
+                        trngParams_ptr,
+                        CC_TRUE/*isRestart*/,
+                        &roscToStart);
+
+                /*Note: in case of error the TRNG HW is still not started*/
+                if (error) {
+                        goto End;
+                }
+        }
+        /* On continued mode check HW TRNG */
+        else {
+                /* check TRNG parameters */
+                error = LLF_RND_TRNG_CheckHwParams(trngParams_ptr);
+                if (error != CC_OK)
+                        goto End;
+
+                /* previously started ROSCs */
+                roscToStart = (rndState_ptr->TrngProcesState & 0xff000000) >> 24;
+        }
+
+        /*====================================================*/
+        /*====================================================*/
+        /*         Processing after previous start            */
+        /*====================================================*/
+        /*====================================================*/
+
+        /*====================================================*/
+        /* FE mode processing: start Roscs sequentially -   *
+        * from fast to slow Rosc                  */
+        /*====================================================*/
+
+        for (i = 0; i < LLF_RND_NUM_OF_ROSCS; ++i) {
+
+                /* read the first EHR */
+                error = LLF_RND_TRNG_ReadEhrData(trngBuff, isFipsSupported);
+                if (error == CC_OK) {
+                        /* read the second EHR */
+                        LLF_RND_TRNG_EnableRngSourceAndWatchdog(trngParams_ptr);
+                        error = LLF_RND_TRNG_ReadEhrData(trngBuff + LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS, isFipsSupported);
+                        if (error == CC_OK) {
+                                break;
+                        }
+                }
+                if (error == LLF_RND_CRNGT_TEST_FAIL_ERROR) {
+                        /* LLF_RND_CRNGT_TEST_FAIL_ERROR is set only in FIPS mode. do not continue to the next rosc. */
+                        break;
+                }
+                if (error != CC_OK) {/* try next rosc */
+                        /*  if no remain roscs to start, return error */
+                        if (roscToStart == 0x8) {
+                                error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
+                                break;
+                        }
+                        else {
+                                /* Call StartTrng, with next ROSC */
+                                roscToStart <<= 1;
+                                error = LLF_RND_StartTrngHW(
+                                        rndState_ptr,
+                                        trngParams_ptr,
+                                        CC_FALSE/*isRestart*/,
+                                        &roscToStart);
+
+                                /* if no remain valid roscs, return error */
+                                if (error == LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR && (trngParams_ptr->RoscsAllowed != 0)) {
+
+                                        error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
+                                }
+
+                                if (error != CC_OK) {
+                                        goto End;
+                                }
+                        }
+                }
+
+
+                /* update total processed ROSCs */
+                rndState_ptr->TrngProcesState |= ((rndState_ptr->TrngProcesState >> 8) & 0x00FF0000);
+                /*clean started & not processed*/
+                rndState_ptr->TrngProcesState &= 0x00FFFFFF;
+
+        }
+
+        if (error == CC_OK) {
+                CC_PalMemCopy(ramAddr, trngBuff, LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE * LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES);
+                *sourceOutSize_ptr = LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE * LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES;
+        }
+
+        /* end FE mode */
+
+        /* ................. end of function ..................................... */
+        /* ----------------------------------------------------------------------- */
+End:
+
+        /* turn the RNG off    */
+#ifndef USE_MBEDTLS_CRYPTOCELL
+
+        if ((rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode) == 0) {
+                LLF_RND_TurnOffTrng();
+        }
+#else
+        LLF_RND_TurnOffTrng();
+
+#endif
+
+        /* release mutex and decrease CC counter */
+        DECREASE_CC_COUNTER
+
+EndUnlockMutex:
+        MUTEX_UNLOCK(pCCRndCryptoMutex);
+
+
+        return error;
+
+
+}/* END of LLF_RND_GetTrngSource */
+
+CCError_t LLF_RND_RunTrngStartupTest(
+        CCRndState_t        *rndState_ptr,
+        CCRndParams_t       *trngParams_ptr,
+        uint32_t                *rndWorkBuff_ptr)
+{
+    CCError_t error = CC_OK;
+    CC_UNUSED_PARAM(rndState_ptr);
+        CC_UNUSED_PARAM(trngParams_ptr);
+        CC_UNUSED_PARAM(rndWorkBuff_ptr);
+
+    return error;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_hwdefs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_hwdefs.h
new file mode 100644
index 0000000..e197c79
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_hwdefs.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef LLF_RND_HW_DEFS_H
+#define LLF_RND_HW_DEFS_H
+
+
+/************************ Defines ******************************/
+
+/* SRAM base address */
+extern uint32_t g_MemOffsetAddr;
+
+/* The number of words generated in the entropy holding register (EHR)
+   6 words (192 bit) according to HW implementation */
+#define LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS  6
+#define LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES  (LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS * sizeof(uint32_t))
+#define LLF_RND_HW_TRNG_EHR_WIDTH_IN_BITS       (8*LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES)
+
+/* ring oscillator length maximal level */
+#define LLF_RND_HW_TRNG_ROSC_LENGTH_MASK       0x0f
+
+/* ring oscillator offsets and numbers */
+#define LLF_RND_HW_TRNG_ROSC0_BIT       0x1
+#define LLF_RND_HW_TRNG_ROSC1_BIT       0x2
+#define LLF_RND_HW_TRNG_ROSC2_BIT       0x4
+#define LLF_RND_HW_TRNG_ROSC3_BIT       0x8
+#define LLF_RND_HW_TRNG_ROSC0_NUM       0x0
+#define LLF_RND_HW_TRNG_ROSC1_NUM       0x1
+#define LLF_RND_HW_TRNG_ROSC2_NUM       0x2
+#define LLF_RND_HW_TRNG_ROSC3_NUM       0x3
+
+/* TRNG_CONFIG value for SRC_SEL = 0, SOP_SEL = 1 (SOP = TRNG EHR output)*/
+#define LLF_RND_HW_TRNG_WITH_DMA_CONFIG_VAL    0x4
+
+/* HW_TRNG registers values on FE mode */
+/*---------------------------------------*/
+#define LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_FE_MODE  0x00000000
+#define LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_FE_MODE  2UL /*for both AES128 and AES256*/
+
+/* HW_TRNG registers values on 800-90b mode */
+/*---------------------------------------*/
+#define LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_TRNG90B_MODE  0x0000000A  /* bypass Von-Neumann balancer and autocorrelation test */
+#define LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_TRNG90B_MODE  22UL
+
+/* HW RND DMA SRAM address offset, bytes */
+
+#define LLF_RND_HW_RND_DMA_ENABLE_VAL       1UL
+#define LLF_RND_HW_RND_DMA_DISABLE_VAL          0UL
+#define LLF_RND_HW_RND_SRC_ENABLE_VAL       1UL
+#define LLF_RND_HW_RND_SRC_DISABLE_VAL          0UL
+#define LLF_RND_HW_RND_CLK_ENABLE_VAL       1UL
+#define LLF_RND_HW_RND_CLK_DISABLE_VAL      0UL
+
+/* currently DX_RNG_ISR_RNG_WATCHDOG_BIT (bit 4 in RNG_ISR) is not defined in dx_rng.h */
+#define DX_RNG_ISR_RNG_WATCHDOG_BIT_SHIFT       0x4UL
+#define DX_RNG_ISR_RNG_WATCHDOG_BIT_SIZE        0x1UL
+
+/*
+   LLF_RND_TRNG_MAX_TIME_COEFF - scaled coefficient, defining relation of
+   maximal allowed time for TRNG generation (per one ROSC) expected minimal
+   time: MaxAllowedTime = (ExpectTime*LLF_RND_TRNG_MAX_TIME_COEFF) / 64, where
+   64 = (1<<6) is a scaling coefficient.
+   Example: if LLF_RND_TRNG_MAX_TIME_COEFF = 128, then MaxAllowedTime =
+   2*ExpectTime.
+*/
+#define LLF_RND_TRNG_MAX_TIME_SCALE         6   /* scaling down by 64 */
+#define LLF_RND_TRNG_MAX_TIME_COEFF       128   /* preferable set value as power of 2  */
+#define LLF_RND_TRNG_VON_NEUMAN_COEFF       4   /* increases time because part of bits are rejected */
+
+
+/* RNG interrupt masks */
+/* on trng90b DMA mode masked bits: DMA_DONE, CTRNGT;
+   unmasked:  AutoCorrT, VNT EHR, other bits masked: 0xFFFFFFE4*/
+#define LLF_RNG_INT_MASK_ON_TRNG90B_MODE  0xFFFFFFE
+
+/* on FE mode: masked all bits besides - EHR_VALID, AUTOCORR_ERR, and WATCHDOG: 0xFFFFFFEC */
+#define LLF_RNG_INT_MASK_ON_FETRNG_MODE  0xFFFFFFEC
+
+/* TRNG errors mask - masking all bits besides TRNG errors: AutoCorr + VN +   *
+*  Watchdog                                       */
+#define LLF_RNG_ERRORS_MASK \
+                ((1UL<<DX_RNG_IMR_AUTOCORR_ERR_INT_MASK_BIT_SHIFT) | \
+         (1UL<<DX_RNG_IMR_VN_ERR_INT_MASK_BIT_SHIFT)       | \
+         (1UL<<DX_RNG_IMR_WATCHDOG_INT_MASK_BIT_SHIFT))
+
+/* auxilary defines */
+#define DX_SEP_HW_RESET_SEED_OVERRIDE_FLAG     0x2Ul
+
+
+
+/*********************** Macros ********************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_trng.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_trng.h
new file mode 100644
index 0000000..c3564f5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_trng.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef LLF_RND_TRNG_H
+#define LLF_RND_TRNG_H
+
+
+#include "dx_rng.h"
+#include "cc_pal_mem.h"
+#include "cc_general_defs.h"
+#include "dx_crys_kernel.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_plat.h"
+#include "cc_rnd_common.h"
+#include "llf_rnd.h"
+
+#define LLF_RND_NUM_OF_ROSCS    4
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/******************** Public Functions *************************/
+
+/****************************************************************************************/
+/**
+ * @brief The function starts the TRNG with given parameters and ROSCs lengths
+ *
+ *      NOTE: It is assumed, that before calling this function, the previously
+ *            started TRNG processes were compleated and Interrupts cleared.
+ *
+ *      Algorithm:
+ *      1. If is continued mode, the function does:
+ *              checks actual parameters, loaded in TRNG registers,
+ *              vs. user given parameters; if any not matchs - returns Error.
+ *         Else /do restart/:
+ *          sets ROSCs to start: for "SWEE" - all allowed, for "FE" -
+ *          fastest from allowed; gets the user given parameters and sets
+ *          them in the HW, starts the TRNG clocks and sets TRNG parameters
+ *          into HW registers.
+ *      2. Initializes the RND DMA according to ROSCs required to start,
+ *         initializes the TRNG Interrupt. Enables RNG source.
+ *      3. Exits.
+ *
+ * @param[in/out] rndContext_ptr - The pointer to the internal State buffer of DRNG.
+ * @param[in/out] trngParams_ptr - The pointer to structure, containing TRNG parameters.
+ * @isContinued[in] isRestart - The variable indicates is a restart required or not.
+ * @roscsToStart[in] roscsToStart_ptr - The variable, defining which ROSCs to
+ *                      start according to bits set: b'0...b'3. When
+ *                      isRestart=TRUE, then:
+ *                      for "swee" - starts all allowed ROSCs, for
+ *                      "fe" - starts fastest ROSC from allowed.
+ *                      Note: if isRestart = 1, then
+ *
+ *
+ * @return CCError_t - no return value
+ */
+CCError_t LLF_RND_StartTrngHW(
+                   CCRndState_t  *rndState_ptr,
+                   CCRndParams_t *trngParams_ptr,
+                   CCBool_t           isRestart,
+                   uint32_t         *roscsToStart_ptr);
+
+/*******************************************************************************/
+/**
+ * @brief The LLF_RND_GetTrngSource reads random source of needed size from TRNG.
+ *
+ *        The function is used in Self, Instantiation and Reseeding functions.
+ *
+ * @param[in/out] rndContext_ptr - The pointer to the internal State buffer of DRNG.
+ * @param[in/out] trngParams_ptr - The pointer to structure, containing TRNG parameters.
+ * @isContinued[in] isContinued - The variable indicates is the required process should
+ *                  continue a  previous one or restart TRNG.
+ * @entropySize_ptr[in/out] - The pointer to size of entropy in bits: input - required,
+ *                            output - actual size.
+ * @sourceOut_ptr_ptr[out] - The pointer to to pointer to the entropy source buffer.
+ *                   The buffer contains one empty word for using by CC level
+ *                   and then buffer for output the rng source.
+ * @param[out] - sourceOutSize_ptr - The pointer to the size in bytes of entropy source
+ *                      in - required size, output - actual size.
+ * @param[in/out] - rndWorkBuff_ptr - The pointer to the temp buffer for allocation of
+ *                     estimator buffers.
+ * @param[in] - isFipsSupported - indication if FIPS is supported.
+ *
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+CCError_t LLF_RND_GetTrngSource(
+                 CCRndState_t  *rndState_ptr,      /*in/out*/
+                 CCRndParams_t  *trngParams_ptr,   /*in/out*/
+                 CCBool_t            isContinued,    /*in*/
+                 uint32_t         *entropySize_ptr,  /*in/out*/
+                 uint32_t         **sourceOut_ptr_ptr, /*out*/
+                 uint32_t         *sourceOutSize_ptr,/*in/out*/
+                 uint32_t         *rndWorkBuff_ptr,      /*in*/
+                 bool              isFipsSupported);      /*in*/
+
+/*******************************************************************************/
+/**
+ * @brief The LLF_RND_RunTrngStartupTest runs the startup tests required for TRNG.
+ *
+ * @param[in/out] rndContext_ptr - The pointer to the internal State buffer of DRNG.
+ * @param[out] trngParams_ptr - The pointer to structure, containing TRNG parameters.
+ * @param[in/out] - rndWorkBuff_ptr - The pointer to the temp buffer for allocation of
+ *                     estimator buffers.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+CCError_t LLF_RND_RunTrngStartupTest(
+                      CCRndState_t *rndState_ptr,   /*in/out*/
+                                      CCRndParams_t *trngParams_ptr,   /*out*/
+                      uint32_t          *rndWorkBuff_ptr);  /*in*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  // LLF_RND_TRNG_H
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_trng90b.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_trng90b.c
new file mode 100644
index 0000000..ce3e9e4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/llf_rnd_trng90b.c
@@ -0,0 +1,733 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include "dx_rng.h"
+#include "cc_pal_mem.h"
+#include "cc_plat.h"
+#include "dx_crys_kernel.h"
+#include "cc_hal.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_rnd_error.h"
+#include "llf_rnd_hwdefs.h"
+#include "llf_rnd.h"
+#include "llf_rnd_error.h"
+#include "cc_sram_map.h"
+#include "llf_rnd_trng.h"
+#include "cc_config_trng90b.h"
+#include "cc_int_general_defs.h"
+
+#ifndef CMPU_UTIL
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_util_pm.h"
+#endif
+
+#define ROSC_INIT_START_BIT   0x80000000
+
+#define LLF_RND_TRNG90B_MAX_BYTES ( LLF_RND_HW_DMA_EHR_SAMPLES_NUM_ON_TRNG90B_MODE * LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES)
+#define CC_CONFIG_TRNG90B_ADAPTIVE_PROPORTION_WINDOW_SIZE      1024     // binary noise source
+
+#if !defined(CMPU_UTIL) && !defined(SC_TEST_MODE)
+extern CC_PalMutex *pCCRndCryptoMutex;
+
+#define MUTEX_LOCK_AND_RETURN_UPON_ERROR(pmutex) \
+        if (CC_PalMutexLock(pmutex, CC_INFINITE) != CC_SUCCESS) { \
+            CC_PalAbort("Fail to acquire mutex\n"); \
+        }
+
+#define MUTEX_UNLOCK(pmutex) \
+        if (CC_PalMutexUnlock(pmutex) != CC_SUCCESS) { \
+            CC_PalAbort("Fail to release mutex\n"); \
+        }
+
+#define DECREASE_CC_COUNTER \
+        if (CC_IS_IDLE != CC_SUCCESS) { \
+            CC_PalAbort("Fail to decrease PM counter\n"); \
+        }
+
+#define INCREASE_CC_COUNTER \
+        if (CC_IS_WAKE != CC_SUCCESS) { \
+            CC_PalAbort("Fail to increase PM counter\n"); \
+        }
+
+#else
+#define MUTEX_LOCK_AND_RETURN_UPON_ERROR(mutex)
+#define MUTEX_UNLOCK(mutex)
+#define DECREASE_CC_COUNTER
+#define INCREASE_CC_COUNTER
+#endif
+
+/*********************************** Enums ******************************/
+/*********************************Typedefs ******************************/
+
+/**************** Global Data to be read by RNG function ****************/
+
+/* test variables */
+#ifdef RND_TEST_TRNG_WITH_ESTIMATOR
+uint32_t  gEntrSize[4];
+#endif
+
+
+/******************************************************************************/
+/***************   Prototypes and Private functions    ************************/
+/******************************************************************************/
+static CCError_t startTrngHW(
+        CCRndState_t  *rndState_ptr,
+        CCRndParams_t *trngParams_ptr,
+        CCBool_t           isRestart,
+        uint32_t          *roscsToStart_ptr,
+        CCBool_t           isStartup);
+static CCError_t getTrngSource(CCRndState_t  *rndState_ptr,
+                 CCRndParams_t  *trngParams_ptr,
+                 CCBool_t            isContinued,
+                 uint32_t        **sourceOut_ptr_ptr,
+                 uint32_t         *sourceOutSize_ptr,
+                 uint32_t         *rndWorkBuff_ptr,
+                 CCBool_t          isStartup);
+static CCError_t runContinuousTesting(uint32_t* pData, uint32_t sizeInBytes, CCRndParams_t  *trngParams_ptr);
+CCError_t LLF_RND_RepetitionCounterTest(uint32_t* pData, uint32_t sizeInBytes, uint32_t C);
+CCError_t LLF_RND_AdaptiveProportionTest(uint32_t* pData, uint32_t sizeInBytes, uint32_t C, uint32_t W);
+static CCError_t LLF_RND_TRNG_ReadMultipleEHR(uint32_t inSize, uint8_t *ramAddr,
+                                    CCRndState_t  *rndState_ptr,
+                                    CCRndParams_t *trngParams_ptr,
+                                    uint32_t *roscsToStart_ptr);
+static int32_t LLF_RND_TRNG_ReadEhrData(uint32_t *sample,
+                            CCRndState_t  *rndState_ptr,
+                            CCRndParams_t *trngParams_ptr,
+                            uint32_t *roscsToStart_ptr);
+static uint32_t LLF_RND_TRNG_RoscMaskToNum(uint32_t mask);
+static void LLF_RND_TRNG_EnableRngSourceAndWatchdog(CCRndParams_t *trngParams_ptr, CCBool_t isStartup);
+
+
+/************************************************************************************/
+/**
+ * The function checks that parameters, loaded in the TRNG HW
+ * are match to parameters, required by trngParams_ptr structures.
+ *
+ * @author reuvenl (6/25/2012)
+ *
+ * @param trngParams_ptr
+ *
+ * @return CCError_t
+ */
+static CCError_t LLF_RND_TRNG_CheckHwParams(CCRndParams_t *trngParams_ptr)
+{
+    uint32_t temp;
+    CCBool_t isTrue = CC_TRUE;
+
+    /* check Debug control - masked TRNG tests according to mode */
+    temp = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, TRNG_DEBUG_CONTROL));
+    isTrue &= (temp == LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_TRNG90B_MODE);
+    /* check samplesCount */
+    temp = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG,SAMPLE_CNT1));
+    isTrue &= (temp == trngParams_ptr->SubSamplingRatio);
+
+    /* if any parameters are not match return an Error */
+    if (isTrue == CC_FALSE)
+        return LLF_RND_TRNG_PREVIOUS_PARAMS_NOT_MATCH_ERROR;
+    else
+        return CC_OK;
+}
+
+/****************************************************************************************/
+/*****************************       Public Functions      ******************************/
+/****************************************************************************************/
+
+CCError_t LLF_RND_StartTrngHW(
+        CCRndState_t  *rndState_ptr,
+        CCRndParams_t *trngParams_ptr,
+        CCBool_t           isRestart,
+        uint32_t         *roscsToStart_ptr)
+{
+        CCError_t error = CC_OK;
+        error = startTrngHW(rndState_ptr, trngParams_ptr, isRestart, roscsToStart_ptr, CC_FALSE/*isStartup*/);
+
+        return error;
+}
+
+
+CCError_t LLF_RND_GetTrngSource(
+                 CCRndState_t  *rndState_ptr,      /*in/out*/
+                 CCRndParams_t  *trngParams_ptr,   /*in/out*/
+                 CCBool_t            isContinued,    /*in*/
+                 uint32_t         *entropySize_ptr,  /*in/out*/
+                 uint32_t        **sourceOut_ptr_ptr,   /*out*/
+                 uint32_t         *sourceOutSize_ptr,/*in/out*/
+                 uint32_t         *rndWorkBuff_ptr,      /*in*/
+                 bool              isFipsSupported)      /*in*/
+{
+    CCError_t error = CC_OK;
+
+    CC_UNUSED_PARAM(entropySize_ptr);
+    CC_UNUSED_PARAM(isFipsSupported);
+
+    /* Lock mutex, check fatal err, and increase cc counter*/
+    MUTEX_LOCK_AND_RETURN_UPON_ERROR(pCCRndCryptoMutex);
+
+    CC_IS_FATAL_ERR_ON(error);
+    if (error == CC_TRUE) {
+            error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
+            goto EndUnlockMutex;
+    }
+
+    INCREASE_CC_COUNTER
+
+    /*Function Logic:*/
+    error = getTrngSource(rndState_ptr, trngParams_ptr, isContinued,
+                  sourceOut_ptr_ptr, sourceOutSize_ptr, rndWorkBuff_ptr, CC_FALSE/* isStartup*/);
+
+    /* release mutex and decrease CC counter */
+    DECREASE_CC_COUNTER
+
+EndUnlockMutex:
+    MUTEX_UNLOCK(pCCRndCryptoMutex);
+    return error;
+}
+
+CCError_t LLF_RND_RunTrngStartupTest(
+        CCRndState_t        *rndState_ptr,
+        CCRndParams_t       *trngParams_ptr,
+        uint32_t                *rndWorkBuff_ptr)
+{
+    CCError_t error = CC_OK;
+
+    uint32_t        *pSourceOut;
+    uint32_t         sourceOutSize;
+
+        error = getTrngSource(rndState_ptr, trngParams_ptr, CC_FALSE/*isContinued*/,
+                  &pSourceOut, &sourceOutSize, rndWorkBuff_ptr, CC_TRUE/* isStartup*/);
+
+    return error;
+}
+
+static CCError_t startTrngHW(
+        CCRndState_t  *rndState_ptr,
+        CCRndParams_t *trngParams_ptr,
+        CCBool_t          isRestart,
+        uint32_t         *roscsToStart_ptr,
+    CCBool_t      isStartup)
+{
+        /* LOCAL DECLARATIONS */
+
+        CCError_t error = CC_OK;
+        uint32_t tmpSamplCnt = 0;
+        uint32_t roscNum = 0;
+#ifdef CC_IOT
+        uint32_t mask = 0;
+#endif
+        /* FUNCTION LOGIC */
+
+        /* Check pointers */
+        if ((rndState_ptr == NULL) || (trngParams_ptr == NULL) ||
+                (roscsToStart_ptr == NULL))
+                return LLF_RND_TRNG_ILLEGAL_PTR_ERROR;
+
+
+        /*--------------------------------------------------------------*/
+        /* 1. If full restart, get semaphore and set initial ROSCs      */
+        /*--------------------------------------------------------------*/
+        if (isRestart) {
+                /* set ROSC to 1 (fastest)  */
+                *roscsToStart_ptr = 1UL;
+
+                /* init rndState flags to zero */
+                rndState_ptr->TrngProcesState = 0;
+        }
+
+
+        if (*roscsToStart_ptr == 0)
+                return LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
+
+
+        /* Get fastest allowed ROSC */
+        error = LLF_RND_GetFastestRosc(
+                trngParams_ptr,
+                roscsToStart_ptr     /*in/out*/);
+        if (error)
+                return error;
+
+        error = LLF_RND_GetRoscSampleCnt(*roscsToStart_ptr, trngParams_ptr);
+        if (error)
+                return error;
+
+        roscNum = LLF_RND_TRNG_RoscMaskToNum(*roscsToStart_ptr);
+
+        /* 2. Restart the TRNG and set parameters and enable the HW RND clock   */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_ENABLE_VAL);
+
+        /* do software reset */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_SW_RESET), 0x1);
+        /* in order to verify that the reset has completed the sample count need to be verified */
+        do {
+                /* enable the HW RND clock   */
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_CLK_ENABLE), LLF_RND_HW_RND_CLK_ENABLE_VAL);
+
+                /* set sampling ratio (rng_clocks) between consecutive bits */
+                CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, SAMPLE_CNT1), trngParams_ptr->SubSamplingRatio);
+
+                /* read the sampling ratio  */
+                tmpSamplCnt = CC_HAL_READ_REGISTER(CC_REG_OFFSET(RNG, SAMPLE_CNT1));
+
+        } while (tmpSamplCnt != trngParams_ptr->SubSamplingRatio);
+
+
+        /* disable the RND source for setting new parameters in HW */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_DISABLE_VAL);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_ICR), 0xFFFFFFFF);
+
+        /* set interrupt mask */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_IMR), LLF_RNG_INT_MASK_ON_TRNG90B_MODE);
+
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, TRNG_CONFIG), roscNum);
+
+#ifdef CC_IOT
+        /* mask RNG_INT - this interrupt should be polled upon,
+         * and not handled by the operating system's interrupt handler. */
+        mask = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR));
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, RNG_INT_MASK, mask, 1);
+        CC_HalMaskInterrupt(mask);
+#endif
+
+        /* Debug Control register: set to 0 - no bypasses */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, TRNG_DEBUG_CONTROL), LLF_RND_HW_DEBUG_CONTROL_VALUE_ON_TRNG90B_MODE);
+
+        LLF_RND_TRNG_EnableRngSourceAndWatchdog(trngParams_ptr, isStartup);
+
+        /* set indication about current started ROSCs:  */
+        /*new started*/
+        rndState_ptr->TrngProcesState = (rndState_ptr->TrngProcesState & 0x00ffffff) | (*roscsToStart_ptr << 24);
+        /*total started*/
+        rndState_ptr->TrngProcesState |= (*roscsToStart_ptr << 8);
+
+        return error;
+}
+
+
+
+
+static uint32_t LLF_RND_TRNG_RoscMaskToNum(uint32_t mask)
+{
+        return (mask == LLF_RND_HW_TRNG_ROSC3_BIT) ? LLF_RND_HW_TRNG_ROSC3_NUM :
+                (mask == LLF_RND_HW_TRNG_ROSC2_BIT) ? LLF_RND_HW_TRNG_ROSC2_NUM :
+                (mask == LLF_RND_HW_TRNG_ROSC1_BIT) ? LLF_RND_HW_TRNG_ROSC1_NUM :
+                LLF_RND_HW_TRNG_ROSC0_NUM;
+}
+
+static CCError_t getTrngSource(
+                CCRndState_t  *rndState_ptr,      /*in/out*/
+                CCRndParams_t  *trngParams_ptr,   /*in/out*/
+                CCBool_t            isContinued,    /*in*/
+                uint32_t        **sourceOut_ptr_ptr,   /*out*/
+                uint32_t         *sourceOutSize_ptr,/*in/out*/
+                uint32_t         *rndWorkBuff_ptr,     /*in*/
+                CCBool_t          isStartup)           /*in*/
+{
+    /* LOCAL DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t error = 0;
+    int32_t  i;
+    uint32_t roscToStart;
+    uint32_t *ramAddr;
+    uint32_t trng90bRequiredBytes;
+
+    /* FUNCTION LOGIC */
+    /* ............... local initializations .............................. */
+    /* -------------------------------------------------------------------- */
+
+    /* initializing the Error to O.K */
+    error = CC_OK;
+
+    if(isStartup == CC_FALSE) {
+        trng90bRequiredBytes = trngParams_ptr->userParams.trngModeParams.numOfBytes;
+    } else {
+        trng90bRequiredBytes = CC_CONFIG_TRNG90B_AMOUNT_OF_BYTES_STARTUP;
+    }
+
+    /* Set source RAM address with offset 8 bytes from sourceOut address in
+      order to remain empty bytes for CC operations */
+    *sourceOut_ptr_ptr = rndWorkBuff_ptr + CC_RND_SRC_BUFF_OFFSET_WORDS;
+    ramAddr = *sourceOut_ptr_ptr + CC_RND_TRNG_SRC_INNER_OFFSET_WORDS;
+
+    /* init to 0 for FE mode */
+    *sourceOutSize_ptr = 0;
+#ifndef USE_MBEDTLS_CRYPTOCELL
+    /* Case of RND KAT or TRNG KAT testing  */
+    if (rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode) {
+        return CC_RND_KAT_DATA_PARAMS_ERROR;
+    }
+
+    if (rndState_ptr->StateFlag & CC_RND_KAT_DRBG_Mode) {
+
+        /* set source sizes given by the user in KAT test and placed
+           in the rndWorkBuff with offset CC_RND_SRC_BUFF_OFFSET_WORDS */
+        *sourceOutSize_ptr = (*sourceOut_ptr_ptr)[0];
+        if (*sourceOutSize_ptr == 0) {
+            return CC_RND_KAT_DATA_PARAMS_ERROR;
+        }
+        goto End;
+    }
+#endif
+    /* If not continued mode, set TRNG parameters and restart TRNG  */
+    /*--------------------------------------------------------------*/
+    if (isContinued == CC_FALSE) {
+
+        /* Set instantiation, TRNG errors and time   *
+        * exceeding bits of State to 0           */
+#ifndef USE_MBEDTLS_CRYPTOCELL
+        rndState_ptr->StateFlag &= ~(CC_RND_INSTANTIATED |
+                         CC_RND_INSTANTRESEED_AUTOCORR_ERRORS |
+                         CC_RND_INSTANTRESEED_TIME_EXCEED |
+                         CC_RND_INSTANTRESEED_LESS_ENTROPY);
+#endif
+        /* Full restart TRNG */
+                error = startTrngHW(
+                       rndState_ptr,
+                       trngParams_ptr,
+                       CC_TRUE/*isRestart*/,
+                       &roscToStart,
+                       isStartup);
+
+        /*Note: in case of error the TRNG HW is still not started*/
+        if (error)
+            goto End;
+    }
+
+    /* On continued mode check HW TRNG */
+    else {
+        /* check TRNG parameters */
+        error = LLF_RND_TRNG_CheckHwParams(trngParams_ptr);
+        if (error != CC_OK){
+                goto End;
+        }
+
+        /* previously started ROSCs */
+        roscToStart = (rndState_ptr->TrngProcesState & 0xff000000)>>24;
+    }
+
+    /*====================================================*/
+    /*====================================================*/
+    /*         Processing after previous start            */
+    /*====================================================*/
+    /*====================================================*/
+
+    /*====================================================*/
+    /* TRNG90b mode processing: start Roscs sequentionally - *
+    * from fast to slow Rosc                  */
+    /*====================================================*/
+
+    for (i = 0; i < LLF_RND_NUM_OF_ROSCS; ++i) {
+        *sourceOutSize_ptr = trng90bRequiredBytes;
+
+        error = LLF_RND_TRNG_ReadMultipleEHR(*sourceOutSize_ptr, (uint8_t *)ramAddr,
+                        rndState_ptr,
+                        trngParams_ptr,
+                        &roscToStart);
+
+        if (error == CC_OK) {
+            error = runContinuousTesting(ramAddr, trng90bRequiredBytes, trngParams_ptr);
+            if (error == CC_OK) {
+                break;
+            }
+            *sourceOutSize_ptr = 0;
+        }
+        if (error == LLF_RND_CRNGT_TEST_FAIL_ERROR) {
+            /* LLF_RND_CRNGT_TEST_FAIL_ERROR is set only in FIPS mode. do not continue to the next rosc. */
+            break;
+        }
+        if (error != CC_OK) {/* try next rosc */
+            /*  if no remain roscs to start, return error */
+            if (roscToStart == 0x8) {
+                error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
+                break;
+            }
+            else {
+                /* Call StartTrng, with next ROSC */
+                roscToStart <<= 1;
+                error = LLF_RND_StartTrngHW(
+                    rndState_ptr,
+                    trngParams_ptr,
+                    CC_FALSE/*isRestart*/,
+                    &roscToStart);
+
+                /* if no remain valid roscs, return error */
+                if (error == LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR && (trngParams_ptr->RoscsAllowed != 0)) {
+
+                    error = LLF_RND_TRNG_GENERATION_NOT_COMPLETED_ERROR;
+                }
+
+                if (error != CC_OK) {
+                    goto End;
+                }
+            }
+        }
+
+
+        /* update total processed ROSCs */
+        rndState_ptr->TrngProcesState |= ((rndState_ptr->TrngProcesState >> 8) & 0x00FF0000);
+        /*clean started & not processed*/
+        rndState_ptr->TrngProcesState &= 0x00FFFFFF;
+    }
+
+    /* ................. end of function ..................................... */
+    /* ----------------------------------------------------------------------- */
+    End:
+
+    CLEAR_TRNG_SRC();
+    /* turn the RNG off    */
+#ifndef USE_MBEDTLS_CRYPTOCELL
+    if ((rndState_ptr->StateFlag & CC_RND_KAT_TRNG_Mode) == 0) {
+        LLF_RND_TurnOffTrng();
+    }
+#else
+    LLF_RND_TurnOffTrng();
+#endif
+
+    return error;
+}/* END of getTrngSource */
+
+
+/*
+implementation of Continuous Testing (NIST SP 800-90B 6.5.1.2)
+*/
+
+static CCError_t runContinuousTesting(uint32_t* pData,
+                                      uint32_t sizeInBytes,
+                                      CCRndParams_t  *trngParams_ptr)
+{
+    CCError_t error = CC_OK;
+    uint32_t repC = trngParams_ptr->userParams.trngModeParams.repetitionCounterCutoff;
+    uint32_t adpW = CC_CONFIG_TRNG90B_ADAPTIVE_PROPORTION_WINDOW_SIZE;
+    uint32_t adpC = trngParams_ptr->userParams.trngModeParams.adaptiveProportionCutOff;
+
+
+    error = LLF_RND_RepetitionCounterTest(pData, sizeInBytes, repC);
+    if (error != CC_OK) {
+        return error;
+    }
+        error = LLF_RND_AdaptiveProportionTest(pData, sizeInBytes, adpC, adpW);
+    if (error != CC_OK) {
+        return error;
+    }
+
+        return CC_OK;
+}
+
+#define UINT8_SIZE_IN_BITS  8
+#define UINT32_SIZE_IN_BITS (sizeof(uint32_t) * UINT8_SIZE_IN_BITS)
+static uint32_t getBitsFromUint32Array(uint32_t arrayBitsOffset, uint32_t numOfBits, uint32_t* arr)
+{
+    uint32_t res = 0;
+    uint32_t byteOffset = arrayBitsOffset / UINT32_SIZE_IN_BITS;
+    uint32_t bitOffset = arrayBitsOffset % UINT32_SIZE_IN_BITS;
+    if (numOfBits > UINT32_SIZE_IN_BITS) {
+        return 0;
+    }
+    res = arr[byteOffset] >> bitOffset;
+    // (UINT32_SIZE_IN_BITS - bitOffset) bits were taken from the first dword.
+
+    if (UINT32_SIZE_IN_BITS - bitOffset > numOfBits)
+    // we copied more bits than required. zero the extra bits.
+    {
+        res &= (0xFFFFFFFF >> (UINT32_SIZE_IN_BITS - numOfBits));
+    } else if (UINT32_SIZE_IN_BITS - bitOffset < numOfBits)
+    // we copied less bits than required. copy the next bits from the next dword.
+    {
+        numOfBits -= UINT32_SIZE_IN_BITS - bitOffset;
+        res |= (arr[byteOffset + 1] & (0xFFFFFFFF >> (UINT32_SIZE_IN_BITS - numOfBits))) << (UINT32_SIZE_IN_BITS - bitOffset);
+    }
+
+    return res;
+}
+
+/*
+implementation of Repetition Counter Test (NIST SP 800-90B (2nd Draft) 4.4.1)
+C = the cutoff value at which the Repetition Count Test fails
+*/
+CCError_t LLF_RND_RepetitionCounterTest(uint32_t* pData, uint32_t sizeInBytes, uint32_t C)
+{
+    uint32_t bitOffset=0;
+    uint32_t newSample = 0;
+    uint32_t A = 0;         /* the most recently seen sample value */
+    uint32_t B = 0;         /* the number of consecutive times that the value A has been seen */
+    uint32_t bitsPerSample = 1; /* always use single bit per sample for repetition counter test */
+
+
+        if (pData == NULL || sizeInBytes == 0 || LLF_RND_TRNG90B_MAX_BYTES < sizeInBytes) {
+        return LLF_RND_TRNG_REPETITION_COUNTER_ERROR;
+    }
+
+        // the repetition count test is performed as follows:
+    for (bitOffset = 0; bitOffset <= (sizeInBytes * UINT8_SIZE_IN_BITS) - bitsPerSample; bitOffset += bitsPerSample) {
+        newSample = getBitsFromUint32Array(bitOffset, bitsPerSample, (uint32_t*)pData);
+
+        // 1. Let A be the current sample value.
+        // 2. Initialize the counter B to 1.
+        if (bitOffset == 0) {
+            A = newSample;
+            B = 1;
+        }
+        // 3. If the next sample value is A, increment B by one.
+        else if (A == newSample) {
+            ++B;
+                        // If B is equal to C, return an error.
+            if (B == C) {
+                                return LLF_RND_TRNG_REPETITION_COUNTER_ERROR;
+            }
+        } else {
+                        // Let A be the next sample value.
+            A = newSample;
+                        // Initialize the counter B to 1.
+            B = 1;
+                        // Repeat Step 3.
+        }
+    }
+    return CC_OK;
+}
+
+/*
+implementation of Adaptive Proportion Test (NIST SP 800-90B (2nd Draft) 4.4.2)
+N = the total number of samples that must be observed in one run of the test, also known as the "window size" of the test
+C = the cutoff value above which the test should fail
+*/
+CCError_t LLF_RND_AdaptiveProportionTest(uint32_t* pData, uint32_t sizeInBytes, uint32_t C, uint32_t W)
+{
+    uint32_t bitOffset=0;
+    uint32_t currentSample = 0;
+    uint32_t A = 0;         /* the sample value currently being counted */
+        uint32_t B = 0;         /* the current number of times that A has been seen in the S samples examined so far */
+        uint32_t i = 0;         /* the counter for the number of samples examined in the current window */
+        uint32_t bitsPerSample = 1; /* binary source */
+
+    if (pData == NULL || sizeInBytes == 0 || LLF_RND_TRNG90B_MAX_BYTES < sizeInBytes || W == 0 || C == 0) {
+        return LLF_RND_TRNG_ADAPTION_PROPORTION_ERROR;
+    }
+
+    // The test is performed as follows:
+    for (bitOffset = 0; bitOffset <= (sizeInBytes * UINT8_SIZE_IN_BITS) - bitsPerSample; bitOffset += bitsPerSample) {
+        currentSample = getBitsFromUint32Array(bitOffset, bitsPerSample, (uint32_t*)pData);
+
+                // 1. Let A be the current sample value.
+                // 2. Initialize the counter B to 1
+                if ((bitOffset == 0) || (i == W)) {
+                        A = currentSample;
+                        B = 1;
+                        i = 0;
+                }
+                // 3. For i = 1 to W-1
+                else {
+                        // If the next sample is equal to A, increment B by 1.
+                        if (A == currentSample) {
+                                ++B;
+                        }
+                }
+                // 4. If B > C, return error.
+                if (i == W - 1) {
+                        if (B > C) {
+                                return LLF_RND_TRNG_ADAPTION_PROPORTION_ERROR;
+                        }
+                }
+                ++i;
+                // 5. Go to Step 1.
+    }
+    return CC_OK;
+}
+
+static int32_t LLF_RND_TRNG_ReadEhrData(uint32_t *sample,
+                            CCRndState_t  *rndState_ptr,
+                            CCRndParams_t *trngParams_ptr,
+                            uint32_t *roscsToStart_ptr)
+{
+    uint32_t i;
+    CCError_t err = CC_OK;
+    uint32_t isr = 0;
+
+    err = startTrngHW(rndState_ptr, trngParams_ptr, CC_FALSE, roscsToStart_ptr, CC_FALSE);
+    if (err) {
+        return err;
+    }
+
+    /* wait RNG interrupt: isr signals error bits */
+    err = LLF_RND_WaitRngInterrupt(&isr);
+    if (err != CC_OK){
+            return err;
+    }
+
+    err = LLF_RND_TRNG_REQUIRED_ROSCS_NOT_ALLOWED_ERROR;
+    if (CC_REG_FLD_GET(0, RNG_ISR, EHR_VALID, isr)) {
+            err = CC_OK;
+    }
+
+    /* Read EHR into tmp buffer */
+    for (i = 0; i < LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS; i++) {
+        uint32_t ehr = CC_HAL_READ_REGISTER(DX_EHR_DATA_0_REG_OFFSET + (i * sizeof(uint32_t)));
+        sample[i] = ehr;
+    }
+
+    return CC_OK;
+}
+
+static CCError_t LLF_RND_TRNG_ReadMultipleEHR(uint32_t inSize, uint8_t *ramAddr,
+                                    CCRndState_t  *rndState_ptr,
+                                    CCRndParams_t *trngParams_ptr,
+                                    uint32_t *roscsToStart_ptr)
+{
+    uint32_t noise_samples[LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS];
+    CCError_t err = CC_OK;
+    uint32_t  final_chunk_size=0;
+    uint32_t counter = 0;
+    /* in case inSize is not divided by 6, copy partial last chunk */
+    if (inSize % LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS){
+            final_chunk_size = inSize % LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS;
+    }
+    while (inSize) {
+        LLF_RND_TurnOffTrng();
+        err = LLF_RND_TRNG_ReadEhrData(noise_samples, rndState_ptr, trngParams_ptr, roscsToStart_ptr);
+        if (err != CC_OK) {
+            return err;
+        }
+        if ((counter == inSize/LLF_RND_HW_TRNG_EHR_WIDTH_IN_WORDS) && (final_chunk_size != 0))
+    {
+            /* Copy the needed amount of bytes to the result buffer */
+            CC_PalMemCopy(ramAddr, (uint8_t *)noise_samples, final_chunk_size);
+                inSize -= final_chunk_size;
+                ramAddr += final_chunk_size;
+    }
+        else{
+            /* Copy the needed amount of bytes to the result buffer */
+            CC_PalMemCopy(ramAddr, (uint8_t *)noise_samples, LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES);
+                inSize -= LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES;
+                ramAddr += LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES;
+        }
+        counter++;
+    }
+
+    return CC_OK;
+}
+
+static void LLF_RND_TRNG_EnableRngSourceAndWatchdog(CCRndParams_t *trngParams_ptr, CCBool_t isStartup)
+{
+        uint32_t maxCycles;
+        uint32_t ehrSamples;
+
+    if (isStartup == CC_TRUE) {
+            ehrSamples = CC_CONFIG_TRNG90B_AMOUNT_OF_BYTES_STARTUP;
+        } else {
+            ehrSamples = trngParams_ptr->userParams.trngModeParams.numOfBytes;
+        }
+        ehrSamples/= LLF_RND_HW_TRNG_EHR_WIDTH_IN_BYTES;
+
+        /* Set watchdog threshold to maximal allowed time (in CPU cycles) */
+        maxCycles = LLF_RND_CalcMaxTrngTime(ehrSamples, trngParams_ptr->SubSamplingRatio);
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RNG_WATCHDOG_VAL), maxCycles);
+
+        /* enable the RND source */
+        CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(RNG, RND_SOURCE_ENABLE), LLF_RND_HW_RND_SRC_ENABLE_VAL);
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/local/cc_rnd_local.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/local/cc_rnd_local.h
new file mode 100644
index 0000000..c21c428
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rnd_dma/local/cc_rnd_local.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_RND_LOCAL_H
+#define _CC_RND_LOCAL_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "cc_rnd_common.h"
+#include "cc_pal_trng.h"
+
+/************************ Defines ****************************/
+
+
+/*************************************************************/
+/****** Common definitions for RND_DMA and non DMA     *******/
+/*************************************************************/
+
+#define CC_RND_VECT_IN_RANGE_MAX_COUNT_OF_TRIES    100
+
+#define CC_RND_BASIC_BLOCK_SIZE_IN_WORDS 4
+#define CC_RND_BASIC_BLOCK_SIZE_IN_BYTES (CC_RND_BASIC_BLOCK_SIZE_IN_WORDS*sizeof(uint32_t))
+#define CC_RND_ENTROPY_BLOCK_SIZE_IN_WORDS 4
+#define CC_RND_ENTROPY_BLOCK_SIZE_IN_BYTES (CC_RND_ENTROPY_BLOCK_SIZE_IN_WORDS*sizeof(uint32_t))
+
+/* Bit-fields of Instantiation steps in the StateFlag:
+    - b'0: 0 - not instantiated, 1 - instantiated normally;
+    - b'1: 1 - loss samples, 0 - no loss;
+    - b'2: 1 - time exceeding, 0 - no time exceeding.
+    In case of sample loss or time exceed b`0 must be 0 */
+#define CC_RND_NOT_INSTANTIATED                 0UL
+#define CC_RND_INSTANTIATED                 1UL
+#define CC_RND_INSTANTRESEED_AUTOCORR_ERRORS    2UL
+#define CC_RND_INSTANTRESEED_TIME_EXCEED        4UL
+#define CC_RND_INSTANTRESEED_LESS_ENTROPY       8UL
+
+/* The 2-bit field in the StateFlag, defining the working or KAT modes:
+     - b`9,8: 0 - working mode, 1 - KAT DRBG mode, 2 - KAT TRNG mode, 3 - KAT
+       DRBG or/and TRNG mode */
+#define CC_RND_WORK_Mode                  (0UL << 8)
+#define CC_RND_KAT_DRBG_Mode              (1UL << 8)
+#define CC_RND_KAT_TRNG_Mode              (2UL << 8)
+#define CC_RND_KAT_Mode               CC_RND_KAT_DRBG_Mode
+
+/* The bit-field in the StateFlag, defining that the previous generated random
+   block is valid for comparison with current block or not */
+#define CC_RND_PreviousIsValid          (1UL << 16)
+
+/* RND WorkBuffer = ESTIM_BUFF || ENTROPY_SOURCE_BUFF. Size of buffer = 1KB = *
+*  1024 words.  Max size (in words) of internal buffers:              */
+#define CC_RND_FULL_ENTROPY_SOURCE_BUFF_SIZE_WORDS 504
+#define CC_RND_ESTIM_BUFF_SIZE_WORDS           386 /*256+128+2*/
+#define CC_RND_ENTROPY_SOURCE_BUFF_SIZE_WORDS     1024/*2+504+504+12+1+padding */
+/* Offsets of buffers used in KAT mode */
+#define CC_RND_WORK_BUFF_TMP1_OFFSET  (CC_RND_ESTIM_BUFF_SIZE_WORDS + CC_RND_ENTROPY_SOURCE_BUFF_SIZE_WORDS + 4)
+#define CC_RND_WORK_BUFF_TMP2_OFFSET  (CC_RND_WORK_BUFF_TMP1_OFFSET + CC_RND_SEED_MAX_SIZE_WORDS + 4)
+
+/* max size of KAT entropy and nonce data in words on SWEE and FE modes*/
+#define CC_RND_ENTROPY_TEMP_BUFFER_MAX_SIZE_WORDS  126
+
+#define CC_RND_SRC_BUFF_OFFSET_WORDS  0
+
+
+/* Offsets (in words) of RND estimator buffer members inside the buffer */
+#define CC_RND_H_BUFF_OFFSET   0
+#define CC_RND_EC_BUFF_OFFSET  256
+
+/* Validation tag for random working state: should be set by:             *
+   RndInstantiateOrReseed function on not continued mode or by           *
+*  LLF_RND_StartTrngHW function on continued mode                     */
+#define CC_RND_WORK_STATE_VALID_TAG  0X0123ABCD
+
+/*Values for entropy flag*/
+#define LLF_RNG_ENTROPY_FLAG_REQUIRED   0x0
+#define LLF_RNG_ENTROPY_FLAG_LOW        0x1
+#define LLF_RNG_ENTROPY_FLAG_NULL       0x2
+#define LLF_RNG_ENTROPY_FLAG_KAT_MODE   0x3
+
+#define LLF_RNG_MAX_COLLECTION_ITERATION_SIZE 0x5
+
+#define LLF_RND_MAX_NUM_OF_ROSCS 0x4
+/************************ Enums ********************************/
+
+
+/************************ Structs  ******************************/
+
+/* The CC Random Generator Parameters  structure CCRndParams_t -
+   structure containing the user given Parameters */
+typedef struct  CCRndParams_t
+{
+    CC_PalTrngParams_t  userParams;
+
+    /* parameters defining TRNG */
+    CCRndMode_t TrngMode;
+
+    /* allowed ring oscillator lengths: bits 0,1,2,3  */
+    uint32_t  RoscsAllowed;
+
+    /* sampling interval: count of ring oscillator cycles between
+       consecutive bits sampling */
+    uint32_t  SubSamplingRatio;
+
+}CCRndParams_t;
+
+
+/************************ Typedefs  ****************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+/**********************************************************************************************************/
+/*!
+@brief Generates a random vector with specific limitations by testing candidates (described and used in FIPS Publication 186-4: Digital
+Signature Standard (DSS): B.1.2, B.4.2 etc.).
+
+This function draws a random vector, compare it to the range limits, and if within range - return it in rndVect_ptr.
+If outside the range, the function continues retrying until a conforming vector is found, or the maximal retries limit is exceeded.
+If maxVect_ptr is provided, rndSizeInBits specifies its size, and the output vector must conform to the range [1 < rndVect < maxVect_ptr].
+If maxVect_ptr is NULL, rndSizeInBits specifies the exact required vector size, and the output vector must be the exact same
+bit size (with its most significant bit = 1).
+\note The RND module must be instantiated prior to invocation of this API.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rnd_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RndGenerateVectorInRange(
+                    CCRndContext_t *rndContext_ptr,     /*!< [in/out] Pointer to the RND context buffer. */
+                    size_t   rndSizeInBits,                 /*!< [in]  The size in bits of the random vector required. The allowed size in range  2 <= rndSizeInBits < 2^19-1, bits. */
+                    uint8_t  *maxVect_ptr,                  /*!< [in]  Pointer to the vector defining the upper limit for the random vector output, Given as little-endian byte array.
+                                                                       If not NULL, its actual size is treated as [(rndSizeInBits+7)/8] bytes. */
+                    uint8_t  *rndVect_ptr                   /*!< [in/out] Pointer to the output buffer for the random vector. Must be at least [(rndSizeInBits+7)/8] bytes.
+                                                                 Treated as little-endian byte array. */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_build.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_build.c
new file mode 100644
index 0000000..6aa85c3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_build.c
@@ -0,0 +1,830 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_pal_mem.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_local.h"
+#include "pki.h"
+#include "rsa.h"
+#include "rsa_public.h"
+#include "rsa_private.h"
+#include "cc_fips_defs.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ***************************/
+
+/************************ Global Data ************************/
+
+/************************ Public Functions ******************************/
+
+/******************************************************************************************/
+/**
+ * @brief CC_RsaPubKeyBuild populates a CCRsaPubKey_t structure with
+ *       the provided modulus and exponent.
+ *
+ *  Assumption : the modulus and the exponent are presented in big endian.
+ *
+ * @param[out] PubKey_ptr - a pointer to the public key structure. This structure will be
+ *            used as an input to the CC_RsaPrimEncrypt API.
+ *
+ * @param[in] Exponent_ptr - a pointer to the exponent stream of bytes ( Big endian ).
+ * @param[in] ExponentSize - The size of the exponent in bytes.
+ * @param[in] Modulus_ptr  - a pointer to the modulus stream of bytes ( Big endian ) the MS
+ *           bit must be set to '1'.
+ * @param[in] ModulusSize  - The size of the modulus in bytes. Sizes supported according to
+ *           used platform from 64 to 256 bytes and in some platforms up to 512 bytes.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in .
+ */
+CEXPORT_C CCError_t CC_RsaPubKeyBuild(
+               CCRsaUserPubKey_t *UserPubKey_ptr,
+               uint8_t *Exponent_ptr,
+               size_t   ExponentSize,
+               uint8_t *Modulus_ptr,
+               size_t ModulusSize )
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the effective size in bits of the modulus buffer */
+    uint32_t ModulusEffectiveSizeInBits;
+
+    /* the effective size in bits of the exponent buffer */
+    uint32_t ExponentEffectiveSizeInBits;
+
+    /* the public key database pointer */
+    CCRsaPubKey_t *PubKey_ptr;
+
+    /* the Error return code identifier */
+    CCError_t Error = CC_OK;
+
+    /* Max Size of buffers in Key structure */
+    uint32_t  buffSizeBytes = CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES;
+
+    /* FUNCTION LOGIC */
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* ...... checking the key database handle pointer .................... */
+    if (UserPubKey_ptr == NULL)
+        return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the validity of the exponent pointer ............... */
+    if (Exponent_ptr == NULL)
+        return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
+
+    /* ...... checking the validity of the modulus pointer .............. */
+    if (Modulus_ptr == NULL)
+        return CC_RSA_INVALID_MODULUS_POINTER_ERROR;
+
+    if (ModulusSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        return CC_RSA_INVALID_MODULUS_SIZE;
+
+    if (ExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        return CC_RSA_INVALID_EXPONENT_SIZE;
+
+    /* .................. copy the buffers to the key handle structure .... */
+    /* -------------------------------------------------------------------- */
+    /* setting the pointer to the key database */
+    PubKey_ptr = ( CCRsaPubKey_t * )UserPubKey_ptr->PublicKeyDbBuff;
+
+    /* clear the public key db */
+    CC_PalMemSetZero( PubKey_ptr, sizeof(CCRsaPubKey_t) );
+
+    /* loading the buffers to little endian order of words in array; each word is loaded according to CPU endianness */
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PubKey_ptr->n, buffSizeBytes, Modulus_ptr, ModulusSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_MODULUS_ERROR;
+        return Error;
+    }
+
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PubKey_ptr->e, buffSizeBytes, Exponent_ptr, ExponentSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /* .................. initializing local variables ................... */
+    /* ------------------------------------------------------------------- */
+
+    /* .......... initializing the effective counters size in bits .......... */
+    ModulusEffectiveSizeInBits =  CC_CommonGetWordsCounterEffectiveSizeInBits(PubKey_ptr->n, (ModulusSize+3)/4);
+    ExponentEffectiveSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(PubKey_ptr->e, (ExponentSize+3)/4);
+
+    /* .................. checking the validity of the counters ............... */
+    /* ------------------------------------------------------------------------ */
+    if ((ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        (ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        (ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)) {
+
+        Error = CC_RSA_INVALID_MODULUS_SIZE;
+        goto End;
+    }
+    /*  verifying the modulus is odd  */
+    if ((PubKey_ptr->n[0] & 1UL) == 0) {
+        Error = CC_RSA_MODULUS_EVEN_ERROR;
+        goto End;
+    }
+
+    /*  checking the exponent size is not 0 in bytes */
+    if (ExponentEffectiveSizeInBits == 0) {
+        Error = CC_RSA_INVALID_EXPONENT_SIZE;
+        goto End;
+    }
+
+    /*  verifying the exponent is less then the modulus */
+    CounterCmpResult = CC_CommonCmpMsbUnsignedCounters(Exponent_ptr, ExponentSize, Modulus_ptr, ModulusSize);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /*  verifying the exponent is not less then 3 */
+    if (ExponentEffectiveSizeInBits < 32 && PubKey_ptr->e[0] < CC_RSA_MIN_PUB_EXP_VALUE) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /* ................. building the structure ............................. */
+    /* ---------------------------------------------------------------------- */
+
+    /* setting the modulus and exponent size in bits */
+    PubKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;
+    PubKey_ptr->eSizeInBits = ExponentEffectiveSizeInBits;
+
+    /* ................ initialize the low level data .............. */
+    Error = RsaInitPubKeyDb(PubKey_ptr);
+
+    if (Error != CC_OK) {
+        Error = CC_RSA_KEY_GENERATION_FAILURE_ERROR;
+        goto End;
+    }
+
+    /* ................ set the tag ................ */
+    UserPubKey_ptr->valid_tag = CC_RSA_PUB_KEY_VALIDATION_TAG;
+
+    /* ................. end of the function .................................. */
+    /* ------------------------------------------------------------------------ */
+
+    End:
+
+    /* if the structure created is not valid - clear it */
+    if (Error != CC_OK) {
+        CC_PalMemSetZero(UserPubKey_ptr, sizeof(CCRsaUserPubKey_t));
+        return Error;
+    }
+
+    return CC_OK;
+
+}/* END OF CC_RsaPubKeyBuild */
+
+
+/******************************************************************************************/
+/**
+ * @brief CC_RsaPrivKeyBuild populates a CCRsaPrivKey_t structure with
+ *        the provided modulus and exponent, marking the key as a "non-CRT" key.
+ *
+ *        Assumption : the modulus and the exponent are presented in big endian.
+ *
+ * @param[out] UserPrivKey_ptr - a pointer to the public key structure. this structure will be used as
+ *                          an input to the CC_RsaPrimDecrypt API.
+ * @param[in] PrivExponent_ptr - a pointer to the private exponent stream of bytes ( Big endian ).
+ * @param[in] PrivExponentSize - the size of the private exponent in bytes.
+ * @param[in] Exponent_ptr - a pointer to the exponent stream of bytes ( Big endian ).
+ * @param[in] ExponentSize - the size of the exponent in bytes.
+ * @param[in] Modulus_ptr  - a pointer to the modulus stream of bytes ( Big endian ) the MS
+ *            bit must be set to '1'.
+ * @param[in] ModulusSize  - the size of the modulus in bytes. Sizes supported according to
+ *            used platform from 64 to 256 bytes and in some platforms up to 512 bytes.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                       value MODULE_* as defined in ...
+ *
+ */
+CEXPORT_C CCError_t CC_RsaPrivKeyBuild(CCRsaUserPrivKey_t       *UserPrivKey_ptr,
+                         uint8_t             *PrivExponent_ptr,
+                         size_t               PrivExponentSize,
+                         uint8_t             *PubExponent_ptr,
+                         size_t               PubExponentSize,
+                         uint8_t             *Modulus_ptr,
+                         size_t               ModulusSize )
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the effective size in bits of the modulus buffer */
+    uint32_t ModulusEffectiveSizeInBits;
+
+    /* the effective sizes in bits of the private and public exponents */
+    uint32_t PrivExponentEffectiveSizeInBits, PubExponentEffectiveSizeInBits;
+
+    /* the private key database pointer */
+    CCRsaPrivKey_t *PrivKey_ptr;
+
+    /* Max Size of buffers in Key structure */
+    uint32_t  buffSizeBytes = CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES;
+
+    /* the Error return code identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* ...... checking the key database handle pointer .................... */
+    if (UserPrivKey_ptr == NULL)
+        return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the validity of the exponents pointers ........... */
+    if (PrivExponent_ptr == NULL)
+        return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
+
+    /* ...... checking the validity of the modulus pointer .............. */
+    if (Modulus_ptr == NULL)
+        return CC_RSA_INVALID_MODULUS_POINTER_ERROR;
+
+    /* ...... checking the validity of the modulus size, private exponent can not be more than 256 bytes .............. */
+    if (ModulusSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        return CC_RSA_INVALID_MODULUS_SIZE;
+
+    if (PrivExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        return CC_RSA_INVALID_EXPONENT_SIZE;
+
+    if (PubExponent_ptr != NULL &&
+        PubExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        return CC_RSA_INVALID_EXPONENT_SIZE;
+
+
+    /* .................. copy the buffers to the key handle structure .... */
+    /* -------------------------------------------------------------------- */
+
+    /* setting the pointer to the key database */
+    PrivKey_ptr = (CCRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+    /* clear the private key db */
+    CC_PalMemSetZero(PrivKey_ptr, sizeof(CCRsaPrivKey_t));
+
+    /* loading the buffers to little endian order of words in array; each word is loaded according to CPU endianness */
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->n, buffSizeBytes, Modulus_ptr, ModulusSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_MODULUS_ERROR;
+        return Error;
+    }
+
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.NonCrt.d, buffSizeBytes,
+                                PrivExponent_ptr, PrivExponentSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /* get actual sizes of modulus and private exponent */
+    ModulusEffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->n, (ModulusSize+3)/4);
+
+    PrivExponentEffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.NonCrt.d, (PrivExponentSize+3)/4);
+
+
+    /* .................. checking the validity of the counters ............... */
+    /* ------------------------------------------------------------------------ */
+
+    /*  checking the size of the modulus  */
+    if (( ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        ( ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        ( ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)) {
+        Error = CC_RSA_INVALID_MODULUS_SIZE;
+        goto End;
+    }
+
+    /*  verifying the modulus is odd  */
+    if ((PrivKey_ptr->n[0] & 1UL) == 0) {
+        Error = CC_RSA_MODULUS_EVEN_ERROR;
+        goto End;
+    }
+
+    /*  checking the priv. exponent size is not 0 in bytes */
+    if (PrivExponentEffectiveSizeInBits == 0) {
+        Error = CC_RSA_INVALID_EXPONENT_SIZE;
+        goto End;
+    }
+
+    /* verifying the priv. exponent is less then the modulus */
+    CounterCmpResult = CC_CommonCmpMsbUnsignedCounters(PrivExponent_ptr, PrivExponentSize,
+                                  Modulus_ptr, ModulusSize);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /* verifying the priv. exponent is not less then 1 */
+    if (PrivExponentEffectiveSizeInBits < 32 &&
+        PrivKey_ptr->PriveKeyDb.NonCrt.d[0] < CC_RSA_MIN_PRIV_EXP_VALUE) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /*  checking that the public exponent is an integer between 3 and modulus - 1 */
+    if (PubExponent_ptr != NULL) {
+        /* loading the buffer to little endian order of words in array; each word is loaded according to CPU endianness */
+        Error = CC_CommonConvertMsbLsbBytesToLswMswWords( PrivKey_ptr->PriveKeyDb.NonCrt.e, buffSizeBytes,
+                                     PubExponent_ptr, PubExponentSize);
+        if (Error) {
+            Error = CC_RSA_INVALID_EXPONENT_VAL;
+            goto End;
+        }
+
+        PubExponentEffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.NonCrt.e, (PubExponentSize+3)/4);
+
+        /* verifying that the exponent is not less than 3 */
+        if (PubExponentEffectiveSizeInBits < 32 &&
+            PrivKey_ptr->PriveKeyDb.NonCrt.e[0] < CC_RSA_MIN_PUB_EXP_VALUE) {
+            Error = CC_RSA_INVALID_EXPONENT_VAL;
+            goto End;
+        }
+
+        /* verifying that the public exponent is less than the modulus */
+        CounterCmpResult = CC_CommonCmpMsbUnsignedCounters(PubExponent_ptr, PubExponentSize,
+                                      Modulus_ptr, ModulusSize);
+
+        if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+            Error = CC_RSA_INVALID_EXPONENT_VAL;
+            goto End;
+        }
+    } else {
+        PubExponentEffectiveSizeInBits = 0;
+    }
+
+
+    /* ................. building the structure ............................. */
+    /* ---------------------------------------------------------------------- */
+
+    /* set the mode to non CRT mode */
+    PrivKey_ptr->OperationMode = CC_RSA_NoCrt;
+
+    /* set the key source as external */
+    PrivKey_ptr->KeySource = CC_RSA_ExternalKey;
+
+    /* setting the modulus and exponent size in bits */
+    PrivKey_ptr->nSizeInBits                   = ModulusEffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.NonCrt.dSizeInBits = PrivExponentEffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.NonCrt.eSizeInBits = PubExponentEffectiveSizeInBits;
+
+    /* ................ initialize the low level data .............. */
+    Error = RsaInitPrivKeyDb(PrivKey_ptr);
+
+    if (Error) {
+        Error = CC_RSA_INTERNAL_ERROR;
+        goto End;
+    }
+
+    /* ................ set the tag ................ */
+    UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+
+    /* ................. end of the function .................................. */
+    /* ------------------------------------------------------------------------ */
+
+    End:
+
+    /* if the structure created is not valid - clear it */
+    if (Error != CC_OK) {
+        CC_PalMemSetZero(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+    }
+
+    return Error;
+
+}/* END OF CC_RsaPrivKeyBuild */
+
+/******************************************************************************************
+
+   @brief CC_RsaPrivKeyCrtBuild populates a CCRsaPrivKey_t structure with
+      the provided parameters, marking the key as a "CRT" key.
+
+    Note: The "First" factor P must be great, than the "Second" factor Q.
+
+
+   @param[out] UserPrivKey_ptr - A pointer to the public key structure.
+                This structure is used as input to the CC_RsaPrimDecrypt API.
+   @param[in] P_ptr - A pointer to the first factor stream of bytes (Big-Endian format)
+   @param[in] PSize - The size of the first factor, in bytes.
+   @param[in] Q_ptr - A pointer to the second factor stream of bytes (Big-Endian format)
+   @param[in] QSize - The size of the second factor, in bytes.
+   @param[in] dP_ptr - A pointer to the first factor's CRT exponent stream of bytes (Big-Endian format)
+   @param[in] dPSize - The size of the first factor's CRT exponent, in bytes.
+   @param[in] dQ_ptr - A pointer to the second factor's CRT exponent stream of bytes (Big-Endian format)
+   @param[in] dQSize - The size of the second factor's CRT exponent, in bytes.
+   @param[in] qInv_ptr - A pointer to the first CRT coefficient stream of bytes (Big-Endian format)
+   @param[in] qInvSize - The size of the first CRT coefficient, in bytes.
+
+*/
+CEXPORT_C CCError_t CC_RsaPrivKeyCrtBuild(
+                           CCRsaUserPrivKey_t *UserPrivKey_ptr,
+                           uint8_t *P_ptr,
+                           size_t   PSize,
+                           uint8_t *Q_ptr,
+                           size_t   QSize,
+                           uint8_t *dP_ptr,
+                           size_t   dPSize,
+                           uint8_t *dQ_ptr,
+                           size_t   dQSize,
+                           uint8_t *qInv_ptr,
+                           size_t   qInvSize)
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the effective size in bits of the modulus factors buffer */
+    uint32_t P_EffectiveSizeInBits;
+    uint32_t Q_EffectiveSizeInBits;
+    uint32_t dP_EffectiveSizeInBits;
+    uint32_t dQ_EffectiveSizeInBits;
+    uint32_t qInv_EffectiveSizeInBits;
+    uint32_t ModulusEffectiveSizeInBits;
+
+    /* the private key database pointer */
+    CCRsaPrivKey_t *PrivKey_ptr;
+
+    /* Max Size of buffers in CRT Key structure */
+    uint32_t  buffSizeBytes;
+
+    /* the Error return code identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+
+
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* ...... checking the key database handle pointer .................... */
+    if (UserPrivKey_ptr == NULL)
+        return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+
+    /* checking the first factor pointer validity */
+    if (P_ptr == NULL)
+        return CC_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR;
+
+    /* checking the second factor pointer validity */
+    if (Q_ptr == NULL)
+        return CC_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR;
+
+    /* checking the first factor exponent pointer validity */
+    if (dP_ptr == NULL)
+        return CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR;
+
+    /* checking the second factor exponent pointer validity */
+    if (dQ_ptr == NULL)
+        return CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR;
+
+    /* checking the CRT coefficient */
+    if (qInv_ptr == NULL)
+        return CC_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR;
+
+    /* checking the input sizes */
+    if (PSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2 ||
+        QSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2) {
+        return CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
+    }
+
+    if (dPSize > PSize ||
+        dQSize > QSize ||
+        qInvSize > PSize) {
+        return CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
+    }
+
+    buffSizeBytes = 4*((PSize + 3)/4) + 4;
+    /* verifying the first factor exponent is less then the first factor */
+    CounterCmpResult =
+    CC_CommonCmpMsbUnsignedCounters(dP_ptr, dPSize, P_ptr, PSize);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        return CC_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL;
+    }
+
+    /* verifying the second factor exponent is less then the second factor */
+    CounterCmpResult =
+    CC_CommonCmpMsbUnsignedCounters(dQ_ptr, dQSize, Q_ptr, QSize);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        return CC_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL;
+    }
+
+    /* verifying the CRT coefficient is less then the first factor */
+    CounterCmpResult =
+    CC_CommonCmpMsbUnsignedCounters(qInv_ptr, qInvSize, P_ptr, PSize);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        return CC_RSA_INVALID_CRT_COEFF_VAL;
+    }
+
+
+    /* .................. copy the buffers to the key handle structure .... */
+    /* -------------------------------------------------------------------- */
+
+    /* setting the pointer to the key database */
+    PrivKey_ptr = (CCRsaPrivKey_t*)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+    /* clear the private key db */
+    CC_PalMemSetZero(PrivKey_ptr, sizeof(CCRsaPrivKey_t));
+
+    /* load the buffers to the data base */
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.P, buffSizeBytes, P_ptr, PSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_ERROR;
+        goto End;
+    }
+
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.Q, buffSizeBytes, Q_ptr, QSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_ERROR;
+        goto End;
+    }
+
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.dP, buffSizeBytes, dP_ptr, dPSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_ERROR;
+        goto End;
+    }
+
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.dQ, buffSizeBytes, dQ_ptr, dQSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_ERROR;
+        goto End;
+    }
+
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.qInv, buffSizeBytes, qInv_ptr, qInvSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_ERROR;
+        goto End;
+    }
+
+    /* ............... initialize local variables ......................... */
+    /* -------------------------------------------------------------------- */
+
+    /* initializing the effective counters size in bits */
+    P_EffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.P, (PSize+3)/4);
+
+    Q_EffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.Q, (QSize+3)/4);
+
+    dP_EffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dP, (dPSize+3)/4);
+
+    dQ_EffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dQ, (dQSize+3)/4);
+
+    qInv_EffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.qInv, (qInvSize+3)/4);
+
+    /*  the first factor size is not 0 in bits */
+    if (P_EffectiveSizeInBits == 0|| P_EffectiveSizeInBits > 8*PSize) {
+        Error = CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE;
+        goto End;
+    }
+
+    /* the second factor size is not 0 in bits */
+    if (Q_EffectiveSizeInBits == 0 || Q_EffectiveSizeInBits > 8*QSize) {
+        Error = CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE;
+        goto End;
+    }
+
+    /* checking that sizes of dP, dQ, qInv > 0 */
+    if (dP_EffectiveSizeInBits == 0 || dQ_EffectiveSizeInBits == 0 || qInv_EffectiveSizeInBits == 0) {
+        Error = CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
+        goto End;
+    }
+
+
+
+    /* ............... calculate the modulus N ........................... */
+    /* -------------------------------------------------------------------- */
+
+
+    Error = PkiLongNumMul(PrivKey_ptr->PriveKeyDb.Crt.P, P_EffectiveSizeInBits,
+                     PrivKey_ptr->PriveKeyDb.Crt.Q, PrivKey_ptr->n);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INTERNAL_ERROR;
+        goto End;
+    }
+
+    ModulusEffectiveSizeInBits =
+    CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->n, (2*CALC_FULL_32BIT_WORDS(P_EffectiveSizeInBits)));
+
+    /* .................. checking the validity of the counters ............... */
+    /* ------------------------------------------------------------------------ */
+
+    /* the size of the modulus  */
+    if (( ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS) ||
+        ( ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS) ||
+        ( ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)) {
+        Error = CC_RSA_INVALID_MODULUS_SIZE;
+        goto End;
+    }
+
+    if ((P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits) &&
+        (P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits - 1)) {
+        Error = CC_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE;
+        goto End;
+    }
+
+
+    /* ................. building the structure ............................. */
+    /* ---------------------------------------------------------------------- */
+
+    /* set the mode to CRT mode */
+    PrivKey_ptr->OperationMode = CC_RSA_Crt;
+
+    /* set the key source as external */
+    PrivKey_ptr->KeySource = CC_RSA_ExternalKey;
+
+    /* loading to structure the buffer sizes... */
+
+    PrivKey_ptr->PriveKeyDb.Crt.PSizeInBits    = P_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.QSizeInBits    = Q_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.dPSizeInBits   = dP_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.dQSizeInBits   = dQ_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.qInvSizeInBits = qInv_EffectiveSizeInBits;
+    PrivKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;
+
+    /* ................ initialize the low level data .............. */
+    Error = RsaInitPrivKeyDb(PrivKey_ptr);
+
+    if (Error != CC_OK) {
+        Error = CC_RSA_INTERNAL_ERROR;
+        goto End;
+    }
+
+    /* ................ set the tag ................ */
+    UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+
+    /* ................. end of the function .................................. */
+    /* ------------------------------------------------------------------------ */
+
+    End:
+
+    /* if the structure created is not valid - clear it */
+    if (Error != CC_OK) {
+        CC_PalMemSetZero(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+        return Error;
+    }
+
+    return Error;
+
+}/* END OF CC_RsaPrivKeyCrtBuild */
+
+
+/******************************************************************************************
+   @brief CC_RsaPubKeyGet gets the e,n public key from the database.
+
+   @param[in] UserPubKey_ptr - A pointer to the public key structure.
+                   This structure is used as input to the CC_RsaPrimEncrypt API.
+
+   @param[out] Exponent_ptr - A pointer to the exponent stream of bytes (Big-Endian format)
+   @param[in,out] ExponentSize_ptr - the size of the exponent buffer in bytes, it is updated to the
+          actual size of the exponent, in bytes.
+   @param[out] Modulus_ptr  - A pointer to the modulus stream of bytes (Big-Endian format).
+               The MS (most significant) bit must be set to '1'.
+   @param[in,out] ModulusSize_ptr  - the size of the modulus buffer in bytes, it is updated to the
+          actual size of the modulus, in bytes.
+
+   NOTE: All members of input UserPrivKey structure must be initialized, including public key
+     e pointer and it size.
+
+*/
+CEXPORT_C CCError_t CC_RsaPubKeyGet(
+                     CCRsaUserPubKey_t *UserPubKey_ptr,
+                     uint8_t  *Exponent_ptr,
+                     size_t   *ExponentSize_ptr,
+                     uint8_t  *Modulus_ptr,
+                     size_t   *ModulusSize_ptr )
+{
+    /* LOCAL DECLERATIONS */
+
+    /* the size in bytes of the modulus and the exponent */
+    uint32_t nSizeInBytes;
+    uint32_t eSizeInBytes;
+    /* the public key database pointer */
+    CCRsaPubKey_t *PubKey_ptr;
+
+    CCError_t Error;
+
+    /* FUNCTION DECLERATIONS */
+
+
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* ...... checking the key database handle pointer .................... */
+    if (UserPubKey_ptr == NULL)
+        return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the validity of the exponent pointer ............... */
+    if (Exponent_ptr == NULL && Modulus_ptr != NULL)
+        return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
+
+    /* ...... checking the validity of the modulus pointer .............. */
+    if (Modulus_ptr == NULL && Exponent_ptr != NULL)
+        return CC_RSA_INVALID_MODULUS_POINTER_ERROR;
+
+    if (ExponentSize_ptr == NULL)
+        return CC_RSA_INVALID_EXP_BUFFER_SIZE_POINTER;
+
+    if (ModulusSize_ptr == NULL)
+        return CC_RSA_INVALID_MOD_BUFFER_SIZE_POINTER;
+
+    /* if the users TAG is illegal return an error - the context is invalid */
+    if (UserPubKey_ptr->valid_tag != CC_RSA_PUB_KEY_VALIDATION_TAG)
+        return CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR;
+
+    /* ...... checking the exponent size ................................ */
+
+    /* setting the pointer to the key database */
+    PubKey_ptr = ( CCRsaPubKey_t * )UserPubKey_ptr->PublicKeyDbBuff;
+
+    /* calculating the required size in bytes */
+    nSizeInBytes = CALC_FULL_BYTES(PubKey_ptr->nSizeInBits);
+    eSizeInBytes = CALC_FULL_BYTES(PubKey_ptr->eSizeInBits);
+
+    /* return the modulus size and exit */
+    if (Exponent_ptr == NULL && Modulus_ptr == NULL){
+        *ModulusSize_ptr  = nSizeInBytes;
+        *ExponentSize_ptr = eSizeInBytes;
+        return CC_OK;
+    }
+    /* if the size of the modulus is to small return error */
+    if (nSizeInBytes > *ModulusSize_ptr)
+        return CC_RSA_INVALID_MODULUS_SIZE;
+
+    /* if the size of the exponent buffer is to small return error */
+    if (eSizeInBytes > *ExponentSize_ptr)
+        return CC_RSA_INVALID_EXPONENT_SIZE;
+
+    /* .............. loading the output arguments and buffers ............... */
+    /* ----------------------------------------------------------------------- */
+
+    /* loading the buffers */
+
+    Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Exponent_ptr, 4*((*ExponentSize_ptr+3)/4),
+                                PubKey_ptr->e, eSizeInBytes );
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_EXPONENT_SIZE;
+        goto End;
+    }
+
+    Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Modulus_ptr, 4*((*ModulusSize_ptr+3)/4),
+                                PubKey_ptr->n, nSizeInBytes );
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_MODULUS_SIZE;
+        goto End;
+    }
+
+    /* updating the buffer sizes */
+    *ModulusSize_ptr  = (uint16_t)nSizeInBytes;
+    *ExponentSize_ptr = (uint16_t)eSizeInBytes;
+
+End:
+    if (Error != CC_OK) {
+        CC_PalMemSetZero(Modulus_ptr, nSizeInBytes);
+        CC_PalMemSetZero(Exponent_ptr, eSizeInBytes);
+        return Error;
+    }
+
+    return CC_OK;
+
+}/* END OF CC_RsaPubKeyGet */
+
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_kg.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_kg.c
new file mode 100644
index 0000000..80393b5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_kg.c
@@ -0,0 +1,598 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include "cc_common.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_local.h"
+#include "cc_common_math.h"
+#include "cc_rnd_error.h"
+#include "cc_rsa_kg.h"
+#include "rsa.h"
+#include "rsa_public.h"
+#include "rsa_private.h"
+#include "cc_general_defs.h"
+#include "cc_fips_defs.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#ifdef CC_SOFT_KEYGEN
+#include "ccsw_rsa_kg.h"
+#endif
+/************************ Defines ******************************/
+
+/************************ Enums ************************************/
+
+/************************ Typedefs *********************************/
+
+/************************ Global Data ******************************/
+#ifdef FIPS_CERTIFICATION
+extern rsaKgInternalDataStruct_t rsaKgOutParams;
+#endif
+/************* Private function prototype **************************/
+
+/************************ Public Functions ******************************/
+
+static CCError_t  KGCheckAndSetParamsRSA(
+                      CCRndContext_t      *rndContext_ptr,
+                                          uint8_t             *PubExp_ptr,
+                                          size_t               PubExpSizeInBytes,
+                                          size_t               KeySize,
+                                          CCRsaUserPrivKey_t   *pCcUserPrivKey,
+                                          CCRsaUserPubKey_t    *pCcUserPubKey,
+                                          CCRsaKgData_t        *KeyGenData_ptr ){
+
+    /* the error identifier */
+        CCError_t Error = CC_OK;
+        /* the pointers to the key structures */
+        CCRsaPubKey_t  *pCcPubKey;
+        CCRsaPrivKey_t *pCcPrivKey;
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+        /* ...... checking the random context pointer ........................ */
+        if (rndContext_ptr == NULL)
+                       return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+
+        /* ...... checking the random generate vector function pointer ....... */
+        if (rndContext_ptr->rndGenerateVectFunc == NULL)
+            return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        /* ...... checking the key database handle pointer .................. */
+        if (PubExp_ptr == NULL)
+            return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
+
+        /* ...... checking the validity of the exponent pointer ............. */
+        if (pCcUserPrivKey == NULL)
+            return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+
+        /* ...... checking the validity of the modulus pointer .............. */
+        if (pCcUserPubKey == NULL)
+            return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+
+        /* ...... checking the validity of the keygen data .................. */
+        if (KeyGenData_ptr == NULL)
+            return CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID;
+
+        /* ...... checking the exponent size .................. */
+        if (PubExpSizeInBytes > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+            return CC_RSA_INVALID_EXPONENT_SIZE;
+
+        /* ...... checking the required key size ............................ */
+        if (( KeySize < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+                ( KeySize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+            ( KeySize % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS )) {
+            return CC_RSA_INVALID_MODULUS_SIZE;
+        }
+
+        /* set the public and private key structure pointers */
+        pCcPubKey  = (CCRsaPubKey_t*)pCcUserPubKey->PublicKeyDbBuff;
+        pCcPrivKey = (CCRsaPrivKey_t*)pCcUserPrivKey->PrivateKeyDbBuff;
+
+
+        /* ................ clear all input structures ............................. */
+        /* ------------------------------------------------------------------------- */
+
+        CC_PalMemSetZero(pCcUserPrivKey, sizeof(CCRsaUserPrivKey_t));
+        CC_PalMemSetZero(pCcUserPubKey, sizeof(CCRsaUserPubKey_t));
+        CC_PalMemSetZero(KeyGenData_ptr, sizeof(CCRsaKgData_t));
+
+        /* ................ loading the public exponent to the structure .......... */
+        /* ------------------------------------------------------------------------- */
+
+        /* loading the buffers to start from LS word to MS word */
+        Error = CC_CommonConvertMsbLsbBytesToLswMswWords(
+                pCcPubKey->e, sizeof(pCcPubKey->e),
+            PubExp_ptr, PubExpSizeInBytes);
+        if (Error != CC_OK) {
+            Error = CC_RSA_INVALID_EXPONENT_VAL;
+            goto End;
+        }
+
+        /* .......... initializing the effective counters size in bits .......... */
+        pCcPubKey->eSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPubKey->e, (PubExpSizeInBytes+3)/4);
+
+        /* if the size in bits is 0 - return error */
+        if (pCcPubKey->eSizeInBits == 0 || pCcPubKey->eSizeInBits > 17) { /* MV - check if needed*/
+            Error = CC_RSA_INVALID_EXPONENT_SIZE;
+            goto End;
+        }
+
+        /* verifing the exponent has legal value (currently only 0x3,0x11 and 0x10001) */
+        /* verifying the exponent has legal value (currently only 0x3,0x11 and 0x10001) */
+        if (pCcPubKey->e[0] != CC_RSA_KG_PUB_EXP_ALLOW_VAL_1  &&
+                pCcPubKey->e[0] != CC_RSA_KG_PUB_EXP_ALLOW_VAL_2 &&
+            pCcPubKey->e[0] != CC_RSA_KG_PUB_EXP_ALLOW_VAL_3) {
+            Error = CC_RSA_INVALID_EXPONENT_VAL;
+            goto End;
+        }
+
+        /* .......... initializing the key sizes  ......................... */
+
+        /* this initialization is required for the low level function (LLF) - indicates the required
+         *             size of the key to be found */
+        pCcPubKey->nSizeInBits  = KeySize;
+        pCcPrivKey->nSizeInBits = KeySize;
+
+ End:
+    return Error;
+}
+
+/***********************************************************************************************/
+#ifndef _INTERNAL_CC_NO_RSA_KG_SUPPORT
+/**
+   @brief CC_RsaKgKeyPairGenerate generates a Pair of public and private keys on non CRT mode.
+
+   Note: FIPS 186-4 [5.1] standard specifies three choices for the length of the RSA
+         keys (modules): 1024, 2048 and 3072 bits and public exponent value >= 0x10001.
+         This implementation allows to generate keys also with other (not FIPS approved)
+         sizes on the user's responcibility.
+
+   @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param [in] PubExp_ptr - The pointer to the public exponent (public key).
+          Allowed values 0x3, 0x11, 0x10001.
+   @param [in] PubExpSizeInBytes - The public exponent size in bytes.
+   @param [in] KeySize  - The size of the key in bits. Supported sizes are 256 bit multiples
+                          between 512 - 4096;
+   @param [out] pCcUserPrivKey - A pointer to the private key structure.
+                           This structure is used as input to the CC_RsaPrimDecrypt API.
+   @param [out] pCcUserPubKey - A pointer to the public key structure.
+                           This structure is used as input to the CC_RsaPrimEncrypt API.
+   @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen operation.
+
+   @return CCError_t - CC_OK,
+                         CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
+                         CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
+                         CC_RSA_INVALID_MODULUS_SIZE,
+                         CC_RSA_INVALID_EXPONENT_SIZE
+*/
+CEXPORT_C CCError_t CC_RsaKgKeyPairGenerate(
+                                                 CCRndContext_t *rndContext_ptr,
+                                                 uint8_t             *PubExp_ptr,
+                                                 size_t               PubExpSizeInBytes,
+                                                 size_t               KeySize,
+                                                 CCRsaUserPrivKey_t *pCcUserPrivKey,
+                                                 CCRsaUserPubKey_t  *pCcUserPubKey,
+                                                 CCRsaKgData_t      *KeyGenData_ptr,
+                         CCRsaKgFipsContext_t    *pFipsCtx)
+{
+        /* LOCAL INITIALIZATIONS AND DECLERATIONS */
+
+        /* the error identifier */
+        CCError_t error = CC_OK;
+
+        /* the pointers to the key structures */
+        CCRsaPubKey_t  *pCcPubKey;
+        CCRsaPrivKey_t *pCcPrivKey;
+
+        error = KGCheckAndSetParamsRSA( rndContext_ptr,
+                    PubExp_ptr,
+                    PubExpSizeInBytes,
+                    KeySize,
+                    pCcUserPrivKey,
+                    pCcUserPubKey,
+                    KeyGenData_ptr );
+        if (error != CC_OK){
+            return error;
+        }
+
+        /* set the public and private key structure pointers */
+        pCcPubKey  = ( CCRsaPubKey_t *)pCcUserPubKey->PublicKeyDbBuff;
+        pCcPrivKey = ( CCRsaPrivKey_t *)pCcUserPrivKey->PrivateKeyDbBuff;
+
+        /* .......... initialize the public key on the private structure ............... */
+        CC_PalMemCopy(pCcPrivKey->PriveKeyDb.NonCrt.e, pCcPubKey->e, ROUNDUP_BYTES_TO_32BIT_WORD(PubExpSizeInBytes));
+        pCcPrivKey->PriveKeyDb.NonCrt.eSizeInBits = pCcPubKey->eSizeInBits;
+
+        /* .......... set the private mode to non CRT .............................. */
+        /* ------------------------------------------------------------------------- */
+
+        /* set the mode to non CRT */
+        pCcPrivKey->OperationMode = CC_RSA_NoCrt;
+
+        /* ................ executing the key generation ........................... */
+        /* ------------------------------------------------------------------------- */
+        /* ................ execute the low level key gen .......................... */
+        do{
+            error = RsaGenPandQ(
+                    rndContext_ptr, /*!< [in/out] Pointer to the RND context buffer. */
+                KeySize,
+                pCcPubKey->eSizeInBits,
+                pCcPubKey->e,
+                KeyGenData_ptr);
+            if (error != CC_OK) {
+                goto End;
+            }
+
+
+            /* calculate modulus n and private exponent d */
+            error = RsaCalculateNandD(
+                            pCcPubKey,
+                            pCcPrivKey,
+                            KeyGenData_ptr,
+                            KeySize/2);
+
+            if (error != CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW && error != CC_OK) { \
+                goto End;
+            }
+        }while(error!=CC_OK);
+
+#ifdef FIPS_CERTIFICATION
+        CC_CommonReverseMemcpy(rsaKgOutParams.nModulus, (uint8_t*)pCcPubKey->n, KeySize/CC_BITS_IN_BYTE);
+        CC_CommonReverseMemcpy(rsaKgOutParams.pPrim, (uint8_t*)KeyGenData_ptr->KGData.p, KeySize/(2*CC_BITS_IN_BYTE));
+        CC_CommonReverseMemcpy(rsaKgOutParams.qPrim, (uint8_t*)KeyGenData_ptr->KGData.q, KeySize/(2*CC_BITS_IN_BYTE));
+        CC_CommonReverseMemcpy(rsaKgOutParams.dPrivExponent, (uint8_t*)pCcPrivKey->PriveKeyDb.NonCrt.d, KeySize/CC_BITS_IN_BYTE);
+#endif
+
+
+
+        /* ................ initialize the low level key structures ................ */
+        /* ------------------------------------------------------------------------- */
+
+        error = RsaInitPubKeyDb( pCcPubKey );
+        if (error != CC_OK) {
+            goto End;
+        }
+
+        error = RsaInitPrivKeyDb( pCcPrivKey );
+        if (error != CC_OK) {
+                goto End;
+    }
+
+        /* ................ set the key valid tags ................................. */
+        /* ------------------------------------------------------------------------- */
+        pCcUserPrivKey->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+        pCcUserPubKey->valid_tag  = CC_RSA_PUB_KEY_VALIDATION_TAG;
+
+        // run conditional test
+        error = FIPS_RSA_VALIDATE(rndContext_ptr,pCcUserPrivKey,pCcUserPubKey,pFipsCtx);
+
+
+End:
+        /* on failure clear the generated key */
+        if (error != CC_OK) {
+                error = CC_RSA_INTERNAL_ERROR;
+            CC_PalMemSetZero((uint8_t*)pCcUserPrivKey,  sizeof(CCRsaUserPrivKey_t) );
+            CC_PalMemSetZero((uint8_t*)pCcUserPubKey, sizeof(CCRsaUserPubKey_t) );
+    }
+    if (pFipsCtx != NULL) {
+        CC_PalMemSetZero((uint8_t*)pFipsCtx, sizeof(CCRsaKgFipsContext_t));
+    }
+        /* clear the KG data structure */
+        CC_PalMemSetZero ((uint8_t*)KeyGenData_ptr ,sizeof(CCRsaKgData_t) );
+
+        return error;
+
+
+}/* END OF CC_RsaKgKeyPairGenerate */
+
+
+/***********************************************************************************************/
+/**
+   @brief CC_RsaKgKeyPairCrtGenerate generates a Pair of public and private keys on CRT mode.
+
+   Note: FIPS 186-4 [5.1] standard specifies three choices for the length of the RSA
+         keys (modules): 1024, 2048 and 3072 bits. This implementation allows
+         generate also some other (not FIPS approved) sizes on the user's responcibility.
+
+   @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param [in] PubExp_ptr - The pointer to the public exponent (public key)
+   @param [in] PubExpSizeInBytes - The public exponent size in bits.
+   @param [in] KeySize  - The size of the key in bits. Supported sizes are 256 bit multiples
+                          between 512 - 4096;
+   @param [out] pCcUserPrivKey - A pointer to the private key structure.
+                           This structure is used as input to the CC_RsaPrimDecrypt API.
+   @param [out] pCcUserPubKey - A pointer to the public key structure.
+                           This structure is used as input to the CC_RsaPrimEncrypt API.
+   @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen operation.
+
+   @return CCError_t - CC_OK,
+                         CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
+                         CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
+                         CC_RSA_INVALID_MODULUS_SIZE,
+                         CC_RSA_INVALID_EXPONENT_SIZE
+*/
+
+CEXPORT_C CCError_t CC_RsaKgKeyPairCrtGenerate(
+                                                CCRndContext_t      *rndContext_ptr,
+                                                uint8_t                 *PubExp_ptr,
+                                                size_t                   PubExpSizeInBytes,
+                                                size_t                   KeySize,
+                                                CCRsaUserPrivKey_t   *pCcUserPrivKey,
+                                                CCRsaUserPubKey_t    *pCcUserPubKey,
+                                                CCRsaKgData_t        *KeyGenData_ptr,
+                                                CCRsaKgFipsContext_t *pFipsCtx )
+{
+        /* LOCAL INITIALIZATIONS AND DECLERATIONS */
+
+        /* the error identifier */
+        CCError_t Error = CC_OK;
+
+        /* the pointers to the key structures */
+        CCRsaPubKey_t  *pCcPubKey;
+        CCRsaPrivKey_t *pCcPrivKey;
+        uint16_t   pSizeWords;
+
+        Error = KGCheckAndSetParamsRSA( rndContext_ptr,
+                    PubExp_ptr,
+                    PubExpSizeInBytes,
+                    KeySize,
+                    pCcUserPrivKey,
+                    pCcUserPubKey,
+                    KeyGenData_ptr );
+        if (Error != CC_OK){
+            return Error;
+        }
+        /* set the public and private key structure pointers */
+        pCcPubKey  = (CCRsaPubKey_t*)pCcUserPubKey->PublicKeyDbBuff;
+        pCcPrivKey = (CCRsaPrivKey_t*)pCcUserPrivKey->PrivateKeyDbBuff;
+
+        /* .......... initializing the key sizes  ......................... */
+        pSizeWords =(uint16_t) KeySize / (2*CC_BITS_IN_32BIT_WORD);  // RL
+
+        /* .......... set the private mode to CRT .................................. */
+        /* ------------------------------------------------------------------------- */
+
+        /* set the mode to CRT */
+        pCcPrivKey->OperationMode = CC_RSA_Crt;
+
+
+        /* ................ executing the key generation ........................... */
+        /* ------------------------------------------------------------------------- */
+
+        /* ................ execute the low level key gen ........................... */
+
+        /*Generate P and Q*/
+        Error = RsaGenPandQ(
+                rndContext_ptr,
+            KeySize,
+            pCcPubKey->eSizeInBits,
+            pCcPubKey->e,
+            KeyGenData_ptr);
+
+        /* on failure exit the function */
+        if (Error != CC_OK) {
+            goto End;
+        }
+
+        /* Calculate CRT private Key parameters*/
+        /* calculate modulus n  */
+        Error = RsaCalculateNandD(
+                pCcPubKey,
+            pCcPrivKey,
+            KeyGenData_ptr,
+            KeySize/2);
+        /* on failure exit the function */
+        if (Error != CC_OK) {
+            goto End;
+        }
+
+        Error = RsaCalculateCrtParams(
+                pCcPubKey->e, pCcPubKey->eSizeInBits,
+            KeySize,
+            KeyGenData_ptr->KGData.p, KeyGenData_ptr->KGData.q,
+            pCcPrivKey->PriveKeyDb.Crt.dP,
+            pCcPrivKey->PriveKeyDb.Crt.dQ,
+            pCcPrivKey->PriveKeyDb.Crt.qInv);
+
+        if (Error !=CC_OK) {
+            goto End;
+        }
+
+#ifdef FIPS_CERTIFICATION
+        CC_CommonReverseMemcpy(rsaKgOutParams.nModulus, (uint8_t*)pCcPubKey->n, KeySize/CC_BITS_IN_BYTE);
+        CC_CommonReverseMemcpy(rsaKgOutParams.pPrim, (uint8_t*)KeyGenData_ptr->KGData.p,KeySize/(2*CC_BITS_IN_BYTE));
+        CC_CommonReverseMemcpy(rsaKgOutParams.qPrim, (uint8_t*)KeyGenData_ptr->KGData.q, KeySize/(2*CC_BITS_IN_BYTE));
+        CC_CommonReverseMemcpy(rsaKgOutParams.dPrivExponent, NULL, KeySize/CC_BITS_IN_BYTE);
+#endif
+
+        /* ................ Set private and public key data ........................ */
+        /* ------------------------------------------------------------------------- */
+        /* Load P,Q vectors */
+        CC_PalMemCopy(pCcPrivKey->PriveKeyDb.Crt.P, KeyGenData_ptr->KGData.p, pCcPubKey->nSizeInBits / 16);
+        CC_PalMemCopy(pCcPrivKey->PriveKeyDb.Crt.Q, KeyGenData_ptr->KGData.q, pCcPubKey->nSizeInBits / 16);
+
+
+        /* ................ set the vector sizes ................................... */
+        /* ------------------------------------------------------------------------- */
+
+        pCcPrivKey->PriveKeyDb.Crt.PSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.P, (uint16_t)pSizeWords);
+
+        pCcPrivKey->PriveKeyDb.Crt.QSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.Q, (uint16_t)pSizeWords);
+
+        pCcPrivKey->PriveKeyDb.Crt.dPSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.dP, (uint16_t)pSizeWords);
+
+        pCcPrivKey->PriveKeyDb.Crt.dQSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.dQ, (uint16_t)pSizeWords);
+
+        pCcPrivKey->PriveKeyDb.Crt.qInvSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.qInv, (uint16_t)pSizeWords);
+
+        /* ................ initialize the low level key structures ................ */
+        /* ------------------------------------------------------------------------- */
+
+        Error = RsaInitPubKeyDb(pCcPubKey);
+        if (Error != CC_OK) {
+                goto End;
+        }
+
+        Error = RsaInitPrivKeyDb(pCcPrivKey);
+        if (Error != CC_OK) {
+                goto End;
+        }
+
+        pCcUserPrivKey->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+        pCcUserPubKey->valid_tag  = CC_RSA_PUB_KEY_VALIDATION_TAG;
+
+        /* run conditional test */
+        Error = FIPS_RSA_VALIDATE(rndContext_ptr,pCcUserPrivKey,pCcUserPubKey,pFipsCtx);
+
+End:
+
+        /* on failure clear the generated key */
+        if (Error != CC_OK) {
+                Error = CC_RSA_INTERNAL_ERROR;
+        CC_PalMemSetZero(pCcUserPrivKey,  sizeof(CCRsaUserPrivKey_t) );
+        CC_PalMemSetZero(pCcUserPubKey, sizeof(CCRsaUserPubKey_t) );
+    }
+    if (pFipsCtx != NULL) {
+        CC_PalMemSetZero(pFipsCtx, sizeof(CCRsaKgFipsContext_t));
+    }
+        /* clear the KG data structure */
+        CC_PalMemSetZero (KeyGenData_ptr ,sizeof(CCRsaKgData_t) );
+
+        return Error;
+
+
+}/* END OF CC_RsaKgKeyPairCrtGenerate */
+
+
+
+/**********************************************************************************************************/
+/**
+ * @brief The CC_RsaGenerateVectorInRangeX931 function generates a random vector in range:
+ *            MinVect < RandVect < MaxVect, where:
+ *            MinVect = squareRoot(2) * 2^(RndSizeInBits-1),  MaxVect = 2^RndSizeInBits.
+ *
+ *            Note: 1. MSBit of RandVect must be set to 1.
+ *                  2. Words order of output vector is set from LS word to MS
+ *                 word.
+ *
+ *        This function is used in PKI RSA for random generation according to ANS X9.31 standard.
+ *        If PKI_RSA is not supported, the function does nothing.
+ *
+ *        Functions algorithm::
+ *
+ *        1.  Calls the CC_RndGenerateVector() function for generating random vector
+ *            RndVect of size RndSizeInWords, rounded up to bytes. Set index i
+ *            to high word i = SizeInWords-1.
+ *        2.  Check and adust candidate for msWord inside the random vector
+ *            starting from msWord himselv, if msWord > high word of MinVect,
+ *            goto step 3, else try next word i--; if no words to try, then goto
+ *            step 1.
+ *        3.  Set the found msWord to high position in array and generate new
+ *            random words instead all checked and rejected words.
+ *
+ * @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
+ * @rndSizeWords[in]  - The size of random vectore that is required.
+ * @rnd_ptr[out]      - The output buffer of size not less, than rndSizeWords.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                       value MODULE_* as defined in ...
+ */
+CCError_t CC_RsaGenerateVectorInRangeX931(
+                                              CCRndContext_t *rndContext_ptr,
+                                              uint32_t   rndSizeWords,
+                                              uint32_t  *rnd_ptr)
+{
+        /* MIN_WORD = rounded up MS word of (2^(32*rndSizeWords-1))*sqwRoot(2)*/
+#define  MIN_VAL 0xB504F334  /* RL minimal value of MS word of rnd vect. */
+
+        /* FUNCTION DECLARATIONS */
+
+        CCError_t error = CC_OK;
+        uint32_t  msWord;
+        int32_t   i;
+        CCBool_t isFound = CC_FALSE;
+        void   *rndState_ptr;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+        /* FUNCTION LOGIC */
+
+        /* check parameters */
+        if (rndContext_ptr == NULL)
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+
+        rndState_ptr = rndContext_ptr->rndState;
+        RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+        if (RndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        /* .........         Rnd generation       .............. */
+        /* ----------------------------------------------------- */
+
+        while (1) {
+                /* Genrate random prime candidate, considered as 32-bit words */
+                error = RndGenerateVectFunc((void*)rndState_ptr,
+                                            (unsigned char *)rnd_ptr,
+                                            (size_t)rndSizeWords*sizeof(uint32_t));
+                if (error)
+                        goto End;
+
+                /* Find and adust candidate for msWord inside the random *
+                *  vector starting from msWord itself             */
+
+                for (i = rndSizeWords-1; i >= 0; i--) {
+                        /* Set MSBit to 1 */
+                        msWord = rnd_ptr[i] | 0x80000000;
+
+                        if (msWord > MIN_VAL) {
+                                rnd_ptr[rndSizeWords-1] = msWord;
+                                isFound = 1;
+                        }
+
+                        /* Generate new random words instead the checked yet  *
+                        *  (for sequrity goals)                   */
+                        if ((isFound == 1) && (i < (int32_t)rndSizeWords - 1)) {
+                                error = RndGenerateVectFunc((void*)rndState_ptr,
+                                                            (unsigned char *)&rnd_ptr[i],
+                                                            (size_t)(rndSizeWords - 1 - i)*sizeof(uint32_t));
+                                if (error)
+                                        goto End;
+                        }
+
+                        if (isFound == 1)
+                                break;
+                }
+
+                if (isFound) {
+                        rnd_ptr[0] |= 1; /* ensure odd result */
+                        break;
+                }
+        }
+
+        End:
+        return error;
+
+} /* End of CC_RsaGenerateVectorInRangeX931 */
+
+#endif /*_INTERNAL_CC_NO_RSA_KG_SUPPORT*/
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_local.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_local.h
new file mode 100644
index 0000000..303f12c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_local.h
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_RSA_LOCAL_H
+#define _CC_RSA_LOCAL_H
+
+#include "cc_error.h"
+#include "cc_rsa_types.h"
+#include "cc_rnd_common.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* the RSA public key user validity TAG */
+#define CC_RSA_PUB_KEY_VALIDATION_TAG 0x13579BDF
+
+/* the RSA private key user validity TAG */
+#define CC_RSA_PRIV_KEY_VALIDATION_TAG 0x2468ACE0
+
+/* the RSA sign Context user validity TAG */
+#define CC_RSA_SIGN_CONTEXT_VALIDATION_TAG   0x98765432
+#define CC_RSA_VERIFY_CONTEXT_VALIDATION_TAG 0x45678901
+
+
+typedef struct {
+    uint16_t hashResultSize;
+    CCHashOperationMode_t hashMode;
+}RsaHash_t;
+
+extern const RsaHash_t RsaHashInfo_t[CC_RSA_HASH_NumOfModes];
+extern const uint8_t RsaSupportedHashModes_t[CC_RSA_HASH_NumOfModes];
+#ifdef USE_MBEDTLS_CRYPTOCELL
+extern const mbedtls_md_type_t RsaHash_CC_mbedtls_Info[CC_HASH_NumOfModes];
+#endif
+
+/***************
+
+  ASN1 types - for BER Parser - used for PKCS#1 Ver 1.5
+
+***************/
+
+#define ASN1_BOOLEAN        1
+#define ASN1_INTEGER        2
+#define ASN1_BIT_STRING     3
+#define ASN1_OCTET_STRING   4
+#define ASN1_NULL       5
+#define ASN1_OBJECT_IDENTIFIER  6
+#define ASN1_SEQUENCE       16 /* 0x10 */
+#define ASN1_SET        17 /* 0x11 */
+#define ASN1_PRINTABLE_STRING   19 /* 0x13 */
+#define ASN1_TELETEX_STRING 20 /* 0x14 */
+#define ASN1_IA5STRING      22 /* 0x16 */
+#define ASN1_UTC_TIME           23 /* 0x17 */
+
+/**********************
+ structures definition
+ **********************/
+#define TEST_MSB_BIT 0x80
+
+/* Hash algorithm ID (DER code) structure type */
+#define HASH_DER_CODE_MAX_SIZE_BYTES 24
+typedef struct HashDerCode_t {
+    uint32_t algIdSizeBytes;
+    CCHashOperationMode_t hashMode;
+    uint8_t algId[HASH_DER_CODE_MAX_SIZE_BYTES];
+}HashDerCode_t;
+
+/* For security goal the padding string PS in EME-PKCS1-v1_5 encodding method
+   must be at least eight octets long */
+#define PS_MIN_LEN 8
+
+
+/************************ macros ********************************/
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+typedef struct CCRsaOaepData_t{
+    uint8_t  MaskDB[CC_RSA_OAEP_ENCODE_MAX_MASKDB_SIZE];
+    uint8_t  SeedMask[CC_RSA_OAEP_ENCODE_MAX_SEEDMASK_SIZE];
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    mbedtls_md_context_t hash_ctx;
+#else
+    CCHashUserContext_t HashUsercontext;
+#endif
+    CCHashResultBuf_t         HashResultBuff;
+}CC_PAL_COMPILER_TYPE_MAY_ALIAS CCRsaOaepData_t;
+
+/************************ Public Variables **********************/
+
+
+/************************ Public Functions **********************/
+
+/*********************************************************************************/
+/**
+ * @brief The function implements PKCS#1 v1.5 (9.2) EMSA Encoding
+ *        algorithm used in Sign/Verify operations.
+ *
+ * @author reuvenl (9/14/2014)
+ *
+ * @param K - The size of encoded message in octets.
+ * @param hashMode - hash mode ID (enum).
+ * @param pM - The Pointer to the Message M. In case of Sign it is a hash (H).
+ * @param MSize - Denotes the Message size: for Sig/Ver = hashSize,
+ *                for Enc/Dec <= K-hashAlgIdSize-PSS_MIN_LEN-3.
+ * @param pOut - The pointer to a buffer which is at least K octets long.
+ *
+ * @return CCError_t
+ */
+CCError_t RsaEmsaPkcs1v15Encode(
+        uint32_t K,
+            CCHashOperationMode_t hashMode,
+        uint8_t     *pM, /*mess.digest*/
+        uint32_t     MSize,
+        uint8_t     *pOut);
+
+
+
+/**********************************************************************************************************/
+
+CCError_t RsaOaepMGF1( uint16_t hLen, /*size in Bytes*/
+                uint8_t * Z_ptr,
+                uint16_t ZSize,/*size in Bytes*/
+                uint32_t L,
+                uint8_t  *Mask_ptr,
+                CCPkcs1HashFunc_t hashFunc,
+                uint8_t  *T_Buf,    /*T_Buf is a buffer used for data manipulation for the function to use instead of allocating the space on stack*/
+                uint8_t  *T_TMP_Buf);/*T_TMP_Buf is a buffer used for data manipulation for the function to use instead of allocating the space on stack*/
+
+/**********************************************************************************************************/
+/**
+   @brief
+   RsaPssOaepEncode implements the the Encoding operation according to the PKCS#1 as defined
+   in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0
+*/
+CCError_t RsaPssOaepEncode(CCRndContext_t *rndContext_ptr, /* random functions context */
+                             CCPkcs1HashFunc_t hashFunc,     /* PKCS1 hash mode enum */
+                             CCPkcs1Mgf_t MGF,               /* MGF function type enum */
+                             uint8_t *M_ptr,                     /* a pointer to the message to be encoded */
+                             uint16_t MSize,                     /* the message size in bytes */
+                             uint8_t *P_ptr,                     /* a pointer to the label; can be empty string */
+                             size_t PSize,                     /* the size of the label in bytes */
+                             uint16_t emLen, /* The value is set before the call */
+                             CCRsaPrimeData_t  *PrimeData_ptr,/* temp buffer */
+                             uint8_t  *EMInput_ptr,              /* encoded message output */
+                             CCPkcs1Version_t PKCS1_ver);
+
+/**********************************************************************************************************/
+/**
+   @brief
+   RsaPssOaepDecode implements the the De operation according to the PKCS#1 as defined
+   in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0
+*/
+CCError_t RsaPssOaepDecode(CCPkcs1HashFunc_t hashFunc,
+                             CCPkcs1Mgf_t MGF,
+                             uint8_t  *EM_ptr,
+                             uint16_t EMSize,
+                             uint8_t *P_ptr,
+                             size_t  PSize,
+                             CCRsaPrimeData_t  *PrimeData_ptr, /*Only for stack memory save*/
+                             uint8_t *M_ptr,
+                             size_t  *MSize_ptr);
+
+/**********************************************************************************************************/
+/**
+ * @brief
+ * This function does implements the functionality of PKCS1 Ver 2.1 Sign
+ *  operation after the Hash operation
+ *
+ * Before using that function a Hash must be completed on the Data.
+ * The function is called after the call to Hash_Finish
+ *
+ * @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
+ * @param[in] Context_ptr - Pointer to a valid context as
+ *                           given from CC_RsaSign
+ *
+ * @param[out] Output_ptr - A buffer allocated for the output which is at least the size of the MOdulus N
+ *
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+CCError_t RsaPssSign21(CCRndContext_t *rndContext_ptr,
+                                RSAPrivContext_t *Context_ptr,
+                                uint8_t     *Output_ptr);
+
+
+/**********************************************************************************************************/
+/**
+    Function Name: RsaPssVerify21
+    Date:   06-12-2004
+    Author: Ohad Shperling
+
+
+    \brief RsaPssVerify21 implements EMSA-PSS-Verify algorithm
+   as defined in PKCS#1 v2.1 Sec 9.1.2
+
+   @param[in] Context_ptr - Pointer to a valid context as
+                            given from the VerifyFinish function.
+
+   The field HASH_Result inside the Context_ptr is initialized with the Hashed digested message.
+   The field HASH_Result_Size inside the Context_ptr is initialized with the Hash digested message size
+
+   @return CCError_t - CC_OK,or error
+*/
+CCError_t RsaPssVerify21(RSAPubContext_t *Context_ptr);
+
+/**********************************************************************************************************/
+/**
+ * @brief The CC_RsaGenerateVectorInRangeX931 function generates a random vector in range:
+ *            MinVect < RandVect < MaxVect, where:
+ *            MinVect = sqwRoot(2) * 2^(RndSizeInBits-1),  MaxVect = 2^RndSizeInBits.
+ *
+ *            Note: 1. MSBit of RandVect must be set to 1.
+ *                  2. Words order of output vector is set from LS word to MS
+ *                 word.
+ *
+ *        This function is used in PKI RSA for random generation according to ANS X9.31 standard.
+ *        If PKI_RSA is not supported, the function does nothing.
+ *
+ *        Functions algorithm::
+ *
+ *        1.  Calls the CC_RndGenerateVector() function for generating random vector
+ *            RndVect of size RndSizeInWords, rounded up to bytes. Set index i
+ *            to high word i = SizeInWords-1.
+ *        2.  Check and adust candidate for msWord inside the random vector
+ *            starting from msWord himselv, if msWord > high word of MinVect,
+ *            goto step 3, else try next word i--; if no words to try, then goto
+ *            step 1.
+ *        3.  Set the found msWord to high position in array and generate new
+ *            random words instead all checked and rejected words.
+ *
+ * @rndContext_ptr[in/out]  - Pointer to the RND context buffer.
+ * @rndSizeWords[in]  - The size of random vectore that is required.
+ * @rnd_ptr[out]      - The output buffer of size not less, than rndSizeWords.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                       value MODULE_* as defined in ...
+ */
+CCError_t CC_RsaGenerateVectorInRangeX931(CCRndContext_t *rndContext_ptr,
+                                               uint32_t   rndSizeWords,
+                                               uint32_t  *rnd_ptr);
+
+/*****************************************************************************/
+/**
+ * The function generates vector of non zero octets.
+ *
+ * @author reuvenl (9/14/2014)
+ *
+ * @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+ * @param pVect - The pointer to output buffer.
+ * @param size  - The size of vector in bytes.
+ *
+ * @return CCError_t
+ */
+CCError_t  RsaGenRndNonZeroVect(CCRndContext_t *rndContext_ptr, uint8_t *pVect, uint32_t size);
+
+
+/**********************************************************************************************************/
+/*!
+@brief RSA_SignInit initializes the Signing multi-call algorithm as defined in PKCS#1 2.1 standard, including v1.5.
+
+NOTE:
+-# In PSS_Sign v2.1 MD5 is not supported, since it is not recommended by the PKCS#1 v2.1.
+-# According to the said standard, implementation of the function for version v1.5 is based on DER encoding of the algorithm info.
+
+This function does not do cryptographic processing. Rather, it
+prepares a context that is used by the Update and Finish functions.
+
+@return CC_OK on success.
+@return error on failure
+*/
+CIMPORT_C CCError_t CC_RsaSignInit(
+                            CCRsaPrivUserContext_t *UserContext_ptr,     /*!< [in/out] A pointer to a Context. The value returned here must be passed to the Update and Finish functions. */
+                            CCRsaUserPrivKey_t *UserPrivKey_ptr,         /*!< [in]  A pointer to the private key data structure.
+                                                                                       \note The representation (pair or quintuple) and hence the algorithm (CRT or not) is determined by the Private Key data structure.
+                                                                                       Using of the CC_BuildPrivKey or CC_BuildPrivKeyCRT determines which algorithm is used. */
+                            CCRsaHashOpMode_t rsaHashMode,             /*!< [in]  The enumerator value, defining the hash function to be used: SHA-1,SHA224/256/384/512, MD5 (MD5 allowed only in v1.5).
+                                                                                        The hash functions recommended by PKCS#1 v2.1 are: 256/384/512. Also allowed "After" HASH modes for said functions. */
+                            CCPkcs1Mgf_t MGF,                           /*!< [in]  The mask generation function. PKCS#1 v2.1 defines MGF1, so the only value allowed here is CC_PKCS1_MGF1. */
+                            size_t SaltLen,                 /*!< [in]  The Length of the Salt buffer (relevant for PKCS#1 Ver 2.1 only, typically lengths is 0 or hLen). FIPS 186-4 requires,
+                                                                                       that SaltLen <= hlen. If SaltLen > KeySize - hLen - 2, the function returns an error. */
+                            CCPkcs1Version_t PKCS1_ver          /*!< [in]  Ver 1.5 or 2.1, according to the functionality required. */
+);
+
+/**********************************************************************************************************/
+/*!
+@brief CC_RsaSignUpdate processes the data to be signed in a given context.
+
+@note CC_RsaSignUpdate can be called multiple times with data
+
+@return CC_OK on success.
+@return Error on failure
+*/
+CIMPORT_C CCError_t CC_RsaSignUpdate(
+                                CCRsaPrivUserContext_t *UserContext_ptr,     /*!< [in] A pointer to a valid context, as returned by CC_RsaSignInit. */
+                                uint8_t     *DataIn_ptr,                        /*!< [in] A pointer to the data to sign. */
+                                size_t      DataInSize                         /*!< [in] The size, in bytes, of the data to sign. */
+);
+
+/**********************************************************************************************************/
+/*!
+@brief CC_RsaSignFinish calculates the signature on the data passed to one or more calls to CC_RsaSignUpdate,
+and releases the context.
+
+@return CC_OK on success.
+@return Error on failure:\n
+            CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR,\n
+            CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR,\n
+            CC_RSA_INVALID_OUTPUT_POINTER_ERROR,\n
+            CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE,\n
+            CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR,\n
+            CC_RSA_PKCS1_VER_ARG_ERROR
+*/
+
+CIMPORT_C CCError_t CC_RsaSignFinish(
+                                CCRndContext_t *rndContext_ptr,             /*!< [in/out] Pointer to the RND context buffer. */
+                                CCRsaPrivUserContext_t *UserContext_ptr,     /*!< [in/out] A pointer to the Context initialized by the SignInit function and used by the SignUpdate function. */
+                                uint8_t     *Output_ptr,                        /*!< [out] A pointer to the signature.
+                                                                                            The buffer must be at least PrivKey_ptr->N.len bytes long (that is, the size of the modulus, in bytes). */
+                                size_t      *OutputSize_ptr                     /*!< [in/out] A pointer to the Signature Size value -
+                                                                                                the input value is the signature buffer size allocated, the output value is the signature size used.
+                                                                                                The buffer must be at least PrivKey_ptr->N.len bytes long (that is, the size of the modulus, in bytes). */
+);
+
+/**********************************************************************************************************/
+/*!
+@brief  RSA_VerifyInit initializes the Verify multi-call algorithm as defined in PKCS#1 v1.5 and 2.1
+
+note:
+-# In PSS_Sign v2.1 MD5 is not supported, since it is not recommended by the PKCS#1 v2.1.
+-# According to the said standard, implementation of the function for version v1.5 is based on DER encoding of the algorithm info.
+
+@return CC_OK on success.
+@return Error on failure
+*/
+CIMPORT_C CCError_t CC_RsaVerifyInit(
+                            CCRsaPubUserContext_t *UserContext_ptr,      /*!< [in]  A pointer to the public Context structure of the User. */
+                            CCRsaUserPubKey_t *UserPubKey_ptr,           /*!< [in]  A pointer to the public key data structure. */
+                            CCRsaHashOpMode_t rsaHashMode,             /*!< [in]  The hash function to be used. Currently available HASH functions: SHA1/SHA-256/384/512/MD5 (MD5 - allowed only for PKCS#1 v1.5).
+                                                                                        Also allowed "After HASH" modes for said functions. */
+                            CCPkcs1Mgf_t MGF,                           /*!< [in]  The mask generation function, relevant only for PKCS#1 v2.1. The currently allowed value for v2.1 is CC_PKCS1_MGF1. */
+                            size_t  SaltLen,                               /*!< [in]  The Length of the Salt buffer. Relevant for PKCS#1 Ver 2.1 only. Typical lengths are 0 and hashLen (20 for SHA1).
+                                                                                        The maximum length allowed is NSize - hLen - 2.
+                                                                                        If the salt length is not available in this process, the user can use the define: CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN.
+                                                                                        Security Note: This mode is not FIPS approved and it is recommended not to use this flag and provide the Salt length
+                                                                                        on each verification. */
+                            CCPkcs1Version_t PKCS1_ver                    /*!< [in]  Ver 1.5 or 2.1, according to the functionality required. */
+);
+
+/**********************************************************************************************************/
+/*!
+@brief RSA_VerifyUpdate processes the data to be verified in a given context, according to PKCS1 v1.5 and 2.1
+@brief RSA_VerifyUpdate can be called multiple times with data
+
+@return CC_OK on success.
+@return Error on failure
+*/
+
+CIMPORT_C CCError_t CC_RsaVerifyUpdate(
+                                CCRsaPubUserContext_t *UserContext_ptr,      /*!< [in]  A pointer to the public Context structure of the User. */
+                                uint8_t     *DataIn_ptr,                        /*!< [in]  A pointer to the data whose signature is to be verified. */
+                                size_t       DataInSize                         /*!< [in]  The size, in bytes, of the data whose signature is to be verified. */
+);
+
+/**********************************************************************************************************/
+/*!
+@brief RSA_VerifyFinish implements the Finish Phase of the Verify algorithm as defined in PKCS#1 v2.1 or PKCS#1 v1.5
+
+@return CC_OK on success.
+@return Error on failure
+*/
+
+CIMPORT_C CCError_t CC_RsaVerifyFinish(
+                            CCRsaPubUserContext_t *UserContext_ptr,      /*!< [in]  A pointer to the public Context structure of the User. */
+                            uint8_t *Sig_ptr                                /*!< [in]  A pointer to the signature to be verified.
+                                                                                        The length of the signature is PubKey_ptr->N.len bytes (that is, the size of the modulus, in bytes). */
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_oaep.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_oaep.c
new file mode 100644
index 0000000..1a7e097
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_oaep.c
@@ -0,0 +1,771 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_common_math.h"
+#include "cc_rsa_error.h"
+#ifndef USE_MBEDTLS_CRYPTOCELL
+#include "cc_hash.h"
+#endif
+#include "cc_hash_defs.h"
+#include "cc_rsa_local.h"
+#include "cc_rnd_error.h"
+#include "cc_general_defs.h"
+
+/************************ Defines ****************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ***************************/
+
+/************************ Global Data *************************/
+
+#ifdef DEBUG_OAEP_SEED
+#include "CRYS_RSA_PSS21_defines.h"
+extern uint8_t SaltDB[NUM_OF_SETS_TEST_VECTORS][NUM_OF_TEST_VECTOR_IN_SET][CC_RSA_PSS_SALT_LENGTH];
+extern uint16_t Global_Set_Index;
+extern uint16_t Global_vector_Index;
+#endif
+
+/************* Private function prototype ****************/
+
+
+
+#if !defined(_INTERNAL_CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)
+/************************ Public Functions ******************************/
+/**
+   @brief
+   RsaPssOaepEncode implements the the Encoding operation according to the PKCS#1 as defined
+   in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0
+*/
+CCError_t RsaPssOaepEncode(
+                                   CCRndContext_t *rndContext_ptr, /* random functions context */
+                                   CCPkcs1HashFunc_t hashFunc,     /* PKCS1 hash mode enum */
+                                   CCPkcs1Mgf_t MGF,               /* MGF function type enum */
+                                   uint8_t *M_ptr,                     /* a pointer to the message to be encoded */
+                                   uint16_t MSize,                     /* the message size in bytes */
+                                   uint8_t *P_ptr,                     /* a pointer to the label; can be empty string */
+                                   size_t   PSize,                     /* the size of the label in bytes */
+                                   uint16_t emLen, /* The value is set before the call */
+                                   CCRsaPrimeData_t  *PrimeData_ptr,/* temp buffer */
+                                   uint8_t  *EMInput_ptr,              /* encoded message output */
+                                   CCPkcs1Version_t PKCS1_ver)
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /*For PKCS1 Ver21 standard: emLen = k = Public mod N size*/
+        /*Used for output of MGF1 function ; the size is at most emLen */
+        uint8_t *MaskDB_Ptr =((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB;
+        uint32_t HashOutputSize;
+        uint16_t TmpSize, I;
+        uint8_t *TmpByte_ptr;
+        uint8_t *EM_ptr = &EMInput_ptr[1];
+        uint8_t VersionConstant;   /*Used to distinguish between Ver 2.1 and others for some memory manipulations*/
+
+#ifdef DEBUG_OAEP_SEED
+        uint8_t *SeedTEST = SaltDB[Global_Set_Index][Global_vector_Index]; /*A Data Base created in the test file for checking the Encrypted operation*/
+#endif/*otherwise the seed is generated strait to EM_ptr*/
+
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        const mbedtls_md_info_t *md_info=NULL;
+        mbedtls_md_context_t *md_ctx=NULL;
+#endif
+
+        void   *rndState_ptr;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+        /* FUNCTION LOGIC */
+
+        /* check parameters */
+        if (rndContext_ptr == NULL)
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+
+        rndState_ptr = (rndContext_ptr->rndState);
+        RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+        if (RndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        /* .................. initializing local variables ................... */
+        /* ------------------------------------------------------------------- */
+
+        /*Initializing the first Byte to Zero*/
+        EMInput_ptr[0] = 0;
+
+        /* get HASH output size */
+        switch (hashFunc) {
+        case CC_HASH_MD5_mode :
+                HashOutputSize = CC_HASH_MD5_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_HASH_SHA1_mode:
+                HashOutputSize = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_HASH_SHA224_mode:
+                HashOutputSize = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_HASH_SHA256_mode:
+                HashOutputSize = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_HASH_SHA384_mode:
+                HashOutputSize = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+                break;
+        case CC_HASH_SHA512_mode:
+                HashOutputSize = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+                break;
+        default:
+                return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+        // RL Version = 2
+        if (PKCS1_ver == CC_PKCS1_VER21)
+                VersionConstant = 2;
+        else
+                VersionConstant = 1;
+
+/*------------------------------------------------------------*
+ * Step 1 : If the length of P is greater than                *
+ *           the input limitation for the hash                *
+ *           function (2^29 octets for SHA-1)                 *
+ *           then output "parameter string too long" and stop *
+ *                                                            *
+ *           In PKCS1_Ver2.1 L = P                            *
+ *------------------------------------------------------------*/
+
+/* if the P  larger then 2^29 which is the input limitation for HASH
+   return error (to prevent an overflow on the transition to bits ) */
+        if (PSize >= (1 << 29))
+                return CC_RSA_BASE_OAEP_ENCODE_PARAMETER_STRING_TOO_LONG;
+
+/*-------------------------------------------------*
+ * Step 2 : If ||M|| > emLen-2hLen-1 then output   *
+ *   "message too long" and stop.                  *
+ *                                                 *
+ * for PKCS1_Ver2.1 Step 1 <b>:            *
+ * If ||M|| > emLen - 2hLen - 2                    *
+ *-------------------------------------------------*/
+
+        if ((uint32_t)MSize + 2 * HashOutputSize + VersionConstant > emLen)
+                return CC_RSA_BASE_OAEP_ENCODE_MESSAGE_TOO_LONG;
+
+/*-----------------------------------------------------*
+ * Step 3 : Generate an octet string PS consisting of  *
+ *           emLen-||M||-2hLen-1 zero octets.          *
+ *           The length of PS may be 0.                *
+ *                                                     *
+ * PKCS1_VER21 Step 2 <b>                  *
+ *       Generate an octet string PS consisting of *
+ *           emLen-||M||-2hLen-2 zero octets.          *
+ *           The length of PS may be 0                 *
+ *-----------------------------------------------------*/
+        CC_PalMemSetZero((uint8_t*)&EM_ptr[2*HashOutputSize], emLen-MSize-2*HashOutputSize-VersionConstant);
+
+/*--------------------------------------------------------------*
+ * Step 4 : Let pHash = Hash(P), an octet string of length hLen.*
+ * PKCS1_VER21 Step 2 <a> where L is denoted by P and usually   *
+ * an empty string                                              *
+ *--------------------------------------------------------------*/
+        if (P_ptr!=NULL) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
+                if (NULL == md_info) {
+                     return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+                Error = mbedtls_md(md_info,
+                                   P_ptr,
+                                   PSize,
+                                   (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+ #else
+                Error=CC_Hash( hashFunc,
+                                 P_ptr,
+                                 PSize,
+                                 ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+#endif
+                if (Error!=CC_OK) {
+                        goto End;
+                }
+        } else {/* if empty string */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                md_ctx = &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->hash_ctx);
+                md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
+                if (NULL == md_info) {
+                        return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+                mbedtls_md_init(md_ctx);
+                Error = mbedtls_md_setup(md_ctx, md_info, 0); // 0 = HASH, not HMAC
+                if (Error != 0) {
+                        goto End;
+                }
+                Error = mbedtls_md_starts(md_ctx);
+#else
+                Error=CC_HashInit(&(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext),
+                                     hashFunc);
+#endif
+                if (Error!=CC_OK) {
+                        goto End;
+                }
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                Error = mbedtls_md_finish(md_ctx, (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+#else
+                Error=CC_HashFinish( &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext) ,
+                                        ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+#endif
+                if (Error!=CC_OK) {
+                        goto End;
+                }
+        }
+        /*Copy the Hash result to the proper place in the output buffer*/
+        CC_PalMemCopy(&EM_ptr[HashOutputSize], (uint8_t *)(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff), HashOutputSize);
+
+/*---------------------------------------------------------*
+ * Step 5 : Concatenate pHash, PS, the message M,          *
+ *           and other padding to form a data block DB     *
+ * PKCS1_VER21 Step 2 <c>                                  *
+ *      Concatenate pHash, PS, the message M,              *
+ *       and other padding to form a data block DB as      *
+ *       DB = pHash || PS || 01 || M                       *
+ *---------------------------------------------------------*/
+        /* EM_ptr[emLen-MSize-1]=0x01;*/
+        EM_ptr[emLen - MSize - 1 - (VersionConstant-1)] = 0x01;/*because emLen = PubNSize; but EM_ptr points to place 1*/
+    if (MSize > 0) // need to copy only if there is data
+        CC_PalMemCopy((uint8_t*)&EM_ptr[emLen - MSize - (VersionConstant - 1)], M_ptr, MSize);/*because emLen = PubNSize; but EM_ptr points to place 1 */
+
+/*--------------------------------------------------------------*
+ * Step 6 : Generate a random octet string seed of length hLen. *
+ * PKCS1_VER21 Step 2.d: Generate a random octet string seed    *
+ *                       of length hLen.                        *
+ *--------------------------------------------------------------*/
+
+#ifdef DEBUG_OAEP_SEED
+        /*Only for PKCS#1 ver2.1 SHA1 - Salt length is 20*/
+        CC_PalMemCopy(EM_ptr, SeedTEST,CC_RSA_PSS_SALT_LENGTH);
+#else
+        Error = RndGenerateVectFunc(rndState_ptr, (unsigned char *)EM_ptr, (size_t)HashOutputSize);
+        if (Error != CC_OK) {
+                goto End;
+        }
+
+#endif
+
+/*-----------------------------------------------*
+ * Step 7 : Let dbMask = MGF(seed, emLen-hLen).  *
+ * PKCS1_VER21 Step 2 <e> Let                    *
+ *      dbMask = MGF(seed, emLen-hLen-1).        *
+ *-----------------------------------------------*/
+
+        switch (MGF) {
+        case CC_PKCS1_MGF1:
+
+                Error = RsaOaepMGF1(
+                                         HashOutputSize,                                                          /*hashLen*/
+                                         &EM_ptr[0],                                                              /*mgfSeed*/
+                                         HashOutputSize,                                                          /*seedLen*/
+                                         emLen-HashOutputSize-(VersionConstant-1),                                /*maskLen*/
+                                         &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[0]), /*mask*/
+                                         hashFunc,                                                                /*hashMode*/
+                                         (uint8_t *)PrimeData_ptr->DataIn,                                        /*1-st tempBuff*/
+                                         (uint8_t *)PrimeData_ptr->DataOut);                                      /*2-nd tempBuff*/
+
+                if (Error != CC_OK) {
+                        goto End;
+                }
+                break;
+
+        /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
+        case CC_PKCS1_NO_MGF:
+        default:
+                Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+                goto End;
+        }
+
+        /*----------------------------------------------*
+        *  Step 8 : PKCS1_VER21 Step 2.f:               *
+        *             Let maskedDB = DB xor dbMask.     *
+        *-----------------------------------------------*/
+
+        TmpSize = emLen - HashOutputSize - (VersionConstant - 1);
+        TmpByte_ptr = &EM_ptr[HashOutputSize];
+        for (I = 0; I < TmpSize; I++)
+                *(TmpByte_ptr + I) ^= ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[I];
+
+        MaskDB_Ptr = TmpByte_ptr;
+
+/*-----------------------------------------------*
+ * Step 9 : Let seedMask = MGF(maskedDB, hLen).  *
+ * PKCS1_VER21 Step 2.g                          *
+ *-----------------------------------------------*/
+
+        switch (MGF) {
+        case CC_PKCS1_MGF1:
+
+                Error = RsaOaepMGF1(
+                                 HashOutputSize, /* This is important its uint32 as a result of size limits */
+                                 MaskDB_Ptr,
+                                 (uint16_t)(emLen-HashOutputSize-(VersionConstant-1)),
+                                 HashOutputSize,
+                                 &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[0]),
+                                 hashFunc,
+                                 (uint8_t *)PrimeData_ptr->DataIn,
+                                 (uint8_t *)PrimeData_ptr->DataOut);
+
+                if (Error != CC_OK)
+                        goto End;
+
+                break;
+
+                /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
+        case CC_PKCS1_NO_MGF:
+        default:
+                Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+                goto End;
+
+        }/* end of MGF type switch */
+
+/*-----------------------------------------------*
+ * Step 10: Let maskedSeed = seed \xor seedMask. *
+ * PKCS1_VER21 Step 2 <h>                        *
+ *-----------------------------------------------*/
+
+        TmpSize = HashOutputSize;
+        TmpByte_ptr =& EM_ptr[0];
+        for (I = 0;I < TmpSize; I++)
+                *(TmpByte_ptr + I)^=((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[I];
+
+/*---------------------------------------------*
+ *  * Step 11:  PKCS1_VER21 Step 2.i:          *
+ * Let EM = 0x00 || maskedSeed || maskedDB.    *
+ * This step is done !                         *
+ *---------------------------------------------*/
+
+        End:
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        if((md_info!=NULL) && (md_ctx!=NULL)) {
+                mbedtls_md_free(md_ctx);
+        }
+#endif
+        /*Clear Internal buffers*/
+        CC_PalMemSetZero((PrimeData_ptr->InternalBuff), sizeof(PrimeData_ptr->InternalBuff));
+        return Error;
+
+}
+#endif /* !defined(CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
+
+#if !defined(CC_NO_RSA_DECRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)
+
+/**
+   @brief
+   RsaPssOaepDecode implements the Decoding operation according to the
+   PKCS#1 as defined in PKCS#1 v2.1 and PKCS#1 v2.0
+*/
+CCError_t RsaPssOaepDecode(
+                                   CCPkcs1HashFunc_t hashFunc,
+                                   CCPkcs1Mgf_t MGF,
+                                   uint8_t  *EM_ptr,
+                                   uint16_t EMSize,
+                                   uint8_t *P_ptr,
+                                   size_t  PSize,
+                                   CCRsaPrimeData_t  *PrimeData_ptr, /*Only for stack memory save*/
+                                   uint8_t *M_ptr,
+                                   size_t  *MSize_ptr)
+{
+        /* FUNCTION DECLERATIONS */
+
+        uint8_t HashOutputSize;
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+        uint8_t  *maskedDB_ptr;
+        uint16_t  I, TmpSize;
+        uint8_t  *TmpByte_ptr;
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        const mbedtls_md_info_t *md_info=NULL;
+        mbedtls_md_context_t *md_ctx=NULL;
+#endif
+
+        /* FUNCTION LOGIC */
+
+        /* .................. initializing local variables ................... */
+        /* ------------------------------------------------------------------- */
+
+        /* get hash output size */
+        switch (hashFunc) {
+        case CC_HASH_MD5_mode : /*MD5 is not recomended in PKCS1 ver 2.1 standard,
+                                    henceit is not supported */
+                return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        case CC_HASH_SHA1_mode:
+                HashOutputSize = CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                break;
+        case CC_HASH_SHA224_mode:
+                HashOutputSize = CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                break;
+        case CC_HASH_SHA256_mode:
+                HashOutputSize = CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                break;
+        case CC_HASH_SHA384_mode:
+                HashOutputSize = CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                break;
+        case CC_HASH_SHA512_mode:
+                HashOutputSize = CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                break;
+        default:
+                return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+
+/*For PKCS1 Ver 2.1 P=L*/
+/*--------------------------------------------------------*
+ * Step 1: if the length of P is greater than the input   *
+ *         limitation of the hash function (2^29 octets *
+ *         for SHA-1) then output "decoding error"        *
+ *          and stop.                                     *
+ *--------------------------------------------------------*/
+        if (PSize >= (1 << 29))
+                return CC_RSA_BASE_OAEP_DECODE_PARAMETER_STRING_TOO_LONG;
+
+/*-------------------------------------------------------*
+ * Step 2: If ||EM|| < 2hLen+2, then output              *
+ *        "decoding error" and stop.                     *
+ *        Note: There EMSize = ||EM|| - 1                *
+ *-------------------------------------------------------*/
+        if (EMSize <  2*HashOutputSize + 1)
+                return CC_RSA_BASE_OAEP_DECODE_MESSAGE_TOO_LONG;
+/*-------------------------------------------------------*
+ * Step 3: Let maskedSeed be the first hLen octets of EM *
+ *         and let maskedDB be the remaining             *
+ *         ||EM|| - hLen octets.                         *
+ * PKCS1 Ver2.1: Step <3> <b>                            *
+ *-------------------------------------------------------*/
+        maskedDB_ptr = EM_ptr + HashOutputSize;
+
+/*-------------------------------------------------------*
+ * Step 4: Let seedMask = MGF(maskedDB, hLen).           *
+ * PKCS1 Ver2.1: Step <3> <c>                            *
+ *-------------------------------------------------------*/
+
+        switch (MGF) {
+        case CC_PKCS1_MGF1:
+
+                Error = RsaOaepMGF1(
+                                         HashOutputSize,                                                             /*hashLen*/
+                                         maskedDB_ptr,                                                               /*mgfSeed - in*/
+                                         (uint16_t)(EMSize - HashOutputSize),                                        /*seedLen*/
+                                         HashOutputSize,                                                             /*maskLen*/
+                                         &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[0]),  /*mask - out*/
+                                         hashFunc,                                                                   /*hashMode*/
+                                         (uint8_t *)PrimeData_ptr->DataIn,                                           /*1-st tempBuff*/
+                                         (uint8_t *)PrimeData_ptr->DataOut);                                         /*2-nd tempBuff*/
+                if (Error != CC_OK) {
+                        return Error;
+                }
+                break;
+
+        /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
+        case CC_PKCS1_NO_MGF:
+        default:
+                return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+
+        }
+
+/*-------------------------------------------------------*
+ * Step 5: Let seed = maskedSeed xor seedMask.           *
+ * PKCS1 Ver2.1: Step <3> <d>                            *
+ *-------------------------------------------------------*/
+        for (I = 0; I < HashOutputSize; I++)
+                EM_ptr[I] ^= ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[I];
+
+/*-------------------------------------------------------*
+ * Step 6: Let dbMask = MGF(seed, ||EM|| - hLen).        *
+ * PKCS1 Ver2.1: Step <3> <e>                            *
+ *-------------------------------------------------------*/
+        Error=RsaOaepMGF1(
+                               HashOutputSize,
+                               EM_ptr,
+                               HashOutputSize,
+                               EMSize - HashOutputSize,
+                               &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[0]),
+                               hashFunc,
+                               (uint8_t *)PrimeData_ptr->DataIn,
+                               (uint8_t *)PrimeData_ptr->DataOut);
+
+        if (Error!=CC_OK)
+                return Error;
+
+/*-------------------------------------------------------*
+ * Step 7: Let DB = maskedDB xor dbMask.                 *
+ *         PKCS1 Ver2.1: Step <3> <f>                    *
+ *-------------------------------------------------------*/
+        TmpSize = EMSize - HashOutputSize;
+        TmpByte_ptr = &EM_ptr[0] + HashOutputSize;
+        for (I = 0; I < TmpSize; I++)
+                TmpByte_ptr[I] ^= ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[I];
+
+/*-------------------------------------------------------*
+ * Step 8: Let pHash = Hash(P), an octet string of       *
+ *         length hLen.                                  *
+ *                                                       *
+ * PKCS1 Ver2.1: Step <3> <a>                            *
+ *-------------------------------------------------------*/
+        if (P_ptr!=NULL) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
+                if (NULL == md_info)
+                {
+                    return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+                Error = mbedtls_md(md_info,
+                                   P_ptr,
+                                   PSize,
+                                   (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+#else
+                Error = CC_Hash(
+                                 hashFunc,
+                                 P_ptr,
+                                 PSize,
+                                 ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+#endif
+                if (Error!=CC_OK) {
+                        return Error;
+                }
+        } else {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                md_ctx = &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->hash_ctx);
+                md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
+                if (NULL == md_info) {
+                        return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+                mbedtls_md_init(md_ctx);
+                Error = mbedtls_md_setup(md_ctx, md_info, 0); // 0 = HASH, not HMAC
+                if (Error != 0) {
+                        goto End;
+                }
+                Error = mbedtls_md_starts(md_ctx);
+#else
+                Error=CC_HashInit(&(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext),
+                                  hashFunc);
+#endif
+                if (Error!=CC_OK) {
+                        goto End;
+                }
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                Error = mbedtls_md_finish(md_ctx, (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+#else
+                Error=CC_HashFinish( &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext),
+                                        ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
+#endif
+                if (Error!=CC_OK) {
+                        goto End;
+                }
+        }
+
+
+/*---------------------------------------------------------*
+ * Step 9: Separate DB into an octet string pHash'         *
+ *         consisting of the first hLen octets of DB,      *
+ *         a (possibly empty) octet string PS consisting   *
+ *         of consecutive zero octets following pHash',    *
+ *         and a message M as DB = pHash' || PS || 01 || M *
+ *         If there is no 01 octet to separate PS from M,  *
+ *         output "decoding error" and stop.               *
+ *                                                         *
+ * PKCS1 Ver2.1: Step <3> <g>                              *
+ *---------------------------------------------------------*/
+        TmpSize = EMSize - 2*HashOutputSize;
+        TmpByte_ptr = &EM_ptr[0] + 2*HashOutputSize;
+        for (I = 0; I < TmpSize; I++) {
+                if (TmpByte_ptr[I] != 0x00)
+                        break;
+        }
+
+        if (TmpByte_ptr[I] != 0x01){
+                Error = CC_RSA_OAEP_DECODE_ERROR;
+                goto End;
+        }
+
+        TmpByte_ptr += I;
+
+/*------------------------------------------------------*
+ * Step 10: If pHash' does not equal pHash, output      *
+ *          "decoding error" and stop.                  *
+ *                                                      *
+ * PKCS1 Ver2.1: Step <3> <g>                           *
+ *------------------------------------------------------*/
+        if (CC_PalMemCmp(&EM_ptr[0] + HashOutputSize,
+                        (uint8_t *)(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff),
+                        HashOutputSize)) {
+                Error = CC_RSA_OAEP_DECODE_ERROR;
+                goto End;
+        }
+
+/*-----------------------------------------------*
+ * Step 11: Output M.                            *
+ *-----------------------------------------------*/
+        /*Checking that the Output buffer Size is enough large for result output */
+        if (*MSize_ptr < (uint32_t)(EMSize - 2*HashOutputSize - I - 1)) {
+                Error = CC_RSA_DECRYPT_INVALID_OUTPUT_SIZE;
+                goto End;
+        }
+
+        else if (*MSize_ptr > (uint32_t)(EMSize - 2*HashOutputSize - I - 1)) {
+                /* set the actual output message size */
+                *MSize_ptr = EMSize - 2*HashOutputSize - I - 1;
+        }
+
+        /* at this point TmpByte_ptr points to 01 */
+        TmpByte_ptr += 1;
+
+        /* at this point TmpByte_ptr points to M  */
+        CC_PalMemCopy( M_ptr, TmpByte_ptr, *MSize_ptr );
+
+        End:
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        if((md_info!=NULL) && (md_ctx!=NULL)) {
+                mbedtls_md_free(md_ctx);
+        }
+#endif
+
+        /*Clear Internal buffers*/
+        CC_PalMemSetZero((PrimeData_ptr->InternalBuff), sizeof(PrimeData_ptr->InternalBuff));
+
+        return Error;
+
+}
+#endif /*!defined(CC_NO_RSA_DECRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)*/
+
+
+/**********************************************************************************************************/
+
+/* -------------------------------------------------------------
+ *  Function Name: RsaOaepMGF1
+ *  Date:   09-1-2005
+ *  Author: Ohad Shperling
+ *
+ *  Inputs:
+ *  Outputs:
+ *
+ *  Algorithm: according to PKCS1-v.2_1
+ *
+ *  Update History:
+ *  Date:       Description:
+ * ----------------------------------------------------------- */
+CCError_t RsaOaepMGF1( uint16_t hLen,                  /*hashLen*/
+                               uint8_t *Z_ptr,                 /*mgfSeed*/
+                               uint16_t ZSize,                 /*seedLen*/
+                               uint32_t L,                     /*maskLen*/
+                               uint8_t  *Mask_ptr,             /*mask*/
+                               CCPkcs1HashFunc_t hashFunc, /*hashMode*/
+                               uint8_t  *T_Buf,                /*1-st tempBuff*/
+                               uint8_t  *T_TMP_Buf)            /*2-nd tempBuff*/
+{
+
+        /* FUNCTION DECLARATIONS */
+
+        CCError_t Error;
+        uint32_t Counter = 0;
+        uint32_t CounterMaxSize, Tmp32Bit;
+        CCHashResultBuf_t  HashResultBuff;
+        uint8_t *Output_ptr;
+        uint8_t *T = T_Buf;/*The size of T for MGF1 used to be 2048/8 now the size of T_Buf in the context is even bigger*/
+        uint8_t *T_TMP = T_TMP_Buf;
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        const mbedtls_md_info_t *md_info=NULL;
+#endif
+
+
+/*---------------------------------------------------------------------*
+ * Step 1:  If l > 2^32 hLen, output "mask too long" and stop.          *
+ *---------------------------------------------------------------------*/
+
+        /* note: check L > (uint32_t)(CC_RSA_MGF_2_POWER_32 *hLen) not needed
+                 because next check is more stronger */
+
+        /* limit the size to the temp buffer size that is the maximum key length */
+        if (L > CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS * sizeof(uint32_t))
+                return CC_RSA_BASE_MGF_MASK_TOO_LONG ;
+
+/*---------------------------------------------------------------------*
+ * Step 2:  Let T  be the empty octet string.                          *
+ *---------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------*
+ * Step 3:  For counter from 0 to  | l / hLen | -1 , do the following: *
+ *          a.  Convert counter to an octet string C of length 4       *
+ *              with the primitive I2OSP:                              *
+ *               C = I2OSP (counter, 4)                                *
+ *          b.  Concatenate the hash of the seed Z and C to the octet  *
+ *               string T:   T = T || Hash (Z || C)                    *
+ *---------------------------------------------------------------------*/
+        Output_ptr = T;
+        CC_PalMemCopy(T_TMP, Z_ptr/*seed*/, ZSize);
+
+        /* count of Hash blocks needed for mask calculation */
+        CounterMaxSize = (uint32_t)((L + hLen - 1)/hLen);
+
+        for (Counter = 0; Counter < CounterMaxSize; Counter++) {
+
+                /*--------------------------------------------------------------------
+                 *          a.  Convert counter to an octet string C of length 4
+                 *              with the primitive I2OSP:   C = I2OSP (counter, 4)
+                 *--------------------------------------------------------------------*/
+
+                /* T_TMP = H||C */
+
+#ifndef BIG__ENDIAN
+                Tmp32Bit = CC_COMMON_REVERSE32(Counter);
+#else
+                Tmp32Bit = Counter;
+#endif
+
+                CC_PalMemCopy(&T_TMP[0] + ZSize, &Tmp32Bit, sizeof(uint32_t));
+
+                /*--------------------------------------------------------------------
+                 *          b.  Concatenate the hash of the seed Z and C to the octet
+                 *               string T: T = T || Hash (Z || C)
+                 *--------------------------------------------------------------------*/
+
+                /* Hash Z||C */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
+                if (NULL == md_info)
+                {
+                    return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+                Error = mbedtls_md(md_info,
+                        T_TMP,
+                        ZSize + sizeof(uint32_t)/*counterSize*/,
+                        (unsigned char *)HashResultBuff);
+                if (0 != Error)
+                {
+                        return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+#else
+                Error = CC_Hash(hashFunc,
+                                T_TMP,
+                                ZSize + sizeof(uint32_t)/*counterSize*/,
+                                HashResultBuff);
+
+                if (Error!=CC_OK)
+                        return Error;
+#endif
+                CC_PalMemCopy(Output_ptr, (uint8_t *)HashResultBuff, hLen);
+                Output_ptr += hLen;
+        }
+
+/*---------------------------------------------------------------------*
+ * Step 4:  Output the leading L octets of T as the octet string mask. *
+ *---------------------------------------------------------------------*/
+        CC_PalMemCopy(Mask_ptr,(uint8_t *)T, L);
+
+        return CC_OK;
+}
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_pkcs_ver15_util.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_pkcs_ver15_util.c
new file mode 100644
index 0000000..bdf5be6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_pkcs_ver15_util.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_ASYM_RSA_DH
+
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include "cc_common_math.h"
+#include "cc_rsa_local.h"
+#include "cc_rsa_error.h"
+#include "cc_rnd_error.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ***************************/
+
+/************************ Public Functions *******************/
+
+
+#if !defined(_INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT)
+
+/************************ Global Data ******************************/
+/* DER(BER) encoded data for allowed HASH algorithms */
+/*typedef struct HashDerCode_t {
+        uint32_t algIdSizeBytes;
+        CCHashOperationMode_t hashMode;
+        uint8_t algId[HASH_DER_CODE_MAX_SIZE_BYTES];
+}*/
+/*   Note: order of algorithms in array must be according to HASH mode ID */
+static const HashDerCode_t gHashDerCodes[] = {
+        {15, CC_HASH_SHA1_mode,  {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14}},                     /*SHA1*/
+        {19, CC_HASH_SHA224_mode,{0x30,0x2D,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1C}}, /*SHA224*/
+        {19, CC_HASH_SHA256_mode,{0x30,0x31,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}}, /*SHA256*/
+        {19, CC_HASH_SHA384_mode,{0x30,0x41,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}}, /*SHA384*/
+        {19, CC_HASH_SHA512_mode,{0x30,0x51,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}}, /*SHA512*/
+        {18, CC_HASH_MD5_mode,   {0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10}},      /*MD5*/
+};
+
+/*************************** Private functions **********************/
+
+/**
+ * The function gets DER code of choosen Hash algoritm.
+ *
+ * @author reuvenl (9/11/2014)
+ *
+ * @param hashMode - Hash mode enumeration.
+ * @param pAlgId - The pointer to Hash algoritm DER code;
+ * @param pAlgIdSize - The size of the Hash algoritm DER code;
+ *
+ * @return CCError_t
+ */
+static CCError_t GetHashAlgDerCode(
+                                    CCHashOperationMode_t hashMode,
+                                    const uint8_t **pAlgId,
+                                    uint32_t *pAlgIdSize)
+{
+        if (hashMode >= sizeof(gHashDerCodes) / sizeof(HashDerCode_t))
+                return CC_RSA_GET_DER_HASH_MODE_ILLEGAL;
+        /* output requirred Hash algorithm DER code */
+        *pAlgId = gHashDerCodes[hashMode].algId;
+        *pAlgIdSize = (gHashDerCodes[hashMode]).algIdSizeBytes;
+        return CC_OK;
+}
+
+/*****************************************************************************/
+/**
+ * The function generates vector of non zero octets.
+ *
+ * @author reuvenl (9/14/2014)
+ *
+ * @param rndContext_ptr  - Pointer to the RND context buffer.
+ * @param pVect - The pointer to output buffer.
+ * @param size  - The size of vector in bytes.
+ *
+ * @return CCError_t
+ */
+CCError_t  RsaGenRndNonZeroVect(CCRndContext_t *rndContext_ptr, uint8_t *pVect, uint32_t size)
+{
+        #define TMP_SIZE 16
+        CCError_t err = CC_OK;
+        uint32_t i, j, newRnd;
+        uint8_t tmp[TMP_SIZE];
+        uint8_t zero[TMP_SIZE] = { 0 };
+
+
+        void   *rndState_ptr;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+        /* check parameters */
+        if (rndContext_ptr == NULL)
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+
+        rndState_ptr = rndContext_ptr->rndState;
+        RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+        if (RndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        /* generate random vector */
+        err = RndGenerateVectFunc(rndState_ptr, (unsigned char *)pVect, (size_t)size);
+        if (err != CC_OK) {
+                return err;
+        }
+
+        /* generate auxiliary random buff and change zero octets */
+        j = 0; newRnd = 1;
+        for (i=0; i<size; i++) {
+                while (1) {
+                        if (newRnd) {
+                                j = 0; newRnd = 0;
+                                err = RndGenerateVectFunc(rndState_ptr, (unsigned char *)tmp, sizeof(tmp));
+                                // Handle case of RND function which returns zeros
+                                if (CC_PalMemCmp(tmp, zero, TMP_SIZE) == 0) {
+                                    return CC_RND_GEN_VECTOR_FUNC_ERROR;
+                                }
+                                if (err != CC_OK) {
+                                        return err;
+                                }
+                        }
+
+                        /* change byte*/
+                        if (pVect[i] == 0 ) {
+                                if (tmp[j] == 0) {
+                                        j++;
+                                        if (j == sizeof(tmp)) {
+                                            newRnd = 1;
+                                        }
+                                        continue;
+                                }
+                                pVect[i] = tmp[j];
+                                j++;
+                                break;
+                        } else
+                                break;
+                }
+                if (j == sizeof(tmp)) {
+                        newRnd = 1;
+                }
+        }
+        return err;
+}
+
+/*********************************************************************************/
+/**
+ * @brief The function implements PKCS#1 v1.5 (9.2) EMSA Encoding
+ *        algorithm used in Sign/Verify operations.
+ *
+ * @author reuvenl (9/14/2014)
+ *
+ * @param K - The size of encoded message in octets.
+ * @param hashMode - hash mode ID (enum).
+ * @param pM - The Pointer to the Message M. In case of Sign it is a hash (H).
+ * @param MSize - Denotes the Message size: for Sig/Ver = hashSize,
+ *                for Enc/Dec <= K-hashAlgIdSize-PSS_MIN_LEN-3.
+ * @param pOut - The pointer to a buffer which is at least K octets long.
+ *
+ * @return CCError_t
+ */
+CCError_t RsaEmsaPkcs1v15Encode(
+                                        uint32_t K,
+                                        CCHashOperationMode_t hashMode,
+                                        uint8_t     *pM, /*mess.digest*/
+                                        uint32_t     MSize,
+                                        uint8_t     *pOut)
+{
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /* Padding String Size  */
+        int32_t  PSSize;
+        /* The pointer to Hash Alg. ID (DER code) and its size */
+        const uint8_t *pHashAlgId = NULL;
+        uint32_t hashAlgIdSize = 0;
+
+        /* FUNCTION LOGIC */
+
+#ifdef DEBUG
+        /* Init to garbage */
+        CC_PalMemSet(pOut, 0xCC, K);
+#endif
+
+        /*---------------------------------------------------*/
+        /*  Encryption block formating for EMSA-PKCS1-v1_5:  */
+        /*          00 || 01 || PS || 00 || T            */
+        /*         MSB                      LSB          */
+        /* Note:  BT=02, PS=FF...FF, T=DER||Hash(M)          */
+        /*---------------------------------------------------*/
+
+        /* Get Hash alg. parametrs including DER code */
+        Error = GetHashAlgDerCode(hashMode, &pHashAlgId, &hashAlgIdSize);
+        if (Error)
+                return Error;
+
+        /* check sizes */
+        if (3+MSize+PS_MIN_LEN+hashAlgIdSize > K)
+                return CC_RSA_ENCODE_15_MSG_OUT_OF_RANGE;
+
+        PSSize = K-MSize-hashAlgIdSize-3; /*therefore, PSSize >= PS_MIN_LEN*/
+
+        /* Fill the formatted output buffer */
+        pOut[0]=0x00;    /* set the 00 */
+        pOut[1]=0x01;    /* set Block Type 01 */
+        CC_PalMemSet(&pOut[2], 0xFF, PSSize);
+        /* copy the Hash Algorithm ID (DER code) */
+        CC_PalMemCopy(&pOut[3+PSSize], pHashAlgId, hashAlgIdSize);
+
+        /* set 00-byte after PS */
+        pOut[2+PSSize] = 0x00;
+        /* copy the message/digest data */
+        CC_PalMemCopy(&pOut[K-MSize], pM, MSize);
+
+        return CC_OK;
+}
+
+#endif /*defined(_INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
+
+
+
+/******************************************************************************************/
+
+/* just to have a declaarion so the 'C' file passes compilation */
+void CRTS_RSA_VER15_UTIL_foo(void) {}
+
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_prim.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_prim.c
new file mode 100644
index 0000000..a577e9b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_prim.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_ASYM_RSA_DH
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_local.h"
+#include "rsa.h"
+#include "rsa_public.h"
+#include "rsa_private.h"
+#include "cc_fips_defs.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Public Functions ******************************/
+
+
+/**********************************************************************************/
+/**
+@brief
+CC_RsaPrimEncrypt implements the RSAEP algorithm as defined in PKCS#1 v2.1 6.1.1
+
+  @param[in] UserPubKey_ptr - Pointer to the public key data structure.
+  @param[in] PrimeData_ptr - A pointer to a structure containing temp buffers.
+  @param[in] Data_ptr - Pointer to the input data to be encrypted.
+  @param[in] DataSize - The size, in bytes, of the input data.
+            \Note: DataSize <= modulus size is supported, but recommended
+            that size is equal to modulus size. If smaller, the data will be
+            zero-padded on left side up to the modulus size and therefore,
+            after further decrypt operation its result will contain
+            padding zeros also.
+  @param[out] Output_ptr - Pointer to the encrypted data. The size of output data
+            is always equal to size modulus size. The output buffer
+            must be at least of modulus size in bytes.
+
+  @return CCError_t - CC_OK,
+            CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
+            CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR,
+            CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID,
+            CC_RSA_DATA_POINTER_INVALID_ERROR,
+            CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
+            CC_RSA_INVALID_MESSAGE_BUFFER_SIZE,
+            CC_RSA_INVALID_MESSAGE_DATA_SIZE,
+            CC_RSA_INVALID_MESSAGE_VAL
+ */
+CEXPORT_C CCError_t CC_RsaPrimEncrypt(CCRsaUserPubKey_t *UserPubKey_ptr,
+                        CCRsaPrimeData_t  *PrimeData_ptr,
+                        uint8_t              *Data_ptr,
+                        size_t                DataSize,
+                        uint8_t              *Output_ptr)
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the public key database pointer */
+    CCRsaPubKey_t *PubKey_ptr;
+
+    /* the modulus size in bytes */
+    uint32_t nSizeInBytes;
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+
+
+    /* ............... checking the parameters pointers validity .......... */
+    /* -------------------------------------------------------------------- */
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+    /* checking the key database handle pointer */
+    if (UserPubKey_ptr == NULL)
+        return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+
+    /* if the users TAG is illegal return an error - the context is invalid */
+    if (UserPubKey_ptr->valid_tag != CC_RSA_PUB_KEY_VALIDATION_TAG)
+        return CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR;
+
+    /* checking the Prime Data pointer */
+    if (PrimeData_ptr == NULL)
+        return CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID;
+
+    /* if the users Data pointer is illegal return an error */
+    if (Data_ptr == NULL)
+        return CC_RSA_DATA_POINTER_INVALID_ERROR;
+
+    /* if the users output pointer is illegal return an error */
+    if (Output_ptr == NULL)
+        return CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
+
+    /* if the data size is larger then the internal buffer return error */
+    if (DataSize > sizeof(PrimeData_ptr->DataIn))
+        return CC_RSA_INVALID_MESSAGE_BUFFER_SIZE;
+
+    /* setting the pointer to the key database */
+    PubKey_ptr = (CCRsaPubKey_t*)UserPubKey_ptr->PublicKeyDbBuff;
+
+    /* setting the modulus size in bytes */
+    nSizeInBytes = CALC_FULL_BYTES(PubKey_ptr->nSizeInBits);
+
+
+    /* ................ copying the input data to the buffer .............. */
+    /* -------------------------------------------------------------------- */
+
+    /* clear the input data */
+    CC_PalMemSet(PrimeData_ptr->DataIn, 0, sizeof(PrimeData_ptr->DataIn));
+
+    /* copy the input data to the aligned buffer on the data handler */
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrimeData_ptr->DataIn, 4*((nSizeInBytes+3)/4),
+                                Data_ptr, DataSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+        goto End;
+    }
+
+        /* ...... checking the the message value it must be less then the modulus ...... */
+    CounterCmpResult = CC_CommonCmpLsWordsUnsignedCounters(
+                                 PrimeData_ptr->DataIn, (uint16_t)(nSizeInBytes+3)/4,
+                                 PubKey_ptr->n, (uint16_t)(nSizeInBytes+3)/4);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        Error = CC_RSA_INVALID_MESSAGE_VAL;
+        goto End;
+    }
+
+    /* executing the encryption */
+    Error = RsaExecPubKeyExp(PubKey_ptr, PrimeData_ptr);
+
+    if (Error != CC_OK) {
+        Error = CC_RSA_INTERNAL_ERROR;
+        goto End;
+    }
+
+    /* copy the output data from the aligned buffer to the users data on big endian format */
+    Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Output_ptr, 4*((nSizeInBytes+3)/4),
+                                PrimeData_ptr->DataOut, nSizeInBytes );
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_MESSAGE_VAL;
+        goto End;
+    }
+
+End:
+    if (Error != CC_OK) {
+        CC_PalMemSetZero(Output_ptr, nSizeInBytes);
+    }
+    /* clear the data buffer */
+    CC_PalMemSetZero(PrimeData_ptr, sizeof(CCRsaPrimeData_t) );
+
+    return Error;
+
+
+}/* END OF CC_RsaPrimEncrypt */
+
+
+/**********************************************************************************/
+/**
+@brief
+CC_RsaPrimDecrypt implements the RSADP algorithm as defined in PKCS#1 v2.1 6.1.2
+
+  @param[in] PrivKey_ptr - Pointer to the private key data
+               structure. \note The RSA key parameters and hence the algorithm (CRT
+               or not) are determined by this structure. Using CC_BuildPrivKey or
+               CC_BuildPrivKeyCRT determines which algorithm will be used.
+
+  @param[in] PrimeData_ptr - A pointer to a structure containing internal
+                 buffers required for the RSA operation.
+  @param[in] Data_ptr - Pointer to the data to be decrypted.
+  @param[in] DataSize - The size, in bytes, of the input data. To decrypt
+            previously encrypted data its size must be equal to
+            modulus size.
+            \Note: DataSize <= modulus size is supported, but
+            it is recommended that the size is equal to modulus size.
+            If smaller, the data will be zero-padded on left side
+            up to the modulus size and therefore, after further decrypt
+            operation its result will contain padding zeros also.
+  @param[out] Output_ptr - Pointer to the decrypted data. The size of output data
+            is always equal to size modulus size. The output buffer
+            must be at least of modulus size in bytes.
+
+  @return CCError_t - CC_OK,
+            CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+            CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID,
+            CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR,
+            CC_RSA_DATA_POINTER_INVALID_ERROR,
+            CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
+            CC_RSA_INVALID_MESSAGE_DATA_SIZE,
+            CC_RSA_INVALID_MESSAGE_VAL
+ */
+
+CEXPORT_C CCError_t CC_RsaPrimDecrypt(
+                       CCRsaUserPrivKey_t *UserPrivKey_ptr,
+                       CCRsaPrimeData_t   *PrimeData_ptr,
+                       uint8_t             *Data_ptr,
+                       size_t               DataSize,
+                       uint8_t             *Output_ptr)
+{
+    /* FUNCTION LOCAL DECLERATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the private key database pointer */
+    CCRsaPrivKey_t *PrivKey_ptr;
+
+    /* the modulus size in bytes */
+    uint32_t nSizeInBytes;
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+
+
+    /* ............... checking the parameters pointers validity .......... */
+    /* -------------------------------------------------------------------- */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /* ...... checking the key database handle pointer .................... */
+    if (UserPrivKey_ptr == NULL)
+        return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the Prime Data pointer .................... */
+    if (PrimeData_ptr == NULL)
+        return CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID;
+
+    /* if the users TAG is illegal return an error - the context is invalid */
+    if (UserPrivKey_ptr->valid_tag != CC_RSA_PRIV_KEY_VALIDATION_TAG)
+        return CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR;
+
+    /* if the users Data pointer is NULL return an error */
+    if (Data_ptr == NULL)
+        return CC_RSA_DATA_POINTER_INVALID_ERROR;
+
+    /* if the users Output pointer is NULL return an error */
+    if (Output_ptr == NULL)
+        return CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
+
+
+    /* setting the pointer to the key database */
+    PrivKey_ptr = (CCRsaPrivKey_t*)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+    /* setting the modulus size in bytes */
+    nSizeInBytes = CALC_FULL_BYTES(PrivKey_ptr->nSizeInBits);
+
+    /* if the data size is 0 or great than modulus size - return an error */
+    if (DataSize == 0 || DataSize > nSizeInBytes)
+        return CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+
+    /* ................ copying the input data to the buffer .............. */
+    /* -------------------------------------------------------------------- */
+
+    /* clear the input data */
+    CC_PalMemSetZero( PrimeData_ptr->DataIn, sizeof(PrimeData_ptr->DataIn));
+
+    /* copy the input data to the aligned buffer on the data handler in little endian format */
+    Error = CC_CommonConvertMsbLsbBytesToLswMswWords(
+                               PrimeData_ptr->DataIn, 4*((nSizeInBytes+3)/4), Data_ptr, DataSize);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+        goto End;
+    }
+
+    /* .. checking the message value it must be less then the modulus .. */
+    /* ----------------------------------------------------------------- */
+    CounterCmpResult = CC_CommonCmpLsWordsUnsignedCounters(
+                                 PrimeData_ptr->DataIn, (uint16_t)(nSizeInBytes+3)/4,
+                                 PrivKey_ptr->n, (uint16_t)(nSizeInBytes+3)/4);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        Error = CC_RSA_INVALID_MESSAGE_VAL;
+        goto End;
+    }
+
+    /* ..................... executing the encryption ...................... */
+    /* --------------------------------------------------------------------- */
+
+    Error = RsaExecPrivKeyExp(PrivKey_ptr, PrimeData_ptr);
+
+    if (Error != CC_OK) {
+        Error = CC_RSA_INTERNAL_ERROR;
+        goto End;
+    }
+
+    /* copy the output data from the aligned words-buffer to the users data in MS-LS bytes order */
+    Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Output_ptr, 4*((nSizeInBytes+3)/4),
+                                PrimeData_ptr->DataOut, nSizeInBytes);
+    if (Error != CC_OK) {
+        Error = CC_RSA_INVALID_MESSAGE_VAL;
+        goto End;
+    }
+
+End:
+    if (Error != CC_OK) {
+        CC_PalMemSetZero(Output_ptr, nSizeInBytes);
+    }
+
+    /* clear the temp data buffer */
+    CC_PalMemSetZero(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+
+    return Error;
+
+
+}/* END OF CC_RsaPrimDecrypt */
+
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_pss21_util.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_pss21_util.c
new file mode 100644
index 0000000..b99f8c3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_pss21_util.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*  Inculde Files */
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#ifndef USE_MBEDTLS_CRYPTOCELL
+#include "cc_hash.h"
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_pal_mem.h"
+#include "cc_common_math.h"
+#include "cc_rsa_local.h"
+#include "cc_rsa_error.h"
+#include "cc_hash_defs.h"
+#include "cc_rnd_error.h"
+#include "cc_rsa_prim.h"
+#include "cc_general_defs.h"
+
+#ifdef CC_RSA_SIGN_USE_TEMP_SALT
+#include "CRYS_RSA_PSS21_defines.h"
+extern uint8_t SaltDB_T[NUM_OF_SETS_TEST_VECTORS][NUM_OF_TEST_VECTOR_IN_SET][CC_RSA_PSS_SALT_LENGTH];
+extern uint16_t Global_Set_Index_T;
+extern uint16_t Global_vector_Index_T;
+#endif
+
+
+#if !defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)
+
+/**********************************************************************************************************/
+/**
+        Function Name: RsaPssVerify21
+        Date:   06-12-2004
+        Author: Ohad Shperling
+
+    \brief RsaPssVerify21 implements EMSA-PSS-Verify algorithm
+   as defined in PKCS#1 v2.1 Sec 9.1.2
+
+   @param[in] Context_ptr - Pointer to a valid context as
+                            given from the VerifyFinish function.
+
+   The field HASH_Result inside the Context_ptr is initialized with the Hashed digested message.
+   The field HASH_Result_Size inside the Context_ptr is initialized with the Hash digested message size
+
+   @return CCError_t - CC_OK, or error
+
+*/
+CCError_t RsaPssVerify21(RSAPubContext_t *Context_ptr)
+{
+        /**********Fitting to the spec******************************/
+        /* Context_ptr->MsgDigestCAL = mHash = Hash(M)
+     * &Context_ptr->KeyObj.PubObj.EBD[0] = pointer to EM = S^E mod N
+     * &Context_ptr->KeyObj.PubObj.EBDSize = pointer to EM size
+        */
+
+
+        CCError_t Error ;
+        uint8_t   *ED_ptr;
+        uint32_t  EDSizeInBytes;
+        uint32_t PubNNewSizeBytes,i;
+        uint8_t *maskedDB_ptr;
+
+        uint32_t maskedDB_size;
+        uint32_t TempIndex ;
+        uint8_t *dbMask_ptr = Context_ptr->T_Buf;
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        const mbedtls_md_info_t *md_info=NULL;
+#endif
+
+        CCHashResultBuf_t H_Saved_buf;
+        /* Set the ED block pointer */
+
+        /*Temporary - only for the size of N*/
+        CCRsaPubKey_t *PubKey_ptr = (CCRsaPubKey_t *)Context_ptr->PubUserKey.PublicKeyDbBuff;
+
+        /* FUNCTION LOGIC */
+
+        ED_ptr=(uint8_t*)&Context_ptr->EBD[0];/* = EM*/
+        EDSizeInBytes = Context_ptr->EBDSizeInBits/8;
+        if (Context_ptr->EBDSizeInBits % 8)
+                EDSizeInBytes++;
+
+        /*Round up the new bytes number - According to the Spec*/
+        PubNNewSizeBytes = (PubKey_ptr->nSizeInBits - 1)/8;
+
+        if (((PubKey_ptr->nSizeInBits - 1) % 8) != 0) {/*Rounding Only in case that (PubNSizebits -1) is not divisble by 8 */
+                PubNNewSizeBytes++;
+        } else {/*(PubNSizebits -1) is divisble by 8 hence ED_ptr has to be shortened by the first octet according to the spec*/
+                ED_ptr += 1;
+                EDSizeInBytes -= 1;
+        }
+
+        /*
+         *  9.1.2 <3> Check restriction of PubNNewSizeBytes - already checked in Verify Init
+         *  9.1.2 <4> Check that the rightmost octet of EM have the hexadecimal value 0xbc
+         */
+        if (ED_ptr[EDSizeInBytes-1] != 0xbc)
+                return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
+
+        /*
+         *  9.1.2 <5> Define the H and the maskedDB
+         */
+        maskedDB_ptr = ED_ptr;
+        maskedDB_size = PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 1 ;
+
+        /*
+         *  9.1.2 <6> Check that the leftmost bits in the leftmost octet of EM have the value 0.
+         *     Note: In CC implementation only the left most bit must be checked, because the
+         *           modulus size is always a multiple of 8 bits.
+         */
+        if (maskedDB_ptr[0] & 0x80)
+                return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
+
+        /*need to save H because ED_ptr is to be used - Context_ptr->MsgDigestSRC = H;
+          i.e. COPIed hash size bytes directly before 0xbc byte (FIPS 186-4, 5.4)      */
+        CC_PalMemCopy((uint8_t *)H_Saved_buf, &ED_ptr[maskedDB_size], Context_ptr->HASH_Result_Size*4);
+
+        /* Calculate the mask by MGF */
+        switch (Context_ptr->MGF_2use) {
+        case CC_PKCS1_MGF1:
+
+                Error = RsaOaepMGF1( (uint16_t)(Context_ptr->HASH_Result_Size*sizeof(uint32_t)), /*hashLen*/
+                                           (uint8_t *)H_Saved_buf,                                 /*mgfSeed = hash */
+                                           (uint16_t)(Context_ptr->HASH_Result_Size*sizeof(uint32_t)),/*seedLen*/
+                                           PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 1, /*maskLen*/
+                                           dbMask_ptr,                                             /*mask out*/
+                                           Context_ptr->HashOperationMode,                         /*hashMode*/
+                                           (uint8_t *)Context_ptr->PrimeData.DataOut,              /*1-st tempBuff*/
+                                           (uint8_t *)Context_ptr->PrimeData.DataIn);              /*2-nd tempBuff*/
+                if (Error != CC_OK) {
+                        return Error;
+                }
+
+                break;
+
+        /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
+        case CC_PKCS1_NO_MGF:
+        default:
+                return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+        }
+
+        /*
+         *  9.1.2 <8> Xor operation on length (PubNNewSizeBytes - Context_ptr->hLen - 1)
+         */
+
+        for (i=0;i<maskedDB_size;i++) {
+                dbMask_ptr[i] = dbMask_ptr[i] ^ maskedDB_ptr[i] ;
+        }
+
+        /*
+         *  9.1.2 <9> Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero
+         *     Note: In CC implementation only NS bit must be zeroed, because modulus size is
+         *           always a multiple of 8 bits.
+         */
+        dbMask_ptr[0] &= 0x7F;
+
+        /*
+         *  9.1.2 <10>
+         */
+
+        i=0;
+        while (dbMask_ptr[i] == 0) {
+                i++;
+        }
+
+        if (Context_ptr->SaltLen == CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN) {
+
+                /* For security goals and preventing memory overflow
+                   check that the buffer parts are consistent */
+                if (PubNNewSizeBytes < Context_ptr->HASH_Result_Size*sizeof(uint32_t) + 2 + i) {
+                        return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
+                }
+                /*Derive the salt length if not supplied */
+                Context_ptr->SaltLen = (uint16_t)(PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 2 - i);
+        } else {
+            /* Sanity check - verify that the given Saltlen equals the computed saltlen*/
+                if (Context_ptr->SaltLen != (uint16_t)(PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 2 - i))
+                {
+                    return CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING;
+                }
+                TempIndex = PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - Context_ptr->SaltLen - 2;
+                for (i = 0; i < TempIndex; i++) {
+                        if (dbMask_ptr[i] != 0)
+                                return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
+                }
+        }
+
+        if (dbMask_ptr[i] != 0x01)
+                return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
+
+        /*
+         *  9.1.2 <11> Let salt be the last sLen octets in DB
+         *  9.1.2 <12> Let M' ==>
+         *   (0x) 00 00 00 00 00 00 00 00 || mHash || salt
+         *   Note: ED is used now as M' temp buffer
+         */
+        CC_PalMemSetZero(ED_ptr, CC_RSA_PSS_PAD1_LEN);/*CC_RSA_PSS_PAD1_LEN = 8*/
+
+        /*copy the Hash output */
+        CC_PalMemCopy(&ED_ptr[CC_RSA_PSS_PAD1_LEN], (uint8_t *)Context_ptr->HASH_Result, Context_ptr->HASH_Result_Size*sizeof(uint32_t));
+        CC_PalMemCopy(&ED_ptr[CC_RSA_PSS_PAD1_LEN + Context_ptr->HASH_Result_Size*sizeof(uint32_t)],
+                        &dbMask_ptr[maskedDB_size - Context_ptr->SaltLen], Context_ptr->SaltLen);
+
+        /*
+         *  9.1.2 <13> H' = Hash(M')
+         */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[Context_ptr->HashOperationMode] );
+        if (NULL == md_info)
+        {
+            return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+        Error = mbedtls_md(md_info,
+                ED_ptr,
+                CC_RSA_PSS_PAD1_LEN + Context_ptr->HASH_Result_Size*sizeof(uint32_t) + Context_ptr->SaltLen,
+                (unsigned char *)Context_ptr->HASH_Result);
+        if (Error != 0)
+        {
+            return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+#else
+        Error = CC_Hash(Context_ptr->HashOperationMode,
+                          ED_ptr,
+                          CC_RSA_PSS_PAD1_LEN + Context_ptr->HASH_Result_Size*sizeof(uint32_t) + Context_ptr->SaltLen,/*8+20+20*/
+                          Context_ptr->HASH_Result);
+
+        if (Error != CC_OK) {
+                return Error;
+        }
+#endif
+        if (CC_PalMemCmp((uint8_t *)Context_ptr->HASH_Result, (uint8_t *)H_Saved_buf, Context_ptr->HASH_Result_Size*sizeof(uint32_t))) {
+                return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
+        } else {
+                return CC_OK;
+        }
+}
+
+#endif /*!defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
+
+
+
+#if !defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)
+#ifndef _INTERNAL_CC_NO_RSA_SIGN_SUPPORT
+/* -------------------------------------------------------------
+ *  Function Name: RsaPssSign21
+ *  Date:   06-12-2004
+ *  Author: Ohad Shperling
+ *
+ *  Inputs:
+ *  Outputs:
+ *
+ *  Algorithm: According to PKCS1 v.2.1
+ *
+ *  Update History:
+ *  Date:       Description:
+ *
+ * ----------------------------------------------------------- */
+
+CCError_t RsaPssSign21(
+                               CCRndContext_t *rndContext_ptr, /*! random context */
+                               RSAPrivContext_t *Context_ptr,
+                               uint8_t  *Output_ptr)
+{
+
+#ifdef CC_RSA_SIGN_USE_TEMP_SALT
+        /*only for debug of signing*/
+        /*Using a known Salt for debug*/
+        uint8_t *Salt = SaltDB_T[Global_Set_Index_T][Global_vector_Index_T];
+#else
+        /*In operational mode Salt is a random number*/
+        uint8_t *Salt = Output_ptr;/*This stack memory saving is ok because Output_ptr is used only in the Primitive operation*/
+#endif
+#ifdef USE_MBEDTLS_CRYPTOCELL
+                const mbedtls_md_info_t *md_info=NULL;
+#endif
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+        uint32_t i;
+        uint32_t TempIndex;
+
+        void   *rndState_ptr;
+        CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
+
+        /*Parameter for the actual size of the modulus N in bits*/
+        uint32_t PrvNSizebits;
+
+        /*Parameter for the new size of the modulus N in bytes according to PKCS1 Ver 2.1*/
+        uint32_t PrvNNewSizeBytes;/*rounded number of Bytes for padding2 length*/
+        uint32_t Index4PSLength;
+
+        uint8_t *EMPadOutputBuffer;
+        uint8_t *MaskOutput_ptr = Context_ptr->T_Buf;/*for stack space saving*/
+
+        CCRsaPrivKey_t *PrivKey_ptr = (CCRsaPrivKey_t *)Context_ptr->PrivUserKey.PrivateKeyDbBuff;
+        uint32_t hashResultSize; /*HASH size in bytes*/
+
+
+        /* FUNCTION LOGIC */
+
+        /* check parameters */
+        if (rndContext_ptr == NULL)
+                return CC_RND_CONTEXT_PTR_INVALID_ERROR;
+
+        rndState_ptr = rndContext_ptr->rndState;
+        RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+        if (RndGenerateVectFunc == NULL)
+                return CC_RND_GEN_VECTOR_FUNC_ERROR;
+
+        /* .................. initializing local variables ................... */
+        /* ------------------------------------------------------------------- */
+
+        EMPadOutputBuffer = (uint8_t*) Context_ptr->EBD;
+        hashResultSize = Context_ptr->HASH_Result_Size*sizeof(uint32_t);
+
+        /*
+         *  9.1.1 <1> checking length restriction of the message M - done in the Update phase
+         *  9.1.1 <2> Hash operation - done in the Update phase
+         */
+
+        /*
+         *  Finding Actual size in bits and new size of Bytes of the modulus N
+         *  This value is already calculated in  Context_ptr->KeyObj.PrvCRTObj.nSizeInBits
+         *  or in  Context_ptr->KeyObj.PrvPAIRObj.nSizeInBits
+         */
+
+        /* Reset the working buffer - RL - check */
+        CC_PalMemSet(EMPadOutputBuffer, 0x00, CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS*sizeof(uint32_t));
+
+        /*Round up the new bytes number*/
+        PrvNNewSizeBytes = (PrivKey_ptr->nSizeInBits -1)/8;
+        PrvNSizebits = PrivKey_ptr->nSizeInBits;
+
+        if (((PrvNSizebits -1) % 8) != 0)
+                PrvNNewSizeBytes++;
+        /*rounding */
+
+        /*
+         *  9.1.1 <3> Check restriction of PrvNNewSizeBytes - already checked in Sign Init
+         *  9.1.1 <5> Generating M' ==> using the output buffer as a container
+         *  EMPadOutputBuffer = (0x) 00 00 00 00 00 00 00 00 || mHash || salt
+         */
+
+        CC_PalMemSet(EMPadOutputBuffer, 0x00, CC_RSA_PSS_PAD1_LEN);/*CC_RSA_PSS_PAD1_LEN = 8*/
+
+        /*copy the Hash output */
+        CC_PalMemCopy(&EMPadOutputBuffer[CC_RSA_PSS_PAD1_LEN], (uint8_t*)Context_ptr->HASH_Result, hashResultSize);
+
+        /*
+         *  9.1.1 <4> Generating a random salt ==> using the output buffer as a container
+         */
+#ifndef CC_RSA_SIGN_USE_TEMP_SALT /*If not using a known salt for Debug then generate random*/
+        Error = RndGenerateVectFunc(rndState_ptr, (unsigned char *)Salt, (size_t)Context_ptr->SaltLen);
+        if (Error != CC_OK) {
+                return Error;
+        }
+#endif
+
+        CC_PalMemCopy(&EMPadOutputBuffer[CC_RSA_PSS_PAD1_LEN + hashResultSize], Salt, Context_ptr->SaltLen);
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[Context_ptr->HashOperationMode] );
+        if (NULL == md_info)
+        {
+            return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+        Error = mbedtls_md(md_info,
+                EMPadOutputBuffer,
+                CC_RSA_PSS_PAD1_LEN + hashResultSize + Context_ptr->SaltLen,/*8+hLen+20*/
+                (unsigned char *)Context_ptr->HASH_Result);
+
+        if (Error != 0)
+        {
+            return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        }
+#else
+        Error = CC_Hash(Context_ptr->HashOperationMode,
+                          EMPadOutputBuffer,
+                          CC_RSA_PSS_PAD1_LEN + hashResultSize + Context_ptr->SaltLen,/*8+hLen+20*/
+                          Context_ptr->HASH_Result);
+
+        if (Error != CC_OK) {
+                return Error;
+        }
+#endif
+        /*
+         *  9.1.1 <7+8> Generate an octet string of zeros of size emLen-sLen-hLen-2 ==> use the output buffer as a container
+         *              DB = PS || 0x01 || salt
+         */
+
+        Index4PSLength = PrvNNewSizeBytes - Context_ptr->SaltLen - hashResultSize - 2;
+
+        CC_PalMemSet(EMPadOutputBuffer, 0x00, Index4PSLength);
+        EMPadOutputBuffer[Index4PSLength] = 0x01;
+        CC_PalMemCopy(&(EMPadOutputBuffer[Index4PSLength+1]), Salt, Context_ptr->SaltLen);
+
+        /*
+         *  9.1.1 <9> MGF operation
+         */
+
+        switch (Context_ptr->MGF_2use) {
+        case CC_PKCS1_MGF1:
+
+                Error = RsaOaepMGF1( (uint16_t)hashResultSize, /* hashLen */
+                                           (uint8_t *)Context_ptr->HASH_Result,         /* mgfSeed */
+                                           (uint16_t)hashResultSize, /* seedLen */
+                                           PrvNNewSizeBytes - hashResultSize - 1, /* maskLen */
+                                           MaskOutput_ptr,                              /* mask */
+                                           Context_ptr->HashOperationMode,              /* hashMode */
+                                           (uint8_t *)Context_ptr->PrimeData.DataOut,   /* temp1 */
+                                           (uint8_t *)Context_ptr->PrimeData.DataIn);   /* temp2 */
+                if (Error != CC_OK) {
+                        return Error;
+                }
+
+                break;
+
+        /* Currently for PKCS1 Ver 2.1 only MGF1 is implemented */
+        case CC_PKCS1_NO_MGF:
+
+        default:
+
+                return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+
+        }/* end of MGF type switch case */
+
+
+        /*
+         *  9.1.1 <10> Xor operation on length (PrvNNewSizeBytes - Context_ptr->hLen - 1)
+         */
+
+        TempIndex = PrvNNewSizeBytes - hashResultSize - 1;
+        for (i = 0; i < TempIndex; i++) {
+                EMPadOutputBuffer[i] = EMPadOutputBuffer[i] ^ MaskOutput_ptr[i];
+        }
+
+
+        /*
+         *   9.1.1 <11> Set the leftmost 8*emLen-emBits bits of the leftmost octet in maskedDB to zero
+         *      Because the RSA modulus in CC always is a multiple of 8, only one (left most) bit
+         *              need to be zeroed.
+         */
+         EMPadOutputBuffer[0] &= 0x7F;
+
+        /*
+         *  ? 9.1.1 <12> Let EM = maskedDB || H || 0xbc
+         *      Note: maskedDB is already generated from the Xor operation.
+         */
+        CC_PalMemCopy(&(EMPadOutputBuffer[PrvNNewSizeBytes - hashResultSize - 1]),
+                         (uint8_t *)Context_ptr->HASH_Result, hashResultSize);
+
+        EMPadOutputBuffer[PrvNNewSizeBytes - 1] = 0xbc;
+
+        /*
+         *  FINISH 9.1.1
+         *
+         *  8.1.1 <2.b>
+         *  Apply the RSASP1 signature primitive to the RSA private key K and the message
+         *  representative m to produce an integer signature representative s
+         *
+         */
+
+        /* ...  execute RSA encrypt using RSA_PRIM_Decrypt for exponentiation ... */
+        /* ---------------------------------------------------------------------- */
+
+        Error = CC_RsaPrimDecrypt(&Context_ptr->PrivUserKey,
+                                      &Context_ptr->PrimeData,
+                                      EMPadOutputBuffer,
+                                      (uint16_t)PrvNNewSizeBytes,
+                                      Output_ptr);
+
+        return Error;
+
+}
+
+#endif /*!defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)*/
+
+
+void CC_RSA_PSS21_UTIL_foo(void) {}
+#endif //_INTERNAL_CC_NO_RSA_SIGN_SUPPORT
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_schemes.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_schemes.c
new file mode 100644
index 0000000..430384e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_schemes.c
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+#include "cc_rsa_error.h"
+#include "cc_hash_defs.h"
+#include "cc_rsa_local.h"
+#include "cc_rsa_prim.h"
+#include "cc_fips_defs.h"
+
+/************************ Defines ****************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ***************************/
+
+/************************ Global Data *************************/
+
+#ifdef DEBUG_OAEP_SEED
+#include "CRYS_RSA_PSS21_defines.h"
+extern uint8_t SaltDB[NUM_OF_SETS_TEST_VECTORS][NUM_OF_TEST_VECTOR_IN_SET][CC_RSA_PSS_SALT_LENGTH];
+extern uint16_t Global_Set_Index;
+extern uint16_t Global_vector_Index;
+#endif
+
+/************* Private function prototype ****************/
+
+#if !defined(_INTERNAL_CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)
+
+/**********************************************************************************************************/
+
+/**
+   @brief
+   RSA_SCHEMES_Encrypt implements the RSAES-OAEP algorithm as defined
+   in PKCS#1 v2.1 8.1 and in PKCS#1 v1.5 8.1
+
+        This function combines the RSA encryption primitive and the
+        EME-OAEP encoding method, to provide an RSA-based encryption
+        method that is semantically secure against adaptive
+        chosen-ciphertext attacks. For more details, please refere to
+        the PKCS#1 standard.
+
+        The actual macro that will be used by the user is:
+        CC_RsaOaepEncrypt     - for v2.1
+        CC_RsaPkcs1V15Encrypt - for v1.5
+
+   @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param[in] UserPubKey_ptr - A pointer to the public key data structure of the User.
+   @param[in] PrimeData_ptr - A pointer to a CCRsaPrimeData_t
+                                that is used for the Encryption operation
+   @param[in] hashFunc - The hash function to be used.
+                         The hash functions supported: SHA1, SHA-256/284/512,
+                         MD5 (MD5 - allowed only for PKCS#1 v1.5).
+   @param[in] L - The label input pointer. Relevant for PKCS#1 Ver2.1 only, may be NULL also.
+                  For PKCS#1 Ver1.5 it is an empty string (NULL).
+   @param[in] Llen - The label length. Relevant for PKCS#1 Ver2.1 only (see notes above).
+   @param[in] MGF - the mask generation function. PKCS#1 v2.1
+                    defines MGF1, so the currently allowed value is CC_PKCS1_MGF1.
+   @param[in] Data_ptr - Pointer to the data to encrypt.
+   @param[in] DataSize - The size, in bytes, of the data to encrypt.
+                         \Note: The data size must be:
+                            1. for PKCS #1 v.2.1  DataSize <= PrivKey_ptr->N.len - 2*HashLen - 2.
+                            2. for PKCS #1 v.1.5  DataSize <= PrivKey_ptr->N.len - 11.
+   @param[out] Output_ptr - Pointer to the encrypted data. The size of the data is always
+                            equal to the RSA key (modulus) size, in bytes. Therefore the size
+                            of allocated buffer must be at least of this size.
+
+   @return CCError_t - CC_OK, or error
+*/
+CEXPORT_C CCError_t CC_RsaSchemesEncrypt(
+                                             CCRndContext_t *rndContext_ptr,
+                                             CCRsaUserPubKey_t *UserPubKey_ptr,
+                                             CCRsaPrimeData_t  *PrimeData_ptr,
+                                             CCRsaHashOpMode_t hashFunc,
+                                             uint8_t            *L,
+                                             size_t             Llen,
+                                             CCPkcs1Mgf_t   MGF,
+                                             uint8_t           *DataIn_ptr,
+                                             size_t             DataInSize,
+                                             uint8_t            *Output_ptr,
+                                             CCPkcs1Version_t PKCS1_ver)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+
+        /*The modulus size in Bytes*/
+        uint16_t K;
+        uint8_t HashOutputSize;
+
+        /*In order to save stack memory place -
+         * It is required that the Output_ptr is at least the size of the modulus
+         * It is also required that the RSA computation is done in-place */
+        uint8_t *EB_buff = Output_ptr;
+
+        CCRsaPubKey_t *PubKey_ptr;
+        CCHashOperationMode_t hashOpMode;
+        uint32_t PSSize;
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* if the users context pointer is NULL return an error */
+        if (UserPubKey_ptr == NULL)
+                return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+
+        /* checking the Prime Data pointer */
+        if (PrimeData_ptr == NULL)
+                return CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID;
+
+        /* check if the hash operation mode is legal */
+        if (hashFunc >= CC_RSA_HASH_NumOfModes)
+                return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+
+        /* check if the MGF operation mode is legal */
+        if (MGF >= CC_RSA_NumOfMGFFunctions)
+                return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+
+        /* check that the PKCS1 version argument is legal*/
+        if (PKCS1_ver >= CC_RSA_NumOf_PKCS1_versions)
+                return CC_RSA_PKCS1_VER_ARG_ERROR;
+
+        /* if the users Data In pointer is illegal return an error */
+        /* note - it is allowed to encrypt a message of size zero ; only on this case a NULL is allowed */
+        if (DataIn_ptr == NULL && DataInSize != 0)
+                return CC_RSA_DATA_POINTER_INVALID_ERROR;
+
+        /*If the output pointer is NULL return Error*/
+        if (Output_ptr == NULL)
+                return CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
+
+        PubKey_ptr = (CCRsaPubKey_t *)UserPubKey_ptr->PublicKeyDbBuff;
+
+        if (UserPubKey_ptr->valid_tag != CC_RSA_PUB_KEY_VALIDATION_TAG)
+                return CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR;
+
+        if (Llen == 0)
+                L = NULL;
+
+        /* .................. initializing local variables ................... */
+        /* ------------------------------------------------------------------- */
+
+        /*Initialize K with the modulus size in Bytes*/
+        K = (uint16_t)CALC_FULL_BYTES(PubKey_ptr->nSizeInBits);
+
+#ifdef DEBUG
+        /*Initialize the Output_ptr to Zero*/
+        CC_PalMemSetZero(EB_buff, K);
+#endif
+
+        /*-------------------------------------------------------*
+         * Perform Encoding and Encryption accordimg to PKCS1    *
+         * Versions: VER21 or VER15                              *
+         *-------------------------------------------------------*/
+
+        switch (PKCS1_ver) {
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT
+        case CC_PKCS1_VER15:
+                /*-------------------------------------------------------*
+                 * Step 1 : Check modulus and data sizes             *
+                 *-------------------------------------------------------*/
+                /*Check the modulus size is legal*/
+                if (K < 3 + PS_MIN_LEN)
+                        return CC_RSA_INVALID_MODULUS_SIZE;
+
+                if (DataInSize + 3 + PS_MIN_LEN > K )
+                        return CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+                /* size of PS buffer, it is >= PS_MIN_LEN  */
+                PSSize = K -  3 - DataInSize;
+
+                /*-------------------------------------------------------*
+                 * Step 2 :  Encode the message                          *
+                 *-------------------------------------------------------*/
+
+                EB_buff[0]=0x00; /*set the 00 */
+                EB_buff[1]=0x02; /*Block type for EME-PKCS1-v1_5*/
+
+                /* Generate random non-zero bytes for PS */
+                Error = RsaGenRndNonZeroVect(rndContext_ptr, &EB_buff[2], PSSize);
+                if (Error != CC_OK) {
+                        goto End;
+        }
+                /* 0-byte after PS */
+                EB_buff[K-DataInSize-1] = 0x00;
+                /* Copy the message data */
+        if (DataInSize > 0)
+            CC_PalMemCopy(&EB_buff[K-DataInSize], DataIn_ptr, DataInSize);
+
+                break;
+#endif
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT
+
+        /* get CC Hash parameters */
+        case CC_PKCS1_VER21:
+
+                switch (hashFunc) {
+                case CC_RSA_HASH_MD5_mode : /*MD5 is not reccomended in PKCS1 ver 2.1 standard,
+                                                hence it is not supported*/
+                        return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                case CC_RSA_HASH_SHA1_mode:
+                        HashOutputSize = CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                        hashOpMode = CC_HASH_SHA1_mode;/*changing the hash mode to CC definition*/
+                        break;
+                case CC_RSA_HASH_SHA224_mode:
+                        HashOutputSize = CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                        hashOpMode = CC_HASH_SHA224_mode;/*changing the hash mode to CC definition*/
+                        break;
+                case CC_RSA_HASH_SHA256_mode:
+                        HashOutputSize = CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                        hashOpMode = CC_HASH_SHA256_mode;/*changing the hash mode to CC definition*/
+                        break;
+                case CC_RSA_HASH_SHA384_mode:
+                        HashOutputSize = CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                        hashOpMode = CC_HASH_SHA384_mode;/*changing the hash mode to CC definition*/
+                        break;
+                case CC_RSA_HASH_SHA512_mode:
+                        HashOutputSize = CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
+                        hashOpMode = CC_HASH_SHA512_mode;/*changing the hash mode to CC definition*/
+                        break;
+                default:
+                        return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+
+                /* if mLen>k-2*hLen-2 output message too long */
+                if ((uint32_t)DataInSize + 2 * HashOutputSize + 2 > K)
+                        return CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+
+                /*-------------------------------------------------------*
+                 * Step 2 : Apply the EME-OAEP encoding operation to     *
+                 *   the message M and the label L to produce a          *
+                 *   ciphertext of length k octets.                      *
+                 *-------------------------------------------------------*/
+
+                Error=RsaPssOaepEncode(
+                                             rndContext_ptr,   /*! random functions comtext*/
+                                             hashOpMode,   /*! hash operation mode enum */
+                                             MGF,              /*! MGF function mode enum */
+                                             DataIn_ptr,       /*! input data to be encrypted */
+                                             DataInSize,       /*! input data size bytes */
+                                             L,                /*! label */
+                                             Llen,             /*! label length bytes */
+                                             K,                /*! modulus size in bytes */
+                                             PrimeData_ptr,    /*! temp buffer 1 structure for imternal use */
+                                             EB_buff,          /*! temp buffer 2 for imternal use */
+                                             PKCS1_ver         /*! PKCS1 version enum */);
+                if (Error != CC_OK) {
+                        goto End;
+                }
+                break;
+#endif
+        default:
+                return CC_RSA_PKCS1_VER_ARG_ERROR;
+        }
+
+        /*-------------------------------------------*/
+        /* Step 3 : RSA computation                  */
+        /*-------------------------------------------*/
+
+        Error = CC_RsaPrimEncrypt(UserPubKey_ptr,
+                                      PrimeData_ptr,
+                                      EB_buff,
+                                      K,
+                                      Output_ptr);
+End:
+    if (Error != CC_OK) {
+        CC_PalMemSetZero (Output_ptr, K);
+    }
+    /* clear the temp data buffer */
+    CC_PalMemSetZero(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+
+        return Error;
+
+
+}/* END OF CC_RsaSchemesEncrypt */
+#endif /*!defined(_INTERNAL_CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
+
+#if !defined(_INTERNAL_CC_NO_RSA_DECRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)
+/**********************************************************************************************************/
+/**
+   @brief
+   RSA_SCHEMES_Decrypt implements the RSAES-OAEP algorithm as defined
+   in PKCS#1 v2.1 8.1 and in PKCS#1 v1.5
+
+           This function combines the RSA decryption primitive and the
+           EME-OAEP decoding method, to provide an RSA-based decryption
+           method that is semantically secure against adaptive
+           chosen-ciphertext attacks. For more details, please refer to
+           the PKCS#1 standard.
+
+   @param[in] UserPrivKey_ptr - Pointer to the private key data structure.
+                   \Note: The representation (pair or quintuple)
+                    and hence the algorithm (CRT or not) is determined
+                    by the Private Key data structure. Using CC_BuildPrivKey
+                    or CC_BuildPrivKeyCRT determines which algorithm will be used.
+
+   @param[in] PrimeData_ptr - Pointer to a CCRsaPrimeData_t which is used for the
+                                                          Encryption operation
+
+   @param[in] hashFunc - The hash function to be used.
+                         The hash functions supported: SHA1, SHA-256/284/512,
+                         MD5 (MD5 - allowed only for PKCS#1 v1.5).
+
+   @param[in] L - The label input pointer. Relevant for PKCS#1 Ver2.1 only, may be NULL also.
+                  For PKCS#1 Ver1.5 it is an empty string (NULL).
+   @param[in] Llen - The label length. Relevant for PKCS#1 Ver2.1 only (see notes above).
+   @param[in] MGF - The mask generation function. PKCS#1 v2.1 defines MGF1,
+                    so the only value allowed here is CC_PKCS1_MGF1.
+   @param[in] Data_ptr - Pointer to the data to decrypt.
+   @param[in] DataSize - The size, in bytes, of the data to decrypt.
+                        \Note: The size must be = the size of the modulus.
+
+   @param[out] Output_ptr - Pointer to the decrypted data, the size of the buffer in bytes
+                must be not less than the actual size of Encrypted message, if it is known,
+                else the output buffer size must be :
+                1. for PKCS #1 v.2.1  *OutputSize_ptr >= PrivKey_ptr->N.len - 2*HashLen - 2.
+                2. for PKCS #1 v.1.5  *OutputSize_ptr >= PrivKey_ptr->N.len - 11.
+   @param[in/out] OutputSize_ptr - The size of the user passed Output_ptr buffer in bytes [in] and
+                actual size of decrypted message [out].
+                The minimal input size value of *OutputSize_ptr is described above.
+                This value is updated with the actual number of bytes that
+                are loaded to Output_ptr buffer byDecrypt function.
+
+   @return CCError_t - CC_OK or appropriate Error message defined in the RSA module.
+*/
+CEXPORT_C CCError_t CC_RsaSchemesDecrypt(
+                                             CCRsaUserPrivKey_t  *UserPrivKey_ptr,
+                                             CCRsaPrimeData_t    *PrimeData_ptr,
+                                             CCRsaHashOpMode_t  hashFunc,
+                                             uint8_t              *L,
+                                             size_t                Llen,
+                                             CCPkcs1Mgf_t      MGF,
+                                             uint8_t              *DataIn_ptr,
+                                             size_t                DataInSize,
+                                             uint8_t              *Output_ptr,
+                                             size_t               *OutputSize_ptr,
+                                             CCPkcs1Version_t    PKCS1_ver)
+{
+        /* FUNCTION DECLARATIONS */
+
+        /* The return error identifier */
+        CCError_t Error = CC_OK;
+        uint16_t K; /*The modulus size in Bytes*/
+        uint8_t EB_buff[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE];
+        uint16_t HashOutputSizeBytes;
+        CCRsaPrivKey_t *PrivKey_ptr;
+        /*The Hash enum sent to the lower level functions*/
+        /*The initialization is to eliminate a warning of uninitialized variable*/
+        CCHashOperationMode_t hashOpMode = CC_HASH_NumOfModes;
+
+        int32_t PSSize, i;
+
+
+        /* FUNCTION LOGIC */
+
+        /* .................. initializing local variables ................... */
+        /* ------------------------------------------------------------------- */
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+        /* initialize the HASH mode as SHA1 - default */
+        hashOpMode = CC_HASH_SHA1_mode;
+
+        /* ............... checking the parameters validity ................... */
+        /* -------------------------------------------------------------------- */
+
+        /* if the users context pointer is NULL return an error */
+        if (UserPrivKey_ptr == NULL)
+                return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+
+        if (PrimeData_ptr == NULL)
+                return CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID;
+
+        /* check if the hash operation mode is legal */
+        if (hashFunc >= CC_RSA_HASH_NumOfModes)
+                return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+
+        /* check if the MGF operation mode is legal */
+        if (MGF >= CC_RSA_NumOfMGFFunctions)
+                return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+
+        /* check that the PKCS1 version argument is legal*/
+        if (PKCS1_ver >= CC_RSA_NumOf_PKCS1_versions)
+                return CC_RSA_PKCS1_VER_ARG_ERROR;
+
+        /* if the users Data In pointer is illegal return an error */
+        if (DataIn_ptr == NULL)
+                return CC_RSA_DATA_POINTER_INVALID_ERROR;
+
+        /* if the data size is zero or larger then 2^29 (to prevent an overflow on the transition to bits )
+           return error */
+        if (DataInSize == 0)
+                return CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+
+        /*If the output pointer is NULL return Error*/
+        if (Output_ptr == NULL)
+                return CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
+
+        /*If the output size pointer is NULL return error*/
+        if (OutputSize_ptr ==NULL)
+                return CC_RSA_DECRYPT_OUTPUT_SIZE_POINTER_ERROR;
+
+        PrivKey_ptr = (CCRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
+        if (UserPrivKey_ptr->valid_tag != CC_RSA_PRIV_KEY_VALIDATION_TAG)
+                return CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR;
+
+        if (Llen == 0)
+                L = NULL;
+
+        /* .................. initializing local variables ................... */
+        /* ------------------------------------------------------------------- */
+
+        /*Initialize K with the modulus size in Bytes*/
+        K = (uint16_t)(CALC_FULL_BYTES(PrivKey_ptr->nSizeInBits));
+
+        /*Length Checking - both for Ver 1.5 and 2.1*/
+        if (DataInSize != K)
+                return CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+
+        /*-------------------------------------------------*/
+        switch (PKCS1_ver) {
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT
+        case CC_PKCS1_VER15:
+                /*Check the modulus size is legal*/
+                if (K < 11)
+                        return CC_RSA_INVALID_MODULUS_SIZE;
+                break;
+#endif
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT
+        case CC_PKCS1_VER21:
+
+                switch (hashFunc) {
+                case CC_RSA_HASH_MD5_mode :
+                        /*MD5 is not recommended in PKCS1 ver 2.1 standard, hence it is not supported*/
+                        return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                case CC_RSA_HASH_SHA1_mode:
+                        hashOpMode = CC_HASH_SHA1_mode;/*changing the hash mode to CC definition*/
+                        HashOutputSizeBytes = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+                        break;
+                case CC_RSA_HASH_SHA224_mode:
+                        hashOpMode = CC_HASH_SHA224_mode;
+                        HashOutputSizeBytes = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+                        break;
+                case CC_RSA_HASH_SHA256_mode:
+                        hashOpMode = CC_HASH_SHA256_mode;
+                        HashOutputSizeBytes = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+                        break;
+                case CC_RSA_HASH_SHA384_mode:
+                        hashOpMode = CC_HASH_SHA384_mode;
+                        HashOutputSizeBytes = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+                        break;
+                case CC_RSA_HASH_SHA512_mode:
+                        hashOpMode = CC_HASH_SHA512_mode;
+                        HashOutputSizeBytes = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+                        break;
+                default:
+                        return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+                }
+
+                /*Checking that the modulus have enough large */
+                if (K < 2*HashOutputSizeBytes + 2)
+                        return CC_RSA_INVALID_MODULUS_SIZE;
+                break;
+#endif
+        default:
+                return CC_RSA_PKCS1_VER_ARG_ERROR;
+
+        }/* end of switch(PKCS1_ver) */
+
+
+        /*-------------------------------------------*/
+        /* Step 2 <b> : RSA computation              */
+        /*-------------------------------------------*/
+        Error = CC_RsaPrimDecrypt(UserPrivKey_ptr,
+                                      PrimeData_ptr,
+                                      DataIn_ptr,
+                                      DataInSize,
+                                      EB_buff);
+        if (Error != CC_OK) {
+                goto End;
+        }
+
+        /*----------------------------------------------*
+         * Step 3 :  EME-OAEP Decoding          *
+         *----------------------------------------------*/
+
+        /* for all modes */
+        if (EB_buff[0] != 0x00) {
+                Error = CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING;
+        goto End;
+        }
+
+        /*------------------------------------------------*
+         * Perform decoding operation according to the    *
+         * encoded message EM choosen PKCS1 version       *
+         *------------------------------------------------*/
+
+        switch (PKCS1_ver) {
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT
+        case CC_PKCS1_VER15:
+
+                /*------------------------------------------------*
+                 * Check parameters of decrypted buffer,          *
+                 *    EM= 0x00||0x02||PS||0x00||M                 *
+                 * If EM[0] != 0 or EM[1] != 2 or no 0-byte       *
+                 * after PS or PS length < 8, then output "error" *
+                 * and stop. Output the message M.            *
+                 *------------------------------------------------*/
+
+                if (EB_buff[1] != 0x02/*Block type for EME-PKCS1-v1_5*/) {
+                        Error = CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING;
+            goto End;
+                }
+
+                /* find next 0-byte after PS */
+                for (i = 2; i < K; i++) {
+                        if (EB_buff[i] == 0x00)
+                                break;
+                }
+                /* if byte 0 not present */
+                if (i == K) {
+                        Error = CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING;
+            goto End;
+        }
+
+                /* check PS size >= 8 */
+                PSSize = i - 2;
+                if (PSSize < PS_MIN_LEN) {
+                        Error = CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING;
+            goto End;
+        }
+
+                if (PSSize + 3 > K) {
+                        Error = CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING;
+            goto End;
+        }
+
+                /* check size of output buffer */
+        /* according to the previous check K - 3 > PSSize => it must be positive and therefor can be casted to unsigned */
+                if (*OutputSize_ptr < (uint32_t)(K - 3 - PSSize)) {
+                        Error = CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE;
+            goto End;
+        } else {
+                        *OutputSize_ptr = K - 3 - PSSize; /* output actual size of decrypted message*/
+        }
+
+                /* copy the message into output buffer */
+                CC_PalMemCopy(Output_ptr, &EB_buff[3 + PSSize], *OutputSize_ptr);
+
+                break;
+#endif
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT
+        case CC_PKCS1_VER21:
+
+                /*------------------------------------------------*
+                 * Apply the EME-OAEP decoding operation to the   *
+                 * encoded message EM and the parameter       *
+                 * L to recover a message M:                      *
+                 * M = EME-OAEP-DECODE (EM, L)                    *
+                 * If the decoding operation outputs              *
+                 * "decoding error," then output                  *
+                 * "decryption error" and stop.                   *
+                 *------------------------------------------------*/
+                Error=RsaPssOaepDecode(
+                                             hashOpMode,
+                                             MGF,
+                                             &EB_buff[1],
+                                             (uint16_t)(K-1),
+                                             L,
+                                             Llen,
+                                             PrimeData_ptr,
+                                             Output_ptr,
+                                             OutputSize_ptr);
+                break;
+#endif
+        default:
+                Error = CC_RSA_PKCS1_VER_ARG_ERROR;
+
+        }
+End:
+    if (Error != CC_OK) {
+        CC_PalMemSetZero (Output_ptr ,*OutputSize_ptr);
+        *OutputSize_ptr = 0;
+    }
+    /* clear the temp data buffer */
+    CC_PalMemSetZero(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+
+        return Error;
+
+}/* END OF CC_RsaSchemesDecrypt */
+
+
+#endif /*!defined(_INTERNAL_CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
+#endif /*!defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_sign.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_sign.c
new file mode 100644
index 0000000..135e3d9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_sign.c
@@ -0,0 +1,665 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+/************* Include Files ****************/
+#include "cc_pal_mem.h"
+#include <stdbool.h>
+#include "cc_rsa_prim.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_types.h"
+#include "cc_rsa_local.h"
+#include "cc_fips_defs.h"
+
+/************************ Defines ******************************/
+
+/* canceling the lint warning:
+   Use of goto is deprecated */
+/*lint --e{801} */
+#if ( CC_HASH_USER_CTX_SIZE_IN_WORDS > CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS )
+#error CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS OR CC_HASH_USER_CTX_SIZE_IN_WORDS do not defined correctly.
+#endif
+
+/************************ Enums ******************************/
+/************************ Typedefs ***************************/
+/************************ Global Data ************************/
+/************* Private function prototype ********************/
+
+
+/***************** Public Functions **************************/
+
+#ifndef _INTERNAL_CC_NO_RSA_SIGN_SUPPORT
+/**********************************************************************************************************/
+/**
+   \brief RSA_SignInit initializes the Signing
+   multi-call algorithm as defined in PKCS#1 v1.5 and 2.1
+
+    NOTE: 1. In PSS_Sign v2.1 MD5 is not supported, since it is not recommended
+         by the PKCS#1 v2.1.
+          2. According to thesaid standard, implementation of the function
+         for version v1.5 is based on DER encoding of the algorithm info.
+
+           This function does not do cryptographic processing. Rather, it
+           prepares a context that is used by the Update and Finish functions.
+
+   @param[in,out] UserContext_ptr - A pointer to a Context. The value returned here
+                                must be passed to the Update and Finish functions.
+   @param[in] UserPrivKey_ptr - A pointer to the private key data structure.
+                  \note The representation (pair or quintuple) and hence the
+                  algorithm (CRT or not) is determined by the Private Key data structure.
+                  Using of the CC_BuildPrivKey or CC_BuildPrivKeyCRT determines
+                  which algorithm will be used.
+   @param[in] rsaHashMode - The enumerator value, defining the hash function to be used:
+             SHA-1SHA224/256/384/512, MD5 (MD5 allowed only in v1.5).
+             The hash functions recommended by PKCS#1 v2.1 are:
+                         256/384/512. Also allowed "After" HASH modes for said functions.
+   @param[in] MGF - The mask generation function. PKCS#1 v2.1
+                    defines MGF1, so the only value allowed here is CC_PKCS1_MGF1.
+   @param[in] SaltLen - The Length of the Salt buffer (relevant for PKCS#1 Ver 2.1 only,
+                        typically lengths is 0 or hLen). FIPS 186-4 requires, that SaltLen <= hlen.
+                        If SaltLen > KeySize - hLen - 2, the function returns an error.
+   @param[in] PKCS1_ver - Ver 1.5 or 2.1, according to the functionality required.
+
+   @return CCError_t - CC_OK, or error
+*/
+CEXPORT_C CCError_t CC_RsaSignInit(CCRsaPrivUserContext_t *UserContext_ptr,
+                       CCRsaUserPrivKey_t *UserPrivKey_ptr,
+                       CCRsaHashOpMode_t rsaHashMode,
+                       CCPkcs1Mgf_t MGF,
+                       size_t  SaltLen,
+                       CCPkcs1Version_t PKCS1_ver)
+{
+    /* FUNCTION DECLERATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+    /* defining a pointer to the active context allcated by the CCM */
+    RSAPrivContext_t *ccmWorkingContext_ptr;
+    /*Pointer to the private key*/
+    CCRsaPrivKey_t *PrivKey_ptr ;
+    /*The modulus size in Octets*/
+    uint16_t ModulusSizeBytes = 0;
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    const mbedtls_md_info_t *md_info=NULL;
+#endif
+
+    /* FUNCTION LOGIC */
+
+    /* .... aquiring the RSA context ...... */
+    ccmWorkingContext_ptr = (RSAPrivContext_t*)((void*)UserContext_ptr->context_buff);
+
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+
+    /* if the users context ID pointer is NULL return an error */
+    if (UserContext_ptr == NULL){
+            return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /*if the private key object is NULL return an error*/
+    if (UserPrivKey_ptr == NULL){
+            Error = CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+            goto End;
+    }
+
+    /* check if the hash operation mode is legal */
+    if (rsaHashMode >= CC_RSA_HASH_NumOfModes){
+            Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+            goto End;
+    }
+
+    /* check if the MGF operation mode is legal */
+    if (MGF >= CC_RSA_NumOfMGFFunctions){
+            Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+            goto End;
+    }
+
+    /* check that the PKCS1 version argument is legal*/
+    if (PKCS1_ver >= CC_RSA_NumOf_PKCS1_versions){
+            Error = CC_RSA_PKCS1_VER_ARG_ERROR;
+            goto End;
+    }
+
+    if (UserPrivKey_ptr->valid_tag != CC_RSA_PRIV_KEY_VALIDATION_TAG){
+            Error = CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR;
+            goto End;
+    }
+
+    /*According to the PKCS1 ver 2.1 standard it is not recommended to use
+         MD5 hash therefore we do not support it */
+    if (PKCS1_ver == CC_PKCS1_VER21 && rsaHashMode == CC_RSA_HASH_MD5_mode){
+            Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+            goto End;
+    }
+
+    if (PKCS1_ver == CC_PKCS1_VER21) {
+        /*Initializing the Modulus Size in Bytes needed for SaltLength parameter check*/
+        PrivKey_ptr = (CCRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+        /*Note: the (-1) is due to the PKCS#1 Ver2.1 standard section 9.1.1*/
+        ModulusSizeBytes =  (uint16_t)((PrivKey_ptr->nSizeInBits -1) / 8);
+        if ((PrivKey_ptr->nSizeInBits -1) % 8)
+            ModulusSizeBytes++;
+    }
+
+    /*Reset the Context handler for improper previous values initialized*/
+    CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPrivUserContext_t));
+
+    /* ................. loading the context .................................. */
+    /* ------------------------------------------------------------------------ */
+
+    /*Initializing the Hash operation mode in the RSA Context level*/
+    ccmWorkingContext_ptr->RsaHashOperationMode = rsaHashMode;
+
+    if (RsaSupportedHashModes_t[rsaHashMode] == CC_FALSE){
+        Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        goto End;
+    }
+
+    ccmWorkingContext_ptr->HashOperationMode = RsaHashInfo_t[rsaHashMode].hashMode;
+    ccmWorkingContext_ptr->HASH_Result_Size = RsaHashInfo_t[rsaHashMode].hashResultSize;
+
+    if ( (ccmWorkingContext_ptr->HashOperationMode == CC_HASH_SHA384_mode) ||
+         (ccmWorkingContext_ptr->HashOperationMode == CC_HASH_SHA512_mode) )
+        ccmWorkingContext_ptr->HashBlockSize = CC_HASH_SHA512_BLOCK_SIZE_IN_WORDS;
+    else
+        ccmWorkingContext_ptr->HashBlockSize = CC_HASH_BLOCK_SIZE_IN_WORDS;
+
+
+    if ( (rsaHashMode == CC_RSA_HASH_MD5_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA1_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA224_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA256_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA384_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA512_mode ) )
+        ccmWorkingContext_ptr->doHash = true; /* for actual Hash modes */
+    else
+        ccmWorkingContext_ptr->doHash = false;
+
+
+    /* Init HASH */
+    if (ccmWorkingContext_ptr->doHash) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        md_info = mbedtls_md_info_from_type(RsaHash_CC_mbedtls_Info[ccmWorkingContext_ptr->HashOperationMode]);
+        if (NULL == md_info) {
+            goto End;
+        }
+        mbedtls_md_init(&ccmWorkingContext_ptr->RsaHashCtx);
+        Error = mbedtls_md_setup(&ccmWorkingContext_ptr->RsaHashCtx, md_info, 0); // 0 = HASH, not HMAC
+        if (Error != 0) {
+            goto End;
+        }
+
+        Error = mbedtls_md_starts(&ccmWorkingContext_ptr->RsaHashCtx);
+        if (Error != 0) {
+            goto End;
+        }
+#else
+        Error = CC_HashInit(
+            ((CCHashUserContext_t *)((ccmWorkingContext_ptr->RsaHashCtxBuff))),
+            ccmWorkingContext_ptr->HashOperationMode);
+        if (Error != CC_OK)
+            goto End;
+
+#endif
+    }
+
+
+    /* Switch to appropriate PKCS1_version */
+    /*-------------------------------------*/
+    switch (PKCS1_ver) {
+    case CC_PKCS1_VER15:
+        ccmWorkingContext_ptr->PKCS1_Version=CC_PKCS1_VER15;
+        break;
+
+    case CC_PKCS1_VER21:
+        /*Checking restriction of Salt Length ; Hash output size and the mosulus*/
+        if (ModulusSizeBytes < (uint32_t)(ccmWorkingContext_ptr->HASH_Result_Size*4 + SaltLen + 2)) {
+            Error = CC_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR;
+            goto End;
+        }
+        ccmWorkingContext_ptr->PKCS1_Version=CC_PKCS1_VER21;
+        break;
+
+    default:
+        Error = CC_RSA_PKCS1_VER_ARG_ERROR;
+        goto End;
+    }
+
+    /*  Set MGF indication */
+    switch (MGF) {
+    case CC_PKCS1_MGF1:
+        ccmWorkingContext_ptr->MGF_2use = CC_PKCS1_MGF1;
+        break;
+    case CC_PKCS1_NO_MGF:
+        ccmWorkingContext_ptr->MGF_2use = CC_PKCS1_NO_MGF;
+        break;
+    default:
+        Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+        goto End;
+    }
+
+    /* Copying the RSA Private key argument to the context*/
+    CC_PalMemCopy((uint8_t*)&ccmWorkingContext_ptr->PrivUserKey,
+        (uint8_t*)UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+
+    /*Initial the Salt random length relevant for PKCS#1 Ver2.1*/
+    ccmWorkingContext_ptr->SaltLen = SaltLen;
+
+    /* Set the RSA tag to the users context */
+    UserContext_ptr->valid_tag = CC_RSA_SIGN_CONTEXT_VALIDATION_TAG;
+
+End:
+
+    /* .... Clearing the users context in case of error ... */
+    if (Error != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        if(md_info!=NULL){
+                mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
+        }
+#endif
+        CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPrivUserContext_t));
+    }
+
+    return Error;
+
+}/* CC_RsaSignInit */
+
+/**********************************************************************************************************/
+/**
+   \brief CC_RsaSignUpdate processes the data to be signed
+   in a given context.
+
+   \note CC_RsaSignUpdate can be called multiple times
+   with data
+
+   @param[in] UserContext_ptr - A pointer to a valid context,
+                as returned by CC_RsaSignInit.
+   @param[in] DataIn_ptr - A pointer to the data to sign.
+   @param[in] DataInSize - The size, in bytes, of the data to sign.
+
+   @return CCError_t - CC_OK, or error
+*/
+
+CEXPORT_C CCError_t CC_RsaSignUpdate(CCRsaPrivUserContext_t *UserContext_ptr,
+                     uint8_t     *DataIn_ptr,
+                     size_t      DataInSize)
+{
+    /* FUNCTION DECLERATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+    /* defining a pointer to the active context allcated by the CCM */
+    RSAPrivContext_t *ccmWorkingContext_ptr;
+
+    /* FUNCTION LOGIC */
+
+    /* ....... aquiring the RSA context ........ */
+    ccmWorkingContext_ptr = (RSAPrivContext_t*)((void*)&UserContext_ptr->context_buff);
+
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+
+    /* if the users context pointer is NULL return an error */
+    if (UserContext_ptr == NULL){
+        return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /* if the users Data In pointer is illegal return an error */
+    if (DataIn_ptr == NULL && DataInSize) {
+        Error =  CC_RSA_DATA_POINTER_INVALID_ERROR;
+        goto End;
+    }
+
+    /* if the data size is larger then 2^29 (to prevant an overflow on the transition to bits )
+       return error */
+    if (DataInSize >= (1 << 29)) {
+        Error =  CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+        goto End;
+    }
+
+    /* if the users context TAG is illegal return an error - the context is invalid */
+    if (UserContext_ptr->valid_tag != CC_RSA_SIGN_CONTEXT_VALIDATION_TAG) {
+        Error =  CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR;
+        goto End;
+    }
+
+    if (ccmWorkingContext_ptr->doHash) {
+        /*Operate the Hash update function for relevant versions*/
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        Error = mbedtls_md_update(&ccmWorkingContext_ptr->RsaHashCtx, DataIn_ptr, DataInSize);
+        if ( Error != 0 )
+            goto End;
+#else
+        Error=CC_HashUpdate( ((CCHashUserContext_t *)(ccmWorkingContext_ptr->RsaHashCtxBuff)),
+                    DataIn_ptr,
+                    DataInSize );
+        if (Error != CC_OK)
+            goto End;
+#endif
+    } else {
+        /* DataInSize must fit exactly to the size of Hash output that we support */
+        if (DataInSize != ccmWorkingContext_ptr->HASH_Result_Size*sizeof(uint32_t)) {
+            Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
+            goto End;
+        }
+        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/
+        CC_PalMemCopy((uint8_t *)ccmWorkingContext_ptr->HASH_Result, DataIn_ptr, DataInSize);
+    }
+
+End:
+
+    /* .... clearing the users context in case of error .... */
+    if (Error != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
+#endif
+        CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPrivUserContext_t));
+    }
+
+    return Error;
+
+
+}/* CC_RsaSignUpdate */
+
+
+/**********************************************************************************************************/
+/**
+   \brief CC_RsaSignFinish calculates the signature on the
+   data passed to one or more calls to CC_RsaSignUpdate,
+   and releases the context.
+
+   @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param[in,out] UserContext_ptr - A pointer to the Context
+                initialized by the SignInit function
+                and used by the SignUpdate function
+   @param[out] Output_ptr - A pointer to the signature.
+                The buffer must be at least PrivKey_ptr->N.len bytes long
+                (that is, the size of the modulus, in bytes).
+   @param[in,out] OutputSize_ptr - A pointer to the Signature Size value - the input value
+                   is the signature buffer size allocated, the output value is
+                   the signature size used.
+                   The buffer must be at least PrivKey_ptr->N.len bytes long
+                   (that is, the size of the modulus, in bytes).
+
+   @return CCError_t - CC_OK,
+             CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR,
+             CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR,
+             CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
+             CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE,
+             CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR,
+             CC_RSA_PKCS1_VER_ARG_ERROR
+*/
+CEXPORT_C CCError_t CC_RsaSignFinish(
+                     CCRndContext_t *rndContext_ptr,
+                     CCRsaPrivUserContext_t *UserContext_ptr,
+             uint8_t                   *Output_ptr,
+             size_t                    *OutputSize_ptr)
+{
+    /* FUNCTION DECLERATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    /* defining a pointer to the active context allocated by the CCM */
+    RSAPrivContext_t *ccmWorkingContext_ptr;
+    /*The modulus size in Octets*/
+    uint16_t K;
+    CCRsaPrivKey_t *PrivKey_ptr;
+
+
+    /* FUNCTION LOGIC */
+
+    /* ................. aquiring the RSA context ............................. */
+    ccmWorkingContext_ptr = (RSAPrivContext_t*)((void*)&UserContext_ptr->context_buff);
+
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+
+    /* if the users context pointer is NULL return an error */
+    if (UserContext_ptr == NULL){
+        return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /*If the output pointer is NULL return Error*/
+    if (Output_ptr == NULL) {
+        Error =  CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
+        goto End1;
+    }
+
+    /*If the output Size pointer is NULL return Error*/
+    if (OutputSize_ptr == NULL) {
+        Error =  CC_RSA_INVALID_OUTPUT_SIZE_POINTER_ERROR;
+        goto End1;
+    }
+
+    /* if the users context TAG is illegal return an error - the context is invalid */
+    if (UserContext_ptr->valid_tag != CC_RSA_SIGN_CONTEXT_VALIDATION_TAG) {
+        Error =  CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR;
+        goto End1;
+    }
+
+
+    /* ......... checking the validity of the prameters in the context ........ */
+    /* ------------------------------------------------------------------------ */
+
+    PrivKey_ptr = (CCRsaPrivKey_t *)ccmWorkingContext_ptr->PrivUserKey.PrivateKeyDbBuff;
+
+    /*Initializing the Modulus Size in Bytes*/
+    K =  (uint16_t)CALC_FULL_BYTES(PrivKey_ptr->nSizeInBits);
+
+    /* If the received output buffer is small then return an error */
+    if (*OutputSize_ptr < K) {
+        Error = CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE;
+        goto End1;
+    }
+
+    /*Operating the HASH Finish function only in case that Hash operation is needed*/
+    if (ccmWorkingContext_ptr->doHash) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        Error = mbedtls_md_finish(&ccmWorkingContext_ptr->RsaHashCtx,
+                                    (unsigned char *)ccmWorkingContext_ptr->HASH_Result);
+        if ( Error != 0 )
+            goto End;
+#else
+        Error = CC_HashFinish(((CCHashUserContext_t *)(ccmWorkingContext_ptr->RsaHashCtxBuff)),
+                       ccmWorkingContext_ptr->HASH_Result);
+        if (Error != CC_OK)
+            goto End;
+#endif
+    }
+    /* ........................... execute the signiture ........................... */
+    /* ----------------------------------------------------------------------------- */
+
+    switch (ccmWorkingContext_ptr->PKCS1_Version) {
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT
+    case CC_PKCS1_VER21:
+
+        Error = RsaPssSign21(rndContext_ptr, ccmWorkingContext_ptr, Output_ptr);
+        if (Error!=CC_OK)
+            goto End;
+        /* set the output size to the modulus size */
+        *OutputSize_ptr = K;
+        break;
+#endif
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT
+    case CC_PKCS1_VER15:
+        /*The ouput size should be of the Modulus size = K*/
+        Error = RsaEmsaPkcs1v15Encode(
+                K,
+                ccmWorkingContext_ptr->HashOperationMode,
+                (uint8_t*)ccmWorkingContext_ptr->HASH_Result,
+                ccmWorkingContext_ptr->HASH_Result_Size*sizeof(uint32_t),
+                (uint8_t*)ccmWorkingContext_ptr->EBD);
+
+        if (Error!=CC_OK)
+            goto End;
+
+        /* ..........    execute RSA encryption   .......... */
+
+        Error = CC_RsaPrimDecrypt(
+                &ccmWorkingContext_ptr->PrivUserKey,
+                &ccmWorkingContext_ptr->PrimeData,
+                (uint8_t*)ccmWorkingContext_ptr->EBD,
+                K, Output_ptr);
+
+        if (Error!=CC_OK)
+            goto End;
+        /* set the output size to the modulus size */
+        *OutputSize_ptr = K;
+        break;
+#endif
+    default:
+        Error = CC_RSA_PKCS1_VER_ARG_ERROR;
+        goto End;
+
+    }/* end of (ccmWorkingContext_ptr->PKCS1_Version ) switch */
+
+End:
+    if(Error != CC_OK) {
+        CC_PalMemSetZero(Output_ptr, *OutputSize_ptr);
+        *OutputSize_ptr = 0;
+    }
+
+End1:
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
+#endif
+
+    /* .... clearing the users context in case of error  ... */
+    CC_PalMemSetZero(UserContext_ptr,sizeof(CCRsaPrivUserContext_t));
+
+    return Error;
+
+}/* CC_RsaSignFinish */
+
+
+/**********************************************************************************************************/
+/**
+   @brief
+   \brief RSA_Sign implements the RSASSA-PKCS1v15 algorithm
+    in a single function as defined in PKCS#1 v2.1 standard, including v1.5.
+
+    The user can call the function by appropriate macro according to choosen
+    (and allowed) HASH algorithm SHA1, SHA224... (see macros below).
+
+    NOTE: 1. In PSS_Sign v2.1 MD5 is not supported, since it is not recommended
+         by the PKCS#1 v2.1.
+          2. According to thesaid standard, implementation of the function
+         for version v1.5 is based on DER encoding of the algorithm info.
+
+   @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param[in] UserContext_ptr - A pointer to a Context. For the use of the
+                                function as a space to work on.
+   @param[in] UserPrivKey_ptr - A pointer to the private key data
+                            structure of the user. \note The representation
+                            (pair or quintuple) and hence the
+                            algorithm (CRT or not) is determined
+                            by the Private Key data
+                            structure - using CC_BuildPrivKey
+                            or CC_BuildPrivKeyCRT determines
+                            which algorithm will be used.
+   @param[in] hashFunc - The hash functions supported: SHA1, SHA-256/224/264/512, MD5
+                         (MD5 - allowed only for PKCS#1 v1.5).
+             Also allowed "After" HASH modes for said functions.
+   @param[in] MGF - The mask generation function (enum). Only for PKCS#1 v2.1
+                    defines MGF1, so the only value allowed for v2.1
+                    is CC_PKCS1_MGF1.
+   @param[in] SaltLen - The Length of the Salt buffer (relevant for PKCS#1 Ver 2.1 only)
+            Typical lengths are 0 and hLen (20 for SHA1)
+            The maximum length allowed is NSize - hLen - 2.
+   @param[in] DataIn_ptr - A pointer to the data to sign.
+   @param[in] DataInSize - The size, in bytes, of the data to sign.
+   @param[out] Output_ptr - A pointer to the signature.
+                            The buffer must be at least PrivKey_ptr->N.len bytes long
+                            (that is, the size of the modulus in bytes).
+   @param[in,out] OutputSize_ptr - A pointer to the Signature Size value - the input value
+                            is the signature buffer size allocated, the output value is
+                            the signature size actually used.
+                            The buffer must be at least PrivKey_ptr->N.len bytes long
+                            (that is, the size of the modulus in bytes).
+   @param[in] PKCS1_ver - Ver 1.5 or 2.1, according to the functionality required
+
+   @return CCError_t - CC_OK,
+                         CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR,
+                         CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR,
+                         CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR,
+                         CC_RSA_MGF_ILLEGAL_ARG_ERROR,
+                         CC_RSA_PKCS1_VER_ARG_ERROR,
+                         CC_RSA_INVALID_MESSAGE_DATA_SIZE,
+                         CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
+                         CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE
+*/
+CEXPORT_C CCError_t CC_RsaSign(
+                   CCRndContext_t *rndContext_ptr,
+                   CCRsaPrivUserContext_t *UserContext_ptr,
+           CCRsaUserPrivKey_t *UserPrivKey_ptr,
+           CCRsaHashOpMode_t rsaHashMode,
+           CCPkcs1Mgf_t MGF,
+           size_t       SaltLen,
+           uint8_t     *DataIn_ptr,
+           size_t       DataInSize,
+           uint8_t     *Output_ptr,
+           size_t      *OutputSize_ptr,
+           CCPkcs1Version_t PKCS1_ver)
+
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+
+    /* FUNCTION LOGIC */
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /**********************************************************************
+     *  RSA_SignInit
+     **********************************************************************/
+    Error = CC_RsaSignInit( UserContext_ptr,
+                  UserPrivKey_ptr,
+                  rsaHashMode,
+                  MGF,
+                  SaltLen,
+                  PKCS1_ver);
+    if (Error!=CC_OK)
+        return Error;
+
+    /**********************************************************************
+     *  RSA_SignUpdate
+     **********************************************************************/
+    Error = CC_RsaSignUpdate(UserContext_ptr,
+                   DataIn_ptr,
+                   DataInSize);
+    if (Error!=CC_OK)
+        return Error;
+
+    /**********************************************************************
+     * RSA_SignFinish
+     **********************************************************************/
+    Error = CC_RsaSignFinish(
+                   rndContext_ptr,
+                   UserContext_ptr,
+                   Output_ptr,
+                   OutputSize_ptr);
+    return Error;
+
+}/* END OF CC_RsaSign */
+
+#endif /*_INTERNAL_CC_NO_RSA_SIGN_SUPPORT*/
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_verify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_verify.c
new file mode 100644
index 0000000..d648074
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/cc_rsa_verify.c
@@ -0,0 +1,624 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_ASYM_RSA_DH
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_prim.h"
+#include "cc_common_math.h"
+#include "cc_rsa_local.h"
+#include "cc_fips_defs.h"
+
+/************************ Defines ******************************/
+
+#if ( CC_HASH_USER_CTX_SIZE_IN_WORDS > CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS )
+#error CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS OR CC_HASH_USER_CTX_SIZE_IN_WORDS do not defined correctly.
+#endif
+
+/************************ Enums ******************************/
+/************************ Typedefs ***************************/
+/************************ Global Data ************************/
+
+
+/************* Private function prototype ********************/
+
+
+#ifndef _INTERNAL_CC_NO_RSA_VERIFY_SUPPORT
+
+/************************ Private Functions ******************************/
+
+/**
+   \brief  RSA_VerifyInit initializes the Verify
+   multi-call algorithm as defined in PKCS#1 v1.5 and 2.1
+
+    NOTE: 1. In PSS_Sign v2.1 MD5 is not supported, since it is not recommended
+         by the PKCS#1 v2.1.
+          2. According to thesaid standard, implementation of the function
+         for version v1.5 is based on DER encoding of the algorithm info.
+
+
+   @param[in] UserContext_ptr - A pointer to the public Context
+             structure of the User.
+   @param[in] UserPubKey_ptr - A pointer to the public key data
+               structure.
+   @param[in] rsaHashMode - The hash function to be used. Currently
+             avaliable HASH functions: SHA1/SHA-256/384/512/MD5
+             (MD5 - allowed only for PKCS#1 v1.5).
+             Also allowed "After" HASH modes for said functions.
+   @param[in] MGF - The mask generation function, relevant only for PKCS#1 v2.1.
+            The currently allowed value for v2.1 is CC_PKCS1_MGF1.
+   @param[in] SaltLen - The Length of the Salt buffer. Relevant for PKCS#1 Ver 2.1 only.
+            Typical lengths are 0 and hashLen (20 for SHA1).
+            The maximum length allowed is NSize - hLen - 2.
+            If the salt length is not available in this process, the user
+            can use the define: CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN.
+            Security Note: it is recommended not to use this flag and provide
+                    the Salt length on each verify
+   @param[in] PKCS1_ver - Ver 1.5 or 2.1, according to the functionality required.
+
+   @return CCError_t - CC_OK, or error
+*/
+
+CEXPORT_C CCError_t CC_RsaVerifyInit(CCRsaPubUserContext_t *UserContext_ptr,
+                     CCRsaUserPubKey_t *UserPubKey_ptr,
+                     CCRsaHashOpMode_t rsaHashMode,
+                     CCPkcs1Mgf_t MGF,
+                     size_t  SaltLen,
+                     CCPkcs1Version_t PKCS1_ver)
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+    /* defining a pointer to the active context allcated by the CCM */
+    RSAPubContext_t *ccmWorkingContext_ptr;
+    /*Pointer to the public key for lengths checking*/
+    CCRsaPubKey_t *PubKey_ptr;
+    /*The size of the modulus for lengths checking*/
+    uint32_t ModulusSizeBytes;
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    const mbedtls_md_info_t *md_info=NULL;
+#endif
+    /* FUNCTION LOGIC */
+
+    /* ............... local initializations .............................. */
+    /* -------------------------------------------------------------------- */
+
+    /* initialize the module size to cancel compilers warnings */
+    ModulusSizeBytes = 0;
+    ccmWorkingContext_ptr = (RSAPubContext_t*)UserContext_ptr->context_buff;
+
+
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+
+
+    /* if the users context ID pointer is NULL return an error */
+    if (UserContext_ptr == NULL){
+        return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /*if the private key object is NULL return an error*/
+    if (UserPubKey_ptr == NULL){
+        Error = CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+        goto End;
+    }
+
+    /* check if the hash operation mode is legal */
+    if (rsaHashMode >= CC_RSA_HASH_NumOfModes){
+        Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        goto End;
+    }
+
+    /* check if the MGF operation mode is legal */
+    if (MGF >= CC_RSA_NumOfMGFFunctions){
+        Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+        goto End;
+    }
+
+    /* check that the PKCS1 version argument is legal*/
+    if (PKCS1_ver >= CC_RSA_NumOf_PKCS1_versions){
+        Error = CC_RSA_PKCS1_VER_ARG_ERROR;
+        goto End;
+    }
+
+    /*According to the PKCS1 ver 2.1 standart it is not recommended to use MD5 hash
+         therefore we do not support it */
+    if (PKCS1_ver == CC_PKCS1_VER21 && rsaHashMode == CC_RSA_HASH_MD5_mode){
+        Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        goto End;
+    }
+
+    /*If the validation tag is incorrect*/
+    if (UserPubKey_ptr->valid_tag != CC_RSA_PUB_KEY_VALIDATION_TAG){
+        Error = CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR;
+        goto End;
+    }
+
+    /*Checking if a check on salt length is needed*/
+    if (SaltLen != CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN && PKCS1_ver == CC_PKCS1_VER21) {
+        /*Initializing the Modulus Size in Bytes needed for SaltLength parameter check*/
+        PubKey_ptr = (CCRsaPubKey_t *)UserPubKey_ptr->PublicKeyDbBuff;
+
+        /*Note: the (-1) is due to the PKCS#1 Ver2.1 standard section 9.1.1*/
+        ModulusSizeBytes =  (PubKey_ptr->nSizeInBits - 1) / 8;
+        if ((PubKey_ptr->nSizeInBits - 1) % 8)
+            ModulusSizeBytes++;
+    }
+
+    /* ............... initializing local variables ................ */
+    /* ------------------------------------------------------------- */
+
+    /*Reset the Context handler for improper previous values initialized*/
+    CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPubUserContext_t));
+
+
+    /* Initializing the Hash operation mode in the RSA Context level */
+    /* ------------------------------------------------------------- */
+
+    ccmWorkingContext_ptr->RsaHashOperationMode = rsaHashMode;
+
+    if (RsaSupportedHashModes_t[rsaHashMode] == CC_FALSE){
+            Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+            goto End;
+    }
+
+    ccmWorkingContext_ptr->HashOperationMode = RsaHashInfo_t[rsaHashMode].hashMode;
+    ccmWorkingContext_ptr->HASH_Result_Size = RsaHashInfo_t[rsaHashMode].hashResultSize;
+
+    if ( (ccmWorkingContext_ptr->HashOperationMode == CC_HASH_SHA384_mode) ||
+         (ccmWorkingContext_ptr->HashOperationMode == CC_HASH_SHA512_mode) )
+        ccmWorkingContext_ptr->HashBlockSize = CC_HASH_SHA512_BLOCK_SIZE_IN_WORDS;
+    else
+        ccmWorkingContext_ptr->HashBlockSize = CC_HASH_BLOCK_SIZE_IN_WORDS;
+
+    if ( (rsaHashMode == CC_RSA_HASH_MD5_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA1_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA224_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA256_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA384_mode ) ||
+         (rsaHashMode == CC_RSA_HASH_SHA512_mode ) )
+        ccmWorkingContext_ptr->doHash = true; /* for actual Hash modes */
+    else
+        ccmWorkingContext_ptr->doHash = false;
+
+
+    /* Init HASH */
+    if (ccmWorkingContext_ptr->doHash) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        md_info = mbedtls_md_info_from_type(RsaHash_CC_mbedtls_Info[ccmWorkingContext_ptr->HashOperationMode]);
+        if (NULL == md_info) {
+            goto End;
+        }
+        mbedtls_md_init(&ccmWorkingContext_ptr->RsaHashCtx);
+        Error = mbedtls_md_setup(&ccmWorkingContext_ptr->RsaHashCtx, md_info, 0); // 0 = HASH, not HMAC
+        if (Error != 0) {
+            goto End;
+        }
+
+        Error = mbedtls_md_starts(&ccmWorkingContext_ptr->RsaHashCtx);
+        if (Error != 0) {
+            goto End;
+        }
+#else
+        Error = CC_HashInit(
+            ((CCHashUserContext_t *)((ccmWorkingContext_ptr->RsaHashCtxBuff))),
+            ccmWorkingContext_ptr->HashOperationMode);
+        if (Error != CC_OK)
+            goto End;
+#endif
+    }
+
+
+    /* Switch to appropriate PKCS1_version */
+    /*-------------------------------------*/
+    switch (PKCS1_ver) {
+    case CC_PKCS1_VER15:
+        ccmWorkingContext_ptr->PKCS1_Version = CC_PKCS1_VER15;
+        break;
+    case CC_PKCS1_VER21:
+        ccmWorkingContext_ptr->PKCS1_Version = CC_PKCS1_VER21;
+        /*Checking restriction of Salt Length ; Hash output size and the mosulus*/
+        if (SaltLen != CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN &&
+            ModulusSizeBytes < (uint32_t)(ccmWorkingContext_ptr->HASH_Result_Size*4 + SaltLen + 2)) {
+            Error = CC_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR;
+            goto End;
+        }
+        break;
+    default:
+        Error = CC_RSA_PKCS1_VER_ARG_ERROR;
+        goto End;
+    }
+
+    switch (MGF) {
+    case CC_PKCS1_MGF1:
+    case CC_PKCS1_NO_MGF:
+        ccmWorkingContext_ptr->MGF_2use = MGF;
+        break;
+    default:
+        Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
+        goto End;
+    }
+
+    /*Copy the RSA Pub key to the context*/
+    CC_PalMemCopy((uint8_t *)&ccmWorkingContext_ptr->PubUserKey,(uint8_t *)UserPubKey_ptr,sizeof(CCRsaUserPubKey_t));
+
+    /*Initial the Salt random length relevant for PKCS#1 Ver2.1*/
+    ccmWorkingContext_ptr->SaltLen = SaltLen;
+
+    /* Initialize the size of the modulus */
+    ccmWorkingContext_ptr->nSizeInBytes = CALC_FULL_BYTES(((CCRsaPubKey_t*)UserPubKey_ptr->PublicKeyDbBuff)->nSizeInBits);
+
+    /* set the RSA tag to the users context */
+    UserContext_ptr->valid_tag = CC_RSA_VERIFY_CONTEXT_VALIDATION_TAG;
+
+End:
+
+    /* .............. clearing the users context in case of error.......... */
+    /* -------------------------------------------------------------------- */
+    if (Error != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+            if(md_info!=NULL){
+                    mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
+            }
+#endif
+        CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPubUserContext_t));
+    }
+
+    return Error;
+
+
+}/* END OF CC_RsaVerifyInit */
+
+
+/**********************************************************************************************************/
+/**
+   \brief RSA_VerifyUpdate processes the data to be verified
+   in a given context, according to PKCS1 v1.5 and 2.1
+
+   \note RSA_VerifyUpdate can be called multiple times with data
+
+   @param[in] UserContext_ptr - A pointer to the public Context
+                               structure of the User.
+   @param[in] DataIn_ptr - A pointer to the data whose signature is
+                         to be verified.
+   @param[in] DataInSize - The size, in bytes, of the data whose
+                         signature is to be verified.
+
+   @return CCError_t - CC_OK, or error
+*/
+
+CEXPORT_C CCError_t CC_RsaVerifyUpdate(CCRsaPubUserContext_t *UserContext_ptr,
+                       uint8_t     *DataIn_ptr,
+                       size_t      DataInSize)
+{
+    /* FUNCTION DECLERATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+    /* defining a pointer to the active context allcated by the CCM */
+    RSAPubContext_t *ccmWorkingContext_ptr;
+
+    /* FUNCTION LOGIC */
+
+    /*  extract the RSA context structure */
+    ccmWorkingContext_ptr = (RSAPubContext_t*)UserContext_ptr->context_buff;
+
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+
+    /* if the users context pointer is NULL return an error */
+    if (UserContext_ptr == NULL){
+        return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /* if the users Data In pointer is illegal return an error */
+    if (DataIn_ptr == NULL && DataInSize) {
+        Error = CC_RSA_DATA_POINTER_INVALID_ERROR;
+        goto End;
+    }
+
+    /* if the data size is larger then 2^29 (to prevant an overflow on the transition to bits )
+       return error */
+    if (DataInSize >= (1UL << 29)) {
+        Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE;
+        goto End;
+    }
+
+    /* if the users context TAG is illegal return an error - the context is invalid */
+    if (UserContext_ptr->valid_tag != CC_RSA_VERIFY_CONTEXT_VALIDATION_TAG) {
+        Error = CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR;
+        goto End;
+    }
+
+    if (ccmWorkingContext_ptr->doHash) {
+        /*Operate the Hash update function for relevant versions*/
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        Error = mbedtls_md_update(&ccmWorkingContext_ptr->RsaHashCtx, DataIn_ptr, DataInSize);
+        if (Error != 0)
+            goto End;
+#else
+        Error = CC_HashUpdate(((CCHashUserContext_t*)(ccmWorkingContext_ptr->RsaHashCtxBuff)),
+                       DataIn_ptr,
+                       DataInSize );
+        if (Error != CC_OK)
+            goto End;
+#endif
+    } else {
+        /* DataInSize must fit exactly to the size of Hash output that we support */
+        if (DataInSize != ccmWorkingContext_ptr->HASH_Result_Size*sizeof(uint32_t)) {
+            Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
+            goto End;
+        }
+        /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/
+        CC_PalMemCopy((uint8_t *)ccmWorkingContext_ptr->HASH_Result, DataIn_ptr, DataInSize);
+    }
+
+End:
+
+    /* ..... clearing the users context in case of error  .... */
+    if (Error != CC_OK) {
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
+#endif
+        CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPubUserContext_t));
+    }
+
+    return Error;
+
+}/* END OF CC_RsaVerifyUpdate */
+
+
+/**********************************************************************************************************/
+/**
+
+   \brief RSA_VerifyFinish implements the Finish Phase of the Verify algorithm
+   as defined in PKCS#1 v2.1 or PKCS#1 v1.5
+
+   @param[in] UserContext_ptr - A pointer to the public Context
+                               structure of the User.
+   @param[in] Sig_ptr - A pointer to the signature to be verified.
+                        The length of the signature is PubKey_ptr->N.len bytes
+                        (that is, the size of the modulus, in bytes).
+
+   @return CCError_t - CC_OK, or error
+*/
+
+CEXPORT_C CCError_t CC_RsaVerifyFinish(CCRsaPubUserContext_t *UserContext_ptr,
+                       uint8_t *Sig_ptr)
+{
+    /* FUNCTION DECLERATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+    /* defining a pointer to the active context allcated by the CCM */
+    RSAPubContext_t *ccmWorkingContext_ptr ;
+
+    /*Parameter for the new size of the modulus N in bytes according to PKCS1 Ver 2.1*/
+    uint16_t modSizeBytes; /*rounded number of Bytes for padding2 length*/
+
+    /*Temporary for the N size*/
+    CCRsaPubKey_t *PubKey_ptr;
+
+
+    /* FUNCTION LOGIC */
+
+    /* ................. aquiring the RSA context ............................. */
+    ccmWorkingContext_ptr = (RSAPubContext_t*)UserContext_ptr->context_buff;
+
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+
+    /* if the users context pointer is NULL return an error */
+    if (UserContext_ptr == NULL){
+        return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
+    }
+
+    /* if the users context pointer is NULL return an error */
+    if (Sig_ptr == NULL) {
+        Error = CC_RSA_INVALID_SIGNATURE_BUFFER_POINTER;
+        goto End;
+    }
+
+    /* if the users context TAG is illegal return an error - the context is invalid */
+    if (UserContext_ptr->valid_tag != CC_RSA_VERIFY_CONTEXT_VALIDATION_TAG) {
+        Error = CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR;
+        goto End;
+    }
+
+    PubKey_ptr = (CCRsaPubKey_t *)ccmWorkingContext_ptr->PubUserKey.PublicKeyDbBuff;
+    modSizeBytes = (uint16_t)(CALC_FULL_BYTES(PubKey_ptr->nSizeInBits));
+
+    /* execute the RSA encription of formatted sign block */
+    Error = CC_RsaPrimEncrypt(&ccmWorkingContext_ptr->PubUserKey,
+                      &ccmWorkingContext_ptr->PrimeData,
+                      Sig_ptr,
+                      modSizeBytes,
+                      (uint8_t*)ccmWorkingContext_ptr->EBD);
+    if (Error != CC_OK)
+        goto End;
+
+    /* Initialize the Effective size in bits of the result */
+    ccmWorkingContext_ptr->EBDSizeInBits = CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)&ccmWorkingContext_ptr->EBD,
+                                                                                              modSizeBytes);
+
+    /*Operating the HASH Finish function only in case that Hash operation is needed*/
+    if (ccmWorkingContext_ptr->doHash) {
+        /*Operating the HASH Finish function*/
+#ifdef USE_MBEDTLS_CRYPTOCELL
+        Error = mbedtls_md_finish(&ccmWorkingContext_ptr->RsaHashCtx,
+                                    (unsigned char *)ccmWorkingContext_ptr->HASH_Result);
+        if (Error != 0)
+            goto End;
+#else
+        Error=CC_HashFinish(((CCHashUserContext_t *)(ccmWorkingContext_ptr->RsaHashCtxBuff)),
+                       ccmWorkingContext_ptr->HASH_Result);
+        if (Error != CC_OK)
+            goto End;
+#endif
+    }
+
+    /*-------------------------------------*/
+    /* switch to appropriate PKCS1 Version */
+    /*-------------------------------------*/
+    switch (ccmWorkingContext_ptr->PKCS1_Version) {
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT
+    case CC_PKCS1_VER21:
+        /*Operating the Verify primitive*/
+        Error = RsaPssVerify21(ccmWorkingContext_ptr);
+        if (Error!=CC_OK)
+            goto End;
+        break;
+#endif
+
+#ifndef _INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT
+    case CC_PKCS1_VER15:
+
+        /* Create expected decrypted signature buff.  */
+        Error = RsaEmsaPkcs1v15Encode(
+                modSizeBytes,
+                ccmWorkingContext_ptr->HashOperationMode,
+                (uint8_t*)ccmWorkingContext_ptr->HASH_Result,
+                ccmWorkingContext_ptr->HASH_Result_Size*sizeof(uint32_t),
+                (uint8_t*)&ccmWorkingContext_ptr->PrimeData/*expected buff*/);
+        if (Error!=CC_OK)
+            goto End;
+
+
+
+        /* compare actual and expected values of signature buffer */
+        if (CC_PalMemCmp(&ccmWorkingContext_ptr->PrimeData,
+                  (uint8_t*)ccmWorkingContext_ptr->EBD, modSizeBytes)) {
+            Error = CC_RSA_ERROR_VER15_INCONSISTENT_VERIFY;
+            goto End;
+        }
+        break;
+#endif
+    default:
+        Error = CC_RSA_PKCS1_VER_ARG_ERROR;
+        goto End;
+
+    }/*End of switch()*/
+
+
+End:
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
+#endif
+    /* ..... clearing the users context in case of error ..... */
+    CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPubUserContext_t));
+
+    return Error;
+
+
+}/* END OF CC_RsaVerifyFinish */
+
+
+/**********************************************************************************************************/
+/**
+   \brief RSA_Verify implements the RSASSA-PKCS1v15 algorithm
+    in a single function as defined in PKCS#1 v2.1 (including v1.5).
+
+    The user can call the function by appropriate macro according to choosen
+    (and allowed) HASH algorithm SHA1, SHA224... (see macros below).
+
+    NOTE: 1. In PSS_Verify v2.1 MD5 is not supported, since it is not recommended
+         by the PKCS#1 ver2.1.
+          2. According to the said standard, implementation of the function
+         for version v1.5 is based on DER encoding of hash algorithm ID.
+
+
+   @param[in] UserContext_ptr - A pointer to the public Context,
+                for the use of the function as a space to work on
+   @param[in] UserPubKey_ptr - A pointer to the public key data
+                           structure of the user.
+   @param[in] rsaHashMode - The hash function to be used. Currently
+              avaliable HASH functions: SHA1/SHA-224/256/384/512, MD5
+              (MD5 - allowed only for PKCS#1 v1.5).
+              Also allowed "After" HASH modes for said functions.
+   @param[in] MGF - The mask generation function. only for PKCS#1 v2.1
+                    defines MGF1, so the only value allowed for v2.1
+                    is CC_PKCS1_MGF1.
+   @param[in] SaltLen - The Length of the Salt buffer. relevant for PKCS#1 Ver 2.1 Only
+            Typical lengths are 0 and hLen (20 for SHA1)
+            The maximum length allowed is NSize - hLen - 2
+   @param[in] DataIn_ptr - A pointer to the data whose signature is
+                         to be verified.
+   @param[in] DataInSize - The size, in bytes, of the data whose
+                         signature is to be verified.
+   @param[in] Sig_ptr - A pointer to the signature to be verified.
+                        The length of the signature is PubKey_ptr->N.len bytes
+                        (that is, the size of the modulus, in bytes).
+   @param[in] PKCS1_ver - Ver 1.5 or 2.1, according to the functionality required
+
+   @return CCError_t - CC_OK, or error
+*/
+
+CEXPORT_C CCError_t CC_RsaVerify(CCRsaPubUserContext_t *UserContext_ptr,
+                     CCRsaUserPubKey_t *UserPubKey_ptr,
+                     CCRsaHashOpMode_t rsaHashMode,
+                     CCPkcs1Mgf_t MGF,
+                     size_t    SaltLen,
+                     uint8_t  *DataIn_ptr,
+                     size_t    DataInSize,
+                     uint8_t  *Sig_ptr,
+                     CCPkcs1Version_t PKCS1_ver)
+{
+    /* FUNCTION DECLERATIONS */
+
+    /* The return error identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+    /**********************************************************************
+     *  RSA_VerifyInit
+     **********************************************************************/
+    Error = CC_RsaVerifyInit(UserContext_ptr,
+                   UserPubKey_ptr,
+                   rsaHashMode,
+                   MGF,
+                   SaltLen,
+                   PKCS1_ver);
+    if (Error!=CC_OK)
+        return Error;
+
+    /**********************************************************************
+     *  RSA_VerifyUpdate
+     **********************************************************************/
+    Error = CC_RsaVerifyUpdate(UserContext_ptr,
+                     DataIn_ptr,
+                     DataInSize);
+    if (Error!=CC_OK)
+        return Error;
+
+    /**********************************************************************
+     *  RSA_VerifyFinish
+     **********************************************************************/
+    Error = CC_RsaVerifyFinish(UserContext_ptr,
+                     Sig_ptr);
+
+    return Error;
+
+}/* END OF CC_RsaVerify */
+
+#endif /*_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT*/
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_kg.c b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_kg.c
new file mode 100644
index 0000000..b0ff059
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_kg.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+
+#include "cc_pal_mem.h"
+#include "cc_common.h"
+#include "cc_common_math.h"
+#include "cc_rnd_common.h"
+#include "cc_rnd_local.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_local.h"
+#include "sw_llf_pki_rsa.h"
+#include "ccsw_cc_rsa_types.h"
+
+
+/************************ Defines ******************************/
+
+/************************ Enums ************************************/
+
+/************************ Typedefs *********************************/
+
+/************************ Global Data ******************************/
+
+/*
+ For debugging the RSA_KG module define the following flags in project properties
+ and perform the following:
+   1. Compile project in DEBUG=1 mode.
+   2. Define LLF_PKI_PKA_DEBUG.
+   3. For findingthe bad random factors (P,Q,P1pR,P2pR,P1qR,P2qR):
+      define RSA_KG_FIND_BAD_RND flag, perform test and save (from memory)
+      the found bad vectors.
+   4. For repeat the testing of found bad vectors, write they as HW
+      initialization of the following buffers:
+      P=>RSA_KG_debugPvect, Q=>RSA_KG_debugQvect - in the cc_rsa_kg.c
+      file, and P1pR=>rBuff1, P2pR=>rBuff1, P1qR=>rBuff3, P2qR=>rBuff4 in the
+      LLF_PKI_GenKeyX931FindPrime.c file. Define the flag RSA_KG_NO_RND instead
+      previously defined RSA_KG_FIND_BAD_RND flag and perform the test.
+   5. For ordinary ATP or other tests (without debug) undef all the named flags.
+*/
+
+#if ((defined RSA_KG_FIND_BAD_RND || defined RSA_KG_NO_RND) && defined DEBUG)
+uint8_t   RSA_KG_debugPvect[CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES] =
+{ 0x78,0x71,0xDF,0xC5,0x36,0x98,0x12,0x21,0xCA,0xAC,0x48,0x22,0x01,0x94,0xF7,0x1A,
+    0x1C,0xBF,0x82,0xE9,0x8A,0xE4,0x2C,0x84,0x43,0x46,0xCF,0x6D,0x60,0xFB,0x5B,0xD3};
+uint8_t   RSA_KG_debugQvect[CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES] =
+{ 0x46,0x13,0x9F,0xBA,0xBC,0x8E,0x21,0x13,0x35,0x8C,0x2C,0x2D,0xA8,0xD6,0x59,0x78,
+    0x8A,0x14,0x17,0x5F,0xA5,0xEC,0x22,0xD5,0x87,0xF9,0x99,0x45,0x1B,0x38,0xA3,0xF0};
+#endif
+
+
+/************* Private function prototype **************************/
+
+
+/************************ Public Functions ******************************/
+
+
+/***********************************************************************************************/
+#ifndef _INTERNAL_CC_NO_RSA_KG_SUPPORT
+/**
+   @brief CC_RsaKgKeyPairGenerate generates a Pair of public and private keys on non CRT mode.
+
+   @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param [in] PubExp_ptr - The pointer to the public exponent (public key)
+   @param [in] PubExpSizeInBytes - The public exponent size in bytes.
+   @param [in] KeySize  - The size of the key, in bits. Supported sizes are:
+                - for PKI without PKA HW: all 256 bit multiples between 512 - 2048;
+                - for PKI with PKA: HW all 32 bit multiples between 512 - 2112;
+   @param [out] UserPrivKey_ptr - A pointer to the private key structure.
+               This structure is used as input to the CC_RsaPrimDecrypt API.
+   @param [out] UserPubKey_ptr - A pointer to the public key structure.
+               This structure is used as input to the CC_RsaPrimEncrypt API.
+   @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen
+      operation.
+ * @param rndCtx_ptr - The pointer to structure, containing context ID and void
+ *              pointer to RND State structure, which should be converted to
+ *              actual type inside of the function according to used platform
+ *                  (External or CC). also containig the generate random vector pointer
+
+   @return CCError_t - CC_OK,
+             CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
+             CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+             CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
+             CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
+             CC_RSA_INVALID_MODULUS_SIZE,
+             CC_RSA_INVALID_EXPONENT_SIZE
+*/
+CEXPORT_C CCError_t CC_SwRsaKgGenerateKeyPair(CCRndContext_t *rndContext_ptr,
+                            uint8_t             *PubExp_ptr,
+                            uint16_t             PubExpSizeInBytes,
+                            uint32_t             KeySize,
+                            CCSwRsaUserPrivKey_t *UserPrivKey_ptr,
+                            CCSwRsaUserPubKey_t  *UserPubKey_ptr,
+                            CCSwRsaKgData_t      *KeyGenData_ptr)
+{
+    /* LOCAL INITIALIZATIONS AND DECLERATIONS */
+
+    /* the error identifier */
+    CCError_t Error;
+
+    /* the pointers to the key structures */
+    SwRsaPubKey_t  *PubKey_ptr;
+    SwRsaPrivKey_t *PrivKey_ptr;
+
+    /* a temp definition to solve a problem on release mode on VC++ */
+    volatile uint32_t dummy = PubExpSizeInBytes;
+
+    uint32_t  KeySizeInWords = KeySize/32;
+
+
+    /* FUNCTION LOGIC */
+    /* ................ initializaions and local declarations ............ */
+    /* ------------------------------------------------------------------- */
+
+    /* to avoid compilers warnings */
+    dummy = dummy;
+
+    /* initialize the error identifier to O.K */
+    Error = CC_OK;
+
+
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+
+    /* ...... checking the key database handle pointer .................... */
+    if (PubExp_ptr == NULL)
+        return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
+
+    /* ...... checking the validity of the exponent pointer ............... */
+    if (UserPrivKey_ptr == NULL)
+        return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the validity of the modulus pointer .............. */
+    if (UserPubKey_ptr == NULL)
+        return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the validity of the keygen data .................. */
+    if (KeyGenData_ptr == NULL)
+        return CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID;
+
+    /* ...... checking the exponent size .................. */
+    if (PubExpSizeInBytes > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        return CC_RSA_INVALID_EXPONENT_SIZE;
+
+    /* ...... checking the required key size ............................ */
+    if (( KeySize < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        ( KeySize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        ( KeySize % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS )) {
+        return CC_RSA_INVALID_MODULUS_SIZE;
+    }
+
+    /* set the public and private key structure pointers */
+    PubKey_ptr  = ( SwRsaPubKey_t *)UserPubKey_ptr->PublicKeyDbBuff;
+    PrivKey_ptr = ( SwRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+    CC_PalMemSet( UserPrivKey_ptr, 0, sizeof(CCSwRsaUserPrivKey_t) );
+    CC_PalMemSet( UserPubKey_ptr, 0, sizeof(CCSwRsaUserPubKey_t) );
+    CC_PalMemSet( KeyGenData_ptr , 0, sizeof(CCSwRsaKgData_t) );
+
+    /* ................ loading the public exponent to the structure .......... */
+    /* ------------------------------------------------------------------------- */
+    /* loading the buffers to start from LS word to MS word */
+    CC_CommonReverseMemcpy( (uint8_t*)PubKey_ptr->e , PubExp_ptr , PubExpSizeInBytes );
+    /* .......... initializing the effective counters size in bits .......... */
+    PubKey_ptr->eSizeInBits = CC_CommonGetBytesCounterEffectiveSizeInBits( (uint8_t*)PubKey_ptr->e,PubExpSizeInBytes );
+
+    /* if the size in bits is 0 - return error */
+    if (PubKey_ptr->eSizeInBits == 0) {
+        Error = CC_RSA_INVALID_EXPONENT_SIZE;
+        goto End;
+    }
+
+    /* verifying the exponent has legal value (currently only 0x3,0x11 and 0x10001) */
+    if (PubKey_ptr->e[0] != 0x3  &&
+        PubKey_ptr->e[0] != 0x11 &&
+        PubKey_ptr->e[0] != 0x010001) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+    /* .......... initialize the public key on the private structure ............... */
+    CC_PalMemCopy( PrivKey_ptr->PriveKeyDb.NonCrt.e , PubKey_ptr->e , 4*((PubExpSizeInBytes+3)/4) );
+    PrivKey_ptr->PriveKeyDb.NonCrt.eSizeInBits = PubKey_ptr->eSizeInBits;
+
+    /* .......... initializing the key size in bits ......................... */
+
+    /* this initialization is required for the low level function (LLF) - indicates the required
+       size of the key to be found */
+    PubKey_ptr->nSizeInBits  = KeySize;
+    PrivKey_ptr->nSizeInBits = KeySize;
+
+    /* .......... set the private mode to non CRT .............................. */
+    /* ------------------------------------------------------------------------- */
+
+    /* set the mode to non CRT */
+    PrivKey_ptr->OperationMode = CC_RSA_NoCrt;
+
+    /* set the key source as internal */
+    PrivKey_ptr->KeySource = CC_RSA_InternalKey;
+
+    /* ................ executing the key generation ........................... */
+    /* ------------------------------------------------------------------------- */
+    /* generate the random */
+
+#if ( (!defined RSA_KG_FIND_BAD_RND && !defined RSA_KG_NO_RND) || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
+    Error = CC_RsaGenerateVectorInRangeX931(rndContext_ptr, KeySizeInWords / 2, KeyGenData_ptr->KGData.p);
+
+    if (Error != CC_OK)
+        goto End;
+
+    Error = CC_RsaGenerateVectorInRangeX931(rndContext_ptr, KeySizeInWords / 2, KeyGenData_ptr->KGData.q);
+
+    if (Error != CC_OK)
+        goto End;
+#endif
+
+#if (defined RSA_KG_FIND_BAD_RND && defined DEBUG)
+    CC_PalMemCopy( RSA_KG_debugPvect, (uint8_t*)KeyGenData_ptr->KGData.p, KeySizeInBytes / 2 );
+    CC_PalMemCopy( RSA_KG_debugQvect, (uint8_t*)KeyGenData_ptr->KGData.q, KeySizeInBytes / 2);
+#endif
+
+#if (defined RSA_KG_NO_RND  && defined DEBUG)
+    CC_PalMemCopy( (uint8_t*)KeyGenData_ptr->KGData.p, RSA_KG_debugPvect, KeySizeInBytes / 2 );
+    CC_PalMemCopy( (uint8_t*)KeyGenData_ptr->KGData.q, RSA_KG_debugQvect, KeySizeInBytes / 2 );
+#endif
+
+#if ((defined RSA_KG_FIND_BAD_RND || defined RSA_KG_NO_RND) && defined DEBUG)
+  #ifdef BIG__ENDIAN
+    /* for big endiannes machine reverse bytes order in words according to Big Endian  */
+    CC_COMMON_INVERSE_UINT32_IN_ARRAY( KeyGenData_ptr->KGData.p, KeySizeInWords / 2);
+    CC_COMMON_INVERSE_UINT32_IN_ARRAY( KeyGenData_ptr->KGData.q, KeySizeInWords / 2 );
+  #endif
+#endif
+    /* clean the n-buffer */
+    CC_PalMemSetZero( PrivKey_ptr->n, 4*CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS );
+
+    /* ................ execute the low level keygen ........................... */
+    Error = SW_LLF_PKI_RSA_GenerateKeyPair( PubKey_ptr,
+                        PrivKey_ptr,
+                        KeyGenData_ptr);
+
+    /* on failure exit the function */
+    if (Error != CC_OK)
+        goto End;
+
+    /* ................ initialize the low level key structures ................ */
+    /* ------------------------------------------------------------------------- */
+    Error = SW_LLF_PKI_RSA_InitPubKeyDb(PubKey_ptr);
+
+    if (Error != CC_OK)
+        goto End;
+
+    Error = SW_LLF_PKI_RSA_InitPrivKeyDb(PrivKey_ptr);
+
+    if (Error != CC_OK)
+        goto End;
+
+    /* ................ set the key valid tags ................................. */
+    /* ------------------------------------------------------------------------- */
+    UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+    UserPubKey_ptr->valid_tag  = CC_RSA_PUB_KEY_VALIDATION_TAG;
+
+
+
+End:
+        /* clear the KG data structure and keys */
+    CC_PalMemSetZero(KeyGenData_ptr, sizeof(CCSwRsaKgData_t));
+        /*............  end on error  .............*/
+        if(Error) {
+                CC_PalMemSetZero(PubKey_ptr, sizeof(CCSwRsaUserPubKey_t));
+                CC_PalMemSetZero(PrivKey_ptr, sizeof(CCSwRsaUserPrivKey_t));
+        }
+
+        return Error;
+
+}/* END OF CC_SwRsaKgGenerateKeyPair */
+
+
+/***********************************************************************************************/
+/**
+   @brief CC_SwRsaKgGenerateKeyPairCRT generates a Pair of public and private keys on CRT mode.
+
+   @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param [in] PubExp_ptr - The pointer to the public exponent (public key)
+   @param [in] PubExpSizeInBytes - The public exponent size in bits.
+   @param [in] KeySize  - The size of the key, in bits. Supported sizes are:
+                - for PKI without PKA HW: all 256 bit multiples between 512 - 2048;
+                - for PKI with PKA: HW all 32 bit multiples between 512 - 2112;
+   @param [out] UserPrivKey_ptr - A pointer to the private key structure.
+               This structure is used as input to the CC_RsaPrimDecrypt API.
+   @param [out] UserPubKey_ptr - A pointer to the public key structure.
+               This structure is used as input to the CC_RsaPrimEncryped API.
+   @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen operation.
+ * @param [in/out] RndCtx_ptr - The pointer to structure, containing context ID and void
+ *              pointer to RND State structure, which should be converted to
+ *              actual type inside of the function according to used platform
+ *                  (External or CC).
+
+   @return CCError_t - CC_OK,
+             CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
+             CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+             CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
+             CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
+             CC_RSA_INVALID_MODULUS_SIZE,
+             CC_RSA_INVALID_EXPONENT_SIZE
+*/
+
+CEXPORT_C CCError_t CC_SwRsaKgGenerateKeyPairCRT(CCRndContext_t *rndContext_ptr,
+                               uint8_t  *PubExp_ptr,
+                               uint16_t  PubExpSizeInBytes,
+                               uint32_t  KeySize,
+                               CCSwRsaUserPrivKey_t *UserPrivKey_ptr,
+                               CCSwRsaUserPubKey_t  *UserPubKey_ptr,
+                               CCSwRsaKgData_t      *KeyGenData_ptr)
+{
+    /* LOCAL INITIALIZATIONS AND DECLERATIONS */
+
+    /* the error identifier */
+    CCError_t Error = CC_OK;
+
+    /* the pointers to the key structures */
+    SwRsaPubKey_t  *PubKey_ptr;
+    SwRsaPrivKey_t *PrivKey_ptr;
+
+    /* FUNCTION LOGIC */
+    uint32_t  KeySizeInBytes = KeySize/8;
+    uint32_t  KeySizeInWords = KeySize/32;
+
+    /* ................ initializations and local declarations ............ */
+    /* ------------------------------------------------------------------- */
+
+
+
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+    /* ...... checking the key database handle pointer .................... */
+    if (PubExp_ptr == NULL)
+        return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
+
+    /* ...... checking the validity of the exponent pointer ............... */
+    if (UserPrivKey_ptr == NULL)
+        return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the validity of the modulus pointer .............. */
+    if (UserPubKey_ptr == NULL)
+        return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
+
+    /* ...... checking the validity of the keygen data .................. */
+    if (KeyGenData_ptr == NULL)
+        return CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID;
+
+    /* ...... checking the required key size ............................ */
+    if (( KeySize < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        ( KeySize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+        ( KeySize % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS ))
+        return CC_RSA_INVALID_MODULUS_SIZE;
+
+    if (PubExpSizeInBytes > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        return CC_RSA_INVALID_EXPONENT_SIZE;
+
+
+    /* set the public and private key structure pointers */
+    PubKey_ptr  = ( SwRsaPubKey_t *)UserPubKey_ptr->PublicKeyDbBuff;
+    PrivKey_ptr = ( SwRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+
+    /* ................ clear all input structures ............................. */
+    /* ------------------------------------------------------------------------- */
+    /* RL Clean buffers  */
+    CC_PalMemSet( UserPrivKey_ptr , 0 , sizeof(CCSwRsaUserPrivKey_t) );
+    CC_PalMemSet( UserPubKey_ptr  , 0 , sizeof(CCSwRsaUserPubKey_t) );
+    CC_PalMemSet( KeyGenData_ptr  , 0 , sizeof(CCSwRsaKgData_t) );
+
+    /* ................ loading the public exponent to the structure .......... */
+    /* ------------------------------------------------------------------------- */
+
+    /* loading the buffers to start from LS word to MS word */
+    CC_CommonReverseMemcpy( (uint8_t*)PubKey_ptr->e , PubExp_ptr , PubExpSizeInBytes );
+
+    /* .......... initializing the effective counters size in bits .......... */
+    PubKey_ptr->eSizeInBits = CC_CommonGetBytesCounterEffectiveSizeInBits( (uint8_t*)PubKey_ptr->e, PubExpSizeInBytes );
+
+    /* if the size in bits is 0 - return error */
+    if (PubKey_ptr->eSizeInBits == 0) {
+        Error = CC_RSA_INVALID_EXPONENT_SIZE;
+        goto End;
+    }
+
+    /* verifing the exponent has legal value (currently only 0x3,0x11 and 0x10001) */
+        if(PubKey_ptr->e[0] != 0x3   &&
+           PubKey_ptr->e[0] != 0x11  &&
+           PubKey_ptr->e[0] != 0x010001){
+            Error = CC_RSA_INVALID_EXPONENT_VAL;
+            goto End;
+    }
+
+
+    /* .......... initializing the key size in bits ......................... */
+
+    /* this initialization is required for the low level function (LLF) - indicates the required
+       size of the key to be found */
+    PubKey_ptr->nSizeInBits  = KeySize;
+    PrivKey_ptr->nSizeInBits = KeySize;
+
+    /* .......... set the private mode to CRT .................................. */
+    /* ------------------------------------------------------------------------- */
+
+    /* set the mode to CRT */
+    PrivKey_ptr->OperationMode = CC_RSA_Crt;
+
+    /* set the key source as internal */
+    PrivKey_ptr->KeySource = CC_RSA_InternalKey;
+
+    /* ................ executing the key generation ........................... */
+    /* ------------------------------------------------------------------------- */
+
+    /* ................ generate the prime1 and prime2 random numbers .......... */
+
+    /* generate the random */
+    Error = CC_RsaGenerateVectorInRangeX931(rndContext_ptr, KeySizeInWords / 2, KeyGenData_ptr->KGData.p);
+
+    if (Error != CC_OK)
+        goto End;
+
+    Error = CC_RsaGenerateVectorInRangeX931(rndContext_ptr, KeySizeInWords / 2, KeyGenData_ptr->KGData.q);
+
+    if (Error != CC_OK)
+        goto End;
+
+  #ifdef BIG__ENDIAN
+    /* for big endianness machine reverse bytes order according to Big Endian words */
+    CC_COMMON_INVERSE_UINT32_IN_ARRAY( KeyGenData_ptr->KGData.p, KeySizeInWords /2 );
+    CC_COMMON_INVERSE_UINT32_IN_ARRAY( KeyGenData_ptr->KGData.q, KeySizeInWords /2 );
+  #endif
+
+    /* clean the n-buffer */
+    CC_PalMemSetZero( PrivKey_ptr->n, 4*CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS );
+
+    /* ................ execute the low level key gen ........................... */
+    Error = SW_LLF_PKI_RSA_GenerateKeyPair( PubKey_ptr,
+                        PrivKey_ptr,
+                        KeyGenData_ptr );
+
+    /* on failure exit the function */
+    if (Error != CC_OK)
+        goto End;
+
+    /* ................ set the vector sizes ................................... */
+    /* ------------------------------------------------------------------------- */
+
+    PrivKey_ptr->PriveKeyDb.Crt.PSizeInBits =
+    CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)PrivKey_ptr->PriveKeyDb.Crt.P, KeySizeInBytes / 2);
+
+    PrivKey_ptr->PriveKeyDb.Crt.QSizeInBits =
+    CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)PrivKey_ptr->PriveKeyDb.Crt.Q, KeySizeInBytes / 2);
+
+    PrivKey_ptr->PriveKeyDb.Crt.dPSizeInBits =
+    CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)PrivKey_ptr->PriveKeyDb.Crt.dP, KeySizeInBytes / 2);
+
+    PrivKey_ptr->PriveKeyDb.Crt.dQSizeInBits =
+    CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)PrivKey_ptr->PriveKeyDb.Crt.dQ, KeySizeInBytes / 2);
+
+    PrivKey_ptr->PriveKeyDb.Crt.qInvSizeInBits =
+    CC_CommonGetBytesCounterEffectiveSizeInBits((uint8_t*)PrivKey_ptr->PriveKeyDb.Crt.qInv, KeySizeInBytes / 2);
+
+    /* ................ initialize the low level key structures ................ */
+    /* ------------------------------------------------------------------------- */
+
+    Error = SW_LLF_PKI_RSA_InitPubKeyDb( PubKey_ptr );
+
+    if (Error != CC_OK)
+        goto End;
+
+    Error = SW_LLF_PKI_RSA_InitPrivKeyDb( PrivKey_ptr );
+
+    if (Error != CC_OK)
+        goto End;
+
+    /* ................ set the key valid tags ................................. */
+    /* ------------------------------------------------------------------------- */
+
+    UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+    UserPubKey_ptr->valid_tag  = CC_RSA_PUB_KEY_VALIDATION_TAG;
+
+    End:
+
+    /* clear the KG data structure */
+    CC_PalMemSetZero ( KeyGenData_ptr, sizeof(CCSwRsaKgData_t));
+
+        /* on error clear the keys */
+        if (Error != CC_OK) {
+                CC_PalMemSetZero(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+                CC_PalMemSetZero(UserPubKey_ptr, sizeof(CCRsaUserPubKey_t));
+        }
+
+    return Error;
+
+}/* END OF CC_RsaKgKeyPairCrtGenerate */
+
+#endif /*_INTERNAL_CC_NO_RSA_KG_SUPPORT*/
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_kg.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_kg.h
new file mode 100644
index 0000000..47086cb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_kg.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef CCSW_RSA_KG_H
+#define CCSW_RSA_KG_H
+
+
+#include "cc_pal_types.h"
+#include "ccsw_cc_rsa_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/**
+   @brief CC_RsaKgKeyPairGenerate generates a Pair of public and private keys on non CRT mode.
+
+   @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param [in] PubExp_ptr - The pointer to the public exponent (public key)
+   @param [in] PubExpSizeInBytes - The public exponent size in bytes.
+   @param [in] KeySize  - The size of the key, in bits. Supported sizes are:
+                            - for PKI without PKA HW: all 256 bit multiples between 512 - 2048;
+                            - for PKI with PKA: HW all 32 bit multiples between 512 - 2112;
+   @param [out] UserPrivKey_ptr - A pointer to the private key structure.
+                           This structure is used as input to the CC_RsaPrimDecrypt API.
+   @param [out] UserPubKey_ptr - A pointer to the public key structure.
+                           This structure is used as input to the CC_RsaPrimEncrypt API.
+   @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen
+          operation.
+ * @param rndCtx_ptr - The pointer to structure, containing context ID and void
+ *              pointer to RND State structure, which should be converted to
+ *              actual type inside of the function according to used platform
+ *                  (External or CC). Also contains the RND generate vecotr function pointer.
+
+   @return CCError_t - CC_OK,
+                         CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
+                         CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
+                         CC_RSA_INVALID_MODULUS_SIZE,
+                         CC_RSA_INVALID_EXPONENT_SIZE
+*/
+CEXPORT_C CCError_t CC_SwRsaKgGenerateKeyPair(
+            CCRndContext_t *rndContext_ptr,
+            uint8_t             *PubExp_ptr,
+            uint16_t             PubExpSizeInBytes,
+            uint32_t             KeySize,
+            CCSwRsaUserPrivKey_t *UserPrivKey_ptr,
+            CCSwRsaUserPubKey_t  *UserPubKey_ptr,
+            CCSwRsaKgData_t      *KeyGenData_ptr);
+
+
+/***********************************************************************************************/
+/**
+   @brief CC_SwRsaKgGenerateKeyPairCRT generates a Pair of public and private keys on CRT mode.
+
+   @param [in/out] rndContext_ptr  - Pointer to the RND context buffer.
+   @param [in] PubExp_ptr - The pointer to the public exponent (public key)
+   @param [in] PubExpSizeInBytes - The public exponent size in bits.
+   @param [in] KeySize  - The size of the key, in bits. Supported sizes are:
+                            - for PKI without PKA HW: all 256 bit multiples between 512 - 2048;
+                            - for PKI with PKA: HW all 32 bit multiples between 512 - 2112;
+   @param [out] UserPrivKey_ptr - A pointer to the private key structure.
+                           This structure is used as input to the CC_RsaPrimDecrypt API.
+   @param [out] UserPubKey_ptr - A pointer to the public key structure.
+                           This structure is used as input to the CC_RsaPrimEncryped API.
+   @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen operation.
+ * @param [in/out] RndCtx_ptr - The pointer to structure, containing context ID and void
+ *              pointer to RND State structure, which should be converted to
+ *              actual type inside of the function according to used platform
+ *                  (External or CC). Also contains the RND generate vecotr function pointer.
+
+   @return CCError_t - CC_OK,
+                         CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
+                         CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
+                         CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
+                         CC_RSA_INVALID_MODULUS_SIZE,
+                         CC_RSA_INVALID_EXPONENT_SIZE
+*/
+
+CEXPORT_C CCError_t CC_SwRsaKgGenerateKeyPairCRT(
+                CCRndContext_t *rndContext_ptr,
+                uint8_t             *PubExp_ptr,
+                uint16_t             PubExpSizeInBytes,
+                uint32_t             KeySize,
+                CCSwRsaUserPrivKey_t *UserPrivKey_ptr,
+                CCSwRsaUserPubKey_t  *UserPubKey_ptr,
+                CCSwRsaKgData_t      *KeyGenData_ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_types.h b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_types.h
new file mode 100644
index 0000000..7221cb1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/crypto_api/rsa/ccsw_rsa_types.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CCSW_RSA_TYPES_H
+#define CCSW_RSA_TYPES_H
+
+
+#include "cc_pal_types.h"
+#include "cc_hash.h"
+#include "cc_rsa_types.h"
+#include "ccsw_rsa_shared_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+#define   PLS_FALSE  0UL
+#define   PLS_TRUE   1UL
+
+/************************************************************************/
+/* the following definitions are only relevant for RSA code on SW */
+/************************************************************************/
+/* Define the maximal allowed width of the exponentiation sliding window
+in range 2...6. This define is actual for projects on soft platform.
+To minimize code size use the minimum value. To optimize performance
+choose the maximum value */
+/* Define the size of the exponentiation temp buffer, used in LLF_PKI and NON DEPENDED on
+width of the sliding window. The size defined in units equaled to maximal RSA modulus size */
+#define PKI_CONV_CRT_CONST_TEMP_BUFF_SIZE_IN_MODULUS_UNITS  16
+
+/**************  Calculation of buffers sizes in words *******************************/
+
+/* Size of buffers for sliding window exponents */
+#if (PKI_EXP_SLIDING_WINDOW_MAX_VALUE == 6)
+#define PKI_EXP_WINDOW_TEMP_BUFFER_SIZE_IN_MODULUS_UNITS  34
+#else
+#define PKI_EXP_WINDOW_TEMP_BUFFER_SIZE_IN_MODULUS_UNITS  (3 + (1 << (PKI_EXP_SLIDING_WINDOW_MAX_VALUE-1)))
+#endif
+
+
+
+
+/* Define the size of the temp buffer, used in LLF_PKI_CONVERT_TO_CRT and DEPENDED on
+   width of the sliding window in words */
+#if (PKI_CONV_CRT_CONST_TEMP_BUFF_SIZE_IN_MODULUS_UNITS > PKI_EXP_WINDOW_TEMP_BUFFER_SIZE_IN_MODULUS_UNITS )
+#define PKI_CONV_CRT_TEMP_BUFFER_SIZE_IN_WORDS  \
+    (PKI_CONV_CRT_CONST_TEMP_BUFF_SIZE_IN_MODULUS_UNITS * SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS + 2 )
+#else
+#define PKI_CONV_CRT_TEMP_BUFFER_SIZE_IN_WORDS  \
+    (PKI_EXP_WINDOW_TEMP_BUFFER_SIZE_IN_MODULUS_UNITS * SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS + 2 )
+#endif
+
+#define SW_CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS     256
+
+/* maximal allowed key size in words */
+#define SW_CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES    (SW_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / 8)
+
+
+
+
+/************************ Public and private key database Structs ******************************/
+
+/* .................. The public key definitions ...................... */
+/* --------------------------------------------------------------------- */
+
+
+
+/* The public key data structure */
+typedef struct {
+    /* The RSA modulus buffer and its size in bits */
+    uint32_t n[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t nSizeInBits;
+
+    /* The RSA public exponent buffer and its size in bits */
+    uint32_t e[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t eSizeInBits;
+    /* # added for compatibility with size of CC CCRsaPubKey_t type */
+    uint32_t ccRSAIntBuff[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+
+}SwRsaPubKey_t;
+
+/* The user structure prototype used as an input to the CC_RsaPrimEncrypt */
+typedef struct CCSwRsaUserPubKey_t {
+
+        uint32_t valid_tag;
+        uint32_t  PublicKeyDbBuff[sizeof(SwRsaPubKey_t)/sizeof(uint32_t)+1];
+}CCSwRsaUserPubKey_t;
+
+/* .................. The private key definitions ...................... */
+/* --------------------------------------------------------------------- */
+
+/* The private key on non-CRT mode data structure */
+typedef struct {
+    /* The RSA private exponent buffer and its size in bits */
+    uint32_t d[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t dSizeInBits;
+
+    /* The RSA public exponent buffer and its size in bits */
+    uint32_t e[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t eSizeInBits;
+
+}CCSwRsaPrivNonCRTKey_t;
+
+/* The private key on CRT mode data structure */
+#ifndef CC_NO_RSA_SMALL_CRT_BUFFERS_SUPPORT
+/* use small CRT buffers */
+typedef struct {
+    /* The first factor buffer and size in bits */
+    uint32_t P[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    uint32_t PSizeInBits;
+
+    /* The second factor buffer and its size in bits */
+    uint32_t Q[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    uint32_t QSizeInBits;
+
+    /* The first CRT exponent buffer and its size in bits */
+    uint32_t dP[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    uint32_t dPSizeInBits;
+
+    /* The second CRT exponent buffer and its size in bits */
+    uint32_t dQ[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    uint32_t dQSizeInBits;
+
+    /* The first CRT coefficient buffer and its size in bits */
+    uint32_t qInv[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    uint32_t qInvSizeInBits;
+
+}CCSwRsaPrivCrtKey_t;
+
+
+#else /* use large CRT buffers */
+typedef struct {
+    /* The first factor buffer and size in bits */
+    uint32_t P[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t PSizeInBits;
+
+    /* The second factor buffer and its size in bits */
+    uint32_t Q[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t QSizeInBits;
+
+    /* The first CRT exponent buffer and its size in bits */
+    uint32_t dP[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t dPSizeInBits;
+
+    /* The second CRT exponent buffer and its size in bits */
+    uint32_t dQ[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t dQSizeInBits;
+
+    /* The first CRT coefficient buffer and its size in bits */
+    uint32_t qInv[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t qInvSizeInBits;
+
+}CCSwRsaPrivCrtKey_t;
+
+#endif
+
+/* The private key data structure: */
+typedef struct {
+    /* The RSA modulus buffer and its size in bits */
+    uint32_t n[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t nSizeInBits;
+
+    /* The decryption operation mode */
+    CCRsaDecryptionMode_t OperationMode;
+
+    /* the source flag: 1 - External;  2 - Internal generation */
+    CCRsaKeySource_t KeySource;
+
+    /* The union between the CRT and non-CRT data structures */
+    union {
+        CCSwRsaPrivNonCRTKey_t NonCrt;
+        CCSwRsaPrivCrtKey_t    Crt;
+    }PriveKeyDb;
+
+       /* # added for compatibility with size of CC CCRsaPrivKey_t type */
+       uint32_t ccRSAPrivKeyIntBuff[CC_PKA_PRIV_KEY_BUFF_SIZE_IN_WORDS];
+
+}SwRsaPrivKey_t;
+
+/* Define the size of SwRsaPrivKey_t structure for using in temp buffers allocation */
+
+/* The users Key structure prototype, used as an input to the
+CC_RsaPrimDecrypt*/
+typedef struct CCSwRsaUserPrivKey_t {
+
+    uint32_t valid_tag;
+    uint32_t  PrivateKeyDbBuff[sizeof(SwRsaPrivKey_t)/sizeof(uint32_t)+1];
+}CCSwRsaUserPrivKey_t;
+
+/* the RSA data type */
+typedef struct CCSwRsaPrimeData_t {
+    /* The aligned input and output data buffers */
+    uint32_t DataIn[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    uint32_t DataOut[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+
+    /* #include specific fields that are used by the low level */
+    struct {
+        union {
+            struct { /* Temporary buffers used for the exponent calculation */
+                uint32_t Tempbuff1[PKI_EXP_TEMP_BUFFER_SIZE_IN_WORDS];
+                uint32_t Tempbuff2[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS * 2];
+                /* Temporary buffer for self-test support */
+                uint32_t TempBuffer[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+            }NonCrt;
+
+            struct { /* Temporary buffers used for the exponent calculation */
+                uint32_t Tempbuff1[PKI_EXP_TEMP_BUFFER_SIZE_IN_WORDS];
+                uint32_t Tempbuff2[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS * 2];
+            }Crt;
+        }Data;
+    }LLF;
+
+}CCSwRsaPrimeData_t;
+
+/* the KG data type */
+typedef union CCSwRsaKgData_t {
+    struct {
+        /* The aligned input and output data buffers */
+        uint32_t p[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS / 2];
+        uint32_t q[SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS / 2];
+        /* Temporary buffers used for the exponent calculation */
+        uint32_t TempbuffExp[PKI_KEY_GEN_TEMP_BUFF_SIZE_WORDS];
+
+    }KGData;
+
+    CCSwRsaPrimeData_t PrimData;
+
+}CCSwRsaKgData_t;
+
+/* .......................... Temp buff definition  ........................ */
+/* ------------------------------------------------------------------------- */
+
+/* the RSA Convert Key to CRT data type */
+typedef struct CCSwRsaConvertKeyToCrtBuffers_t {
+    /* #include specific fields that are used by the low level */
+    struct {
+        uint32_t TempBuffers[ 7*SW_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS + PKI_EXP_TEMP_BUFFER_SIZE_IN_WORDS ];
+
+    } LLF;
+}CCSwRsaConvertKeyToCrtBuffers_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/aes_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/aes_alt.c
new file mode 100644
index 0000000..b532339
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/aes_alt.c
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdio.h>
+#include "mbedtls/aes_alt.h"
+
+#if defined(MBEDTLS_AES_C) && defined (MBEDTLS_AES_ALT)
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "aes_driver.h"
+
+/**
+ * \brief          Initialize AES context
+ *
+ *
+ * \note           Context block should be pre-allocated by the caller.
+ *
+ * \param ctx      AES context to be initialized
+ */
+void mbedtls_aes_init(mbedtls_aes_context * ctx)
+{
+    AesContext_t *aesCtx = NULL;
+
+    if (NULL == ctx)
+    {
+        CC_PalAbort("ctx cannot be NULL");
+    }
+
+    /* check size of structs match */
+    if (sizeof(mbedtls_aes_context) != sizeof(AesContext_t))
+    {
+        CC_PalAbort("!!!!AES context sizes mismatch!!!\n");
+    }
+
+    aesCtx = (AesContext_t *)ctx;
+
+    aesCtx->padType = CRYPTO_PADDING_NONE;
+    aesCtx->dataBlockType = FIRST_BLOCK;
+    aesCtx->inputDataAddrType = DLLI_ADDR;
+    aesCtx->outputDataAddrType = DLLI_ADDR;
+}
+
+
+/**
+ * \brief          Clear AES context
+ *
+ * \param ctx      AES context to be cleared
+ */
+void mbedtls_aes_free(mbedtls_aes_context * ctx)
+{
+    if (NULL == ctx)
+    {
+        CC_PAL_LOG_ERR("ctx cannot be NULL\n");
+        return;
+    }
+    CC_PalMemSet(ctx, 0, sizeof(mbedtls_aes_context));
+}
+
+
+/**
+ * @brief Internal function:
+ * This function checks the validity of inputs and set the encrypt/decript key & direction
+ * called by mbedtls_aes_setkey_* functions.
+ *
+ * @returns: 0 on success, verious error in case of error.
+ *
+ */
+static int aes_setkey(mbedtls_aes_context * ctx, const unsigned char * key,
+        unsigned int keybits, cryptoDirection_t dir)
+{
+    AesContext_t *aesCtx = NULL;
+
+    /* if the users context ID pointer is NULL return an error */
+    if (NULL == ctx)
+    {
+        CC_PAL_LOG_ERR("ctx cannot be NULL\n");
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    /* check the validity of the key data pointer */
+    if (NULL == key)
+    {
+        CC_PAL_LOG_ERR("key cannot be NULL\n");
+        return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
+    }
+
+    aesCtx = (AesContext_t *)ctx;
+    aesCtx->dir = dir;
+    aesCtx->cryptoKey = USER_KEY;
+
+    switch (keybits) {
+        case 128:
+            aesCtx->keySizeId = KEY_SIZE_128_BIT;
+            break;
+        case 192:
+            aesCtx->keySizeId = KEY_SIZE_192_BIT;
+            break;
+        case 256:
+            aesCtx->keySizeId = KEY_SIZE_256_BIT;
+            break;
+        default:
+            CC_PAL_LOG_ERR("key length (%d) not supported\n", keybits);
+            return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
+        }
+
+    CC_PalMemCopy(aesCtx->keyBuf, key, keybits/8);
+
+    return (0);   // no mbedTLS const for OK.
+
+}
+
+/*
+ * Copy the key into the context, and set the direction to encryption.
+ * A lot of the initialization needed by CC, will be done in the actual crypt function.
+ *
+ * mbedTLS error codes are much more limited then CC, so have to map a bit.
+ *
+ *
+ */
+int mbedtls_aes_setkey_enc(mbedtls_aes_context * ctx, const unsigned char * key,
+        unsigned int keybits)
+{
+    return aes_setkey(ctx, key, keybits, CRYPTO_DIRECTION_ENCRYPT);
+}
+
+/**
+ * \brief          AES key schedule (decryption)
+ *
+ * \param ctx      AES context to be initialized
+ * \param key      decryption key
+ * \param keybits  must be 128, 192 or 256
+ *
+ * \return         0 if successful, or MBEDTLS_ERR_AES_INVALID_KEY_LENGTH/
+ *                 MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH
+ */
+
+
+int mbedtls_aes_setkey_dec(mbedtls_aes_context * ctx, const unsigned char * key,
+        unsigned int keybits)
+{
+    return aes_setkey(ctx, key, keybits, CRYPTO_DIRECTION_DECRYPT);
+}
+
+/**
+ * \brief          AES-ECB block encryption/decryption
+ *
+ * \param ctx      AES context
+ * \param mode     MBEDTLS_AES_ENCRYPT or MBEDTLS_AES_DECRYPT
+ * \param input    16-byte input block
+ * \param output   16-byte output block
+ *
+ * \return         0 if successful, MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH otherwise
+ */
+
+
+int mbedtls_aes_crypt_ecb(mbedtls_aes_context * ctx,
+        int mode,
+        const unsigned char input[AES_BLOCK_SIZE],
+        unsigned char output[AES_BLOCK_SIZE])
+{
+    AesContext_t *aesCtx = NULL;
+    drvError_t drvRet;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if (NULL == ctx || NULL == input || NULL == output)
+    {
+        CC_PAL_LOG_ERR("Null pointer exception\n");
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+    if (MBEDTLS_AES_ENCRYPT != mode && MBEDTLS_AES_DECRYPT != mode)
+    {
+        CC_PAL_LOG_ERR("Mode %d is not supported\n", mode);
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    aesCtx = (AesContext_t *)ctx;
+
+    if (((MBEDTLS_AES_ENCRYPT == mode) && (CRYPTO_DIRECTION_ENCRYPT != aesCtx->dir))  ||
+            ((MBEDTLS_AES_DECRYPT == mode) && (CRYPTO_DIRECTION_DECRYPT != aesCtx->dir)))
+    {
+        //someone made a mistake - set key in the wrong direction
+        CC_PAL_LOG_ERR("Key & operation mode mismatch: mode = %d. aesCtx->dir = %d\n", mode, aesCtx->dir);
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    aesCtx->mode = CIPHER_ECB;
+
+    drvRet = SetDataBuffersInfo(input, AES_BLOCK_SIZE, &inBuffInfo,
+                                output, AES_BLOCK_SIZE, &outBuffInfo);
+    if (drvRet != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+     }
+
+    drvRet = ProcessAesDrv(aesCtx, &inBuffInfo, &outBuffInfo, AES_BLOCK_SIZE);
+
+    if (drvRet != AES_DRV_OK)
+    {
+        CC_PAL_LOG_ERR("ecb crypt failed with error code %d\n", drvRet);
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+    return (0);
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx,
+                    int mode,
+                    size_t length,
+                    unsigned char iv[AES_IV_SIZE],
+                    const unsigned char *input,
+                    unsigned char *output )
+{
+
+    AesContext_t *aesCtx = NULL;
+    drvError_t drvRet;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if (0 == length) /* In case input size is 0 - do nothing and return with success*/
+    {
+        return (0);
+    }
+
+    if (NULL == ctx || NULL == input || NULL == output || NULL == iv)
+    {
+        CC_PAL_LOG_ERR("Null pointer exception\n");
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    if (MBEDTLS_AES_ENCRYPT != mode && MBEDTLS_AES_DECRYPT != mode)
+    {
+        CC_PAL_LOG_ERR("Mode %d is not supported\n", mode);
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    if( length % AES_BLOCK_SIZE )
+    {
+        CC_PAL_LOG_ERR("Length should be a multiple of the block size (16 bytes)\n");
+        return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH );
+    }
+
+    aesCtx = (AesContext_t *)ctx;
+
+    if (((MBEDTLS_AES_ENCRYPT == mode) && (CRYPTO_DIRECTION_ENCRYPT != aesCtx->dir))  ||
+            ((MBEDTLS_AES_DECRYPT == mode) && (CRYPTO_DIRECTION_DECRYPT != aesCtx->dir)))
+    {
+        //someone made a mistake - set key in the wrong direction
+        CC_PAL_LOG_ERR("Key & operation mode mismatch: operation %d key %d\n", mode, aesCtx->dir);
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    CC_PalMemCopy(aesCtx->ivBuf, iv, AES_IV_SIZE);
+    aesCtx->mode = CIPHER_CBC;
+
+    drvRet = SetDataBuffersInfo(input, length, &inBuffInfo,
+                                output, length, &outBuffInfo);
+    if (drvRet != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+     }
+
+    drvRet = ProcessAesDrv(aesCtx, &inBuffInfo, &outBuffInfo, length);
+
+    if (drvRet != AES_DRV_OK)
+    {
+        CC_PAL_LOG_ERR("cbc crypt failed with error code %d\n", drvRet);
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    CC_PalMemCopy(iv, aesCtx->ivBuf, AES_IV_SIZE);
+
+    return (0);
+}
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+
+#if defined(MBEDTLS_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[AES_IV_SIZE],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(mode);
+    CC_UNUSED_PARAM(length);
+    CC_UNUSED_PARAM(iv_off);
+    CC_UNUSED_PARAM(iv);
+    CC_UNUSED_PARAM(input);
+    CC_UNUSED_PARAM(output);
+    return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx,
+                       int mode,
+                       size_t length,
+                       unsigned char iv[AES_IV_SIZE],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(mode);
+    CC_UNUSED_PARAM(length);
+    CC_UNUSED_PARAM(iv);
+    CC_UNUSED_PARAM(input);
+    CC_UNUSED_PARAM(output);
+    return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
+}
+
+#endif /*MBEDTLS_CIPHER_MODE_CFB */
+#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+static int aes_crypt_ctr_ofb( mbedtls_aes_context *ctx,
+                              aesMode_t mode,
+                              size_t length,
+                              size_t *iv_off,
+                              unsigned char iv[AES_BLOCK_SIZE],
+                              const unsigned char *input,
+                              unsigned char *output )
+{
+    AesContext_t *aesCtx = NULL;
+    drvError_t drvRet;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if (0 == length) /* In case input size is 0 - do nothing and return with success*/
+    {
+        return (0);
+    }
+
+    if (NULL == ctx || NULL == iv || NULL == input || NULL == output)
+    {
+        CC_PAL_LOG_ERR("Null pointer exception\n");
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    if ((iv_off != NULL) && (*iv_off != 0))
+    {
+        CC_PAL_LOG_ERR("offset other then 0 is not supported\n");
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    aesCtx = (AesContext_t *)ctx;
+
+    aesCtx->mode = mode;
+    CC_PalMemCopy(aesCtx->ivBuf, iv, AES_BLOCK_SIZE);
+
+    drvRet = SetDataBuffersInfo(input, length, &inBuffInfo,
+                               output, length, &outBuffInfo);
+    if (drvRet != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+
+    drvRet = ProcessAesDrv(aesCtx, &inBuffInfo, &outBuffInfo, length);
+    if (drvRet != AES_DRV_OK)
+    {
+        CC_PAL_LOG_ERR("ctr/ofb crypt failed with error code %d\n", drvRet);
+        return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+    }
+    CC_PalMemCopy(iv, aesCtx->ivBuf, AES_BLOCK_SIZE);
+
+    return (0);
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR || MBEDTLS_CIPHER_MODE_OFB*/
+
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *nc_off,
+                       unsigned char nonce_counter[AES_BLOCK_SIZE],
+                       unsigned char stream_block[AES_BLOCK_SIZE],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    CC_UNUSED_PARAM(stream_block);
+    return aes_crypt_ctr_ofb(ctx, CIPHER_CTR, length, nc_off, nonce_counter, input, output);
+}
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+
+#if defined(MBEDTLS_CIPHER_MODE_OFB)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int mbedtls_aes_crypt_ofb( mbedtls_aes_context *ctx,
+                       size_t length,
+                       size_t *iv_off,
+                       unsigned char iv[AES_BLOCK_SIZE],
+                       const unsigned char *input,
+                       unsigned char *output )
+{
+    return aes_crypt_ctr_ofb(ctx, CIPHER_OFB, length, iv_off, iv, input, output);
+}
+#endif /* MBEDTLS_CIPHER_MODE_OFB */
+
+/*
+ * AES-ECB block encryption
+ */
+int mbedtls_internal_aes_encrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    return( mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_ENCRYPT,  input, output) );
+}
+
+/**
+ * \brief           Internal AES block encryption function
+ *                  (Only exposed to allow overriding it,
+ *                  see MBEDTLS_AES_ENCRYPT_ALT)
+ *
+ * \param ctx       AES context
+ * \param input     Plaintext block
+ * \param output    Output (ciphertext) block
+ */
+void mbedtls_aes_encrypt( mbedtls_aes_context *ctx,
+        const unsigned char input[16],
+        unsigned char output[16] )
+{
+    mbedtls_internal_aes_encrypt( ctx, input, output );
+}
+
+/*
+ * AES-ECB block decryption
+ */
+int mbedtls_internal_aes_decrypt( mbedtls_aes_context *ctx,
+                                  const unsigned char input[16],
+                                  unsigned char output[16] )
+{
+    return( mbedtls_aes_crypt_ecb(ctx, MBEDTLS_AES_DECRYPT,  input, output) );
+}
+
+void mbedtls_aes_decrypt( mbedtls_aes_context *ctx,
+        const unsigned char input[16],
+        unsigned char output[16] )
+{
+    mbedtls_internal_aes_decrypt( ctx, input, output );
+}
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+
+void mbedtls_aes_xts_init( mbedtls_aes_xts_context *ctx )
+{
+    CC_UNUSED_PARAM(ctx);
+    return ;
+}
+
+void mbedtls_aes_xts_free( mbedtls_aes_xts_context *ctx )
+{
+    CC_UNUSED_PARAM(ctx);
+    return ;
+}
+
+
+int mbedtls_aes_xts_setkey_enc( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(key);
+    CC_UNUSED_PARAM(keybits);
+    return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
+}
+
+int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx,
+                                const unsigned char *key,
+                                unsigned int keybits)
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(key);
+    CC_UNUSED_PARAM(keybits);
+    return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
+}
+
+
+int mbedtls_aes_crypt_xts( mbedtls_aes_xts_context *ctx,
+                       int mode,
+                       size_t length,
+                       const unsigned char data_unit[AES_BLOCK_SIZE],
+                       const unsigned char *input,
+                       unsigned char *output )
+
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(mode);
+    CC_UNUSED_PARAM(length);
+    CC_UNUSED_PARAM(data_unit);
+    CC_UNUSED_PARAM(input);
+    CC_UNUSED_PARAM(output);
+    return MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE;
+}
+#endif //defined(MBEDTLS_CIPHER_MODE_XTS)
+
+#endif //defined(MBEDTLS_AES_C) && defined (MBEDTLS_AES_ALT)
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/cc_ecp_internal.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/cc_ecp_internal.c
new file mode 100644
index 0000000..8e4f3ac
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/cc_ecp_internal.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * References:
+ *
+ * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
+ * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone
+ * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
+ * RFC 4492 for the related TLS structures and constants
+ *
+ * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
+ *
+ * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis
+ *     for elliptic curve cryptosystems. In : Cryptographic Hardware and
+ *     Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302.
+ *     <http://link.springer.com/chapter/10.1007/3-540-48059-5_25>
+ *
+ * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to
+ *     render ECC resistant against Side Channel Attacks. IACR Cryptology
+ *     ePrint Archive, 2004, vol. 2004, p. 342.
+ *     <http://eprint.iacr.org/2004/342.pdf>
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECP_C)
+
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define ECP_SHORTWEIERSTRASS
+#endif
+#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+#define ECP_MONTGOMERY
+#endif
+
+#include "mbedtls/ecp.h"
+#include "ecp_common.h"
+#include "mbedtls_common.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_common.h"
+#include "cc_ecpki_error.h"
+#if defined (ECP_MONTGOMERY)
+#include "cc_ec_mont_api.h"
+#endif
+#if defined (ECP_SHORTWEIERSTRASS)
+#include "pka_ec_wrst.h"
+#include "cc_ecpki_kg.h"
+#endif
+#include "cc_ecpki_domain.h"
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#define mbedtls_printf     printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+static int ecc_conv_scalar_to_mpi( uint8_t * scalar, size_t scalarSize, mbedtls_mpi * X)
+{
+    CCError_t status;
+    int ret;
+    unsigned char * outArr = (unsigned char*)mbedtls_calloc(1, scalarSize);
+    CC_UNUSED_PARAM(status); // Fix mps2 warning
+
+    if (NULL == outArr)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    if (CC_OK != (status = CC_CommonReverseMemcpy(outArr, scalar, scalarSize)))
+    {
+        mbedtls_free(outArr);
+        CC_PAL_LOG_ERR("Error - failed to reverse memcpy, status = %d\n",status);
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+    ret = mbedtls_mpi_read_binary(X, outArr, scalarSize);
+    if (0 != ret)
+    {
+        mbedtls_free(outArr);
+        CC_PAL_LOG_ERR("Error - failed to read binary to mpi, ret = %d\n",ret);
+        return ret;
+    }
+
+    X->s = 1; /*unsigned*/
+
+    mbedtls_free(outArr);
+
+    return (0);
+}
+
+static int ecc_conv_mpi_to_scalar( const mbedtls_mpi * X, uint8_t *scalar, size_t *scalarSize)
+{
+    CCError_t  status;
+    int ret;
+    unsigned char * outArr = (unsigned char*)mbedtls_calloc(1, *scalarSize);
+    CC_UNUSED_PARAM(status); // Fix mps2 warning
+
+    if (NULL == outArr)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+
+    ret = mbedtls_mpi_write_binary(X, outArr, *scalarSize);
+    if (0 != ret)
+    {
+        mbedtls_free(outArr);
+        CC_PAL_LOG_ERR("Error - failed to write mpi to binary, ret = %d\n",ret);
+        return ret;
+    }
+
+    if (CC_OK != (status = CC_CommonReverseMemcpy(scalar, outArr, *scalarSize)))
+    {
+        mbedtls_free(outArr);
+        CC_PAL_LOG_ERR("Error - failed to reverse memcpy, status = %d\n",status);
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+    *scalarSize = (X->n * sizeof(mbedtls_mpi_uint));
+
+    mbedtls_free(outArr);
+
+    return 0;
+}
+
+#if defined(ECP_MONTGOMERY)
+static int ecp_mont_mul( mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P )
+{
+    int ret;
+    CCError_t rc;
+    CCEcMontTempBuff_t *ecMontTempBuff;
+    uint8_t resPoint[CC_EC_MONT_MOD_SIZE_IN_BYTES];
+    uint8_t scalar[MBEDTLS_ECP_MAX_BYTES];
+    uint8_t px[CC_EC_MONT_MOD_SIZE_IN_BYTES];
+    size_t resPointSize;
+    size_t scalarSize, pxSize;
+
+    scalarSize = MBEDTLS_ECP_MAX_BYTES;
+    pxSize = CC_EC_MONT_MOD_SIZE_IN_BYTES;
+    resPointSize = CC_EC_MONT_MOD_SIZE_IN_BYTES;
+
+    ret = ecc_conv_mpi_to_scalar(m, scalar, &scalarSize);
+    if (ret != 0)
+    {
+       return ret;
+    }
+
+    mbedtls_zeroize_internal(px, CC_EC_MONT_MOD_SIZE_IN_BYTES);
+    ret = ecc_conv_mpi_to_scalar(&P->X, px, &pxSize);
+    if (ret != 0)
+    {
+        return ret;
+    }
+
+    ecMontTempBuff = mbedtls_calloc( 1, sizeof( CCEcMontTempBuff_t ));
+    if (NULL == ecMontTempBuff)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+
+    rc = CC_EcMontScalarmult(resPoint, &resPointSize, scalar, scalarSize, px, CC_EC_MONT_MOD_SIZE_IN_BYTES, ecMontTempBuff);
+
+    mbedtls_free(ecMontTempBuff);
+    /*secure programing*/
+    mbedtls_zeroize_internal(scalar,scalarSize);
+
+    if (rc != CC_SUCCESS)
+    {
+        CC_PAL_LOG_ERR("Error - multiplication ended with result: %d\n", rc);
+        return error_mapping_cc_to_mbedtls_ecc(rc);
+    }
+    /* prepare the output point R*/
+    /* Y is not used in the result, and Z is 1*/
+    ret =  mbedtls_mpi_lset( &R->Z, 1 );
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - could not set R.z\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    mbedtls_mpi_free(&R->Y);
+    ret = ecc_conv_scalar_to_mpi(resPoint, resPointSize, &R->X);
+    if (ret != 0)
+    {
+        return ret;
+    }
+    return (0);
+
+}
+#endif /* ECP_MONTGOMERY */
+
+#if defined(ECP_SHORTWEIERSTRASS)
+
+static int ecp_wrst_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P )
+{
+    int ret;
+    CCError_t rc;
+    void *tmpBuf;
+    const CCEcpkiDomain_t *pDomain;
+    CCEcpkiDomainID_t domainId;
+
+    ret = ecp_grp_id_to_domain_id(grp->id, &domainId);
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - group id %d is not supported\n",grp->id);
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+    }
+    pDomain = CC_EcpkiGetEcDomain(domainId);
+    if (NULL == pDomain)
+    {
+        CC_PAL_LOG_ERR("Error - domain id %d is not supported\n",domainId);
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+    tmpBuf = mbedtls_calloc(1, sizeof(CCEcpkiKgTempData_t));
+    if (NULL == tmpBuf)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for temporary buffer\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    ret = mbedtls_mpi_grow(&R->X, CALC_FULL_32BIT_WORDS(pDomain->modSizeInBits));
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for R\n");
+        mbedtls_free(tmpBuf);
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+
+    ret = mbedtls_mpi_grow(&R->Y, CALC_FULL_32BIT_WORDS(pDomain->modSizeInBits));
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for R.x\n");
+        mbedtls_free(tmpBuf);
+        mbedtls_mpi_free(&R->X);
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+
+    rc = PkaEcWrstScalarMult(pDomain, m->p, m->n, P->X.p, P->Y.p, R->X.p, R->Y.p, tmpBuf);
+    mbedtls_free(tmpBuf);
+    if (rc != CC_SUCCESS)
+    {
+        CC_PAL_LOG_ERR("Error - multiplication ended with result: %d\n", rc);
+        return error_mapping_cc_to_mbedtls_ecc(rc);
+    }
+
+    ret = mbedtls_mpi_lset( &R->Z, 1 );
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for R\n");
+        mbedtls_mpi_free(&R->X);
+        mbedtls_mpi_free(&R->Y);
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    return (0);
+}
+#endif /* ECP_SHORTWEIERSTRASS */
+
+/*
+ * Multiplication R = m * P
+ */
+int cc_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret;
+
+    CC_UNUSED_PARAM(f_rng);
+    CC_UNUSED_PARAM(p_rng);
+
+    /* Input parameters validation */
+    if (NULL == grp || NULL == R || NULL == m || NULL == P )
+    {
+        CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    }
+    /* Common sanity checks */
+    if( mbedtls_mpi_cmp_int( &P->Z, 1 ) != 0 )
+    {
+        CC_PAL_LOG_ERR("Error - trying to multiply the infinity point\n");
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    ret = mbedtls_ecp_check_privkey( grp, m );
+    if (ret !=0 )
+    {
+        CC_PAL_LOG_ERR("Error - bad private key\n");
+        return( ret );
+    }
+    ret = mbedtls_ecp_check_pubkey( grp, P );
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - bad public key\n");
+        return( ret );
+    }
+
+#if defined(ECP_MONTGOMERY)
+    if( ecp_get_type( grp ) == ECP_TYPE_25519 )
+    {
+        return ecp_mont_mul( R, m, P);
+    }
+#endif
+#if defined(ECP_SHORTWEIERSTRASS)
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+    {
+        return ecp_wrst_mul( grp, R, m, P);
+    }
+#endif
+    return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+}
+
+#if defined(ECP_MONTGOMERY)
+static int ecp_mont_gen_keypair_base(
+                     const mbedtls_ecp_point *G, /* can be NULL in order to use the curve generator*/
+                     mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    CCError_t rc;
+    CCEcMontTempBuff_t *ecMontTempBuff;
+    uint8_t resPoint[CC_EC_MONT_MOD_SIZE_IN_BYTES];
+    uint8_t scalar[MBEDTLS_ECP_MAX_BYTES];
+    uint8_t px[CC_EC_MONT_MOD_SIZE_IN_BYTES];
+    size_t resPointSize;
+    size_t scalarSize, pxSize;
+    CCRndContext_t *pRndContext;
+
+    scalarSize = MBEDTLS_ECP_MAX_BYTES;
+    pxSize = CC_EC_MONT_MOD_SIZE_IN_BYTES;
+    resPointSize = CC_EC_MONT_MOD_SIZE_IN_BYTES;
+
+
+    if (G != NULL) /* Base point was supplied by application*/
+    {
+        mbedtls_zeroize_internal(px, CC_EC_MONT_MOD_SIZE_IN_BYTES);
+        ret = ecc_conv_mpi_to_scalar(&G->X, px, &pxSize);
+        if (ret != 0)
+        {
+            return ret;
+        }
+    }
+
+    ecMontTempBuff = mbedtls_calloc( 1, (sizeof( CCEcMontTempBuff_t ) + sizeof( CCRndContext_t )));
+    if (NULL == ecMontTempBuff)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+
+    pRndContext = (CCRndContext_t *)(ecMontTempBuff + 1);
+    pRndContext->rndGenerateVectFunc = (CCRndGenerateVectWorkFunc_t)f_rng;
+    pRndContext->rndState = p_rng;
+
+    if (G != NULL)
+    {
+        rc = CC_EcMontKeyPairBase(resPoint, &resPointSize, scalar, &scalarSize, px, CC_EC_MONT_MOD_SIZE_IN_BYTES, pRndContext, ecMontTempBuff);
+    }
+    else
+    {
+        rc = CC_EcMontKeyPair(resPoint, &resPointSize, scalar, &scalarSize, pRndContext, ecMontTempBuff);
+    }
+
+    mbedtls_free(ecMontTempBuff);
+
+    if (rc != CC_SUCCESS)
+    {
+        CC_PAL_LOG_ERR("Error - keypair generation ended with result: %d\n", rc);
+        return error_mapping_cc_to_mbedtls_ecc(rc);
+    }
+
+    ret = ecc_conv_scalar_to_mpi(scalar, scalarSize, d);
+    /* secure programing */
+    mbedtls_zeroize_internal(scalar, scalarSize);
+    if (ret != 0)
+    {
+        goto END;
+    }
+    /* prepare the output point Q*/
+    /* Y is not used in the result, and Z is 1*/
+    ret =  mbedtls_mpi_lset( &Q->Z, 1 );
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - could not set Q.z\n");
+        goto END;
+    }
+    mbedtls_mpi_free(&Q->Y);
+    ret = ecc_conv_scalar_to_mpi(resPoint, resPointSize, &Q->X);
+    if (ret != 0)
+    {
+        goto END;
+    }
+
+    /* see [Curve25519] page 5 */
+    ret = mbedtls_mpi_set_bit(d, 0, 0);
+    if (ret != 0)
+    {
+        goto END;
+    }
+    ret = mbedtls_mpi_set_bit(d, 1, 0);
+    if (ret != 0)
+    {
+        goto END;
+    }
+    ret = mbedtls_mpi_set_bit(d, 2, 0);
+    if (ret != 0)
+    {
+        goto END;
+    }
+    ret = mbedtls_mpi_set_bit(d, 255, 0);
+    if (ret != 0)
+    {
+        goto END;
+    }
+    ret = mbedtls_mpi_set_bit(d, 254, 1);
+    if (ret != 0)
+    {
+        goto END;
+    }
+
+    return (0);
+
+    END:
+        mbedtls_ecp_point_free(Q);
+        mbedtls_mpi_free(d);
+        return ret;
+
+}
+#endif /* ECP_MONTGOMERY */
+#if defined(ECP_SHORTWEIERSTRASS)
+
+static int ecp_wrst_gen_keypair_base( mbedtls_ecp_group *grp,
+                     const mbedtls_ecp_point *G, /* can be NULL in order to use the curve generator*/
+                     mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    CCError_t rc;
+    const CCEcpkiDomain_t *pDomain;
+    CCEcpkiDomainID_t domainId;
+    CCRndContext_t *pRndContext;
+    CCEcpkiUserPrivKey_t        *pUserPrivKey;
+    CCEcpkiUserPublKey_t        *pUserPublKey;
+    CCEcpkiPrivKey_t            *pPrivKey;
+    CCEcpkiPublKey_t            *pPublicKey;
+
+    CCEcpkiKgTempData_t         *pTempBuff = NULL;
+
+    ret = ecp_grp_id_to_domain_id(grp->id, &domainId);
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - group id %d is not supported\n",grp->id);
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+
+    }
+    pDomain = CC_EcpkiGetEcDomain(domainId);
+    if (NULL == pDomain)
+    {
+        CC_PAL_LOG_ERR("Error - domain id %d is not supported\n",domainId);
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+    pTempBuff = mbedtls_calloc(1, (sizeof( CCEcpkiKgTempData_t ) + sizeof( CCRndContext_t ) + sizeof( CCEcpkiUserPrivKey_t ) + sizeof( CCEcpkiUserPublKey_t )));
+    if (NULL == pTempBuff)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for temporary buffer\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    pRndContext = (CCRndContext_t *)(pTempBuff + 1);
+    pUserPrivKey = (CCEcpkiUserPrivKey_t *)(pRndContext + 1);
+    pUserPublKey = (CCEcpkiUserPublKey_t *)(pUserPrivKey + 1);
+
+    pRndContext->rndGenerateVectFunc = (CCRndGenerateVectWorkFunc_t)f_rng;
+    pRndContext->rndState = p_rng;
+
+    ret = mbedtls_mpi_grow(&Q->X, CALC_FULL_32BIT_WORDS(pDomain->modSizeInBits));
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for R\n");
+        goto END;
+    }
+    Q->X.s = 1; /*unsigned*/
+
+    ret = mbedtls_mpi_grow(&Q->Y, CALC_FULL_32BIT_WORDS(pDomain->modSizeInBits));
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for R.x\n");
+        goto END;
+    }
+    Q->Y.s = 1; /*unsigned*/
+
+    ret = mbedtls_mpi_grow(d, CALC_FULL_32BIT_WORDS(pDomain->modSizeInBits));
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for R.d\n");
+        goto END;
+    }
+
+    d->s = 1; /*unsigned*/
+
+    if (G != NULL) /* Base point was supplied by the application*/
+    {
+        rc = CC_EcpkiKeyPairGenerateBase(pRndContext, pDomain, G->X.p, G->Y.p, pUserPrivKey, pUserPublKey, pTempBuff, NULL);
+    }
+    else
+    {
+        rc = CC_EcpkiKeyPairGenerate(pRndContext, pDomain, pUserPrivKey, pUserPublKey, pTempBuff, NULL);
+    }
+    if (rc != CC_SUCCESS)
+    {
+        CC_PAL_LOG_ERR("Error - Key generation ended with result: %d\n", rc);
+        ret =  error_mapping_cc_to_mbedtls_ecc(rc);
+        goto END;
+    }
+
+    pPrivKey = (CCEcpkiPrivKey_t *)pUserPrivKey->PrivKeyDbBuff;
+    pPublicKey = (CCEcpkiPublKey_t *)pUserPublKey->PublKeyDbBuff;
+    CC_PalMemCopy(d->p, pPrivKey->PrivKey, CALC_FULL_BYTES(pDomain->modSizeInBits));
+    CC_PalMemCopy(Q->X.p, pPublicKey->x, CALC_FULL_BYTES(pDomain->modSizeInBits));
+    CC_PalMemCopy(Q->Y.p, pPublicKey->y, CALC_FULL_BYTES(pDomain->modSizeInBits));
+
+    ret = mbedtls_mpi_lset( &Q->Z, 1 );
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for R\n");
+        goto END;
+    }
+    ret = (0);
+    goto SUCCESS;
+
+    END:
+
+        mbedtls_ecp_point_free(Q);
+        mbedtls_mpi_free(d);
+    SUCCESS:
+        mbedtls_zeroize_internal(pTempBuff, (sizeof( CCEcpkiKgTempData_t ) + sizeof( CCRndContext_t ) + sizeof( CCEcpkiUserPrivKey_t ) + sizeof( CCEcpkiUserPublKey_t )));
+        mbedtls_free(pTempBuff);
+        return ret;
+}
+#endif /* ECP_SHORTWEIERSTRASS */
+/*
+ * Generate a keypair with configurable base point
+ */
+int cc_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
+                     const mbedtls_ecp_point *G,
+                     mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+
+    /* Input parameters validation */
+    if (NULL == grp || NULL == Q || NULL == d || NULL == G || f_rng == NULL || p_rng == NULL)
+    {
+        CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    }
+#if defined(ECP_MONTGOMERY)
+    if( ecp_get_type( grp ) == ECP_TYPE_25519 )
+    {
+        return ecp_mont_gen_keypair_base(G, d, Q, f_rng, p_rng);
+    }
+#endif /* ECP_MONTGOMERY */
+
+#if defined(ECP_SHORTWEIERSTRASS)
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+    {
+        return ecp_wrst_gen_keypair_base(grp, G, d, Q, f_rng, p_rng);
+    }
+#endif /* ECP_SHORTWEIERSTRASS */
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+}
+#endif /*(MBEDTLS_ECP_C)*/
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ccm_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ccm_alt.c
new file mode 100644
index 0000000..93074e9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ccm_alt.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Definition of CCM:
+ * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
+ * RFC 3610 "Counter with CBC-MAC (CCM)"
+ *
+ * Related:
+ * RFC 5116 "An Interface and Algorithms for Authenticated Encryption"
+ */
+#include "ccm_alt.h"
+
+#if defined(MBEDTLS_CCM_C) && defined (MBEDTLS_CCM_ALT)
+
+#include "cc_pal_types.h"
+#include "mbedtls_common.h"
+
+#include "mbedtls_ccm_internal.h"
+#include "mbedtls_ccm_common.h"
+
+
+/************************ Public Functions **********************/
+/*
+ * Initialize context
+ */
+void mbedtls_ccm_init( mbedtls_ccm_context *ctx )
+{
+    mbedtls_ccm_init_int(ctx);
+}
+
+int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx,
+                        mbedtls_cipher_id_t cipher,
+                        const unsigned char *key,
+                        unsigned int keybits)
+{
+    return mbedtls_ccm_setkey_int(ctx, cipher, key, keybits);
+}
+
+/*
+ * Free context
+ */
+void mbedtls_ccm_free( mbedtls_ccm_context *ctx )
+{
+    mbedtls_ccm_free_int(ctx);
+}
+
+/*
+ * Authenticated encryption
+ */
+int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx,
+                                 size_t length,
+                                 const unsigned char *iv,
+                                 size_t iv_len,
+                                 const unsigned char *add,
+                                 size_t add_len,
+                                 const unsigned char *input,
+                                 unsigned char *output,
+                                 unsigned char *tag,
+                                 size_t tag_len )
+{
+    return mbedtls_ccm_encrypt_and_tag_int(ctx, length, iv, iv_len, add, add_len, input, output, tag, tag_len, MBEDTLS_AESCCM_MODE_CCM);
+}
+
+/*
+ * Authenticated decryption
+ */
+int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx,
+                              size_t length,
+                              const unsigned char *iv,
+                              size_t iv_len,
+                              const unsigned char *add,
+                              size_t add_len,
+                              const unsigned char *input,
+                              unsigned char *output,
+                              const unsigned char *tag,
+                              size_t tag_len )
+{
+
+
+    return mbedtls_ccm_auth_decrypt_int( ctx, length, iv, iv_len, add, add_len, input, output, tag, tag_len, MBEDTLS_AESCCM_MODE_CCM);
+}
+
+int mbedtls_ccm_star_encrypt_and_tag(mbedtls_ccm_context *ctx,
+                                     size_t length,
+                                     const unsigned char *iv,
+                                     size_t iv_len,
+                                     const unsigned char *add,
+                                     size_t add_len,
+                                     const unsigned char *input,
+                                     unsigned char *output,
+                                     unsigned char *tag,
+                                     size_t tag_len)
+{
+    return mbedtls_ccm_encrypt_and_tag_int(ctx, length, iv, iv_len, add, add_len, input, output, tag, tag_len, MBEDTLS_AESCCM_MODE_STAR);
+}
+
+int mbedtls_ccm_star_auth_decrypt(mbedtls_ccm_context *ctx,
+                                  size_t length,
+                                  const unsigned char *iv,
+                                  size_t iv_len,
+                                  const unsigned char *add,
+                                  size_t add_len,
+                                  const unsigned char *input,
+                                  unsigned char *output,
+                                  const unsigned char *tag,
+                                  size_t tag_len)
+{
+    return mbedtls_ccm_auth_decrypt_int(ctx, length, iv, iv_len, add, add_len, input, output, tag, tag_len, MBEDTLS_AESCCM_MODE_STAR);
+
+}
+
+
+
+#endif /* defined(MBEDTLS_CCM_C) && defined (MBEDTLS_CCM_ALT) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/chacha20_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/chacha20_alt.c
new file mode 100644
index 0000000..e8ebfc1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/chacha20_alt.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CHACHA20_C)
+#include "mbedtls/chacha20.h"
+#include "chacha20_alt.h"
+#include "mbedtls/platform_util.h"
+#include "chacha_driver.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if defined(MBEDTLS_CHACHA20_ALT)
+
+
+void mbedtls_chacha20_init( mbedtls_chacha20_context *ctx )
+{
+    ChachaContext_t *chachaCtx = NULL;
+
+    /* ............... checking the parameters validity ................... */
+    /* -------------------------------------------------------------------- */
+    if (NULL == ctx)
+    {
+        CC_PalAbort("ctx cannot be NULL");
+    }
+
+    if (sizeof(mbedtls_chacha20_context) != sizeof(ChachaContext_t)) {
+        CC_PalAbort("\nChacha context sizes mismatch\n");
+    }
+
+    chachaCtx = (ChachaContext_t *)ctx;
+
+    chachaCtx->inputDataAddrType = DLLI_ADDR;
+    chachaCtx->outputDataAddrType = DLLI_ADDR;
+}
+
+void mbedtls_chacha20_free( mbedtls_chacha20_context *ctx )
+{
+    if( ctx != NULL )
+    {
+        mbedtls_platform_zeroize( ctx, sizeof( mbedtls_chacha20_context ) );
+    }
+}
+
+int mbedtls_chacha20_setkey( mbedtls_chacha20_context *ctx,
+                            const unsigned char key[32] )
+{
+
+    ChachaContext_t *chachaCtx = NULL;
+    if( ( ctx == NULL ) || ( key == NULL ) )
+    {
+        return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
+    }
+
+    chachaCtx = (ChachaContext_t *)ctx;
+    CC_PalMemCopy(chachaCtx->keyBuf, key, MBEDTLS_CHACHA_KEY_SIZE_BYTES);
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_starts( mbedtls_chacha20_context* ctx,
+                             const unsigned char nonce[12],
+                             uint32_t counter )
+{
+    ChachaContext_t *chachaCtx = NULL;
+    if( ( ctx == NULL ) || ( nonce == NULL ) )
+    {
+        return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
+    }
+    if (sizeof(mbedtls_chacha20_context) != sizeof(ChachaContext_t)) {
+        return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA;
+    }
+    chachaCtx = (ChachaContext_t *)ctx;
+
+    chachaCtx->nonceSize = (chachaNonceSize_t)MBEDTLS_CHACHA_NONCE_SIZE_12BYTE_TYPE;
+
+    /* Copy the nonce to the context */
+    CC_PalMemCopy(chachaCtx->nonceBuf, nonce, MBEDTLS_CHACHA_NONCE_SIZE_BYTES);
+
+    /* init the block counter */
+    chachaCtx->blockCounterLsb = counter;
+    chachaCtx->blockCounterMsb = 0;
+
+    return( 0 );
+}
+
+int mbedtls_chacha20_update( mbedtls_chacha20_context *ctx,
+                              size_t size,
+                              const unsigned char *input,
+                              unsigned char *output )
+{
+    ChachaContext_t *chachaCtx = NULL;
+    drvError_t drvRc;
+    uintptr_t upDataOut = 0;
+    uintptr_t upDataIn = 0;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if( ctx == NULL )
+    {
+        return( MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA );
+    }
+
+    if ( size != 0 && input == NULL ) {
+        return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA;
+    }
+    if ( size != 0 && output == NULL ) {
+        return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA;
+    }
+    if (size == 0) {
+        return ( 0 );
+    }
+
+    upDataOut = (uintptr_t)input;
+    upDataIn = (uintptr_t)output;
+    if ((((upDataOut > upDataIn) && (upDataOut - upDataIn < size))) ||
+        (((upDataIn > upDataOut) && (upDataIn - upDataOut < size)))) {
+        return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA;
+    }
+
+    drvRc = SetDataBuffersInfo(input, size, &inBuffInfo,
+                               output, size, &outBuffInfo);
+    if (drvRc != 0) {
+        CC_PAL_LOG_ERR("illegal data buffers\n");
+        return MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA;
+    }
+
+    chachaCtx = (ChachaContext_t *)ctx;
+
+    drvRc = ProcessChacha(chachaCtx, &inBuffInfo, &outBuffInfo, size);
+    if (drvRc != 0) {
+        CC_PAL_LOG_ERR("\nProcessChacha failed %d", drvRc);
+        return MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED;
+    }
+
+    return ( 0 );
+}
+
+int mbedtls_chacha20_crypt( const unsigned char key[32],
+                            const unsigned char nonce[12],
+                            uint32_t counter,
+                            size_t data_len,
+                            const unsigned char* input,
+                            unsigned char* output )
+{
+    mbedtls_chacha20_context ctx;
+    int ret;
+
+    mbedtls_chacha20_init( &ctx );
+
+    ret = mbedtls_chacha20_setkey( &ctx, key );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chacha20_starts( &ctx, nonce, counter );
+    if( ret != 0 )
+        goto cleanup;
+
+    ret = mbedtls_chacha20_update( &ctx, data_len, input, output );
+
+cleanup:
+    mbedtls_chacha20_free( &ctx );
+    return( ret );
+}
+
+#endif /* !MBEDTLS_CHACHA20_ALT */
+
+#endif /* !MBEDTLS_CHACHA20_C */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/chachapoly_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/chachapoly_alt.c
new file mode 100644
index 0000000..abf676f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/chachapoly_alt.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CHACHAPOLY_C)
+#include "mbedtls/chachapoly.h"
+#include "poly.h"
+#include "mbedtls/chacha20.h"
+#include "mbedtls/platform_util.h"
+#include "chacha_driver.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if defined(MBEDTLS_CHACHAPOLY_ALT)
+
+void mbedtls_chachapoly_init( mbedtls_chachapoly_context *ctx )
+{
+    if (NULL == ctx)
+    {
+        CC_PalAbort("ctx cannot be NULL");
+    }
+
+    mbedtls_platform_zeroize( ctx->key, sizeof( ctx->key ) );
+
+}
+
+void mbedtls_chachapoly_free( mbedtls_chachapoly_context *ctx )
+{
+    if (ctx == NULL) {
+        return;
+    }
+    mbedtls_platform_zeroize( ctx->key, sizeof( ctx->key ) );
+}
+
+int mbedtls_chachapoly_setkey( mbedtls_chachapoly_context *ctx,
+                               const unsigned char key[32] )
+{
+    if ( (ctx == NULL) || (key == NULL)) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+    CC_PalMemCopy(ctx->key, key, MBEDTLS_CHACHA_KEY_SIZE_BYTES);
+    return ( 0 );
+}
+
+/* Cryptocell only supports integrated chachapoly operations  */
+int mbedtls_chachapoly_starts( mbedtls_chachapoly_context *ctx,
+                               const unsigned char nonce[12],
+                               mbedtls_chachapoly_mode_t mode  )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(nonce);
+    CC_UNUSED_PARAM(mode);
+    return MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE;
+}
+/* Cryptocell only supports integrated chachapoly operations  */
+int mbedtls_chachapoly_update_aad( mbedtls_chachapoly_context *ctx,
+                                   const unsigned char *aad,
+                                   size_t aad_len )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(aad);
+    CC_UNUSED_PARAM(aad_len);
+    return MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE;
+}
+
+/* Cryptocell only supports integrated chachapoly operations  */
+int mbedtls_chachapoly_update( mbedtls_chachapoly_context *ctx,
+                               size_t len,
+                               const unsigned char *input,
+                               unsigned char *output )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(len);
+    CC_UNUSED_PARAM(input);
+    CC_UNUSED_PARAM(output);
+    return MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE;
+}
+
+/* Cryptocell only supports integrated chachapoly operations  */
+int mbedtls_chachapoly_finish( mbedtls_chachapoly_context *ctx,
+                               unsigned char mac[16] )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(mac);
+    return MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE;
+}
+
+static int chachapoly_crypt_and_tag( mbedtls_chachapoly_mode_t mode,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char key[32],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char *input,
+                                     unsigned char *output,
+                                     unsigned char tag[16] )
+{
+    int rc;
+    uint8_t chachaInState[MBEDTLS_CHACHA_BLOCK_SIZE_BYTES] = {0};
+    uint8_t chachaOutState[MBEDTLS_CHACHA_BLOCK_SIZE_BYTES] = {0};
+    mbedtls_poly_key polyKey = {0};
+    mbedtls_poly_mac polyMac = {0};
+    const uint8_t *pCipherData = NULL;
+
+    if (key == NULL) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+
+    if (mode == MBEDTLS_CHACHAPOLY_ENCRYPT) {
+        pCipherData = output;
+    } else if (mode == MBEDTLS_CHACHAPOLY_DECRYPT) {
+        pCipherData = input;
+    } else {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+
+    // 1. Generate poly key
+    // Calling mbedtls_chacha with data=0 is like performing the chacha block function without the encryption
+    rc = mbedtls_chacha20_crypt( key, nonce, 0, sizeof(chachaInState), chachaInState, chachaOutState );
+    if (rc != 0) {
+        goto end_with_error;
+    }
+    // poly key defined as the first 32 bytes of chacha output.
+    CC_PalMemCopy(polyKey, chachaOutState, sizeof(polyKey));
+
+    // 2. Encryption pDataIn
+    if (mode == MBEDTLS_CHACHAPOLY_ENCRYPT) {
+        rc = mbedtls_chacha20_crypt( key, nonce, 1, length, (uint8_t *)input, (uint8_t *)output );
+        if (rc != 0) {
+            goto end_with_error;
+        }
+    }
+
+    // 3. Authentication
+    rc = PolyMacCalc(polyKey, aad, aad_len, pCipherData, length, polyMac, true);
+    if (rc != 0) {
+        rc = MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED;
+        goto end_with_error;
+    }
+
+    CC_PalMemCopy(tag, polyMac, sizeof(polyMac));
+
+    if (mode == MBEDTLS_CHACHAPOLY_DECRYPT) {
+        rc = mbedtls_chacha20_crypt( key, nonce, 1, length, (uint8_t *)input, (uint8_t *)output );
+        if (rc != 0) {
+            goto end_with_error;
+        }
+    }
+
+    return ( 0 );
+
+    end_with_error:
+    if (output != NULL) {
+        CC_PalMemSetZero(output, length);
+    }
+    return rc;
+}
+
+int mbedtls_chachapoly_encrypt_and_tag( mbedtls_chachapoly_context *ctx,
+                                        size_t length,
+                                        const unsigned char nonce[12],
+                                        const unsigned char *aad,
+                                        size_t aad_len,
+                                        const unsigned char *input,
+                                        unsigned char *output,
+                                        unsigned char tag[16] )
+{
+
+    if ( (ctx == NULL) || (nonce == NULL) || (tag == NULL) ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+
+    if ( aad_len != 0 && aad == NULL ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+    if ( length != 0 && input == NULL ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+    if ( length != 0 && output == NULL ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+
+    return( chachapoly_crypt_and_tag( MBEDTLS_CHACHAPOLY_ENCRYPT,
+                                      length, nonce, ctx->key, aad, aad_len,
+                                      input, output, tag ) );
+}
+
+int mbedtls_chachapoly_auth_decrypt( mbedtls_chachapoly_context *ctx,
+                                     size_t length,
+                                     const unsigned char nonce[12],
+                                     const unsigned char *aad,
+                                     size_t aad_len,
+                                     const unsigned char tag[16],
+                                     const unsigned char *input,
+                                     unsigned char *output )
+{
+    unsigned char check_tag[16];
+    int ret;
+    int diff;
+    size_t i;
+
+    if ( (nonce == NULL) || (tag == NULL) ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+
+    if ( aad_len != 0 && aad == NULL ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+    if ( length != 0 && input == NULL ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+    if ( length != 0 && output == NULL ) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+
+    if ( (ret = chachapoly_crypt_and_tag( MBEDTLS_CHACHAPOLY_DECRYPT,
+                                      length, nonce, ctx->key, aad, aad_len,
+                                      input, output, check_tag ) ) != 0 ) {
+        return( ret );
+    }
+
+    /* Check tag in "constant-time" */
+    for( diff = 0, i = 0; i < sizeof( check_tag ); i++ )
+        diff |= tag[i] ^ check_tag[i];
+
+    if( diff != 0 )
+    {
+        mbedtls_platform_zeroize( output, length );
+        return( MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED );
+    }
+    return ( 0 );
+
+}
+
+#endif /* !MBEDTLS_CHACHAPOLY_ALT */
+
+#endif /* !MBEDTLS_CHACHAPOLY_C */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/cmac_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/cmac_alt.c
new file mode 100644
index 0000000..9c15b9b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/cmac_alt.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * References:
+ *
+ * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The
+ *      CMAC Mode for Authentication
+ *   http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf
+ *
+ * - RFC 4493 - The AES-CMAC Algorithm
+ *   https://tools.ietf.org/html/rfc4493
+ *
+ * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message
+ *      Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128)
+ *      Algorithm for the Internet Key Exchange Protocol (IKE)
+ *   https://tools.ietf.org/html/rfc4615
+ *
+ *   Additional test vectors: ISO/IEC 9797-1
+ *
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_CMAC_C) && defined (MBEDTLS_CMAC_ALT)
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free   free
+#endif
+
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_common.h"
+#include "aes_driver.h"
+#include "cc_aes_defs.h"
+#include "cc_aes_error.h"
+#include "mbedtls_common.h"
+#include "mbedtls/cmac.h"
+#include "memory_buffer_alloc.h"
+
+
+/**
+ * \brief        CMAC control context structure
+ */
+typedef struct {
+    /** Internal state of the CMAC algorithm  */
+    unsigned char   state[MBEDTLS_AES_BLOCK_SIZE];
+
+    /** Unprocessed data - either data that was not block aligned and is still
+     *  pending to be processed, or the final block */
+    uint8_t         unprocessed_block[MBEDTLS_AES_BLOCK_SIZE];
+
+    /** Length of data pending to be processed */
+    uint32_t        unprocessed_len;
+}
+mbedtls_cmac_control_context_t;
+
+
+/**
+ * \brief        CMAC private context structure
+ */
+typedef struct {
+    AesContext_t                    aes_ctx;
+    mbedtls_cmac_control_context_t  cmac_ctrl_ctx;
+}
+mbedtls_cmac_private_context_t;
+
+/*
+ * Initialize a context
+ */
+static int cmac_init( AesContext_t *ctx )
+{
+    if( ctx == NULL )
+    {
+        CC_PAL_LOG_ERR("NULL pointer exception\n");
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    mbedtls_zeroize_internal(ctx, sizeof(AesContext_t));
+
+    ctx->mode               = CIPHER_CMAC;
+    ctx->padType            = CRYPTO_PADDING_NONE;
+    ctx->dir                = CRYPTO_DIRECTION_ENCRYPT;
+    ctx->inputDataAddrType  = DLLI_ADDR;
+    ctx->outputDataAddrType = DLLI_ADDR;
+    ctx->dataBlockType      = FIRST_BLOCK;
+
+    return(0);
+}
+
+static int cmac_setkey(AesContext_t *ctx,
+               const unsigned char *key,
+               unsigned int keybits)
+{
+    if (ctx == NULL || key == NULL) {
+        CC_PAL_LOG_ERR("Null pointer, ctx or key are NULL\n");
+        return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+    }
+
+    switch (keybits) {
+        case 128:
+            ctx->keySizeId = KEY_SIZE_128_BIT;
+            break;
+        case 192:
+            ctx->keySizeId = KEY_SIZE_192_BIT;
+            break;
+        case 256:
+            ctx->keySizeId = KEY_SIZE_256_BIT;
+            break;
+        default:
+            return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+    }
+
+    /* update key information in the context */
+    ctx->cryptoKey = USER_KEY;
+
+    /* Copy user key to context */
+    CC_PalMemCopy(ctx->keyBuf, key, (keybits/8));
+
+    return(0);
+}
+
+//***************************************************************************************************//
+int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, const unsigned char *key, size_t keybits )
+{
+    int retval;
+    mbedtls_cmac_context_t *cmac_ctx = NULL;
+
+    if( ctx == NULL )
+    {
+        CC_PAL_LOG_ERR("NULL pointer exception\n");
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    /* Allocated and initialize in the cipher context memory for the CMAC context */
+    cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_private_context_t ) );
+    if( cmac_ctx == NULL ) {
+        return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED );
+    }
+
+    ctx->cmac_ctx = cmac_ctx;
+    mbedtls_zeroize_internal( ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.state,
+                            sizeof( ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.state ) );
+
+    /* Init */
+    if( ( retval = cmac_init( &((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx ) ) != 0 )
+    {
+       CC_PAL_LOG_ERR(" 'cmac_init' failed with return code %d\n", retval);
+       return( retval );
+    }
+
+    /* Set key */
+    if( ( retval = cmac_setkey( &((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx, key, keybits) ) != 0 )
+    {
+       CC_PAL_LOG_ERR(" 'cmac_setkey' failed with return code %d\n", retval);
+       return( retval );
+    }
+
+    return (0);
+}
+
+int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, size_t ilen )
+{
+    mbedtls_cmac_context_t *cmac_ctx = NULL;
+    drvError_t ret = 0;
+    unsigned int block_size;
+    size_t blocks_num;
+    size_t main_chunk_in_bytes = 0;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if( (ctx == NULL) || (input == NULL) )
+    {
+            CC_PAL_LOG_ERR("NULL pointer exception\n");
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    if( ctx == NULL || ctx->cipher_info == NULL || input == NULL ||
+        ctx->cmac_ctx == NULL )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    cmac_ctx = ctx->cmac_ctx;
+    block_size = ctx->cipher_info->block_size;
+
+    /* Is there data still to process from the last call, that's greater in
+     * size than a block? */
+    if( (((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len > 0) &&
+        (ilen > (block_size - ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len)) )
+    {
+        CC_PalMemCopy( &((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_block[((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len],
+                input,
+                block_size - ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len );
+
+        ret = SetDataBuffersInfo((const uint8_t*)&((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_block,
+                                 block_size,
+                                 &inBuffInfo,
+                                 NULL,
+                                 0,
+                                 &outBuffInfo);
+        if (ret != 0)
+        {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+        }
+
+        ret = ProcessAesDrv(&((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx,
+                         &inBuffInfo,
+                         &outBuffInfo,
+                         block_size);
+
+        if (AES_DRV_OK != ret)
+        {
+            CC_PAL_LOG_ERR("ProcessAesDrv failed with return code %d\n", ret);
+            return MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+        }
+
+        input += (block_size - ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len);
+        ilen  -= (block_size - ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len);
+        ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len = 0;
+    }
+
+    /* blocks_num is the number of blocks including any final partial block */
+    blocks_num = ( ilen + block_size - 1 ) / block_size;
+    if ( 1 < blocks_num )
+    {
+        main_chunk_in_bytes = (blocks_num - 1) * block_size;
+
+        ret = SetDataBuffersInfo(input,
+                                 main_chunk_in_bytes,
+                                 &inBuffInfo,
+                                 NULL,
+                                 0,
+                                 &outBuffInfo);
+        if (ret != 0)
+        {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+        }
+
+        /* Process the input data, excluding any final partial or complete block */
+        ret = ProcessAesDrv(&((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx,
+                         &inBuffInfo,
+                         &outBuffInfo,
+                         main_chunk_in_bytes);
+        if (AES_DRV_OK != ret)
+        {
+            CC_PAL_LOG_ERR("ProcessAesDrv failed with return code %d\n",ret);
+            return MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+        }
+
+        ilen  -= main_chunk_in_bytes;
+        input += main_chunk_in_bytes;
+    }
+
+    /* If there is data left over that wasn't aligned to a block */
+    if( ilen > 0 )
+    {
+        CC_PalMemCopy( &((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_block[((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len],
+                input,
+                ilen );
+        ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len += ilen;
+    }
+
+    return (0);
+}
+
+int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, unsigned char *output )
+{
+    mbedtls_cmac_context_t *cmac_ctx = NULL;
+    drvError_t ret = 0;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ||
+            output == NULL )
+    {
+            return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    cmac_ctx = ctx->cmac_ctx;
+
+    ret = SetDataBuffersInfo((const uint8_t*)&((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_block,
+                             ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len,
+                             &inBuffInfo,
+                             NULL,
+                             0,
+                             &outBuffInfo);
+    if (ret != 0)
+    {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
+    }
+
+    ret = FinishAesDrv(&((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx,
+                      &inBuffInfo,
+                      &outBuffInfo,
+                      (uint32_t)((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len);
+
+    if (AES_DRV_OK != ret)
+    {
+        CC_PAL_LOG_ERR("FinishAesDrv failed with return code 0x%x\n", ret);
+        return MBEDTLS_ERR_CIPHER_AUTH_FAILED;
+    }
+
+    CC_PalMemCopy(output, ((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx.ivBuf, AES_IV_SIZE);
+
+    mbedtls_zeroize_internal( ctx->cmac_ctx, sizeof( mbedtls_cmac_private_context_t ) );
+
+    return (0);
+}
+
+int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx )
+{
+    mbedtls_cmac_context_t* cmac_ctx = NULL;
+
+    if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    cmac_ctx = ctx->cmac_ctx;
+
+    /* Reset the internal state */
+    ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_len = 0;
+    mbedtls_zeroize_internal( ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_block,
+                             sizeof( ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.unprocessed_block ) );
+    mbedtls_zeroize_internal( ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.state,
+                             sizeof( ((mbedtls_cmac_private_context_t*)cmac_ctx)->cmac_ctrl_ctx.state ) );
+
+    /* Zeroize the IV in the context */
+    mbedtls_zeroize_internal( ((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx.ivBuf,
+                                 sizeof( ((mbedtls_cmac_private_context_t*)cmac_ctx)->aes_ctx.ivBuf ) );
+
+    return( 0 );
+}
+
+int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info,
+                         const unsigned char *key, size_t keylen,
+                         const unsigned char *input, size_t ilen,
+                         unsigned char *output )
+{
+    mbedtls_cipher_context_t ctx;
+    int ret;
+
+    if( cipher_info == NULL || key == NULL || input == NULL || output == NULL )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+    if( cipher_info->base == NULL )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+    mbedtls_cipher_init( &ctx );
+    ret = mbedtls_cipher_setup( &ctx, cipher_info );
+    if( ret != 0 )
+    {
+        goto exit;
+    }
+
+    ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen );
+    if( ret != 0 )
+    {
+        goto exit;
+    }
+
+    ret = mbedtls_cipher_cmac_update( &ctx, input, ilen );
+    if( ret != 0 )
+    {
+        goto exit;
+    }
+
+    ret = mbedtls_cipher_cmac_finish( &ctx, output );
+
+exit:
+    mbedtls_cipher_free( &ctx );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_AES_C)
+/*
+ * Implementation of AES-CMAC-PRF-128 defined in RFC 4615
+ */
+int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length,
+                              const unsigned char *input, size_t in_len,
+                              unsigned char *output )
+{
+    int ret;
+    const mbedtls_cipher_info_t *cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB);
+    unsigned char zero_key[AES_BLOCK_SIZE];
+    unsigned char int_key[AES_BLOCK_SIZE];
+
+    if( key == NULL || input == NULL || output == NULL )
+    {
+        return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA );
+    }
+
+    if( key_length == AES_BLOCK_SIZE )
+    {
+        /* Use key as is */
+        CC_PalMemCopy( int_key, key, AES_BLOCK_SIZE );
+    }
+    else
+    {
+        memset( zero_key, 0, AES_BLOCK_SIZE );
+
+        ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key,
+                                   key_length, int_key );
+        if( ret != 0 )
+            goto exit;
+    }
+
+    ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len,
+                               output );
+
+exit:
+    mbedtls_zeroize_internal( int_key, sizeof( int_key ) );
+
+    return( ret );
+}
+#endif /* MBEDTLS_AES_C */
+
+#endif /* defined(MBEDTLS_CMAC_C) && defined (MBEDTLS_CMAC_ALT) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/dhm_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/dhm_alt.c
new file mode 100644
index 0000000..5336e91
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/dhm_alt.c
@@ -0,0 +1,727 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_DHM_C)
+#if defined(MBEDTLS_DHM_ALT)
+#include <string.h>
+
+#if defined(MBEDTLS_PEM_PARSE_C)
+#include "mbedtls/pem.h"
+#endif
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+#include "mbedtls/asn1.h"
+#endif
+
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+
+/* include pki.h for using HW Exponentiation function */
+#include "cc_bitops.h"
+#include "cc_common_math.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "dhm_alt.h"
+#include "pka.h"
+#include "pki.h"
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_zeroize( void *v, size_t n ) {
+    volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
+/*
+ * helper to validate the mbedtls_mpi size and import it
+ */
+static int dhm_read_bignum( mbedtls_mpi *X,
+                            unsigned char **p,
+                            const unsigned char *end )
+{
+    int ret, n;
+
+    if( end - *p < 2 )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    n = ( (*p)[0] << 8 ) | (*p)[1];
+    (*p) += 2;
+
+    if( (int)( end - *p ) < n )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 )
+        return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret );
+
+    (*p) += n;
+
+    return( 0 );
+}
+
+/*
+ * Verify sanity of parameter with regards to P
+ *
+ * Parameter should be: 2 <= public_param <= P - 2
+ *
+ * For more information on the attack, see:
+ *  http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
+ *  http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
+ */
+static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P )
+{
+    mbedtls_mpi L, U;
+    int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
+
+    mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) );
+
+    if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 &&
+        mbedtls_mpi_cmp_mpi( param, &U ) <= 0 ) {
+        ret = 0;
+    }
+
+cleanup:
+    mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U );
+    return( ret );
+}
+
+
+#define EXP_MOD_HW 1
+#ifdef EXP_MOD_HW
+
+/**
+ *  Execute modular exponentiation using ARM HW PKA.
+ *
+ *  Notes: Assumed all parameters are checked before calling this function.
+ *         All sizes aligned to 32-bit words, leading zeros are present if exist.
+ *         Values of A and E should be less than modulus size.
+ *         PKA registers used: r0,r1,r2,r3,r4, r30,r31.
+ *
+ *
+ * @return  no return value
+ */
+
+static int mbedtls_mpi_exp_mod_hw(
+        mbedtls_mpi *X/*out*/, const mbedtls_mpi *A/*in*/, const mbedtls_mpi *E/*in*/,
+        const mbedtls_mpi *N/*in*/, mbedtls_mpi *_RR/*in*/ )
+{
+    int err = 0;
+    uint32_t n_size_bits, a_size_bits;
+    uint32_t n_len_words, a_len_words;
+    mbedtls_mpi T;
+
+    mbedtls_mpi_init( &T );
+
+    /* compare range of input parameters */
+    if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) {
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    }
+    if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) {
+        return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
+    }
+
+    /* get actual length of A and N in bits and words */
+    a_size_bits = mbedtls_mpi_bitlen( A );
+    n_size_bits = mbedtls_mpi_bitlen( N );
+    n_len_words = CALC_FULL_32BIT_WORDS( n_size_bits );
+    a_len_words = CALC_FULL_32BIT_WORDS( a_size_bits );
+
+    /* if prime N size is very small or very big (not meets to HW PKA and standards requirements),
+     * then use SW mbedtls function. These exceptions are not important for real practic.  */
+    if( n_size_bits < PKA_MIN_OPERATION_SIZE_BITS || n_size_bits > PKA_MAX_OPERATION_SIZE_BITS ) {
+          err = mbedtls_mpi_exp_mod( X, A, E, N, _RR );
+          goto End;
+    }
+
+    /* allocate positive X  */
+    err = mbedtls_mpi_grow( X, N->n/* + 1*/ );
+    X->s = 1;
+
+    if ( err != 0 ) {
+        goto End;
+    }
+
+    /* if needed reduce A according to its sign and modulus N and then
+       perform exponentiation using PKA HW. */
+    if( a_size_bits > n_size_bits ) {
+        err = mbedtls_mpi_grow( &T, N->n/* + 1*/ );
+        if ( err != 0 ) {
+            goto End;
+        }
+        /* reduction by modulus P using PKA. */
+        err = PkiLongNumDiv( A->p, a_len_words, N->p, n_len_words, T.p/*ModRes*/, NULL/*DivRes*/ );
+        if (err != 0) {
+            goto End;
+        }
+
+        /* execute exponentiation on PKA HW */
+        err = PkiExecModExpLeW( X->p/*out*/, T.p/*in*/, n_len_words, N->p/*modulus*/, n_size_bits, E->p, E->n );
+        if ( err != 0 ) {
+            goto End;
+        }
+    }
+    /* exponentiation without reduction */
+    else {
+        /* execute exponentiation on PKA HW */
+        err = PkiExecModExpLeW( X->p/*out*/, A->p/*in*/, a_len_words, N->p/*modulus*/, n_size_bits, E->p, E->n );
+        if ( err != 0 ) {
+            goto End;
+        }
+    }
+
+    /* modular correction for negative base A */
+    if( ( A->s == -1 )  && ( E->n != 0 ) && (( E->p[0] & 1 ) != 0) )
+    {
+        X->s = -1;
+        err = mbedtls_mpi_add_mpi( X, N, X );
+        if ( err != 0 ) {
+            goto End;
+        }
+    }
+
+
+End:
+
+    if(err) {
+        mbedtls_zeroize( X->p, X->n );
+    }
+    mbedtls_mpi_free(&T);
+
+    return err;
+
+}
+#else
+#define mbedtls_mpi_exp_mod_hw mbedtls_mpi_exp_mod
+#endif
+
+void mbedtls_dhm_init( mbedtls_dhm_context *ctx )
+{
+    if (NULL == ctx)
+    {
+        CC_PalAbort("ctx cannot be NULL");
+    }
+
+    CC_PalMemSetZero(ctx, sizeof(mbedtls_dhm_context));
+
+}
+
+/*
+ * Parse the ServerKeyExchange parameters
+ */
+int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx,
+                     unsigned char **p,
+                     const unsigned char *end )
+{
+    int ret;
+    if ( (ctx == NULL) ||
+         (p == NULL) ||
+         (end == NULL) ) {
+        return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
+    }
+    if (*p == NULL) {
+        return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
+    }
+
+    if( ( ret = dhm_read_bignum( &ctx->P,  p, end ) ) != 0 ||
+        ( ret = dhm_read_bignum( &ctx->G,  p, end ) ) != 0 ||
+        ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 ){
+        return( ret );
+    }
+
+    if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ){
+        return( ret );
+    }
+
+    ctx->len = mbedtls_mpi_size( &ctx->P );
+
+    return( 0 );
+}
+
+/*
+ * Setup and write the ServerKeyExchange parameters
+ */
+int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret, count = 0;
+    size_t n1, n2, n3;
+    unsigned char *p;
+
+    if ( (ctx == NULL) || (output == NULL) || (olen == NULL) ||
+         (f_rng == NULL) || (p_rng == NULL)) {
+        return MBEDTLS_ERR_DHM_BAD_INPUT_DATA ;
+    }
+    /*
+     * x size must be less or equal to size of P
+     */
+    if ((x_size > (int)mbedtls_mpi_size(&ctx->P)) || (x_size <= 0)){
+        return MBEDTLS_ERR_DHM_BAD_INPUT_DATA ;
+    }
+
+    if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ){
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+    }
+    /*
+     * Generate X as large as possible ( < P )
+     */
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED );
+    }
+    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
+
+    /*
+     * Calculate GX = G^X mod P
+     */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod_hw( &ctx->GX, &ctx->G, &ctx->X,
+                          &ctx->P , &ctx->RP ) );
+    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ){
+        return( ret );
+    }
+    /*
+     * export P, G, GX
+     */
+#define DHM_MPI_EXPORT(X,n)                     \
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \
+    *p++ = (unsigned char)( n >> 8 );           \
+    *p++ = (unsigned char)( n      ); p += n;
+
+    n1 = mbedtls_mpi_size( &ctx->P  );
+    n2 = mbedtls_mpi_size( &ctx->G  );
+    n3 = mbedtls_mpi_size( &ctx->GX );
+
+    p = output;
+    DHM_MPI_EXPORT( &ctx->P , n1 );
+    DHM_MPI_EXPORT( &ctx->G , n2 );
+    DHM_MPI_EXPORT( &ctx->GX, n3 );
+
+    *olen  = p - output;
+
+    ctx->len = n1;
+
+cleanup:
+
+    if( ret != 0 ){
+        return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret );
+    }
+    return( 0 );
+}
+
+/*
+ * Set prime modulus and generator
+ */
+int mbedtls_dhm_set_group( mbedtls_dhm_context *ctx,
+                           const mbedtls_mpi *P,
+                           const mbedtls_mpi *G )
+{
+    int ret;
+
+    if( ctx == NULL || P == NULL || G == NULL )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ||
+        ( ret = mbedtls_mpi_copy( &ctx->G, G ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_DHM_SET_GROUP_FAILED + ret );
+    }
+
+    ctx->len = mbedtls_mpi_size( &ctx->P );
+    return( 0 );
+}
+
+/*
+ * Import the peer's public value G^Y
+ */
+int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx,
+                     const unsigned char *input, size_t ilen )
+{
+    int ret;
+
+    if( ctx == NULL || input == NULL || ilen < 1 || ilen > ctx->len )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 )
+        return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Create own private value X and export G^X
+ */
+int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size,
+                     unsigned char *output, size_t olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret, count = 0;
+
+    if( ctx == NULL || output == NULL || f_rng == NULL || p_rng ==NULL || olen < ctx->len )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+    if( (x_size > (int)ctx->len ) || (x_size <= 0))
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    /*
+     * generate X and calculate GX = G^X mod P
+     */
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED );
+    }
+    while( dhm_check_range( &ctx->X, &ctx->P ) != 0 );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod_hw( &ctx->GX, &ctx->G, &ctx->X,
+                          &ctx->P , &ctx->RP ) );
+
+    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
+        return( ret );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) );
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Use the blinding method and optimisation suggested in section 10 of:
+ *  KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA,
+ *  DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer
+ *  Berlin Heidelberg, 1996. p. 104-113.
+ */
+static int dhm_update_blinding( mbedtls_dhm_context *ctx,
+                    int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret, count;
+
+    /*
+     * Don't use any blinding the first time a particular X is used,
+     * but remember it to use blinding next time.
+     */
+    if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) );
+
+        return( 0 );
+    }
+
+    /*
+     * Ok, we need blinding. Can we re-use existing values?
+     * If yes, just update them by squaring them.
+     */
+    if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) );
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) );
+
+        return( 0 );
+    }
+
+    /*
+     * We need to generate blinding values from scratch
+     */
+
+    /* Vi = random( 2, P-1 ) */
+    count = 0;
+    do
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ) );
+
+        while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 )
+            MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) );
+
+        if( count++ > 10 )
+            return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
+    }
+    while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 );
+
+    /* Vf = Vi^-X mod P */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod_hw( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) );
+
+cleanup:
+    return( ret );
+}
+
+/*
+ * Derive and export the shared secret (G^Y)^X mod P
+ */
+int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx,
+                     unsigned char *output, size_t output_size, size_t *olen,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    int ret;
+    mbedtls_mpi GYb;
+
+    if( ctx == NULL || output == NULL || olen == NULL || output_size < ctx->len )
+        return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA );
+
+    if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) {
+        return( ret );
+    }
+
+    mbedtls_mpi_init( &GYb );
+
+    /* Blind peer's value */
+    if( f_rng != NULL )
+    {
+        MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) );
+    }
+    else
+        MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) );
+
+    /* Do modular exponentiation */
+    MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod_hw( &ctx->K, &GYb, &ctx->X,
+                          &ctx->P, &ctx->RP ) );
+
+    /* Unblind secret value */
+    if( f_rng != NULL )
+    {
+       MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) );
+       MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) );
+    }
+
+    *olen = mbedtls_mpi_size( &ctx->K );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) );
+
+cleanup:
+    mbedtls_mpi_free( &GYb );
+    if( ret != 0 )
+        return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret );
+
+    return( 0 );
+}
+
+/*
+ * Free the components of a DHM key
+ */
+void mbedtls_dhm_free( mbedtls_dhm_context *ctx )
+{
+    if ( ctx != NULL) {
+        mbedtls_mpi_free( &ctx->pX); mbedtls_mpi_free( &ctx->Vf ); mbedtls_mpi_free( &ctx->Vi );
+        mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY );
+        mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); mbedtls_mpi_free( &ctx->G );
+        mbedtls_mpi_free( &ctx->P );
+
+        mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) );
+    }
+}
+
+#if defined(MBEDTLS_ASN1_PARSE_C)
+/*
+ * Parse DHM parameters
+ */
+int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin,
+                   size_t dhminlen )
+{
+    int ret;
+    size_t len;
+    unsigned char *p, *end;
+#if defined(MBEDTLS_PEM_PARSE_C)
+    mbedtls_pem_context pem;
+
+    mbedtls_pem_init( &pem );
+
+    if ((dhm == NULL) || (dhmin == NULL)){
+        return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
+    }
+    /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
+    if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' )
+        ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT;
+    else
+        ret = mbedtls_pem_read_buffer( &pem,
+                               "-----BEGIN DH PARAMETERS-----",
+                               "-----END DH PARAMETERS-----",
+                               dhmin, NULL, 0, &dhminlen );
+
+    if( ret == 0 )
+    {
+        /*
+         * Was PEM encoded
+         */
+        dhminlen = pem.buflen;
+    }
+    else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
+        goto exit;
+
+    p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin;
+#else
+    p = (unsigned char *) dhmin;
+#endif /* MBEDTLS_PEM_PARSE_C */
+    end = p + dhminlen;
+
+    /*
+     *  DHParams ::= SEQUENCE {
+     *      prime              INTEGER,  -- P
+     *      generator          INTEGER,  -- g
+     *      privateValueLength INTEGER OPTIONAL
+     *  }
+     */
+    if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
+            MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+        goto exit;
+    }
+
+    end = p + len;
+
+    if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P  ) ) != 0 ||
+        ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 )
+    {
+        ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+        goto exit;
+    }
+
+    if( p != end )
+    {
+        /* This might be the optional privateValueLength.
+         * If so, we can cleanly discard it */
+        mbedtls_mpi rec;
+        mbedtls_mpi_init( &rec );
+        ret = mbedtls_asn1_get_mpi( &p, end, &rec );
+        mbedtls_mpi_free( &rec );
+        if ( ret != 0 )
+        {
+            ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret;
+            goto exit;
+        }
+        if ( p != end )
+        {
+            ret = MBEDTLS_ERR_DHM_INVALID_FORMAT +
+                MBEDTLS_ERR_ASN1_LENGTH_MISMATCH;
+            goto exit;
+        }
+    }
+
+    ret = 0;
+
+    dhm->len = mbedtls_mpi_size( &dhm->P );
+
+exit:
+#if defined(MBEDTLS_PEM_PARSE_C)
+    mbedtls_pem_free( &pem );
+#endif
+    if( ret != 0 )
+        mbedtls_dhm_free( dhm );
+
+    return( ret );
+}
+
+#if defined(MBEDTLS_FS_IO)
+/*
+ * Load all data from a file into a given buffer.
+ *
+ * The file is expected to contain either PEM or DER encoded data.
+ * A terminating null byte is always appended. It is included in the announced
+ * length only if the data looks like it is PEM encoded.
+ */
+static int load_file( const char *path, unsigned char **buf, size_t *n )
+{
+    FILE *f;
+    long size;
+
+    if( ( f = fopen( path, "rb" ) ) == NULL )
+        return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
+
+    fseek( f, 0, SEEK_END );
+    if( ( size = ftell( f ) ) == -1 )
+    {
+        fclose( f );
+        return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
+    }
+    fseek( f, 0, SEEK_SET );
+
+    *n = (size_t) size;
+
+    if( *n + 1 == 0 ||
+        ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL )
+    {
+        fclose( f );
+        return( MBEDTLS_ERR_DHM_ALLOC_FAILED );
+    }
+
+    if( fread( *buf, 1, *n, f ) != *n )
+    {
+        fclose( f );
+        mbedtls_free( *buf );
+        return( MBEDTLS_ERR_DHM_FILE_IO_ERROR );
+    }
+
+    fclose( f );
+
+    (*buf)[*n] = '\0';
+
+    if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL )
+        ++*n;
+
+    return( 0 );
+}
+
+/*
+ * Load and parse DHM parameters
+ */
+int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path )
+{
+    int ret;
+    size_t n;
+    unsigned char *buf;
+
+    if ( (dhm == NULL) || (path == NULL) ){
+        return MBEDTLS_ERR_DHM_BAD_INPUT_DATA;
+    }
+
+    if( ( ret = load_file( path, &buf, &n ) ) != 0 ){
+        return( ret );
+    }
+
+    ret = mbedtls_dhm_parse_dhm( dhm, buf, n );
+
+    mbedtls_zeroize( buf, n );
+    mbedtls_free( buf );
+
+    return( ret );
+}
+#endif /* MBEDTLS_FS_IO */
+#endif /* MBEDTLS_ASN1_PARSE_C */
+
+#endif /* MBEDTLS_DHM_ALT */
+#endif /* MBEDTLS_DHM_C */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdh_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdh_alt.c
new file mode 100644
index 0000000..e12ee1b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdh_alt.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#include "mbedtls/ecdh.h"
+
+#include "cc_ecc_internal.h"
+
+
+
+const mbedtls_ecp_curve_info curve_25519_data = { MBEDTLS_ECP_DP_CURVE25519,   29,     255,     "curve25519"};
+
+#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
+/*
+ * Generate key pair, wrapper for conventional base point
+ */
+int cc_ecp_gen_keypair( mbedtls_ecp_group *grp,
+                             mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng )
+{
+    return( cc_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) );
+}
+
+/*
+ * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair
+ */
+int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                     int (*f_rng)(void *, unsigned char *, size_t),
+                     void *p_rng )
+{
+    return cc_ecp_gen_keypair( grp, d, Q, f_rng, p_rng );
+}
+#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT */
+
+#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
+/*
+ * Compute shared secret (SEC1 3.3.1)
+ */
+int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z,
+                         const mbedtls_ecp_point *Q, const mbedtls_mpi *d,
+                         int (*f_rng)(void *, unsigned char *, size_t),
+                         void *p_rng )
+{
+    int ret;
+    mbedtls_ecp_point P;
+
+    mbedtls_ecp_point_init( &P );
+
+    if ( z == NULL || Q == NULL || grp == NULL || d == NULL)
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+    /*
+     * Make sure Q is a valid pubkey before using it
+     */
+    MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) );
+
+    MBEDTLS_MPI_CHK( cc_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) );
+
+    if( mbedtls_ecp_is_zero( &P ) )
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        goto cleanup;
+    }
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) );
+
+cleanup:
+    mbedtls_ecp_point_free( &P );
+
+    return( ret );
+}
+#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
+
+/*
+ * Write the ECParameters record corresponding to a group (RFC 4492)
+ */
+static int mbedtls_ecp_tls_write_group_edwards( const mbedtls_ecp_group *grp, size_t *olen,
+                         unsigned char *buf, size_t blen )
+{
+    const mbedtls_ecp_curve_info *curve_info = &curve_25519_data;
+
+    if (grp->id != MBEDTLS_ECP_DP_CURVE25519){
+            return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+    /*
+     * We are going to write 3 bytes (see below)
+     */
+    *olen = 3;
+    if( blen < *olen )
+        return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
+
+    /*
+     * First byte is curve_type, always named_curve
+     */
+    *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE;
+
+    /*
+     * Next two bytes are the namedcurve value
+     */
+    buf[0] = curve_info->tls_id >> 8;
+    buf[1] = curve_info->tls_id & 0xFF;
+
+    return( 0 );
+}
+
+/*
+ * Setup and write the ServerKeyExhange parameters (RFC 4492)
+ *      struct {
+ *          ECParameters    curve_params;
+ *          ECPoint         public;
+ *      } ServerECDHParams;
+ */
+int mbedtls_ecdh_make_params_edwards( mbedtls_ecdh_context *ctx, size_t *olen,
+                      unsigned char *buf, size_t blen,
+                      int (*f_rng)(void *, unsigned char *, size_t),
+                      void *p_rng )
+{
+    int ret;
+    size_t grp_len, pt_len;
+
+    if( ctx == NULL || ctx->grp.pbits == 0 ||
+            olen == NULL || buf == NULL ||
+            blen <= 0 || (ctx->grp.id != MBEDTLS_ECP_DP_CURVE25519) ){
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+
+    if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) )
+                != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_ecp_tls_write_group_edwards( &ctx->grp, &grp_len, buf, blen ) )
+                != 0 )
+        return( ret );
+
+    buf += grp_len;
+    blen -= grp_len;
+
+    if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format,
+                                     &pt_len, buf, blen ) ) != 0 )
+        return( ret );
+
+    *olen = grp_len + pt_len;
+    return( 0 );
+}
+
+/*
+ * Set a group from an ECParameters record (RFC 4492)
+ */
+static int mbedtls_ecp_tls_read_group_edwards( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len )
+{
+    uint16_t tls_id;
+    const mbedtls_ecp_curve_info *curve_info = &curve_25519_data;
+
+    /*
+     * We expect at least three bytes (see below)
+     */
+    if( len < 3 )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * First byte is curve_type; only named_curve is handled
+     */
+    if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE )
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    /*
+     * Next two bytes are the namedcurve value
+     */
+    tls_id = *(*buf)++;
+    tls_id <<= 8;
+    tls_id |= *(*buf)++;
+
+    if (curve_info->tls_id != tls_id){
+            return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+    return mbedtls_ecp_group_load( grp, curve_info->grp_id );
+}
+
+/*
+ * Read the ServerKeyExhange parameters (RFC 4492)
+ *      struct {
+ *          ECParameters    curve_params;
+ *          ECPoint         public;
+ *      } ServerECDHParams;
+ */
+int mbedtls_ecdh_read_params_edwards( mbedtls_ecdh_context *ctx,
+                      const unsigned char **buf, const unsigned char *end )
+{
+    int ret;
+
+    if( ctx == NULL || buf == NULL || end == NULL){
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+    }
+    if( ( ret = mbedtls_ecp_tls_read_group_edwards( &ctx->grp, buf, end - *buf ) ) != 0 )
+        return( ret );
+
+    if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) )
+                != 0 ){
+            return( ret );
+    }
+
+    return( 0 );
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdsa_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdsa_alt.c
new file mode 100644
index 0000000..da0c770
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdsa_alt.c
@@ -0,0 +1,386 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * References:
+ *
+ * SEC1 http://www.secg.org/index.php?action=secg,docs_secg
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+
+#include "mbedtls/ecdsa.h"
+#include "mbedtls/asn1write.h"
+
+#include "cc_ecc_internal.h"
+
+
+#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_BP256R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_BP384R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_BP512R1_ENABLED)   ||   \
+    defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) ||   \
+    defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
+#define ECP_SHORTWEIERSTRASS
+#endif
+
+#include "mbedtls_common.h"
+#include "ecp_common.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_common.h"
+#include "cc_ecpki_error.h"
+
+#if defined (ECP_SHORTWEIERSTRASS)
+
+#include "cc_ecpki_ecdsa.h"
+#include "cc_ecpki_build.h"
+
+#endif
+#include "cc_ecpki_domain.h"
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#define mbedtls_printf     printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#if defined(MBEDTLS_ECDSA_VERIFY_ALT) || defined (MBEDTLS_ECDSA_SIGN_ALT)
+static CCEcpkiHashOpMode_t message_size_to_hash_mode( size_t bytelen )
+{
+    CCEcpkiHashOpMode_t hash_mode;
+    size_t wordlen = (bytelen / sizeof(uint32_t));
+
+    switch( wordlen )
+    {
+        case CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS:
+            hash_mode = CC_ECPKI_AFTER_HASH_SHA1_mode;
+            break;
+        case CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS:
+            hash_mode = CC_ECPKI_AFTER_HASH_SHA224_mode;
+            break;
+        case CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS:
+            hash_mode = CC_ECPKI_AFTER_HASH_SHA256_mode;
+            break;
+        case CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS:
+            hash_mode = CC_ECPKI_AFTER_HASH_SHA384_mode;
+            break;
+        case CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS:
+            hash_mode = CC_ECPKI_AFTER_HASH_SHA512_mode;
+            break;
+        default:
+            hash_mode = CC_ECPKI_AFTER_HASH_SHA512_mode;//use default value, to avoid checking the hash
+    }
+
+    return hash_mode;
+}
+#endif
+
+#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+#if defined(ECP_SHORTWEIERSTRASS)
+
+static int ecdsa_wrst_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    int ret;
+    CCEcpkiDomainID_t domainId;
+    CCEcdsaSignUserContext_t* temp_context;
+    CCRndContext_t      rnd_ctx;
+    uint8_t temp_buf[ (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*sizeof(uint32_t) ] = {0};
+    CCEcpkiUserPrivKey_t* priv_key;
+    const CCEcpkiDomain_t*  pDomain;
+    CCEcpkiHashOpMode_t hash_mode;
+    size_t signature_size;
+    uint8_t * pSignature;
+    size_t key_size, order_size;
+    uint32_t status;
+
+    ret = ecp_grp_id_to_domain_id( grp->id, &domainId );
+    if (ret != 0)
+    {
+        return ret;
+    }
+    pDomain =  CC_EcpkiGetEcDomain( domainId );
+
+    if (NULL == pDomain)
+    {
+        CC_PAL_LOG_ERR( "Error - domain id: %d is not supported\n",domainId );
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+    rnd_ctx.rndGenerateVectFunc = f_rng;
+    rnd_ctx.rndState = p_rng;
+
+    order_size = CALC_FULL_BYTES ( grp->nbits );
+    signature_size =  order_size*2;
+
+    temp_context = (CCEcdsaSignUserContext_t *)mbedtls_calloc( 1, sizeof( CCEcdsaSignUserContext_t ) + signature_size + sizeof( CCEcpkiUserPrivKey_t ) );
+    if ( temp_context == NULL )
+    {
+        CC_PAL_LOG_ERR( "Error - failed to alloc memory for the temp context\n" );
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    mbedtls_zeroize_internal( temp_context, signature_size + sizeof( CCEcdsaSignUserContext_t ) + sizeof( CCEcpkiUserPrivKey_t ) );
+
+    key_size = mbedtls_mpi_size( d );
+
+    hash_mode = message_size_to_hash_mode( blen );
+
+    priv_key = (CCEcpkiUserPrivKey_t *)(temp_context + 1);
+
+    pSignature = (uint8_t *)(priv_key + 1);
+
+    ret = mbedtls_mpi_write_binary( d, temp_buf, key_size );
+
+    if (ret !=0 )
+    {
+        CC_PAL_LOG_ERR( "Error - failed to convert d to binary\n" );
+        goto end;
+    }
+    status = CC_EcpkiPrivKeyBuild( pDomain,
+                             temp_buf,
+                             mbedtls_mpi_size( d ),
+                             priv_key );
+    if ( status != CC_OK )
+    {
+        CC_PAL_LOG_ERR( "Error - failed to build private key, return code is: %d\n", status );
+        ret = error_mapping_cc_to_mbedtls_ecc( status );
+         goto end;
+    }
+
+    status =  CC_EcdsaSign( &rnd_ctx,
+                         temp_context,
+                         priv_key,
+                         hash_mode,
+                         (uint8_t*)buf,
+                         blen,
+                         pSignature,
+                         &signature_size );
+
+    if ( status != CC_OK )
+    {
+        CC_PAL_LOG_ERR( "Error - signing failed, return code is: %d\n", status );
+        ret = error_mapping_cc_to_mbedtls_ecc( status );
+        goto end;
+    }
+
+    ret = mbedtls_mpi_read_binary( r, pSignature, order_size );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR( "Error - failed to convert r\n" );
+        goto end;
+    }
+    ret = mbedtls_mpi_read_binary( s, pSignature + order_size , order_size );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR( "Error - failed to convert s\n" );
+        goto end;
+    }
+
+end:
+
+       mbedtls_zeroize_internal( temp_context, signature_size + sizeof( CCEcdsaSignUserContext_t ) + sizeof( CCEcpkiUserPrivKey_t ) );
+       mbedtls_free( temp_context );
+
+       return ret;
+}
+
+#endif /*(ECP_SHORTWEIERSTRASS)*/
+
+/*
+ * Compute ECDSA signature of a hashed message (SEC1 4.1.3)
+ * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message)
+ * The only exception is for curve 25519-Edwareds where we do hash
+ */
+int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                const mbedtls_mpi *d, const unsigned char *buf, size_t blen,
+                int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+
+    /* Input parameters validation */
+    if (NULL == grp || NULL == r || NULL == s || NULL == d || NULL == buf)
+    {
+        CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    }
+
+#if defined(ECP_SHORTWEIERSTRASS)
+
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+    {
+        if(NULL == f_rng || NULL == p_rng)
+        {
+            CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
+            return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+        }
+        return ecdsa_wrst_sign(grp, r, s, d, buf, blen, f_rng, p_rng);
+    }
+#endif /* ECP_SHORTWEIERSTRASS */
+    return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+}
+#endif /* MBEDTLS_ECDSA_SIGN_ALT */
+
+#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
+#if defined(ECP_SHORTWEIERSTRASS)
+
+static int ecdsa_wrst_verify( mbedtls_ecp_group *grp,
+                  const unsigned char *buf, size_t blen,
+                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
+{
+    CCEcpkiHashOpMode_t hash_mode;
+    CCEcdsaVerifyUserContext_t* pTemp_context;
+    CCEcpkiUserPublKey_t* pPub_key;
+    size_t temp_size, order_size;
+    uint8_t pTemp_buf[ (2*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*sizeof(uint32_t) ] = {0};
+    uint8_t * pSignature;
+    CCEcpkiDomainID_t domainId;
+    const CCEcpkiDomain_t*  pDomain;
+    int ret;
+    CCError_t status;
+    uint32_t signature_size;
+
+    order_size = CALC_FULL_BYTES ( grp->nbits );
+    signature_size = order_size *2;
+
+
+    hash_mode = message_size_to_hash_mode( blen );
+
+    ret = ecp_grp_id_to_domain_id( grp->id, &domainId );
+    if (ret != 0)
+    {
+        return ret;
+    }
+    pDomain =  CC_EcpkiGetEcDomain(domainId);
+
+    if (NULL == pDomain)
+    {
+        CC_PAL_LOG_ERR("Error - domain id %d is not supported\n",domainId);
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+
+    ret = mbedtls_ecp_point_write_binary( grp, Q, MBEDTLS_ECP_PF_UNCOMPRESSED,
+                                           &temp_size, pTemp_buf, sizeof(pTemp_buf) );
+
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - converting Q\n");
+        return ret;
+    }
+
+    pPub_key = (CCEcpkiUserPublKey_t*)mbedtls_calloc( 1, sizeof(CCEcpkiUserPublKey_t) + sizeof(CCEcdsaVerifyUserContext_t) + signature_size );
+    if ( pPub_key == NULL )
+    {
+        CC_PAL_LOG_ERR("Error - cant allocate memory for pPub_key\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    pTemp_context = (CCEcdsaVerifyUserContext_t*)(pPub_key + 1);
+    pSignature = (uint8_t *)(pTemp_context + 1);
+
+    status = CC_EcpkiPubKeyBuild(pDomain, pTemp_buf, temp_size, pPub_key);
+    if (status != CC_OK)
+    {
+        ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+        CC_PAL_LOG_ERR("Error - building public key failed with return code 0x%08x\n", status);
+        goto end;
+    }
+
+    ret = mbedtls_mpi_write_binary( r, pSignature, order_size );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR("Error - converting r\n");
+        goto end;
+    }
+
+    ret = mbedtls_mpi_write_binary( s, pSignature + order_size, order_size );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR("Error - converting s\n");
+        goto end;
+    }
+
+
+    status =  CC_EcdsaVerify ( pTemp_context,
+                               pPub_key,
+                               hash_mode,
+                               pSignature,
+                               signature_size,
+                               (uint8_t*)buf,
+                               blen );
+
+    if ( status != CC_OK )
+    {
+        ret = error_mapping_cc_to_mbedtls_ecc(status);
+        CC_PAL_LOG_ERR("Error - verification failed with return code 0x%08x\n", status);
+    }
+
+end:
+    mbedtls_zeroize_internal(pPub_key, sizeof(CCEcpkiUserPublKey_t) + sizeof(CCEcdsaVerifyUserContext_t) + signature_size);
+    mbedtls_free( pPub_key );
+    return ret;
+}
+#endif /* ECP_SHORTWEIERSTRASS */
+
+
+
+/*
+ * Verify ECDSA signature of hashed message (SEC1 4.1.4)
+ * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message)
+ * The only exception is for curve 25519-Edwareds where we do hash
+ */
+int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp,
+                  const unsigned char *buf, size_t blen,
+                  const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
+{
+        /* Input parameters validation */
+    if (NULL == grp || NULL == r || NULL == s || NULL == Q || buf == NULL)
+    {
+        CC_PAL_LOG_ERR("Error - NULL pointer exception\n");
+        return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+
+    }
+
+#if defined(ECP_SHORTWEIERSTRASS)
+
+    if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
+    {
+        return ecdsa_wrst_verify(grp, buf, blen, Q, r, s);
+    }
+#endif /* ECP_SHORTWEIERSTRASS */
+    return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
+}
+#endif /* MBEDTLS_ECDSA_VERIFY_ALT */
+
+#if defined(MBEDTLS_ECDSA_GENKEY_ALT)
+/*
+ * Generate key pair
+ */
+int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
+                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    return( mbedtls_ecp_group_load( &ctx->grp, gid ) ||
+            cc_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) );
+}
+#endif /* MBEDTLS_ECDSA_GENKEY_ALT */
+
+#endif /* defined(MBEDTLS_ECDSA_C) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdsa_edwards.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdsa_edwards.c
new file mode 100644
index 0000000..039b37e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecdsa_edwards.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_ECDSA_C)
+
+#include "mbedtls/ecdsa.h"
+#include "cc_ecc_internal.h"
+#include "mbedtls_common.h"
+#include "ecp_common.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_common.h"
+#include "cc_ecpki_error.h"
+#include "ec_edw.h"
+
+#include "cc_ec_edw_api.h"
+#include "ec_edw_local.h"
+#include "cc_ecpki_domain.h"
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#define mbedtls_printf     printf
+#define mbedtls_calloc    calloc
+#define mbedtls_free       free
+#endif
+
+#ifdef MBEDTLS_ECP_DP_CURVE25519_ENABLED
+
+static int ecdsa_export_mpi_to_buff(const mbedtls_mpi *mpi, size_t *outBuffSize, unsigned char *buf, size_t buffSize)
+{
+    int ret;
+    uint32_t i = 0;
+    uint32_t actSize;
+    uint32_t zeroFill;
+
+    actSize = mbedtls_mpi_size(mpi);
+    zeroFill = buffSize - actSize;
+    i = 0;
+    while (zeroFill) {
+        buf[i] = 0;
+        zeroFill--;
+        i++;
+    }
+    ret = mbedtls_mpi_write_binary(mpi, &buf[i], actSize);
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed mbedtls_mpi_write_binary 0x%x\n", ret);
+        return ret;
+    }
+    *outBuffSize = buffSize;
+    return CC_OK;
+
+}
+
+/*
+ * Generate key pair for Edwards ed25519 curve
+ */
+int mbedtls_ecdsa_genkey_edwards( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid,
+                                  int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
+{
+    mbedtls_ecp_group *grp;
+    mbedtls_mpi *d;
+    mbedtls_ecp_point *Q;
+    int ret = 0;
+    CCError_t rc = 0;
+    const CCEcEdwDomain_t *pDomain;
+    uint32_t    *pFuncTemp;
+    uint32_t    ecEdwOrderSizeBytes;
+    uint8_t     *pPrivKey;  // size is 2*ecEdwOrderSizeBytes
+    uint32_t    privKeySizeBytes;
+    uint8_t     *pPublicKey;  // size is ecEdwOrderSizeBytes
+    uint32_t    pubKeySizeBytes;
+    CCEcEdwTempBuff_t     *pTempBuff = NULL; // size is 3*ecEdwOrderSizeBytes
+    uint8_t *pSeed;
+
+    /* Verify inputs */
+    if ((ctx == NULL ) ||
+            (f_rng == NULL) ||
+            (p_rng == NULL) ||
+            (gid != MBEDTLS_ECP_DP_CURVE25519 ))
+    {
+        CC_PAL_LOG_ERR("Failed check params");
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    grp = &ctx->grp;
+    d = &ctx->d;
+    Q = &ctx->Q;
+
+    pDomain = EcEdwGetDomain25519();
+    if (NULL == pDomain)
+    {
+        CC_PAL_LOG_ERR("Failed invalid domain");
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+    ecEdwOrderSizeBytes = CALC_FULL_BYTES(pDomain->ecOrdSizeInBits);
+    privKeySizeBytes = 2*ecEdwOrderSizeBytes;
+    pubKeySizeBytes = CALC_FULL_BYTES(pDomain->ecModSizeInBits);
+    pTempBuff = mbedtls_calloc(1, ((ecEdwOrderSizeBytes + sizeof(CCEcEdwTempBuff_t) + privKeySizeBytes + pubKeySizeBytes)));
+    if (NULL == pTempBuff)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for temporary buffer\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+
+    pSeed = (uint8_t*)pTempBuff;
+    pFuncTemp = (uint32_t*)pTempBuff + CALC_32BIT_WORDS_FROM_BYTES(ecEdwOrderSizeBytes);
+    pPrivKey =  (uint8_t*)pFuncTemp + sizeof( CCEcEdwTempBuff_t );
+    pPublicKey = pPrivKey + privKeySizeBytes;
+
+    /* generate random seed */
+    rc = f_rng((void *)p_rng, (unsigned char *)pSeed, (size_t)ecEdwOrderSizeBytes);
+    if (rc) {
+        ret = error_mapping_cc_to_mbedtls_ecc(rc);
+        CC_PAL_LOG_ERR("Failed to generate random seed");
+        goto END;
+    }
+
+    /* generate key pair */
+    rc = EcEdwSeedKeyPair(pPublicKey, pPrivKey,
+                          pSeed, pDomain,
+                          (uint32_t*)pFuncTemp);
+    if (rc != CC_SUCCESS)
+    {
+        CC_PAL_LOG_ERR("Error - Key generation ended with result: 0x%x\n", rc);
+        ret =  error_mapping_cc_to_mbedtls_ecc(rc);
+        goto END;
+    }
+     ret = mbedtls_mpi_read_binary(&Q->Y, pPublicKey, CALC_FULL_BYTES(pDomain->ecModSizeInBits));
+    if (ret != 0)
+    {
+         CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
+        goto END;
+    }
+    Q->Y.s = 1; /*unsigned*/
+
+    ret = mbedtls_mpi_read_binary(d, pPrivKey, CALC_FULL_BYTES(2*pDomain->ecModSizeInBits));
+    if (ret != 0)
+    {
+         CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
+        goto END;
+    }
+    d->s = 1; /*unsigned*/
+
+
+    /* Set the group curve order used by sign & verify functions */
+    grp->nbits = pDomain->ecModSizeInBits;  // 253
+    ret = (0);
+    goto SUCCESS;
+
+    END:
+
+    mbedtls_ecp_point_free(Q);
+    mbedtls_mpi_free(d);
+    SUCCESS:
+    mbedtls_zeroize_internal(pTempBuff, (ecEdwOrderSizeBytes + sizeof(CCEcEdwTempBuff_t) + privKeySizeBytes + pubKeySizeBytes));
+    mbedtls_free(pTempBuff);
+    return ret;
+
+}
+
+
+int mbedtls_ecdsa_sign_edwards( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s,
+                                const mbedtls_mpi *d, const unsigned char *buf, size_t blen)
+{
+    int ret;
+    CCEcEdwTempBuff_t *cc_temp_buff;
+    uint8_t temp_buf[ (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*sizeof(uint32_t) ] = {0};
+    const CCEcEdwDomain_t*  pDomain;
+    size_t signature_size;
+    uint8_t * pSignature;
+    size_t key_size, order_size;
+    uint32_t status;
+
+    CC_UNUSED_PARAM(grp);
+    /* Verify inputs */
+    if ((r == NULL) ||
+        (s == NULL) ||
+        (d == NULL) ||
+        ((buf == NULL) ^ (blen == 0)))
+    {
+        CC_PAL_LOG_ERR("Failed check params");
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    pDomain =  EcEdwGetDomain25519();
+    if (NULL == pDomain)
+    {
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+    order_size = CALC_FULL_BYTES (pDomain->ecModSizeInBits);
+    signature_size = order_size * 2 ;
+
+    cc_temp_buff = (CCEcEdwTempBuff_t *)mbedtls_calloc(1, sizeof(CCEcEdwTempBuff_t) + signature_size );
+    if ( cc_temp_buff == NULL )
+    {
+        CC_PAL_LOG_ERR("Error - failed to alloc memory for the cc_temp_buff\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+    mbedtls_zeroize_internal(cc_temp_buff, signature_size + sizeof(CCEcEdwTempBuff_t));
+
+    pSignature = (uint8_t *)(cc_temp_buff + 1);
+
+    ret = ecdsa_export_mpi_to_buff(d, &key_size, temp_buf, order_size * 2);
+
+    if (ret !=0 )
+    {
+        CC_PAL_LOG_ERR("Error - failed to convert d to binary\n");
+        goto end;
+    }
+
+    status = CC_EcEdwSign(pSignature,
+                          &signature_size,
+                          (uint8_t*)buf,
+                          blen,
+                          temp_buf,
+                          key_size,
+                          cc_temp_buff);
+    if (( status != CC_OK ) ||
+            (signature_size != order_size * 2))
+    {
+        CC_PAL_LOG_ERR("Error - Edwards signing failed, return code is: %d\n", status);
+        ret = error_mapping_cc_to_mbedtls_ecc(status);
+        goto end;
+    }
+
+    ret = mbedtls_mpi_read_binary( r, pSignature, order_size );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR("Error - failed to convert r\n");
+        goto end;
+    }
+
+    ret = mbedtls_mpi_read_binary( s, pSignature + order_size, order_size );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR("Error - failed to convert s\n");
+        goto end;
+    }
+
+    end:
+
+    mbedtls_zeroize_internal(cc_temp_buff, signature_size + sizeof(CCEcEdwTempBuff_t) );
+    mbedtls_free( cc_temp_buff );
+
+    return ret;
+}
+
+
+int mbedtls_ecdsa_verify_edwards(mbedtls_ecp_group *grp, const unsigned char *buf, size_t blen,
+                                 const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s)
+{
+    const CCEcEdwDomain_t*  pDomain;
+    CCEcEdwTempBuff_t* p_cc_temp_buf;
+    size_t pub_key_size;
+    uint8_t pub_key_buf[ (2*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+1)*CC_32BIT_WORD_SIZE ] = {0};
+    uint8_t * p_signature;
+    int ret;
+    CCError_t status;
+
+    size_t order_size = 0;
+    size_t tmp_size = 0;
+    uint32_t signature_size = 0 ;
+
+    CC_UNUSED_PARAM(grp);
+
+    /* Verify inputs */
+    if (((buf == NULL) ^ (blen == 0)) ||
+            (Q == NULL) ||
+            (r == NULL) ||
+            (s == NULL))
+    {
+        CC_PAL_LOG_ERR("Failed check params");
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    pDomain =  EcEdwGetDomain25519();
+    if (NULL == pDomain)
+    {
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+    order_size = CALC_FULL_BYTES (pDomain->ecModSizeInBits);
+    signature_size = order_size*2 ;
+
+    /* Only the Y coordinate is required */
+    pub_key_size = order_size;
+    ret = ecdsa_export_mpi_to_buff( &Q->Y, &pub_key_size, pub_key_buf, order_size );
+    if ((ret != 0) ||
+        (pub_key_size != order_size))
+    {
+        CC_PAL_LOG_ERR("Error - converting Q\n");
+        return ret;
+    }
+
+    p_cc_temp_buf = (CCEcEdwTempBuff_t*)mbedtls_calloc( 1, sizeof(CCEcEdwTempBuff_t) + signature_size );
+    if ( p_cc_temp_buf == NULL )
+    {
+        CC_PAL_LOG_ERR("Error - cant allocate memory for CC temp buf\n");
+        return MBEDTLS_ERR_ECP_ALLOC_FAILED;
+    }
+
+    p_signature = (uint8_t *)(p_cc_temp_buf + 1);
+    tmp_size = order_size;
+
+    ret = ecdsa_export_mpi_to_buff( r, &tmp_size, p_signature, order_size );
+    if ((ret != 0) ||
+        (tmp_size != order_size))
+    {
+        CC_PAL_LOG_ERR("Error - converting r\n");
+        goto end;
+    }
+
+   ret = ecdsa_export_mpi_to_buff( s, &tmp_size, p_signature + order_size, order_size );
+    if ((ret != 0) ||
+        (tmp_size != order_size))
+    {
+        CC_PAL_LOG_ERR("Error - converting s\n");
+        goto end;
+    }
+
+
+    status =  CC_EcEdwVerify ( p_signature,
+                               signature_size,
+                               pub_key_buf,
+                               pub_key_size,
+                               (uint8_t*)buf,
+                               blen,
+                               p_cc_temp_buf);
+
+    if ( status != CC_OK )
+    {
+        ret = error_mapping_cc_to_mbedtls_ecc(status);
+        CC_PAL_LOG_ERR("Error - verification failed with return code 0x%08x\n", status);
+    }
+
+    end:
+    mbedtls_zeroize_internal(p_cc_temp_buf, sizeof(CCEcEdwTempBuff_t) + signature_size);
+    mbedtls_free( p_cc_temp_buf );
+    return ret;
+}
+
+
+int mbedtls_ecdsa_public_key_read_edwards( mbedtls_ecp_point *Q,
+                                           unsigned char *buf, size_t blen )
+{
+    const CCEcEdwDomain_t *pDomain;
+    int ret;
+
+    if ((Q == NULL) ||
+            (buf == NULL) ||
+            (blen == 0)) {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+    pDomain = EcEdwGetDomain25519();
+    if (NULL == pDomain) {
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+
+    if (blen != CALC_FULL_BYTES(pDomain->ecModSizeInBits)) {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+
+    ret = mbedtls_mpi_read_binary(&Q->Y, buf, blen);
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
+        return ret;
+    }
+    Q->Y.s = 1; /*unsigned*/
+
+    return CC_OK;
+
+}
+
+
+int mbedtls_ecdsa_public_key_write_edwards( const mbedtls_ecp_point *Q,
+                                            size_t *olen,
+                                            unsigned char *buf, size_t blen )
+{
+    int ret;
+    uint32_t keySize;
+    const CCEcEdwDomain_t *pDomain;
+
+    if ((Q == NULL) ||
+            (olen == NULL) ||
+            (buf == NULL) ||
+            (blen == 0)) {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+    pDomain = EcEdwGetDomain25519();
+    if (NULL == pDomain) {
+        return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+    keySize = CALC_FULL_BYTES(pDomain->ecModSizeInBits);
+    if (blen < keySize)
+    {
+        return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+    }
+    ret = ecdsa_export_mpi_to_buff(&Q->Y, olen, buf, keySize);
+    if (ret != 0)
+    {
+        CC_PAL_LOG_ERR("Error - failed to allocate memory for Q->Y\n");
+        return ret;
+    }
+
+    return CC_OK;
+}
+
+
+#endif  /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+#endif /* defined(MBEDTLS_ECDSA_C) */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecp_common.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecp_common.c
new file mode 100644
index 0000000..c64b9c3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecp_common.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include "cc_pal_log.h"
+#include "cc_ecpki_error.h"
+#include "mbedtls_cc_ec_mont_edw_error.h"
+#include "ecp.h"
+#include "ecp_common.h"
+#include "cc_bitops.h"
+
+int error_mapping_cc_to_mbedtls_ecc (CCError_t cc_error)
+{
+    int ret;
+    switch (cc_error)
+    {
+
+            case CC_ECPKI_ILLEGAL_DOMAIN_ID_ERROR:
+            case CC_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR:
+            case CC_ECPKI_BUILD_DOMAIN_ID_IS_NOT_VALID_ERROR:
+            case CC_ECDH_SVDP_DH_ILLEGAL_DOMAIN_ID_ERROR :
+            case CC_ECDSA_SIGN_INVALID_DOMAIN_ID_ERROR:
+            case CC_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR:
+            case CC_ECPKI_INVALID_DOMAIN_ID_ERROR:
+            case CC_EC_MONT_IS_NOT_SUPPORTED:
+            case CC_EC_EDW_IS_NOT_SUPPORTED:
+
+                ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+                break;
+
+            case CC_ECPKI_INTERNAL_ERROR:
+            case CC_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR:
+            case CC_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR:
+            case CC_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR:
+            case CC_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR:
+            case CC_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
+            case CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR:
+            case CC_ECPKI_INVALID_PRIV_KEY_TAG_ERROR:
+            case CC_ECPKI_INVALID_PUBL_KEY_TAG_ERROR:
+            case CC_ECIES_INVALID_PUBL_KEY_TAG_ERROR:
+            case CC_ECIES_INVALID_PRIV_KEY_TAG_ERROR:
+            case CC_ECIES_INVALID_PRIV_KEY_VALUE_ERROR:
+
+                ret = MBEDTLS_ERR_ECP_INVALID_KEY;
+                break;
+
+            case CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
+            case CC_EC_EDW_SIGN_VERIFY_FAILED_ERROR:
+                ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
+                break;
+
+            case CC_ECPKI_DOMAIN_PTR_ERROR:
+            case CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR:
+            case CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR:
+            case CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR:
+            case CC_ECPKI_RND_CONTEXT_PTR_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR:
+            case CC_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_VALIDATION_TAG_ERROR:
+            case CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR:
+            case CC_ECPKI_BUILD_DOMAIN_DOMAIN_PTR_ERROR:
+            case CC_ECPKI_BUILD_DOMAIN_EC_PARAMETR_PTR_ERROR:
+            case CC_ECPKI_BUILD_DOMAIN_EC_PARAMETR_SIZE_ERROR:
+            case CC_ECPKI_BUILD_DOMAIN_COFACTOR_PARAMS_ERROR:
+            case CC_ECPKI_BUILD_DOMAIN_SECURITY_STRENGTH_ERROR:
+            case CC_ECPKI_BUILD_SCA_RESIST_ILLEGAL_MODE_ERROR:
+            case CC_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR:
+            case CC_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR:
+            case CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR:
+            case CC_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR:
+            case CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR:
+            case CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR:
+            case CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR:
+            case CC_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR:
+            case CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR:
+            case CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
+            case CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
+            case CC_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR:
+            case CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR:
+            case CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR:
+            case CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR:
+            case CC_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR:
+            case CC_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR:
+            case CC_ECDSA_SIGN_INVALID_RND_FUNCTION_PTR_ERROR:
+            case CC_ECDSA_SIGN_SIGNING_ERROR:
+            case CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR:
+            case CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR:
+            case CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR:
+            case CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR:
+            case CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR:
+            case CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
+            case CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
+            case CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR:
+            case CC_ECC_ILLEGAL_HASH_MODE_ERROR:
+            case CC_ECPKI_INVALID_RND_FUNC_PTR_ERROR:
+            case CC_ECPKI_INVALID_RND_CTX_PTR_ERROR:
+            case CC_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR:
+            case CC_ECPKI_INVALID_BASE_POINT_PTR_ERROR:
+            case CC_ECIES_INVALID_PUBL_KEY_PTR_ERROR:
+            case CC_ECIES_INVALID_PRIV_KEY_PTR_ERROR:
+            case CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR:
+            case CC_ECIES_INVALID_KDF_HASH_MODE_ERROR:
+            case CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR:
+            case CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR:
+            case CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR:
+            case CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR:
+            case CC_ECIES_INVALID_CIPHER_DATA_SIZE_ERROR:
+            case CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR:
+            case CC_ECIES_INVALID_EPHEM_KEY_PAIR_PTR_ERROR:
+            case CC_EC_EDW_INVALID_INPUT_POINTER_ERROR:
+            case CC_EC_EDW_INVALID_INPUT_SIZE_ERROR:
+            case CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR:
+            case CC_EC_EDW_INVALID_SCALAR_DATA_ERROR:
+            case CC_EC_EDW_RND_CONTEXT_PTR_INVALID_ERROR:
+            case CC_EC_EDW_RND_GEN_VECTOR_FUNC_ERROR:
+            case CC_EC_MONT_INVALID_INPUT_POINTER_ERROR:
+            case CC_EC_MONT_INVALID_INPUT_SIZE_ERROR:
+            case CC_EC_MONT_INVALID_DOMAIN_ID_ERROR:
+            case CC_ECEDW_INTERNAL_ERROR:
+            case CC_ECMONT_INTERNAL_ERROR:
+
+                ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
+                break;
+
+            default:
+                ret = -1;
+                CC_PAL_LOG_ERR("Unknown CC_ERROR %d\n", cc_error);
+                break;
+    }
+    CC_PAL_LOG_INFO("Converted CC_ERROR %d to MBEDTLS_ERR %d\n", cc_error, ret);
+    return ret;
+}
+
+/* conversion from mbedtls group id (curve) to CC domain*/
+int ecp_grp_id_to_domain_id (const mbedtls_ecp_group_id id, CCEcpkiDomainID_t *domain_id)
+{
+    switch (id)
+    {
+        case MBEDTLS_ECP_DP_SECP192R1:
+            *domain_id = CC_ECPKI_DomainID_secp192r1;
+            break;                          /*!< 192-bits NIST curve  */
+        case MBEDTLS_ECP_DP_SECP224R1:      /*!< 224-bits NIST curve  */
+            *domain_id = CC_ECPKI_DomainID_secp224r1;
+            break;
+        case MBEDTLS_ECP_DP_SECP256R1:      /*!< 256-bits NIST curve  */
+            *domain_id = CC_ECPKI_DomainID_secp256r1;
+            break;
+        case MBEDTLS_ECP_DP_SECP384R1:      /*!< 384-bits NIST curve  */
+            *domain_id = CC_ECPKI_DomainID_secp384r1;
+            break;
+        case MBEDTLS_ECP_DP_SECP521R1:      /*!< 521-bits NIST curve  */
+            *domain_id = CC_ECPKI_DomainID_secp521r1;
+            break;
+        case MBEDTLS_ECP_DP_SECP192K1:      /*!< 192-bits "Koblitz" curve */
+            *domain_id = CC_ECPKI_DomainID_secp192k1;
+            break;
+        case MBEDTLS_ECP_DP_SECP224K1:      /*!< 224-bits "Koblitz" curve */
+            *domain_id = CC_ECPKI_DomainID_secp224k1;
+            break;
+        case MBEDTLS_ECP_DP_SECP256K1:      /*!< 256-bits "Koblitz" curve */
+            *domain_id = CC_ECPKI_DomainID_secp256k1;
+            break;
+
+        default:
+            CC_PAL_LOG_ERR("Error - ecp_grp_id_to_domain_id, group id %d is not supported\n", id);
+            *domain_id = CC_ECPKI_DomainIDLast;
+            return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+    }
+    return (0);
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecp_common.h b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecp_common.h
new file mode 100644
index 0000000..a232d53
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/ecp_common.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef ECP_COMMON_H
+#define ECP_COMMON_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "cc_pal_types_plat.h"
+#include "cc_ecpki_types.h"
+#include "mbedtls/ecp.h"
+
+/*
+ *\brief         Curve types
+ *
+ */
+typedef enum
+{
+    ECP_TYPE_NONE = 0,
+    ECP_TYPE_SHORT_WEIERSTRASS,    /* y^2 = x^3 + a x + b      */
+    ECP_TYPE_25519,         /* MONTGOMERY : y^2 = x^3 + a x^2 + x  EDWARDS: x^2 + y^2 = 1 + dx^2y^2 (modp) */
+} ecp_curve_type;
+
+/**
+ * \brief           mapping CC ECP return codes to mbedtls
+ *
+ */
+int error_mapping_cc_to_mbedtls_ecc (CCError_t cc_error);
+
+/**
+ * \brief           get the cfurve type
+ *
+ */
+static inline ecp_curve_type ecp_get_type(const mbedtls_ecp_group *grp)
+{
+    if (grp->G.X.p == NULL)
+        return (ECP_TYPE_NONE);
+
+    if (grp->G.Y.p == NULL)
+        return (ECP_TYPE_25519);
+    else
+        return (ECP_TYPE_SHORT_WEIERSTRASS);
+}
+
+/**
+ * \brief           map mbedtls group id to CC domain id
+ *
+ */
+
+int ecp_grp_id_to_domain_id (const mbedtls_ecp_group_id id, CCEcpkiDomainID_t *domain_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* MBEDTLS_COMMON_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/gcm_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/gcm_alt.c
new file mode 100644
index 0000000..59e340e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/gcm_alt.c
@@ -0,0 +1,621 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * Definition of GCM:
+ * http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf
+ * Recommendation for Block Cipher Modes of Operation:
+ * Galois/Counter Mode (GCM) and GMAC
+ *
+ * The API supports AES-GCM as defined in NIST SP 800-38D.
+ *
+ */
+#if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_GCM_C) && defined(MBEDTLS_GCM_ALT)
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_common.h"
+#include "aesgcm_driver.h"
+#include "mbedtls_common.h"
+#include "mbedtls/gcm.h"
+
+#define MBEDTLS_ERR_GCM_API_IS_NOT_SUPPORTED        -0x0016  /**< API is NOT supported. */
+
+/*! AES GCM data in maximal size in bytes. */
+#define MBEDTLS_AESGCM_DATA_IN_MAX_SIZE_BYTES       0xFFFF // (64KB - 1)
+/*! AES GCM IV maximal size in bytes. */
+#define MBEDTLS_AESGCM_IV_MAX_SIZE_BYTES            0xFFFF // (64KB - 1)
+/*! AES GCM AAD maximal size in bytes. */
+#define MBEDTLS_AESGCM_AAD_MAX_SIZE_BYTES           0xFFFF // (64KB - 1)
+
+/*! AES GCM 96 bits size IV. */
+#define MBEDTLS_AESGCM_IV_96_BITS_SIZE_BYTES        12
+
+/*! AES GCM Tag size: 4 bytes. */
+#define MBEDTLS_AESGCM_TAG_SIZE_4_BYTES             4
+/*! AES GCM Tag size: 8 bytes. */
+#define MBEDTLS_AESGCM_TAG_SIZE_8_BYTES             8
+/*! AES GCM Tag size: 12 bytes. */
+#define MBEDTLS_AESGCM_TAG_SIZE_12_BYTES            12
+/*! AES GCM Tag size: 13 bytes. */
+#define MBEDTLS_AESGCM_TAG_SIZE_13_BYTES            13
+/*! AES GCM Tag size: 14 bytes. */
+#define MBEDTLS_AESGCM_TAG_SIZE_14_BYTES            14
+/*! AES GCM Tag size: 15 bytes. */
+#define MBEDTLS_AESGCM_TAG_SIZE_15_BYTES            15
+/*! AES GCM Tag size: 16 bytes. */
+#define MBEDTLS_AESGCM_TAG_SIZE_16_BYTES            16
+
+/*
+ * Initialize a context
+ */
+void mbedtls_gcm_init(mbedtls_gcm_context *ctx)
+{
+    if (NULL == ctx) {
+        CC_PalAbort("!!!!GCM context is NULL!!!\n");
+    }
+
+    if (sizeof(mbedtls_gcm_context) < sizeof(AesGcmContext_t)) {
+        CC_PalAbort("!!!!GCM context sizes mismatch!!!\n");
+    }
+
+    mbedtls_zeroize_internal(ctx, sizeof(mbedtls_gcm_context));
+}
+
+int mbedtls_gcm_setkey(mbedtls_gcm_context *ctx,
+               mbedtls_cipher_id_t cipher,
+               const unsigned char *key,
+               unsigned int keybits)
+{
+    AesGcmContext_t *aes_gcm_ctx ;
+
+    if (ctx == NULL || key == NULL) {
+        CC_PAL_LOG_ERR("Null pointer, ctx or key are NULL\n");
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    if (cipher != MBEDTLS_CIPHER_ID_AES) {
+        /* No real use case for GCM other then AES*/
+        CC_PAL_LOG_ERR("Only AES cipher id is supported\n");
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    aes_gcm_ctx = (AesGcmContext_t *)ctx;
+    switch (keybits) {
+        case 128:
+            aes_gcm_ctx->keySizeId = KEY_SIZE_128_BIT;
+            break;
+        case 192:
+            aes_gcm_ctx->keySizeId = KEY_SIZE_192_BIT;
+            break;
+        case 256:
+            aes_gcm_ctx->keySizeId = KEY_SIZE_256_BIT;
+            break;
+        default:
+            return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Copy user key to context */
+    CC_PalMemCopy(aes_gcm_ctx->keyBuf, key, (keybits/8));
+
+    return(0);
+}
+
+/*
+ * Free context
+ */
+void mbedtls_gcm_free(mbedtls_gcm_context *ctx)
+{
+    mbedtls_zeroize_internal(ctx, sizeof(mbedtls_gcm_context));
+}
+
+static int gcm_calc_h(mbedtls_gcm_context *ctx)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    drvError_t rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* set pointer to user context */
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+
+    /* Set process mode to 'CalcH' */
+    pAesGcmCtx->processMode = DRV_AESGCM_Process_CalcH;
+
+    /* set data buffers structures */
+    rc = SetDataBuffersInfo((uint8_t*)(pAesGcmCtx->tempBuf), CC_AESGCM_GHASH_DIGEST_SIZE_BYTES, &inBuffInfo,
+                            (uint8_t*)(pAesGcmCtx->H), AES_128_BIT_KEY_SIZE, &outBuffInfo);
+    if (rc != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    /* Calculate H */
+    rc = ProcessAesGcm(pAesGcmCtx, &inBuffInfo, &outBuffInfo, CC_AES_BLOCK_SIZE_IN_BYTES);
+    if (rc != AES_DRV_OK) {
+        CC_PAL_LOG_ERR("calculating H failed with error code %d\n", rc);
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return (0);
+}
+
+static int gcm_init(mbedtls_gcm_context *ctx,
+                    cryptoDirection_t encryptDecryptFlag,
+            const uint8_t* pIv,
+            size_t ivSize,
+            const uint8_t* pAad,
+            size_t aadSize,
+            const uint8_t* pDataIn,
+            size_t dataSize,
+            uint8_t* pDataOut,
+            const uint8_t* pTag,
+            size_t tagSize)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    drvError_t rc;
+
+    /* Check the Encrypt / Decrypt flag validity */
+    if (CRYPTO_DIRECTION_NUM_OF_ENC_MODES <= encryptDecryptFlag) {
+        return  MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Check the data in size validity */
+    if (MBEDTLS_AESGCM_DATA_IN_MAX_SIZE_BYTES < dataSize) {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    if (0 != dataSize) {
+        /* Check dataIn pointer */
+        if (NULL == pDataIn) {
+            return MBEDTLS_ERR_GCM_BAD_INPUT;
+        }
+
+        /* Check dataOut pointer */
+        if (NULL == pDataOut) {
+            return MBEDTLS_ERR_GCM_BAD_INPUT;
+        }
+    }
+
+    /* Check the IV size validity */
+    if ((MBEDTLS_AESGCM_IV_MAX_SIZE_BYTES < ivSize) || (0 == ivSize)) {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Check iv pointer */
+    if (NULL == pIv) {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Check the AAD size validity */
+    if (MBEDTLS_AESGCM_AAD_MAX_SIZE_BYTES < aadSize) {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Check aad pointer */
+    if ((NULL == pAad) && (aadSize != 0)) {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Check the Tag size validity */
+    if ((MBEDTLS_AESGCM_TAG_SIZE_4_BYTES  != tagSize) && (MBEDTLS_AESGCM_TAG_SIZE_8_BYTES  != tagSize) &&
+        (MBEDTLS_AESGCM_TAG_SIZE_12_BYTES != tagSize) && (MBEDTLS_AESGCM_TAG_SIZE_13_BYTES != tagSize) &&
+        (MBEDTLS_AESGCM_TAG_SIZE_14_BYTES != tagSize) && (MBEDTLS_AESGCM_TAG_SIZE_15_BYTES != tagSize) &&
+        (MBEDTLS_AESGCM_TAG_SIZE_16_BYTES != tagSize)) {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Check Tag pointer */
+    if (NULL == pTag) {
+        return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* set pointer to user context */
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+
+    /* Set direction of operation: enc./dec. */
+    pAesGcmCtx->dir = MBEDTLS_2_DRIVER_DIRECTION(encryptDecryptFlag);
+    pAesGcmCtx->dataSize = dataSize;
+    pAesGcmCtx->ivSize = ivSize;
+    pAesGcmCtx->aadSize = aadSize;
+    pAesGcmCtx->tagSize = tagSize;
+
+    /******************************************************/
+    /***                Calculate H                     ***/
+    /******************************************************/
+    rc = gcm_calc_h(ctx);
+    if (rc != AES_DRV_OK) {
+        CC_PAL_LOG_ERR("calculating H failed with error code %d\n", rc);
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+static int gcm_process_j0(mbedtls_gcm_context *ctx, const uint8_t* pIv)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    drvError_t rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* set pointer to user context */
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+
+    if (MBEDTLS_AESGCM_IV_96_BITS_SIZE_BYTES == pAesGcmCtx->ivSize) {
+        // Concatenate IV||0(31)||1
+        CC_PalMemCopy(pAesGcmCtx->J0, pIv, MBEDTLS_AESGCM_IV_96_BITS_SIZE_BYTES);
+        pAesGcmCtx->J0[3] = SWAP_ENDIAN(0x00000001);
+    } else {
+
+        /***********************************************/
+        /* Calculate GHASH over the first phase buffer */
+        /***********************************************/
+        /* Set process mode to 'CalcJ0' */
+        pAesGcmCtx->processMode = DRV_AESGCM_Process_CalcJ0_FirstPhase;
+
+        /* set data buffers structures */
+        rc = SetDataBuffersInfo(pIv, pAesGcmCtx->ivSize, &inBuffInfo,
+                                NULL, 0, &outBuffInfo);
+        if (rc != 0) {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return MBEDTLS_ERR_GCM_AUTH_FAILED;
+        }
+
+        /* Calculate J0 - First phase */
+        rc = ProcessAesGcm(pAesGcmCtx, &inBuffInfo, &outBuffInfo, pAesGcmCtx->ivSize);
+        if (rc != AES_DRV_OK) {
+            CC_PAL_LOG_ERR("calculating J0 (phase 1) failed with error code 0x%X\n", rc);
+            return MBEDTLS_ERR_GCM_AUTH_FAILED;
+        }
+
+        /*********************************************/
+        /* Build & Calculate the second phase buffer */
+        /*********************************************/
+        CC_PalMemSetZero(pAesGcmCtx->tempBuf, sizeof(pAesGcmCtx->tempBuf));
+        pAesGcmCtx->tempBuf[3] = (pAesGcmCtx->ivSize << 3) & BITMASK(CC_BITS_IN_32BIT_WORD);
+        pAesGcmCtx->tempBuf[3] = SWAP_ENDIAN(pAesGcmCtx->tempBuf[3]);
+
+        /* Set process mode to 'CalcJ0' */
+        pAesGcmCtx->processMode = DRV_AESGCM_Process_CalcJ0_SecondPhase;
+
+        /* set data buffers structures */
+        rc = SetDataBuffersInfo((uint8_t*)(pAesGcmCtx->tempBuf), CC_AESGCM_GHASH_DIGEST_SIZE_BYTES, &inBuffInfo,
+                                NULL, 0, &outBuffInfo);
+        if (rc != 0) {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return MBEDTLS_ERR_GCM_AUTH_FAILED;
+        }
+
+        /* Calculate J0 - Second phase  */
+        rc = ProcessAesGcm(pAesGcmCtx, &inBuffInfo, &outBuffInfo, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+        if (rc != AES_DRV_OK) {
+            CC_PAL_LOG_ERR("calculating J0 (phase 2) failed with error code %d\n", rc);
+            return MBEDTLS_ERR_GCM_AUTH_FAILED;
+        }
+    }
+
+    return 0;
+}
+
+static int gcm_process_aad(mbedtls_gcm_context *ctx, const uint8_t* pAad)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    drvError_t rc = 0;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* set pointer to user context */
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+
+    /* Clear Ghash result buffer */
+    CC_PalMemSetZero(pAesGcmCtx->ghashResBuf, sizeof(pAesGcmCtx->ghashResBuf));
+
+    if (0 == pAesGcmCtx->aadSize) {
+        return rc;
+    }
+
+    /* Set process mode to 'Process_A' */
+    pAesGcmCtx->processMode = DRV_AESGCM_Process_A;
+
+    /* set data buffers structures */
+    rc = SetDataBuffersInfo(pAad, pAesGcmCtx->aadSize, &inBuffInfo,
+                            NULL, 0, &outBuffInfo);
+    if (rc != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    /* Calculate GHASH(A) */
+    rc = ProcessAesGcm(pAesGcmCtx, &inBuffInfo, &outBuffInfo, pAesGcmCtx->aadSize);
+    if (rc != AES_DRV_OK) {
+        CC_PAL_LOG_ERR("processing AAD failed with error code %d\n", rc);
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+static int gcm_process_cipher(mbedtls_gcm_context *ctx, const uint8_t* pTextDataIn, uint8_t* pTextDataOut)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    drvError_t rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* set pointer to user context */
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+
+    /* Must NOT perform in this case */
+    if (0 == pAesGcmCtx->dataSize) {
+        return 0;
+    }
+
+    /* Set process mode to 'Process_DataIn' */
+    pAesGcmCtx->processMode = DRV_AESGCM_Process_DataIn;
+
+    /* set data buffers structures */
+    rc = SetDataBuffersInfo(pTextDataIn, pAesGcmCtx->dataSize, &inBuffInfo,
+                            pTextDataOut, pAesGcmCtx->dataSize, &outBuffInfo);
+    if (rc != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    rc = ProcessAesGcm(pAesGcmCtx, &inBuffInfo, &outBuffInfo, pAesGcmCtx->dataSize);
+    if (rc != AES_DRV_OK) {
+        CC_PAL_LOG_ERR("processing cipher failed with error code %d\n", rc);
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+static int gcm_process_lenA_lenC(mbedtls_gcm_context *ctx)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    drvError_t rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* set pointer to user context */
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+
+    /* Build buffer */
+    pAesGcmCtx->tempBuf[1] = (pAesGcmCtx->aadSize << 3) & BITMASK(CC_BITS_IN_32BIT_WORD);
+    pAesGcmCtx->tempBuf[1] = SWAP_ENDIAN(pAesGcmCtx->tempBuf[1]);
+    pAesGcmCtx->tempBuf[0] = 0;
+    pAesGcmCtx->tempBuf[3] = (pAesGcmCtx->dataSize << 3) & BITMASK(CC_BITS_IN_32BIT_WORD);
+    pAesGcmCtx->tempBuf[3] = SWAP_ENDIAN(pAesGcmCtx->tempBuf[3]);
+    pAesGcmCtx->tempBuf[2] = 0;
+
+    /* Set process mode to 'Process_LenA_LenC' */
+    pAesGcmCtx->processMode = DRV_AESGCM_Process_LenA_LenC;
+
+   /* set data buffers structures */
+    rc = SetDataBuffersInfo((uint8_t*)(pAesGcmCtx->tempBuf), CC_AESGCM_GHASH_DIGEST_SIZE_BYTES, &inBuffInfo,
+                            NULL, 0, &outBuffInfo);
+    if (rc != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    /* Calculate GHASH(LenA || LenC) */
+    rc = ProcessAesGcm(pAesGcmCtx, &inBuffInfo, &outBuffInfo, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+    if (rc != AES_DRV_OK) {
+        CC_PAL_LOG_ERR("processing Lengths of AAD and Cipher failed with error code %d\n", rc);
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    return 0;
+}
+
+static int gcm_finish(mbedtls_gcm_context *ctx, uint8_t* pTag)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    int rc;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* set pointer to user context */
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+
+    /* Set process mode to 'Process_GctrFinal' */
+    pAesGcmCtx->processMode = DRV_AESGCM_Process_GctrFinal;
+
+    /* set data buffers structures */
+    rc = SetDataBuffersInfo((uint8_t*)(pAesGcmCtx->tempBuf), CC_AESGCM_GHASH_DIGEST_SIZE_BYTES, &inBuffInfo,
+                            pAesGcmCtx->preTagBuf, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES, &outBuffInfo);
+    if (rc != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    /* Calculate Encrypt and Calc. Tag */
+    rc = ProcessAesGcm(pAesGcmCtx, &inBuffInfo, &outBuffInfo, CC_AESGCM_GHASH_DIGEST_SIZE_BYTES);
+    if (rc != AES_DRV_OK) {
+        CC_PAL_LOG_ERR("Finish operation failed with error code %d\n", rc);
+        return MBEDTLS_ERR_GCM_AUTH_FAILED;
+    }
+
+    if (CRYPTO_DIRECTION_ENCRYPT == pAesGcmCtx->dir) {
+        CC_PalMemCopy(pTag, pAesGcmCtx->preTagBuf, pAesGcmCtx->tagSize);
+        rc = 0;
+    } else {
+        if (0 == CC_PalMemCmp(pAesGcmCtx->preTagBuf, pTag, pAesGcmCtx->tagSize)) {
+            rc = 0;
+        } else {
+            rc = MBEDTLS_ERR_GCM_AUTH_FAILED;
+           }
+    }
+
+    return rc;
+}
+
+static int gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                 int mode,
+                 size_t length,
+                 const unsigned char *iv,
+                 size_t iv_len,
+                 const unsigned char *aad,
+                 size_t aad_len,
+                 const unsigned char *input,
+                 unsigned char *output,
+                 size_t tag_len,
+                 unsigned char *tag)
+{
+    AesGcmContext_t *pAesGcmCtx = NULL;
+    int rc;
+
+    /* check for  user context */
+    if (NULL == ctx) {
+    return MBEDTLS_ERR_GCM_BAD_INPUT;
+    }
+
+    /* Aes-GCM Initialization function */
+    rc = gcm_init(ctx, (cryptoDirection_t)mode,
+          iv, iv_len,
+          aad, aad_len,
+          input, length, output,
+          tag, tag_len);
+
+    if (0 != rc) {
+    goto gcm_crypt_and_tag_END;
+    }
+
+    /* Aes-GCM Process J0 function */
+    rc = gcm_process_j0(ctx, iv);
+    if (0 != rc) {
+    goto gcm_crypt_and_tag_END;
+    }
+
+    /* Aes-GCM Process AAD function */
+    rc = gcm_process_aad(ctx, aad);
+    if (0 != rc) {
+    goto gcm_crypt_and_tag_END;
+    }
+
+    /* Aes-GCM Process Cipher function */
+    rc = gcm_process_cipher(ctx, input, output);
+    if (0 != rc) {
+    goto gcm_crypt_and_tag_END;
+    }
+
+    /* Aes-GCM Process LenA||LenC function */
+    rc = gcm_process_lenA_lenC(ctx);
+    if (0 != rc) {
+    goto gcm_crypt_and_tag_END;
+    }
+
+    rc = gcm_finish(ctx, tag);
+
+
+gcm_crypt_and_tag_END:
+    /* set pointer to user context and clear the output in case of failure*/
+    pAesGcmCtx = (AesGcmContext_t *)ctx;
+    if ((CRYPTO_DIRECTION_DECRYPT == pAesGcmCtx->dir) && (MBEDTLS_ERR_GCM_AUTH_FAILED == rc)) {
+        CC_PalMemSetZero(output, pAesGcmCtx->dataSize);
+    }
+
+    /* Clear working context */
+    CC_PalMemSetZero(ctx->buf, sizeof(mbedtls_gcm_context));
+
+    return rc;
+}
+
+int mbedtls_gcm_crypt_and_tag(mbedtls_gcm_context *ctx,
+                  int mode,
+                  size_t length,
+                  const unsigned char *iv,
+                  size_t iv_len,
+                  const unsigned char *add,
+                  size_t add_len,
+                  const unsigned char *input,
+                  unsigned char *output,
+                  size_t tag_len,
+                  unsigned char *tag)
+{
+    int rc;
+
+    rc = gcm_crypt_and_tag(ctx, mode, length,
+                   iv, iv_len,
+                   add, add_len,
+                   input, output,
+                   tag_len, tag);
+    return rc;
+}
+
+int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx,
+                  size_t length,
+                  const unsigned char *iv,
+                  size_t iv_len,
+                  const unsigned char *add,
+                  size_t add_len,
+                  const unsigned char *tag,
+                  size_t tag_len,
+                  const unsigned char *input,
+                  unsigned char *output )
+{
+    int rc;
+
+    rc = gcm_crypt_and_tag(ctx, 0, length,
+                   iv, iv_len,
+                   add, add_len,
+                   input, output,
+                   tag_len, (unsigned char *)tag);
+    return rc;
+}
+
+/**************************************************************************************************/
+/******                             UN-Supported API's                   **************************/
+/**************************************************************************************************/
+int mbedtls_gcm_starts(mbedtls_gcm_context *ctx,
+                       int mode,
+                       const unsigned char *iv,
+               size_t iv_len,
+               const unsigned char *aad,
+               size_t aad_len)
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(mode);
+    CC_UNUSED_PARAM(iv);
+    CC_UNUSED_PARAM(iv_len);
+    CC_UNUSED_PARAM(aad);
+    CC_UNUSED_PARAM(aad_len);
+
+    return (MBEDTLS_ERR_GCM_API_IS_NOT_SUPPORTED);
+}
+
+int mbedtls_gcm_update(mbedtls_gcm_context *ctx,
+               size_t length,
+               const unsigned char *input,
+               unsigned char *output)
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(length);
+    CC_UNUSED_PARAM(input);
+    CC_UNUSED_PARAM(output);
+
+    return (MBEDTLS_ERR_GCM_API_IS_NOT_SUPPORTED);
+}
+
+int mbedtls_gcm_finish(mbedtls_gcm_context *ctx,
+               unsigned char *tag,
+               size_t tag_len)
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(tag);
+    CC_UNUSED_PARAM(tag_len);
+
+    return (MBEDTLS_ERR_GCM_API_IS_NOT_SUPPORTED);
+}
+/**************************************************************************************************/
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_ccm_common.h b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_ccm_common.h
new file mode 100644
index 0000000..6f184a5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_ccm_common.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_aesccm_star_common
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the common definitions of the CryptoCell AES-CCM star APIs.
+ */
+
+
+
+#ifndef _MBEDTLS_CCM_COMMON_H
+#define _MBEDTLS_CCM_COMMON_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! The size of the AES CCM star nonce in bytes. */
+#define MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES               13
+/*! The size of source address of the AES CCM star in bytes. */
+#define MBEDTLS_AESCCM_STAR_SOURCE_ADDRESS_SIZE_BYTES      8
+
+/*! AES CCM mode: CCM. */
+#define MBEDTLS_AESCCM_MODE_CCM             0
+/*! AES CCM mode: CCM star. */
+#define MBEDTLS_AESCCM_MODE_STAR            1
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /* _MBEDTLS_CCM_COMMON_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_common.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_common.c
new file mode 100644
index 0000000..e166423
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_common.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include "cc_pal_types.h"
+#include "cc_pal_log.h"
+
+/* Implementation that should never be optimized out by the compiler */
+
+void mbedtls_zeroize_internal( void *v, size_t n )
+{
+    volatile unsigned char *p = NULL;
+    if( NULL == v )
+    {
+        CC_PAL_LOG_ERR( "input is NULL\n" );
+        return;
+    }
+    p = (unsigned char*)v; while( n-- ) *p++ = 0;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_common.h b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_common.h
new file mode 100644
index 0000000..9491a0e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_common.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MBEDTLS_COMMON_H
+#define MBEDTLS_COMMON_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * \brief           Implementation of memset to zero
+ *
+ * \param v         adrress to set
+ * \param n         size
+ */
+void mbedtls_zeroize_internal( void *v, size_t n );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* MBEDTLS_COMMON_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_hash_common.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_hash_common.c
new file mode 100644
index 0000000..bb4c85f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_hash_common.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "hash_driver.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_log.h"
+#include "sha1_alt.h"
+#include "sha256_alt.h"
+
+/*
+In CC312, DMA (i.e. for hash module input ) needs access to physical and continues memory.
+In order to assure the DMA can access the residue data saved in the hashCtx, it is being to copied to a local
+stack variable.
+In case memory is guaranteed to be DMAable, this copy can be removed, and hashCtx->prevData can be used.
+*/
+static uint32_t   mbedtls_hashUpdate(void    *pHashUserCtx,
+                        uint8_t     *pDataIn,
+                        size_t      dataInSize)
+{
+    uint32_t rc = 0;
+    HashContext_t *pHashCtx = NULL;
+    size_t   bytesToAdd = 0;
+    uint32_t localPrevDataIn[HASH_SHA512_BLOCK_SIZE_IN_WORDS];
+    CCBuffInfo_t inBuffInfo;
+
+    pHashCtx = (HashContext_t *)pHashUserCtx;
+    // If pHashCtx->prevDataInSize > 0, fill it with with the current data
+    bytesToAdd = CC_MIN(((pHashCtx->blockSizeInBytes - pHashCtx->prevDataInSize) % pHashCtx->blockSizeInBytes), dataInSize);
+    if (bytesToAdd > 0) {
+        /* add the data to the remaining buffer */
+        CC_PalMemCopy(&(((uint8_t *)(pHashCtx->prevDataIn))[pHashCtx->prevDataInSize]), pDataIn, bytesToAdd);
+        pHashCtx->prevDataInSize += bytesToAdd;
+        pDataIn += bytesToAdd;
+        dataInSize -= bytesToAdd;
+    }
+
+    // If the remaining buffer is full, process the block (else, the remaining buffer will be processed in the next update or finish) */
+    if (pHashCtx->prevDataInSize == pHashCtx->blockSizeInBytes) {
+        /* Copy prevDataIn to stack, in order to ensure continues and physical memory access.
+        That way, DMA will be able to access the data on any platform.*/
+        CC_PalMemCopy(localPrevDataIn, pHashCtx->prevDataIn, CC_MIN(HASH_SHA512_BLOCK_SIZE_IN_WORDS*sizeof(uint32_t), pHashCtx->prevDataInSize));
+
+        rc = SetDataBuffersInfo((uint8_t*)localPrevDataIn, pHashCtx->blockSizeInBytes, &inBuffInfo,
+                                   NULL, 0, NULL);
+        if (rc != 0) {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return rc;
+        }
+
+        rc = ProcessHashDrv(pHashCtx, &inBuffInfo, pHashCtx->blockSizeInBytes);
+        if (rc != CC_OK) {
+            CC_PAL_LOG_ERR( "ProcessHashDrv failed, ret = %d\n", rc );
+            return rc;
+        }
+        pHashCtx->prevDataInSize = 0;
+    }
+
+    // Process all the blocks that remain in the data
+    bytesToAdd = (dataInSize / pHashCtx->blockSizeInBytes) * pHashCtx->blockSizeInBytes;
+    if (bytesToAdd > 0) {
+
+        rc = SetDataBuffersInfo(pDataIn, bytesToAdd, &inBuffInfo,
+                                   NULL, 0, NULL);
+        if (rc != 0) {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return rc;
+        }
+
+        rc = ProcessHashDrv(pHashCtx, &inBuffInfo, bytesToAdd);
+        if (rc != CC_OK) {
+            CC_PAL_LOG_ERR( "ProcessHashDrv failed, ret = %d\n", rc );
+            return rc;
+        }
+        pDataIn += bytesToAdd;
+        dataInSize -= bytesToAdd;
+    }
+
+    // Copy the remaining partial block to prevDataIn */
+    bytesToAdd = dataInSize;
+    if (bytesToAdd > 0) {
+        CC_PalMemCopy((uint8_t *)&((pHashCtx->prevDataIn)[pHashCtx->prevDataInSize]), pDataIn, bytesToAdd);
+        pHashCtx->prevDataInSize += bytesToAdd;
+    }
+    return CC_OK;
+}
+
+int mbedtls_sha_process_internal( void *ctx, const unsigned char *data )
+{
+    int ret;
+
+    if ( NULL == ctx )
+    {
+        CC_PAL_LOG_ERR( "ctx is NULL\n" );
+        return( 1 );
+    }
+    if ( NULL == data )
+    {
+        CC_PAL_LOG_ERR( "data is NULL\n" );
+        return( 1 );
+    }
+    ret = mbedtls_hashUpdate(ctx, (uint8_t *)data, HASH_BLOCK_SIZE_IN_BYTES);
+    if( CC_OK != ret)
+    {
+        CC_PAL_LOG_ERR("mbedtls_hashUpdate failed, ret = %d\n", ret);
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+int mbedtls_sha_starts_internal( void *ctx, hashMode_t mode )
+{
+    int ret;
+    HashContext_t *pHashCtx = NULL;
+
+    if( NULL == ctx )
+    {
+        CC_PAL_LOG_ERR( "ctx is NULL\n" );
+        return( 1 );
+    }
+
+    pHashCtx = (HashContext_t *)ctx;
+    CC_PalMemSetZero(ctx, sizeof( HashContext_t ) );
+    pHashCtx->mode = mode;
+    pHashCtx->blockSizeInBytes = HASH_BLOCK_SIZE_IN_BYTES;
+    ret = InitHashDrv(pHashCtx);
+    if(ret != 0)
+    {
+        return( 1 );
+    }
+    else
+    {
+        return( 0 );
+    }
+}
+
+int mbedtls_sha_finish_internal( void *ctx )
+{
+    uint32_t localPrevDataIn[HASH_SHA512_BLOCK_SIZE_IN_WORDS];
+    size_t      dataInSize = 0;
+    drvError_t drvRc = HASH_DRV_OK;
+    HashContext_t *pHashCtx = NULL;
+    CCBuffInfo_t inBuffInfo;
+
+    pHashCtx = (HashContext_t *)ctx;
+    if (pHashCtx->prevDataInSize != 0) {
+        /* Copy prevDataIn to stack, in order to ensure continues and physical memory access.
+        That way, DMA will be able to access the data on any platform.*/
+        CC_PalMemCopy(localPrevDataIn, pHashCtx->prevDataIn, CC_MIN(HASH_SHA512_BLOCK_SIZE_IN_WORDS*sizeof(uint32_t), pHashCtx->prevDataInSize));
+        dataInSize = pHashCtx->prevDataInSize;
+    }
+    pHashCtx->isLastBlockProcessed = 1;
+
+    drvRc = SetDataBuffersInfo((uint8_t*)localPrevDataIn, dataInSize, &inBuffInfo,
+                               NULL, 0, NULL);
+    if (drvRc != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return( 1 );
+    }
+
+    drvRc = ProcessHashDrv(pHashCtx, &inBuffInfo, dataInSize);
+    if (drvRc != HASH_DRV_OK){
+        CC_PAL_LOG_ERR( "ProcessHashDrv failed, ret = %d\n", drvRc );
+        return( 1 );
+    }
+    drvRc = FinishHashDrv(pHashCtx);
+    if (drvRc != HASH_DRV_OK) {
+        CC_PAL_LOG_ERR( "FinishHashDrv failed, ret = %d\n", drvRc );
+        return( 1 );
+    }
+    pHashCtx->prevDataInSize = 0;
+
+    return( 0 );
+}
+
+int mbedtls_sha_update_internal( void *ctx, const unsigned char *input, size_t ilen )
+{
+    int ret = 1;
+
+    if (NULL == ctx){
+        CC_PAL_LOG_ERR( "ctx is NULL\n" );
+        return( 1 );
+    }
+
+    if (0 == ilen){
+        /* This is a valid situation, no need to call hashUpdate.
+        HashFinish will produce the result. */
+        return( 0 );
+    }
+
+    //if len not zero, but pointer is NULL
+    if (NULL == input){
+        CC_PAL_LOG_ERR( "input is NULL\n" );
+        //printf("TEST12, hash err = 1\n");
+        return( 1 );
+    }
+    ret = mbedtls_hashUpdate(ctx, (uint8_t *)input, ilen);
+    if( CC_OK != ret)
+    {
+        CC_PAL_LOG_ERR("mbedtls_hashUpdate failed, ret = %d\n", ret);
+        return( 1 );
+    }
+
+    return( 0 );
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_hash_common.h b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_hash_common.h
new file mode 100644
index 0000000..2abe140
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/mbedtls_hash_common.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MBEDTLS_HASH_COMMON_H
+#define MBEDTLS_HASH_COMMON_H
+#include "mbedtls_common.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+uint32_t   mbedtls_hashUpdate(void   *pHashUserCtx,
+                        uint8_t     *pDataIn,
+                        size_t      dataInSize);
+
+void mbedtls_sha_init_internal( void *ctx );
+
+int mbedtls_sha_process_internal( void *ctx, const unsigned char *data );
+
+int mbedtls_sha_finish_internal( void *ctx );
+
+int mbedtls_sha_update_internal( void *ctx, const unsigned char *input, size_t ilen );
+
+int mbedtls_sha_starts_internal( void *ctx, hashMode_t mode);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* MBEDTLS_HASH_COMMON_H */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/platform_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/platform_alt.c
new file mode 100644
index 0000000..8bd3b7b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/platform_alt.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free   free
+#endif
+
+#include "mbedtls/platform.h"
+
+#include <pthread.h>
+#include "tests_phys_map.h"
+#include "tests_hw_access_iot.h"
+#include "tst_common.h"
+#include "cc_lib.h"
+
+void* Test_LibInit(void *params ){
+   uint32_t rc;
+   CClibRetCode_t *pRc =NULL;
+   LibInitArgs* threadArgs = (LibInitArgs*)params;
+
+   pRc = (CClibRetCode_t *)malloc(sizeof(CClibRetCode_t));
+   if( pRc == NULL){
+       return((void *)pRc);
+   }
+   rc = CC_LibInit(threadArgs->rndContext_ptr, threadArgs->rndWorkBuff_ptr);
+   *pRc =rc;
+
+   return((void *)pRc);
+}
+
+int tests_CC_libInit(CCRndContext_t* rndContext_ptr, CCRndWorkBuff_t * rndWorkBuff_ptr, unsigned long* stackAddress){
+    uint32_t rc = 0;
+    void *res;
+    pthread_t threadId;
+    pthread_attr_t threadAttr;
+    LibInitArgs threadArgs;
+
+    threadArgs.rndContext_ptr=rndContext_ptr;
+    threadArgs.rndWorkBuff_ptr=rndWorkBuff_ptr;
+
+    rc = pthread_attr_init(&threadAttr);
+    mbedtls_printf( "\n'pthread_attr_init' result = %d \n", rc );
+    if (rc != 0) {
+        goto EndThread_2;
+    }
+
+    rc = pthread_attr_setstack(&threadAttr,  stackAddress, THREAD_STACK_SIZE);
+    mbedtls_printf( "\n'pthread_attr_setstack' result = %d \n", rc );
+    if (rc != 0) {
+        goto EndThread;
+    }
+
+    rc = pthread_create(&threadId, &threadAttr, Test_LibInit, (void *)&threadArgs);
+    mbedtls_printf( "\n'pthread_create' result = %d \n", rc );
+    if (rc != 0) {
+        goto EndThread;
+    }
+    rc = pthread_join(threadId, (void**)&res);
+    mbedtls_printf( "\n'pthread_join' result = %d \n", rc );
+    if (rc != 0 || res == NULL) {
+        goto EndThread;
+    }
+
+    rc = *((int *)*&res);
+    mbedtls_printf( "\n'res' result = %d \n", rc );
+
+EndThread:
+    pthread_attr_destroy(&threadAttr);
+    free(res);
+EndThread_2:
+    return rc;
+}
+
+//uint32_t platform_start(void)
+int mbedtls_platform_setup( mbedtls_platform_context *ctx )
+{
+   uint32_t rc = 0;
+   zynqPlatTestContext_t *pPlatTestCtx = NULL;
+
+   rc = initPlatform();
+
+   mbedtls_printf( "\n'initPlatform' result = %d \n", rc );
+
+   if (rc != 0){
+       return rc;
+   }
+
+   /* set pointer to user context */
+   pPlatTestCtx = (zynqPlatTestContext_t *)ctx;
+
+   pPlatTestCtx->rndContext_ptr = (CCRndContext_t *)g_testHwRndCtxBaseAddr;
+   pPlatTestCtx->rndWorkBuff_ptr = (CCRndWorkBuff_t *)(g_testHwRndWorkBuffBaseAddr);
+   pPlatTestCtx->rndContext_ptr->rndState = (void *)(g_testHwRndCtxBaseAddr+sizeof(CCRndContext_t));
+   pPlatTestCtx->rndContext_ptr->entropyCtx = (void *)(g_testHwRndCtxBaseAddr+sizeof(CCRndContext_t)+sizeof(CCRndState_t));
+   rc = tests_CC_libInit(pPlatTestCtx->rndContext_ptr, pPlatTestCtx->rndWorkBuff_ptr, (unsigned long*)g_testHwUserStackBaseAddr);
+
+   mbedtls_printf( "\n'tests_CC_libInit' result = %d \n", rc );
+
+   return rc;
+}
+
+//void platform_stop(void)
+void mbedtls_platform_teardown( mbedtls_platform_context *ctx )
+{
+    zynqPlatTestContext_t *pPlatTestCtx = NULL;
+
+    pPlatTestCtx = (zynqPlatTestContext_t *)ctx;
+
+    CC_LibFini(pPlatTestCtx->rndContext_ptr);
+    freePlatform();
+}
+
+
+
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/poly1305_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/poly1305_alt.c
new file mode 100644
index 0000000..b52acce
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/poly1305_alt.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_POLY1305_C)
+#include "mbedtls/poly1305.h"
+#include "poly.h"
+#include "mbedtls/platform_util.h"
+#include "chacha_driver.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_types.h"
+
+#if defined(MBEDTLS_SELF_TEST)
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_printf printf
+#endif /* MBEDTLS_PLATFORM_C */
+#endif /* MBEDTLS_SELF_TEST */
+
+#if defined(MBEDTLS_POLY1305_ALT)
+
+
+void mbedtls_poly1305_init( mbedtls_poly1305_context *ctx )
+{
+    CC_UNUSED_PARAM(ctx);
+    return;
+}
+
+void mbedtls_poly1305_free( mbedtls_poly1305_context *ctx )
+{
+    CC_UNUSED_PARAM(ctx);
+    return;
+}
+
+/* Cryptocell only supports integrated poly1305 operations  */
+int mbedtls_poly1305_starts( mbedtls_poly1305_context *ctx,
+                             const unsigned char key[32] )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(key);
+    return MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE;
+}
+
+/* Cryptocell only supports integrated poly1305 operations  */
+int mbedtls_poly1305_update( mbedtls_poly1305_context *ctx,
+                             const unsigned char *input,
+                             size_t ilen )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(input);
+    CC_UNUSED_PARAM(ilen);
+    return MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE;
+}
+
+/* Cryptocell only supports integrated poly1305 operations  */
+int mbedtls_poly1305_finish( mbedtls_poly1305_context *ctx,
+                             unsigned char mac[16] )
+{
+    CC_UNUSED_PARAM(ctx);
+    CC_UNUSED_PARAM(mac);
+    return MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE;
+}
+
+int mbedtls_poly1305_mac( const unsigned char key[32],
+                          const unsigned char *input,
+                          size_t ilen,
+                          unsigned char mac[16] )
+{
+    int rc;
+    mbedtls_poly_key pKey;
+    mbedtls_poly_mac macRes;
+
+    // Verify inputs
+    if (key == NULL) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+    if ((mac == NULL) || ((input == NULL) ^ (ilen == 0)) || (ilen > CC_MAX_UINT32_VAL)) {
+        return MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA;
+    }
+
+    CC_PalMemCopy((unsigned char *)pKey, key, MBEDTLS_POLY_KEY_SIZE_BYTES);
+
+    rc = PolyMacCalc(pKey, NULL, 0, input, ilen, macRes, false);
+    if (rc != 0) {
+        return MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED;
+    }
+
+    CC_PalMemCopy(mac, (unsigned char *)macRes, MBEDTLS_POLY_MAC_SIZE_BYTES);
+
+    return ( 0 );
+}
+
+
+#endif /* !MBEDTLS_POLY1305_ALT */
+
+#endif /* !MBEDTLS_POLY1305_C */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/rsa_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/rsa_alt.c
new file mode 100644
index 0000000..604f857
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/rsa_alt.c
@@ -0,0 +1,3257 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_RSA_C)
+
+#include "mbedtls/rsa.h"
+#include "mbedtls/rsa_internal.h"
+#include "mbedtls/oid.h"
+#include "mbedtls_common.h"
+#include "bignum.h"
+
+#include <string.h>
+
+#if defined(MBEDTLS_PKCS1_V21)
+#include "mbedtls/md.h"
+#endif
+
+#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__)
+#include <stdlib.h>
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#define mbedtls_printf printf
+#define mbedtls_calloc calloc
+#define mbedtls_free   free
+#endif
+
+
+#if defined (MBEDTLS_RSA_ALT)
+#include "cc_bitops.h"
+#include "rsa_public.h"
+#include "rsa_private.h"
+#include "cc_pal_mem.h"
+#include "cc_rsa_error.h"
+#include "cc_rsa_local.h"
+#include "cc_common_math.h"
+#include "cc_fips_defs.h"
+#include "cc_pal_types_plat.h"
+#include "cc_pal_log.h"
+#include "cc_rsa_schemes.h"
+#include "cc_rnd_common.h"
+#include "cc_rnd_error.h"
+
+#define IN
+#define OUT
+
+#include "cc_rsa_kg.h"
+#include "cc_rsa_prim.h"
+#include "cc_common.h"
+#include "pki.h"
+#include "rsa.h"
+
+#include "ctr_drbg.h"
+#include "pka.h"
+#include "cc_pal_abort.h"
+
+#define GOTO_END(ERR) \
+    do { \
+        Error = ERR; \
+        goto End; \
+    } while (0)
+
+#define GOTO_CLEANUP(ERR) \
+    do { \
+        Error = ERR; \
+        goto Cleanup; \
+    } while (0)
+
+
+/* Minimal and maximal size of RSA modulus in bits
+ * According to FIPS 186-4 size in bits should be in range [1024...3072] */
+#define MBEDTLS_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS  1024
+#define MBEDTLS_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS  4096
+
+#define MBEDTLS_RSA_MIN_VALID_KEYGEN_SIZE_VALUE_IN_BITS  1024
+#define MBEDTLS_RSA_MAX_VALID_KEYGEN_SIZE_VALUE_IN_BITS  3072
+
+#define MBEDTLS_RSA_CHK(f) do { if( ( err = f ) != 0 ) goto End; } while( 0 )
+
+#define  MOD_LEN_ID 0
+#define  REG_LEN_ID 1
+#define  PLEN_ID    2
+
+typedef enum {
+    CC_RSA_OP_DEFAULT,
+    CC_RSA_OP_PUBLIC,
+    CC_RSA_OP_PRIVATE,
+} CC_RSA_OP;
+
+static int mbedtls_alt_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                            const mbedtls_mpi *D, mbedtls_mpi *DP,
+                            mbedtls_mpi *DQ, mbedtls_mpi *QP );
+
+/* Implementation that should never be optimized out by the compiler */
+static void mbedtls_rsa_zeroize( void *v, size_t n ) {
+    volatile uint8_t *p = v; while( n-- ) *p++ = 0;
+}
+
+/* The function zeroizes size_bytes part on allocated buffer and
+ * then releases the memory given by the pointer X
+ */
+static void mbedtls_buff_free( void *X, size_t size_bytes )
+{
+    if( X == NULL )
+        return;
+    if(size_bytes != 0)
+        mbedtls_rsa_zeroize( X, size_bytes );
+
+    mbedtls_free( X );
+}
+
+#define WORD_SIZE_IN_BYTES       sizeof(mbedtls_mpi_uint)
+
+static size_t mbedtls_mpi_size_in_words( const mbedtls_mpi *X )
+{
+    return ((mbedtls_mpi_size(X) + WORD_SIZE_IN_BYTES - 1) / WORD_SIZE_IN_BYTES);
+}
+/*
+* The function allocates mpi inner buffer X->p of required length sizeInWords, copies given data into it.
+* Assumed that the data is positive, therefore the function sets X->s = 1.
+*/
+static int32_t mbedtls_rsa_uint32_buf_to_mpi(mbedtls_mpi *X, const uint32_t *buf, size_t sizeInWords)
+{
+     int32_t err = 0;
+
+     if(X == NULL || X->p != NULL || X->n != 0 || sizeInWords == 0) {
+        err = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+        goto End;
+     }
+
+    if( ( X->p = (uint32_t*)mbedtls_calloc( sizeInWords, sizeof(uint32_t) ) ) == NULL ) {
+        err = MBEDTLS_ERR_MPI_ALLOC_FAILED;
+        goto End;
+    }
+
+    CC_PalMemCopy(X->p, buf, sizeInWords*CC_32BIT_WORD_SIZE);
+    X->s = 1;
+    X->n = sizeInWords;
+
+    End:
+    return err;
+}
+
+
+/*
+ * The function converts CC errors codes to appropriate mbedtls defined code
+ *
+ * */
+static int error_mapping_cc_to_mbedtls_rsa (CCError_t cc_error, CC_RSA_OP op)
+{
+    int ret=-1;
+    int base = 0;
+
+    switch (op)
+    {
+        case CC_RSA_OP_PUBLIC:
+            base = MBEDTLS_ERR_RSA_PUBLIC_FAILED;
+            break;
+
+        case CC_RSA_OP_PRIVATE:
+            base = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
+            break;
+
+        default:
+            base = 0;
+            break;
+    }
+
+    switch (cc_error)
+    {
+        case CC_RSA_BASE_MGF_MASK_TOO_LONG:
+        case CC_RSA_BASE_OAEP_DECODE_MESSAGE_TOO_LONG:
+        case CC_RSA_BASE_OAEP_DECODE_PARAMETER_STRING_TOO_LONG:
+        case CC_RSA_BASE_OAEP_ENCODE_MESSAGE_TOO_LONG:
+        case CC_RSA_BASE_OAEP_ENCODE_PARAMETER_STRING_TOO_LONG:
+        case CC_RSA_CONV_TO_CRT_INVALID_TEMP_BUFF_POINTER_ERROR:
+        case CC_RSA_DATA_POINTER_INVALID_ERROR:
+        case CC_RSA_DECRYPT_INVALID_OUTPUT_SIZE:
+        case CC_RSA_DECRYPT_OUTPUT_SIZE_POINTER_ERROR:
+        case CC_RSA_ENCODE_15_MSG_OUT_OF_RANGE:
+        case CC_RSA_GET_DER_HASH_MODE_ILLEGAL:
+        case CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR:
+        case CC_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR:
+        case CC_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR:
+        case CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_ERROR:
+        case CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_PTR_ERROR:
+        case CC_RSA_INVALID_CRT_COEFF_VAL:
+        case CC_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_ERROR:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_PTR_ERROR:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_ERROR:
+        case CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_POINTER_ERROR:
+        case CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_ERROR:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_PTR_ERROR:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_ERROR:
+        case CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_POINTER_ERROR:
+        case CC_RSA_INVALID_DECRYPRION_MODE_ERROR:
+        case CC_RSA_INVALID_EXPONENT_POINTER_ERROR:
+        case CC_RSA_INVALID_EXPONENT_SIZE:
+        case CC_RSA_INVALID_EXPONENT_VAL:
+        case CC_RSA_INVALID_EXP_BUFFER_SIZE_POINTER:
+        case CC_RSA_INVALID_MESSAGE_BUFFER_SIZE:
+        case CC_RSA_INVALID_MESSAGE_DATA_SIZE:
+        case CC_RSA_INVALID_MODULUS_ERROR:
+        case CC_RSA_INVALID_MODULUS_POINTER_ERROR:
+        case CC_RSA_INVALID_MODULUS_SIZE:
+        case CC_RSA_INVALID_MOD_BUFFER_SIZE_POINTER:
+        case CC_RSA_INVALID_OUTPUT_POINTER_ERROR:
+        case CC_RSA_INVALID_OUTPUT_SIZE_POINTER_ERROR:
+        case CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR:
+        case CC_RSA_INVALID_PTR_ERROR:
+        case CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR:
+        case CC_RSA_INVALID_SIGNATURE_BUFFER_POINTER:
+        case CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE:
+        case CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR:
+        case CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID:
+        case CC_RSA_MGF_ILLEGAL_ARG_ERROR:
+        case CC_RSA_MODULUS_EVEN_ERROR:
+        case CC_RSA_PKCS1_VER_ARG_ERROR:
+        case CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID:
+        case CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR:
+        case CC_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR:
+        case CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR:
+        case CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR:
+        case CC_RSA_WRONG_PRIVATE_KEY_TYPE:
+            ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+            break;
+
+        case CC_RSA_INVALID_MESSAGE_VAL:
+            ret = base + MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+            break;
+
+        case CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE:
+        case CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING:
+        case CC_RSA_OAEP_DECODE_ERROR:
+            ret = MBEDTLS_ERR_RSA_INVALID_PADDING;
+            break;
+
+        case CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE:
+            ret = MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE;
+            break;
+
+        case CC_RSA_KEY_GEN_CONDITIONAL_TEST_FAIL_ERROR:
+        case CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW:
+        case CC_RSA_KEY_GENERATION_FAILURE_ERROR:
+            ret = MBEDTLS_ERR_RSA_KEY_GEN_FAILED;
+            break;
+
+        case CC_RSA_CAN_NOT_GENERATE_RAND_IN_RANGE:
+        case CC_RSA_ERROR_IN_RANDOM_OPERATION_FOR_ENCODE:
+        case CC_RND_STATE_PTR_INVALID_ERROR:
+        case CC_RND_GEN_VECTOR_FUNC_ERROR:
+            ret = MBEDTLS_ERR_RSA_RNG_FAILED;
+            break;
+
+        case CC_RSA_ERROR_VER15_INCONSISTENT_VERIFY:
+        case CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY:
+            ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;
+            break;
+
+        // For now, there is no better error code for malloc failure, both in CC and mbedtls
+        case CC_OUT_OF_RESOURCE_ERROR:
+            ret = -1;
+            break;
+
+        case CC_OK:
+            ret = 0;
+            break;
+        default:
+            ret = -1;
+            CC_PAL_LOG_ERR("Unknown CC_ERROR %d (0x%08x)\n", cc_error, cc_error);
+            break;
+    }
+
+
+    CC_PAL_LOG_INFO("Converted CC_ERROR %d (0x%08x) to MBEDTLS_ERR %d\n",
+                    cc_error, cc_error, ret);
+    return ret;
+}
+
+void mbedtls_rsa_init( mbedtls_rsa_context *ctx,
+        int padding,
+        int hash_id )
+{
+    /* check input parameters and functions */
+    if (ctx == NULL){
+            CC_PalAbort("Ctx is NULL\n");
+    }
+    if ((hash_id != MBEDTLS_MD_NONE) && ((hash_id < MBEDTLS_MD_SHA1) || (hash_id > MBEDTLS_MD_SHA512))){
+            CC_PalAbort("Not valid hash id\n");
+    }
+    CC_PalMemSetZero(ctx, sizeof( mbedtls_rsa_context));
+
+    mbedtls_rsa_set_padding( ctx, padding, hash_id );
+
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_mutex_init( &ctx->mutex );
+#endif
+}
+
+/*
+ * Set padding for an existing RSA context
+ */
+void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id )
+{
+    /* check input parameters and functions */
+    if (ctx == NULL){
+            CC_PalAbort("Ctx is NULL\n");
+    }
+    if ((hash_id != MBEDTLS_MD_NONE) && ((hash_id < MBEDTLS_MD_SHA1) || (hash_id > MBEDTLS_MD_SHA512))){
+            CC_PalAbort("Not valid hash id\n");
+    }
+    ctx->padding = padding;
+    ctx->hash_id = hash_id;
+}
+
+#if defined(MBEDTLS_GENPRIME)
+
+/*
+ * Generate the RSA key pair (CRT and non CRT parameters) .
+ */
+int mbedtls_rsa_gen_key( mbedtls_rsa_context *pCtx,    /*!< pointer to context structure, containing RSA parameters */
+        int (*f_rng)(void *, unsigned char *, size_t), /*<! random vector generation function prototype */
+        void *p_rng,                                   /*<! pointer to PRNG buffer (state) */
+        unsigned int nbits,                            /*<! RSA modulus size in bits */
+        int pubExp )                                   /*<! public exponent value */
+{
+
+
+    CCRndContext_t rndContext;
+    CCRndContext_t *pRndContext = &rndContext;
+
+    /* the Error return code identifier */
+    CCError_t err = CC_OK;
+    uint32_t pubExpSizeBits, mask;
+    uint32_t keySizeWords; /* size of RSA modulus */
+    CCRsaPubKey_t  *pCcPubKey = NULL;
+    CCRsaPrivKey_t *pCcPrivKey = NULL;
+    CCRsaKgData_t  *pKeyGenData = NULL;
+
+    uint32_t keySizeBytes = CALC_FULL_BYTES(nbits);
+#define PUB_EXP_SIZE_IN_WORDS 1
+
+#ifdef FIPS_CERTIFICATION
+    CCRsaKgFipsContext_t  FipsCtx;
+#endif
+
+
+    /* check input parameters and functions */
+    if ( pCtx == NULL || f_rng == NULL || p_rng == NULL ){
+            return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+    }
+
+    /* verifying the exponent has legal value (currently only 0x3,0x11 and 0x10001) */
+    if (pubExp != CC_RSA_KG_PUB_EXP_ALLOW_VAL_1  &&
+        pubExp != CC_RSA_KG_PUB_EXP_ALLOW_VAL_2  &&
+        pubExp != CC_RSA_KG_PUB_EXP_ALLOW_VAL_3) {
+            return  MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+    }
+
+    /*  check that the key size allowed by CRYS requirements  */
+    if (( nbits < MBEDTLS_RSA_MIN_VALID_KEYGEN_SIZE_VALUE_IN_BITS ) ||
+        ( nbits > MBEDTLS_RSA_MAX_VALID_KEYGEN_SIZE_VALUE_IN_BITS ) ||
+        ( nbits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS )) {
+            return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+    }
+
+    /* set random generation function and context */
+    pRndContext->rndState = p_rng;
+
+    err = CC_RndSetGenerateVectorFunc(pRndContext, f_rng);
+    if ( err != CC_OK ){
+            return MBEDTLS_ERR_RSA_RNG_FAILED;
+    }
+
+    /* RSA modulus size in bytes and words */
+    keySizeWords = CALC_FULL_32BIT_WORDS(nbits);
+
+    /* allocate temp buffers */
+    pCcPubKey = (CCRsaPubKey_t *)mbedtls_calloc(CALC_32BIT_WORDS_FROM_BYTES(sizeof(CCRsaPubKey_t)), sizeof(uint32_t));
+    if (pCcPubKey == NULL) {
+        err = CC_OUT_OF_RESOURCE_ERROR;
+        goto End;
+    }
+    pCcPrivKey = (CCRsaPrivKey_t *)mbedtls_calloc(CALC_32BIT_WORDS_FROM_BYTES(sizeof(CCRsaPrivKey_t)), sizeof(uint32_t));
+    if (pCcPrivKey == NULL) {
+        err = CC_OUT_OF_RESOURCE_ERROR;
+        goto End;
+    }
+    pKeyGenData = (CCRsaKgData_t *)mbedtls_calloc(CALC_32BIT_WORDS_FROM_BYTES(sizeof(CCRsaKgData_t)), sizeof(uint32_t));
+    if (pKeyGenData == NULL) {
+        err = CC_OUT_OF_RESOURCE_ERROR;
+        goto End;
+    }
+
+    /* get pub.exp size in bits */
+    pubExpSizeBits = 32;
+    mask = 1UL << 31;
+    while((pubExp & mask) == 0) {
+        pubExpSizeBits--;
+        mask >>= 1;
+    }
+
+    /* init sizes */
+    pCcPubKey->nSizeInBits  = nbits;
+    pCcPubKey->eSizeInBits  = pubExpSizeBits;
+    pCcPrivKey->nSizeInBits = nbits;
+    pCcPubKey->e[0] = pubExp;
+
+    /* set params for non CRT */
+    pCcPrivKey->OperationMode = CC_RSA_NoCrt; /* default mode */
+    pCcPrivKey->PriveKeyDb.NonCrt.eSizeInBits = pCcPubKey->eSizeInBits;
+    pCcPrivKey->PriveKeyDb.NonCrt.e[0] = pubExp;
+
+
+    /* .....   calculate primes (P, Q) and nonCRT key (N, D) ..... */
+    do{
+         err = RsaGenPandQ(
+                        pRndContext,
+                        nbits,
+                        pubExpSizeBits,
+                        (uint32_t*)&pubExp,
+                        pKeyGenData );
+        if (err != CC_OK) {
+           goto End;
+        }
+
+        /* calculate modulus n and private nonCRT exponent d */
+        err = RsaCalculateNandD(
+                        pCcPubKey,
+                        pCcPrivKey,
+                        pKeyGenData,
+                        nbits/2 );
+
+        if (err != CC_OK) {
+            goto End;
+        }
+
+        /* repeat the loop if D is too low */
+    } while( err == CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW );
+
+     /* calculate Barr. tag for modulus N */
+    err = PkiCalcNp(((RsaPubKeyDb_t*)(pCcPubKey->ccRSAIntBuff))->NP, /*out*/
+            pCcPubKey->n, nbits);   /*in*/
+
+    if (err != CC_OK) {
+        goto End;
+    }
+
+
+    /* allocate mbedtls context internal buffers and copy data to them  */
+    pCtx->len = keySizeBytes; /* full size of modulus in bytes, including leading zeros*/
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->N, pCcPubKey->n, keySizeWords ) );
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->E, pCcPubKey->e, PUB_EXP_SIZE_IN_WORDS ) );
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->D, pCcPrivKey->PriveKeyDb.NonCrt.d, keySizeWords ) );
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->NP, ((RsaPubKeyDb_t*)(pCcPubKey->ccRSAIntBuff))->NP,
+                           CC_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS ) );
+
+    /*  P,Q saved in the context as it is done in mbedtls independent on
+     * CRT compilation flag  */
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->P, pKeyGenData->KGData.p, keySizeWords/2 ) );
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->Q, pKeyGenData->KGData.q, keySizeWords/2 ) );
+
+    /* calculate Barrett tags for P,Q and set into context */
+    err = PkiCalcNp(((RsaPrivKeyDb_t *)(pCcPrivKey->ccRSAPrivKeyIntBuff))->Crt.PP,/*out*/
+            pKeyGenData->KGData.p, nbits/2);   /*in*/
+    if (err != CC_OK) {
+        goto End;
+    }
+    err = PkiCalcNp(((RsaPrivKeyDb_t *)(pCcPrivKey->ccRSAPrivKeyIntBuff))->Crt.QP,/*out*/
+            pKeyGenData->KGData.q, nbits/2);   /*in*/
+    if (err != CC_OK) {
+        goto End;
+    }
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->BPP, ((RsaPrivKeyDb_t*)(pCcPrivKey->ccRSAPrivKeyIntBuff))->Crt.PP, CC_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS ) );
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->BQP, ((RsaPrivKeyDb_t*)(pCcPrivKey->ccRSAPrivKeyIntBuff))->Crt.QP, CC_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS ) );
+
+    /* calculate CRT parameters */
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    pCcPrivKey->OperationMode = CC_RSA_Crt;
+    err = RsaCalculateCrtParams(
+                        (uint32_t*)&pubExp, pubExpSizeBits,
+                        nbits,
+                        pKeyGenData->KGData.p, pKeyGenData->KGData.q,
+                        pCcPrivKey->PriveKeyDb.Crt.dP,
+                        pCcPrivKey->PriveKeyDb.Crt.dQ,
+                        pCcPrivKey->PriveKeyDb.Crt.qInv );
+
+    if (err !=CC_OK) {
+       goto End;
+    }
+
+    /* allocate mbedtls context internal buffers and copy data to them  */
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->DP, pCcPrivKey->PriveKeyDb.Crt.dP, keySizeWords/2 ) );
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->DQ, pCcPrivKey->PriveKeyDb.Crt.dQ, keySizeWords/2 ) );
+    MBEDTLS_RSA_CHK( mbedtls_rsa_uint32_buf_to_mpi( &pCtx->QP, pCcPrivKey->PriveKeyDb.Crt.qInv, keySizeWords/2 ) );
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+#ifdef FIPS_CERTIFICATION
+        CC_CommonReverseMemcpy( rsaKgOutParams.nModulus, (uint8_t*)pCcPubKey->n, keySizeBytes );
+        CC_CommonReverseMemcpy( rsaKgOutParams.pPrim, (uint8_t*)pKeyGenData->KGData.p, keySizeBytes/2 );
+        CC_CommonReverseMemcpy( rsaKgOutParams.qPrim, (uint8_t*)pKeyGenData->KGData.q, keySizeBytes/2 );
+        CC_CommonReverseMemcpy( rsaKgOutParams.dPrivExponent, (uint8_t*)pCcPrivKey->PriveKeyDb.NonCrt.d, keySizeBytes );
+#endif
+
+    End:
+    /* zeroing temp buffers  */
+    mbedtls_buff_free( pKeyGenData, sizeof( CCRsaKgData_t ) );
+    mbedtls_buff_free( pCcPrivKey,  sizeof( CCRsaPrivKey_t ) );
+    mbedtls_buff_free( pCcPubKey,   sizeof( CCRsaPubKey_t ) );
+
+    if( err != 0 ) {
+        mbedtls_rsa_free( pCtx );
+
+    }
+
+    return error_mapping_cc_to_mbedtls_rsa( err, CC_RSA_OP_PUBLIC );
+
+}
+
+#endif /* MBEDTLS_GENPRIME */
+
+
+/*
+ * Checks whether the context fields are set in such a way
+ * that the RSA primitives will be able to execute without error.
+ * It does *not* make guarantees for consistency of the parameters.
+ */
+static int rsa_check_context_alt( mbedtls_rsa_context const *ctx, int is_priv,
+                              int blinding_needed )
+{
+    /* blinding_needed is only used for NO_CRT to decide whether
+     * P,Q need to be present or not. In this function this variable is not used */
+    ((void) blinding_needed);
+
+    if( ctx->len != mbedtls_mpi_size( &ctx->N ) ||
+        ctx->len > MBEDTLS_MPI_MAX_SIZE )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /*
+     * 1. Modular exponentiation needs positive, odd moduli.
+     */
+
+    /* Modular exponentiation wrt. N is always used for
+     * RSA public key operations. */
+    if( mbedtls_mpi_cmp_int( &ctx->N, 0 ) <= 0 ||
+        mbedtls_mpi_get_bit( &ctx->N, 0 ) == 0  )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* Modular exponentiation for P and Q is only
+     * used for private key operations and if CRT
+     * is used. */
+    if( is_priv &&
+        ( mbedtls_mpi_cmp_int( &ctx->P, 0 ) <= 0 ||
+          mbedtls_mpi_get_bit( &ctx->P, 0 ) == 0 ||
+          mbedtls_mpi_cmp_int( &ctx->Q, 0 ) <= 0 ||
+          mbedtls_mpi_get_bit( &ctx->Q, 0 ) == 0  ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* !MBEDTLS_RSA_NO_CRT */
+
+    /*
+     * 2. Exponents must be positive
+     */
+
+    /* Always need E for public key operations */
+    if( mbedtls_mpi_cmp_int( &ctx->E, 0 ) <= 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+    /* For private key operations, use D or DP & DQ
+     * as (unblinded) exponents. */
+    if( is_priv && mbedtls_mpi_cmp_int( &ctx->D, 0 ) <= 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+#else
+    if( is_priv &&
+        ( mbedtls_mpi_cmp_int( &ctx->DP, 0 ) <= 0 ||
+          mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) <= 0  ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    /* It wouldn't lead to an error if it wasn't satisfied,
+     * but check for QP >= 1 nonetheless. */
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    if( is_priv &&
+        mbedtls_mpi_cmp_int( &ctx->QP, 0 ) <= 0 )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+#endif
+
+    return( 0 );
+}
+
+
+/*
+ * Check that core RSA parameters are sane.
+ * Note: this function checks only that given combination of parameters is
+ * mathematically correct and not checks consistency and security of public/private key-pair.
+ *
+ */
+int mbedtls_rsa_validate_params_alt( const mbedtls_mpi *N, const mbedtls_mpi *P,
+                                 const mbedtls_mpi *Q, const mbedtls_mpi *D,
+                                 const mbedtls_mpi *E,
+                                 int (*f_rng)(void *, unsigned char *, size_t),
+                                 void *p_rng )
+{
+    int ret = 0;
+    mbedtls_mpi K, L;
+
+#if defined( MBEDTLS_GENPRIME )
+    uint32_t keySizeWords;
+    uint32_t *pTempBuff; /* temp buffer of size 3*key size in words */
+#endif
+
+    /* check that at least one checking operation is avaliable */
+    if( !( ( P != NULL )                           ||
+           ( Q != NULL )                           ||
+           ( N != NULL && D != NULL && E != NULL ))) {
+        ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+    }
+
+    /*
+     * Step 1: If PRNG provided, check that P and Q are prime
+     */
+
+    /* get key size from existed data */
+    if ( N != NULL ) {
+        keySizeWords = mbedtls_mpi_size_in_words(N);
+    } else if ( P != NULL ) {
+        keySizeWords = 2 * mbedtls_mpi_size_in_words(P);
+    } else if ( Q != NULL ) {
+        keySizeWords = 2 * mbedtls_mpi_size_in_words(Q);
+    } else {
+        return MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+    }
+
+    /* allocate temp buffer */
+    if( ( pTempBuff = (uint32_t*)mbedtls_calloc( 3*keySizeWords/2, CC_32BIT_WORD_SIZE ) ) == NULL ) {
+        return  MBEDTLS_ERR_MPI_ALLOC_FAILED;
+    }
+
+    mbedtls_mpi_init( &K );
+    mbedtls_mpi_init( &L );
+
+#if defined( MBEDTLS_GENPRIME )
+
+    if( f_rng != NULL && p_rng != NULL ) {
+
+        CCRndContext_t ccRndCtx;
+        int8_t isPrime = 0;
+        uint32_t rabinTestsCount;
+
+        ccRndCtx.rndState = p_rng;
+        ccRndCtx.rndGenerateVectFunc = f_rng;
+        ccRndCtx.entropyCtx = NULL;
+
+        /* Set count of R-M tests */
+        if ( keySizeWords * CC_BITS_IN_32BIT_WORD <= 1024 ) {
+            rabinTestsCount = PKA_RSA_KEY_1024_PQ_PRIME_RM_TST_COUNT;  /* 7 */
+        } else if ( keySizeWords * CC_BITS_IN_32BIT_WORD <= 2048 ) {
+            rabinTestsCount = PKA_RSA_KEY_2048_PQ_PRIME_RM_TST_COUNT;  /* 4 */;
+        } else {/* if key size > 2048 */
+            rabinTestsCount = PKA_RSA_KEY_3072_PQ_PRIME_RM_TST_COUNT;  /* 3 */;
+        }
+
+        if( P != NULL ) {
+            ret = RsaPrimeTestCall( &ccRndCtx, &P->p[0], mbedtls_mpi_size_in_words(P),
+                                    rabinTestsCount,
+                                    &isPrime, pTempBuff/*3*modSizeWords*/,
+                                    CC_RSA_PRIME_TEST_MODE );
+            if ( ret != 0  && isPrime != 1 ) {
+                ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+               goto cleanup;
+            }
+        }
+        if( Q != NULL ) {
+            ret = RsaPrimeTestCall( &ccRndCtx, &Q->p[0], mbedtls_mpi_size_in_words(Q),
+                                    rabinTestsCount,
+                                    &isPrime, pTempBuff/*3*modSizeWords*/,
+                                    CC_RSA_PRIME_TEST_MODE );
+            if ( ret != 0 && isPrime != 1 ) {
+                ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+                goto cleanup;
+            }
+        }
+    }
+
+#else
+    ((void) f_rng);
+    ((void) p_rng);
+#endif /* MBEDTLS_GENPRIME */
+
+    /*
+     * Step 2: Check that 1 < N = P * Q
+     */
+
+    if( P != NULL && Q != NULL && N != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, P, Q ) );
+        if( mbedtls_mpi_cmp_int( N, 1 )  <= 0 ||
+            mbedtls_mpi_cmp_mpi( &K, N ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /*
+     * Step 3: Check and 1 < D, E < N if present.
+     */
+
+    if( N != NULL && D != NULL && E != NULL )
+    {
+        if ( mbedtls_mpi_cmp_int( D, 1 ) <= 0 ||
+             mbedtls_mpi_cmp_int( E, 1 ) <= 0 ||
+             mbedtls_mpi_cmp_mpi( D, N ) >= 0 ||
+             mbedtls_mpi_cmp_mpi( E, N ) >= 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /*
+     * Step 4: Check that D, E are inverse modulo P-1 and Q-1
+     */
+
+    if( P != NULL && Q != NULL && D != NULL && E != NULL )
+    {
+        if( mbedtls_mpi_cmp_int( P, 1 ) <= 0 ||
+            mbedtls_mpi_cmp_int( Q, 1 ) <= 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+
+        /* Compute DE-1 mod P-1 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, P, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
+        if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+
+        /* Compute DE-1 mod Q-1 */
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, D, E ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &L, Q, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, &L ) );
+        if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+cleanup:
+
+#if defined( MBEDTLS_GENPRIME )
+    mbedtls_rsa_zeroize( pTempBuff, 3*keySizeWords*CC_32BIT_WORD_SIZE/2 );
+    mbedtls_free( pTempBuff );
+#endif
+    mbedtls_mpi_free( &K );
+    mbedtls_mpi_free( &L );
+
+    /* Wrap MPI error codes by RSA check failure error code */
+    if( ret != 0 && ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED )
+    {
+        ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+    }
+
+    return( ret );
+}
+
+#if !defined MBEDTLS_RSA_NO_CRT
+/*
+ * Check that RSA CRT parameters are in accordance with core parameters.
+ */
+static int mbedtls_rsa_validate_crt_alt( const mbedtls_mpi *P,  const mbedtls_mpi *Q,
+                              const mbedtls_mpi *D,  const mbedtls_mpi *DP,
+                              const mbedtls_mpi *DQ, const mbedtls_mpi *QP )
+{
+    int ret = 0;
+
+    mbedtls_mpi K, L;
+    mbedtls_mpi_init( &K );
+    mbedtls_mpi_init( &L );
+
+    /* Check that DP - D == 0 mod P - 1 */
+    if( DP != NULL )
+    {
+        if( P == NULL )
+        {
+            ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+            goto cleanup;
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, P, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DP, D ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
+
+        if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /* Check that DQ - D == 0 mod Q - 1 */
+    if( DQ != NULL )
+    {
+        if( Q == NULL )
+        {
+            ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+            goto cleanup;
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, Q, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &L, DQ, D ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &L, &L, &K ) );
+
+        if( mbedtls_mpi_cmp_int( &L, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+    /* Check that QP * Q - 1 == 0 mod P */
+    if( QP != NULL )
+    {
+        if( P == NULL || Q == NULL )
+        {
+            ret = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+            goto cleanup;
+        }
+
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &K, QP, Q ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &K, &K, 1 ) );
+        MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &K, &K, P ) );
+        if( mbedtls_mpi_cmp_int( &K, 0 ) != 0 )
+        {
+            ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+            goto cleanup;
+        }
+    }
+
+cleanup:
+
+    /* Wrap MPI error codes by RSA check failure error code */
+    if( ret != 0 &&
+        ret != MBEDTLS_ERR_RSA_KEY_CHECK_FAILED &&
+        ret != MBEDTLS_ERR_RSA_BAD_INPUT_DATA )
+    {
+        ret += MBEDTLS_ERR_RSA_KEY_CHECK_FAILED;
+    }
+
+    mbedtls_mpi_free( &K );
+    mbedtls_mpi_free( &L );
+
+    return( ret );
+}
+#endif
+
+/*
+ * Check a public RSA key
+ */
+int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx )
+{
+    if( ctx == NULL || !ctx->N.p || ( ctx->N.s != 1 ) || !ctx->E.p || ( ctx->E.s != 1 ) )
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+
+    /* check oddness */
+    if( ( ctx->N.p[0] & 1 ) == 0 ||
+        ( ctx->E.p[0] & 1 ) == 0 )
+          return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED);
+
+    if( mbedtls_mpi_bitlen( &ctx->N ) < MBEDTLS_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ||
+        mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS )
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+
+
+    if( mbedtls_mpi_bitlen( &ctx->E ) < 2 ||
+        mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+
+    return( 0 );
+}
+
+
+/*
+ * Check for the consistency of all fields in an RSA private key context
+ */
+int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx )
+{
+    if( ctx == NULL )
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+
+    if( mbedtls_rsa_check_pubkey( ctx ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( rsa_check_context_alt( ctx, 1 /* private */, 1 /* blinding */ ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedtls_rsa_validate_params_alt( &ctx->N, &ctx->P, &ctx->Q,
+                                         &ctx->D, &ctx->E, NULL, NULL ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    if( mbedtls_rsa_validate_crt_alt( &ctx->P, &ctx->Q, &ctx->D,
+                                      &ctx->DP, &ctx->DQ, &ctx->QP ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Check if contexts holding a public and private key match
+ */
+int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv )
+{
+    if( mbedtls_rsa_check_pubkey( pub ) != 0 ||
+        mbedtls_rsa_check_privkey( prv ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
+        mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED );
+    }
+
+    return( 0 );
+}
+
+
+static CCError_t convert_mbedtls_md_type_to_cc_rsa_hash_opmode(IN mbedtls_md_type_t mdType,
+                                                    IN  int isRsaHashModeAfter,
+                                                    OUT CCRsaHashOpMode_t * hashOpMode,
+                                                    OUT size_t * hashOutputSizeBytes)
+{
+    switch (mdType)
+    {
+        case MBEDTLS_MD_MD5 :
+            /*MD5 is not recommended in PKCS1 ver 2.1 standard, hence it is not supported*/
+            return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+        case MBEDTLS_MD_SHA1:
+            *hashOpMode = CC_RSA_HASH_SHA1_mode;/*changing the hash mode to CC definition*/
+            *hashOutputSizeBytes = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
+            break;
+        case MBEDTLS_MD_SHA224:
+            *hashOpMode = CC_RSA_HASH_SHA224_mode;
+            *hashOutputSizeBytes = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
+            break;
+        case MBEDTLS_MD_SHA256:
+            *hashOpMode = CC_RSA_HASH_SHA256_mode;
+            *hashOutputSizeBytes = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+            break;
+        case MBEDTLS_MD_SHA384:
+            *hashOpMode = CC_RSA_HASH_SHA384_mode;
+            *hashOutputSizeBytes = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
+            break;
+        case MBEDTLS_MD_SHA512:
+            *hashOpMode = CC_RSA_HASH_SHA512_mode;
+            *hashOutputSizeBytes = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
+            break;
+        default:
+            return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
+    }
+    if (isRsaHashModeAfter)
+    {
+        *hashOpMode += CC_RSA_After_MD5_mode;
+
+    }
+    return CC_OK;
+}
+
+static CCError_t validate_mbedtls_rsa_context_private_key(mbedtls_rsa_context * ctx)
+{
+    CCError_t Error = CC_OK;
+
+    if (ctx == NULL)
+    {
+        GOTO_END( CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR );
+    }
+
+    if (ctx->N.p == NULL)
+    {
+        GOTO_END( CC_RSA_INVALID_MODULUS_POINTER_ERROR );
+    }
+
+    if (ctx->len == 0)
+    {
+        GOTO_END( CC_RSA_INVALID_MODULUS_SIZE );
+    }
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+    if (ctx->D.p == NULL)
+    {
+        GOTO_END( CC_RSA_INVALID_EXPONENT_POINTER_ERROR );
+    }
+#else
+    if (ctx->P.p == NULL)
+        GOTO_END( CC_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR );
+
+    if (ctx->Q.p == NULL)
+        GOTO_END( CC_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR );
+
+    if (ctx->DP.p == NULL)
+        GOTO_END( CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR );
+
+    if (ctx->DQ.p == NULL)
+        GOTO_END( CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR );
+
+    if (ctx->QP.p == NULL)
+        GOTO_END( CC_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR );
+
+#endif
+
+End:
+    return Error;
+}
+
+static CCError_t validate_mbedtls_rsa_context_public_key(mbedtls_rsa_context * ctx)
+{
+    CCError_t Error = CC_OK;
+
+    if (ctx == NULL)
+    {
+        GOTO_END( CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR );
+    }
+
+    /* ...... checking the validity of the exponent pointer ............... */
+    if (ctx->E.p == NULL)
+        GOTO_END( CC_RSA_INVALID_EXPONENT_POINTER_ERROR );
+
+    /* ...... checking the validity of the modulus pointer .............. */
+    if (ctx->N.p == NULL)
+        GOTO_END( CC_RSA_INVALID_MODULUS_POINTER_ERROR );
+
+    if (ctx->len == 0)
+    {
+        GOTO_END( CC_RSA_INVALID_MODULUS_SIZE );
+    }
+
+End:
+    return Error;
+}
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+static CCError_t build_cc_priv_non_crt_key(
+        IN mbedtls_rsa_context *ctx,
+        OUT CCRsaUserPrivKey_t *UserPrivKey_ptr
+        )
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the size in bytes of the modulus buffer from mbedtls_rsa_ctx*/
+    size_t ModulusSize;
+
+    /* the effective size in bits of the modulus buffer */
+    uint32_t ModulusEffectiveSizeInBits;
+
+    /* the size in bytes of the exponent buffers (private and public) from mbedtls_rsa_ctx*/
+    size_t PrivExponentSize, PubExponentSize;
+
+    /* the effective sizes in bits of the private and public exponents */
+    uint32_t PrivExponentEffectiveSizeInBits, PubExponentEffectiveSizeInBits;
+
+    /* the private key database pointer */
+    CCRsaPrivKey_t *PrivKey_ptr;
+
+    /* the Error return code identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+    ModulusSize = mbedtls_mpi_size(&ctx->N);
+    PubExponentSize = mbedtls_mpi_size(&ctx->E);
+    PrivExponentSize = mbedtls_mpi_size(&ctx->D);
+
+    /* ...... checking the validity of the modulus size, private exponent can not be more than 256 bytes .............. */
+    if (ModulusSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        GOTO_END(CC_RSA_INVALID_MODULUS_SIZE);
+
+    if (PrivExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        GOTO_END(CC_RSA_INVALID_EXPONENT_SIZE);
+
+    if (PubExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
+        GOTO_END(CC_RSA_INVALID_EXPONENT_SIZE);
+
+    /* .................. copy the buffers to the key handle structure .... */
+    /* -------------------------------------------------------------------- */
+
+    /* setting the pointer to the key database */
+    PrivKey_ptr = (CCRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+
+    /* clear the private key db */
+    CC_PalMemSetZero(PrivKey_ptr, sizeof(CCRsaPrivKey_t));
+
+    CC_PalMemCopy(PrivKey_ptr->n, ctx->N.p, ModulusSize);
+    CC_PalMemCopy(PrivKey_ptr->PriveKeyDb.NonCrt.d, ctx->D.p, PrivExponentSize);
+
+    /* .................. initializing local variables ................... */
+    /* ------------------------------------------------------------------- */
+
+    /* .......... initializing the effective counters size in bits .......... */
+    ModulusEffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->n, (ModulusSize + 3)/4);
+    PrivExponentEffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.NonCrt.d, (PrivExponentSize + 3) / 4);
+
+    /*  checking the size of the modulus  */
+    if ( ( ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+            ( ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+            ( ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS ) ) {
+        GOTO_CLEANUP(CC_RSA_INVALID_MODULUS_SIZE);
+    }
+
+    /*  verifying the modulus is odd  */
+    if ( (PrivKey_ptr->n[0] & 1UL) == 0 ) {
+        GOTO_CLEANUP(CC_RSA_MODULUS_EVEN_ERROR);
+    }
+
+    /*  checking the priv. exponent size is not 0 in bytes */
+    if ( PrivExponentEffectiveSizeInBits == 0 ) {
+        GOTO_CLEANUP(CC_RSA_INVALID_EXPONENT_SIZE);
+    }
+
+    /* verifying the priv. exponent is less then the modulus */
+    CounterCmpResult =
+        CC_CommonCmpLsWordsUnsignedCounters(PrivKey_ptr->PriveKeyDb.NonCrt.d, (PrivExponentSize+3)/4,
+                PrivKey_ptr->n, (ModulusSize+3)/4);
+
+    if ( CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1 ) {
+        GOTO_CLEANUP(CC_RSA_INVALID_EXPONENT_VAL);
+    }
+
+    /* verifying the priv. exponent is not less then 1 */
+    if ( PrivExponentEffectiveSizeInBits < 32 &&
+            PrivKey_ptr->PriveKeyDb.NonCrt.d[0] < CC_RSA_MIN_PRIV_EXP_VALUE ) {
+        GOTO_CLEANUP(CC_RSA_INVALID_EXPONENT_VAL);
+    }
+
+    /*  checking that the public exponent is an integer between 3 and modulus - 1 */
+    if ( ctx->E.p != NULL ) {
+        CC_PalMemCopy(PrivKey_ptr->PriveKeyDb.NonCrt.e, ctx->E.p, PubExponentSize);
+        PubExponentEffectiveSizeInBits =
+            CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.NonCrt.e, (PubExponentSize+3)/4);
+
+        /* verifying that the exponent is not less than 3 */
+        if (PubExponentEffectiveSizeInBits < 32 &&
+                PrivKey_ptr->PriveKeyDb.NonCrt.e[0] < CC_RSA_MIN_PUB_EXP_VALUE) {
+            GOTO_CLEANUP(CC_RSA_INVALID_EXPONENT_VAL);
+        }
+
+        /* verifying that the public exponent is less than the modulus */
+        CounterCmpResult =
+            CC_CommonCmpLsWordsUnsignedCounters(PrivKey_ptr->PriveKeyDb.NonCrt.e, (PubExponentSize+3)/4,
+                    PrivKey_ptr->n, (ModulusSize+3)/4);
+
+        if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+            GOTO_CLEANUP(CC_RSA_INVALID_EXPONENT_VAL);
+        }
+    } else {
+        PubExponentEffectiveSizeInBits = 0;
+    }
+
+
+    /* ................. building the structure ............................. */
+    /* ---------------------------------------------------------------------- */
+
+    /* set the mode to non CRT mode */
+    PrivKey_ptr->OperationMode = CC_RSA_NoCrt;
+
+    /* set the key source as external */
+    PrivKey_ptr->KeySource = CC_RSA_ExternalKey;
+
+    /* setting the modulus and exponent size in bits */
+    PrivKey_ptr->nSizeInBits                   = ModulusEffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.NonCrt.dSizeInBits = PrivExponentEffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.NonCrt.eSizeInBits = PubExponentEffectiveSizeInBits;
+
+    /* ................ calculate the Barret tag .............. */
+    Error = RsaInitPrivKeyDb(PrivKey_ptr);
+
+    if ( Error != CC_OK ) {
+        GOTO_CLEANUP(CC_RSA_INTERNAL_ERROR);
+    }
+
+    /* ................ set the tag ................ */
+    UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+
+    /* ................. end of the function .................................. */
+    /* ------------------------------------------------------------------------ */
+Cleanup:
+    /* if the structure created is not valid - clear it */
+    if ( Error != CC_OK ) {
+        CC_PalMemSetZero(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+    }
+End:
+    return Error;
+
+}
+
+#else // !defined(MBEDTLS_RSA_NO_CRT)
+static CCError_t build_cc_priv_crt_key(
+        IN mbedtls_rsa_context *ctx,
+        OUT CCRsaUserPrivKey_t *UserPrivKey_ptr
+        )
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the size in bytes of the modulus buffer from mbedtls_rsa_ctx*/
+    size_t ModulusSize;
+
+    /* the effective size in bits of the modulus buffer */
+    uint32_t ModulusEffectiveSizeInBits;
+
+    /* the size in bytes of the exponent buffers (private and public) from mbedtls_rsa_ctx*/
+    //size_t PrivExponentSize, PubExponentSize;
+    size_t   PSize;
+    size_t   QSize;
+    size_t   dPSize;
+    size_t   dQSize;
+    size_t   qInvSize;
+
+    /* the effective size in bits of the modulus factors buffer */
+    uint32_t P_EffectiveSizeInBits;
+    uint32_t Q_EffectiveSizeInBits;
+    uint32_t dP_EffectiveSizeInBits;
+    uint32_t dQ_EffectiveSizeInBits;
+    uint32_t qInv_EffectiveSizeInBits;
+
+    /* the private key database pointer */
+    CCRsaPrivKey_t *PrivKey_ptr;
+
+    /* the Error return code identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+    PSize    = mbedtls_mpi_size(&ctx->P);
+    QSize    = mbedtls_mpi_size(&ctx->Q);
+    dPSize   = mbedtls_mpi_size(&ctx->DP);
+    dQSize   = mbedtls_mpi_size(&ctx->DQ);
+    qInvSize = mbedtls_mpi_size(&ctx->QP);
+    ModulusSize = mbedtls_mpi_size(&ctx->N);
+
+
+    /* checking the input sizes */
+    if (PSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2 ||
+            QSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2) {
+        GOTO_END(CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR);
+    }
+
+    if (dPSize > PSize ||
+            dQSize > QSize ||
+            qInvSize > PSize) {
+        GOTO_END(CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR);
+    }
+
+    /* verifying the first factor exponent is less then the first factor */
+    CounterCmpResult =
+        CC_CommonCmpLsWordsUnsignedCounters(ctx->DP.p, mbedtls_mpi_size_in_words(&ctx->DP), ctx->P.p, mbedtls_mpi_size_in_words(&ctx->P));
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        GOTO_END(CC_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL);
+    }
+
+    /* verifying the second factor exponent is less then the second factor */
+    CounterCmpResult =
+        CC_CommonCmpLsWordsUnsignedCounters(ctx->DQ.p, mbedtls_mpi_size_in_words(&ctx->DQ), ctx->Q.p, mbedtls_mpi_size_in_words(&ctx->Q));
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        GOTO_END(CC_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL);
+    }
+
+    /* verifying the CRT coefficient is less then the first factor */
+    CounterCmpResult =
+        CC_CommonCmpLsWordsUnsignedCounters(ctx->QP.p, mbedtls_mpi_size_in_words(&ctx->QP), ctx->P.p, mbedtls_mpi_size_in_words(&ctx->P));
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        GOTO_END(CC_RSA_INVALID_CRT_COEFF_VAL);
+    }
+
+    /* .................. copy the buffers to the key handle structure .... */
+    /* -------------------------------------------------------------------- */
+
+    /* setting the pointer to the key database */
+    PrivKey_ptr = (CCRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
+
+
+    /* clear the private key db */
+    CC_PalMemSetZero(PrivKey_ptr, sizeof(CCRsaPrivKey_t));
+
+    CC_PalMemCopy(PrivKey_ptr->PriveKeyDb.Crt.P, ctx->P.p, PSize);
+    CC_PalMemCopy(PrivKey_ptr->PriveKeyDb.Crt.Q, ctx->Q.p, QSize);
+    CC_PalMemCopy(PrivKey_ptr->PriveKeyDb.Crt.dP, ctx->DP.p, dPSize);
+    CC_PalMemCopy(PrivKey_ptr->PriveKeyDb.Crt.dQ, ctx->DQ.p, dQSize);
+    CC_PalMemCopy(PrivKey_ptr->PriveKeyDb.Crt.qInv, ctx->QP.p, qInvSize);
+
+    /* .................. initializing local variables ................... */
+    /* ------------------------------------------------------------------- */
+
+    /* .......... initializing the effective counters size in bits .......... */
+    /* initializing the effective counters size in bits */
+    P_EffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.P, (PSize+3)/4);
+
+    Q_EffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.Q, (QSize+3)/4);
+
+    dP_EffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dP, (dPSize+3)/4);
+
+    dQ_EffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dQ, (dQSize+3)/4);
+
+    qInv_EffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.qInv, (qInvSize+3)/4);
+
+
+    /*  the first factor size is not 0 in bits */
+    if (P_EffectiveSizeInBits == 0|| P_EffectiveSizeInBits > 8*PSize) {
+        GOTO_CLEANUP(CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE);
+    }
+
+    /* the second factor size is not 0 in bits */
+    if (Q_EffectiveSizeInBits == 0 || Q_EffectiveSizeInBits > 8*QSize) {
+        GOTO_CLEANUP(CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE);
+    }
+
+    /* checking that sizes of dP, dQ, qInv > 0 */
+    if (dP_EffectiveSizeInBits == 0 || dQ_EffectiveSizeInBits == 0 || qInv_EffectiveSizeInBits == 0) {
+        GOTO_CLEANUP(CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR);
+    }
+
+
+    // The following code is copied from cc_rsa_build.c
+    // For now we don't need as mbedtls_rsa_context contains n
+    // In case this'll change, the code should be used.
+#ifdef MBEDTLS_RSA_PRIVATE_KEY_OPTIMIZED_IMPLEMENTATION
+    /* ............... calculate the modulus N ........................... */
+    /* -------------------------------------------------------------------- */
+
+
+    Error = PkiLongNumMul(PrivKey_ptr->PriveKeyDb.Crt.P, P_EffectiveSizeInBits,
+            PrivKey_ptr->PriveKeyDb.Crt.Q, PrivKey_ptr->n);
+    if ( Error != CC_OK ) {
+        GOTO_CLEANUP(CC_RSA_INTERNAL_ERROR);
+    }
+#else
+    CC_PalMemCopy(PrivKey_ptr->n, ctx->N.p, ModulusSize);
+#endif
+
+    ModulusEffectiveSizeInBits =
+        CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->n, (2*CALC_FULL_32BIT_WORDS(P_EffectiveSizeInBits)));
+
+    /* .................. checking the validity of the counters ............... */
+    /* ------------------------------------------------------------------------ */
+
+    /*  checking the size of the modulus  */
+    if ( ( ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+            ( ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+            ( ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS ) ) {
+        GOTO_CLEANUP(CC_RSA_INVALID_MODULUS_SIZE);
+    }
+
+    /*  verifying the modulus is odd  */
+    if ((PrivKey_ptr->n[0] & 1UL) == 0) {
+        GOTO_CLEANUP(CC_RSA_MODULUS_EVEN_ERROR);
+    }
+
+    if ((P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits) &&
+            (P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits - 1)) {
+        GOTO_CLEANUP(CC_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE);
+    }
+
+
+    /* ................. building the structure ............................. */
+    /* ---------------------------------------------------------------------- */
+
+    /* set the mode to non CRT mode */
+    PrivKey_ptr->OperationMode = CC_RSA_Crt;
+
+    /* set the key source as external */
+    PrivKey_ptr->KeySource = CC_RSA_ExternalKey;
+
+    /* loading to structure the buffer sizes... */
+
+    PrivKey_ptr->PriveKeyDb.Crt.PSizeInBits    = P_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.QSizeInBits    = Q_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.dPSizeInBits   = dP_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.dQSizeInBits   = dQ_EffectiveSizeInBits;
+    PrivKey_ptr->PriveKeyDb.Crt.qInvSizeInBits = qInv_EffectiveSizeInBits;
+    PrivKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;
+
+    /* ................ initialize the low level data .............. */
+    Error = RsaInitPrivKeyDb(PrivKey_ptr);
+
+    if (Error) {
+        GOTO_CLEANUP(CC_RSA_INTERNAL_ERROR);
+    }
+
+    /* ................ set the tag ................ */
+    UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
+
+    /* ................. end of the function .................................. */
+    /* ------------------------------------------------------------------------ */
+Cleanup:
+    /* if the structure created is not valid - clear it */
+    if ( Error != CC_OK ) {
+        CC_PalMemSetZero(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+    }
+End:
+    return Error;
+
+}
+#endif
+
+static CCError_t build_cc_pubkey(
+        IN mbedtls_rsa_context *ctx,
+        OUT CCRsaUserPubKey_t *UserPubKey_ptr)
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* the counter compare result */
+    CCCommonCmpCounter_t CounterCmpResult;
+
+    /* the size in bytes of the modulus buffer from mbedtls_rsa_ctx*/
+    size_t ModulusSize;
+
+    /* the effective size in bits of the modulus buffer */
+    uint32_t ModulusEffectiveSizeInBits;
+
+    /* the size in bytes of the exponent buffer from mbedtls_rsa_ctx*/
+    size_t   ExponentSize;
+
+    /* the effective size in bits of the exponent buffer */
+    uint32_t ExponentEffectiveSizeInBits;
+
+    /* the public key database pointer */
+    CCRsaPubKey_t *PubKey_ptr;
+
+    /* the Error return code identifier */
+    CCError_t Error = CC_OK;
+
+    /* FUNCTION LOGIC */
+    /* ................. checking the validity of the pointer arguments ....... */
+    /* ------------------------------------------------------------------------ */
+
+    CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+    ModulusSize = mbedtls_mpi_size(&ctx->N);
+    ExponentSize = mbedtls_mpi_size(&ctx->E);
+
+    if ((ExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES) ||
+            (ctx->E.n == 0))
+        return CC_RSA_INVALID_EXPONENT_SIZE;
+
+    if ((ModulusSize  > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES) ||
+            (ctx->N.n == 0))
+    {
+        return CC_RSA_INVALID_MODULUS_SIZE;
+    }
+
+    /* .................. copy the buffers to the key handle structure .... */
+    /* -------------------------------------------------------------------- */
+    /* setting the pointer to the key database */
+    PubKey_ptr = ( CCRsaPubKey_t * )UserPubKey_ptr->PublicKeyDbBuff;
+
+    /* clear the public key db */
+    CC_PalMemSetZero( PubKey_ptr, sizeof(CCRsaPubKey_t) );
+    CC_PalMemCopy(PubKey_ptr->n, ctx->N.p, mbedtls_mpi_size(&ctx->N));
+    CC_PalMemCopy(PubKey_ptr->e, ctx->E.p, mbedtls_mpi_size(&ctx->E));
+
+    /* .................. initializing local variables ................... */
+    /* ------------------------------------------------------------------- */
+
+    /* .......... initializing the effective counters size in bits .......... */
+    ModulusEffectiveSizeInBits =  CC_CommonGetWordsCounterEffectiveSizeInBits(PubKey_ptr->n, (ModulusSize+3)/4);
+    ExponentEffectiveSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(PubKey_ptr->e, (ExponentSize+3)/4);
+
+    /* .................. checking the validity of the counters ............... */
+    /* ------------------------------------------------------------------------ */
+    if ( ( ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+            ( ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
+            ( ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS )) {
+        Error = CC_RSA_INVALID_MODULUS_SIZE;
+        goto End;
+    }
+    /*  verifying the modulus is odd  */
+    if ( (PubKey_ptr->n[0] & 1UL) == 0 ) {
+        Error = CC_RSA_MODULUS_EVEN_ERROR;
+        goto End;
+    }
+
+    /*  checking the exponent size is not 0 in bytes */
+    if (ExponentEffectiveSizeInBits == 0) {
+        Error = CC_RSA_INVALID_EXPONENT_SIZE;
+        goto End;
+    }
+
+    /*  verifying the exponent is less then the modulus */
+    CounterCmpResult = CC_CommonCmpLsWordsUnsignedCounters(PubKey_ptr->e, (ExponentSize+3)/4, PubKey_ptr->n, (ModulusSize+3)/4);
+
+    if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /*  verifying the exponent is not less then 3 */
+    if (ExponentEffectiveSizeInBits < 32 && PubKey_ptr->e[0] < CC_RSA_MIN_PUB_EXP_VALUE) {
+        Error = CC_RSA_INVALID_EXPONENT_VAL;
+        goto End;
+    }
+
+    /* ................. building the structure ............................. */
+    /* ---------------------------------------------------------------------- */
+
+    /* setting the modulus and exponent size in bits */
+    PubKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;
+    PubKey_ptr->eSizeInBits = ExponentEffectiveSizeInBits;
+
+    /* ................ initialize the low level data .............. */
+    Error = RsaInitPubKeyDb(PubKey_ptr);
+
+    if ( Error != CC_OK ) {
+        Error = CC_RSA_KEY_GENERATION_FAILURE_ERROR;
+        goto End;
+    }
+
+    /* ................ set the tag ................ */
+    UserPubKey_ptr->valid_tag = CC_RSA_PUB_KEY_VALIDATION_TAG;
+
+    /* ................. end of the function .................................. */
+    /* ------------------------------------------------------------------------ */
+
+End:
+    /* if the structure created is not valid - clear it */
+    if ( Error != CC_OK ) {
+        CC_PalMemSetZero(UserPubKey_ptr, sizeof(CCRsaUserPubKey_t));
+        return Error;
+    }
+
+    return CC_OK;
+
+}/* END OF build_cc_pubkey */
+
+
+
+/*
+ * Do an RSA public key operation
+ */
+int mbedtls_rsa_public( mbedtls_rsa_context *ctx,
+        const unsigned char *input,
+        unsigned char *output )
+{
+#if defined(MBEDTLS_THREADING_C)
+    int ret;
+#endif
+    CCError_t Error = CC_OK;
+    CCRsaUserPubKey_t * UserPubKey_ptr = NULL;
+    CCRsaPrimeData_t * PrimeData_ptr = NULL;
+
+
+    if (ctx == NULL) {
+        Error = CC_RSA_INVALID_PTR_ERROR;
+        goto End;
+    }
+
+#if defined(MBEDTLS_THREADING_C)
+    if ( (ret = mbedtls_mutex_lock(&ctx->mutex) ) != 0)
+        return( ret );
+#endif
+
+    /* ...... checking the validity of the exponent pointer ............... */
+    if (ctx->E.p == NULL)
+        return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
+
+    /* ...... checking the validity of the modulus pointer .............. */
+    if (ctx->N.p == NULL)
+        return CC_RSA_INVALID_MODULUS_POINTER_ERROR;
+
+    UserPubKey_ptr = (CCRsaUserPubKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPubKey_t));
+    if (UserPubKey_ptr == NULL) {
+        Error = CC_OUT_OF_RESOURCE_ERROR;
+        goto End;
+    }
+
+    PrimeData_ptr = (CCRsaPrimeData_t *)mbedtls_calloc(1, sizeof(CCRsaPrimeData_t));
+    if (PrimeData_ptr == NULL) {
+        Error = CC_OUT_OF_RESOURCE_ERROR;
+        goto End;
+    }
+
+    Error = build_cc_pubkey(ctx, UserPubKey_ptr);
+    if ( Error != CC_OK ) {
+        goto End;
+    }
+
+    Error = CC_RsaPrimEncrypt(UserPubKey_ptr, PrimeData_ptr, (unsigned char *)input, ctx->len, output);
+    if ( Error != CC_OK ) {
+        goto End;
+    }
+
+End:
+    mbedtls_zeroize_internal(UserPubKey_ptr, sizeof(CCRsaUserPubKey_t));
+    mbedtls_zeroize_internal(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+    mbedtls_free(PrimeData_ptr);
+    mbedtls_free(UserPubKey_ptr);
+
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PUBLIC);
+}
+
+/*
+ * Do an RSA private key operation
+ */
+int mbedtls_rsa_private( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        const unsigned char *input,
+        unsigned char *output )
+{
+#if defined(MBEDTLS_THREADING_C)
+    int ret;
+#endif
+    CCError_t Error = CC_OK;
+    CCRsaUserPrivKey_t * UserPrivKey_ptr = NULL;
+    CCRsaPrimeData_t * PrimeData_ptr = NULL;
+
+    // f_rng and p_rng are used for blinding, which CC does not support
+    CC_UNUSED_PARAM(f_rng);
+    CC_UNUSED_PARAM(p_rng);
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    /* Make sure we have private key info, prevent possible misuse */
+    if( input == NULL || output == NULL )
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    /* Validate mbedtls_rsa_context for private key actions*/
+    if ( (Error = validate_mbedtls_rsa_context_private_key(ctx)) != 0 )
+    {
+        GOTO_END( Error );
+    }
+
+#if defined(MBEDTLS_THREADING_C)
+    if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 )
+        return( ret );
+#endif
+
+    UserPrivKey_ptr = (CCRsaUserPrivKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPrivKey_t));
+    if ( UserPrivKey_ptr == NULL ) {
+        GOTO_CLEANUP(CC_OUT_OF_RESOURCE_ERROR);
+    }
+
+    PrimeData_ptr = (CCRsaPrimeData_t *)mbedtls_calloc(1, sizeof(CCRsaPrimeData_t));
+    if ( PrimeData_ptr == NULL ) {
+        GOTO_CLEANUP(CC_OUT_OF_RESOURCE_ERROR);
+    }
+
+    // In mbedTLS CRT vs. non-CRT it compilation-time define
+#if defined(MBEDTLS_RSA_NO_CRT)
+    Error = build_cc_priv_non_crt_key(ctx, UserPrivKey_ptr);
+#else
+    Error = build_cc_priv_crt_key(ctx, UserPrivKey_ptr);
+#endif
+    if ( Error != CC_OK ) {
+        GOTO_CLEANUP(Error);
+    }
+
+    Error = CC_RsaPrimDecrypt(UserPrivKey_ptr, PrimeData_ptr, (unsigned char *)input, ctx->len, output);
+    if ( Error != CC_OK ) {
+        GOTO_CLEANUP(Error);
+    }
+Cleanup:
+    if ( Error != CC_OK ) {
+        mbedtls_zeroize_internal(output, ctx->len);
+    }
+    mbedtls_zeroize_internal(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+    mbedtls_zeroize_internal(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+    mbedtls_free(PrimeData_ptr);
+    mbedtls_free(UserPrivKey_ptr);
+End:
+#if defined(MBEDTLS_THREADING_C)
+    if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 )
+        return( MBEDTLS_ERR_THREADING_MUTEX_ERROR );
+#endif
+
+    return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PRIVATE);
+}
+
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
+ */
+int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        const unsigned char *label, size_t label_len,
+        size_t ilen,
+        const unsigned char *input,
+        unsigned char *output )
+{
+    size_t olen;
+    unsigned int hlen;
+    const mbedtls_md_info_t *md_info;
+
+    CCError_t Error = CC_OK;
+    CCRsaUserPubKey_t * UserPubKey_ptr = NULL;
+    CCRsaPrimeData_t * PrimeData_ptr = NULL;
+    CCRndContext_t rndContext;
+    CCRndContext_t *rndContext_ptr = &rndContext;
+    CCRsaHashOpMode_t hashOpMode = CC_RSA_HASH_OpModeLast;
+    size_t hashOutputSizeBytes = 0;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    if( mode != MBEDTLS_RSA_PUBLIC )
+    {
+        GOTO_END( CC_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR );
+    }
+
+    if( input == NULL || output == NULL )
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    if( f_rng == NULL )
+    {
+        GOTO_END( CC_RND_STATE_PTR_INVALID_ERROR );
+    }
+
+    rndContext_ptr->rndState = p_rng;
+    if ( (Error = CC_RndSetGenerateVectorFunc(rndContext_ptr, f_rng)) != CC_OK )
+    {
+        GOTO_END( Error );
+    }
+
+    if ( (Error = validate_mbedtls_rsa_context_public_key(ctx)) != CC_OK )
+    {
+        GOTO_END( Error );
+    }
+
+    if (ctx->padding != MBEDTLS_RSA_PKCS_V21)
+    {
+        GOTO_END( CC_RSA_DATA_POINTER_INVALID_ERROR );
+    }
+
+
+    if ( (Error = convert_mbedtls_md_type_to_cc_rsa_hash_opmode((mbedtls_md_type_t)ctx->hash_id,
+                                               0,     // HashMode - before
+                                               &hashOpMode,
+                                               &hashOutputSizeBytes)) != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+
+    md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );
+    if( md_info == NULL )
+    {
+        GOTO_END( CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR );
+    }
+
+    olen = ctx->len;
+    hlen = mbedtls_md_get_size( md_info );
+
+    /* first comparison checks for overflow */
+    if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 )
+    {
+        GOTO_END( CC_RSA_INVALID_MESSAGE_DATA_SIZE );
+    }
+
+    UserPubKey_ptr = (CCRsaUserPubKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPubKey_t));
+    if (UserPubKey_ptr == NULL) {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+
+    PrimeData_ptr = (CCRsaPrimeData_t *)mbedtls_calloc(1, sizeof(CCRsaPrimeData_t));
+    if (PrimeData_ptr == NULL)
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+
+    Error = build_cc_pubkey(ctx, UserPubKey_ptr);
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+
+    Error = CC_RsaOaepEncrypt(rndContext_ptr,
+                  UserPubKey_ptr,
+                  PrimeData_ptr,
+                  hashOpMode,
+                  (unsigned char *)label, // Need to remove the const-ness
+                  label_len,
+                  CC_PKCS1_MGF1,
+                  (unsigned char *)input, // Need to remove the const-ness
+                  ilen,
+                  output);
+
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+
+Cleanup:
+    if ( Error != CC_OK )
+    {
+        mbedtls_zeroize_internal(output, ctx->len);
+    }
+    mbedtls_zeroize_internal(UserPubKey_ptr, sizeof(CCRsaUserPubKey_t));
+    mbedtls_zeroize_internal(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+    mbedtls_free(PrimeData_ptr);
+    mbedtls_free(UserPubKey_ptr);
+End:
+    return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PUBLIC);
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        size_t ilen,
+        const unsigned char *input,
+        unsigned char *output )
+{
+
+    CCError_t Error = CC_OK;
+    CCRsaUserPubKey_t * UserPubKey_ptr = NULL;
+    CCRsaPrimeData_t * PrimeData_ptr = NULL;
+    CCRndContext_t rndContext;
+    CCRndContext_t *rndContext_ptr = &rndContext;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    if( mode != MBEDTLS_RSA_PUBLIC )
+    {
+        GOTO_END( CC_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR );
+    }
+
+    if( input == NULL || output == NULL )
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    if( f_rng == NULL )
+    {
+        GOTO_END( CC_RND_STATE_PTR_INVALID_ERROR );
+    }
+
+    rndContext_ptr->rndState = p_rng;
+    if ( (Error = CC_RndSetGenerateVectorFunc(rndContext_ptr, f_rng)) != CC_OK )
+        GOTO_END( Error );
+
+    if ( (Error = validate_mbedtls_rsa_context_public_key(ctx)) != CC_OK )
+    {
+        GOTO_END( Error );
+    }
+
+    if ( ctx->padding != MBEDTLS_RSA_PKCS_V15 )
+    {
+        GOTO_END( CC_RSA_DATA_POINTER_INVALID_ERROR );
+    }
+
+    /* first comparison checks for overflow */
+    if( ilen + 11 < ilen || ctx->len < ilen + 11 )
+    {
+        GOTO_END( CC_RSA_INVALID_MESSAGE_DATA_SIZE );
+    }
+
+    UserPubKey_ptr = (CCRsaUserPubKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPubKey_t));
+    if ( UserPubKey_ptr == NULL )
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+
+    PrimeData_ptr = (CCRsaPrimeData_t *)mbedtls_calloc(1, sizeof(CCRsaPrimeData_t));
+    if ( PrimeData_ptr == NULL )
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+
+    Error = build_cc_pubkey(ctx, UserPubKey_ptr);
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+
+    Error = CC_RsaPkcs1V15Encrypt(rndContext_ptr,
+                                  UserPubKey_ptr,
+                                  PrimeData_ptr,
+                                  (unsigned char *)input, // Need to remove the const-ness
+                                  ilen,
+                                  (unsigned char *)output); // Need to remove the const-ness
+
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+
+Cleanup:
+    if ( Error != CC_OK )
+    {
+        mbedtls_zeroize_internal(output, ctx->len);
+    }
+    mbedtls_zeroize_internal(UserPubKey_ptr, sizeof(CCRsaUserPubKey_t));
+    mbedtls_zeroize_internal(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+    mbedtls_free(PrimeData_ptr);
+    mbedtls_free(UserPubKey_ptr);
+End:
+
+    return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PUBLIC);
+}
+
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode, size_t ilen,
+        const unsigned char *input,
+        unsigned char *output )
+{
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen,
+                    input, output );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                    ilen, input, output );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
+ */
+int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        const unsigned char *label, size_t label_len,
+        size_t *olen,
+        const unsigned char *input,
+        unsigned char *output,
+        size_t output_max_len )
+{
+    CCError_t Error = CC_OK;
+    CCRsaUserPrivKey_t * UserPrivKey_ptr = NULL;
+    CCRsaPrimeData_t * PrimeData_ptr = NULL;
+    CCRsaHashOpMode_t hashOpMode = CC_RSA_HASH_OpModeLast;
+    size_t hashOutputSizeBytes = 0;
+
+    // in mbedtls decrypt scheme f_rng and p_rng are used for blinding
+    // CC does not support blinding
+    CC_UNUSED_PARAM(f_rng);
+    CC_UNUSED_PARAM(p_rng);
+
+    // mbedtls supports decryption with public key, CC does not
+    if ( mode != MBEDTLS_RSA_PRIVATE )
+    {
+        GOTO_END( CC_RSA_INVALID_DECRYPRION_MODE_ERROR );
+    }
+
+    if( input == NULL || output == NULL )
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    /* Validate mbedtls_rsa_context for private key actions*/
+    if ( (Error = validate_mbedtls_rsa_context_private_key(ctx)) != CC_OK )
+    {
+        GOTO_END( Error );
+    }
+
+    if ( ctx->padding != MBEDTLS_RSA_PKCS_V21 )
+        GOTO_END( CC_RSA_DATA_POINTER_INVALID_ERROR );
+
+    // Sanity check on input length, not sure it's needed
+    if( ctx->len < 16 || ctx->len > MBEDTLS_MPI_MAX_SIZE )
+    {
+        GOTO_END( CC_RSA_INVALID_MESSAGE_DATA_SIZE );
+    }
+
+    if ( ( Error = convert_mbedtls_md_type_to_cc_rsa_hash_opmode((mbedtls_md_type_t)ctx->hash_id,
+                                               0,    // HashMode - before
+                                               &hashOpMode,
+                                               &hashOutputSizeBytes) ) != CC_OK )
+    {
+        GOTO_END( Error );
+    }
+
+    // checking for integer underflow
+    if( 2 * hashOutputSizeBytes + 2 > ctx->len )
+    {
+        GOTO_END( CC_RSA_INVALID_MESSAGE_DATA_SIZE );
+    }
+
+    UserPrivKey_ptr = (CCRsaUserPrivKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPrivKey_t));
+    if ( UserPrivKey_ptr == NULL )
+    {
+        GOTO_CLEANUP(CC_OUT_OF_RESOURCE_ERROR);
+    }
+
+    PrimeData_ptr = (CCRsaPrimeData_t *)mbedtls_calloc(1, sizeof(CCRsaPrimeData_t));
+    if ( PrimeData_ptr == NULL )
+    {
+        GOTO_CLEANUP(CC_OUT_OF_RESOURCE_ERROR);
+    }
+
+    // In mbedTLS CRT vs. non-CRT it compilation-time define
+#if defined(MBEDTLS_RSA_NO_CRT)
+    Error = build_cc_priv_non_crt_key(ctx, UserPrivKey_ptr);
+#else
+    Error = build_cc_priv_crt_key(ctx, UserPrivKey_ptr);
+#endif
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP(Error);
+    }
+
+    *olen = output_max_len;
+
+    Error = CC_RsaOaepDecrypt(UserPrivKey_ptr,
+                              PrimeData_ptr,
+                              hashOpMode,
+                              (unsigned char *)label, // Need to remove the const-ness
+                              label_len,
+                              CC_PKCS1_MGF1,
+                              (unsigned char *)input, // Need to remove the const-ness
+                              ctx->len,
+                              output,
+                              olen);
+    if ( Error != CC_OK)
+    {
+        GOTO_CLEANUP(Error);
+    }
+
+    if( *olen > output_max_len )
+    {
+        GOTO_CLEANUP( CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE );
+    }
+
+Cleanup:
+    if ( Error != CC_OK )
+    {
+        mbedtls_zeroize_internal(output, ctx->len);
+    }
+    mbedtls_zeroize_internal(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+    mbedtls_zeroize_internal(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+    mbedtls_free(PrimeData_ptr);
+    mbedtls_free(UserPrivKey_ptr);
+End:
+    return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PRIVATE);
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
+ */
+int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        size_t *olen,
+        const unsigned char *input,
+        unsigned char *output,
+        size_t output_max_len)
+{
+    CCError_t Error = CC_OK;
+    CCRsaUserPrivKey_t * UserPrivKey_ptr = NULL;
+    CCRsaPrimeData_t * PrimeData_ptr = NULL;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    // in mbedtls decrypt scheme f_rng and p_rng are used for blinding
+    // CC does not support blinding
+    CC_UNUSED_PARAM(f_rng);
+    CC_UNUSED_PARAM(p_rng);
+
+    // mbedtls supports decryption with public key, CC does not
+    if (mode != MBEDTLS_RSA_PRIVATE)
+    {
+        GOTO_END( CC_RSA_INVALID_DECRYPRION_MODE_ERROR );
+    }
+
+    if( input == NULL || output == NULL )
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+
+    /* Validate mbedtls_rsa_context for private key actions*/
+    if ( (Error = validate_mbedtls_rsa_context_private_key(ctx)) != 0 )
+    {
+        GOTO_END( Error );
+    }
+
+    if( ctx->padding != MBEDTLS_RSA_PKCS_V15 )
+    {
+        GOTO_END( CC_RSA_DATA_POINTER_INVALID_ERROR );
+    }
+
+    // Sanity check on input length, not sure it's needed
+    if( ctx->len < 16 || ctx->len > MBEDTLS_MPI_MAX_SIZE )
+    {
+        GOTO_END( CC_RSA_INVALID_MESSAGE_DATA_SIZE );
+    }
+
+    UserPrivKey_ptr = (CCRsaUserPrivKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPrivKey_t));
+    if ( UserPrivKey_ptr == NULL )
+    {
+        GOTO_CLEANUP(CC_OUT_OF_RESOURCE_ERROR);
+    }
+
+    PrimeData_ptr = (CCRsaPrimeData_t *)mbedtls_calloc(1, sizeof(CCRsaPrimeData_t));
+    if ( PrimeData_ptr == NULL )
+    {
+        GOTO_CLEANUP(CC_OUT_OF_RESOURCE_ERROR);
+    }
+
+    // In mbedTLS CRT vs. non-CRT it compilation-time define
+#if defined(MBEDTLS_RSA_NO_CRT)
+    Error = build_cc_priv_non_crt_key(ctx, UserPrivKey_ptr);
+#else
+    Error = build_cc_priv_crt_key(ctx, UserPrivKey_ptr);
+#endif
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP(Error);
+    }
+
+    *olen = output_max_len;
+
+    Error = CC_RsaPkcs1V15Decrypt(UserPrivKey_ptr,
+                                  PrimeData_ptr,
+                                  (unsigned char *)input, // Need to remove the const-ness
+                                  ctx->len,
+                                  output,
+                                  olen);
+
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP(Error);
+    }
+
+    if( *olen > output_max_len )
+    {
+        GOTO_CLEANUP( CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE );
+    }
+
+Cleanup:
+    if ( Error != CC_OK )
+    {
+        mbedtls_zeroize_internal(output, ctx->len);
+    }
+    mbedtls_zeroize_internal(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
+    mbedtls_zeroize_internal(PrimeData_ptr, sizeof(CCRsaPrimeData_t));
+    mbedtls_free(PrimeData_ptr);
+    mbedtls_free(UserPrivKey_ptr);
+End:
+
+    return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PRIVATE);
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Do an RSA operation, then remove the message padding
+ */
+int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode, size_t *olen,
+        const unsigned char *input,
+        unsigned char *output,
+        size_t output_max_len)
+{
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen,
+                    input, output, output_max_len );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0,
+                    olen, input, output,
+                    output_max_len );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
+ */
+int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        mbedtls_md_type_t md_alg,
+        unsigned int hashlen,
+        const unsigned char *hash,
+        unsigned char *sig )
+{
+
+    CCRndContext_t              rndContext;
+    CCRsaPrivUserContext_t      *UserContext_ptr = NULL;
+    CCRsaUserPrivKey_t          *UserPrivKey_ptr = NULL;
+    CCRsaHashOpMode_t           hashOpMode;
+    size_t                      hashOutputSizeBytes;
+    size_t                      sig_size;
+    CCError_t                   Error = CC_OK;
+
+    CC_UNUSED_PARAM( hashlen );        /* message digest length (for MBEDTLS_MD_NONE only which is not supported.) */
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+    if (mode != MBEDTLS_RSA_PRIVATE) /* In cryptocell only private key operations are allowed with sign */
+    {
+        GOTO_END( CC_RSA_WRONG_PRIVATE_KEY_TYPE );
+    }
+    if ( NULL == sig || NULL == hash )
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+    if ( MBEDTLS_MD_NONE == md_alg )
+    {
+        mbedtls_printf( "\nERROR: MBEDTLS_MD_NONE is not supported! \n" );
+        GOTO_END(CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR); /* MD_NONE is not supported in cryptocell */
+    }
+        /* The hash_id in the RSA context is the one used for the
+        encoding. md_alg in the function call is the type of hash
+        that is encoded. According to RFC 3447 it is advised to keep
+        both hashes the same. */
+    if ( md_alg != ( mbedtls_md_type_t ) ctx->hash_id )
+    {
+        GOTO_END( CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR );
+    }
+    Error = convert_mbedtls_md_type_to_cc_rsa_hash_opmode( md_alg,
+                                                           1, // After hash.
+                                                           &hashOpMode,
+                                                           &hashOutputSizeBytes );
+    if ( CC_OK!= Error )
+    {
+        GOTO_END( Error );
+    }
+
+    rndContext.rndState = p_rng;
+    if ( ( Error = CC_RndSetGenerateVectorFunc(&rndContext, f_rng)) != CC_OK )
+    {
+        GOTO_END( Error );
+    }
+
+    UserPrivKey_ptr = ( CCRsaUserPrivKey_t * )mbedtls_calloc( 1, sizeof(CCRsaUserPrivKey_t ) );
+    if ( NULL == UserPrivKey_ptr )
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    UserContext_ptr = ( CCRsaPrivUserContext_t * )mbedtls_calloc( 1, sizeof(CCRsaPrivUserContext_t ) );
+    if ( NULL == UserContext_ptr )
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    if ( (Error = validate_mbedtls_rsa_context_private_key( ctx ) ) != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+#if defined(MBEDTLS_RSA_NO_CRT)
+    Error = build_cc_priv_non_crt_key( ctx, UserPrivKey_ptr );
+#else
+    Error = build_cc_priv_crt_key( ctx, UserPrivKey_ptr );
+#endif
+    if ( CC_OK != Error )
+    {
+        GOTO_CLEANUP( Error );
+    }
+
+    sig_size = mbedtls_mpi_size( ( const mbedtls_mpi *)&( ctx->N ) );
+
+    Error = CC_RsaPssSign( &rndContext,
+        UserContext_ptr,
+        UserPrivKey_ptr,
+        hashOpMode,
+        CC_PKCS1_MGF1,
+        hashOutputSizeBytes,
+        ( uint8_t * )hash,
+        hashOutputSizeBytes,
+        ( uint8_t * )sig,
+        &sig_size );
+Cleanup:
+        mbedtls_free( UserPrivKey_ptr );
+        mbedtls_free( UserContext_ptr );
+End:
+        return error_mapping_cc_to_mbedtls_rsa( Error, CC_RSA_OP_PRIVATE );
+}
+
+
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function
+ */
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        mbedtls_md_type_t md_alg,
+        unsigned int hashlen,
+        const unsigned char *hash,
+        unsigned char *sig )
+{
+    CCRndContext_t              rndContext;
+    CCRsaPrivUserContext_t      *UserContext_ptr = NULL;
+    CCRsaUserPrivKey_t          *UserPrivKey_ptr = NULL;
+    CCRsaHashOpMode_t           hashOpMode;
+    size_t                      hashOutputSizeBytes;
+    size_t                      sig_size;
+    CCError_t                   Error = CC_OK;
+
+    CC_UNUSED_PARAM(hashlen); /* message digest length (for MBEDTLS_MD_NONE only which is not supported.) */
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+    if (mode != MBEDTLS_RSA_PRIVATE) /* In cryptocell only private key operations are allowed with sign */
+    {
+        GOTO_END( CC_RSA_WRONG_PRIVATE_KEY_TYPE );
+    }
+    if (NULL == sig || NULL == hash)
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+    if ( MBEDTLS_MD_NONE == md_alg )
+    {
+        printf("\nDVIR: ERROR: MBEDTLS_MD_NONE is not supported! \n");
+        GOTO_END(CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR); /* MD_NONE is not supported in cryptocell */
+    }
+    Error = convert_mbedtls_md_type_to_cc_rsa_hash_opmode(md_alg,
+                                                           1, // After hash.
+                                                           &hashOpMode,
+                                                           &hashOutputSizeBytes);
+    if (Error != CC_OK)
+    {
+        GOTO_END(Error);
+    }
+
+    rndContext.rndState = p_rng;
+    if ( (Error = CC_RndSetGenerateVectorFunc(&rndContext, f_rng)) != CC_OK)
+    {
+        GOTO_END(Error);
+    }
+
+    UserPrivKey_ptr = (CCRsaUserPrivKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPrivKey_t));
+    if (NULL == UserPrivKey_ptr)
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    UserContext_ptr = (CCRsaPrivUserContext_t *)mbedtls_calloc(1, sizeof(CCRsaPrivUserContext_t));
+    if (NULL == UserContext_ptr)
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    if ( (Error = validate_mbedtls_rsa_context_private_key(ctx)) != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+#if defined(MBEDTLS_RSA_NO_CRT)
+    Error = build_cc_priv_non_crt_key(ctx, UserPrivKey_ptr);
+#else
+    Error = build_cc_priv_crt_key(ctx, UserPrivKey_ptr);
+#endif
+    if ( Error != CC_OK )
+    {
+        GOTO_CLEANUP(Error);
+    }
+
+    sig_size = mbedtls_mpi_size( (const mbedtls_mpi *)&(ctx->N) );
+    Error = CC_RsaPkcs1V15Sign(&rndContext,
+        UserContext_ptr,
+        UserPrivKey_ptr,
+        hashOpMode,
+        (uint8_t *)hash,
+        hashOutputSizeBytes,
+        (uint8_t *)sig,
+        &sig_size);
+
+Cleanup:
+        mbedtls_free(UserPrivKey_ptr);
+        mbedtls_free(UserContext_ptr);
+End:
+        return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PRIVATE);
+        }
+
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        mbedtls_md_type_t md_alg,
+        unsigned int hashlen,
+        const unsigned char *hash,
+        unsigned char *sig )
+{
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg,
+                    hashlen, hash, sig );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg,
+                    hashlen, hash, sig );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+#if defined(MBEDTLS_PKCS1_V21)
+/*
+ * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
+ */
+int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,
+                               int (*f_rng)(void *, unsigned char *, size_t),
+                               void *p_rng,
+                               int mode,
+                               mbedtls_md_type_t md_alg,
+                               unsigned int hashlen,
+                               const unsigned char *hash,
+                               mbedtls_md_type_t mgf1_hash_id,
+                               int expected_salt_len,
+                               const unsigned char *sig )
+{
+    CCRsaPubUserContext_t        *UserContext_ptr = NULL;
+    CCRsaUserPubKey_t            *UserPubKey_ptr = NULL;
+    CCRsaHashOpMode_t            hashOpMode;
+    int                          saltLen = CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN;
+    CCError_t Error = CC_OK;
+    mbedtls_md_type_t mdType;
+
+    CC_UNUSED_PARAM(f_rng);
+    CC_UNUSED_PARAM(p_rng);
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_WRONG_PRIVATE_KEY_TYPE );
+    }
+
+    if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) /* In cryptocell only public key operations are allowed with verify */
+    {
+        GOTO_END( CC_RSA_WRONG_PRIVATE_KEY_TYPE );
+    }
+    if (NULL == sig || NULL == hash)
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    if (( md_alg != MBEDTLS_MD_NONE ) && ( mgf1_hash_id != MBEDTLS_MD_NONE ) && (md_alg != mgf1_hash_id)){
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    mdType = ( md_alg != MBEDTLS_MD_NONE )? md_alg : mgf1_hash_id;
+
+    //if md_alg == MD_NONE, use mgf1_hash_id, if no -> md_alg=mgf1_hash_id
+    Error = convert_mbedtls_md_type_to_cc_rsa_hash_opmode(mdType,
+                                                          1,
+                                                          &hashOpMode,
+                                                          &hashlen);
+    if (Error != CC_OK)
+    {
+        GOTO_END(Error);
+    }
+    if (expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY)
+    {
+        saltLen = expected_salt_len;
+    }
+    UserPubKey_ptr = (CCRsaUserPubKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPubKey_t));
+    if (NULL == UserPubKey_ptr)
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    UserContext_ptr = (CCRsaPubUserContext_t *)mbedtls_calloc(1, sizeof(CCRsaPubUserContext_t));
+    if (NULL == UserContext_ptr)
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    if ( (Error = validate_mbedtls_rsa_context_public_key(ctx)) != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+    Error = build_cc_pubkey(ctx, UserPubKey_ptr);
+    if (CC_OK != Error)
+    {
+        GOTO_CLEANUP(Error);
+    }
+
+    Error = CC_RsaPssVerify(UserContext_ptr,UserPubKey_ptr,hashOpMode,CC_PKCS1_MGF1,saltLen, (uint8_t *)hash, hashlen, (uint8_t *)sig);
+
+Cleanup:
+        mbedtls_free(UserPubKey_ptr);
+        mbedtls_free(UserContext_ptr);
+End:
+        return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PUBLIC);
+}
+
+/*
+ * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function
+ */
+int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        mbedtls_md_type_t md_alg,
+        unsigned int hashlen,
+        const unsigned char *hash,
+        const unsigned char *sig )
+{
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    if (( ctx->hash_id != MBEDTLS_MD_NONE ) && ((mbedtls_md_type_t) ctx->hash_id != md_alg)){
+            return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+    }
+    return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,
+                md_alg, hashlen, hash,
+                md_alg, MBEDTLS_RSA_SALT_LEN_ANY,
+                sig ) );
+
+}
+#endif /* MBEDTLS_PKCS1_V21 */
+
+#if defined(MBEDTLS_PKCS1_V15)
+int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        mbedtls_md_type_t md_alg,
+        unsigned int hashlen,
+        const unsigned char *hash,
+        const unsigned char *sig )
+{
+    CCRsaPubUserContext_t        *UserContext_ptr = NULL;
+    CCRsaUserPubKey_t            *UserPubKey_ptr = NULL;
+    CCRsaHashOpMode_t            hashOpMode;
+    size_t                       hashOutputSizeBytes = 0;
+    CCError_t                    Error = CC_OK;
+
+    CC_UNUSED_PARAM(f_rng);
+    CC_UNUSED_PARAM(p_rng);
+    /* Check input parameters */
+    if (ctx == NULL){
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+
+    if ( MBEDTLS_MD_NONE == md_alg )
+    {
+        GOTO_END(CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR); /* MD_NONE is not supported in cryptocell */
+    }
+    Error = convert_mbedtls_md_type_to_cc_rsa_hash_opmode(md_alg,
+                                                           1,
+                                                           &hashOpMode,
+                                                           &hashOutputSizeBytes);
+    if (Error != CC_OK)
+    {
+        GOTO_END(Error);
+    }
+    if ( hashOutputSizeBytes != hashlen )
+    {
+        hashlen = hashOutputSizeBytes;
+    }
+    if (mode != MBEDTLS_RSA_PUBLIC) /* In cryptocell only public key operations are allowed with verify */
+    {
+        GOTO_END( CC_RSA_WRONG_PRIVATE_KEY_TYPE );
+    }
+    if (NULL == sig || NULL == hash)
+    {
+        GOTO_END( CC_RSA_INVALID_PTR_ERROR );
+    }
+    UserPubKey_ptr = (CCRsaUserPubKey_t *)mbedtls_calloc(1, sizeof(CCRsaUserPubKey_t));
+    if (NULL == UserPubKey_ptr)
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    UserContext_ptr = (CCRsaPubUserContext_t *)mbedtls_calloc(1, sizeof(CCRsaPubUserContext_t));
+    if (NULL == UserContext_ptr)
+    {
+        GOTO_CLEANUP( CC_OUT_OF_RESOURCE_ERROR );
+    }
+    if ( (Error = validate_mbedtls_rsa_context_public_key(ctx)) != CC_OK )
+    {
+        GOTO_CLEANUP( Error );
+    }
+    Error = build_cc_pubkey(ctx, UserPubKey_ptr);
+    if (CC_OK != Error)
+    {
+        GOTO_CLEANUP(Error);
+    }
+    Error = CC_RsaPkcs1V15Verify(UserContext_ptr,
+                                    UserPubKey_ptr,
+                                    hashOpMode,
+                                    (uint8_t *)hash,
+                                    hashlen,
+                                    (uint8_t *)sig);
+Cleanup:
+    mbedtls_free(UserPubKey_ptr);
+    mbedtls_free(UserContext_ptr);
+End:
+    return error_mapping_cc_to_mbedtls_rsa(Error, CC_RSA_OP_PUBLIC);
+
+}
+#endif /* MBEDTLS_PKCS1_V15 */
+
+/*
+ * Do an RSA operation and check the message digest
+ */
+int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx,
+        int (*f_rng)(void *, unsigned char *, size_t),
+        void *p_rng,
+        int mode,
+        mbedtls_md_type_t md_alg,
+        unsigned int hashlen,
+        const unsigned char *hash,
+        const unsigned char *sig )
+{
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    switch( ctx->padding )
+    {
+#if defined(MBEDTLS_PKCS1_V15)
+        case MBEDTLS_RSA_PKCS_V15:
+            return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg,
+                    hashlen, hash, sig );
+#endif
+
+#if defined(MBEDTLS_PKCS1_V21)
+        case MBEDTLS_RSA_PKCS_V21:
+            return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg,
+                    hashlen, hash, sig );
+#endif
+
+        default:
+            return( MBEDTLS_ERR_RSA_INVALID_PADDING );
+    }
+}
+
+/*
+ * Copy the components of an RSA key
+ */
+int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src )
+{
+    int ret;
+
+    if ((dst == NULL) || (src == NULL)){
+        return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+    }
+
+    dst->ver = src->ver;
+    dst->len = src->len;
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->NP, &src->NP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->BPP, &src->BPP ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->BQP, &src->BQP ) );
+
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) );
+    MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) );
+
+    dst->padding = src->padding;
+    dst->hash_id = src->hash_id;
+
+cleanup:
+    if( ret != 0 )
+        mbedtls_rsa_free( dst );
+
+    return( ret );
+}
+
+/*
+ * Free the components of an RSA key
+ */
+void mbedtls_rsa_free( mbedtls_rsa_context *ctx )
+{
+    if (ctx != NULL) {
+        mbedtls_mpi_free( &ctx->BQP ); mbedtls_mpi_free( &ctx->BPP ); mbedtls_mpi_free( &ctx->NP );
+        mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf );
+        mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->RN );
+        mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); mbedtls_mpi_free( &ctx->DP );
+        mbedtls_mpi_free( &ctx->Q  ); mbedtls_mpi_free( &ctx->P  ); mbedtls_mpi_free( &ctx->D );
+        mbedtls_mpi_free( &ctx->E  ); mbedtls_mpi_free( &ctx->N  );
+
+#if defined(MBEDTLS_THREADING_C)
+        mbedtls_mutex_free( &ctx->mutex );
+#endif
+    }
+}
+/**************************************************************************************/
+int mbedtls_rsa_import( mbedtls_rsa_context *ctx,
+                        const mbedtls_mpi *N,
+                        const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                        const mbedtls_mpi *D, const mbedtls_mpi *E )
+{
+    int ret;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    if( ( N != NULL && ( ret = mbedtls_mpi_copy( &ctx->N, N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedtls_mpi_copy( &ctx->P, P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedtls_mpi_copy( &ctx->Q, Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedtls_mpi_copy( &ctx->D, D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedtls_mpi_copy( &ctx->E, E ) ) != 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+
+    if( N != NULL )
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+
+    return( 0 );
+}
+
+int mbedtls_rsa_import_raw( mbedtls_rsa_context *ctx,
+                            unsigned char const *N, size_t N_len,
+                            unsigned char const *P, size_t P_len,
+                            unsigned char const *Q, size_t Q_len,
+                            unsigned char const *D, size_t D_len,
+                            unsigned char const *E, size_t E_len )
+{
+    int ret = 0;
+
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    if( N != NULL )
+    {
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->N, N, N_len ) );
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+    }
+
+    if( P != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    if( ret != 0 )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+
+    return( 0 );
+}
+
+/*
+ * calculate crt parameters from the non crt
+ * input - non crt key params P, Q, D
+ * output - crt params DP, DQ, QP
+ */
+static int mbedtls_alt_rsa_deduce_crt( const mbedtls_mpi *P, const mbedtls_mpi *Q,
+                            const mbedtls_mpi *D, mbedtls_mpi *DP,
+                            mbedtls_mpi *DQ, mbedtls_mpi *QP )
+{
+    int ret = 0;
+
+    const uint32_t rP =0;
+    const uint32_t regNp = 1;
+    const uint32_t rQ = 2;
+    const uint32_t rT1 = 3;
+    const uint32_t rT2 = 4;
+    const uint32_t rT3 = 5;
+    const uint32_t rD = 6;
+
+    uint32_t regCount = 7;
+
+    uint32_t* pTempBuf;
+    uint32_t tempBufSize;
+    uint32_t sizeBitsP;
+
+    if ((DP == NULL) || (DQ == NULL) || (QP == NULL) || (P == NULL) || (Q == NULL) || (D == NULL)){
+            return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
+    }
+
+    tempBufSize = P->n;
+    sizeBitsP = P->n*sizeof(uint32_t)*8;
+
+    ret = PkaInitAndMutexLock(2*sizeBitsP, &regCount);
+    if (ret != 0)
+    {
+            return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+    }
+
+    if( ( pTempBuf = (uint32_t*)mbedtls_calloc( tempBufSize, sizeof(uint32_t) ) ) == NULL ) {
+        ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
+        return( ret);
+    }
+
+    PKA_SET_REG_SIZE(sizeBitsP, PLEN_ID);
+    PkaCopyDataIntoPkaReg(rP, REG_LEN_ID, P->p, P->n);
+    PkaCopyDataIntoPkaReg(rQ, REG_LEN_ID, Q->p, Q->n);
+    PkaCopyDataIntoPkaReg(rD, REG_LEN_ID, D->p, D->n);
+
+    ret = PkaCalcNpIntoPkaReg(PLEN_ID, sizeBitsP, rP/*regN*/, regNp,  rT1, rT2 );
+    if (ret != 0)
+    {
+            ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
+            goto cleanup;
+    }
+
+    /* DP = D mod P-1 */
+    PKA_COPY(REG_LEN_ID, rT1, rD);     // rT1 = D
+    PKA_SUB_IM(MOD_LEN_ID, rP, rP, 1); // P -= 1 (rP)
+    PKA_DIV(MOD_LEN_ID, rT2, rT1, rP); // DP = rT1 = rT1 mod P
+
+    /* DQ = D mod Q-1 */
+    PKA_COPY(REG_LEN_ID, rT2, rD);     // rT2 = D
+    PKA_SUB_IM(MOD_LEN_ID, rQ, rQ, 1); // Q -= 1 (rQ)
+    PKA_DIV(MOD_LEN_ID, rT3, rT2, rQ); // DQ = rT2 = rT2 mod Q
+
+    /* QP = Q^{-1} mod P */
+    PKA_ADD_IM(MOD_LEN_ID, rP, rP, 1);
+    PKA_ADD_IM(MOD_LEN_ID, rQ, rQ, 1);
+    PKA_SUB_IM(MOD_LEN_ID, rD, rP, 2); // temporary rD = P-2
+    PKA_MOD_EXP(PLEN_ID, rT3/*res*/, rQ, rD);  // QP = rT3 = 1/Q mod P
+    PkaCopyDataFromPkaReg(pTempBuf, P->n, rT1);
+    MBEDTLS_MPI_CHK(mbedtls_rsa_uint32_buf_to_mpi( DP, pTempBuf, P->n ));
+
+    PkaCopyDataFromPkaReg(pTempBuf, P->n, rT2);
+    MBEDTLS_MPI_CHK(mbedtls_rsa_uint32_buf_to_mpi( DQ, pTempBuf, P->n ));
+
+    PkaCopyDataFromPkaReg (pTempBuf, P->n, rT3);
+    MBEDTLS_MPI_CHK(mbedtls_rsa_uint32_buf_to_mpi( QP, pTempBuf, P->n ));
+
+cleanup:
+    PkaFinishAndMutexUnlock(regCount);
+    mbedtls_free(pTempBuf);
+    return ret;
+}
+
+int mbedtls_rsa_complete( mbedtls_rsa_context *ctx )
+{
+    int ret = 0;
+
+    int have_N;
+    int have_P;
+    int have_Q;
+    int have_D;
+    int have_E;
+    int have_DP;
+    int have_DQ;
+    int have_QP;
+
+    /*
+    * 1. The user may insert N, D, E and the complete function will not derive the P and Q from it.
+    * 2. If user inserted P, Q it means he wants to work in CRT mode:
+    * we will derive the CRT values from it, we will not derive the D from it.
+    * 3. If user inserted D, it means he wants to work in NON SRT mode:
+    * we will not derive P, Q from it
+    * 4. If N is missing, wi'll calculated it if there is enough information, but it will be done by sw with lower performance
+    */
+
+    int is_priv;
+
+    int is_pub;
+    int crt_missing;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+
+    have_N = mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0;
+    have_P = mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0;
+    have_Q = mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0;
+    have_D = mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0;
+    have_E = mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+    have_DP = mbedtls_mpi_cmp_int( &ctx->DP, 0 ) != 0;
+    have_DQ = mbedtls_mpi_cmp_int( &ctx->DQ, 0 ) != 0;
+    have_QP = mbedtls_mpi_cmp_int( &ctx->QP, 0 ) != 0;
+
+    /*
+    * 1. The user may insert N, D, E and the complete function will not derive the P and Q from it.
+    * 2. If user inserted P, Q it means he wants to work in CRT mode:
+    * we will derive the CRT values from it, we will not derive the D from it.
+    * 3. If user inserted D, it means he wants to work in NON SRT mode:
+    * we will not derive P, Q from it
+    * 4. If N is missing, wi'll calculated it if there is enough information, but it will be done by sw with lower performance
+    */
+
+#if defined(MBEDTLS_RSA_NO_CRT)
+    is_priv    =   have_D && have_E && (have_N || (have_P && have_Q));
+#else
+    is_priv    =   have_D && have_E && have_P && have_Q;
+#endif
+    is_pub     =   have_N && !have_P && !have_Q && !have_D && have_E;
+    crt_missing =  !have_DP && !have_DQ && !have_QP;
+
+
+    if( !is_priv && !is_pub ){
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /* Function should get or all DP,QP and DQ or no one of them*/
+    if (((!have_DP) || (!have_DQ) || (!have_QP)) && (!crt_missing)){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+    /*
+     * Step 1: Deduce N if P, Q are provided.
+     */
+
+    //if N is requested to be calculated from P and Q, it will be done by sw
+    if( !have_N && have_P && have_Q )
+    {
+        if( ( ret = mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P,
+                                         &ctx->Q ) ) != 0 )
+        {
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+        }
+
+        ctx->len = mbedtls_mpi_size( &ctx->N );
+    }
+
+    /*
+     * Step 2: Deduce all additional parameters specific
+     *         to our current RSA implementation.
+     */
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+
+    if (( is_priv ) && (crt_missing))
+    {
+        ret = mbedtls_alt_rsa_deduce_crt( &ctx->P,  &ctx->Q,  &ctx->D,
+                                      &ctx->DP, &ctx->DQ, &ctx->QP );
+        if( ret != 0 )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#endif /* MBEDTLS_RSA_NO_CRT */
+
+    /*
+     * Step 3: Basic sanity checks
+     */
+
+    return( rsa_check_context_alt( ctx, is_priv, 1 ) );
+}
+
+int mbedtls_rsa_export_raw( const mbedtls_rsa_context *ctx,
+                            unsigned char *N, size_t N_len,
+                            unsigned char *P, size_t P_len,
+                            unsigned char *Q, size_t Q_len,
+                            unsigned char *D, size_t D_len,
+                            unsigned char *E, size_t E_len )
+{
+    int ret = 0;
+    int is_priv;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /* Check if key is private or public */
+    is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+    {
+        /* If we're trying to export private parameters for a public key,
+         * something must be wrong. */
+        if( P != NULL || Q != NULL || D != NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    if( N != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->N, N, N_len ) );
+
+    if( P != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->P, P, P_len ) );
+
+    if( Q != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->Q, Q, Q_len ) );
+
+    if( D != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->D, D, D_len ) );
+
+    if( E != NULL )
+        MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->E, E, E_len ) );
+
+cleanup:
+
+    return( ret );
+}
+
+int mbedtls_rsa_export( const mbedtls_rsa_context *ctx,
+                        mbedtls_mpi *N, mbedtls_mpi *P, mbedtls_mpi *Q,
+                        mbedtls_mpi *D, mbedtls_mpi *E )
+{
+    int ret = 0;
+    int is_priv;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /* Check if key is private or public */
+    is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+   if( !is_priv )
+    {
+        /* If we're trying to export private parameters for a public key,
+         * something must be wrong. */
+        if( P != NULL || Q != NULL || D != NULL )
+            return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+    }
+
+    /* Export all requested core parameters. */
+    if( ( N != NULL && ( ret = mbedtls_mpi_copy( N, &ctx->N ) ) != 0 ) ||
+        ( P != NULL && ( ret = mbedtls_mpi_copy( P, &ctx->P ) ) != 0 ) ||
+        ( Q != NULL && ( ret = mbedtls_mpi_copy( Q, &ctx->Q ) ) != 0 ) ||
+        ( D != NULL && ( ret = mbedtls_mpi_copy( D, &ctx->D ) ) != 0 ) ||
+        ( E != NULL && ( ret = mbedtls_mpi_copy( E, &ctx->E ) ) != 0 ) )
+    {
+        return( ret );
+    }
+
+    return( ret );
+}
+
+int mbedtls_rsa_export_crt( const mbedtls_rsa_context *ctx,
+                            mbedtls_mpi *DP, mbedtls_mpi *DQ, mbedtls_mpi *QP )
+{
+    int ret = 0;
+    int is_priv;
+
+    /* Check input parameters */
+    if (ctx == NULL){
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+    }
+
+    /* Check if key is private or public */
+    is_priv =
+        mbedtls_mpi_cmp_int( &ctx->N, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->P, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->Q, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->D, 0 ) != 0 &&
+        mbedtls_mpi_cmp_int( &ctx->E, 0 ) != 0;
+
+    if( !is_priv )
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+
+#if !defined(MBEDTLS_RSA_NO_CRT)
+    /* Export all requested blinding parameters. */
+    if( ( DP != NULL && ( ret = mbedtls_mpi_copy( DP, &ctx->DP ) ) != 0 ) ||
+        ( DQ != NULL && ( ret = mbedtls_mpi_copy( DQ, &ctx->DQ ) ) != 0 ) ||
+        ( QP != NULL && ( ret = mbedtls_mpi_copy( QP, &ctx->QP ) ) != 0 ) )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#else
+    if( ( ret = mbedtls_alt_rsa_deduce_crt( &ctx->P, &ctx->Q, &ctx->D,
+                                        DP, DQ, QP ) ) != 0 )
+    {
+        return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA + ret );
+    }
+#endif
+
+    return( 0 );
+}
+
+/*
+ * Get length in bytes of RSA modulus. If ctx is NULL the length output will be 0
+ */
+
+size_t mbedtls_rsa_get_len( const mbedtls_rsa_context *ctx )
+{
+    if (ctx == NULL){
+        return 0;
+    }
+
+    return( ctx->len );
+}
+
+/**************************************************************************************/
+
+#endif /*  defined (MBEDTLS_RSA_ALT)  */
+
+#endif /*  defined(MBEDTLS_RSA_C)  */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/sha1_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/sha1_alt.c
new file mode 100644
index 0000000..2523ebb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/sha1_alt.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "sha1_alt.h"
+#include "hash_driver.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_log.h"
+#include "cc_pal_abort.h"
+#include "mbedtls_hash_common.h"
+#include <stdio.h>
+
+#if defined(MBEDTLS_SHA1_ALT) && defined(MBEDTLS_SHA1_C)
+
+/* Internal function*/
+
+void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
+{
+    if( NULL == ctx  )
+    {
+        CC_PalAbort("\nctx is NULL\n");
+    }
+    CC_PalMemSetZero(ctx, sizeof( mbedtls_sha1_context ) );
+}
+
+void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
+{
+    if( NULL == ctx  )
+    {
+        CC_PAL_LOG_ERR("\nctx is NULL\n");
+        return;
+    }
+    mbedtls_zeroize_internal( ctx, sizeof( mbedtls_sha1_context ) );
+}
+
+void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
+                         const mbedtls_sha1_context *src )
+{
+    if( NULL == src || NULL == dst )
+    {
+        CC_PalAbort("src or dst are NULL\n" );
+    }
+
+    *dst = *src;
+}
+
+int mbedtls_sha1_starts_ret( mbedtls_sha1_context *ctx )
+{
+    int ret;
+
+    ret = mbedtls_sha_starts_internal( ctx, HASH_SHA1);
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED );
+    }
+
+    return( ret );
+}
+
+int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
+{
+    int ret;
+
+    ret = mbedtls_sha_process_internal( ctx, data );
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED );
+    }
+
+    return( ret );
+}
+
+
+/*
+ * SHA-1 process buffer
+ */
+int mbedtls_sha1_update_ret( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
+{
+    int ret;
+
+    ret = mbedtls_sha_update_internal( ctx, input, ilen );
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED );
+    }
+
+    return( ret );
+}
+
+
+/*
+ * SHA-1 final digest
+ */
+int mbedtls_sha1_finish_ret( mbedtls_sha1_context *ctx, unsigned char output[20] )
+{
+    int ret;
+
+    HashContext_t *pHashCtx = NULL;
+    if (NULL == ctx || NULL == output ){
+        CC_PAL_LOG_ERR( "ctx or output buffer are NULL\n" );
+        return( MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED );
+    }
+    pHashCtx = (HashContext_t *)ctx;
+
+    ret = mbedtls_sha_finish_internal( ctx );
+    if( ret != 0)
+    {
+        return( MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED );
+    }
+
+    CC_PalMemCopy(output, pHashCtx->digest, SHA1_DIGEST_SIZE_IN_BYTES);
+
+    return( ret );
+}
+#endif /* #if defined(MBEDTLS_SHA1_ALT) && defined(MBEDTLS_SHA1_C) */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/sha256_alt.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/sha256_alt.c
new file mode 100644
index 0000000..4b9c29e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/sha256_alt.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "sha256_alt.h"
+#include "hash_driver.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_log.h"
+#include "cc_pal_abort.h"
+#include "mbedtls_hash_common.h"
+#include <stdio.h>
+
+#if defined(MBEDTLS_SHA256_ALT) && defined(MBEDTLS_SHA256_C)
+
+
+void mbedtls_sha256_init( mbedtls_sha256_context *ctx )
+{
+    if( NULL == ctx  )
+    {
+        CC_PalAbort("\nctx is NULL\n");
+    }
+    CC_PalMemSetZero(ctx, sizeof( mbedtls_sha256_context ) );
+}
+
+void mbedtls_sha256_free( mbedtls_sha256_context *ctx )
+{
+    if( NULL == ctx  )
+    {
+        CC_PAL_LOG_ERR("\nctx is NULL\n");
+        return;
+    }
+    mbedtls_zeroize_internal( ctx, sizeof( mbedtls_sha256_context ) );
+}
+
+void mbedtls_sha256_clone( mbedtls_sha256_context *dst,
+                         const mbedtls_sha256_context *src )
+{
+    if( NULL == src || NULL == dst )
+    {
+        CC_PalAbort("src or dst are NULL\n" );
+    }
+    *dst = *src;
+}
+
+/*
+ * SHA-256 context setup
+ */
+int mbedtls_sha256_starts_ret( mbedtls_sha256_context *ctx, int is224 )
+{
+    int ret;
+
+    switch (is224){
+        case 0:
+            ret = mbedtls_sha_starts_internal( ctx, HASH_SHA256);
+            break;
+        case 1 :
+            ret = mbedtls_sha_starts_internal( ctx, HASH_SHA224);
+            break;
+        default:
+            return MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED;
+    };
+
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED );
+    }
+
+    return( ret );
+}
+
+int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] )
+{
+    int ret;
+
+    ret = mbedtls_sha_process_internal( ctx, data );
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED );
+    }
+
+    return( ret );
+}
+
+
+int mbedtls_sha256_update_ret( mbedtls_sha256_context *ctx, const unsigned char *input, size_t ilen )
+{
+    int ret;
+
+    ret = mbedtls_sha_update_internal( ctx, input, ilen );
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED );
+    }
+
+    return( ret );
+}
+
+
+/*
+ * SHA-256 final digest
+ */
+int mbedtls_sha256_finish_ret( mbedtls_sha256_context *ctx, unsigned char output[32] )
+{
+    int ret;
+    HashContext_t *pHashCtx = NULL;
+
+    if (NULL == ctx || NULL == output){
+        CC_PAL_LOG_ERR( "ctx or output buffer are NULL\n" );
+        return( MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED );
+    }
+
+    if (NULL == output){
+        CC_PAL_LOG_ERR( "output is NULL\n" );
+        return( MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED );
+    }
+
+    pHashCtx = (HashContext_t *)ctx;
+    ret = mbedtls_sha_finish_internal( ctx );
+    if( ret != 0 )
+    {
+        return( MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED );
+    }
+
+    /* Copy the result to the user buffer  */
+    switch (pHashCtx->mode)
+    {
+        case HASH_SHA224:
+            CC_PalMemCopy(output, pHashCtx->digest, SHA224_DIGEST_SIZE_IN_BYTES);
+            break;
+        case HASH_SHA256:
+            CC_PalMemCopy(output, pHashCtx->digest, SHA256_DIGEST_SIZE_IN_BYTES);
+            break;
+        default:
+            CC_PAL_LOG_ERR( "Unsupported HASH type (%d)\n", pHashCtx->mode );
+    }
+
+    return( 0 );
+
+}
+#endif /* #if defined(MBEDTLS_SHA256_ALT) && defined(MBEDTLS_SHA256_C) */
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/trng_api.c b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/trng_api.c
new file mode 100644
index 0000000..d156f8f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/mbedtls_api/trng_api.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "llf_rnd_trng.h"
+#include "cc_rng_plat.h"
+#include "cc_rnd_common.h"
+#include "cc_pal_log.h"
+#include "mbedtls_common.h"
+#include "cc_pal_mem.h"
+
+
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_PLATFORM_C)
+#include "mbedtls/platform.h"
+#else
+#include <stdio.h>
+#define mbedtls_fprintf fprintf
+#define mbedtls_calloc calloc
+#define mbedtls_free   free
+#endif
+
+#ifdef DEBUG
+#define GOTO_END(ERR) \
+    do { \
+        Error = ERR; \
+        mbedtls_fprintf(stderr, "%s:%d - %s: %d (0x%08x)\n", __FILE__, __LINE__, __func__, (int)Error, (int)Error); \
+        goto End; \
+    } while (0)
+
+#define GOTO_CLEANUP(ERR) \
+    do { \
+        Error = ERR; \
+        mbedtls_fprintf(stderr, "%s:%d - %s: %d (0x%08x)\n", __FILE__, __LINE__, __func__, (int)Error, (int)Error); \
+        goto Cleanup; \
+    } while (0)
+#else // DEBUG
+#define GOTO_END(ERR) \
+    do { \
+        Error = ERR; \
+        goto End; \
+    } while (0)
+
+#define GOTO_CLEANUP(ERR) \
+    do { \
+        Error = ERR; \
+        goto Cleanup; \
+    } while (0)
+#endif // DEBUG
+
+
+int mbedtls_hardware_poll( void *data,
+                           unsigned char *output, size_t len, size_t *olen )
+{
+    CCRndWorkBuff_t  *rndWorkBuff_ptr;
+    CCRndState_t rndState;
+    CCRndParams_t trngParams;
+    int ret, Error = 0;
+    uint32_t  *entrSource_ptr;
+
+    CC_UNUSED_PARAM(data);
+
+    if ( NULL == output )
+    {
+        CC_PAL_LOG_ERR( "output cannot be NULL\n" );
+        GOTO_END( -1 );
+    }
+    if ( NULL == olen )
+    {
+        CC_PAL_LOG_ERR( "olen cannot be NULL\n" );
+        GOTO_END( -1 );
+
+    }
+    if ( 0 == len )
+    {
+        CC_PAL_LOG_ERR( "len cannot be zero\n" );
+        GOTO_END( -1 );
+    }
+
+    rndWorkBuff_ptr = ( CCRndWorkBuff_t * )mbedtls_calloc( 1, sizeof ( CCRndWorkBuff_t ) );
+    if ( NULL == rndWorkBuff_ptr )
+    {
+        CC_PAL_LOG_ERR( "Error: cannot allocate memory for rndWorkbuff\n" );
+        GOTO_END ( -1 );
+    }
+    CC_PalMemSetZero( &rndState, sizeof( CCRndState_t ) );
+    CC_PalMemSetZero( &trngParams, sizeof( CCRndParams_t ) );
+
+    ret = RNG_PLAT_SetUserRngParameters(  &trngParams );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR( "Error: RNG_PLAT_SetUserRngParameters() failed.\n" );
+        GOTO_CLEANUP( -1 );
+    }
+
+    ret = LLF_RND_GetTrngSource(
+                &rndState ,    /*in/out*/
+                &trngParams,       /*in/out*/
+                0,                 /*in  -  isContinued - false*/
+                (uint32_t*)&len,  /*in/out*/
+                &entrSource_ptr,   /*out*/
+                (uint32_t*)olen,               /*out*/
+                (uint32_t*)rndWorkBuff_ptr,   /*in*/
+                0                  /*in - isFipsSupport false*/ );
+    if ( ret != 0 )
+    {
+        CC_PAL_LOG_ERR( "Error: LLF_RND_GetTrngSource() failed.\n" );
+        GOTO_CLEANUP( -1 );
+    }
+
+    if (*olen <= len ){
+        CC_PalMemCopy ( output, entrSource_ptr + CC_RND_TRNG_SRC_INNER_OFFSET_WORDS , *olen );
+    } else{
+        CC_PAL_LOG_ERR( "buffer length is smaller than LLF_RND_GetTrngSource output length\n" );
+        GOTO_CLEANUP( -1 );
+    }
+
+Cleanup:
+    mbedtls_zeroize_internal( rndWorkBuff_ptr, sizeof( CCRndWorkBuff_t ) );
+    mbedtls_free( rndWorkBuff_ptr );
+    mbedtls_zeroize_internal( &rndState, sizeof( CCRndState_t ) );
+End:
+    return Error;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_api.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_api.h
new file mode 100644
index 0000000..ac8e7e7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_api.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _BOOT_IMAGES_VERIFIER_API_H
+#define _BOOT_IMAGES_VERIFIER_API_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*! @file
+@brief This file contains the set of Secure Boot APIs.
+*/
+
+#include "secureboot_defs.h"
+#include "secureboot_gen_defs.h"
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+@brief This function initializes the Secure Boot certificate chain processing, and must be the first API called when processing Secure Boot certificate chain. It initializes the internal data fields of the certificate package.
+
+@return CC_OK on success.
+@return A non-zero value from sbrom_bsv_error.h on failure.
+*/
+CCError_t CC_SbCertChainVerificationInit(
+    CCSbCertInfo_t *certPkgInfo     /*!< [in/out] Pointer to the information about the certificate package */
+    );
+
+/*!
+@brief This function verifies a single certificate package (containing either a key or content certificate). It verifies the following:
+    <ul><li> The public key (as saved in the certificate) against its Hash that is either found in the OTP memory (HBK) or in certPkgInfo.</li>
+    <li> The certificate's RSA signature.</li>
+    <li> The SW version in the certificate must be higher than or equal to the minimum SW version, as recorded on the device and passed in certPkgInfo.</li>
+    <li> Each SW module against its Hash in the certificate (for content certificates).</li></ul>
+
+@return CC_OK   On success.
+@return A non-zero value from bsv_error.h on failure.
+*/
+CCError_t CC_SbCertVerifySingle(
+    CCSbFlashReadFunc flashReadFunc,    /*!< [in] Pointer to the flash read function. */
+    void *userContext,          /*!< [in] An additional pointer for flashRead usage. May be NULL. */
+    unsigned long hwBaseAddress,        /*!< [in] CryptoCell HW registers' base address. */
+    CCAddr_t certStoreAddress,      /*!< [in] Flash address where the certificate is located. This address is provided to flashReadFunc. */
+    CCSbCertInfo_t *certPkgInfo,        /*!< [in/out] Pointer to the information about the certificate package. */
+    uint32_t  *pHeader,                 /*!< [in/out] Pointer to a buffer used for extracting the X509 TBS Headers. Must be NULL for proprietary certificates. */
+    uint32_t  headerSize,           /*!< [in] The size of pHeader in bytes. Must be 0 for proprietary certificates. */
+    uint32_t *pWorkspace,           /*!< [in] Buffer for the function's internal use. */
+    uint32_t workspaceSize          /*!< [in] The size of the workspace in bytes. Must be at least CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES. */
+    );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_base_single.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_base_single.c
new file mode 100644
index 0000000..1ae3c2a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_base_single.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+#include "secureboot_basetypes.h"
+#include "secureboot_error.h"
+#include "bootimagesverifier_error.h"
+#include "bootimagesverifier_def.h"
+#include "bootimagesverifier_parser.h"
+#include "secureboot_base_func.h"
+#include "secureboot_base_swimgverify.h"
+#include "cc_pal_log.h"
+#include "secureboot_defs.h"
+#include "bootimagesverifier_swcomp.h"
+#include "common_cert_verify.h"
+#include "common_cert_parser.h"
+
+/************************ Defines ******************************/
+
+
+/************************ Enums ******************************/
+
+
+/************************ Typedefs ******************************/
+
+
+/************************ Global Data ******************************/
+
+/************************ Private functions  ******************************/
+
+/************************ Public functions  ******************************/
+
+CCError_t CC_SbCertChainVerificationInit(CCSbCertInfo_t *certPkgInfo)
+{
+        if (certPkgInfo == NULL) {
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+        /*clear the external hash */
+        UTIL_MemSet((uint8_t *)&(certPkgInfo->pubKeyHash), 0x0, sizeof(certPkgInfo->pubKeyHash));
+        certPkgInfo->initDataFlag = 0;
+
+
+        return CC_OK;
+}
+
+
+/**
+   @brief This function
+   loadSbCert() loads the certificate from Flash to RAM
+        if called first time, expected certificate is key certificate
+        else, if second time, expected is key or content certificate
+        else, if third, expected is content.
+   Call CCCommonCertVerify(expected types) to verify common certificate fields,
+        and returns pointers to certificate proprietary header, and body.
+   If certificate type in proprietary header is key, call CCCommonKeyCertVerify(), to verify key certificate fields.
+   Otherwise, call CCCommonContentCertVerify(), to verify Content certificate fields.
+*/
+CCError_t CC_SbCertVerifySingle(CCSbFlashReadFunc flashReadFunc,
+                                void *userContext,
+                                unsigned long hwBaseAddress,
+                                CCAddr_t certStoreAddress,
+                                CCSbCertInfo_t *pCertPkgInfo,
+                                uint32_t *pHeader,     // used for X509 header
+                                uint32_t  headerSize,
+                                uint32_t *pWorkspace,
+                                uint32_t workspaceSize)
+{
+        CCError_t   rc = CC_OK;
+        uint32_t    certLoadWordSize;
+        CertFieldsInfo_t  certFields;
+        BufferInfo32_t  workspaceInfo;
+        BufferInfo32_t  certInfo;
+        BufferInfo32_t  x509HeaderInfo;
+        BufferInfo32_t *pX509HeaderInfo = NULL;
+
+
+        /* 1. Verify input parameters */
+        /*----------------------------*/
+        if ((flashReadFunc == NULL) ||
+            (pCertPkgInfo == NULL) ||
+            (pWorkspace == NULL) ||
+            (workspaceSize == 0) ||
+            ((unsigned long)pWorkspace + workspaceSize < (unsigned long)pWorkspace) ||   /* Verify no overflow in workspace */
+            (workspaceSize < CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES) ||
+            (!IS_ALIGNED(workspaceSize, sizeof(uint32_t))) ||
+            (!IS_ALIGNED(pWorkspace, sizeof(uint32_t)))) {
+                CC_PAL_LOG_ERR("illegal params \n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+        if ((pHeader != NULL) && (headerSize != 0)) {
+                x509HeaderInfo.pBuffer = pHeader;
+                x509HeaderInfo.bufferSize = headerSize;
+                pX509HeaderInfo = &x509HeaderInfo;
+        }
+
+        if (CC_SB_MAX_CERT_SIZE_IN_BYTES < CC_SB_MAX_CONTENT_PKG_SIZE_IN_BYTES) {
+                CC_PAL_LOG_ERR("CC_SB_MAX_CERT_SIZE_IN_BYTES \n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        UTIL_MemSet((uint8_t *)&certFields, 0, sizeof(CertFieldsInfo_t));
+        /* Clearing the RAM just to verify that there is no secret data on it, before starting to process certificate */
+        UTIL_MemSet((uint8_t *)pWorkspace, 0, workspaceSize);
+
+
+        /* 2. Load the certificate from the Flash */
+        /*----------------------------------------*/
+        /* Set the maximum certificate size, and get back the current certificate size.
+           The certificate to load is 32 bit aligned */
+        certLoadWordSize = (CC_SB_MAX_CERT_SIZE_IN_BYTES / CC_32BIT_WORD_SIZE);
+        rc = CCCertLoadCertificate(flashReadFunc,
+                                   userContext,
+                                   certStoreAddress,
+                                   pWorkspace,
+                                   &certLoadWordSize);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("CCCertParserLoadCertificate  returned 0x%X\n", (unsigned int)rc);
+                return rc;
+        }
+
+        /* workspace order:
+           [0]  certificate
+            [certificate size]   if content certificate - additional data for images and addresses
+           [end of workspace]   N+Np+Signature  OR images information */
+        certInfo.pBuffer =  pWorkspace;
+
+        /* Set expected certificate type according to the certificate place in chain - first key ,
+           second key or content, third content. Maximal size in content certificate is calculated according to
+           MAX number of possible SW images.*/
+        switch (pCertPkgInfo->initDataFlag) {
+        case CC_SB_FIRST_CERT_IN_CHAIN:
+                certFields.certType = CC_SB_KEY_CERT;
+                certFields.certBodySize = sizeof(KeyCertMain_t);
+                certInfo.bufferSize = CC_SB_MAX_KEY_CERT_SIZE_IN_BYTES;
+                break;
+        case CC_SB_SECOND_CERT_IN_CHAIN:
+                certFields.certType = CC_SB_KEY_OR_CONTENT_CERT;
+                certFields.certBodySize = sizeof(ContentCertMain_t);
+                certInfo.bufferSize = CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES;
+                break;
+        case CC_SB_THIRD_CERT_IN_CHAIN:
+                certFields.certType = CC_SB_CONTENT_CERT;
+                certFields.certBodySize = sizeof(ContentCertMain_t);
+                certInfo.bufferSize = CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES;
+                break;
+        default:
+                CC_PAL_LOG_ERR("Not expecting any certificate in the chain \n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        // set the workspace for N, Np and signature
+        workspaceInfo.bufferSize = sizeof(workspaceInt_t);
+        workspaceInfo.pBuffer = (uint32_t *)((unsigned long)pWorkspace + workspaceSize - sizeof(workspaceInt_t));
+
+        /* 3. Verify the certificate (Verify the RSA signature and the public key hash) . */
+        rc = CCCommonCertVerify(hwBaseAddress,
+                                &certInfo,
+                                &certFields,
+                                pCertPkgInfo,
+                                &workspaceInfo,
+                                pX509HeaderInfo);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("CCCommonCertVerify failed 0x%X\n", rc);
+                return rc;
+        }
+
+
+        /* 4. In case of content certificate - verify the SW images */
+        /*----------------------------------------------------------*/
+        switch (certFields.certType) {
+        case CC_SB_KEY_CERT:
+                /* Verify the key certificate sw version. */
+                rc = CCCommonKeyCertVerify(hwBaseAddress,
+                                           certFields.certHeader.certFlags,
+                                           certFields.pCertBody,
+                                           pCertPkgInfo);
+                /* Update the certificate number in the chain.*/
+                pCertPkgInfo->initDataFlag++;
+                break;
+        case CC_SB_CONTENT_CERT:
+                /* Verify the content certificate sw version and verify the SW images. If needed update the sw version.
+                  workspaceInfo may overlap with N+Np+Signature, since N, Np and signature were already verified */
+                workspaceInfo.pBuffer = pWorkspace + certLoadWordSize;
+                workspaceInfo.bufferSize = workspaceSize - certLoadWordSize * CC_32BIT_WORD_SIZE;
+                rc = CCCommonContentCertVerify(flashReadFunc,
+                                               userContext,
+                                               hwBaseAddress,
+                                               certStoreAddress + certLoadWordSize * CC_32BIT_WORD_SIZE,
+                                               pCertPkgInfo,
+                                               certFields.certHeader.certFlags,
+                                               certFields.pCertBody,
+                                               &workspaceInfo);
+                /* the content certificate is always the last. */
+                pCertPkgInfo->initDataFlag = CC_SB_LAST_CERT_IN_CHAIN;
+                break;
+        default:
+                CC_PAL_LOG_ERR("Illegal certificate type for secure boot flow.\n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        return rc;
+
+} /* End of CC_SbCertVerifySingle */
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_def.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_def.h
new file mode 100644
index 0000000..0108211
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_def.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ /*!
+ @addtogroup cc_sb_image_verifier
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains definitions used for the Secure Boot and Secure
+ Debug APIs.
+ */
+
+
+#ifndef _BOOT_IMAGES_VERIFIER_DEF_H
+#define _BOOT_IMAGES_VERIFIER_DEF_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+
+/*! The maximal number of SW images per content certificate. */
+#define CC_SB_MAX_NUM_OF_IMAGES 16
+
+#ifdef CC_SB_X509_CERT_SUPPORTED
+/*! The maximal size of an X.509 certificate in bytes.*/
+#define CC_SB_MAX_CERT_SIZE_IN_BYTES    (0xB10)
+#else
+/*! The maximal size of an Arm proprietary certificate in bytes. */
+#define CC_SB_MAX_CERT_SIZE_IN_BYTES    (0x700)
+#endif
+/*! The maximal size of a certificate in words.*/
+#define CC_SB_MAX_CERT_SIZE_IN_WORDS    (CC_SB_MAX_CERT_SIZE_IN_BYTES/CC_32BIT_WORD_SIZE)
+
+/*! The size of the Secure Debug workspace in bytes. This workspace is used
+to store RSA parameters. For example, modulus and signature. */
+#define CC_SB_MIN_DBG_WORKSPACE_SIZE_IN_BYTES   (0x350)
+
+/*!
+ @brief The minimal size of the Secure Boot workspace in bytes.
+
+ The Secure Boot APIs use a temporary workspace for processing the data that
+ is read from the flash, before loading the SW modules to their designated
+ memory addresses. This workspace must be large enough to accommodate the size
+ of the certificates, and twice the size of the data that is read from flash
+ in each processing round.
+
+ The definition of \c CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES is comprised of
+ \c CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES and additional space for the
+ certificate itself, which resides in the workspace at the same time the SW
+ images data is processed.\n
+ It is assumed that the optimal size of the data to read in each processing
+ round is 4KB, based on the standard flash-memory page size. Therefore, the
+ size of the double buffer, \c CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES,
+ is defined by default as 8KB in the project configuration file. This can be
+ changed to accommodate the optimal value in different environments.
+ \c CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES is defined by the Boot Services
+ makefile as equal to \c CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES.
+
+ @note When writing code that uses the Secure Boot APIs, and includes the
+ bootimagesverifier_def.h file, the value of
+ \c CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES must be defined by your makefile to be
+ exactly the same value as was used when compiling the SBROM library.
+ Additionally, \c CC_SB_X509_CERT_SUPPORTED must be defined in the Makefile,
+ according to the definition of \c CC_CONFIG_SB_X509_CERT_SUPPORTED. \par
+
+ @note The size of \c CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES must be a multiple of
+ the hash SHA-256 block size of 64 bytes. \par
+*/
+#define CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES   (CC_SB_MAX_CERT_SIZE_IN_BYTES + CC_MAX(CC_SB_MIN_DBG_WORKSPACE_SIZE_IN_BYTES, CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+ /*!
+ @}
+ */
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_parser.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_parser.c
new file mode 100644
index 0000000..5f03405
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_parser.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+#include "secureboot_error.h"
+#include "secureboot_basetypes.h"
+#include "secureboot_defs.h"
+#include "rsa_bsv.h"
+#include "bootimagesverifier_def.h"
+#include "bootimagesverifier_error.h"
+#include "bootimagesverifier_parser.h"
+#include "cc_pal_log.h"
+
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Internal Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+
+/**
+   @brief This function load sizeof(CCSbCertHeader_t ) from flash and get the
+   certificate size from it. Make sure size is within range (smaller than workspace
+   size not including the required space for N, Np and signature).
+   read the certificate according to size from header and copy the certificate content from Flash to RAM.
+ */
+uint32_t CCCertLoadCertificate(CCSbFlashReadFunc flashRead_func,
+                               void *userContext,
+                               CCAddr_t certAddress,
+                               uint32_t *pCert,
+                               uint32_t *pCertBufferWordSize)
+{
+        CCError_t error = CC_OK;
+        CCSbCertHeader_t *pCertHeader = (CCSbCertHeader_t *)pCert;
+
+        /* Verify that the certificate buffer size is big enough to contain the header */
+        if (*pCertBufferWordSize < (sizeof(CCSbCertHeader_t) / CC_32BIT_WORD_SIZE)) {
+                CC_PAL_LOG_ERR("certificate buff size too small to contain certificate header\n");
+                return CC_BOOT_IMG_VERIFIER_WORKSPACE_SIZE_TOO_SMALL;
+        }
+
+        /* Read the certificate header from the Flash */
+        error = flashRead_func(certAddress, (uint8_t *)pCertHeader, sizeof(CCSbCertHeader_t), userContext);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("failed flashRead_func for certificate header\n");
+                return error;
+        }
+
+        /* Verify there is no wrap around in the certificate size*/
+        if ((pCertHeader->certSize + SB_CERT_RSA_KEY_SIZE_IN_WORDS) < pCertHeader->certSize){
+            CC_PAL_LOG_ERR("Certificate size too big\n");
+            return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* Make sure certificate size is within range (certificate size + signature size) */
+        if ((pCertHeader->certSize + SB_CERT_RSA_KEY_SIZE_IN_WORDS) > *pCertBufferWordSize) {
+                CC_PAL_LOG_ERR("Certificate size too big\n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* according to the header read the additional certificate buffer -
+           not including the non-signed part in case of content certificate */
+        error = flashRead_func(certAddress + sizeof(CCSbCertHeader_t),
+                               (uint8_t *)pCert + sizeof(CCSbCertHeader_t),
+                               ((pCertHeader->certSize + SB_CERT_RSA_KEY_SIZE_IN_WORDS) * CC_32BIT_WORD_SIZE) - sizeof(CCSbCertHeader_t),
+                               userContext);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("failed flashRead_func for certificate\n");
+                return error;
+        }
+
+        *pCertBufferWordSize = (pCertHeader->certSize + SB_CERT_RSA_KEY_SIZE_IN_WORDS);
+
+        return CC_OK;
+
+} /* End of CCCertLoadCertificate */
+
+
+/****************************************************************************************************/
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_parser.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_parser.h
new file mode 100644
index 0000000..2fca4e3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_parser.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _BOOT_IMAGES_VERIFIER_PARSER_H
+#define _BOOT_IMAGES_VERIFIER_PARSER_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "secureboot_defs.h"
+#include "cc_crypto_boot_defs.h"
+#include "secureboot_parser_gen_defs.h"
+#include "secdebug_defs.h"
+
+/* Definitions used by the functions */
+/*-----------------------------------*/
+
+/* mask to location of Offset to signature bits in the header cert size parameter */
+#define CERT_LEN_SIGNATURE_OFFSET_BIT_MASK         0x0000FFFFUL
+
+/* certificate version Major offset */
+#define CERT_VERSION_MAJOR_BIT_SHIFT    16
+
+/* Structures used inside the parser code */
+/*----------------------------------------*/
+
+/* RSA data (united to one structure) for RSA_PSS_3072 */
+typedef struct {
+    /* Pointer to N */
+    uint32_t  *N_ptr;
+
+    /* Pointer to Np OR H according to algorithm used */
+    uint32_t  *NDer_ptr;
+
+    /* Pointer to RSA signature */
+    uint32_t *signature;
+
+    /* Size of cert for HASH computation (offset to signature) */
+    uint32_t   certSizeInWordsForHash;
+
+}CCSbCertParserRSAData_t;
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+   @brief This function start to load the certificate from flash to RAM,
+   including the signed data and the signature.
+   It does not include the unsigned data in case of content certificate.
+
+@return CC_OK   On success.
+@return A non-zero value from bsv_error.h on failure.
+ */
+uint32_t CCCertLoadCertificate(CCSbFlashReadFunc flashRead_func,    /*!< [in] Pointer to the flash read function. */
+                               void *userContext,           /*!< [in] An additional pointer for flashRead usage. May be NULL. */
+                               CCAddr_t certAddress,            /*!< [in] The address where the certificate is located. This address is provided to flashReadFunc. */
+                               uint32_t *pCert,             /*!< [in] Buffer for the function's internal use. */
+                               uint32_t *pCertBufferWordSize);      /*!< [in/out] Set the maximum certificate size, and get back the actual certificate size. */
+
+/*!
+   @brief This function calculates the certificate size that includes the signed data and the signature.
+
+@return CC_OK   On success.
+@return A non-zero value from bsv_error.h on failure.
+ */
+uint32_t CCCertGetUnsignedDataOffset(uint32_t *pCert,           /*!< [in] Buffer for the function's internal use. */
+                     uint32_t *pUnsignedDataOffset);    /*!< [out] Get the actual certificate size of the signed data and the signature (in words). */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_swcomp.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_swcomp.c
new file mode 100644
index 0000000..2275ba9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_swcomp.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+#include "secureboot_basetypes.h"
+#include "rsa_bsv.h"
+#include "bootimagesverifier_def.h"
+#include "secureboot_error.h"
+#include "bootimagesverifier_error.h"
+#include "bootimagesverifier_parser.h"
+#include "secureboot_stage_defs.h"
+#include "nvm.h"
+#include "bootimagesverifier_swcomp.h"
+#include "secureboot_base_swimgverify.h"
+#include "cc_pal_log.h"
+
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Internal Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+CCError_t CCCertValidateSWComps(CCSbFlashReadFunc flashRead_func,
+                  void *userContext,
+                  unsigned long hwBaseAddress,
+                  CCSbPubKeyIndexType_t keyIndex,
+                  CCSbCertParserSwCompsInfo_t *pSwImagesData,
+                  uint32_t *pSwImagesAddData,
+                  uint32_t *workspace_ptr,
+                  uint32_t workspaceSize)
+{
+    /* error variable */
+    CCError_t error = CC_OK;
+
+    /* internal index */
+    uint32_t i = 0;
+
+    /* internal pointer for the certificate main body, might not be word aligned */
+    uint8_t *pSwRecSignedData = NULL;
+    /* the non-signed part is always word aligned */
+    uint32_t *pSwRecNoneSignedData = NULL;
+
+    /* AES IV buffer */
+    AES_Iv_t AESIv;
+    uint8_t *nonce;
+    CCswCodeEncType_t swCodeEncType;
+    CCBsvKeyType_t  keyType;
+    bsvCryptoMode_t cryptoMode;
+    CCswCryptoType_t swCryptoType;
+    CCswLoadVerifyScheme_t swLoadVerifyScheme;
+
+    uint32_t lcs;
+
+    uint8_t isLoadFromFlash;
+    uint8_t isVerifyImage;
+        ContentCertImageRecord_t cntImageRec;
+
+    /*------------------
+        CODE
+    -------------------*/
+
+    /* Point to the s/w record signed data: hash, load address, max size, code enc */
+    pSwRecSignedData = pSwImagesData->pSwCompsData;
+
+    /* Point to the s/w record non-signed data: storage address, actual size */
+    pSwRecNoneSignedData = pSwImagesAddData;
+
+    nonce = pSwImagesData->nonce;
+    swCodeEncType = pSwImagesData->swCodeEncType;
+    swCryptoType = pSwImagesData->swCryptoType;
+    swLoadVerifyScheme = pSwImagesData->swLoadVerifyScheme;
+
+    /* Set default CC mode to Hash only (no encrypted images) */
+    cryptoMode = BSV_CRYPTO_HASH;
+    keyType = CC_BSV_END_OF_KEY_TYPE;
+
+    /* Get LCS */
+    error = NVM_GetLCS(hwBaseAddress, &lcs);
+    if (error != CC_OK){
+        return error;
+    }
+
+    switch(swLoadVerifyScheme){
+    case CC_SB_LOAD_AND_VERIFY:
+        isLoadFromFlash = CC_TRUE;
+        isVerifyImage = CC_TRUE;
+        break;
+    case CC_SB_VERIFY_ONLY_IN_FLASH:
+        isLoadFromFlash = CC_TRUE;
+        isVerifyImage = CC_TRUE;
+        break;
+    case CC_SB_VERIFY_ONLY_IN_MEM:
+        isLoadFromFlash = CC_FALSE;
+        isVerifyImage = CC_TRUE;
+        break;
+    case CC_SB_LOAD_ONLY:
+        isLoadFromFlash = CC_TRUE;
+        isVerifyImage = CC_FALSE;
+        /* Loading only is validate only in none secure lifecycle */
+        if (lcs == CC_BSV_SECURE_LCS) {
+            return CC_BOOT_IMG_VERIFIER_ILLEGAL_LCS_FOR_OPERATION_ERR;
+        }
+        break;
+    default:
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+    /* Set AES key type */
+    switch (swCodeEncType){
+    case CC_SB_NO_IMAGE_ENCRYPTION:
+        break;
+    case CC_SB_ICV_CODE_ENCRYPTION:
+        keyType = CC_BSV_ICV_CE_KEY;
+        if ((keyIndex!=CC_SB_HASH_BOOT_KEY_0_128B) && (keyIndex!=CC_SB_HASH_BOOT_KEY_256B)){
+            return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+        break;
+    case CC_SB_OEM_CODE_ENCRYPTION:
+        keyType = CC_BSV_CE_KEY;
+        if ((keyIndex!=CC_SB_HASH_BOOT_KEY_1_128B) && (keyIndex!=CC_SB_HASH_BOOT_KEY_256B)){
+            return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+        break;
+    default:
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+    /* Case of encrypted SW image */
+    if (swCodeEncType != CC_SB_NO_IMAGE_ENCRYPTION) {
+
+        /* SB should fail if CE is needed in RMA lcs */
+        if (lcs == CC_BSV_RMA_LCS) {
+            return CC_BOOT_IMG_VERIFIER_ILLEGAL_LCS_FOR_OPERATION_ERR;
+        }
+
+        /* image can not be encrypted in case of "load only" or "verify in flash" */
+        if ( (swLoadVerifyScheme == CC_SB_LOAD_ONLY) || (swLoadVerifyScheme == CC_SB_VERIFY_ONLY_IN_FLASH) ) {
+            return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* Set crypto mode */
+        switch (swCryptoType){
+        case CC_SB_HASH_ON_DECRYPTED_IMAGE:
+            /* do AES decrypt on cipher image, and then do hash is done on plain image */
+            cryptoMode = BSV_CRYPTO_AES_TO_HASH_AND_DOUT;
+            break;
+        case CC_SB_HASH_ON_ENCRYPTED_IMAGE:
+            /* do AES decrypt and Hash on cipher image */
+            cryptoMode = BSV_CRYPTO_AES_AND_HASH;
+            break;
+        default:
+            return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* Initiate AES IV with nonce data */
+        UTIL_MemSet((uint8_t*)AESIv, 0, AES_IV_COUNTER_SIZE_IN_BYTES);
+        UTIL_MemCopy((uint8_t*)&AESIv[0], nonce, CC_SB_MAX_SIZE_NONCE_BYTES);
+    }
+
+    /* Load and verify all images in the certificate */
+    /*-----------------------------------------------*/
+    for (i = 0; i < pSwImagesData->numOfSwComps; i++ ) {
+
+        /* In case of encrypted image, set AES IV CTR */
+        if ((isVerifyImage == CC_TRUE) && (keyType != CC_BSV_END_OF_KEY_TYPE)) {
+            UTIL_MemCopy((uint8_t *)&cntImageRec, (uint8_t *)pSwRecSignedData, sizeof(ContentCertImageRecord_t));
+#ifdef BIG__ENDIAN
+            UTIL_MemCopy((uint8_t*)&AESIv[2], (uint8_t*)&cntImageRec.loadAddr, sizeof(CCAddr_t));
+#else
+            UTIL_ReverseMemCopy((uint8_t*)&AESIv[2], (uint8_t*)&cntImageRec.loadAddr, sizeof(CCAddr_t));
+#endif
+        }
+
+        /* Load and/or verify image as needed */
+        error = _CCSbImageLoadAndVerify(flashRead_func, userContext,/* Flash Read function */
+                             hwBaseAddress,         /* CC base address */
+                             isLoadFromFlash,       /* should image be copied from Flash with user callback */
+                             isVerifyImage,         /* should image be verified with hash (and Aes if needed) */
+                             cryptoMode,            /* crypto mode type */
+                             keyType,           /* code encryption type definition */
+                             AESIv,             /* AES IV buffer */
+                             pSwRecSignedData,      /* pointer to SW component signed data - not word aligned for x.509 */
+                             pSwRecNoneSignedData,  /* pointer to SW components non-signed data. always word aligned */
+                             workspace_ptr, workspaceSize); /* workspace & workspaceSize to load the SW component into */
+
+        if (error != CC_OK){
+            return error;
+        }
+
+        /* Point to the next SW record */
+        pSwRecSignedData = (uint8_t *)((unsigned long)pSwRecSignedData + SW_REC_SIGNED_DATA_SIZE_IN_BYTES);
+        pSwRecNoneSignedData = (uint32_t *)((unsigned long)pSwRecNoneSignedData + SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES);
+
+    }
+
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_swcomp.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_swcomp.h
new file mode 100644
index 0000000..419e7f5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_swcomp.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+
+#ifndef _BOOT_IMAGES_VERIFIER_SWCOMP_H
+#define _BOOT_IMAGES_VERIFIER_SWCOMP_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/************************ Public Functions ******************************/
+/**
+ * @brief This function is responsible to verification of the SW components.
+ *        The function will go over the SW components load each component,
+ *        compute its HASH and compare it with the HASH saved in the certificate.
+ *
+ *
+ * @param[in] flashRead_func - User's Flash read function used to read data from the flash to memory location
+ * @param[in] userContext - User's context for the usage of flashRead_func
+ * @param[in] hwBaseAddress - base address for the ARM CryptoCell HW engines
+ * @param[in] pSwImagesData - s/w comps data, pointers to certificate locations of the s/w comps HASH data
+ * @param[in] pSwImagesAddData - s/w comps additional data, pointers to certificate locations of the s/w comps additional data
+ * @param[in] workspace_ptr - temporary buffer to load the SW components to (SW components without
+ *            loading address).
+ * @param[in] workspaceSize - the temporary buffer size in bytes
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from BootImagesVerifier_error.h
+ */
+CCError_t CCCertValidateSWComps(CCSbFlashReadFunc flashRead_func,
+                  void *userContext,
+                  unsigned long hwBaseAddress,
+                  CCSbPubKeyIndexType_t keyIndex,
+                  CCSbCertParserSwCompsInfo_t *pSwImagesData,
+                  uint32_t *pSwImagesAddData,
+                  uint32_t *workspace_ptr,
+                  uint32_t workspaceSize);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_parser.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_parser.c
new file mode 100644
index 0000000..28420a3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_parser.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "bsv_defs.h"
+#include "bsv_error.h"
+#include "secureboot_stage_defs.h"
+#include "bootimagesverifier_error.h"
+
+#include "common_cert_parser.h"
+#include "cc_pal_log.h"
+
+#include "secdebug_api.h"
+#include "secdebug_defs.h"
+
+/*
+#define KEY_CERT_SIZE               (sizeof(KeyCert_t))
+#define CERT_SIGNATURE_SIZE         (sizeof(CCSbSignature_t))
+#define ENABLER_CERT_SIZE           (sizeof(EnablerCertMain_t))
+#define ENABLER_CERT_HEADER_SIZE        (sizeof(EnablerCertHeader_t))
+#define ENABLER_CERT_HEADER_SIZE_WORDS      (ENABLER_CERT_HEADER_SIZE/CC_32BIT_WORD_SIZE)
+#define DEVELOPER_CERT_SIZE         (sizeof(DeveloperCertMain_t))
+#define DEVELOPER_CERT_HEADER_SIZE      (sizeof(DeveloperCertHeader_t))
+#define DEVELOPER_CERT_HEADER_SIZE_WORDS    (DEVELOPER_CERT_HEADER_SIZE/CC_32BIT_WORD_SIZE)
+#define MASK_WORD_ALIGN             (CC_32BIT_WORD_SIZE-1)
+*/
+
+/**
+   @brief This function copy N, Np (CCSbNParams_t) and signature
+   (certificate start address + sizeof certificate in certificate header) from the certificate to workspace.
+   Return pointer to certificate header CCSbCertHeader_t, and pointer to cert body sizeof()
+
+ */
+CCError_t CCCertFieldsParse(BufferInfo32_t  *pCertInfo,
+                            BufferInfo32_t  *pWorkspaceInfo,
+                            CertFieldsInfo_t  *pCertFields,
+                            uint32_t    **ppCertStartSign,
+                            uint32_t    *pCertSignedSize,
+                            BufferInfo32_t  *pX509HeaderInfo)
+{
+        uint8_t *pPubKey = NULL;
+        uint8_t *pSignature = NULL;
+        uint32_t  certSignedSize = 0;
+        workspaceInt_t  *lpWorkspaceInt;
+
+        /* Fields used only for X509 */
+        CC_UNUSED_PARAM(pX509HeaderInfo);
+
+        if ((pWorkspaceInfo == NULL) ||
+            (pWorkspaceInfo->pBuffer == NULL) ||
+            (pWorkspaceInfo->bufferSize < sizeof(workspaceInt_t))) {
+                CC_PAL_LOG_ERR("workspace and or sizes illegal\n");
+                return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+        }
+        lpWorkspaceInt = (workspaceInt_t  *)(pWorkspaceInfo->pBuffer);
+
+        /* Verify the cert size (from the header), certSize is constant according to MAX certificate size. */
+        UTIL_MemCopy((uint8_t *)&pCertFields->certHeader, (uint8_t *)pCertInfo->pBuffer, sizeof(CCSbCertHeader_t));
+        certSignedSize = pCertFields->certHeader.certSize * CC_32BIT_WORD_SIZE;
+        if (certSignedSize > pCertInfo->bufferSize - sizeof(CCSbSignature_t)) {
+                CC_PAL_LOG_ERR("certSignedSize illegal 0x%x, certSize  0x%x, sizeof(CCSbSignature_t) 0x%x,\n", certSignedSize, pCertInfo->bufferSize, sizeof(CCSbSignature_t));
+                UTIL_MemSet((uint8_t *)&pCertFields->certHeader, 0, sizeof(CCSbCertHeader_t));
+                return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+        }
+
+        /* Parse and set the pointers */
+        pCertFields->pCertBody = (uint8_t *)((unsigned long)pCertInfo->pBuffer + sizeof(CCSbCertHeader_t) + sizeof(CCSbNParams_t));
+        pCertFields->certBodySize = pCertInfo->bufferSize - (sizeof(CCSbCertHeader_t) + sizeof(CCSbNParams_t) + sizeof(CCSbSignature_t));
+        pPubKey = (uint8_t *)((unsigned long)pCertInfo->pBuffer + sizeof(CCSbCertHeader_t));
+        pSignature = (uint8_t *)((unsigned long)pCertInfo->pBuffer + certSignedSize);
+        /* copy N and Np into workspace */
+        UTIL_MemCopy((uint8_t *)&lpWorkspaceInt->pubKey, pPubKey, sizeof(CCSbNParams_t));
+        /* copy signature into workspace */
+        UTIL_MemCopy((uint8_t *)&lpWorkspaceInt->signature, pSignature, sizeof(CCSbSignature_t));
+        *ppCertStartSign = pCertInfo->pBuffer;
+        *pCertSignedSize = certSignedSize;
+
+
+        return CC_OK;
+}
+
+uint32_t CCCertGetUnsignedDataOffset(uint32_t *pCert,
+                     uint32_t *pUnsignedDataOffset)
+{
+        CCSbCertHeader_t *pCertHeader = (CCSbCertHeader_t *)pCert;
+
+    if ((pCert == NULL)||(pUnsignedDataOffset == NULL)){
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+        *pUnsignedDataOffset = (pCertHeader->certSize + SB_CERT_RSA_KEY_SIZE_IN_WORDS);
+
+        return CC_OK;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_parser.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_parser.h
new file mode 100644
index 0000000..d47051b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_parser.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _COMMON_CERT_PARSER_H
+#define _COMMON_CERT_PARSER_H
+
+#include "secdebug_defs.h"
+
+/* IMPORATNT NOTE:  The certificate body may not be word aligned.
+   For proprietary it is aligned but for x.509 we can not guarantee that */
+typedef struct {
+        CCSbCertTypes_t certType;
+        CCSbCertHeader_t certHeader;
+        uint8_t     *pCertBody;
+        uint32_t certBodySize;
+} CertFieldsInfo_t;
+
+typedef struct {
+        uint32_t   *pBuffer;
+        uint32_t   bufferSize;
+} BufferInfo32_t;
+
+CCError_t CCCertSecDbgParse(uint32_t   *pDebugCertPkg,
+                            uint32_t   certPkgSize,
+                            BufferInfo32_t  *pKeyCert,       // out
+                            BufferInfo32_t  *pEnablerCert,   // out
+                            BufferInfo32_t  *pDeveloperCert); // out
+
+uint32_t CCCertLoadCertificate(CCSbFlashReadFunc flashRead_func,
+                               void *userContext,
+                               CCAddr_t certAddress,
+                               uint32_t *pCert,
+                               uint32_t *pCertBufferWordSize);
+
+/**
+   @brief This function copy N, Np (CCSbNParams_t) and signature
+   (certificate start address + sizeof certificate in certificate header) from the certificate to workspace.
+   Return pointer to certificate header CCSbCertHeader_t, and pointer to cert body sizeof()
+
+ */
+CCError_t CCCertFieldsParse(BufferInfo32_t  *pCertInfo,
+                            BufferInfo32_t  *pWorkspaceInfo,
+                            CertFieldsInfo_t  *pCertFields,
+                            uint32_t    **ppCertStartSign,
+                            uint32_t    *pCertSignedSize,
+                            BufferInfo32_t  *pX509HeaderInfo);
+
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_verify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_verify.c
new file mode 100644
index 0000000..b16d7a3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_verify.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "secureboot_basetypes.h"
+#include "secureboot_general_hwdefs.h"
+#include "bsv_defs.h"
+#include "bsv_error.h"
+#include "cc_pal_log.h"
+#include "cc_otp_defs.h"
+#include "bootimagesverifier_def.h"
+#include "secureboot_stage_defs.h"
+#include "secureboot_base_func.h"
+#include "secureboot_base_swimgverify.h"
+#include "bootimagesverifier_swcomp.h"
+#include "bootimagesverifier_error.h"
+#include "bootimagesverifier_parser.h"
+#include "common_cert_parser.h"
+#include "cc_crypto_boot_defs.h"
+#include "nvm.h"
+#include "secdebug_api.h"
+#include "secdebug_defs.h"
+
+const uint32_t certMagicNumber[CC_SB_MAX_CERT] = {
+        /* No enum */           0,
+        /*  CC_SB_KEY_CERT       */ CC_SB_KEY_CERT_MAGIC_NUMBER,
+        /*  CC_SB_CONTENT_CERT   */ CC_SB_CONTENT_CERT_MAGIC_NUMBER,
+        0,
+        /*  CC_SB_ENABLER_CERT   */ CC_CERT_SEC_DEBUG_ENABLER_MAGIC,
+        /*  CC_SB_DEVELOPER_CERT */ CC_CERT_SEC_DEBUG_DEVELOPER_MAGIC
+};
+
+const uint32_t certMainMaxSize[CC_SB_MAX_CERT] = {
+        /* No enum */                 0,
+        /*  CC_SB_KEY_CERT       */(CC_SB_MAX_KEY_CERT_SIZE_IN_BYTES - CC_SB_MAX_CERT_SIGN_SIZE_IN_BYTES),
+        /*  CC_SB_CONTENT_CERT   */(CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES - CC_SB_MAX_CERT_SIGN_SIZE_IN_BYTES),
+        0,
+        /*  CC_SB_ENABLER_CERT   */(CC_SB_MAX_ENABLER_CERT_SIZE_IN_BYTES - CC_SB_MAX_CERT_SIGN_SIZE_IN_BYTES),
+        /*  CC_SB_DEVELOPER_CERT */(CC_SB_MAX_DEVELOPER_CERT_SIZE_IN_BYTES - CC_SB_MAX_CERT_SIGN_SIZE_IN_BYTES)
+};
+
+
+uint32_t hbkId2HashSizeWords[] = {
+        /* CC_SB_HASH_BOOT_KEY_0_128B */  CC_BSV_128B_HASH_SIZE_IN_WORDS,
+        /* CC_SB_HASH_BOOT_KEY_1_128B */  CC_BSV_128B_HASH_SIZE_IN_WORDS,
+        /* CC_SB_HASH_BOOT_KEY_256B   */ CC_BSV_256B_HASH_SIZE_IN_WORDS,
+};
+
+
+
+
+static CCError_t verifyCertPubKeyAndSign(unsigned long hwBaseAddress,
+                                         uint32_t    *pCert,
+                                         size_t      certSize,
+                                         CCSbCertInfo_t  *pSbCertInfo,
+                                         workspaceInt_t  *pWorkspaceInt)
+{
+        CCError_t rc = CC_OK;
+        uint32_t  expPubKeyHashSizeWords;
+        CCHashResult_t    expPubKeyHash;
+
+        if (pSbCertInfo->initDataFlag != CC_SB_FIRST_CERT_IN_CHAIN) { // not first certificate in chain
+                expPubKeyHashSizeWords = sizeof(CCHashResult_t) / CC_32BIT_WORD_SIZE;
+                UTIL_MemCopy((uint8_t *)expPubKeyHash, (uint8_t *)pSbCertInfo->pubKeyHash, expPubKeyHashSizeWords * CC_32BIT_WORD_SIZE);
+        } else { // meaning this is first certificate in chain
+                expPubKeyHashSizeWords = hbkId2HashSizeWords[pSbCertInfo->keyIndex];
+                rc = NVM_ReadHASHPubKey(hwBaseAddress,
+                                        pSbCertInfo->keyIndex,
+                                        expPubKeyHash,
+                                        expPubKeyHashSizeWords);
+                if (rc != CC_OK) {
+                        // if HBK not programed yet, skip HBK verify, but continue verifying the certificate
+                        if (rc == CC_BOOT_IMG_VERIFIER_SKIP_PUBLIC_KEY_VERIFY) {
+                                expPubKeyHashSizeWords = 0;
+                        } else {
+                                CC_PAL_LOG_ERR("Failed NVM_ReadHASHPubKey 0x%x", rc);
+                                return rc;
+                        }
+                }
+        }
+
+        /* Verify  public key hash only if expectedSize > 0 */
+        if (expPubKeyHashSizeWords > 0) {
+                rc = CCSbCalcPublicKeyHASHAndCompare(hwBaseAddress,
+                                                     (uint32_t *)(&pWorkspaceInt->pubKey.N[0]),
+                                                     expPubKeyHash,
+                                                     expPubKeyHashSizeWords * CC_32BIT_WORD_SIZE);
+                if (rc != CC_OK) {
+                        CC_PAL_LOG_ERR("CCSbCalcPublicKeyHASHAndCompare failed 0x%x\n", rc);
+                        return rc;
+                }
+        }
+
+        /* Verify the certificate signature */
+        rc = CCSbVerifySignature(hwBaseAddress,
+                                 pCert,
+                                 (CCSbNParams_t *)(pWorkspaceInt->pubKey.N),
+                                 (CCSbSignature_t *)&pWorkspaceInt->signature,
+                                 certSize,
+                                 RSA_PSS_3072);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("CCSbVerifySignature failed 0x%x\n", rc);
+                return rc;
+        }
+
+        return CC_OK;
+
+}
+
+/* The function validates the certificate header - Magic number , type and version. */
+static CCError_t CCCertValidateHeader(CCSbCertHeader_t *pCertHeader,
+                                      CCSbCertTypes_t *pCertType)
+{
+        uint32_t expVersion;
+        CCSbCertTypes_t certType = CC_SB_MAX_CERT;
+        uint32_t i = 0;
+
+        /* Verify Magic number, and get certificate type out of it */
+        /*---------------------*/
+        if (pCertHeader->magicNumber == 0) {
+                CC_PAL_LOG_ERR("certificate magic number is incorrect \n");
+                return CC_BOOT_IMG_VERIFIER_INCORRECT_CERT_TYPE;
+        }
+
+        for (i = CC_SB_MIN_CERT + 1; i < CC_SB_MAX_CERT; i++) {
+                if (pCertHeader->magicNumber == certMagicNumber[i]) {
+                        certType = (CCSbCertTypes_t)i;
+                        break;
+                }
+        }
+
+        if ((certType & *pCertType) == 0) {
+                CC_PAL_LOG_ERR("certificate type is incorrect %d exp 0x%x\n", certType, *pCertType);
+                return CC_BOOT_IMG_VERIFIER_INCORRECT_CERT_TYPE;
+        }
+
+        /* Verify certificate version */
+        /*----------------------------*/
+        expVersion = (CC_SB_CERT_VERSION_MAJOR << CERT_VERSION_MAJOR_BIT_SHIFT) | CC_SB_CERT_VERSION_MINOR;
+        if (pCertHeader->certVersion != expVersion) {
+                CC_PAL_LOG_ERR("Certificate version incorrect, expVersion 0x%x, pCertHeader->certVersion 0x%x\n",
+                               expVersion, pCertHeader->certVersion);
+                return CC_BOOT_IMG_VERIFIER_CERT_VERSION_NUM_INCORRECT;
+        }
+
+        // set the actual certificate type
+        *pCertType = certType;
+        return CC_OK;
+
+}
+
+
+
+/**
+   @brief This function is basic verification for all secure boot/debug certificates.
+   it verifies type, size, public key and signature.
+   Return pointers to certificate proprietary header, and body.
+   Workspace should be clear when function returns
+        call CCCertFieldsParse() - according to certificate type(x509 or not),
+                copy public key, Np and signature to workspace,
+                and returns pointers to certificate proprietary header, and body.
+        call CCCertValidateHeader(), and verify cert type (as expected) and size (according to type).
+        If expected public key hash is NULL, call CC_BsvPubKeyHashGet() with HBK type defined in certificate to get OTP HBK
+        Call verifyCertPubKeyAndSign() To verify public key and certificate signature.
+                Public key is verified against the expected value, and N and Np and signature resides on workspace.
+
+ */
+CCError_t CCCommonCertVerify(unsigned long   hwBaseAddress,
+                             BufferInfo32_t  *pCertInfo,
+                             CertFieldsInfo_t  *pCertFields,  // in/out
+                             CCSbCertInfo_t  *pSbCertInfo,   //in/out
+                             BufferInfo32_t  *pWorkspaceInfo,
+                             BufferInfo32_t  *pX509HeaderInfo) //in/out
+{
+        uint32_t        rc = 0;
+        uint32_t        certSignedSize = 0;
+        keyCertFlags_t  certFlag;
+        uint32_t    *pCertStartSign;
+
+        if ((pWorkspaceInfo == NULL) ||
+            (pWorkspaceInfo->pBuffer == NULL) ||
+            (pWorkspaceInfo->bufferSize < sizeof(workspaceInt_t)) ||
+            (!IS_ALIGNED(pWorkspaceInfo->bufferSize, sizeof(uint32_t))) ||
+            (!IS_ALIGNED(sizeof(workspaceInt_t), sizeof(uint32_t)))) {
+                CC_PAL_LOG_ERR("workspace and or sizes illegal\n");
+                return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+        }
+
+        /* Parse the certificate fields to get pointers to the certificate internals */
+        /*---------------------------------------------------------------------------*/
+        rc = CCCertFieldsParse(pCertInfo,
+                               pWorkspaceInfo,
+                               pCertFields,
+                               &pCertStartSign,
+                               &certSignedSize,
+                               pX509HeaderInfo);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed CCCertFieldsParse 0x%x\n", rc);
+                goto end_with_error;
+        }
+        /* Verify Magic number, and version. returns the certificate type */
+        /*----------------------------------------------------------------*/
+        rc = CCCertValidateHeader(&pCertFields->certHeader, &pCertFields->certType);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed CCCertValidateHeader 0x%x\n", rc);
+                goto end_with_error;
+        }
+
+        // Verify certificate size. no need to verify the type again
+        if (((pCertFields->certType == CC_SB_KEY_CERT) ||
+             (pCertFields->certType == CC_SB_CONTENT_CERT) ||
+             (pCertFields->certType == CC_SB_ENABLER_CERT) ||
+             (pCertFields->certType ==  CC_SB_DEVELOPER_CERT)) &&
+            (certSignedSize > certMainMaxSize[pCertFields->certType])) {
+                CC_PAL_LOG_ERR("certSignedSize too big 0x%x for cert %d\n", certSignedSize, pCertFields->certType);
+                rc = CC_BOOT_IMG_VERIFIER_INCORRECT_CERT_TYPE;
+                goto end_with_error;
+        }
+
+        if (pSbCertInfo->initDataFlag == CC_SB_FIRST_CERT_IN_CHAIN) { // Verify the first HBK in chain
+                certFlag.flagsWord = pCertFields->certHeader.certFlags;
+                pSbCertInfo->keyIndex = (CCSbPubKeyIndexType_t)(certFlag.flagsBits.hbkId);
+                if (pSbCertInfo->keyIndex > CC_SB_HASH_BOOT_KEY_256B) {
+                        CC_PAL_LOG_ERR("invalid hbkId %d", pSbCertInfo->keyIndex);
+                        rc = CC_BOOT_IMG_VERIFIER_ILLEGAL_HBK_IDX;
+                        goto end_with_error;
+                }
+        }
+
+
+        /* Verify certificate public key and it's signature,  pCertStartSign is word aligned for propritery and x509*/
+        /*--------------------------------------------------*/
+        rc = verifyCertPubKeyAndSign(hwBaseAddress,
+                                     (uint32_t *)pCertStartSign,
+                                     certSignedSize,
+                                     pSbCertInfo,
+                                     (workspaceInt_t  *)pWorkspaceInfo->pBuffer);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("verifyCertPubKeyAndSign failed 0x%X\n", rc);
+                goto end_with_error;
+        }
+
+        goto end;
+
+end_with_error:
+        UTIL_MemSet((uint8_t *)pCertFields, 0, sizeof(CertFieldsInfo_t));
+end:
+        UTIL_MemSet((uint8_t *)pWorkspaceInfo->pBuffer, 0, pWorkspaceInfo->bufferSize);
+        return rc;
+}
+
+
+/**
+   @brief This function verifies key certificate specific fields
+        The header flags, NV counter according to HBK type
+        Return next certificate public key hash.
+ */
+uint32_t CCCommonKeyCertVerify(unsigned long   hwBaseAddress,
+                               uint32_t certFlags,
+                               uint8_t *pCertMain,
+                               CCSbCertInfo_t *pCertPkgInfo)
+{
+        uint32_t       rc = 0;
+        keyCertFlags_t  keyFlag;
+        KeyCertMain_t certMain;
+
+        keyFlag.flagsWord = certFlags;
+
+        if (pCertPkgInfo->initDataFlag == CC_SB_FIRST_CERT_IN_CHAIN) {
+                pCertPkgInfo->keyIndex = (CCSbPubKeyIndexType_t)(keyFlag.flagsBits.hbkId);
+        }
+
+        /* Copy non-aligned certFields.pCertBody into aligned struct */
+        UTIL_MemCopy((uint8_t *)&certMain, (uint8_t *)pCertMain, sizeof(KeyCertMain_t));
+
+        /* Verify that the SW version is valid */
+        rc = CCSbVerifyNvCounter(hwBaseAddress, certMain.swVer, pCertPkgInfo);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("CCSbVerifyNvCounter failed 0x%X\n", rc);
+                return rc;
+        }
+        if (pCertPkgInfo->initDataFlag == CC_SB_FIRST_CERT_IN_CHAIN) {
+                pCertPkgInfo->activeMinSwVersionVal = certMain.swVer;
+        }
+
+        /* Set function output values */
+        UTIL_MemCopy((uint8_t *)pCertPkgInfo->pubKeyHash, (uint8_t *)certMain.nextPubKeyHash, sizeof(CCHashResult_t));
+
+        return CC_OK;
+}
+
+/**
+   @brief This function   verifies content certificate specific fields
+        Verifies certificate flags, NV counter according to HBK type
+        Call CCCertValidateSWComps()
+        Call CCSbSetNvCounter()
+ *      The function uses the workspace  for loading the
+ *      non-signed certificate part and  if required to load and
+ *      verify the images.
+ */
+uint32_t CCCommonContentCertVerify(CCSbFlashReadFunc flashReadFunc,
+                                   void *userContext,
+                                   unsigned long hwBaseAddress,
+                                   CCAddr_t certStoreAddress,
+                                   CCSbCertInfo_t *certPkgInfo,
+                                   uint32_t certFlags,
+                                   uint8_t  *pCertMain,
+                                   BufferInfo32_t  *pWorkspaceInfo)
+{
+        CCError_t rc = CC_OK;
+        CCSbCertParserSwCompsInfo_t swImagesData;
+        /* Content additional data is always word aligned*/
+        uint32_t *pSwImagesAddData;
+        uint32_t sizeOfNonSignedCert = 0;
+        uint32_t numOfImages = 0;
+        CCSbCertFlags_t flags;
+        uint32_t  swVer;
+
+
+        /* 1. Get the number of sw components from the header flags field */
+        flags.flagsWord = certFlags;
+        numOfImages = flags.flagsBits.numOfSwCmp;
+        if ((numOfImages > CC_SB_MAX_NUM_OF_IMAGES) ||
+            (numOfImages == 0)) {
+                return CC_BOOT_IMG_VERIFIER_ILLEGAL_NUM_OF_IMAGES;
+        }
+
+        /* 2. Load the extended data (unsigned data), in this stage the certificate is already verified. */
+        sizeOfNonSignedCert = numOfImages * SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES;
+        if (sizeOfNonSignedCert > pWorkspaceInfo->bufferSize) {
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* Read the Non-signed part of the certificate package from the Flash, and place it right after the certificate. */
+        rc = flashReadFunc(certStoreAddress, (uint8_t *)pWorkspaceInfo->pBuffer, sizeOfNonSignedCert, userContext);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("failed flashRead_func for Non-signed part\n");
+                return rc;
+        }
+        pSwImagesAddData = pWorkspaceInfo->pBuffer;
+        pWorkspaceInfo->bufferSize -= sizeOfNonSignedCert;
+        pWorkspaceInfo->pBuffer += (sizeOfNonSignedCert / CC_32BIT_WORD_SIZE) + 1;
+
+        /* 3. verify sw version
+           Copy 4 bytes instead of accessing teh struct field, since  pCertMain is not word aligned */
+        UTIL_MemCopy((uint8_t *)&swVer, (uint8_t *)pCertMain, sizeof(uint32_t));
+        rc = CCSbVerifyNvCounter(hwBaseAddress, swVer, certPkgInfo);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("CCSbVerifyNvCounter failed\n");
+                return rc;
+        }
+
+        /* 4. load and verify sw comps */
+        swImagesData.swCodeEncType = (CCswCodeEncType_t)(flags.flagsBits.swCodeEncType);
+        swImagesData.swLoadVerifyScheme = (CCswLoadVerifyScheme_t)(flags.flagsBits.swLoadVerifyScheme);
+        swImagesData.swCryptoType = (CCswCryptoType_t)(flags.flagsBits.swCryptoType);
+        swImagesData.numOfSwComps = (flags.flagsBits.numOfSwCmp);
+
+        /* move the pointers for nonce and images by sizeof bytes instead of using struct fiels, since  pCertMain is not word aligned */
+        UTIL_MemCopy((uint8_t *)swImagesData.nonce, (uint8_t *)(((unsigned long)pCertMain) + sizeof(uint32_t)), sizeof(CCSbNonce_t));
+        swImagesData.pSwCompsData = (uint8_t *)(((unsigned long)pCertMain) + sizeof(uint32_t) + sizeof(CCSbNonce_t));
+
+        rc = CCCertValidateSWComps(flashReadFunc,
+                                   userContext,
+                                   hwBaseAddress,
+                                   certPkgInfo->keyIndex,
+                                   &swImagesData,
+                                   pSwImagesAddData,
+                                   pWorkspaceInfo->pBuffer,
+                                   pWorkspaceInfo->bufferSize);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("CCCertValidateSWComps failed\n");
+                return rc;
+        }
+
+        /* 5. Assuming there is only one content certificate in the chain, */
+        /*    Set the sw version in the OTP (if required)  */
+        rc = CCSbSetNvCounter(hwBaseAddress, certPkgInfo);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("CCSbSetNvCounter failed\n");
+                return rc;
+        }
+        return CC_OK;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_verify.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_verify.h
new file mode 100644
index 0000000..09f78fa
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/common/common_cert_verify.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _COMMON_CERT_VERIFY_H
+#define _COMMON_CERT_VERIFY_H
+
+#include "common_cert_parser.h"
+
+/**
+   @brief This function is used for basic verification of all secure boot/debug certificates.
+   it verifies type, size, public key and signature.
+   The function returns pointers to certificate proprietary header, and body.
+   The function:
+   1. calls CCCertFieldsParse() - according to certificate type(x509 or not),
+                copy public key, Np and signature to workspace,
+                and returns pointers to certificate proprietary header, and body.
+   2. Calls CCCertValidateHeader(), and verify cert type (as expected) and size (according to type).
+   3. If expected public key hash is NULL, call CC_BsvPubKeyHashGet() with HBK type defined in certificate to get OTP HBK
+   4. Calls verifyCertPubKeyAndSign() To verify public key and certificate RSA signature.
+ */
+CCError_t CCCommonCertVerify(unsigned long   hwBaseAddress,
+                             BufferInfo32_t  *pCertInfo,
+                             CertFieldsInfo_t  *pCertFields,  // in/out
+                             CCSbCertInfo_t  *pSbCertInfo,   //in/out
+                             BufferInfo32_t  *pWorkspaceInfo,
+                             BufferInfo32_t  *pX509HeaderInfo);
+
+
+/**
+   @brief This function verifies key certificate specific fields.
+ */
+uint32_t CCCommonKeyCertVerify(unsigned long   hwBaseAddress,
+                               uint32_t certFlags,
+                               uint8_t  *pCertMain,
+                               CCSbCertInfo_t *pCertPkgInfo);
+
+/**
+   @brief This function   verifies content certificate specific fields
+        Verifies certificate flags, NV counter according to HBK type
+        Call CCCertValidateSWComps()
+        Call CCSbSetNvCounter()
+ */
+uint32_t CCCommonContentCertVerify(CCSbFlashReadFunc flashReadFunc,
+                                   void *userContext,
+                                   unsigned long hwBaseAddress,
+                                   CCAddr_t certStoreAddress,
+                                   CCSbCertInfo_t *certPkgInfo,
+                                   uint32_t certFlags,
+                                   uint8_t *pCertMain,
+                                   BufferInfo32_t  *pWorkspaceInfo);
+
+
+#endif /* _COMMON_CERT_VERIFY_H */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver.c
new file mode 100644
index 0000000..e77b9c8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+
+#include "cc_pal_types.h"
+#include "secureboot_basetypes.h"
+#include "secureboot_error.h"
+#include "secureboot_general_hwdefs.h"
+#include "util.h"
+#include "cc_hal_sb.h"
+#include "crypto_driver_defs.h"
+#include "crypto_driver.h"
+#include "cc_hal_sb_plat.h"
+#include "cc_pal_sb_plat.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Internal data ******************************/
+static const uint32_t HASH_LARVAL_SHA256[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+
+/*!
+ * This function initializes the AES and HASH HW engines according to required crypto operations.
+ * This should be the first function called.
+ *
+ * @param[in] hwBaseAddress     - cryptocell base address
+ * @param[in] aesKeyAddr    - the address of the AES key
+ * @param[in] aesIvAddr     - the address of the AES IV
+ * @param[in] cryptoDriverMode  - can be one of CryptoDriverMode_t
+ *
+ */
+void SBROM_CryptoInitDriver(unsigned long hwBaseAddress, CCDmaAddr_t aesKeyAddr, CCDmaAddr_t aesIvAddr, CryptoDriverMode_t cryptoDriverMode)
+{
+    uint32_t aesCtrl = 0, address = 0,  irrVal = 0;
+    uint32_t *ivPtr = (uint32_t*)aesIvAddr;
+    uint32_t *keyPtr = (uint32_t*)aesKeyAddr;
+    int32_t i = 0;
+
+    /*poll on DOUT/DIN DMA busy */
+    CC_SB_WAIT_ON_DOUT_DMA_BUSY(hwBaseAddress);
+    CC_SB_WAIT_ON_DIN_DMA_BUSY(hwBaseAddress);
+
+    /* clear all interrupts before starting the engine */
+    SB_HalClearInterruptBit(hwBaseAddress, 0xFFFFFFFFUL);
+
+    /* Initialze AES block */
+    /************************/
+    if (cryptoDriverMode != CRYPTO_DRIVER_HASH_MODE){
+
+        CC_SB_WAIT_ON_AES_BUSY();
+
+        /* enable aes clock */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress,AES_CLK_ENABLE) ,SB_SET_CLK_ENABLE_VAL);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress,DMA_CLK_ENABLE) ,SB_SET_CLK_ENABLE_VAL);
+
+        /* Zero AES_REMAINING_BYTES */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_REMAINING_BYTES) ,0);
+
+        /* write the key */
+        address = SB_REG_ADDR(hwBaseAddress, AES_KEY_0_0);
+        for (i=0; i<4; i++){
+
+            SB_HAL_WRITE_REGISTER(address, keyPtr[i]);
+            address = address + 4;
+        }
+
+        if (cryptoDriverMode == CRYPTO_DRIVER_AES_CMAC_MODE){
+
+            aesCtrl |= (CC_SB_CMAC_MODE << SB_AES_CTRL_MODE_BIT_SHIFT);
+
+            /* write 0 to initial counter for CMAC */
+            address = SB_REG_ADDR(hwBaseAddress, AES_IV_0_0);
+            for (i=0; i<4; i++){
+                SB_HAL_WRITE_REGISTER(address, 0x0UL);
+                address = address + 4;
+            }
+
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CMAC_INIT) ,0x1);
+
+        } else {
+
+            aesCtrl |= (CC_SB_CTR_MODE << SB_AES_CTRL_MODE_BIT_SHIFT);
+
+            /* write the initial value for CTR */
+            address = SB_REG_ADDR(hwBaseAddress, AES_CTR_0_0);
+            for (i=0; i<4; i++){
+                SB_HAL_WRITE_REGISTER(address, ivPtr[i]);
+                address = address + 4;
+            }
+        }
+
+        /* configure AES mode and direction */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CONTROL) ,aesCtrl);
+    }
+
+    /* Initialze Hash block */
+    /************************/
+    if (cryptoDriverMode == CRYPTO_DRIVER_HASH_MODE || cryptoDriverMode == CRYPTO_DRIVER_AES_CTR_TO_HASH_MODE){
+
+        CC_SB_WAIT_ON_HASH_BUSY();
+
+        /* enable hash clock */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CLK_ENABLE) ,SB_SET_CLK_ENABLE_VAL);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,SB_SET_CLK_ENABLE_VAL);
+
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_EN) ,1);
+
+
+        /* reset the current length of message being processed */
+        address = SB_REG_ADDR(hwBaseAddress, HASH_CUR_LEN_0);
+        for (i=0; i<2; i++){
+            SB_HAL_WRITE_REGISTER(address, 0);
+            address = address + 4;
+        }
+
+        /* setting the register HASH control register with the calculated value */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CONTROL) ,SB_HASH_CTL_SHA256_VAL);
+
+        /* initialize the HASH vectors */
+        address = SB_REG_ADDR(hwBaseAddress, HASH_H7);
+        for (i=HASH_DIGEST_SIZE_IN_WORDS-1; i>=0; i--){
+            SB_HAL_WRITE_REGISTER(address, HASH_LARVAL_SHA256[i]);
+            address = address - 4;
+        }
+
+        /* wait on crypto busy to assure that Hash initialized values are set! */
+        CC_SB_WAIT_ON_CRYPTO_BUSY(hwBaseAddress);
+    }
+
+    switch (cryptoDriverMode){
+    case CRYPTO_DRIVER_HASH_MODE:
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,SB_CRYPTO_CTL_HASH_MODE);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+        break;
+    case CRYPTO_DRIVER_AES_CTR_MODE:
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,SB_CRYPTO_CTL_AES_MODE);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+        break;
+    case CRYPTO_DRIVER_AES_CTR_TO_HASH_MODE:
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,SB_CRYPTO_CTL_AES_TO_HASH_MODE);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, irrVal, 1);
+        break;
+    case CRYPTO_DRIVER_AES_CMAC_MODE:
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,SB_CRYPTO_CTL_AES_MODE);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, irrVal, 1);
+    default:
+        break;
+    }
+
+    /* mask unneeded interrupt */
+    SB_HalMaskInterrupt(hwBaseAddress, irrVal);
+
+    return;
+}
+
+
+/*!
+ * This function is used to do cryptographic operations on a block(s) of data using HASH and/or AES machines.
+ *
+ * @param[in] hwBaseAddress     - cryptocell base address
+ * @param[in] inputDataAddr     - address of the users data input buffer.
+ * @param[out] outputDataAddr   - address of the users data output buffer.
+ * @param[in] BlockSize      - number of bytes to update.
+ *                                if it is not the last block, the size must be a multiple of AES blocks.
+ * @param[in] isLastBlock   - if false, just updates the data; otherwise, enable hash padding
+ * @param[in] cryptoDriverMode  - can be one of CryptoDriverMode_t
+ * @param[in] isWaitForCryptoCompletion -enum for crypto operation completion mode
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from secureboot_error.h
+ */
+CCError_t SBROM_CryptoUpdateBlockDriver(unsigned long hwBaseAddress, CCDmaAddr_t inputDataAddr, CCDmaAddr_t outputDataAddr, uint32_t BlockSize,
+                        uint8_t isLastBlock, CryptoDriverMode_t cryptoDriverMode,
+                    CCSbCryptoCompletionMode_t isWaitForCryptoCompletion)
+{
+    uint32_t irrVal = 0;
+    uint32_t *outputPtr = (uint32_t*)outputDataAddr;
+
+    /* for IOT, we MUST handle the crypto operation in synchronic way */
+    if (isWaitForCryptoCompletion != CC_SB_CRYPTO_COMPLETION_WAIT_UPON_END)
+        return CC_SB_DRV_ILLEGAL_INPUT_ERR;
+
+    if (cryptoDriverMode == CRYPTO_DRIVER_AES_CMAC_MODE){
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_REMAINING_BYTES) ,BlockSize);
+    }
+
+    if (cryptoDriverMode == CRYPTO_DRIVER_AES_CTR_MODE || cryptoDriverMode == CRYPTO_DRIVER_AES_CTR_TO_HASH_MODE){
+
+        /* configure destination - address and size */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DST_LLI_WORD0) ,outputDataAddr);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DST_LLI_WORD1) ,BlockSize);
+
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, DOUT_TO_MEM_INT, irrVal, 1);
+    } else {
+
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, MEM_TO_DIN_INT, irrVal, 1);
+    }
+
+    /* use HW padding (NA for zero bytes) for last block */
+    if (cryptoDriverMode == CRYPTO_DRIVER_HASH_MODE || cryptoDriverMode == CRYPTO_DRIVER_AES_CTR_TO_HASH_MODE){
+        if (isLastBlock) {
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AUTO_HW_PADDING) ,1);
+        } else {
+            /* if not last block, then, check the data in size */
+            if ((BlockSize % SB_HASH_BLOCK_SIZE_BYTES) != 0) {
+                return CC_SB_DRV_ILLEGAL_SIZE_ERR;
+            }
+
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AUTO_HW_PADDING) ,0);
+        }
+    }
+
+    /* configure source - address and size */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD0) ,inputDataAddr);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD1) ,BlockSize);
+
+    SB_HalWaitInterrupt(hwBaseAddress, irrVal);
+
+    CC_SB_WAIT_ON_CRYPTO_BUSY(hwBaseAddress);
+
+    /* read the results */
+    if (cryptoDriverMode == CRYPTO_DRIVER_AES_CMAC_MODE){
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_0) ,outputPtr[0]);
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_1) ,outputPtr[1]);
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_2) ,outputPtr[2]);
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_3) ,outputPtr[3]);
+    }
+
+    if (isLastBlock) {
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress,AES_CLK_ENABLE) ,SB_SET_CLK_DISABLE_VAL);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress,DMA_CLK_ENABLE) ,SB_SET_CLK_DISABLE_VAL);
+    }
+
+    return CC_OK;
+}
+
+
+/*!
+ * This function returns the digest result of crypto hash operation.
+ *
+ * @param[in] hwBaseAddress     - cryptocell base address
+ * @param[out] hashResult   - the HASH result.
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from secureboot_error.h
+ */
+CCError_t SBROM_CryptoFinishDriver(unsigned long hwBaseAddress, CCDmaAddr_t hashResult)
+{
+
+    uint32_t *pHashRes = (uint32_t*)hashResult;
+    uint32_t address = 0;
+    int32_t i = 0;
+
+    address = SB_REG_ADDR(hwBaseAddress, HASH_H0);
+    for (i=0; i<HASH_DIGEST_SIZE_IN_WORDS; i++){
+        SB_HAL_READ_REGISTER(address ,pHashRes[i]);
+        address = address + 4;
+        pHashRes[i] = UTIL_INVERSE_UINT32_BYTES(pHashRes[i]);
+    }
+
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress,HASH_CLK_ENABLE) ,SB_SET_CLK_DISABLE_VAL);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress,DMA_CLK_ENABLE) ,SB_SET_CLK_DISABLE_VAL);
+
+    return CC_OK;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver.h
new file mode 100644
index 0000000..6f34570
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _CRYPTO_DRIVER_H
+#define _CRYPTO_DRIVER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "secureboot_basetypes.h"
+#include "bsv_crypto_api.h"
+
+
+/*!
+ * @brief This function gives the functionality of integrated hash
+ *
+ * @param[in] hwBaseAddress     - CryptoCell base address
+ * @param[out] hashResult   - the HASH result.
+ *
+ */
+#define SBROM_CryptoHash(wBaseAddress, inputDataAddr, dataSize, hashBuff)       \
+    CC_BsvSHA256(hwBaseAddress, (uint8_t *)inputDataAddr, (size_t)dataSize, hashBuff);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver_defs.h
new file mode 100644
index 0000000..333c331
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/reg/crypto_driver_defs.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CRYPTO_DRIVER_DEFS_H
+#define _CRYPTO_DRIVER_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types_plat.h"
+#include "cc_sec_defs.h"
+#include "cc_crypto_defs.h"
+/******************************************************************************
+*                           DEFINITIONS
+******************************************************************************/
+#define SB_SET_CLK_ENABLE_VAL       0x1UL
+#define SB_SET_CLK_DISABLE_VAL      0x0UL
+
+#define SB_CRYPTO_CTL_AES_MODE      0x1UL
+#define SB_CRYPTO_CTL_AES_TO_HASH_MODE  0xAUL
+#define SB_CRYPTO_CTL_HASH_MODE     0x7UL
+
+#define SB_AES_ENCRYPT          0x0UL
+#define SB_AES_DECRYPT          0x1UL
+
+#define SB_HASH_CTL_SHA256_VAL      0x2UL
+#define SB_AES_CTRL_MODE_BIT_SHIFT      2
+
+#define SB_HASH_BLOCK_SIZE_BYTES    64
+
+typedef enum {
+    CC_SB_ECB_MODE      = 0,
+    CC_SB_CBC_MODE      = 1,
+    CC_SB_CTR_MODE      = 2,
+    CC_SB_CBC_MAC_MODE  = 3,
+    CC_SB_CMAC_MODE     = 7,
+    CC_SB_MAX_MODES     = 0x7FFFFFFFUL
+
+}CCSbAesModes;
+
+
+/* Poll on the DOUT DMA busy till it is = 0 */
+#define CC_SB_WAIT_ON_DOUT_DMA_BUSY(hwBaseAddress)                      \
+    do {                                            \
+        uint32_t regVal;                                \
+        do {                                        \
+            SB_HAL_READ_REGISTER( SB_REG_ADDR(hwBaseAddress, DOUT_MEM_DMA_BUSY), regVal);   \
+        }while( regVal );                               \
+    }while(0)
+
+/* Poll on the DIN DMA busy till it is = 0 */
+#define CC_SB_WAIT_ON_DIN_DMA_BUSY(hwBaseAddress)                       \
+    do {                                            \
+        uint32_t regVal;                                \
+        do {                                        \
+            SB_HAL_READ_REGISTER( SB_REG_ADDR(hwBaseAddress, DIN_MEM_DMA_BUSY), regVal);    \
+        }while( regVal );                               \
+    }while(0)
+
+/* Poll on the DOUT DMA busy till it is = 0 */
+#define CC_SB_WAIT_ON_CRYPTO_BUSY(hwBaseAddress)                        \
+    do {                                            \
+        uint32_t regVal;                                \
+        do {                                        \
+            SB_HAL_READ_REGISTER( SB_REG_ADDR(hwBaseAddress, CRYPTO_BUSY), regVal);     \
+        }while( regVal );                               \
+    }while(0)
+
+/* Poll on the AES busy till it is = 0 */
+#define CC_SB_WAIT_ON_AES_BUSY()\
+    do {\
+        uint32_t regVal=1;\
+            do {\
+            SB_HAL_READ_REGISTER( SB_REG_ADDR(hwBaseAddress, AES_BUSY), regVal);    \
+                }while( regVal );\
+        }while(0)
+
+/* Poll on the HASH busy till it is = 0 */
+#define CC_SB_WAIT_ON_HASH_BUSY()\
+    do {\
+        uint32_t regVal=1;\
+            do {\
+            SB_HAL_READ_REGISTER( SB_REG_ADDR(hwBaseAddress, HASH_BUSY), regVal);   \
+                }while( regVal );\
+        }while(0)
+
+/* Use constant counter ID and AXI ID */
+#define SB_COUNTER_ID   0
+
+
+/* The AES block size in words and in bytes */
+#define AES_BLOCK_SIZE_IN_WORDS 4
+
+/* The size of the IV or counter buffer */
+#define AES_IV_COUNTER_SIZE_IN_WORDS   AES_BLOCK_SIZE_IN_WORDS
+#define AES_IV_COUNTER_SIZE_IN_BYTES  (AES_IV_COUNTER_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* The size of the AES KEY in words and bytes */
+#define AES_KEY_SIZE_IN_WORDS AES_BLOCK_SIZE_IN_WORDS
+#define AES_KEY_SIZE_IN_BYTES (AES_KEY_SIZE_IN_WORDS * sizeof(uint32_t))
+
+#define AES_Key128Bits_SIZE_IN_WORDS    AES_BLOCK_SIZE_IN_WORDS
+#define AES_Key128Bits_SIZE_IN_BYTES    AES_BLOCK_SIZE_IN_BYTES
+#define AES_Key256Bits_SIZE_IN_WORDS    8
+#define AES_Key256Bits_SIZE_IN_BYTES    (AES_Key256Bits_SIZE_IN_WORDS * sizeof(uint32_t))
+
+
+/* Hash IV+Length */
+#define HASH_DIGEST_SIZE_IN_WORDS   8
+#define HASH_DIGEST_SIZE_IN_BYTES   (HASH_DIGEST_SIZE_IN_WORDS * sizeof(uint32_t))
+#define HASH_LENGTH_SIZE_IN_WORDS   4
+#define HASH_LENGTH_SIZE_IN_BYTES   (HASH_LENGTH_SIZE_IN_WORDS * sizeof(uint32_t))
+
+
+/******************************************************************************
+*               TYPE DEFINITIONS
+******************************************************************************/
+
+
+#define NVM_HASH_Result_t CCHashResult_t
+
+/* Defines the IV counter buffer  - 16 bytes array */
+typedef uint32_t AES_Iv_t[AES_IV_COUNTER_SIZE_IN_WORDS];
+
+/* Defines the AES key buffer */
+typedef uint32_t AES_Key_t[AES_KEY_SIZE_IN_WORDS];
+
+/* Defines the AES CMAC output result */
+typedef uint8_t AES_CMAC_RESULT_t[AES_BLOCK_SIZE_IN_BYTES];
+
+
+typedef enum {
+    CRYPTO_DRIVER_HASH_MODE     = 0,
+    CRYPTO_DRIVER_AES_CTR_MODE  = 1,
+    CRYPTO_DRIVER_AES_CTR_TO_HASH_MODE = 2,
+    CRYPTO_DRIVER_AES_CMAC_MODE = 3
+}CryptoDriverMode_t;
+
+
+/* enum definitons for crypto operation completion mode */
+typedef enum
+{
+    CC_SB_CRYPTO_COMPLETION_NO_WAIT = 0,
+    CC_SB_CRYPTO_COMPLETION_NO_WAIT_ASK_ACK = 1,
+    CC_SB_CRYPTO_COMPLETION_WAIT_UPON_START = 2,
+    CC_SB_CRYPTO_COMPLETION_WAIT_UPON_END = 3
+} CCSbCryptoCompletionMode_t;
+
+
+
+/******************************************************************************
+*                HW engines related definitions
+******************************************************************************/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_bsv.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_bsv.h
new file mode 100644
index 0000000..991c5e8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_bsv.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef RSA_H
+#define RSA_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#include "cc_pka_hw_plat_defs.h"
+#include "cc_sec_defs.h"
+#include "cc_pal_types_plat.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+#define CC_BOOT_RSA_VERIFIER_ALG_FAILURE    (CC_SB_RSA_BASE_ERROR + 0x00000001)
+#define CC_BOOT_RSA_VERIFIER_CMP_FAILURE    (CC_SB_RSA_BASE_ERROR + 0x00000002)
+
+/* the modulus size ion bits */
+#define RSA_EXP_SIZE_WORDS          1
+
+
+/* PKA max count of SRAM registers: */
+#define RSA_HW_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS  PKA_MAX_COUNT_OF_PHYS_MEM_REGS /*32*/
+/* PKA required count of SRAM registers: */
+#define RSA_PKA_REQUIRED_COUNT_OF_PHYS_MEM_REGS     7
+
+/* maximal size of extended register in "big PKA words" and in 32-bit words:  *
+   the size defined according to RSA as more large, and used to define some   *
+*  auxiliary buffers sizes                                */
+#define RSA_PKA_MAX_REGISTER_SIZE_IN_PKA_WORDS \
+        ((SB_CERT_RSA_KEY_SIZE_IN_BITS + RSA_PKA_EXTRA_BITS + RSA_PKA_BIG_WORD_SIZE_IN_BITS - 1)/RSA_PKA_BIG_WORD_SIZE_IN_BITS + 1)
+#define RSA_PKA_MAX_REGISTER_SIZE_WORDS  (RSA_PKA_MAX_REGISTER_SIZE_IN_PKA_WORDS*(RSA_PKA_BIG_WORD_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD))
+#define RSA_PKA_MAX_REGISTER_SIZE_BITS   (RSA_PKA_MAX_REGISTER_SIZE_WORDS * CC_BITS_IN_32BIT_WORD)
+
+/* size of Barrett modulus tag NP, used in PKA algorithms */
+#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS    (RSA_PKA_BIG_WORD_SIZE_IN_BITS + RSA_PKA_EXTRA_BITS)
+#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BYTES   (CALC_FULL_BYTES(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
+#define RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS   (CALC_FULL_32BIT_WORDS(RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_BITS))
+
+/* size of buffer for Barrett modulus tag NP, used for both 64- and 128-bits PKA */
+#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS  5 /*maximal of RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS*/
+#define RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES  (RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE)
+
+/* the public exponent */
+#define RSA_PUBL_EXP_SIZE_IN_BITS  17UL
+#define RSA_PUBL_EXP_SIZE_IN_BYTES (CALC_FULL_BYTES(RSA_PUBL_EXP_SIZE_IN_BITS))
+#ifndef BIG__ENDIAN
+#define RSA_EXP_VAL          0x00010001UL
+#else
+#define RSA_EXP_VAL          0x01000100UL
+#endif
+
+/* RSA PSS verify definitions */
+#define RSA_HASH_LENGTH  32 /*SHA256*/
+#define RSA_PSS_SALT_LENGTH  32
+#define RSA_PSS_PAD1_LEN     8
+
+/* RSA Encrypt definitions */
+#define RSA_ENCR_RND_PS_SIZE_BYTES   8
+#define RSA_ENCR_DATA_IN_SIZE_BYTES  16
+
+#define RSA_PKCS1_VER21   1
+
+
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+
+/*************************************************************************/
+/**
+
+   \brief RSA_PSS_Verify implements the Verify algorithm
+   as defined in PKCS#1 v2.1
+
+   @param[in] hwBaseAddress - HW base address. Relevant for HW
+                              implementation, for SW it is ignored.
+   @param[in] dataInHashResult - the DataIn hash result.
+   @param[in] pN           - the modulus (2048 bits).
+   @param[in] pNp          - the Barrett tag. Relevant for HW
+                              implementation, for SW it is ignored.
+   @param[in] pSig   - the pointer to the signature to be
+                   verified.
+        Note: All input arrays are in LE format of bytes and words.
+
+   @return CCError_t - On success the value CC_OK is returned,
+           on failure - a value from secureboot_error.h
+*/
+
+CCError_t RSA_PSS_Verify( unsigned long    hwBaseAddress,
+                           CCHashResult_t  dataInHashResult,
+                           uint32_t      *pN,
+                           uint32_t      *pNp,
+                           uint32_t      *pSig);
+
+
+/*************************************************************************/
+/**
+ * @brief The RSA_CalcExponent calculates The following:
+ *
+ *                   Res = (Base ^ Exp) mod N ( Exp = 0x10001 )
+ *
+ *        The calculation is done in a secured way using the PIC.
+ *
+ * @param[in] hwBaseAddress - HW base address. Relevant for HW
+ *                      implementation, for SW it is ignored.
+ * @Base_ptr[in]         - The pointer to the base buffer.
+ * @pN[in]            - The pointer to the modulus buffer (2048 bits).
+ * @pNp[in]           - The np vector buffer (160 bits). Relevant for HW
+ *                         implementation, for SW it is ignored.
+ * @pRes[out]         - The pointer to the buffer that will contain the result.
+ *
+ *     NOTE:  The SW version of the function uses a temp buffer, pointed by
+ *            global pointer gSecBootExpTempBuff; the size of the buffer must be
+ *            not less than 8*SB_CERT_RSA_KEY_SIZE_IN_WORDS + 1 word.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+void RSA_CalcExponent(
+        unsigned long hwBaseAddress,
+        uint32_t *Base_ptr,
+        uint32_t *pN,
+        uint32_t *pNp,
+        uint32_t *pRes);
+
+
+/*************************************************************************/
+/**
+ * @brief The RSA_CalcNp calculates Np value and saves it into pNp:
+ *
+ * @param[in] hwBaseAddress - The HW base address. Relevant for HW
+ *                      implementation, for SW it is ignored.
+ * @pN[in]    - The pointer to the modulus buffer.
+ * @pNp[out]  - The pointer to Np vector buffer. Its size must be >= 160.
+ */
+void RSA_CalcNp( unsigned long hwBaseAddress,
+                        uint32_t *pN,
+                        uint32_t *pNp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_exp.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_exp.c
new file mode 100644
index 0000000..18936d7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_exp.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT HOST_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+#include "rsa_pki_pka.h"
+#include "rsa_bsv.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+#ifdef PKA_DEBUG
+  extern uint8_t tempRes[SB_CERT_RSA_KEY_SIZE_IN_WORDS+2*RSA_PKA_BIG_WORD_SIZE_IN_32_BIT_WORDS];
+  extern uint32_t g_SramPkaAddr;
+#endif
+
+/* ********** Internal private functions ****************** */
+
+
+/* ************************** public functions ********************************* */
+
+
+/**
+ * @brief The RSA_CalcExponent calculates The following:
+ *
+ *                   Res = (Base ^ Exp) mod N. ( Exp = 0x10001 )
+ *
+ *        The calculation is done in a secured way using the PIC.
+ *
+ * @hwBaseAddress        - Cryptocell base address
+ * @Base_ptr[in]         - The pointer to the base buffer.
+ * @N_ptr[in]            - The pointer to the modulus buffer.
+ * @Np_ptr[in]           - The Np vector buffer..
+ *                       - Its size must be 160.
+ * @Res_ptr[out]         - The pointer to the buffer that will contain the result.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure a
+ *                        value MODULE_* as defined in ...
+ */
+void RSA_CalcExponent( unsigned long hwBaseAddress,
+                       uint32_t *Base_ptr,
+                       uint32_t *N_ptr,
+                       uint32_t *Np_ptr,
+                       uint32_t *Res_ptr )
+{
+
+   /* Fix value for the Exponent */
+   uint32_t Exp = RSA_EXP_VAL;
+   uint32_t regsCount = 7; /*5 working + 2 temp registers*/
+
+  /* FUNCTION LOGIC */
+
+   /* .................... initialize local variables ...................... */
+   /* ---------------------------------------------------------------------- */
+
+    /* initialize the PKA engine on default mode */
+    RSA_PKA_InitPka(SB_CERT_RSA_KEY_SIZE_IN_BITS, regsCount, hwBaseAddress);
+
+    /* copy modulus N into r0 register */
+    RSA_HW_PKI_PKA_CopyDataIntoPkaReg( 0/*dstReg*/, 1/*LenID*/,
+                   N_ptr/*src_ptr*/, SB_CERT_RSA_KEY_SIZE_IN_WORDS, hwBaseAddress );
+
+    /* copy the NP into r1 register NP */
+    RSA_HW_PKI_PKA_CopyDataIntoPkaReg( 1/*dstReg*/, 1/*LenID*/, Np_ptr/*src_ptr*/,
+                      RSA_HW_PKI_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS, hwBaseAddress );
+
+    /* copy input data into PKI register: DataIn=>r2 */
+    RSA_HW_PKI_PKA_CopyDataIntoPkaReg( 2/*dstReg*/, 1/*LenID*/,
+             Base_ptr, SB_CERT_RSA_KEY_SIZE_IN_WORDS, hwBaseAddress );
+
+    /* copy exponent data PKI register: e=>r3 */
+    RSA_HW_PKI_PKA_CopyDataIntoPkaReg( 3/*dstReg*/, 1/*LenID*/,
+             &Exp, RSA_EXP_SIZE_WORDS, hwBaseAddress );
+
+
+    /* .. calculate the exponent Res = OpA**OpB mod N;                  ... */
+    /* -------------------------------------------------------------------- */
+    RSA_HW_PKI_PKA_ModExp( 0/*LenID*/, 2/*OpA*/, 3/*OpB*/, 4/*Res*/, 0/*Tag*/, hwBaseAddress );
+
+    /* copy result into output: r4 =>DataOut */
+    RSA_HW_PKI_PKA_CopyDataFromPkaReg( Res_ptr, SB_CERT_RSA_KEY_SIZE_IN_WORDS,
+                   4/*srcReg*/, hwBaseAddress );
+
+    /* Finish PKA operations (waiting PKI done and close PKA clocks) */
+    RSA_HW_PKI_PKA_FinishPKA( hwBaseAddress );
+
+}/* END OF RSA_CalcExponent */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_hwdefs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_hwdefs.h
new file mode 100644
index 0000000..f06950c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_hwdefs.h
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef RSA_HWDEFS_H
+#define RSA_HWDEFS_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+#include "secureboot_general_hwdefs.h"
+#include "cc_pka_hw_plat_defs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* PKA big word size in bits */
+#define RSA_PKA_BIG_WORD_SIZE_IN_BITS  CC_PKA_WORD_SIZE_IN_BITS
+#define RSA_PKA_BIG_WORD_SIZE_IN_BYTES  (RSA_PKA_BIG_WORD_SIZE_IN_BITS/8)
+#define RSA_PKA_BIG_WORD_SIZE_IN_32_BIT_WORDS  (RSA_PKA_BIG_WORD_SIZE_IN_BITS/32)
+
+#define RSA_PKA_EXTRA_BITS  PKA_EXTRA_BITS
+
+/* PKA max count of SRAM registers: */
+#define RSA_HW_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS  PKA_MAX_COUNT_OF_PHYS_MEM_REGS
+
+/* The maximal size of allowed PKA physical registers memory including tables */
+#define RSA_PKA_MAX_REGS_MEM_SIZE_BYTES   (6 * 1024)
+
+/* SRAM definitions */
+#define RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR           g_SramPkaAddr
+
+/* The maximal count of allowed sizes of PKA operands or register-variables */
+#define RSA_PKA_MAX_COUNT_OF_REGS_SIZES                   8 /*PKA_MAX_COUNT_OF_REGS_SIZES */
+#define RSA_PKA_MAX_COUNT_OF_ADDITIONAL_REGS          10
+#define RSA_PKA_SRAM_REGS_MEM_OFFSET_WORDS                RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR
+
+
+/* PKA OPCODE register fields positions (low bit position) */
+#define RSA_HW_PKI_PKA_OPCODE_TAG_POS                               0
+#define RSA_HW_PKI_PKA_OPCODE_RESULT_POS                            6
+#define RSA_HW_PKI_PKA_OPCODE_R_DISCARD_POS                        11
+#define RSA_HW_PKI_PKA_OPCODE_OPERAND_2_POS                        12
+#define RSA_HW_PKI_PKA_OPCODE_OPERAND_2_IMMED_POS                  17
+#define RSA_HW_PKI_PKA_OPCODE_OPERAND_1_POS                        18
+#define RSA_HW_PKI_PKA_OPCODE_OPERAND_1_IMMED_POS                  23
+#define RSA_HW_PKI_PKA_OPCODE_LEN_POS                              24
+#define RSA_HW_PKI_PKA_OPCODE_OPERATION_ID_POS                     27
+
+
+/* PKA N_NP_T0_T1 register fields positions (low bit position) */
+#define RSA_HW_PKI_PKA_N_NP_T0_T1_REG_N_POS                         DX_N_NP_T0_T1_ADDR_N_VIRTUAL_ADDR_BIT_SHIFT
+#define RSA_HW_PKI_PKA_N_NP_T0_T1_REG_NP_POS                        DX_N_NP_T0_T1_ADDR_NP_VIRTUAL_ADDR_BIT_SHIFT
+#define RSA_HW_PKI_PKA_N_NP_T0_T1_REG_T0_POS                        DX_N_NP_T0_T1_ADDR_T0_VIRTUAL_ADDR_BIT_SHIFT
+#define RSA_HW_PKI_PKA_N_NP_T0_T1_REG_T1_POS                        DX_N_NP_T0_T1_ADDR_T1_VIRTUAL_ADDR_BIT_SHIFT
+
+/* PKA N_NP_T0_T1 register default (reset) value: N=0, NP=1, T0=30, T1=31 */
+#define PKA_N                                                    0UL
+#define PKA_NP                                                   1UL
+#define PKA_T0                                                  30UL
+#define PKA_T1                                                  31UL
+#define RSA_HW_PKI_PKA_N_NP_T0_T1_REG_DEFAULT_VAL                  ( PKA_N  << RSA_HW_PKI_PKA_N_NP_T0_T1_REG_N_POS  | \
+                                                                  PKA_NP << RSA_HW_PKI_PKA_N_NP_T0_T1_REG_NP_POS | \
+                                                                  PKA_T0 << RSA_HW_PKI_PKA_N_NP_T0_T1_REG_T0_POS | \
+                                                                  PKA_T1 << RSA_HW_PKI_PKA_N_NP_T0_T1_REG_T1_POS )
+
+/* PKA control values  */
+#define RSA_PKA_PIPE_READY                                   1
+#define RSA_PKA_OP_DONE                                      1
+#define RSA_PKA_SW_REST                                      1
+
+/* Machine Opcodes definitions (according to HW CRS ) */
+#define   PkaSepDone        0x00
+#define   PkaAdd            0x04
+#define   PkaAddIm          0x04
+#define   PkaSub            0x05
+#define   PkaSubIm          0x05
+#define   PkaNeg            0x05
+#define   PkaModAdd         0x06
+#define   PkaModAddIm       0x06
+#define   PkaModSub         0x07
+#define   PkaModSubIm       0x07
+#define   PkaModNeg         0x07
+#define   PkaAND            0x08
+#define   PkaTest0          0x08
+#define   PkaClr0           0x08
+#define   PkaClr            0x08
+#define   PkaOR             0x09
+#define   PkaCopy       0x09
+#define   PkaSetBit0        0x09
+#define   PkaXOR        0x0A
+#define   PkaFlip0      0x0A
+#define   PkaInvertBits     0x0A
+#define   PkaCompare        0x0A
+#define   PkaSHR0       0x0C
+#define   PkaSHR1           0x0D
+#define   PkaSHL0       0x0E
+#define   PkaSHL1       0x0F
+#define   PkaLMul       0x10
+#define   PkaModMul     0x11
+#define   PkaModMulNR       0x12
+#define   PkaModExp     0x13
+#define   PkaDiv        0x14
+#define   PkaModInv         0x15
+#define   PkaHMul       0x17
+#define   PkaModMulAcc      0x18
+#define   PkaModMulAccN     0x19
+#define   PkaSepInt         0x1A
+#define   PkaReduce         0x1B
+
+#define   PKA_MAX_OPCODE    0x1B
+
+
+/* **********************           MACROS          ******************************* */
+
+
+/* Full register (operation) size including extra bits + one PKA-word (64 or  *
+*  128 bits), rounded up to PKA words.                                        */
+#define GET_FULL_OP_SIZE_PKA_WORDS(opSizeInBits)     (((opSizeInBits)/RSA_PKA_BIG_WORD_SIZE_IN_BITS + (((opSizeInBits) & (RSA_PKA_BIG_WORD_SIZE_IN_BITS-1)) > 0)) + 1)
+
+/*************************************************************/
+/* Macros for waiting PKA machine ready states               */
+/*************************************************************/
+
+/* defining a macro for waiting to the PKA_PIPE_READY */
+#define RSA_PKA_WAIT_ON_PKA_PIPE_READY(VirtualHwBaseAddr) \
+do \
+{ \
+   volatile uint32_t output_reg_val; \
+   do \
+   { \
+    SB_HAL_READ_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_PIPE_RDY), output_reg_val ); \
+   }while( (output_reg_val & 0x01) != RSA_PKA_PIPE_READY ); \
+}while(0)
+
+/* defining a macro for waiting to the PKA_OP_DONE */
+#define RSA_PKA_WAIT_ON_PKA_DONE(VirtualHwBaseAddr) \
+do \
+{ \
+   volatile uint32_t output_reg_val; \
+   do \
+   { \
+    SB_HAL_READ_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_DONE), output_reg_val); \
+   }while( (output_reg_val & 0x01) != RSA_PKA_OP_DONE ); \
+}while(0)
+
+/******************************************************************/
+/* Macros for setting and reading sizes from PKA regsSizesTable   */
+/******************************************************************/
+
+
+/*  ReadRegSizeInTable:  Readss the size from regsSizesTable entry */
+#define RSA_PKA_ReadRegSize(SizeBits, EntryNum, VirtualHwBaseAddr) \
+    RSA_PKA_WAIT_ON_PKA_DONE( VirtualHwBaseAddr ); \
+    SB_HAL_READ_REGISTER( (SB_REG_ADDR(VirtualHwBaseAddr,PKA_L0) + 4*(EntryNum)), \
+                                (SizeBits) )
+
+/******************************************************************/
+/* Macros for setting and reading addresses of PKA data registers */
+/******************************************************************/
+
+/*The following macros are used for setting and reading the data registers addresses in mapping table.*/
+
+/*  GetRegAddress:  Returns the physical address of register VirtReg from mapping table  */
+#define RSA_PKA_GetRegAddress(VirtReg, VirtualHwBaseAddr) \
+ ( *((volatile uint32_t*)(SB_REG_ADDR(VirtualHwBaseAddr,MEMORY_MAP0) + 4*(VirtReg))) )
+
+/******************************************************************/
+/*          Macros for setting Full PKI opcode                    */
+/******************************************************************/
+
+#define RSA_PKA_FullOpCode( Opcode,LenID,IsAImmed,OpA,IsBImmed,OpB,ResDiscard,Res,Tag ) \
+   ( ((Opcode))      << RSA_HW_PKI_PKA_OPCODE_OPERATION_ID_POS     | \
+     ((LenID))       << RSA_HW_PKI_PKA_OPCODE_LEN_POS              | \
+     ((IsAImmed))    << RSA_HW_PKI_PKA_OPCODE_OPERAND_1_IMMED_POS  | \
+     ((OpA))         << RSA_HW_PKI_PKA_OPCODE_OPERAND_1_POS        | \
+     ((IsBImmed))    << RSA_HW_PKI_PKA_OPCODE_OPERAND_2_IMMED_POS  | \
+     ((OpB))         << RSA_HW_PKI_PKA_OPCODE_OPERAND_2_POS        | \
+     ((ResDiscard))  << RSA_HW_PKI_PKA_OPCODE_R_DISCARD_POS        | \
+     ((Res))         << RSA_HW_PKI_PKA_OPCODE_RESULT_POS           | \
+     ((Tag))         << RSA_HW_PKI_PKA_OPCODE_TAG_POS  )
+
+/******************************************************************/
+/*          Macros for reading and loading PKA memory data        */
+/******************************************************************/
+
+/* MACRO DEFINITIONS FOR WORKING WITH INDIRECT ACCESS TO SRAM PKA DATA REGISTERS */
+
+    /*These registers  not included in the HW_CC definitions because they are HOST registers */
+#ifdef CC_SB_INDIRECT_SRAM_ACCESS
+/* MACRO DEFINITIONS FOR WORKING WITH INDIRECT ACCESS TO SRAM PKA DATA REGISTERS */
+
+    #define RSA_PKA_SRAM_WRITE_CLR(VirtualHwBaseAddr, SizeWords) \
+    for(; ii < 4*(((SizeWords)+3)/4) ; ii++) { \
+        SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_WDATA), 0); \
+    }
+
+    #ifndef BIG__ENDIAN
+    /* macro to load a value to SRAM with 32-bit access */
+    #define RSA_HW_PKI_HW_LOAD_VALUE_TO_PKA_MEM(VirtualHwBaseAddr, Addr, Val) \
+    do \
+    { \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_ADDR), ((Addr)+ RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR)); \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_WDATA), (Val)); \
+    }while(0)
+    #else
+    #define RSA_HW_PKI_HW_LOAD_VALUE_TO_PKA_MEM(VirtualHwBaseAddr, Addr, Val) \
+    do \
+    { \
+       uint32_t tempVal; \
+       UTIL_ReverseMemCopy((uint8_t*)&tempVal , (uint8_t*)&Val , sizeof(uint32_t) ); \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_ADDR), ((Addr)+ RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR)); \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_WDATA), (tempVal)); \
+    }while(0)
+    #endif
+
+    #ifndef BIG__ENDIAN
+    /* macro to load block to SRAM memory */
+    #define RSA_HW_PKI_HW_LOAD_BLOCK_TO_PKA_MEM(VirtualHwBaseAddr, Addr, ptr, SizeWords) \
+    do \
+    { \
+       uint32_t ii; \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_ADDR), ((Addr)+RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR)); \
+       for(ii = 0; ii < (SizeWords); ii++) \
+       { \
+           SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_WDATA), ((uint32_t*)(ptr))[ii]); \
+       } \
+       RSA_PKA_SRAM_WRITE_CLR(VirtualHwBaseAddr, SizeWords) \
+    }while(0)
+    /* defining a macro to load a block to the PKA data memory */
+
+    #else
+    #define RSA_HW_PKI_HW_LOAD_BLOCK_TO_PKA_MEM(VirtualHwBaseAddr, Addr, ptr, SizeWords) \
+    do \
+    { \
+       uint32_t ii; \
+       uint32_t tempWord; \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_ADDR), ((Addr)+RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR)); \
+       for(ii = 0; ii < (SizeWords); ii++) \
+       { \
+           UTIL_ReverseMemCopy((uint8_t*)&tempWord , (uint8_t*)&(ptr)[ii] , sizeof(uint32_t) ); \
+           SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_WDATA), tempWord); \
+       } \
+       RSA_PKA_SRAM_WRITE_CLR(VirtualHwBaseAddr, SizeWords) \
+    }while(0)
+    #endif
+
+        /* macro to clear PKA memory: Addr must be alighned to PKA_WORD size */
+    #define RSA_HW_PKI_HW_CLEAR_PKA_MEM(VirtualHwBaseAddr, Addr, SizeWords) \
+    do \
+    { \
+       uint32_t ii; \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_ADDR), (Addr)); \
+       for( ii = 0; ii < (uint32_t)(SizeWords); ii++ ) \
+       { \
+        SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_WDATA), 0x0UL ); \
+       }\
+       RSA_PKA_SRAM_WRITE_CLR(VirtualHwBaseAddr, (SizeWords)); \
+    }while(0)
+
+    #ifndef BIG__ENDIAN
+    /* macro to read a value from the PKA data memory */
+    #define RSA_HW_PKI_HW_READ_VALUE_FROM_PKA_MEM(VirtualHwBaseAddr, Addr, Val) \
+    do \
+    { \
+       volatile uint32_t dummy; \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RADDR), ((Addr)+ RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR)); \
+       SB_HAL_READ_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RDATA), (dummy)); \
+       (Val) = dummy; \
+    }while(0)
+    #else
+    #define RSA_HW_PKI_HW_READ_VALUE_FROM_PKA_MEM(VirtualHwBaseAddr, Addr, Val) \
+    do \
+    { \
+       volatile uint32_t dummy; \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RADDR), ((Addr)+ RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR)); \
+       SB_HAL_READ_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RDATA), (dummy)); \
+       (Val) = dummy; \
+       UTIL_ReverseBuff((uint8_t*)&Val , sizeof(uint32_t) ); \
+    }while(0)
+    #endif
+
+    #ifndef BIG__ENDIAN
+    /* defining a macro to read a block from the PKA data memory */
+    #define RSA_HW_PKI_HW_READ_BLOCK_FROM_PKA_MEM(VirtualHwBaseAddr, Addr, ptr, SizeWords) \
+    do \
+    { \
+       uint32_t ii; \
+       volatile uint32_t dummy; \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RADDR), (Addr)); \
+       for(ii = 0; ii < (SizeWords); ii++) \
+       { \
+          SB_HAL_READ_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RDATA), (dummy));\
+          ((uint32_t*)(ptr))[ii] = (dummy); \
+       } \
+    }while(0)
+    #else
+    #define RSA_HW_PKI_HW_READ_BLOCK_FROM_PKA_MEM(VirtualHwBaseAddr, Addr, ptr, SizeWords) \
+    do \
+    { \
+       uint32_t ii; \
+       volatile uint32_t dummy; \
+       SB_HAL_WRITE_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RADDR), (Addr)); \
+       for(ii = 0; ii < (SizeWords); ii++) \
+       { \
+          SB_HAL_READ_REGISTER( SB_REG_ADDR(VirtualHwBaseAddr, PKA_SRAM_RDATA), (dummy));\
+          ((uint32_t*)(ptr))[ii] = (dummy); \
+          UTIL_ReverseBuff((uint8_t*)&(ptr)[ii] , sizeof(uint32_t) ); \
+       } \
+    }while(0)
+    #endif
+
+#else //CC_SB_INDIRECT_SRAM_ACCESS=0 => direct access
+        /* MACRO DEFINITIONS FOR WORKING WITH INDIRECT ACCESS TO SRAM PKA DATA REGISTERS */
+
+    /*These registers  not included in the HW_CC definitions because they are HOST registers */
+
+    /* defining a macro to load a value to the PKA data memory */
+    #define RSA_HW_PKI_HW_LOAD_VALUE_TO_PKA_MEM( VirtualHwBaseAddr , Addr , Val ) \
+    do \
+    { \
+       *(uint32_t*)(((Addr) + RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR)) = (uint32_t)Val; \
+    }while(0)
+
+
+    /* defining a macro to load a block to the PKA data memory */
+    #define RSA_HW_PKI_HW_LOAD_BLOCK_TO_PKA_MEM( VirtualHwBaseAddr , Addr , ptr , SizeWords ) \
+    do \
+    { \
+        UTIL_MemCopy((uint8_t*)((Addr) + RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR),(uint8_t*)(ptr),(SizeWords)*sizeof(uint32_t)); \
+    }while(0)
+
+
+    /* defining a macro to clear PKA data memory */
+    #define RSA_HW_PKI_HW_CLEAR_PKA_MEM( VirtualHwBaseAddr , Addr , SizeWords ) \
+    do \
+    { \
+        UTIL_MemSet((uint8_t*)((Addr) + RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR),0x0,(SizeWords)*sizeof(uint32_t)); \
+    }while(0)
+
+
+    /* defining a macro to read a value from the PKA data memory */
+    #define RSA_HW_PKI_HW_READ_VALUE_FROM_PKA_MEM( VirtualHwBaseAddr , Addr , Val ) \
+    do \
+    { \
+        Val = *(uint32_t*)((Addr) + RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR); \
+    }while(0)
+
+
+    /* defining a macro to read a block from the PKA data memory */
+    #define RSA_HW_PKI_HW_READ_BLOCK_FROM_PKA_MEM( VirtualHwBaseAddr , Addr , ptr , SizeWords ) \
+    do \
+    { \
+        UTIL_MemCopy((uint8_t*)(ptr),(uint8_t*)((Addr) + RSA_HW_PKI_PKA_DATA_REGS_MEMORY_OFFSET_ADDR),(SizeWords)*sizeof(uint32_t)); \
+    }while(0)
+
+#endif //CC_SB_INDIRECT_SRAM_ACCESS
+
+
+/************************ Defines ******************************/
+
+/* ********************** Macros ******************************* */
+
+/************************ Enums ********************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_pki_pka.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_pki_pka.c
new file mode 100644
index 0000000..a2dce4e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_pki_pka.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT HOST_LOG_MASK_SECURE_BOOT
+
+#include "rsa_pki_pka.h"
+#include "rsa_bsv.h"
+#include "secureboot_stage_defs.h"
+
+
+/************************ Defines ******************************/
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+/* SRAM address used for the PKA */
+const uint32_t g_SramPkaAddr = 0;
+
+/************************ Public Functions ******************************/
+
+#ifdef PKA_DEBUG
+  uint8_t tempRes[268];
+#endif
+
+/* ***************************************************************************** */
+/* *********      RSA PKI PKA initialisation functions and macros      ********* */
+/* ***************************************************************************** */
+
+/***********      PkaSetRegsSizesTab function      **********************/
+/**
+ * @brief This function initializes the PKA registers sizes table.
+ *
+ *      The function sets sizes table as follows:
+ *            -  tab[0] = MaxSizeBits; //maximal size, usually this is exact modulus size in bits
+ *            -  tab[1] = Extended size with extra bits, aligned to big words.
+ *            -  other entrie,
+        uint32_t  Xs = PKA_SIZE_ENTRY_NOT_USED, means - not used.
+ *
+ * @param[in] opSizeInBits - Size of PKA operations (modulus) in bits. The value must be in interval
+ *                          from defined Min. to Max. size bits.
+ * @param[in] regSizeInPkaWords - Sise of registers in PKA big words (e.g. 128-bit words).
+ *
+ * @return - no return value
+ *
+ */
+void RSA_PKA_SetRegsSizesTab( uint32_t     opSizeInBits,
+                  int32_t      regSizeInPkaWords,
+                  unsigned long  virtualHwBaseAddr)
+{
+    /* LOCAL DECLARATIONS */
+
+    uint32_t  i;
+
+    /* FUNCTION LOGIC */
+
+    /* Set exact op. size */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, PKA_L0), opSizeInBits);
+    /* Set register size (with extra bits) aligned to PKA big words */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, PKA_L0) + 4,
+                  regSizeInPkaWords*RSA_PKA_BIG_WORD_SIZE_IN_BITS);
+
+    /* remaining entries set to PKA_SIZE_ENTRY_NOT_USED for debugging goals */
+    for (i = 2; i < RSA_PKA_MAX_COUNT_OF_REGS_SIZES; i++) {
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, PKA_L0) + 4*i, PKA_SIZE_ENTRY_NOT_USED);
+    }
+
+    return;
+
+} /* END of the finction  PkaSetRegsSizesTab */
+
+
+/***********      PkaSetRegsMapTab function      **********************/
+/**
+ * @brief This function initializes the PKA registers sizes table.
+ *
+ *   The function checks input parameters and sets the physical memory registers mapping-table
+ *   according to parameters, passed by the user:
+ *     - start address of register 0 is the start address of PKA data registers memory
+ *       PKA_SRAM_REGS_MEM_OFFSET_WORDS (defined in pka_hw_defs.h file);
+ *     - special registers are set as follows: N=0,NP=1,T0=30,T1=31;
+ *     - all registers have the same size, equalled to given size;
+ *
+ * @param[in] countOfRegs  - The count of registeres, requirred by the user.
+ * @param[in] regSizeInPkaWords - Sise of registers in PKA big words (e.g. 128-bit words).
+ * @param[in] virtualHwBaseAddr - cc base address
+ *
+ * @return - no return value
+ *
+ */
+void RSA_PKA_SetRegsMapTab(int32_t   countOfRegs,
+               int32_t   regSizeInPkaWords,
+               unsigned long  virtualHwBaseAddr)
+{
+    /* LOCAL DECLARATIONS */
+
+    uint32_t  currentAddr;
+    int32_t i;
+
+    /* FUNCTION LOGIC */
+    /* start addres of PKA mem. */
+    currentAddr = RSA_PKA_SRAM_REGS_MEM_OFFSET_WORDS;
+
+    /* set addresses of the user requested registers (excluding T0,T1) */
+    for (i = 0; i < countOfRegs-2; i++) {
+                SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, MEMORY_MAP0) +
+                                      i*sizeof(uint32_t), currentAddr);
+                currentAddr += regSizeInPkaWords*RSA_PKA_BIG_WORD_SIZE_IN_32_BIT_WORDS;
+    }
+    /* set addresses of 2 temp registers: T0=30, T1=31 */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, MEMORY_MAP0) + 30*sizeof(uint32_t), currentAddr);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, MEMORY_MAP0) + 31*sizeof(uint32_t),
+                  currentAddr + regSizeInPkaWords*RSA_PKA_BIG_WORD_SIZE_IN_32_BIT_WORDS);
+
+    /* set default virtual addresses of N,NP,T0,T1 registers into N_NP_T0_T1_Reg */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, N_NP_T0_T1_ADDR),
+                  (uint32_t)RSA_HW_PKI_PKA_N_NP_T0_T1_REG_DEFAULT_VAL);
+
+    return;
+
+}  /* END of the finction  PkaSetRegsMapTab */
+
+
+/***********      PkaInitPka function      **********************/
+/**
+ * @brief This function initializes the PKA engine.
+ *
+ *    The function performs the following:
+ *      - initializes the PKA_SizesTable, PKA_MappingTable and special register
+ *        N_NP_T0_T1 according to user passed register sizes, registers mapping
+ *        and default N_NP_T0_T1 value.
+ *
+ *    The function calls the PkaSetRegsSizesTab  and PkaSetRegsMapTab
+ *    functions and sets N_NP_T0_T1 value into N_NP_T0_T1 register.
+ *    Notes:
+ *            - See remarks to PkaSetRegsSizesTab and PkaSetRegsMapTab functions.
+ *            - The function allocates one additional word for each register if it is needed for extra bits.
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure an error code:
+ *                       PKA_REGISTER_SIZES_ERROR
+ *                       PKA_ENTRIES_COUNT_ERROR
+ *                       PKA_NOT_ENOUGH_MEMORY_ERROR
+ *
+ */
+void RSA_PKA_InitPka( uint32_t   opSizeInBits,          /*in - modulus size in bits*/
+              uint32_t   regsCount,             /*in*/
+              unsigned long  virtualHwBaseAddr) /*in*/
+{
+
+    /* LOCAL DECLARATIONS */
+
+    uint32_t  regSizeInPkaWords;
+
+    /*     enabling the PKA clocks      */
+    SB_HAL_WRITE_REGISTER( SB_REG_ADDR(virtualHwBaseAddr, PKA_CLK_ENABLE), 0x1UL );
+
+    /* minimal needed regs size */
+    regSizeInPkaWords = GET_FULL_OP_SIZE_PKA_WORDS(opSizeInBits);
+
+
+    /* setting the PKA registers mapping table */
+    /*-----------------------------------------*/
+    RSA_PKA_SetRegsMapTab(regsCount, regSizeInPkaWords, virtualHwBaseAddr);
+
+    /* setting the PKA registers sizes table   */
+    /*-----------------------------------------*/
+    RSA_PKA_SetRegsSizesTab(opSizeInBits, regSizeInPkaWords, virtualHwBaseAddr);
+
+    /* ......  End of function ...... */
+    return;
+
+}
+
+
+/***********      RSA_HW_PKI_PKA_FinishPKA function      **********************/
+/**
+ * @brief This function ends the PKA engine session and disables PKA clocks.
+ *
+ * @param[in] virtualHwBaseAddr -  Virtual HW base address, passed by user.
+ *
+ * @return - no return parameters.
+ *
+ */
+ void RSA_HW_PKI_PKA_FinishPKA( unsigned long virtualHwBaseAddr /*in*/ )
+ {
+
+   /* FUNCTION LOGIC */
+
+   /* close PKA clocks */
+   SB_HAL_WRITE_REGISTER( SB_REG_ADDR(virtualHwBaseAddr, PKA_CLK_ENABLE), 0x0UL );
+
+ }
+
+
+
+/*******************************************************************************/
+/************    RSA PKI PKA mathmatic functions and macros     ****************/
+/*******************************************************************************/
+
+
+/***********    PkaDbgExecOperation (with virtual pointers)     ******************/
+/**
+ * @brief This function executes any allowed PKA mathematic operation according to
+ *        user passed Opcode.
+ *
+ *        The function receives code of operation, virtual pointers to PKI registers
+ *        (sequence number), for arguments and result, and operates PKA machine by writing
+ *        full operation code into OPCODE register. Then the function calls macros for
+ *        waiting the PKA pipe ready signal.
+ *        If opcode is illegal or one of operands is illegal, the function returns an
+ *        error code defined in llf_pki_error.h file.
+ *
+ *        The user don't call this function directly. For user convenience, in llf_pki.h file  are
+ *        given some macros for calling this function according to each performed operation.
+ *
+ *     NOTES:
+ *       -  Before executing modular operations, the modulus must be set into N=r0 register of PKA.
+ *       -  Before modular multiplication and exponentiation must be calculated and set into NP=r1
+ *          register the Barrett modulus tag NP = 2**(sizeN+132) / N.
+ *       -  In operations with immediate operands (IsImmediate bit = 1), the operand value (5-bit)
+ *          is treated as sign-extended. That means: low 4 bits are treated as unsigned operand
+ *          value in range 0-15 and bit 5 is a sign (with extension to all high bits of register,
+ *          in which the full operand shall be set).
+ *       -  In shift operations the 5-bits shift operand is treated as unsigned value in range 0-31
+ *          (count of shifts is equaled to shift operand value + 1).
+ *       -  The LMul operation gives the low half of multiplication result of length equaled to
+ *          operation size. The leading not significant bits of the operands and result (including
+ *          the the extra word) must be zeroed.
+ *       -  The HMul operation gives the high half of multiplication result plus one high word of low
+ *          half of full multiplication result. Therefore this result is by one word large, than
+ *          operation size. The leading not significant bits of the operands and result,
+ *          including extra word must be zeroed.
+ *       -  The ModInv operation calculates Res = 1/OpB mod N for odd modulus. Operand A is ignored.
+ *          In case of even modulus the function returns an error. Therefore in this case
+ *          (also for odd modulus) the user may call the PkaExecFullModInv function.
+ *
+ * @param[in] Opcode   - The operation code according HW PKA definitions. Valid values: 0 - max Opcode.
+ * @param[in] LenID    - ID of the length of operands according to register sizes table
+ *                       (means the number of entry in the table). Valid values: 0...7.
+ * @param[in] IsAImmed - If IsAImmed = 1, then operand A treated as immediate value, else -
+ *                       as virtual register pointer. Valid values: 0,1.
+ * @param[in] OpA      - Operand A: an immediate value or virtual register pointer, according to IsAImmed
+ *                       IsAImmed parameter. Valid values: 0 <= OpA <= 31.
+ * @param[in] IsBImmed - If IsBImmed = 1, then operand B treated as immediate value, else -
+ *                       as virtual register pointer. Valid values: 0,1.
+ * @param[in] OpB      - Operand B: an immediate value or virtual register pointer, according to IsAImmed
+ *                       IsBImmed parameter. Valid values: 0 <= OpA <= 31.
+ * @param[in] ResDiscard -  If ResDiscard = 1, then result is discarded.
+ * @param[in] Res        - Virtual register pointer for result data.
+ *                         Valid values: 0 <= Res <= 31. Value Res = RES_DISCARD means result must be discarded.
+ * @param[in] Tag        - The user defined value (Tag <= 31), used for indication goals.
+ *
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure an error code:
+ *                       PKA_ILLEGAL_OPCODE_ERROR
+ *                       PKA_ILLEGAL_OPERAND_LEN_ERROR
+ *                       PKA_ILLEGAL_OPERAND_TYPE_ERROR
+ *                       PKA_ILLEGAL_OPERAND_ERROR
+ *                       PKA_INVERSION_NOT_EXISTS_ERROR
+ */
+
+
+CCError_t _RSA_PKA_ExecOperation( uint32_t      Opcode,      /*in*/
+                uint8_t       LenID,         /*in*/
+                uint8_t       IsAImmed,      /*in*/
+                int8_t        OpA,       /*in*/
+                uint8_t       IsBImmed,      /*in*/
+                int8_t        OpB,       /*in*/
+                uint8_t       ResDiscard,    /*in*/
+                int8_t        Res,       /*in*/
+                uint8_t       Tag,       /*in*/
+                    unsigned long      virtualHwBaseAddr)
+{
+
+    /* LOCAL DECLARATIONS */
+
+    /* error identification */
+    CCError_t Error = CC_OK;
+
+    /* full Operation Code word */
+    uint32_t FullOpCode;
+
+    /* FUNCTION LOGIC */
+
+    /* if Res == RES_DISCARD , then result is discarded */
+    if (Res == (int8_t)RES_DISCARD) {
+        ResDiscard = 1;
+        Res = 0;
+    }
+
+
+    /*************************************************/
+    /*      main PKI operation of this function      */
+    /*************************************************/
+
+    FullOpCode = RSA_PKA_FullOpCode(Opcode, LenID, IsAImmed, OpA, IsBImmed, OpB, ResDiscard, Res, Tag);
+    RSA_PKA_WAIT_ON_PKA_PIPE_READY(virtualHwBaseAddr);
+    SB_HAL_WRITE_REGISTER( SB_REG_ADDR(virtualHwBaseAddr, OPCODE), FullOpCode);
+
+
+    /*************************************************/
+    /* finishing operations for different cases      */
+    /*************************************************/
+
+    return Error;
+
+} /* END OF function PkaDbgExecOperation */
+
+
+/***********      PkaCopyDataIntoPkaReg function      **********************/
+/**
+* @brief This function  copies source data into PKA register .
+*
+*        Assumings: - PKA is initialized.
+*                   - Length of extended (by word) registers is placed into LenID entry of
+*                     sizes table.
+*                   - If the extra word of register must be cleared also the user must
+*                     set LenID according to extended register size
+*
+* @param[in] dstReg       - Virtual address (number) of destination register.
+* @param[in] LenId        - ID of entry of regsSizesTable, defining full register length,
+*                           aligned to PKA word.
+* @param[in] src_ptr      - Pointer to source buffer.
+* @param[in] sizeWords    - Data size in words.
+*
+* @return - no return parameters.
+*
+*/
+void RSA_HW_PKI_PKA_CopyDataIntoPkaReg(uint32_t    dstReg,    /*out*/
+                       uint32_t    LenID,     /*in*/
+                       const  uint32_t  *src_ptr, /*in*/
+                       uint32_t    sizeWords,  /*in*/
+                       unsigned long  virtualHwBaseAddr)
+{
+
+    /* LOCAL DECLARATIONS */
+
+
+    /* current register address and size */
+    uint32_t  currAddr;
+    uint32_t  regSizeWords;
+
+
+    /* FUNCTION LOGIC */
+
+    /* copy data from src buffer into PKA register with 0-padding  *
+    *  in the last PKA-word                       */
+
+    RSA_PKA_WAIT_ON_PKA_DONE(virtualHwBaseAddr);
+        /* register size in 32-bits words */
+    RSA_PKA_ReadRegSize(regSizeWords, LenID, virtualHwBaseAddr);/*temporary in Bits*/
+    regSizeWords = CALC_FULL_32BIT_WORDS(regSizeWords);
+
+        currAddr = RSA_PKA_GetRegAddress(dstReg, virtualHwBaseAddr);
+        RSA_HW_PKI_HW_LOAD_BLOCK_TO_PKA_MEM(virtualHwBaseAddr, currAddr, src_ptr, sizeWords);
+
+        /* zeroe not significant high words of the register */
+        if (regSizeWords > sizeWords){
+                currAddr = currAddr + sizeWords;
+                RSA_HW_PKI_HW_CLEAR_PKA_MEM(virtualHwBaseAddr, currAddr, regSizeWords - sizeWords);
+        }
+
+#ifdef PKA_DEBUG
+    /*! PKA_DEBUG */
+//!! RL RSA_PKA_Copy(LenID/*LenID*/, dstReg, dstReg, 0/*Tag*/ , virtualHwBaseAddr);
+#endif
+    return;
+} /* END OF function PkaCopyDataIntoPkaReg */
+
+
+
+/***********      RSA_HW_PKI_PKA_CopyDataFromPkaReg      **********************/
+/**
+ * @brief This function copies data from PKA register into output buffer .
+ *
+ *        Assumings: - PKA is initialized.
+ *                   - Length of extended (by word) registers is placed into LenID entry of
+ *                     sizes table.
+ *                   - If the extra word of register must be cleared also the user must
+ *                     set LenID according to extended register size
+ *
+ * @param[in] srcReg       - Virtual address (number) of source PKA register.
+ * @param[in] dst_ptr      - Pointer to destination buffer.
+ * @param[in] sizeBytes - Source size in bytes.
+ *
+ * @return - no return parameters.
+ *
+ */
+void RSA_HW_PKI_PKA_CopyDataFromPkaReg(uint32_t *dst_ptr,       /*out*/
+                uint32_t  sizeWords,        /*in*/
+                uint32_t  srcReg,       /*in*/
+                unsigned long  virtualHwBaseAddr)
+{
+
+    /* LOCAL DECLARATIONS */
+
+    /* current register address and size */
+    uint32_t  currAddr = 0;
+
+    /* FUNCTION LOGIC */
+
+    RSA_PKA_WAIT_ON_PKA_DONE(virtualHwBaseAddr);
+    currAddr = RSA_PKA_GetRegAddress(srcReg, virtualHwBaseAddr);
+    RSA_HW_PKI_HW_READ_BLOCK_FROM_PKA_MEM(virtualHwBaseAddr, currAddr, dst_ptr, sizeWords );
+
+    return;
+
+} /* END OF function PkaCopyDataFromPkaReg */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_pki_pka.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_pki_pka.h
new file mode 100644
index 0000000..6996fac
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_pki_pka.h
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef RSA_PKI_PKA_H
+#define RSA_PKI_PKA_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#include "secureboot_basetypes.h"
+#include "secureboot_stage_defs.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+
+/* values for defining, that PKA entry is not in use */
+#define PKA_SIZE_ENTRY_NOT_USED  0xFFFFFFFF
+#define PKA_ADDRESS_ENTRY_NOT_USED  0xFFC
+
+/* define NpCreateFlag values */
+#define PKA_CreateNP  1
+#define PKA_SetNP     0
+
+/* define "discard result" value */
+#define RES_DISCARD  0x3F
+
+
+/* default LenID-s definitions. Last 3 names used in RSA KG.
+   Note: extended sizes are in the entries LenID+1 (i.e. 1,3) accordingly */
+#define LenIDn    0  /* for operation or modulus size*/
+#define LenIDpq   2  /* for P, Q size */
+#define LenID101  4  /* for P1,P2,Q1,Q2 101 bit size */
+#define LenIDmin  6  /* for min allowed operation size (now 128 bit) */
+#define LenIDmax  7  /* for max allowed operation size (now 2112 bit) */
+
+/* define of PKA Tag for debug printing of PKA operations result
+   into tempRes global buffer */
+#define PKA_TAG_DebugPtint  1
+
+
+/************************ Enums ********************************/
+
+/* defines enumerator for all allowed PKA operations */
+typedef enum
+{
+    PKA_Terminate_ID    =  0,
+    PKA_Add_ID          =  1,
+    PKA_AddIm_ID        =  2,
+    PKA_Sub_ID          =  3,
+    PKA_SubIm_ID        =  4,
+    PKA_Neg_ID          =  5,
+
+    PKA_ModAdd_ID       =  6,
+    PKA_ModAddIm_ID     =  7,
+    PKA_ModSub_ID       =  8,
+    PKA_ModSubIm_ID     =  9,
+    PKA_ModNeg_ID       = 10,
+
+    PKA_And_ID          = 11,
+    PKA_Tst0_ID         = 12,
+    PKA_Clr0_ID         = 13,
+    PKA_Clr_ID          = 14,
+
+    PKA_OR_ID           = 15,
+    PKA_Copy_ID         = 16,
+    PKA_SetBit0_ID      = 17,
+
+    PKA_XOR_ID          = 18,
+    PKA_Flip0_ID        = 19,
+    PKA_InvBits_ID      = 20,
+    PKA_Compare_ID      = 21,
+
+    PKA_SHR0_ID         = 22,
+    PKA_SHR1_ID         = 23,
+    PKA_SHL0_ID         = 24,
+    PKA_SHL1_ID         = 25,
+
+    PKA_LMul_ID         = 26,
+    PKA_HMul_ID         = 27,
+    PKA_ModMul_ID       = 28,
+    PKA_ModMulNR_ID     = 29,
+    PKA_ModExp_ID       = 30,
+
+    PKA_Div_ID          = 31,
+    PKA_ModInv_ID       = 32,
+
+    PKA_OpOffMode
+
+} RSA_HW_PKI_PKA_OpID_t;
+
+
+/*  Enumerator, defining whether the functions performs default settings
+    of PKI registers, or takes they from user passed arguments  */
+typedef enum
+{
+      DefaultRegs       = 0,
+      SetRegs           = 1,
+      RegsSetOffMode
+
+} RSA_HW_PKI_PKA_SetRegs_t;
+
+
+/************************ Typedefs  ****************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  ******************************/
+
+/* definition of the Registers sizes array type, used for initialisation
+   of the PKA sizes table */
+typedef uint32_t RSA_HW_PKI_PKA_RegsSizes_t[RSA_PKA_MAX_COUNT_OF_REGS_SIZES];
+
+ /* This structure contains virtual pointers (numbers in range 0-31) of
+    PKI registers RegsNum[]  and registers physical addresses RegsAddr[].
+    For example: RegsNum[3] = 5 and RegsAddr[3] = 0x400 means, that address of
+    register 5 is 0x400. The user may set into this structure only needed registers,
+    used in planned PKA operations. */
+
+typedef  struct
+{
+       uint32_t    RegsNum[RSA_HW_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS] ;
+       uint32_t    RegsAddr[RSA_HW_PKI_PKA_MAX_COUNT_OF_PHYS_MEM_REGS] ;
+}RSA_HW_PKI_PKA_RegsMap_t;
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions ******************************/
+
+
+/***********************************************************************************************/
+/***********************************************************************************************/
+/*                                                                                             */
+/*                   RSA PKI FUNCTIONS, PERFORMING PKA OPERATIONS                              */
+/*                                                                                             */
+/***********************************************************************************************/
+/***********************************************************************************************/
+
+
+
+/*******************************************************************************/
+/**********      RSA PKI PKA initialisation functions and macros      **********/
+/*******************************************************************************/
+
+/***********      PkaSetRegsSizesTab function      **********************/
+/**
+ * @brief This function initializes the PKA registers sizes table.
+ *
+ *      The function sets sizes table as follows:
+ *            -  tab[0] = MaxSizeBits; //maximal size, usually this is exact modulus size in bits
+ *            -  tab[1] = Extended size with extra bits, aligned to big words.
+ *            -  other entrie,
+        uint32_t  Xs = PKA_SIZE_ENTRY_NOT_USED, means - not used.
+ *
+ * @param[in] opSizeInBits - Size of PKA operations (modulus) in bits. The value must be in interval
+ *                          from defined Min. to Max. size bits.
+ * @param[in] regSizeInPkaWords - Sise of registers in PKA big words (e.g. 128-bit words).
+ *
+ * @return - no return value
+ *
+ */
+void RSA_PKA_SetRegsSizesTab( uint32_t     opSizeInBits,
+                  int32_t      regSizeInPkaWords,
+                  unsigned long  VirtualHwBaseAddr);
+
+
+/***********      PkaSetRegsMapTab function      **********************/
+/**
+ * @brief This function initializes the PKA registers sizes table.
+ *
+ *   The function checks input parameters and sets the physical memory registers mapping-table
+ *   according to parameters, passed by the user:
+ *     - start address of register 0 is the start address of PKA data registers memory
+ *       PKA_SRAM_REGS_MEM_OFFSET_WORDS (defined in pka_hw_defs.h file);
+ *     - special registers are set as follows: N=0,NP=1,T0=30,T1=31;
+ *     - all registers have the same size, equalled to given size;
+ *
+ * @param[in] countOfRegs  - The count of registeres, requirred by the user.
+ * @param[in] regSizeInPkaWords - Sise of registers in PKA big words (e.g. 128-bit words).
+ * @param[in] VirtualHwBaseAddr - ARM CryptoCell base address
+ *
+ * @return - no return value
+ *
+ */
+void RSA_PKA_SetRegsMapTab(int32_t   countOfRegs,
+               int32_t   regSizeInPkaWords,
+               unsigned long  VirtualHwBaseAddr);
+
+
+
+/***********      PkaInitPka function      **********************/
+/**
+ * @brief This function initializes the PKA engine.
+ *
+ *    The function performs the following:
+ *      - initializes the PKA_SizesTable, PKA_MappingTable and special register
+ *        N_NP_T0_T1 according to user passed register sizes, registers mapping
+ *        and default N_NP_T0_T1 value.
+ *
+ *    The function calls the PkaSetRegsSizesTab  and PkaSetRegsMapTab
+ *    functions and sets N_NP_T0_T1 value into N_NP_T0_T1 register.
+ *    Notes:
+ *            - See remarks to PkaSetRegsSizesTab and PkaSetRegsMapTab functions.
+ *            - The function allocates one additional word for each register if it is needed for extra bits.
+ *
+ *
+ * @return void
+ *
+ */
+ void RSA_PKA_InitPka(uint32_t   opSizeInBits,  /*in*/
+                      uint32_t   regsCount,     /*in*/
+                      unsigned long  virtualHwBaseAddr) /*out*/;
+
+
+/***********      RSA_HW_PKI_PKA_FinishPKA function      **********************/
+/**
+ * @brief This function ends the PKA engine session and disables PKA clocks.
+ *
+ * @param[in] VirtualHwBaseAddr -  Virtual HW base address, passed by user.
+ *
+ * @return - no return parameters.
+ *
+ */
+ void RSA_HW_PKI_PKA_FinishPKA( unsigned long VirtualHwBaseAddr /*in*/ );
+
+
+
+/*******************************************************************************/
+/************    RSA PKI PKA mathmatic functions and macros     ****************/
+/*******************************************************************************/
+
+/***********    PkaDbgExecOperation (with virtual pointers)     ******************/
+/**
+ * @brief This function executes any allowed PKA mathematic operation according to
+ *        user passed Opcode.
+ *
+ *        The function receives code of operation, virtual pointers to PKI registers
+ *        (sequence number), for arguments and result, and operates PKA machine by writing
+ *        full operation code into OPCODE register. Then the function calls macros for
+ *        waiting the PKA pipe ready signal.
+ *        If opcode is illegal or one of operands is illegal, the function returns an
+ *        error code defined in llf_pki_error.h file.
+ *
+ *        The user don't call this function directly. For user convenience, in llf_pki.h file  are
+ *        given some macros for calling this function according to each performed operation.
+ *
+ *     NOTES:
+ *       -  Before executing modular operations, the modulus must be set into N=r0 register of PKA.
+ *       -  Before modular multiplication and exponentiation must be calculated and set into NP=r1
+ *          register the Barrett modulus tag NP = 2**(sizeN+132) / N.
+ *       -  In operations with immediate operands (IsImmediate bit = 1), the operand value (5-bit)
+ *          is treated as sign-extended. That means: low 4 bits are treated as unsigned operand
+ *          value in range 0-15 and bit 5 is a sign (with extension to all high bits of register,
+ *          in which the full operand shall be set).
+ *       -  In shift operations the 5-bits shift operand is treated as unsigned value in range 0-31
+ *          (count of shifts is equaled to shift operand value + 1).
+ *       -  The LMul operation gives the low half of multiplication result of length equaled to
+ *          operation size. The leading not significant bits of the operands and result (including
+ *          the the extra word) must be zeroed.
+ *       -  The HMul operation gives the high half of multiplication result plus one high word of low
+ *          half of full multiplication result. Therefore this result is by one word large, than
+ *          operation size. The leading not significant bits of the operands and result,
+ *          including extra word must be zeroed.
+ *       -  The ModInv operation calculates Res = 1/OpB mod N for odd modulus. Operand A is ignored.
+ *          In case of even modulus the function returns an error. Therefore in this case
+ *          (also for odd modulus) the user may call the PkaExecFullModInv function.
+ *
+ * @param[in] Opcode   - The operation code according HW PKA definitions. Valid values: 0 - max Opcode.
+ * @param[in] LenID    - ID of the length of operands according to register sizes table
+ *                       (means the number of entry in the table). Valid values: 0...7.
+ * @param[in] IsAImmed - If IsAImmed = 1, then operand A treated as immediate value, else -
+ *                       as virtual register pointer. Valid values: 0,1.
+ * @param[in] OpA      - Operand A: an immediate value or virtual register pointer, according to IsAImmed
+ *                       IsAImmed parameter. Valid values: 0 <= OpA <= 31.
+ * @param[in] IsBImmed - If IsBImmed = 1, then operand B treated as immediate value, else -
+ *                       as virtual register pointer. Valid values: 0,1.
+ * @param[in] OpB      - Operand B: an immediate value or virtual register pointer, according to IsAImmed
+ *                       IsBImmed parameter. Valid values: 0 <= OpA <= 31.
+ * @param[in] ResDiscard -  If ResDiscard = 1, then result is discarded.
+ * @param[in] Res        - Virtual register pointer for result data.
+ *                         Valid values: 0 <= Res <= 31. Value Res = RES_DISCARD means result must be discarded.
+ * @param[in] Tag        - The user defined value (Tag <= 31), used for indication goals.
+ *
+ *
+ * @return CCError_t - On success CC_OK is returned, on failure an error code:
+ *                       PKA_ILLEGAL_OPCODE_ERROR
+ *                       PKA_ILLEGAL_OPERAND_LEN_ERROR
+ *                       PKA_ILLEGAL_OPERAND_TYPE_ERROR
+ *                       PKA_ILLEGAL_OPERAND_ERROR
+ *                       PKA_INVERSION_NOT_EXISTS_ERROR
+ */
+
+
+CCError_t _RSA_PKA_ExecOperation( uint32_t      Opcode,      /*in*/
+                uint8_t       LenID,         /*in*/
+                uint8_t       IsAImmed,      /*in*/
+                int8_t        OpA,       /*in*/
+                uint8_t       IsBImmed,      /*in*/
+                int8_t        OpB,       /*in*/
+                uint8_t       ResDiscard,    /*in*/
+                int8_t        Res,       /*in*/
+                uint8_t       Tag,       /*in*/
+                    unsigned long      VirtualHwBaseAddr);
+
+/*************************************************************************/
+/* Macros for calling PKA operations (names according to operation issue */
+/*************************************************************************/
+
+/*----------------------------------*/
+/*   1.  ADD - SUBTRACT operations  */
+/*----------------------------------*/
+
+/*  Add:   Res =  OpA + OpB  */
+#define   RSA_PKA_Add(LenID, OpA, OpB, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation( PkaAdd,(LenID), 0, (OpA), 0, (OpB), 0, (Res), (Tag), (VirtualHwBaseAddr) )
+/*  AddIm:  Res =  OpA + OpBIm  */
+#define   RSA_PKA_Add_IM(LenID, OpA, OpBIm, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation( PkaAddIm,(LenID), 0, (OpA), 1, (OpBIm), 0, (Res), (Tag), (VirtualHwBaseAddr) )
+/*  SubIm:  Res =  OpA - OpBIm  */
+#define   RSA_PKA_SUB_IM(LenID, OpA, OpBIm, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation( PkaSubIm,(LenID), 0, (OpA), 1, (OpBIm), 0, (Res), (Tag), (VirtualHwBaseAddr) )
+
+/*----------------------------------*/
+/*   2.  Logical   operations       */
+/*----------------------------------*/
+
+/*  Clr:  Res =  OpA & 0  - clears the operand A.  */
+#define   RSA_PKA_Clr(LenID, OpA, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation( PkaAND, (LenID), 0, (OpA), 1, 0x00, 0, (OpA), (Tag), (VirtualHwBaseAddr))
+
+/*  Clear:  for full clearing the actual register opA, this macro calls Clr operation twice.  */
+#define   RSA_PKA_Clear(LenID, OpA, Tag, VirtualHwBaseAddr)   \
+            RSA_PKA_Clr(LenID, OpA, Tag, VirtualHwBaseAddr);  \
+            RSA_PKA_Clr(LenID, OpA, Tag, VirtualHwBaseAddr)
+
+/*  Set0:  Res =  OpA || 1  : set bit0 = 1, other bits are not changed */
+#define   RSA_PKA_Set0(LenID, OpA, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation(PkaOR, (LenID), 0, (OpA), 1, 0x01, 0, (Res), (Tag), (VirtualHwBaseAddr))
+
+/*-----------------------------------------------------*/
+/*   2.  Multiplication and other   operations         */
+/*       Note:  See notes to PKA_ExecOperation */
+/*-----------------------------------------------------*/
+#define   RSA_PKA_Add(LenID, OpA, OpB, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation( PkaAdd,(LenID), 0, (OpA), 0, (OpB), 0, (Res), (Tag), (VirtualHwBaseAddr) )
+
+/*  ModExp:  Res =  OpA ** OpB  mod N - modular exponentiation */
+#define   RSA_HW_PKI_PKA_ModExp(LenID, OpA, OpB, Res, Tag, VirtualHwBaseAddr)   \
+             _RSA_PKA_ExecOperation( PkaModExp, (LenID), 0, (OpA), 0, (OpB), 0, (Res), (Tag), (VirtualHwBaseAddr))
+
+/*  Copy:  OpDest =  OpSrc || 0  */
+#define   RSA_PKA_Copy(LenID, OpDest, OpSrc, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation(PkaOR, (LenID), 0, (OpSrc), 1, 0x00, 0, (OpDest), (Tag), (VirtualHwBaseAddr))
+
+/*  SHR0:  Res =  OpA >> (S+1) :   shifts right operand A by S+1 bits, insert 0 to left most bits */
+#define   RSA_PKA_SHR0(LenID, OpA, S, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation( PkaSHR0, (LenID), 0, (OpA), 0, (S), 0, (Res), (Tag), (VirtualHwBaseAddr))
+
+/*  SHL0:  Res =  OpA << (S+1) :   shifts left operand A by S+1 bits, insert 0 to right most bits */
+#define   RSA_PKA_SHL0(LenID, OpA, S, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation(PkaSHL0, (LenID), 0, (OpA), 0, (S), 0, (Res), (Tag), (VirtualHwBaseAddr))
+
+/*  Divide:  Res =  OpA / OpB , OpA = OpA mod OpB - division,  */
+#define   RSA_PKA_Div(LenID, OpA, OpB, Res, Tag, VirtualHwBaseAddr)   \
+            _RSA_PKA_ExecOperation( PkaDiv, (LenID), 0, (OpA), 0, (OpB), 0, (Res), (Tag),  (VirtualHwBaseAddr))
+
+
+
+#define RSA_PKA_WRITE_WORD_TO_REG(Val,i,VirtReg, VirtualHwBaseAddr) {\
+    uint32_t  currAddr;\
+    RSA_PKA_WAIT_ON_PKA_DONE(VirtualHwBaseAddr); \
+    currAddr = RSA_PKA_GetRegAddress(VirtReg, VirtualHwBaseAddr);\
+    RSA_HW_PKI_HW_LOAD_VALUE_TO_PKA_MEM(VirtualHwBaseAddr, currAddr+(i), (Val));\
+}
+
+
+/* ***************************************************************************** */
+/* ************   Auxiliary functions used in PKA               **************** */
+/* ***************************************************************************** */
+
+
+/***********      RSA_HW_PKI_PKA_ClearBlockOfRegs function      **********************/
+/**
+ * @brief This function clears block of PKA registers.
+ *
+ *        Assumings: - PKA is initialised.
+ *                   - Length of extended (by word) registers is plased into LenID entry of
+ *                     sizes table.
+ *
+ * @param[in] firstReg    - Virtual address (number) of first register in block.
+ * @param[in] countOfRegs - Count of registers to clear.
+ * @param[in] LenId       - ID of entry of regsSizesTable defines registers lengts with word extension.
+ * @param[in] VirtualHwBaseAddr -  Virtual HW base address, passed by user.
+ *
+ */
+ void RSA_HW_PKI_PKA_ClearBlockOfRegs(
+                                uint8_t  firstReg,          /*in*/
+                                uint8_t  countOfRegs,       /*in*/
+                                uint8_t  LenID,             /*in*/
+                                unsigned long VirtualHwBaseAddr  /*in*/ );
+
+
+
+/***********      RSA_HW_PKI_PKA_CopyDataIntoPkaReg function      **********************/
+/**
+ * @brief This function  copies source data into PKA register .
+ *
+ *        Assumings: - PKA is initialised.
+ *                   - Length of extended (by word) registers is plased into LenID entry of
+ *                     sizes table.
+ *                   - If the extra word of register must be cleared also the user must
+ *                     set LenID according to extended register size
+ *
+ * @param[in] dstReg       - Virtual address (number) of destination register.
+ * @param[in] LenId        - ID of entry of regsSizesTable defines registers lengts with word extension.
+ * @param[in] src_ptr      - Pointer to source buffer.
+ * @param[in] sizeBytes    - Data size in bytes.
+ * @param[in] VirtualHwBaseAddr -  Virtual HW base address, passed by user.
+ *
+ * @return - no return parameters.
+ *
+ */
+ void RSA_HW_PKI_PKA_CopyDataIntoPkaReg(uint32_t    dstReg,   /*out*/
+                       uint32_t    LenID,     /*in*/
+                       const  uint32_t  *src_ptr, /*in*/
+                       uint32_t    sizeWords,  /*in*/
+                       unsigned long  VirtualHwBaseAddr);
+
+
+
+
+/***********      RSA_HW_PKI_PKA_CopyDataFromPkaReg      **********************/
+/**
+ * @brief This function copies data from PKA register into output buffer .
+ *
+ *        Assumings: - PKA is initialised.
+ *                   - Length of extended (by word) registers is plased into LenID entry of
+ *                     sizes table.
+ *                   - If the extra word of register must be cleared also the user must
+ *                     set LenID according to extended register size
+ *
+ * @param[in] srcReg       - Virtual address (number) of source PKA register.
+ * @param[in] dst_ptr      - Pointer to destination buffer.
+ * @param[in] sizeBytes - Source size in bytes.
+ * @param[in] VirtualHwBaseAddr -  Virtual HW base address, passed by user.
+ *
+ * @return - no return parameters.
+ *
+ */
+ void RSA_HW_PKI_PKA_CopyDataFromPkaReg(uint32_t *dst_ptr,      /*out*/
+                uint32_t  sizeWords,        /*in*/
+                uint32_t  srcReg,       /*in*/
+                unsigned long  VirtualHwBaseAddr);
+
+
+ /***********      RSA_HW_PKI_SET_MSB_ADDR      **********************/
+/**
+ * @brief This function sets the PKI MSB register according ot the SRAM address .
+ *
+ *        Assumings: - PKA registers are accessable.
+ *                   - SRAM address is multiple of 4KB.
+ *
+ * @param[in] pkaAdrress       - base address of the SRAM for PKA.
+ *
+ * @return - no return parameters.
+ *
+ */
+void RSA_HW_PKI_SET_MSB_ADDR(unsigned long virtualAddress, uint32_t pkaAdrress);
+
+/**
+ * The function uses physical data pointers to calculate
+ * the Barrett tag Np. Np is saved into Register indexed by regNp.
+ *
+ *  For RSA it uses truncated sizes:
+ *      Np = truncated(2^(3*A+3*X-1) / ceiling(n/(2^(N-2*A-2*X)));
+ *
+ *      function assumes modulus in PKA reg 0, and output is to PKA reg 1
+ *
+ */
+uint32_t  RSA_HW_PKA_CalcNpIntoPkaReg(uint32_t lenId,
+                uint32_t    sizeNbits,
+                int8_t      regN,
+                int8_t      regNp,   // out
+                int8_t      regTemp1,
+                int8_t      regTempN,
+                unsigned long VirtualHwBaseAddr) ;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_verify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_verify.c
new file mode 100644
index 0000000..9bc5fb9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/crypto_driver/rsa_verify.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT HOST_LOG_MASK_SECURE_BOOT
+
+
+/************* Include Files ****************/
+
+#include "secureboot_basetypes.h"
+#include "secureboot_error.h"
+#include "rsa_bsv.h"
+#include "cc_pka_hw_plat_defs.h"
+#include "secureboot_stage_defs.h"
+
+
+/************************ Defines ******************************/
+
+/************************ Global Data **************************/
+
+/*********************** Private Functions *********************/
+
+/*
+\brief The function implements the RSA_PSS_Decode algorithm (PKCS#1 v2.1).
+\note The input data is placed as BE bytes arrays into 32-bit word buffers
+      for alignment goal. Order of bytes in arrays is BE (MS byte is left most one).
+@return CC_OK on success,
+@return A non-zero value from secureboot_error.h on failure.
+*/
+
+CCError_t RSA_PSS_Decode(unsigned long hwBaseAddress,  /* [in] HW base address of registers. */
+                         CCHashResult_t mHash,         /* [in] SHA256 hash of the message (32 bytes). */
+                         uint8_t *pEncodedMsg,         /* [in] Pointer to PSS encoded message (EM). Size = modulus size. */
+                         int32_t *pVerifyStat          /* [out] Pointer to validation status value, equalled to:
+                                                                1 - if valid, 0 - if not valid. */ )
+{
+        /* FUNCTION DECLERATIONS */
+
+#define MASKED_DB_SIZE (SB_CERT_RSA_KEY_SIZE_IN_BYTES - HASH_RESULT_SIZE_IN_BYTES - 1)
+
+    /* error variable */
+    CCError_t error = CC_OK;
+        uint32_t stat = 0;
+
+    /* temp buffers and byte pointers */
+    uint32_t tmpBuff[HASH_RESULT_SIZE_IN_WORDS + 1/*for counter*/];
+    uint32_t dbMask[SB_CERT_RSA_KEY_SIZE_IN_WORDS];
+    uint8_t *pDbMask;
+
+        /* loop variables */
+    uint32_t i, counter;
+
+    /* FUNCTION LOGIC */
+
+        /* check input pointers */
+        if(mHash == NULL || pEncodedMsg == NULL || pVerifyStat == NULL) {
+                return CC_BOOT_RSA_VERIFIER_ALG_FAILURE;
+        }
+
+        *pVerifyStat = 0; /*set status to "not valid"*/
+
+        /* setting the EM and masked DB byte-pointers */
+    pDbMask = (uint8_t*)dbMask;
+
+        /*   operating the RSA PSS decoding scheme      */
+        /*----------------------------------------------*/
+
+        /* 9.1.2 <1,2,3> meet  */
+        /* 9.1.2 <4> Check that the rightmost octet of EM = 0xbc */
+    if (pEncodedMsg[SB_CERT_RSA_KEY_SIZE_IN_BYTES - 1] != 0xbc) {
+        error = CC_BOOT_RSA_VERIFIER_CMP_FAILURE;
+        goto End;
+    }
+
+        /*  9.1.2 <6> Check that the leftmost (8*emLen - emLenbit) of  *
+        *   masked DB are equalled to 0, i.e. in our case MSbit = 0    */
+    if (pEncodedMsg[0] & 0x80) {
+        error = CC_BOOT_RSA_VERIFIER_CMP_FAILURE;
+        goto End;
+    }
+
+        /*  9.1.2 <7> Let dbMask = MGF1(H,emLen-hLen-1)                *
+         *  B.2.1 MGF1:                                                *
+         *  For counter from 0 to  | L / hLen | , do the following:    *
+     *  a.  Convert counter to an octet string C of length 4       *
+         *  b.  Concatenate the hash of the seed H and C to the octet  *
+         *      string T:  T = T || Hash(H || C)                       *
+         *      C = C + 1                                              */
+
+        /* copy the HASH from the EM (EncodedMsg) to the temp buffer */
+        UTIL_MemCopy((uint8_t*)tmpBuff, &pEncodedMsg[MASKED_DB_SIZE], HASH_RESULT_SIZE_IN_BYTES);
+
+    for (counter = 0; counter <= (MASKED_DB_SIZE/HASH_RESULT_SIZE_IN_BYTES); counter++ ) {
+
+                /* a. tmp = H||C */
+        tmpBuff[HASH_RESULT_SIZE_IN_WORDS] = UTIL_INVERSE_UINT32_BYTES(counter);
+
+                /* b. Calculate and concatenate the hash on dbMask buffer: *
+                *           T = T || HASH(H || C)                          */
+                error = SBROM_CryptoHash(hwBaseAddress, CONVERT_TO_ADDR(tmpBuff),
+                                     (HASH_RESULT_SIZE_IN_WORDS+1)*sizeof(uint32_t),
+                                     &dbMask[counter*HASH_RESULT_SIZE_IN_WORDS]);
+
+        if (error != CC_OK) {
+                        goto End;
+        }
+    }
+
+        /*  9.1.2 <8> Xor operation */
+    for (i=0; i < MASKED_DB_SIZE; i++) {
+        pDbMask[i] ^= pEncodedMsg[i];
+    }
+
+        /*  9.1.2 <9> Set the leftmost (8emLen - emBits) bits of the leftmost
+                      octet in DB to zero (in this case it is MS bit only) */
+    pDbMask[0] &= 0x7F;
+
+        /*  9.1.2 <10> Check, that padding PS is zero and next byte = 0x01*/
+    for (i = 0; i < SB_CERT_RSA_KEY_SIZE_IN_BYTES - HASH_RESULT_SIZE_IN_BYTES - RSA_PSS_SALT_LENGTH - 2; i++) {
+                stat |= pDbMask[i];
+    }
+        if ((stat != 0) || (pDbMask[i] != 0x01)) {
+                error = CC_BOOT_RSA_VERIFIER_CMP_FAILURE;
+                goto End;
+        }
+
+        /*  9.1.2 <11> Let salt be the last sLen octets in DB */
+        /*  9.1.2 <12> Let M' => (0x) 00 00 00 00 00 00 00 00 || mHash || salt*/
+
+    UTIL_MemSet(pEncodedMsg, 0x00, RSA_PSS_PAD1_LEN); /* PS zero padding */
+        /* Hash and Salt */
+    UTIL_MemCopy(&pEncodedMsg[RSA_PSS_PAD1_LEN], (uint8_t*)mHash, HASH_RESULT_SIZE_IN_BYTES);
+    UTIL_MemCopy(&pEncodedMsg[RSA_PSS_PAD1_LEN + HASH_RESULT_SIZE_IN_BYTES],
+                     &pDbMask[MASKED_DB_SIZE - RSA_PSS_SALT_LENGTH], RSA_PSS_SALT_LENGTH);
+
+        /*  9.1.2 <13> H' = Hash(M') ==> dbMask*/
+    error = SBROM_CryptoHash(hwBaseAddress,
+                        CONVERT_TO_ADDR(pEncodedMsg),
+                        (RSA_PSS_PAD1_LEN + HASH_RESULT_SIZE_IN_BYTES + RSA_PSS_SALT_LENGTH),
+                        dbMask/*H'*/);
+
+        if (error != CC_OK) {
+        goto End;
+    }
+
+        /*  9.1.2 <14> Compare H' == H; Note: If buffers are equalled,        *
+        *   then CC_TRUE = 1 is returned                                      */
+    *pVerifyStat = UTIL_MemCmp((uint8_t*)dbMask/*H'*/, (uint8_t*)tmpBuff/*hash on EM*/, sizeof(CCHashResult_t));
+
+    if(*pVerifyStat != CC_TRUE) {
+        error = CC_BOOT_RSA_VERIFIER_CMP_FAILURE;
+                *pVerifyStat = CC_FALSE;
+                goto End;
+        }
+
+        /* end of function, clean temp buffers */
+End:
+        UTIL_MemSet((uint8_t*)tmpBuff, 0, (HASH_RESULT_SIZE_IN_BYTES +4));
+        UTIL_MemSet((uint8_t*)dbMask, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES));
+
+    return error;
+
+#undef MASKED_DB_SIZE
+
+}/* End of RSA_PSS_Decode */
+
+
+/*
+\brief The function implements the RSA_PSS_Verify algorithm (PKCS#1 v2.1).
+@return CC_OK on success,
+@return A non-zero value from secureboot_error.h on failure.
+*/
+CCError_t RSA_PSS_Verify(unsigned long hwBaseAddress,  /* [in] HW base address of registers. */
+                         CCHashResult_t mHash,    /* [in] Pointer to the SHA256 hash of the message. */
+                         uint32_t      *pN,            /* [in] Pointer to the RSA modulus (LE words array). */
+                         uint32_t      *pNp,           /* [in] Pointer to the Barrett tag of the RSA modulus (LE words array). */
+                         uint32_t      *pSign          /* [out] Pointer to the signature output (it is placed as BE bytes
+                                                                array into words buffer for alignments goal). */)
+{
+        /* DECLARATIONS */
+
+    CCError_t error = CC_OK;
+        int32_t verifyStat = 0; /* 1 - valid, 0 - not valid */
+
+        /* a buffer for the decrypted signiture */
+    uint32_t ED[SB_CERT_RSA_KEY_SIZE_IN_WORDS + 1];
+
+    /* FUNCTION LOGIC */
+
+        /* execute the decryption */
+    RSA_CalcExponent(hwBaseAddress, pSign/*in*/, pN, pNp, ED/*res*/);
+        /* reverse to big.end format */
+    UTIL_ReverseBuff((uint8_t*)ED, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+
+        /*  operating the RSA PSS decoding primitive  */
+    /* ------------------------------------------ */
+
+        error = RSA_PSS_Decode(hwBaseAddress,
+                         mHash, /*32 bytes*/
+                         (uint8_t*)ED/*RSA mod. size*/,
+                         &verifyStat);
+        if (error) {
+                goto End;
+    }
+
+        if(verifyStat != 1) {
+                error = CC_BOOT_RSA_VERIFIER_CMP_FAILURE;
+    }
+
+End:
+        /* zeroing temp buffer */
+        UTIL_MemSet((uint8_t*)ED, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES + 4));
+
+        return error;
+
+}/* END OF RSA_PSS_Verify */
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_base_swimgverify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_base_swimgverify.c
new file mode 100644
index 0000000..355c6c2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_base_swimgverify.c
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+
+#include "secureboot_error.h"
+#include "secureboot_basetypes.h"
+#include "secureboot_stage_defs.h"
+#include "secureboot_gen_defs.h"
+#include "secureboot_defs.h"
+#include "bootimagesverifier_error.h"
+#include "nvm_otp.h"
+#include "cc_pal_log.h"
+#include "secureboot_stage_defs.h"
+#include "secdebug_defs.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Internal Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+CCError_t CCSbImageLoadAndVerify(CCSbFlashReadFunc preHashflashRead_func,
+                       void *preHashUserContext,
+                       unsigned long hwBaseAddress,
+                       uint8_t isLoadFromFlash,
+                       uint8_t isVerifyImage,
+                       bsvCryptoMode_t cryptoMode,
+                       CCBsvKeyType_t  keyType,
+                       AES_Iv_t AESIv,
+                       uint8_t *pSwRecSignedData,
+                       uint32_t *pSwRecNonSignedData,
+                       uint32_t *workspace_ptr,
+                       uint32_t workspaceSize)
+{
+    /* error variable */
+    CCError_t error = CC_OK;
+
+        ContentCertImageRecord_t cntImageRec;
+        CCSbSwImgAddData_t  cntNonSignedImageRec;
+        CCHashResult_t      actImageHash;
+    CCAddr_t currLoadStartAddress = 0;
+    uint32_t chunkSizeInBytes = 0;
+    uint32_t actualImageSize = 0;
+
+    /* Use user workspace in double buffer manner */
+    uint32_t *workRam1=NULL, *workRam2=NULL;
+    uint8_t isToggle = CC_FALSE, isLoadIV = CC_TRUE;
+
+    /*------------------
+        CODE
+    -------------------*/
+
+    /* In order to improve performance the Loading from Flash will be done simultaneously wit Hash calculation */
+
+    /* Initialize parameters */
+        UTIL_MemCopy((uint8_t *)&cntImageRec, (uint8_t *)pSwRecSignedData, sizeof(ContentCertImageRecord_t));
+    /* The non-signed is word aligned, so we can cast the pointer */
+        UTIL_MemCopy((uint8_t *)&cntNonSignedImageRec, (uint8_t *)pSwRecNonSignedData, sizeof(CCSbSwImgAddData_t));
+
+        actualImageSize = cntNonSignedImageRec.Len;
+    currLoadStartAddress = cntImageRec.loadAddr;
+
+        if (cntImageRec.isAesCodeEncUsed == 0){
+        /* overwrite crypto mode to hash only */
+        cryptoMode = BSV_CRYPTO_HASH;
+        keyType = CC_BSV_END_OF_KEY_TYPE;
+    } else {
+        /* verify crypto mode and key are set for aes */
+        if( (cryptoMode == BSV_CRYPTO_HASH) || (keyType == CC_BSV_END_OF_KEY_TYPE) ){
+            CC_PAL_LOG_ERR("AES operation is not configuraed correctly\n");
+            return CC_BOOT_IMG_VERIFIER_CERT_DECODING_ILLEGAL;
+        }
+    }
+
+    /* Validate image size */
+    if ((cntNonSignedImageRec.Len == 0) ||
+            (cntNonSignedImageRec.Len > cntImageRec.imageMaxSize)) {
+        CC_PAL_LOG_ERR("SW image size is illegal !\n");
+        return CC_BOOT_IMG_VERIFIER_SW_COMP_SIZE_IS_NULL;
+    }
+
+    /* Set chunk size for read and process data (fixed according to user workspace or HW limitation) */
+    chunkSizeInBytes = CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES / 2;
+
+    /* In case of no loading address, we use user workspace in double buffer mode */
+    if (cntImageRec.loadAddr == CC_SW_COMP_NO_MEM_LOAD_INDICATION) {
+
+        isToggle = CC_TRUE;
+
+        /* The workspace minimum size must be at least CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES,
+           if its not the function will return error (if temp memory should be used) */
+        if (workspaceSize < CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES){
+
+            CC_PAL_LOG_ERR("workspace size too small\n");
+            return CC_BOOT_IMG_VERIFIER_WORKSPACE_SIZE_TOO_SMALL;
+        }
+
+        /* Divide the workspace into 2 buffers, in order to allow reading and calculating HASH
+         simultaneously , each buffer size is CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES/2 */
+        workRam1 = workspace_ptr; /* Size of this section is CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES/2 */
+        workRam2 = workspace_ptr + (CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES/2)/sizeof(uint32_t);
+
+        /* Starting with the first buffer */
+        cntImageRec.loadAddr = CONVERT_TO_ADDR(workRam1);
+    }
+
+    if (isVerifyImage == CC_TRUE){
+
+        /* initialize the AES and HASH */
+        error = BsvCryptoImageInit(hwBaseAddress, cryptoMode, keyType);
+        if (error != CC_OK) {
+                            CC_PAL_LOG_ERR("BsvCryptoImageInit failed 0x%xl !\n", error);
+                return error;
+        }
+    }
+
+    /* Load and/or Verify image in chunks */
+    /*------------------------------------*/
+    while (cntNonSignedImageRec.Len > 0) {
+
+        /* Set number of bytes to load and/or verify */
+        chunkSizeInBytes = min(chunkSizeInBytes, cntNonSignedImageRec.Len);
+
+        /* Copy data from the flash to memory with user callback */
+        if ( isLoadFromFlash == CC_TRUE) {
+            error = preHashflashRead_func(cntNonSignedImageRec.StoreAddr, (uint8_t*)(CONVERT_TO_ADDR(cntImageRec.loadAddr)),
+                                            chunkSizeInBytes, preHashUserContext);
+            if (error != CC_OK) {
+                                CC_PAL_LOG_ERR("preHashflashRead_func failed 0x%xl !\n", error);
+                return error;
+            }
+        }
+
+        if (isVerifyImage == CC_TRUE){
+            /* Per chunk, run CC operation (hash + AES) in-place.
+            To improve performance, do not wait for completion operation */
+            error = BsvCryptoImageUpdate( hwBaseAddress, cryptoMode, keyType, (uint32_t *)AESIv,
+                            (uint8_t *)(CONVERT_TO_ADDR(cntImageRec.loadAddr)),
+                            (uint8_t *)(CONVERT_TO_ADDR(cntImageRec.loadAddr)),
+                                                     chunkSizeInBytes, actImageHash, isLoadIV);
+            if (error != CC_OK) {
+                                CC_PAL_LOG_ERR("BsvCryptoImageUpdate failed 0x%xl !\n", error);
+                return error;
+            }
+            isLoadIV = CC_FALSE;
+        }
+
+        /* Update for next chunk */
+               cntNonSignedImageRec.StoreAddr = (CCAddr_t)((unsigned long)cntNonSignedImageRec.StoreAddr + chunkSizeInBytes);
+        cntImageRec.loadAddr = (CCAddr_t)((unsigned long)cntImageRec.loadAddr + chunkSizeInBytes);
+        cntNonSignedImageRec.Len = cntNonSignedImageRec.Len - chunkSizeInBytes;
+
+        if (isToggle == CC_TRUE) {
+
+            /* Toggle on user's workspace (double buffer) */
+            if ( cntImageRec.loadAddr == CONVERT_TO_ADDR(workRam1) ){
+                cntImageRec.loadAddr = CONVERT_TO_ADDR(workRam2);
+            } else {
+                cntImageRec.loadAddr = CONVERT_TO_ADDR(workRam1);
+            }
+        }
+    }
+
+    if (isVerifyImage == CC_TRUE){
+
+        /* get Hash result  and compare  */
+                error = BsvCryptoImageFinish(hwBaseAddress, cryptoMode, actImageHash);
+        if (error != CC_OK){
+                        CC_PAL_LOG_ERR("BsvCryptoImageFinish failed 0x%xl !\n", error);
+            return error;
+        }
+
+                error = UTIL_MemCmp((uint8_t *)cntImageRec.imageHash, (uint8_t *)actImageHash, HASH_RESULT_SIZE_IN_BYTES);
+        if (error != CC_TRUE){
+            CC_PAL_LOG_ERR("SW comp failed verification\n");
+            /* clear image in RAM in case of CC_SB_LOAD_AND_VERIFY scheme */
+            if ((isLoadFromFlash == CC_TRUE) && (isVerifyImage == CC_TRUE)
+                && (currLoadStartAddress != CC_SW_COMP_NO_MEM_LOAD_INDICATION)){
+                    UTIL_MemSet((uint8_t*)currLoadStartAddress, 0, actualImageSize);
+            }
+            return CC_BOOT_IMG_VERIFIER_SW_COMP_FAILED_VERIFICATION;
+        }
+    }
+
+    return CC_OK;
+}
+
+
+CCError_t CCSbSetNvCounter(unsigned long hwBaseAddress, CCSbCertInfo_t *certPkgInfo)
+{
+    CCError_t error = CC_OK;
+
+    if (NULL == certPkgInfo) {
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+    /* if version is bigger, then set the new version in the otp */
+    if (certPkgInfo->activeMinSwVersionVal > certPkgInfo->otpVersion) {
+        error =  NVM_SetSwVersion(hwBaseAddress, certPkgInfo->keyIndex, certPkgInfo->activeMinSwVersionVal);
+        if (CC_OK != error) {
+            return error;
+        }
+    }
+
+    return error;
+}
+
+CCError_t CCSbVerifyNvCounter(unsigned long hwBaseAddress, uint32_t swVersion, CCSbCertInfo_t *certPkgInfo)
+{
+    CCError_t error = CC_OK;
+    uint32_t otpVersion;
+    uint8_t initFlag;
+    CCSbPubKeyIndexType_t keyIndex;
+    uint32_t activeNvCounterVal;
+
+    /* Validate input parameters */
+    if (NULL == certPkgInfo) {
+        CC_PAL_LOG_ERR("invalid inputs\n");
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+    initFlag = certPkgInfo->initDataFlag;
+
+    keyIndex = certPkgInfo->keyIndex;
+
+    if (initFlag == 0) {
+        /* Get sw version from OTP */
+        error = NVM_GetSwVersion(hwBaseAddress, keyIndex, &otpVersion);
+        if (CC_OK != error) {
+            return error;
+        }
+
+        certPkgInfo->otpVersion = otpVersion;
+    } else {
+
+        otpVersion = certPkgInfo->otpVersion;
+        //keyIndex = certPkgInfo->keyIndex;
+        activeNvCounterVal = certPkgInfo->activeMinSwVersionVal;
+
+        if ( activeNvCounterVal != swVersion ){
+            CC_PAL_LOG_ERR("active counter version is different from the current\n");
+            return CC_BOOT_IMG_VERIFIER_CERT_SW_VER_ILLEGAL;
+        }
+
+    }
+
+    /* Verify the certificate version against the otp */
+    if (swVersion < otpVersion){
+        CC_PAL_LOG_ERR("currSwVersion1 < minVersion\n");
+        return CC_BOOT_IMG_VERIFIER_SW_VER_SMALLER_THAN_MIN_VER;
+    }
+
+    return CC_OK;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_base_swimgverify.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_base_swimgverify.h
new file mode 100644
index 0000000..321b06e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_base_swimgverify.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _SECURE_BOOT_BASE_SWIMGVERIFY_H
+#define _SECURE_BOOT_BASE_SWIMGVERIFY_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "secureboot_defs.h"
+#include "secureboot_stage_defs.h"
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/**
+ * @brief This function load the SW component to RAM, calculates HASH on it and compares the
+ *        result with the given HASH (taken from the certificate).
+ *        This function calculates the HASH simultaneously to reading data from the Flash.
+ *
+ *
+ * @param[in] preHashflashRead_func - User's Flash read function used to read data from the flash to memory location.
+ *        this is the first function used (before the hash)
+ * @param[in] preHashUserContext - User's context for the usage of preHashflashRead_func
+ * @param[in] hwBaseAddress - base address for the ARM TrustZone CryptoCell HW engines
+ * @param[in] isLoadFromFlash - should image be copied from flash with user callback
+ * @param[in] isVerifyImage - should image be verified with hash (and Aes if needed)
+ * @param[in] cryptoMode - crypto mode type: 0 = AES to Hash; 1 = AES and Hash
+ * @param[in] keyType - code encryption type definition
+ * @param[in] AESIv - AES IV buffer
+ * @param[in] pSwRecSignedData - a pointer to the s/w record signed data: hash, load address, max image size, code encode flag
+ * @param[in] pSwRecNoneSignedData - a pointer to the s/w record non-signed data: storage address, actual image size
+ * @param[in] workspace_ptr - temporary buffer to load the SW components to (SW components without
+ *            loading address).
+ * @param[in] workspaceSize - the temporary buffer size in bytes, minimal allowed size is
+ *            CC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from BootImagesVerifier_error.h
+ */
+
+CCError_t CCSbImageLoadAndVerify(CCSbFlashReadFunc preHashflashRead_func,
+                       void *preHashUserContext,
+                       unsigned long hwBaseAddress,
+                       uint8_t isLoadFromFlash,
+                       uint8_t isVerifyImage,
+                       bsvCryptoMode_t cryptoMode,
+                       CCBsvKeyType_t  keyType,
+                       AES_Iv_t AESIv,
+                       uint8_t *pSwRecSignedData,
+                       uint32_t *pSwRecNoneSignedData,
+                       uint32_t *workspace_ptr,
+                       uint32_t workspaceSize);
+
+/*!
+ * @brief verify NV counter extension against OTP
+ *
+ * @param[in] hwBaseAddress - hw registers base address
+ * @param[in] pCertNvCounter    - NV counter fields read from certificate
+ * @param[in] certPkgInfo   - certPkgInfo - certificate data structure
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from bsv_error.h
+ */
+CCError_t CCSbVerifyNvCounter(unsigned long hwBaseAddress, uint32_t swVersion, CCSbCertInfo_t *certPkgInfo);
+
+/*!
+ * @brief Set NV counter to the OTP (if needed)
+ *
+ * @param[in] hwBaseAddress - hw registers base address
+ * @param[in] certPkgInfo   - certificate data structure
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from bsv_error.h
+ */
+CCError_t CCSbSetNvCounter(unsigned long hwBaseAddress, CCSbCertInfo_t *certPkgInfo);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_defs.h
new file mode 100644
index 0000000..4394c82
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_defs.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_sb_defs
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains type definitions for the Secure Boot.
+ */
+
+
+#ifndef _SECURE_BOOT_DEFS_H
+#define _SECURE_BOOT_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_crypto_boot_defs.h"
+#include "cc_sec_defs.h"
+
+
+/* General definitions */
+/***********************/
+
+/*! Input or output structure for the Secure Boot verification API. */
+typedef struct{
+    /*! The NV counter saved in OTP. */
+    uint32_t otpVersion;
+    /*! The key hash to retrieve: The 128-bit Hbk0, the 128-bit Hbk1, or the
+    256-bit Hbk. */
+    CCSbPubKeyIndexType_t keyIndex;
+    /*! The value of the SW version for the certificate-chain. */
+    uint32_t activeMinSwVersionVal;
+    /*! In: The hash of the public key (N||Np), to compare to the public key
+    stored in the certificate. Out: The hash of the public key (N||Np) stored
+    in the certificate, to be used for verification of the public key of the
+    next certificate in the chain. */
+    CCHashResult_t pubKeyHash;
+    /*! Internal flag for the initialization indication. */
+    uint32_t initDataFlag;
+}CCSbCertInfo_t;
+
+
+
+/*! The size of the data of the SW-image certificate. */
+#define SW_REC_SIGNED_DATA_SIZE_IN_BYTES            44  // HS(8W) + load_adddr(1) + maxSize(1) + isCodeEncUsed(1)
+/*! The size of the additional-data of the SW-image certificate in bytes. */
+#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES       8   // storage_addr(1) + ActualSize(1)
+/*! The size of the additional-data of the SW-image certificate in words. */
+#define SW_REC_NONE_SIGNED_DATA_SIZE_IN_WORDS       SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES/CC_32BIT_WORD_SIZE
+/*! Indication whether or not to load the SW image to memory. */
+#define CC_SW_COMP_NO_MEM_LOAD_INDICATION       0xFFFFFFFFUL
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/cc3x_nvm_rt/nvm_otp.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/cc3x_nvm_rt/nvm_otp.c
new file mode 100644
index 0000000..3611ae8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/cc3x_nvm_rt/nvm_otp.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+
+#include "secureboot_basetypes.h"
+#include "secureboot_error.h"
+#include "nvm_otp.h"
+#include "secureboot_general_hwdefs.h"
+#include "rsa_bsv.h"
+#include "bootimagesverifier_error.h"
+#include "mbedtls_cc_mng_error.h"
+
+#include "bsv_defs.h"
+#include "bsv_error.h"
+
+#include "secureboot_stage_defs.h"
+
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Public functions ******************************/
+
+/************************ Private functions ******************************/
+
+
+/**
+ * @brief This function reads the LCS from the SRAM/NVM
+ *
+ * @param[in] hwBaseAddress  -  cryptocell base address
+ *
+ * @param[in/out] lcs_ptr  - pointer to memory to store the LCS
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure   -a value from NVM_error.h
+ */
+CCError_t NVM_GetLCS(unsigned long hwBaseAddress, uint32_t *lcs_ptr)
+{
+  CCError_t error = CC_OK;
+
+  /* Get LCS from register */
+  error = CC_BsvLcsGet(hwBaseAddress, lcs_ptr);
+
+  return error;
+}
+
+
+/**
+ * @brief The NVM_ReadHASHPubKey function is a NVM interface function -
+ *        The function retrieves the HASH of the device Public key from the SRAM/NVM
+ *
+ *
+ * @param[in] hwBaseAddress -  cryptocell base address
+ *
+ * @param[in] keyIndex -  Index of HASH in the OTP
+ *
+ * @param[out] PubKeyHASH   -  the public key HASH.
+ *
+ * @param[in] hashSizeInWords -  hash size (valid values: 4W, 8W)
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure   -a value from NVM_error.h
+ */
+CCError_t NVM_ReadHASHPubKey(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, CCHashResult_t PubKeyHASH, uint32_t hashSizeInWords)
+{
+    CCError_t error = CC_OK;
+    uint32_t i;
+    uint32_t lcs;
+
+    /* Check input variables */
+    if (PubKeyHASH == NULL)
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+
+    /* Get LCS from register */
+    error = CC_BsvLcsGet(hwBaseAddress, &lcs);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    if ( (lcs == CC_BSV_CHIP_MANUFACTURE_LCS) ||
+         (lcs == CC_BSV_RMA_LCS) ){
+        return CC_BOOT_IMG_VERIFIER_SKIP_PUBLIC_KEY_VERIFY;
+    }
+
+    error = CC_BsvPubKeyHashGet(hwBaseAddress, keyIndex, PubKeyHASH, hashSizeInWords);
+    /* Secure Boot should skip verification of the Certificate key against OTP memory when public key hash is not programmed yet (in CM or DM). */
+    if (error == CC_MNG_HASH_NOT_PROGRAMMED_ERR){
+        return CC_BOOT_IMG_VERIFIER_SKIP_PUBLIC_KEY_VERIFY;
+    }
+
+    if (error == CC_OK){
+        /* All key and digest fields are stored in OTP in little-endian format */
+        for (i=0; i < hashSizeInWords; i++) {
+            PubKeyHASH[i] = UTIL_REVERT_UINT32_BYTES( PubKeyHASH[i] );
+        }
+    }
+
+    return error;
+}
+
+
+/**
+ * @brief The NVM_GetSwVersion function is a NVM interface function -
+ *        The function retrieves the SW version from the SRAM/NVM.
+ *        In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate)
+ *
+ * @param[in] hwBaseAddress -  cryptocell base address
+ *
+ * @param[in] keyIndex -  relevant only for OTP (valid values: 1,2)
+ *
+ * @param[out] swVersion   -  the minimum SW version
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure   -a value from NVM_error.h
+ */
+CCError_t NVM_GetSwVersion(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t* swVersion)
+{
+    uint32_t swVersionNum = 0;
+    CCError_t error = CC_OK;
+
+    /* Check input variables */
+    if (swVersion == NULL)
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+
+    /* get FW minimum version according to counter ID */
+    error = CC_BsvSwVersionGet(hwBaseAddress, keyIndex, &swVersionNum);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    *swVersion = swVersionNum;
+    return CC_OK;
+}
+
+CCError_t NVM_SetSwVersion(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t swVersion)
+{
+    CC_UNUSED_PARAM(hwBaseAddress);
+    CC_UNUSED_PARAM(keyIndex);
+    CC_UNUSED_PARAM(swVersion);
+
+    return CC_OK;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/cc3x_nvm_rt/nvm_otp.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/cc3x_nvm_rt/nvm_otp.h
new file mode 100644
index 0000000..8ba99c7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/cc3x_nvm_rt/nvm_otp.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _NVM_OTP_H
+#define _NVM_OTP_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_crypto_boot_defs.h"
+
+/*------------------------------------
+    DEFINES
+-------------------------------------*/
+
+/**
+ * @brief The NVM_GetSwVersion function is a NVM interface function -
+ *        The function retrieves the SW version from the SRAM/NVM.
+ *    In case of OTP, we support up to 16 anti-rollback counters (taken from the certificate)
+ *
+ * @param[in] hwBaseAddress -  CryptoCell base address
+ *
+ * @param[in] counterId -  relevant only for OTP (valid values: 1,2)
+ *
+ * @param[out] swVersion   -  the minimum SW version
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure   -a value from NVM_error.h
+ */
+CCError_t NVM_GetSwVersion(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t* swVersion);
+
+
+/**
+ * @brief The run time secure boot should not support SW version update.
+ *
+ * @param[in] hwBaseAddress -  CryptoCell base address
+ *
+ * @param[in] counterId -  relevant only for OTP (valid values: 1,2)
+ *
+ * @param[out] swVersion   -  the minimum SW version
+ *
+ * @return CCError_t - always return CC_OK
+ */
+
+CCError_t NVM_SetSwVersion(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t swVersion);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/nvm.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/nvm.h
new file mode 100644
index 0000000..c1afa13
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/nvm/nvm.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _NVM__H
+#define _NVM__H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*------------------------------------
+    DEFINES
+-------------------------------------*/
+
+/**
+ * @brief This function reads the LCS from the SRAM/NVM
+ *
+ * @param[in] hwBaseAddress  -  CryptoCell base address
+ *
+ * @param[in/out] lcs_ptr  - pointer to memory to store the LCS
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure   -a value from NVM_error.h
+ */
+CCError_t NVM_GetLCS(unsigned long hwBaseAddress, uint32_t *lcs_ptr);
+
+/**
+ * @brief The NVM_ReadHASHPubKey function is a NVM interface function -
+ *        The function retrieves the HASH of the device Public key from the SRAM/NVM
+ *
+ * @param[in] hwBaseAddress -  CryptoCell base address
+ *
+ * @param[in] pubKeyIndex -  Index of HASH in the OTP
+ *
+ * @param[out] PubKeyHASH   -  the public key HASH.
+ *
+ * @param[in] hashSizeInWords -  hash size (valid values: 4W, 8W)
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure   -a value from NVM_error.h
+ */
+
+CCError_t NVM_ReadHASHPubKey(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t pubKeyIndex, CCHashResult_t PubKeyHASH, uint32_t hashSizeInWords);
+
+
+/**
+ * @brief The NVM_ReadAESKey function is a NVM interface function -
+ *        The function retrieves the AES CTR 128 bit key from the NVM
+ *
+ * @param[in] hwBaseAddress -  CryptoCell base address
+ *
+ * @param[out] AESKey   -  Kce from OTP for SW image decryption
+ *
+ * @return CCError_t - On success the value CC_OK is returned, and on failure   -a value from NVM_error.h
+ */
+CCError_t NVM_ReadAESKey(unsigned long hwBaseAddress, AES_Key_t AESKey);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc3x/cc_pal_sb_plat.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc3x/cc_pal_sb_plat.h
new file mode 100644
index 0000000..5805fd1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc3x/cc_pal_sb_plat.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_sb_plat
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains platform-dependent definitions used in the Boot Services code.
+ */
+
+#ifndef _CC_PAL_SB_PLAT_H
+#define _CC_PAL_SB_PLAT_H
+
+#include "cc_pal_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! DMA address types: 32 bits or 64 bits, according to platform. */
+typedef uint32_t        CCDmaAddr_t;
+/*! CryptocCell address types: 32 bits or 64 bits, according to platform. */
+typedef uint32_t        CCAddr_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+/*!
+ @}
+ */
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc_pal_x509_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc_pal_x509_defs.h
new file mode 100644
index 0000000..2815004
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc_pal_x509_defs.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+@file
+@brief This file contains user-defined functions, definitions and TBS header struct.
+*/
+
+#ifndef _CC_PAL_X509_DEFS_H
+#define _CC_PAL_X509_DEFS_H
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_crypto_x509_common_defs.h"
+
+#define CC_CERT_USER_DATA_KEY_OFFSET        0
+#define CC_CERT_USER_DATA_PRIM_OFFSET       1
+#define CC_CERT_USER_DATA_SECOND_OFFSET     2
+
+/*!
+@brief This function checks validity period and should be implemented by customer.
+       It receives start and end validity period as input. It also receives an indication flag for each period. If the flag is not 1,
+       the value of current period was not defined by the user.
+
+@return CC_OK On success.
+@return A non-zero value from sbrom_bsv_error.h on failure.
+*/
+CCError_t CC_PalVerifyCertValidity(char *pNotBeforeStr, /*!< [in] Pointer to the start period string. */
+    uint32_t notBeforeStrSize, /*!< [in] Size of the start period string. */
+    uint8_t notBeforeStrFlag, /*!< [in] Start period definition flag indication. */
+    char *pNotAfterStr,/*!< [in] Pointer to the end period string. */
+    uint32_t notAfterStrSize,/*!< [in] Size of the end period string. */
+    uint8_t notAfterStrFlag); /*!< [in] Start period definition Flag indication. */
+
+
+
+/*! x509 Certificate user's data. This data is outputed after the certificate passed validation */
+typedef struct {
+    uint8_t   setSerialNum;                                   /*! Definition flag of certificate serial number. */
+    uint32_t  serialNum;                                      /*! Value of  certificate serial number. */
+    uint8_t   setIssuerName;                                  /*! Definition flag of certificate issuer name. */
+    char      IssuerName[X509_ISSUER_NAME_MAX_STRING_SIZE+1];   /*! String of certificate issuer name. */
+    uint8_t   setSubjectName;                                 /*! Definition flag of certificate subject name. */
+    char      SubjectName[X509_SUBJECT_NAME_MAX_STRING_SIZE+1]; /*! String of certificate subject name. */
+    uint8_t   setNotBeforeStr;                                /*! Definition flag of start validity period.  */
+    char      NotBeforeStr[X509_VALIDITY_PERIOD_MAX_STRING_SIZE+1]; /*! String of start validity period. */
+    uint8_t   setNotAfterStr;                                     /*! Definition flag of end validity period.  */
+    char      NotAfterStr[X509_VALIDITY_PERIOD_MAX_STRING_SIZE+1]; /*! String of end validity period. */
+#ifdef CC_SB_CERT_USER_DATA_EXT
+    uint8_t   userData[X509_USER_DATA_MAX_SIZE_BYTES*3];           /*! Byte array containing the user's data from the certificate, only valid if the ROM was
+                                       compiled with CC_CONFIG_SB_CERT_USER_DATA_EXT = 1.
+                                       This structure is used by secure debug and secure boot. In case of secure debug
+                                       there are 3 buffers of user's data: key, primary debug, secondary debug*/
+#endif
+}CCX509CertHeaderInfo_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc_pal_x509_verify.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc_pal_x509_verify.c
new file mode 100644
index 0000000..85b178d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/pal/cc_pal_x509_verify.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+#include "secureboot_basetypes.h"
+/*!
+@brief This function checks validity period and should be implemented by customer.
+    <ul><li> The function gets as input start and end validiy period.</li>
+    <li> For each period the function gets indication flag.</li>
+    <li> if the flag is not 1 the value of current period wasn't defined be user.</li></ul>
+
+@return CC_OK   On success.
+@return a non-zero value from sbrom_bsv_error.h on failure.
+*/
+
+CCError_t CC_PalVerifyCertValidity(char *pNotBeforeStr,uint32_t notBeforeStrSize,uint8_t notBeforeStrFlag,
+    char *pNotAfterStr,uint32_t notAfterStrSize,uint8_t notAfterStrFlag){
+
+    CC_UNUSED_PARAM(pNotBeforeStr);
+    CC_UNUSED_PARAM(pNotAfterStr);
+    CC_UNUSED_PARAM(notBeforeStrSize);
+    CC_UNUSED_PARAM(notBeforeStrFlag);
+    CC_UNUSED_PARAM(notAfterStrSize);
+    CC_UNUSED_PARAM(notAfterStrFlag);
+
+    return 0;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/stage/rt/cc3x/secureboot_stage_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/stage/rt/cc3x/secureboot_stage_defs.h
new file mode 100644
index 0000000..b7b0844
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/platform/stage/rt/cc3x/secureboot_stage_defs.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SECURE_BOOT_STAGE_DEFS_H
+#define _SECURE_BOOT_STAGE_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains all of the definitions and structures used for the run-time Secure Boot.
+*/
+
+#include "cc_pal_mem.h"
+#include "cc_crypto_boot_defs.h"
+#include "cc_sec_defs.h"
+#include "secureboot_parser_gen_defs.h"
+#include "secureboot_general_hwdefs.h"
+#include "bsv_crypto_driver.h"
+#include "bsv_crypto_api.h"
+#include "crypto_driver.h"
+#include "bsv_hw_defs.h"
+#include "sbrt_int_func.h"
+#include "mbedtls_cc_mng.h"
+#include "pka_hw_defs.h"
+
+extern unsigned long gCcRegBase;
+
+/* ROM ==> RT */
+#define CC_BSV_CHIP_MANUFACTURE_LCS CC_MNG_LCS_CM
+#define CC_BSV_DEVICE_MANUFACTURE_LCS   CC_MNG_LCS_DM
+#define CC_BSV_SECURE_LCS       CC_MNG_LCS_SEC_ENABLED
+#define CC_BSV_RMA_LCS          CC_MNG_LCS_RMA
+
+#define UTIL_MemCopy(pDst, pSrc ,size)          \
+    CC_PalMemCopy(pDst, pSrc, size)
+#define UTIL_MemSet(pBuff, val, size )          \
+    CC_PalMemSet(pBuff, val, size)
+#define UTIL_MemCmp(pBuff1, pBuff2, size)       \
+    SBRT_MemCmp(pBuff1, pBuff2, size)
+#define UTIL_ReverseMemCopy(pDst, pSrc, size)       \
+    SBRT_ReverseMemCopy(pDst, pSrc, size)
+#define UTIL_ReverseBuff(pBuff, size)           \
+    SBRT_ReverseMemCopy(pBuff, pBuff, size)
+
+#define _CCSbImageLoadAndVerify(preHashflashRead_func, preHashUserContext, hwBaseAddress, isLoadFromFlash, isVerifyImage, cryptoMode, keyType, AESIv, pSwRecSignedData, pSwRecNoneSignedData, workspace_ptr, workspaceSize) \
+    SBRT_ImageLoadAndVerify(preHashflashRead_func, preHashUserContext, hwBaseAddress, isLoadFromFlash, isVerifyImage, cryptoMode, keyType, AESIv, pSwRecSignedData, pSwRecNoneSignedData, workspace_ptr, workspaceSize)
+
+#define _RSA_PSS_Verify(hwBaseAddress, mHash, pN, pNp, pSign)   \
+    SBRT_RSA_PSS_Verify(hwBaseAddress, mHash, pN, pNp, pSign)
+
+#define CC_BsvLcsGet(hwBaseAddress, pLcs) \
+    SBRT_LcsGet(hwBaseAddress, pLcs)
+
+#define SB_HAL_WRITE_REGISTER(addr,val) \
+        ((*((volatile uint32_t*)(gCcRegBase + addr))) = (unsigned long)(val))
+#define SB_HAL_READ_REGISTER(addr,val)  \
+        ((val) = (*((volatile uint32_t*)(gCcRegBase + addr))))
+
+#define SB_HalClearInterruptBit(hwBaseAddress, data) \
+    SBRT_HalClearInterruptBit(hwBaseAddress, data)
+
+#define SB_HalMaskInterrupt(hwBaseAddress, data) \
+    SBRT_HalMaskInterrupt(hwBaseAddress, data)
+
+#define SB_HalWaitInterrupt(hwBaseAddress, data) \
+    SBRT_HalWaitInterrupt(hwBaseAddress, data)
+
+#define CC_BsvOTPWordRead(hwBaseAddress, otpAddress, pOtpWord) \
+    SBRT_OTPWordRead(hwBaseAddress, otpAddress, pOtpWord)
+
+#define CC_BsvSwVersionGet(hwBaseAddress, keyIndex, swVersion)  \
+    SBRT_SwVersionGet(hwBaseAddress, keyIndex, swVersion)
+
+#define CC_BsvPubKeyHashGet(hwBaseAddress, keyIndex, hashedPubKey, hashResultSizeWords) \
+    SBRT_PubKeyHashGet(hwBaseAddress, keyIndex, hashedPubKey, hashResultSizeWords)
+
+#define CC_BsvSHA256(hwBaseAddress, pDataIn, dataSize, hashBuff) \
+    SBRT_SHA256(hwBaseAddress, pDataIn, dataSize, hashBuff)
+
+#define BsvCryptoImageInit(hwBaseAddress, mode, keyType) \
+    SBRT_CryptoImageInit(hwBaseAddress, mode, keyType)
+
+#define BsvCryptoImageUpdate(hwBaseAddress, mode, keyType, pCtrStateBuf, pDataIn, pDataOut, dataSize, hashBuff, isLoadIV) \
+    SBRT_CryptoImageUpdate(hwBaseAddress, mode, keyType, pCtrStateBuf, pDataIn, pDataOut, dataSize, hashBuff, isLoadIV)
+
+#define BsvCryptoImageFinish(hwBaseAddress, mode, hashBuff) \
+    SBRT_CryptoImageFinish(hwBaseAddress, mode, hashBuff)
+
+#undef min
+#define min(a, b) \
+    CC_MIN(a, b)
+
+#ifdef BIG__ENDIAN
+#define UTIL_REVERT_UINT32_BYTES( val ) \
+   ( ((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24) )
+#else
+#define UTIL_REVERT_UINT32_BYTES( val ) (val)
+#endif
+
+#ifdef BIG__ENDIAN
+#define UTIL_INVERSE_UINT32_BYTES( val )    (val)
+#else
+#define UTIL_INVERSE_UINT32_BYTES( val ) \
+   ( ((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24) )
+#endif
+
+/* rsa_hwdefs => pka_hw_defs */
+#define RSA_PKA_MAX_COUNT_OF_REGS_SIZES         PKA_NUM_OF_PKA_LEN_IDS_REGS
+#define RSA_PKA_BIG_WORD_SIZE_IN_BITS           CC_PKA_WORD_SIZE_IN_BITS
+#define RSA_PKA_BIG_WORD_SIZE_IN_32_BIT_WORDS       PKA_WORD_SIZE_IN_32BIT_WORDS
+#define RSA_PKA_EXTRA_BITS                  PKA_EXTRA_BITS
+#define   PkaModExp                 PKA_OPCODE_ID_MODEXP
+#define RSA_PKA_SRAM_REGS_MEM_OFFSET_WORDS      CC_SRAM_PKA_BASE_ADDRESS
+#define RSA_HW_PKI_PKA_N_NP_T0_T1_REG_DEFAULT_VAL   PKA_N_NP_T0_T1_REG_DEFAULT_VAL
+
+#define RSA_PKA_FullOpCode( Opcode,LenID,IsAImmed,OpA,IsBImmed,OpB,ResDiscard,Res,Tag ) \
+    PKA_SET_FULL_OPCODE(Opcode,LenID,IsAImmed,OpA,IsBImmed,OpB,ResDiscard,Res,Tag )
+#define RSA_PKA_WAIT_ON_PKA_PIPE_READY(VirtualHwBaseAddr) \
+    CC_UNUSED_PARAM(VirtualHwBaseAddr); \
+    PKA_WAIT_ON_PKA_PIPE_READY()
+#define RSA_PKA_WAIT_ON_PKA_DONE(VirtualHwBaseAddr) \
+    CC_UNUSED_PARAM(VirtualHwBaseAddr); \
+    PKA_WAIT_ON_PKA_DONE()
+#define RSA_PKA_ReadRegSize(SizeBits, EntryNum, VirtualHwBaseAddr) \
+    CC_UNUSED_PARAM(VirtualHwBaseAddr); \
+    PKA_GET_REG_SIZE(SizeBits, EntryNum)
+#define RSA_HW_PKI_HW_LOAD_BLOCK_TO_PKA_MEM( VirtualHwBaseAddr , Addr , ptr , SizeWords ) \
+    CC_UNUSED_PARAM(VirtualHwBaseAddr); \
+    PKA_HW_LOAD_BLOCK_TO_PKA_MEM(Addr, ptr, SizeWords)
+#define RSA_HW_PKI_HW_CLEAR_PKA_MEM( VirtualHwBaseAddr , Addr , SizeWords ) \
+    CC_UNUSED_PARAM(VirtualHwBaseAddr); \
+    PKA_HW_CLEAR_PKA_MEM(Addr, SizeWords)
+#define RSA_HW_PKI_HW_READ_BLOCK_FROM_PKA_MEM( VirtualHwBaseAddr , Addr , ptr , SizeWords ) \
+    CC_UNUSED_PARAM(VirtualHwBaseAddr); \
+    PKA_HW_READ_BLOCK_FROM_PKA_MEM(Addr, ptr, SizeWords)
+#define RSA_PKA_GetRegAddress(VirtReg, VirtualHwBaseAddr) \
+    (*((volatile uint32_t*)(gCcRegBase + CC_REG_OFFSET(CRY_KERNEL, MEMORY_MAP0) + 4*(VirtReg))))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/bootimagesverifier_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/bootimagesverifier_error.h
new file mode 100644
index 0000000..125f333
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/bootimagesverifier_error.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _BOOT_IMAGES_VERIFIER_ERROR_H
+#define _BOOT_IMAGES_VERIFIER_ERROR_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "secureboot_error.h"
+
+/*! @file
+@brief This file contains error code definitions used for the Secure Boot and Secure Debug APIs.
+*/
+
+/*! Defines error code for invalid input parameters. */
+#define CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM                            (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000001)
+/*! Defines error code for invalid OTP version. */
+#define CC_BOOT_IMG_VERIFIER_OTP_VERSION_FAILURE                        (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000002)
+/*! Defines error code for illegal certificate's magic number. */
+#define CC_BOOT_IMG_VERIFIER_CERT_MAGIC_NUM_INCORRECT                   (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000003)
+/*! Defines error code for illegal certificate version. */
+#define CC_BOOT_IMG_VERIFIER_CERT_VERSION_NUM_INCORRECT                 (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000004)
+/*! Defines error code for illegal certificate SW version, that is smaller than the version stored in the OTP. */
+#define CC_BOOT_IMG_VERIFIER_SW_VER_SMALLER_THAN_MIN_VER                (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000005)
+/*! Defines error code for public key verification compared to the OTP value failed. */
+#define CC_BOOT_IMG_VERIFIER_PUB_KEY_HASH_VALIDATION_FAILURE            (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000006)
+/*! Defines error code for certificate's RSA signature verification failure. */
+#define CC_BOOT_IMG_VERIFIER_RSA_SIG_VERIFICATION_FAILED                (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000007)
+/*! Defines error code for workspace buffer given to the API is too small. */
+#define CC_BOOT_IMG_VERIFIER_WORKSPACE_SIZE_TOO_SMALL                   (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000008)
+/*! Defines error code for SW image hash verification failure. */
+#define CC_BOOT_IMG_VERIFIER_SW_COMP_FAILED_VERIFICATION                (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000009)
+/*! Defines error code for illegal SW version or ID of SW version. */
+#define CC_BOOT_IMG_VERIFIER_CERT_SW_VER_ILLEGAL                (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x0000000D)
+/*! Defines error code for illegal number of SW components (zero). */
+#define CC_BOOT_IMG_VERIFIER_SW_COMP_SIZE_IS_NULL                       (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000011)
+/*! Defines error code for hash of public key is not burned yet. */
+#define CC_BOOT_IMG_VERIFIER_PUBLIC_KEY_HASH_EMPTY                      (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000014)
+/*! Defines error code for illegal lifecycle state (LCS) for operation.*/
+#define CC_BOOT_IMG_VERIFIER_ILLEGAL_LCS_FOR_OPERATION_ERR          (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000015)
+/*! Defines error code for hash of public key is already programmed.*/
+#define CC_BOOT_IMG_VERIFIER_PUB_KEY_ALREADY_PROGRAMMED_ERR     (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000016)
+/*! Defines error code for OTP write failure.*/
+#define CC_BOOT_IMG_VERIFIER_OTP_WRITE_FAIL_ERR             (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000017)
+/*! Defines error code for incorrect certificate type.*/
+#define CC_BOOT_IMG_VERIFIER_INCORRECT_CERT_TYPE            (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000018)
+/*! Defines error code for illegal Hash boot key index.*/
+#define CC_BOOT_IMG_VERIFIER_ILLEGAL_HBK_IDX                (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000019)
+/*! Defines error code for hash boot key of ICV is not programmed.*/
+#define CC_BOOT_IMG_VERIFIER_PUB_KEY1_NOT_PROGRAMMED_ERR        (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x0000001A)
+/*! Defines error code for illegal certificate version value.*/
+#define CC_BOOT_IMG_VERIFIER_CERT_VER_VAL_ILLEGAL               (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x0000001C)
+/*! Defines error code for illegal certificate decoding value.*/
+#define CC_BOOT_IMG_VERIFIER_CERT_DECODING_ILLEGAL              (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x0000001D)
+/*! Defines error code for illegal Kce in RMA LCS.*/
+#define CC_BOOT_IMG_VERIFIER_ILLEGAL_KCE_IN_RMA_STATE               (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x0000001E)
+/*! Defines error code for illegal SOC ID value.*/
+#define CC_BOOT_IMG_VERIFIER_ILLEGAL_SOC_ID_VALUE               (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x0000001F)
+/*! Defines error code for illegal number of SW images per content certificate. */
+#define CC_BOOT_IMG_VERIFIER_ILLEGAL_NUM_OF_IMAGES              (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000020)
+/*! Defines error code for no need to verify hashed public key. */
+#define CC_BOOT_IMG_VERIFIER_SKIP_PUBLIC_KEY_VERIFY                      (CC_BOOT_IMG_VERIFIER_BASE_ERROR + 0x00000014)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_base_func.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_base_func.c
new file mode 100644
index 0000000..12fc261
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_base_func.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+
+#include "secureboot_error.h"
+#include "secureboot_basetypes.h"
+#include "secureboot_parser_gen_defs.h"
+#include "secureboot_defs.h"
+
+#include "bootimagesverifier_error.h"
+#include "rsa_bsv.h"
+#include "cc_pal_log.h"
+#include "cc_pka_hw_plat_defs.h"
+
+#include "secureboot_stage_defs.h"
+
+
+CCError_t CCSbCalcPublicKeyHASH(unsigned long hwBaseAddress,
+                                uint32_t *NAndRevNp_ptr,
+                                uint32_t *hashResult)
+{
+
+        /* error variable */
+        CCError_t error = CC_OK;
+
+        if ((NAndRevNp_ptr == NULL) ||
+            (hashResult == NULL)) {
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        error = SBROM_CryptoHash(hwBaseAddress, CONVERT_TO_ADDR(NAndRevNp_ptr),
+                                 (SB_CERT_RSA_KEY_SIZE_IN_WORDS + RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS) * sizeof(uint32_t),
+                                 hashResult);
+
+        return error;
+}
+
+CCError_t CCSbCalcPublicKeyHASHAndCompare(unsigned long hwBaseAddress,
+                                          uint32_t *NAndRevNp_ptr,
+                                          uint32_t *NHASH_ptr,
+                                          uint32_t    HashSize)
+{
+        /* error variable */
+        CCError_t error = CC_OK;
+
+        /* HASH result of the E||N */
+        CCHashResult_t LocalHashResult;
+
+/*------------------
+    CODE
+-------------------*/
+        if ((NAndRevNp_ptr == NULL) ||
+            (NHASH_ptr == NULL)) {
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        if (HashSize != sizeof(CCHashResult_t) && HashSize != sizeof(CCHashResult_t) / 2) {
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* calculate the HASH value of N (big endian)|| Np (reversed - little endian) */
+        error = CCSbCalcPublicKeyHASH(hwBaseAddress, NAndRevNp_ptr, LocalHashResult);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        /* compare the HASH results */
+        error = UTIL_MemCmp((uint8_t *)LocalHashResult, (uint8_t *)NHASH_ptr, HashSize);
+        if (error != CC_TRUE) {
+                CC_PAL_LOG_ERR("PUB KEY HASH VALIDATION FAILURE\n");
+                return CC_BOOT_IMG_VERIFIER_PUB_KEY_HASH_VALIDATION_FAILURE;
+        }
+
+        return CC_OK;
+} /* End of CCSbCalcPublicKeyHASHAndCompare */
+
+
+
+CCError_t CCSbVerifySignature(unsigned long hwBaseAddress,
+                              uint32_t *pData,
+                              CCSbNParams_t *pNParams,
+                              CCSbSignature_t *pSignature,
+                              uint32_t sizeOfData,
+                              CCSbSignAlg_t sigAlg)
+{
+
+        /* error variable */
+        CCError_t error = CC_OK;
+
+        /* a HASH result variable */
+        CCHashResult_t HashResult;
+
+#ifndef CC_CONFIG_SB_CC3X
+        /* reversed N public key */
+        uint32_t RevN[SB_CERT_RSA_KEY_SIZE_IN_WORDS];
+        uint32_t RevNp[RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+#endif
+
+
+/*------------------
+    CODE
+-------------------*/
+        if ((pData == NULL) ||
+            (pNParams == NULL) ||
+            (pSignature == NULL) ||
+            (sizeOfData == 0) ||
+            ((sigAlg == RSA_PSS_3072) && (SB_CERT_RSA_KEY_SIZE_IN_BITS != 3072)) ||
+            ((sigAlg == RSA_PSS_2048) && (SB_CERT_RSA_KEY_SIZE_IN_BITS != 2048))) {
+                CC_PAL_LOG_ERR("CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM\n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* Calculate HASH on the certificate */
+        /*---------------------------------- */
+        /* calc the  HASH according to the length minus the signature struct size (N,Np & signature)*/
+        error = SBROM_CryptoHash(hwBaseAddress, CONVERT_TO_ADDR(pData),
+                                 sizeOfData,
+                                 HashResult);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed SBROM_CryptoHash 0x%x\n", error);
+                return error;
+        }
+#ifndef CC_CONFIG_SB_CC3X
+        /* Verify the RSA signature of the certificate */
+        /*---------------------------------------------*/
+        /* Reverse the N and Np to be little endian arrays for the PKA usage */
+        UTIL_ReverseMemCopy((uint8_t *)RevN, (uint8_t *)pNParams->N, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+        UTIL_ReverseMemCopy((uint8_t *)RevNp, (uint8_t *)pNParams->Np, RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES);
+        /* Verify the RSA signature */
+        error = _RSA_PSS_Verify(hwBaseAddress, HashResult, RevN, RevNp, pSignature->sig);
+#else
+        /* Reverse the N and Np to be little endian arrays for the PKA usage */
+        /* NOTICE: Must be after certificate hash is calculated and
+           certificate public key Hash is verified */
+        UTIL_ReverseMemCopy((uint8_t *)pNParams->N, (uint8_t *)pNParams->N, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+        UTIL_ReverseMemCopy((uint8_t *)pNParams->Np, (uint8_t *)pNParams->Np, RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES);
+        /* Verify the RSA signature */
+        error = RSA_PSS_Verify(hwBaseAddress, HashResult, pNParams->N, pNParams->Np, pSignature->sig);
+#endif
+
+        /* on failure exit with an error code */
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("RSA sig verification failed 0x%x\n", error);
+                return CC_BOOT_IMG_VERIFIER_RSA_SIG_VERIFICATION_FAILED;
+        }
+
+        return CC_OK;
+} /* End of CCSbVerifySignature */
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_base_func.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_base_func.h
new file mode 100644
index 0000000..398697e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_base_func.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SECURE_BOOT_BASE_FUNC_H
+#define _SECURE_BOOT_BASE_FUNC_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "secureboot_parser_gen_defs.h"
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+
+/**
+ * @brief This function calculates the HASH over the PubKey (N, big endian) || Np (reversed - little endian).
+ *
+ * @param[in] hwBaseAddr -  CryptoCell base address
+ * @param[in] NAndRevNp_ptr - pointer to N public key and Np in the certificate
+ * @param[out] hashResult - a pointer to HASH of the public key
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from BootImagesVerifier_error.h
+ */
+CCError_t CCSbCalcPublicKeyHASH(unsigned long hwBaseAddress,
+                uint32_t *NAndRevNp_ptr,
+                uint32_t *hashResult);
+
+/**
+ * @brief This function calculates the HASH over the PubKey (N, big endian) || Np (reversed - little endian).
+ *        The function gets the Public key pointer and Np (Barrett n value) from the certificate calculates hash on it and
+ *    compare it to the HASH from the OTP/NVM.
+ *
+ * @param[in] hwBaseAddr -  CryptoCell base address
+ * @param[in] NAndRevNp_ptr - pointer to N public key and Np in the certificate
+ * @param[in] NHASH_ptr - a pointer to HASH of the public key
+ * @param[in] HashSize - hash size (to compare)
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from BootImagesVerifier_error.h
+ */
+CCError_t CCSbCalcPublicKeyHASHAndCompare(unsigned long hwBaseAddress,
+                         uint32_t *NAndRevNp_ptr,
+                         uint32_t *NHASH_ptr,
+                         uint32_t HashSize);
+
+/**
+ * @brief This function calculates the HASH over the given data and than verify
+ *    RSA signature on that hashed data
+ *
+ * @param[in] hwBaseAddr -  CryptoCell base address
+ * @param[in] pData - pointer to the data to be verified
+ * @param[in] pNParams - a pointer to the public key parameters
+ * @param[in] pSignature - a pointer to the signature structure
+ * @param[in] sizeOfData - size of the data to calculate the HASH on (in bytes)
+ * @param[in] sigAlg - signature algorithm to use
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from BootImagesVerifier_error.h
+CCError_t CCSbVerifySignature(unsigned long hwBaseAddress,
+                uint32_t *pData,
+                CCSbNParams_t *pNParams,
+                CCSbSignature_t *pSignature,
+                uint32_t sizeOfData,
+                CCSbSignAlg_t sigAlg);
+
+
+ */
+CCError_t CCSbVerifySignature(unsigned long hwBaseAddress,
+                uint32_t *pData,
+                CCSbNParams_t *pNParams,
+                CCSbSignature_t *pSignature,
+                uint32_t sizeOfData,
+                CCSbSignAlg_t sigAlg);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_basetypes.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_basetypes.h
new file mode 100644
index 0000000..024f23b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_basetypes.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_sb_basetypes
+ @{
+ */
+
+ /*!
+ @file
+ @brief This file contains basic type definitions for the Secure Boot.
+ */
+
+#ifndef _SECUREBOOT_BASE_TYPES_H
+#define _SECUREBOOT_BASE_TYPES_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "cc_pal_types_plat.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_error.h
new file mode 100644
index 0000000..d517920
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_error.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _SECUREBOOT_ERROR_H
+#define _SECUREBOOT_ERROR_H
+
+/*! @file
+@brief This file defines the error code types returned from the secure boot code.
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+/*! Defines the error number space used for the Secure Boot different modules. */
+#define CC_SECUREBOOT_BASE_ERROR                 0xF0000000
+
+/*! Defines the secure boot's base layer's error number. */
+#define CC_SECUREBOOT_LAYER_BASE_ERROR           0x01000000
+
+/*! Defines the Secure boot's verifier layer's error prefix number. */
+#define CC_SB_VERIFIER_LAYER_PREFIX         1
+/*! Defines the Secure boot's driver layer's error prefix number. */
+#define CC_SB_DRV_LAYER_PREFIX          2
+/*! Defines the Secure boot's revocation layer's error prefix number. */
+#define CC_SB_SW_REVOCATION_LAYER_PREFIX    3
+/*! Defines the Secure boot's HAL layer's error prefix number. */
+#define CC_SB_HAL_LAYER_PREFIX                  6
+/*! Defines the Secure boot's RSA layer's error prefix number. */
+#define CC_SB_RSA_LAYER_PREFIX              7
+/*! Defines the Secure boot's certificate verifier layer's error prefix number. */
+#define CC_SB_VERIFIER_CERT_LAYER_PREFIX    8
+/*! Defines the Secure boot's X509 certificate layer's error prefix number. */
+#define CC_SB_X509_CERT_LAYER_PREFIX        9
+
+
+/*! Defines the boot images verifier base error = 0xF1000000. */
+#define CC_BOOT_IMG_VERIFIER_BASE_ERROR          (CC_SECUREBOOT_BASE_ERROR + CC_SB_VERIFIER_LAYER_PREFIX*CC_SECUREBOOT_LAYER_BASE_ERROR)
+/*! Defines the NVM base error = 0xF4000000. */
+#define CC_SB_HAL_BASE_ERROR                     (CC_SECUREBOOT_BASE_ERROR + CC_SB_HAL_LAYER_PREFIX*CC_SECUREBOOT_LAYER_BASE_ERROR)
+/*! Defines the RSA's base error = 0xF7000000. */
+#define CC_SB_RSA_BASE_ERROR                     (CC_SECUREBOOT_BASE_ERROR + CC_SB_RSA_LAYER_PREFIX*CC_SECUREBOOT_LAYER_BASE_ERROR)
+
+/*! Defines the boot images verifier certificates base error = 0xF8000000. */
+#define CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR     (CC_SECUREBOOT_BASE_ERROR + CC_SB_VERIFIER_CERT_LAYER_PREFIX*CC_SECUREBOOT_LAYER_BASE_ERROR)
+
+/*! Defines the X.509's base error = 0xF9000000. */
+#define CC_SB_X509_CERT_BASE_ERROR               (CC_SECUREBOOT_BASE_ERROR + CC_SB_X509_CERT_LAYER_PREFIX*CC_SECUREBOOT_LAYER_BASE_ERROR)
+
+/*! Defines the cryptographic driver base error = 0xF2000000. */
+#define CC_SB_DRV_BASE_ERROR             (CC_SECUREBOOT_BASE_ERROR + CC_SB_DRV_LAYER_PREFIX*CC_SECUREBOOT_LAYER_BASE_ERROR)
+
+/*! Defines a HAL fatal error. */
+#define CC_SB_HAL_FATAL_ERROR_ERR            (CC_SB_HAL_BASE_ERROR + 0x00000001)
+/*! Illegal input error. */
+#define CC_SB_DRV_ILLEGAL_INPUT_ERR      (CC_SB_DRV_BASE_ERROR + 0x00000001)
+/*! Illegal key error. */
+#define CC_SB_DRV_ILLEGAL_KEY_ERR        (CC_SB_DRV_BASE_ERROR + 0x00000002)
+/*! Illegal size error. */
+#define CC_SB_DRV_ILLEGAL_SIZE_ERR       (CC_SB_DRV_BASE_ERROR + 0x00000003)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_gen_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_gen_defs.h
new file mode 100644
index 0000000..df637f8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_gen_defs.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_sb_gen_defs
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all of the definitions and structures used for the
+ Secure Boot and Secure Debug.
+ */
+
+#ifndef _SECURE_BOOT_GEN_DEFS_H
+#define _SECURE_BOOT_GEN_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "secureboot_basetypes.h"
+#include "cc_sec_defs.h"
+#include "cc_pal_sb_plat.h"
+
+/* General definitions */
+/***********************/
+
+/*! The maximal size of the additional-data of the Secure Boot in bytes. */
+#define CC_SB_MAX_SIZE_ADDITIONAL_DATA_BYTES    128
+
+/*! Definition of public key hash array. */
+typedef uint32_t CCSbCertPubKeyHash_t[HASH_RESULT_SIZE_IN_WORDS];
+/*! Definition of <em>SoC_ID</em> array. */
+typedef uint32_t CCSbCertSocId_t[HASH_RESULT_SIZE_IN_WORDS];
+
+
+/********* Function pointer definitions ***********/
+
+/*! @brief Typedef of the pointer to the Flash read function that you
+must implement.
+
+The Flash read function is called to read the certificates and SW modules from
+flash memory.
+
+  @note It is your responsibility to verify that this function does not copy
+  data from restricted memory regions.
+ */
+typedef uint32_t (*CCSbFlashReadFunc) (
+                     /*! [in] The address for reading from flash memory. */
+                     CCAddr_t flashAddress,
+                     /*! [out] A pointer to the RAM destination address to
+                     write the data to. */
+                     uint8_t *memDst,
+                     /*! [in] The size to read in bytes. */
+                     uint32_t sizeToRead,
+                     /*! [in] For partner use. */
+                     void* context
+                     );
+
+
+/*! @brief Typedef of the pointer to the Flash write function that you must
+implement.
+
+  The Flash write function is called to write authenticated and decrypted SW
+  modules to flash memory. */
+typedef uint32_t (*CCBsvFlashWriteFunc) (
+                    /*! [in] The address for writing to flash memory. */
+                    CCAddr_t flashAddress,
+                    /*! [out] A pointer to the RAM source to read the
+                    data from. */
+                    uint8_t *memSrc,
+                    /*! [in] The size to write in bytes. */
+                    uint32_t sizeToWrite,
+                    /*! [in] For partner use. */
+                    void* context
+                    );
+
+/********* End of Function pointer definitions ***********/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_general_hwdefs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_general_hwdefs.h
new file mode 100644
index 0000000..d672c57
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_general_hwdefs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SECUREBOOT_GENERAL_HWDEFS_H
+#define SECUREBOOT_GENERAL_HWDEFS_H
+
+
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "dx_crys_kernel.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+#define SB_REG_ADDR(base, reg_name)     (base + CC_REG_OFFSET(CRY_KERNEL, reg_name))
+#define SB_REG_ADDR_UNIT(base, reg_name, unit)  (base + CC_REG_OFFSET(unit, reg_name))
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_parser_gen_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_parser_gen_defs.h
new file mode 100644
index 0000000..30b11b4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_parser_gen_defs.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SECUREBOOT_PARSER_GEN_DEFS_H_
+#define _SECUREBOOT_PARSER_GEN_DEFS_H_
+
+
+#include "cc_pal_sb_plat.h"
+#include "cc_pka_hw_plat_defs.h"
+#include "rsa_bsv.h"
+#include "secureboot_defs.h"
+
+
+/*! Public key data structure. */
+typedef struct {
+    uint32_t N[SB_CERT_RSA_KEY_SIZE_IN_WORDS];              /*!< N public key, big endian representation. */
+    uint32_t Np[RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];    /*!< Np (Barrett n' value). */
+}CCSbNParams_t;
+
+
+/*! SW image data structure. */
+typedef struct {
+    uint32_t SwHashResult[HASH_RESULT_SIZE_IN_WORDS];       /*!< Hash calculated on the record.*/
+    CCAddr_t    memLoadAddr;                    /*!< Memory load address. */
+}CCSbHashRecordInfo_t;
+
+
+/*! Signature structure. */
+typedef struct {
+    uint32_t sig[SB_CERT_RSA_KEY_SIZE_IN_WORDS];                /*!< RSA PSS signature. */
+}CCSbSignature_t;
+
+/*! SW component additional parameters. */
+typedef struct {
+    CCAddr_t  StoreAddr;                        /*!< Storage address. */
+    uint32_t    Len;                        /*!< Size of the SW component in words. */
+}CCSbSwImgAddData_t;
+
+
+/********* Supported algorithms definitions ***********/
+
+/*! hash supported algorithms. */
+typedef enum {
+    HASH_SHA256_Alg_Output      = 0x01,     /*!< hash SHA 256 output. */
+    HASH_SHA256_Alg_128_Output  = 0x02,     /*!< hash SHA 256 output truncated to 128 bits. */
+    HASH_Last                   = 0x7FFFFFFF
+
+}CCSbHashAlg_t;
+
+
+/*! RSA supported algorithms */
+typedef enum {
+    RSA_ALG_MIN,
+    RSA_PSS_2048           = 0x01,          /*!< RSA PSS 2048 after hash SHA 256 */
+    RSA_PSS_3072           = 0x02,          /*!< RSA PSS 3072 after hash SHA 256 */
+    RSA_ALG_MAX,
+    RSA_Last               = 0x7FFFFFFF
+}CCSbSignAlg_t;
+
+#endif /* _GEN_SECUREBOOT_PARSER_GEN_DEFS_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_debug/cc3x/secdebug_api.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_debug/cc3x/secdebug_api.h
new file mode 100644
index 0000000..192f3b1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_debug/cc3x/secdebug_api.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _SECDEBUG_API_H
+#define _SECDEBUG_API_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains the secure debug API definition.
+*/
+
+#include "cc_pal_types_plat.h"
+
+/*! SOC-id size. */
+#define CC_BSV_SEC_DEBUG_SOC_ID_SIZE            0x20
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+@brief This API enables/disables debug (through the DCU registers), according to the
+permissions given in the debug certificate, or predefined values.
+For more information, see ARM TrustZone CryptoCell-312 Software Integrator's Manual.
+
+
+@return CC_OK on success.
+@return A non-zero value from bsv_error.h on failure.
+*/
+CCError_t CC_BsvSecureDebugSet(
+    unsigned long   hwBaseAddress,  /*!< [in] CryptoCell HW registers' base address. */
+    uint32_t   *pDebugCertPkg,  /*!< [in] Pointer to the Secure Debug certificate package. NULL is a valid value. */
+    uint32_t   certPkgSize,     /*!< [in] Byte size of the certificate package. */
+    uint32_t   *pEnableRmaMode, /*!< [out] RMA entry flag. Non-zero indicates RMA LCS entry is required. */
+    uint32_t   *pWorkspace,     /*!< [in] Pointer buffer used internally */
+    uint32_t   workspaceSize    /*!< [in] Size of the buffer used internally, minimal size is CC_SB_MIN_DBG_WORKSPACE_SIZE_IN_BYTES. */
+    );
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_debug/cc3x/secdebug_defs.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_debug/cc3x/secdebug_defs.h
new file mode 100644
index 0000000..e1b74c7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/secure_debug/cc3x/secdebug_defs.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _SECDEBUG_DEFS_H
+#define _SECDEBUG_DEFS_H
+
+//#include "cc_pal_types_plat.h"
+#include "cc_pal_sb_plat.h"
+#include "secureboot_basetypes.h"
+#include "secdebug_api.h"
+#include "bootimagesverifier_def.h"
+#include "dx_nvm.h"
+#include "dx_crys_kernel.h"
+#include "rsa_bsv.h"
+#include "cc_crypto_defs.h"
+#include "secureboot_gen_defs.h"
+#include  "secureboot_parser_gen_defs.h"
+
+#define CC_BSV_SEC_DEBUG_HASH_SIZE_IN_WORDS (HASH_SHA256_DIGEST_SIZE_IN_BYTES/CC_32BIT_WORD_SIZE)
+
+#define CC_BSV_SEC_DEBUG_DCU_SIZE_IN_BITS   128
+#define CC_BSV_SEC_DEBUG_DCU_SIZE_IN_BYTES   (CC_BSV_SEC_DEBUG_DCU_SIZE_IN_BITS/CC_BITS_IN_BYTE)
+#define CC_BSV_SEC_DEBUG_DCU_SIZE_IN_WORDS   (CC_BSV_SEC_DEBUG_DCU_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD)
+
+/*! Defines SOC ID */
+typedef uint8_t        SocId_t[CC_BSV_SEC_DEBUG_SOC_ID_SIZE];
+/*! Defines DCU */
+typedef uint32_t       Dcu_t[CC_BSV_SEC_DEBUG_DCU_SIZE_IN_WORDS];
+
+typedef struct {  // must be word aligned!!!
+        CCSbNParams_t   pubKey;
+        CCSbSignature_t     signature;
+} workspaceInt_t;
+
+
+/*! Secure Boot key certificate magic number. "S,B,K,C" */
+#define CC_SB_KEY_CERT_MAGIC_NUMBER     0x53426b63
+/*! Secure Boot content certificate magic number.  "S,B,C,C" */
+#define CC_SB_CONTENT_CERT_MAGIC_NUMBER     0x53426363
+/*! Certificate debug enabler magic number. */
+#define CC_CERT_SEC_DEBUG_ENABLER_MAGIC     0x5364656E
+/*! Certificate debug developer magic number. */
+#define CC_CERT_SEC_DEBUG_DEVELOPER_MAGIC   0x53646465
+
+
+
+/* The  restiction mask is actualy teh ICV ownership mask; meaning all ICV bits are set to 1 , OEM bit are 0 */
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK0_REG_OFFSET                 DX_AO_ICV_DCU_RESTRICTION_MASK0_REG_OFFSET
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK0_VALUE_BIT_SHIFT           DX_AO_ICV_DCU_RESTRICTION_MASK0_VALUE_BIT_SHIFT
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK0_VALUE_BIT_SIZE               DX_AO_ICV_DCU_RESTRICTION_MASK0_VALUE_BIT_SIZE
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK1_REG_OFFSET                 DX_AO_ICV_DCU_RESTRICTION_MASK1_REG_OFFSET
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK1_VALUE_BIT_SHIFT           DX_AO_ICV_DCU_RESTRICTION_MASK1_VALUE_BIT_SHIFT
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK1_VALUE_BIT_SIZE             DX_AO_ICV_DCU_RESTRICTION_MASK1_VALUE_BIT_SIZE
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK2_REG_OFFSET                 DX_AO_ICV_DCU_RESTRICTION_MASK2_REG_OFFSET
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK2_VALUE_BIT_SHIFT           DX_AO_ICV_DCU_RESTRICTION_MASK2_VALUE_BIT_SHIFT
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK2_VALUE_BIT_SIZE               DX_AO_ICV_DCU_RESTRICTION_MASK2_VALUE_BIT_SIZE
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK3_REG_OFFSET                 DX_AO_ICV_DCU_RESTRICTION_MASK3_REG_OFFSET
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK3_VALUE_BIT_SHIFT           DX_AO_ICV_DCU_RESTRICTION_MASK3_VALUE_BIT_SHIFT
+#define DX_AO_ICV_DCU_OWNERSHIP_MASK3_VALUE_BIT_SIZE               DX_AO_ICV_DCU_RESTRICTION_MASK3_VALUE_BIT_SIZE
+
+/********* Certificate structure definitions ***********/
+
+
+/*! Certificate header structure. */
+typedef struct {
+        uint32_t magicNumber;           /*!< Magic number to validate the certificate. */
+        uint32_t certVersion;           /*!< Certificate version to validate the certificate. */
+        uint32_t certSize;              /*!< Offset in words to the Certificate signature.
+                                            And number of SW components , if any exist.*/
+        uint32_t certFlags;             /*!< Bit field according to certificate type */
+}CCSbCertHeader_t;
+
+
+// All certificate header flags, first 4 bits are for certificate type,
+// next 4 bits are rsa algorithm used.
+// for  key certficate and enabler ecrtificate next 4 bits are HBK-id used
+
+/* Key certificate definitions */
+typedef union {
+        struct {
+                uint32_t      hbkId:4;  // must be first
+                uint32_t      reserved:28;
+        }flagsBits;
+        uint32_t      flagsWord;
+} keyCertFlags_t;
+
+typedef struct {
+        uint32_t    swVer;
+        CCHashResult_t      nextPubKeyHash;
+} KeyCertMain_t;
+
+
+typedef struct {
+        CCSbCertHeader_t    certHeader;
+        CCSbNParams_t           certPubKey;
+        KeyCertMain_t       certBody;
+        CCSbSignature_t         certSign;
+} KeyCert_t;
+
+/* Content certificate definitions */
+/*! Content Certificate flag bit field structure. */
+typedef union {
+        /*! Flags definitions in bits.*/
+        struct {
+                uint32_t      hbkId:4;
+                uint32_t      swCodeEncType:4;
+                uint32_t      swLoadVerifyScheme:4;
+                uint32_t      swCryptoType:4;
+                uint32_t      numOfSwCmp:16;
+        }flagsBits;
+        /*! Flags definition as a word.*/
+        uint32_t      flagsWord;
+} CCSbCertFlags_t;
+
+
+typedef struct {
+        CCHashResult_t      imageHash;
+        CCAddr_t    loadAddr;
+        uint32_t    imageMaxSize;
+        uint32_t    isAesCodeEncUsed;
+} ContentCertImageRecord_t;
+
+typedef struct {
+        uint32_t    swVer;
+        CCSbNonce_t     nonce;
+        ContentCertImageRecord_t    imageRec[CC_SB_MAX_NUM_OF_IMAGES];
+} ContentCertMain_t;
+
+
+
+typedef struct {
+        CCSbCertHeader_t    certHeader;
+        CCSbNParams_t           certPubKey;
+        ContentCertMain_t   certBody;
+        CCSbSignature_t         certSign;
+} ContentCert_t;
+
+
+/* Enabler certificate definitions */
+typedef union {
+        struct {
+                uint32_t      hbkId:4; // must be first
+                uint32_t      lcs:4;
+                uint32_t      isRma:4;
+                uint32_t      reserved:20;
+        }flagsBits;
+        uint32_t      flagsWord;
+} EnablerCertFlags_t;
+
+/* definition for enabler certificate */
+typedef struct {
+        Dcu_t       debugMask;
+        Dcu_t       debugLock;
+        CCHashResult_t      nextPubKeyHash;
+} EnablerCertMain_t;
+
+typedef struct {
+        CCSbCertHeader_t    certHeader;
+        CCSbNParams_t       certPubKey;
+        EnablerCertMain_t   certBody;
+        CCSbSignature_t         certSign;
+} EnablerCert_t;
+
+/* Developer certificate definitions */
+typedef struct {
+        struct {
+                uint32_t      reserved:32;
+        }flagsBits;
+        uint32_t      flagsWord;
+} DeveloperCertFlags_t;
+
+typedef struct {
+        Dcu_t       debugMask;
+        SocId_t         socId;
+} DeveloperCertMain_t;
+
+typedef struct {
+        CCSbCertHeader_t    certHeader;
+        CCSbNParams_t        certPubKey;
+        DeveloperCertMain_t certBody;
+        CCSbSignature_t         certSign;
+} DeveloperCert_t;
+
+
+
+/*! Certificate types structure. */
+typedef enum {
+        /*! Reserved.*/
+        CC_SB_MIN_CERT,
+        /*! Key certificate. */
+        CC_SB_KEY_CERT = 1,
+        /*! Content certificate. */
+        CC_SB_CONTENT_CERT = 2,
+        /*! Key or content certificate. */
+        CC_SB_KEY_OR_CONTENT_CERT = 3,
+        /*! Debug enabler certificate. */
+        CC_SB_ENABLER_CERT = 4,
+        /*! Debug developer certificate. */
+        CC_SB_DEVELOPER_CERT = 5,
+        /*! Max number of certificates types.*/
+        CC_SB_MAX_CERT,
+        /*! Reserved.*/
+        CC_SB_CERT_TYPE_LAST = 0x7FFFFFFF
+
+}CCSbCertTypes_t;
+
+
+/*! Certificate types structure. */
+typedef enum {
+        /*! First certificate in chain.*/
+        CC_SB_FIRST_CERT_IN_CHAIN = 0,
+        /*! Second certificate in chain.*/
+        CC_SB_SECOND_CERT_IN_CHAIN = 1,
+        /*! Third and last certificate in chain.*/
+        CC_SB_THIRD_CERT_IN_CHAIN = 2,
+        /*! Last certificate in chain.*/
+        CC_SB_LAST_CERT_IN_CHAIN = 3,
+        /*! Reserved.*/
+        CC_SB_RESERVED_CERT_IN_CHAIN = 0x7FFFFFFF
+
+}CCSbCertOrderInChain_t;
+
+
+
+/*!  MAX size of certificate pkg. */
+#ifdef CC_SB_X509_CERT_SUPPORTED
+#define CC_SB_MAX_KEY_CERT_SIZE_IN_BYTES    (0x500UL)
+#define CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES    (0x7A0UL) /* may contain up to 16 signed sw images */
+#define CC_SB_MAX_ENABLER_CERT_SIZE_IN_BYTES    (0x500UL)
+#define CC_SB_MAX_DEVELOPER_CERT_SIZE_IN_BYTES  (0x500UL)
+#define CC_SB_MAX_CERT_SIGN_SIZE_IN_BYTES               (0x1D0)
+#else
+#define CC_SB_MAX_KEY_CERT_SIZE_IN_BYTES    (sizeof(KeyCert_t))
+#define CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES    (sizeof(ContentCert_t)) /* may contain up to 16 signed sw images */
+#define CC_SB_MAX_ENABLER_CERT_SIZE_IN_BYTES    (sizeof(EnablerCert_t))
+#define CC_SB_MAX_DEVELOPER_CERT_SIZE_IN_BYTES  (sizeof(DeveloperCert_t))
+#define CC_SB_MAX_CERT_SIGN_SIZE_IN_BYTES               (sizeof(CCSbSignature_t))
+#endif
+
+#define CC_SB_MAX_KEY_CERT_BODY_SIZE_IN_BYTES   (sizeof(KeyCertMain_t))
+#define CC_SB_MAX_CONTENT_CERT_BODY_SIZE_IN_BYTES   (sizeof(ContentCertMain_t)) /* may contain up to 16 signed sw images */
+#define CC_SB_MAX_ENABLER_CERT_BODY_SIZE_IN_BYTES   (sizeof(EnablerCertMain_t))
+#define CC_SB_MAX_DEVELOPER_CERT_BODY_SIZE_IN_BYTES (sizeof(DeveloperCertMain_t))
+
+#define CC_SB_MAX_CONTENT_PKG_SIZE_IN_BYTES     (CC_SB_MAX_CONTENT_CERT_SIZE_IN_BYTES + SW_REC_NONE_SIGNED_DATA_SIZE_IN_BYTES*CC_SB_MAX_NUM_OF_IMAGES)
+
+#define CC_SB_MAX_CERT_PKG_SIZE_IN_BYTES    (CC_SB_MAX_KEY_CERT_SIZE_IN_BYTES+CC_SB_MAX_ENABLER_CERT_SIZE_IN_BYTES+CC_SB_MAX_DEVELOPER_CERT_SIZE_IN_BYTES)
+
+
+/* check KDR error bit in LCS register */
+#define DCU_RESET_OVERRIDE_BIT_SHIFT    0x0
+#define DCU_RESET_OVERRIDE_BIT_SIZE 0x1
+#define IS_DCU_RESET_OVERRIDE(dcuVal)   ((dcuVal>>DCU_RESET_OVERRIDE_BIT_SHIFT) & DCU_RESET_OVERRIDE_BIT_SIZE)
+
+#define CLEAR_ALL_DCU(dcuVal) {\
+    dcuVal[0] = DCU_DISABLE_ALL_DBG; \
+    dcuVal[1] = DCU_DISABLE_ALL_DBG; \
+    dcuVal[2] = DCU_DISABLE_ALL_DBG; \
+    dcuVal[3] = DCU_DISABLE_ALL_DBG; \
+}
+
+#define LOCK_ALL_DCU(dcuLock) {\
+    dcuLock[0] = DCU_ENABLE_ALL_DBG; \
+    dcuLock[1] = DCU_ENABLE_ALL_DBG; \
+    dcuLock[2] = DCU_ENABLE_ALL_DBG; \
+    dcuLock[3] = DCU_ENABLE_ALL_DBG; \
+}
+
+
+#define WRITE_DCU_LOCK(hwBaseAddress, dcuLock, rc) {\
+    uint32_t ii = 0;\
+    volatile uint32_t rr = 0;\
+    for (ii = 0; ii < CC_BSV_SEC_DEBUG_DCU_SIZE_IN_WORDS; ii++) {\
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HOST_DCU_LOCK0) + ii * sizeof(uint32_t), dcuLock[ii]); \
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress,HOST_DCU_LOCK0) + ii * sizeof(uint32_t), rr);       \
+        if(rr!=dcuLock[ii]) { \
+            rc = CC_BSV_AO_WRITE_FAILED_ERR; \
+        } \
+    }\
+}
+
+#define WRITE_DCU_VAL(hwBaseAddress, dcuVal) {\
+    uint32_t ii = 0;\
+    for (ii = 0; ii < CC_BSV_SEC_DEBUG_DCU_SIZE_IN_WORDS; ii++) {\
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HOST_DCU_EN0) + ii * sizeof(uint32_t), dcuVal[ii]); \
+        CC_BSV_WAIT_ON_NVM_IDLE_BIT(hwBaseAddress); \
+    }\
+}
+
+/* Read-Modify-Write a field of a register */
+#define READ_MODIFY_WRITE_AO_REGISTER(hwBaseAddress, regName, fldName, fldVal, tc) \
+do {                                            \
+    volatile uint32_t regVal = 0; \
+    volatile uint32_t rr = 0; \
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress,regName), regVal);       \
+    CC_REG_FLD_SET(DX, regName, fldName, regVal, fldVal); \
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, regName), regVal);       \
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress,regName), rr);       \
+    if(rr!=regVal) { \
+        rc = CC_BSV_AO_WRITE_FAILED_ERR; \
+    } \
+} while (0)
+
+
+#define READ_DCU_LOCK_DEFAULT(hwBaseAddress, dcuLock, rc) \
+do {\
+    uint32_t ii; \
+    for (ii = 0; ii<CC_OTP_DCU_SIZE_IN_WORDS; ii++) { \
+        rc = CC_BsvOTPWordRead(hwBaseAddress, (CC_OTP_DCU_OFFSET+ii), &dcuLock[ii]); \
+        if (rc != CC_OK) { \
+            break;\
+        } \
+    }  \
+} while(0)
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util.h
new file mode 100644
index 0000000..5d1d326
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef UTIL_H
+#define UTIL_H
+
+/*
+ * All the includes that are needed for code using this module to
+ * compile correctly should be #included here.
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* invers the bytes on a word- used for output from HASH */
+#ifdef BIG__ENDIAN
+#define UTIL_INVERSE_UINT32_BYTES( val )    (val)
+#else
+#define UTIL_INVERSE_UINT32_BYTES( val ) \
+   ( ((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24) )
+#endif
+
+/* invers the bytes on a word - used for input data for HASH */
+#ifdef BIG__ENDIAN
+#define UTIL_REVERT_UINT32_BYTES( val ) \
+   ( ((val) >> 24) | (((val) & 0x00FF0000) >> 8) | (((val) & 0x0000FF00) << 8) | (((val) & 0x000000FF) << 24) )
+#else
+#define UTIL_REVERT_UINT32_BYTES( val ) (val)
+#endif
+
+/* the minimum and maximum macros */
+#undef min
+#define min( a , b ) ( ( (a) < (b) ) ? (a) : (b) )
+
+#undef max
+#define max( a , b ) ( ( (a) > (b) ) ? (a) : (b) )
+
+/* MACRO to count one bits */
+#define COUNT_ONE_BITS(number, BitCount) \
+do \
+{ \
+      uint32_t tmp_num = number; \
+      BitCount = 0; \
+      while (tmp_num)   \
+      {         \
+        tmp_num = tmp_num & (tmp_num - 1); \
+        BitCount = BitCount + 1; \
+      }         \
+} while (0)
+
+#define CONVERT_BYTE_ARR_TO_WORD(inPtr, outWord, numOfBytes) \
+do{\
+    uint8_t index;\
+    outWord = 0;\
+    for (index = 0; index < numOfBytes; index ++){\
+        outWord |= (*(inPtr + index)<<8*index);\
+    }\
+} while(0)
+
+
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  *****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+/* ------------------------------------------------------------
+ **
+ * @brief This function executes a reversed words copy on a specified buffer.
+ *
+ *        on a 6 words byffer:
+ *
+ *        buff[5] <---> buff[0]
+ *        buff[4] <---> buff[1]
+ *        buff[3] <---> buff[2]
+ *
+ * @param[in] dst_ptr - The counter buffer.
+ * @param[in] size    - The counter size in words.
+ *
+ */
+ void UTIL_ReverseWordsBuff( uint32_t *pBuff , uint32_t sizeWords );
+
+
+/* ------------------------------------------------------------
+ **
+ * @brief This function executes a reversed byte copy on a specified buffer.
+ *
+ *        on a 6 byte byffer:
+ *
+ *        buff[5] <---> buff[0]
+ *        buff[4] <---> buff[1]
+ *        buff[3] <---> buff[2]
+ *
+ * @param[in] pBuff - The buffer.
+ * @param[in] size - The size in bytes.
+ *
+ */
+ void UTIL_ReverseBuff( uint8_t *pBuff , uint32_t size );
+
+/* ------------------------------------------------------------
+ **
+ * @brief This function executes a memory copy between 2 buffers.
+ *
+ * @param[in] pDst - The first counter buffer.
+ * @param[in] pSrc - The second counter buffer.
+ * @param[in] size - The counter size in bytes.
+ *
+ */
+ void UTIL_MemCopy( uint8_t *pDst, const uint8_t *pSrc, uint32_t size );
+
+/* ------------------------------------------------------------
+ **
+ * @brief This function executes a memory set operation on a buffer.
+ *
+ * @param[in] pBuff - the buffer.
+ * @param[in] val   - The value to set the buffer.
+ * @param[in] size  - the buffers size.
+ *
+ */
+ void UTIL_MemSet( uint8_t *pBuff, uint8_t val, uint32_t size );
+
+/* ------------------------------------------------------------
+ **
+ * @brief This function executes secure memory comparing of two buffers.
+ *
+ * @param[in] pBuff1 - The first counter buffer.
+ * @param[in] pBuff2 - The second counter buffer.
+ * @param[in] size   - the counters size in bytes.
+ *
+ */
+ uint32_t UTIL_MemCmp( uint8_t *pBuff1, uint8_t *pBuff2, uint32_t size );
+
+/* ------------------------------------------------------------
+ **
+ * @brief This function executes a reverse bytes copying from one buffer to another buffer.
+ *
+ * @param[in] pDst  - The pointer to destination buffer.
+ * @param[in] pSrc  - The pointer to source buffer.
+ * @param[in] size  - The size in bytes.
+ *
+ */
+ void UTIL_ReverseMemCopy( uint8_t *pDst, uint8_t *pSrc, uint32_t size );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_asn1_parser.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_asn1_parser.c
new file mode 100644
index 0000000..c5cdc4e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_asn1_parser.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+#include "secureboot_basetypes.h"
+#include "util.h"
+#include "secureboot_error.h"
+#include "sb_x509_error.h"
+#include "util_asn1_parser.h"
+#include "cc_pal_log.h"
+#include "bootimagesverifier_def.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+
+/************************ Typedefs ******************************/
+
+
+/************************ Global Data ******************************/
+
+
+/************* Private function prototype ****************/
+
+
+/************************ Private Functions ******************************/
+/* The function reads the size of the following item */
+static CCError_t UTIL_Asn1ReadItemLength(uint8_t *pInStr, uint32_t *itemLen, uint8_t *index)
+{
+    uint8_t currVal = 0;
+    uint32_t i = 0;
+
+    currVal = *pInStr;
+
+    /* Parsing Item's length according to X.690 Section 8.1.3 */
+    if (currVal < 0x80){
+        *itemLen = currVal;
+        *index = *index + 1;
+    }
+    else {
+        currVal &= 0x7F;
+        if ((currVal == 0) || (currVal > sizeof(uint32_t))){
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+        else {
+            pInStr++;
+            /* read the size according to number of bytes */
+            *itemLen = 0;
+            for (i=0 ; i<currVal ; i++){
+                *itemLen = (*itemLen << 8) + (*pInStr++);
+            }
+            /* update the size of bytes */
+            *index = *index + currVal + 1;
+        }
+    }
+    if (*itemLen > CC_SB_MAX_CERT_SIZE_IN_BYTES) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    return CC_OK;
+}
+
+/* The function reads the ASN1 tag + size and returns it */
+CCError_t UTIL_Asn1ReadItemVerifyTag(uint8_t *pInStr, CCSbCertAsn1Data_t *pAsn1Data, uint8_t tag)
+{
+    CCError_t  error = CC_OK;
+
+    /* Read item id + size */
+    pAsn1Data->tagId = *pInStr++;
+    if (pAsn1Data->tagId != tag) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    pAsn1Data->index = 1;
+    error = UTIL_Asn1ReadItemLength(pInStr, &(pAsn1Data->itemSize), &(pAsn1Data->index));
+
+    return error;
+}
+
+/* The function reads the ASN1 tag + size and returns it */
+CCError_t UTIL_Asn1ReadItemVerifyTagFW(uint8_t **ppInStr, CCSbCertAsn1Data_t *pAsn1Data, uint8_t tag, unsigned long startAddress, unsigned long endAddress)
+{
+    CCError_t  error = CC_OK;
+    uint8_t *tempCertPtr = *ppInStr;
+
+    /* Read item id + size */
+    pAsn1Data->tagId = *tempCertPtr++;
+
+    if (pAsn1Data->tagId != tag) {
+        CC_PAL_LOG_WARN("Invalid tag 0x%x, expected 0x%x\n", pAsn1Data->tagId, tag);
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    pAsn1Data->index = 1;
+    error = UTIL_Asn1ReadItemLength(tempCertPtr, &(pAsn1Data->itemSize), &(pAsn1Data->index));
+    if (error != CC_OK) {
+        CC_PAL_LOG_WARN("Failed UTIL_Asn1ReadItemLength 0x%x\n", error);
+        return error;
+    }
+
+    *ppInStr = *ppInStr + pAsn1Data->index;
+    /* verify that index does not increment the cert pointer to invalid address (beyond the certificate boundaries) */
+    UTILS_ASN1_CERT_VERIFY_PTR_RET((unsigned long)*ppInStr, startAddress, endAddress);
+
+    return error;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_asn1_parser.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_asn1_parser.h
new file mode 100644
index 0000000..0390941
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_asn1_parser.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef UTIL_ASN1_PARSER_H
+#define UTIL_ASN1_PARSER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* ASN1 data structure */
+typedef struct
+{
+    uint8_t  tagId;
+    uint32_t itemSize;
+    uint8_t  index;
+
+}CCSbCertAsn1Data_t;
+
+#define UTILS_ASN1_CERT_VERIFY_PTR_RET(address, startAddress, endAddress){ \
+    /* If current address is bigger than endAddress, or if there was a wrapAround and the address is smaller than the address we started with */ \
+    if ((address > endAddress) || (address < startAddress)){ \
+        CC_PAL_LOG_ERR("Certificate pointer is beyond the allowed limit: addr 0x%lx, start 0x%lx, end 0x%lx\n", address, startAddress, endAddress);\
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;\
+    }\
+}\
+
+
+#define UTIL_ASN1_GET_NEXT_ITEM_RET(pAsn1buff, size, startAddress, endAddress){ \
+    (pAsn1buff += size); \
+    UTILS_ASN1_CERT_VERIFY_PTR_RET((unsigned long)pAsn1buff, startAddress, endAddress); \
+}\
+
+/**
+ * @brief This function reads ASN1 string and verify its tag
+ *
+ *
+ * @param[in] pInStr - the ASN1 string to read from
+ * @param[in] pAsn1Data - output the asn1 fields
+ * @param[in] tag - tag to comapre to
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_Asn1ReadItemVerifyTag(uint8_t *pInStr, CCSbCertAsn1Data_t *pAsn1Data, uint8_t tag);
+
+/**
+ * @brief This function reads ASN1 string, verify its tag and fw the str pointer
+ *
+ *
+ * @param[in] ppInStr - the ASN1 string to read from
+ * @param[in] pAsn1Data - output the asn1 fields
+ * @param[in] tag - tag to comapre to
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_Asn1ReadItemVerifyTagFW(uint8_t **ppInStr, CCSbCertAsn1Data_t *pAsn1Data, uint8_t tag,
+                       unsigned long startAddress, unsigned long endAddress);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_base64.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_base64.h
new file mode 100644
index 0000000..0be3439
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_base64.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef UTIL_BASE64_H
+#define UTIL_BASE64_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @brief This function converts pem base64 encoded string to char string
+ *
+ *
+ * @param[in] pInStr - PEM base64 string
+ * @param[in] inSize - size of given string
+ * @param[out] pOutStr - output string decoded
+ * @param[in/out] outSize - the output buffer size (in MAX size out actual size)
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_ConvertPemStrToCharStr(uint8_t *pInStr, uint32_t inSize,
+                      uint8_t *pOutStr, uint32_t *outSize);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_x509_parser.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_x509_parser.c
new file mode 100644
index 0000000..b32fc1a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_x509_parser.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+#include "secureboot_basetypes.h"
+#include "secureboot_stage_defs.h"
+#include "util_asn1_parser.h"
+#include "util_x509_parser.h"
+#include "secureboot_error.h"
+#include "sb_x509_error.h"
+#include "rsa_bsv.h"
+#include "cc_pal_log.h"
+#include "cc_pka_hw_plat_defs.h"
+
+
+/************************ Defines ******************************/
+
+
+/************************ Enums ******************************/
+
+
+/************************ Typedefs ******************************/
+
+
+/************************ Global Data ******************************/
+const uint8_t *certType2SubjectNames[CC_X509_CERT_TYPE_MAX] = {
+  /*CC_X509_CERT_TYPE_MIN      */   (uint8_t *)NULL,
+  /*CC_X509_CERT_TYPE_KEY      */   (uint8_t *)CC_X509_CERT_KEY_CERT,
+  /*CC_X509_CERT_TYPE_CONTENT  */   (uint8_t *)CC_X509_CERT_CNT_CERT,
+  /*CC_X509_CERT_TYPE_ENABLER_DBG */    (uint8_t *)CC_X509_CERT_ENABLER_CERT,
+  /*CC_X509_CERT_TYPE_DEVELOPER_DBG */  (uint8_t *)CC_X509_CERT_DEVELOPER_CERT
+};
+
+/************* Private function prototype ****************/
+
+
+/************************ Private Functions ******************************/
+/* the following function verify the ASN1 tags sequences in case of strings (Issuer name and subject name) */
+CCError_t UTIL_X509VerifyStr(uint8_t **pCert, uint32_t *dataSize, unsigned long startAddress, unsigned long endAddress)
+{
+    CCError_t error = CC_OK;
+    CCSbCertAsn1Data_t asn1Data;
+
+    /* read SEQ */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* read SET */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SET_OF_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* read SEQ */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* OBJ ID */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress)
+
+    /* PRINT STR ID */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_PRNT_STR_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_UTF8_TAG_ID, startAddress, endAddress);
+        if (error != CC_OK) {
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+    }
+    *dataSize = asn1Data.itemSize;
+
+    return error;
+}
+
+CCError_t UTIL_X509VerifyIssuerName(uint8_t *pCert, uint32_t size)
+{
+    CCError_t error = CC_OK;
+
+    error = UTIL_MemCmp(pCert, (uint8_t*)CC_X509_CERT_ISSUER_NAME, size);
+    if (error != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    return CC_OK;
+}
+
+
+/* the following function verify the subject name */
+CCError_t UTIL_X509VerifySubjectName(uint8_t *pCert, CCX509CertType_t certType, uint32_t subNameSize)
+{
+    CCError_t error = CC_OK;
+    /* validate inputs */
+    if ((NULL == pCert) ||
+        ((certType >= CC_X509_CERT_TYPE_MAX) || (certType <= CC_X509_CERT_TYPE_MIN))) {
+        CC_PAL_LOG_ERR("Invalid inputs\n");
+        return CC_SB_X509_CERT_INV_PARAM;
+    }
+
+    error = UTIL_MemCmp(pCert,(uint8_t*)certType2SubjectNames[certType],subNameSize);
+    if(error != CC_TRUE)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+
+    return CC_OK;
+}
+
+
+/* the following function verify the ASN1 tags sequences in case of strings (Issuer name and subject name) */
+CCError_t UTIL_X509VerifyPubKey(uint8_t **pCert, CCSbNParams_t *pParamsN, unsigned long startAddress, unsigned long endAddress)
+{
+    CCError_t error = CC_OK;
+    CCSbCertAsn1Data_t asn1Data;
+    uint8_t objId[] = CC_X509_CERT_RSASSAENC_ID;
+    uint8_t eVal[] = X509_RSA_E_VAL_IN_BYTES;
+
+    /* read SEQ */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    /* read SEQ */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    /* OBJ ID */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if ((error != CC_OK) || (asn1Data.itemSize != sizeof(objId))) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify ID */
+    if ((error = UTIL_MemCmp(*pCert, objId, asn1Data.itemSize)) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* read NULL */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_NULL_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+    /* BIT Str */
+    error = UTIL_Asn1ReadItemVerifyTag(*pCert, &asn1Data, CC_X509_CERT_BIT_STR_TAG_ID);
+    if (error != CC_OK)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.index+1, startAddress, endAddress);//add 1 for unused bits
+    /* SEQ */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    /* read INT and copy the N into buffer */
+    error = UTIL_Asn1ReadItemVerifyTag(*pCert, &asn1Data, CC_X509_CERT_INT_TAG_ID);
+    if (error != CC_OK)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    if (asn1Data.itemSize != SB_CERT_RSA_KEY_SIZE_IN_BYTES){
+        if (asn1Data.itemSize != (SB_CERT_RSA_KEY_SIZE_IN_BYTES + 1)){
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+        asn1Data.index ++;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.index, startAddress, endAddress);
+    UTIL_MemCopy((uint8_t*)pParamsN->N, *pCert, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize-1, startAddress, endAddress);
+
+    /* Verify E is the expected constant */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_INT_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK)
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+
+    if (asn1Data.itemSize != sizeof(eVal)) /* verify the size of E is correct */
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+
+    if ((error = UTIL_MemCmp(*pCert, eVal, asn1Data.itemSize)) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+
+    return CC_OK;
+}
+
+/* the following function retrieves the signature */
+CCError_t UTIL_X509GetSignature(uint8_t **pCert, CCSbSignature_t *signatureP, unsigned long startAddress, unsigned long endAddress)
+{
+    CCError_t error = CC_OK;
+    CCSbCertAsn1Data_t asn1Data;
+    uint8_t objId[] = CC_X509_CERT_SHA256RSAPSS_ID;
+    uint8_t objSha256Id[] = CC_X509_CERT_SHA256_ID;
+    uint8_t objMgf1Id[] = CC_X509_CERT_MGF1_ID;
+
+    /* read SEQ */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* OBJ ID */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (asn1Data.itemSize != sizeof(objId)) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify ID */
+    if ((error = UTIL_MemCmp(*pCert, objId, asn1Data.itemSize)) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* verify sha256 + PSS + mgf1 attributes signature */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify sha256 */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (asn1Data.itemSize != sizeof(objSha256Id)) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if ((error = UTIL_MemCmp(*pCert, objSha256Id, asn1Data.itemSize)) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+    /* verify mgf1 + sha256 */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG1_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify mgf1 */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (asn1Data.itemSize != sizeof(objMgf1Id)) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if ((error = UTIL_MemCmp(*pCert, objMgf1Id, asn1Data.itemSize)) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify sha256 */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (asn1Data.itemSize != sizeof(objSha256Id)) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if ((error = UTIL_MemCmp(*pCert, objSha256Id, asn1Data.itemSize)) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* verify last special tag size */
+    error = UTIL_Asn1ReadItemVerifyTagFW(pCert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG2_ID, startAddress, endAddress);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (asn1Data.itemSize != CC_X509_CERT_CTX_SPEC_TAG2_SIZE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize, startAddress, endAddress);
+    /* BIT Str */
+    error = UTIL_Asn1ReadItemVerifyTag(*pCert, &asn1Data, CC_X509_CERT_BIT_STR_TAG_ID);
+    if (error != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (asn1Data.itemSize != (SB_CERT_RSA_KEY_SIZE_IN_BYTES + 1)){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.index + 1, startAddress, endAddress);//add 1 for unused bits
+    // copy the signature as reversed buffer
+    UTIL_ReverseMemCopy((uint8_t*)signatureP->sig, *pCert, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*pCert, asn1Data.itemSize-1, startAddress, endAddress);//add 1 for unused bits
+
+    return error;
+}
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_x509_parser.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_x509_parser.h
new file mode 100644
index 0000000..ae2826d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/util/util_x509_parser.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _UTIL_X509_PARSER_H_
+#define _UTIL_X509_PARSER_H_
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_crypto_x509_defs.h"
+#include "secureboot_defs.h"
+#include  "secureboot_parser_gen_defs.h"
+
+
+#define X509_RSA_E_VAL_IN_BYTES     {0x01,0x00,0x01}
+
+/* TBS structure */
+#define CC_X509_CERT_SEQ_TAG_ID         0x30
+#define CC_X509_CERT_INT_TAG_ID         0x02
+#define CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID      0x06
+#define CC_X509_CERT_SET_OF_TAG_ID          0x31
+#define CC_X509_CERT_PRNT_STR_TAG_ID            0x13
+#define CC_X509_CERT_UTF8_TAG_ID            0x0C
+#define CC_X509_CERT_BIT_STR_TAG_ID         0x03
+#define CC_X509_CERT_BOOL_TAG_ID            0x01
+#define CC_X509_CERT_CTX_SPEC_TAG_ID            0xA0
+#define CC_X509_CERT_CTX_SPEC_TAG1_ID           0xA1
+#define CC_X509_CERT_CTX_SPEC_TAG2_ID           0xA2
+#define CC_X509_CERT_NULL_TAG_ID            0x05
+#define CC_X509_CERT_CTX_EXT_TAG_ID         0xA3
+#define CC_X509_CERT_OCT_STR_TAG_ID         0x04
+
+#define CC_X509_CERT_UTC_TIME_TAG_ID            0x17
+#define CC_X509_CERT_GENERALIZED_TIME_TAG_ID    0x18
+
+/* x509 definitions */
+#define CC_X509_CERT_VERSION        0x02
+#define CC_X509_CERT_RSASSAENC_ID   {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01}  // 1.2.840.113549.1.1.1
+#define CC_X509_CERT_SHA256RSAENC_ID    {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B}  // 1.2.840.113549.1.1.11
+#define CC_X509_CERT_SHA256RSAPSS_ID    {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A}  // 1.2.840.113549.1.1.10
+#define CC_X509_CERT_SHA256_ID      {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}  // 2.16.840.1.101.3.4.2.1
+#define CC_X509_CERT_MGF1_ID        {0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x08}  // 1.2.840.113549.1.1.8
+
+#define CC_X509_CERT_CNT_NUM_OF_OBJ_IN_EXT  5
+#define CC_X509_CERT_KEY_NUM_OF_OBJ_IN_EXT  4
+
+#define CC_X509_CERT_CTX_SPEC_TAG2_SIZE     0x3
+
+/**
+ * @brief This function verifies certificate's issuer name according to predefined name
+ *
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_X509VerifyIssuerName(uint8_t *pCert, uint32_t size);
+
+/**
+ * @brief This function follows x509 string structure, should be called before
+ *    reading the issuer name or the subject name
+ *
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_X509VerifyStr(uint8_t **pCert, uint32_t *dataSize, unsigned long startAddress, unsigned long endAddress);
+
+/**
+ * @brief This function verify the subject name according to fixed data
+ *
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_X509VerifySubjectName(uint8_t *pCert, CCX509CertType_t certType, uint32_t subNameSize);
+
+/**
+ * @brief This function gets the public key from the certificate and copy it to the external buffer
+ *
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_X509VerifyPubKey(uint8_t **pCert, CCSbNParams_t *pParamsN, unsigned long startAddress, unsigned long endAddress);
+
+/**
+ * @brief This function gets the signature from the certificate and copy it to the external buffer
+ *
+ *
+ * @return CCError_t - On success the value CC_OK is returned,
+ *         on failure - a value from bootimagesverifierx509_error.h
+ */
+CCError_t UTIL_X509GetSignature(uint8_t **pCert, CCSbSignature_t *signatureP, unsigned long startAddress, unsigned long endAddress);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_ext_parser.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_ext_parser.c
new file mode 100644
index 0000000..e376b82
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_ext_parser.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+#include "secureboot_basetypes.h"
+#include "secureboot_stage_defs.h"
+#include "secureboot_defs.h"
+#include "cc_crypto_x509_defs.h"
+#include "secureboot_base_func.h"
+#include "bsv_error.h"
+#include "sb_x509_cert_parser.h"
+#include "cc3x_sb_x509_ext_parser.h"
+#include "sb_x509_error.h"
+#include "bootimagesverifierx509_error.h"
+#include "util_asn1_parser.h"
+#include "util_base64.h"
+#include "util_x509_parser.h"
+#include "cc_pal_log.h"
+//#include "bootimagesverifierx509_def.h"
+#include "bootimagesverifier_def.h"
+#include "cc_crypto_x509_defs.h"
+
+/*!
+ * @brief Parse certificate extension segment
+ *
+ * @param[in/out] ppCert    - pointer to X509 certificate as ASN.1 byte array
+ * @param[in] certType      - certificate type
+ * @param[in] cntNumOfImg   - number of images for content certificate (should be 0 for all else)
+ * @param[out] pOutStr      - extension data structure according to certificate type
+ * @param[in] pOutStrSize   - extension data structure max size
+ * @param[in] maxCertSize   - max certficate size
+ * @param[in] startAddress      - start address of certificate
+ * @param[in] endAddress    - end address of certificate (the certificate pointer cannot exceed this address)
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from bsv_error.h
+ */
+CCError_t SB_X509_ParseCertExtensions(uint8_t       **ppCert,
+                        uint32_t    certSize,
+                    CCSbCertHeader_t **ppCertPropHeader,
+                        uint8_t     **ppNp,
+                    uint8_t     **ppCertBody,
+                    uint32_t    *pCertBodySize,
+                    unsigned long   startAddress,
+                    unsigned long   endAddress)
+{
+    CCError_t rc = CC_OK;
+    CCSbCertAsn1Data_t asn1Data;
+    uint32_t nextBuffOffset = 0;
+    uint32_t extNum = 0;
+    uint8_t extVal = 0;
+    uint8_t **ppExtBuff;
+    uint32_t extBuffSize = 0;
+
+
+    /* validate inputs */
+    if ((ppCert == NULL) ||
+        (certSize == 0) ||
+        (ppCertPropHeader == NULL) ||
+        (ppNp == NULL) ||
+        (ppCertBody == NULL) ||
+        (pCertBodySize == NULL)){
+         CC_PAL_LOG_ERR("Invalid inputs\n");
+        return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* parse certificate extension header */
+    /* the first tag is always the extension tag */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppCert, &asn1Data, CC_X509_CERT_CTX_EXT_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+         CC_PAL_LOG_ERR("1. Failed to read CC_X509_CERT_CTX_EXT_TAG_ID \n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* read SEQ */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+         CC_PAL_LOG_ERR("2. Failed to read CC_X509_CERT_SEQ_TAG_ID \n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    for (extNum=0; extNum < CC3X_X509_CERT_EXT_NUMBER && nextBuffOffset < certSize; extNum++){
+        /* read SEQ */
+        rc = UTIL_Asn1ReadItemVerifyTagFW(ppCert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+        if (rc != CC_OK) {
+             CC_PAL_LOG_ERR("3. Failed to read CC_X509_CERT_SEQ_TAG_ID\n");
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+        nextBuffOffset += asn1Data.itemSize;
+        /* read OBJ ID */
+        rc = UTIL_Asn1ReadItemVerifyTagFW(ppCert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+        if (rc != CC_OK) {
+             CC_PAL_LOG_ERR("3. Failed to read CC_X509_CERT_SEQ_TAG_ID\n");
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+        /* the last byte of the identifier , identifies the extension field */
+        if (asn1Data.itemSize == 0){
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+        extVal = *((*ppCert) + asn1Data.itemSize -1);
+        UTIL_ASN1_GET_NEXT_ITEM_RET(*ppCert, asn1Data.itemSize, startAddress, endAddress);
+
+        rc = UTIL_Asn1ReadItemVerifyTagFW(ppCert, &asn1Data, CC_X509_CERT_BOOL_TAG_ID, startAddress, endAddress);
+        if (rc != CC_OK) {
+             CC_PAL_LOG_ERR("5. Failed to read CC_X509_CERT_BOOL_TAG_ID\n");
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+        UTIL_ASN1_GET_NEXT_ITEM_RET(*ppCert, asn1Data.itemSize, startAddress, endAddress);
+
+        switch(extNum) {
+        case 0:
+            if (extVal != CC_X509_ID_EXT_PROPRIETARY_HEADER) {
+                 CC_PAL_LOG_ERR("Illegal extension %d, expected Header\n", extVal);
+                return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+            }
+
+            ppExtBuff = (uint8_t **)ppCertPropHeader;
+            extBuffSize = sizeof(CCSbCertHeader_t);
+            break;
+        case 1:
+            if (extVal != CC_X509_ID_EXT_PUB_KEY_NP) {
+                 CC_PAL_LOG_ERR("Illegal extension %d, expected Np\n", extVal);
+                return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+            }
+            ppExtBuff = (uint8_t **)ppNp;
+            extBuffSize = RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES;
+            break;
+        case 2:
+            if ((extVal != CC_X509_ID_EXT_KEY_CERT_MAIN_VAL) &&
+                (extVal != CC_X509_ID_EXT_CONTENT_CERT_MAIN_VAL) &&
+                (extVal != CC_X509_ID_EXT_ENABLER_CERT_MAIN_VAL) &&
+                (extVal != CC_X509_ID_EXT_DEVELOPER_CERT_MAIN_VAL)) {
+                 CC_PAL_LOG_ERR("Illegal extension %d, expected key, content, enabler, developer\n", extVal);
+                return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+            }
+            ppExtBuff = (uint8_t **)ppCertBody;
+            extBuffSize = *pCertBodySize;
+            break;
+        default:
+            CC_PAL_LOG_ERR("Invalid loop %d\n", extNum);
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+
+        rc = UTIL_Asn1ReadItemVerifyTagFW(ppCert, &asn1Data, CC_X509_CERT_OCT_STR_TAG_ID, startAddress, endAddress);
+        if (rc != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to verify CC_X509_CERT_OCT_STR_TAG_ID, rc 0x%X\n", rc);
+            return rc;
+        }
+        /* in case we have leading 0 before buffer */
+        if ((asn1Data.itemSize > extBuffSize) && (**ppCert == 0)) {
+            UTIL_ASN1_GET_NEXT_ITEM_RET(*ppCert, 1, startAddress, endAddress);
+            asn1Data.itemSize--;
+        } else if (asn1Data.itemSize > extBuffSize) {
+             CC_PAL_LOG_ERR("Invalid inputs > extBuffSize 0x%x\n", extBuffSize);
+            return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+        }
+
+        *ppExtBuff = (uint8_t*)*ppCert;
+        if (extNum == 2) {
+            *pCertBodySize = asn1Data.itemSize;
+        }
+
+        UTIL_ASN1_GET_NEXT_ITEM_RET(*ppCert, asn1Data.itemSize, startAddress, endAddress);
+    }
+
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_ext_parser.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_ext_parser.h
new file mode 100644
index 0000000..faa66e9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_ext_parser.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SB_CC3X_X509_EXT_PARSER_H
+#define _SB_CC3X_X509_EXT_PARSER_H
+
+#include "stdint.h"
+#include "secureboot_basetypes.h"
+#include "bootimagesverifier_def.h"
+#include "secdebug_defs.h"
+
+/*!
+ * @brief Parse certificate extension segment
+ *
+ * @param[in/out] ppCert    - pointer to X509 certificate as ASN.1 byte array
+ * @param[in] certType      - certificate type
+ * @param[in] cntNumOfImg   - number of images for content certificate (should be 0 for all else)
+ * @param[out] pOutStr      - extension data structure according to certificate type
+ * @param[in] pOutStrSize   - extension data structure max size
+ * @param[in] maxCertSize   - max certificate size
+ * @param[in] startAddress      - start address of certificate
+ * @param[in] endAddress    - end address of certificate (the certificate pointer cannot exceed this address)
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from bsv_error.h
+ */
+CCError_t SB_X509_ParseCertExtensions(uint8_t       **ppCert,
+                                      uint32_t      certSize,
+                                      CCSbCertHeader_t **ppCertPropHeader,
+                                      uint8_t       **ppNp,
+                                      uint8_t       **ppCertBody,
+                                      uint32_t  *pCertBodySize,
+                                      unsigned long   startAddress,
+                                      unsigned long   endAddress);
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_parser.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_parser.c
new file mode 100644
index 0000000..0632713
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/cc3x_sb_x509_parser.c
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "secureboot_basetypes.h"
+#include "util_asn1_parser.h"
+#include "util_x509_parser.h"
+#include "sb_x509_error.h"
+#include "sb_x509_cert_parser.h"
+#include "cc3x_sb_x509_ext_parser.h"
+#include "bootimagesverifier_error.h"
+#include "cc_pal_x509_defs.h"
+#include "bsv_error.h"
+#include "cc_bitops.h"
+#include "cc_pal_log.h"
+#include "secdebug_defs.h"
+#include "cc_pka_hw_plat_defs.h"
+#include "common_cert_parser.h"
+#include "secureboot_stage_defs.h"
+
+
+#define SIZE_OF_CERT_ASN1_HEADER 4 // 0x30,0x82, MSB size, LSB size - not like CCSbCertAsn1Data_t, since we have 2 bytes of certificate size
+
+/**
+   @brief This function verifies the secure debug package size and returns the
+   pointer to each of the certificates within the package.
+  from the ASN.1 first package we read the first certificate size.
+  We jump to the following certificate and read its size from the ASN.1 header.
+  If the sum of both certificates smaller than the certificate package size,
+  we assume we have key certificate as well. And set the certificate pointers
+  according to the ASN.1 header sizes of each certificate.
+  In any case we need to compare each certificate size and the certificate package
+  total size with the maximum possible value of the certificate sizes.
+ */
+CCError_t CCCertSecDbgParse(uint32_t   *pDebugCertPkg,
+                            uint32_t   certPkgSize,
+                            BufferInfo32_t  *pKeyCert,         // out
+                            BufferInfo32_t  *pEnablerCert,   // out
+                            BufferInfo32_t  *pDeveloperCert) // out
+{
+
+        uint32_t rc = 0;
+        CCSbCertAsn1Data_t asn1DataCert1;
+        CCSbCertAsn1Data_t asn1DataCert2;
+        uint32_t    cert2WordOffset;
+        CCSbCertAsn1Data_t asn1DataCert3;
+        uint32_t    cert3WordOffset;
+        uint32_t  numOfCert = 0;
+        uint32_t  *pCertPkg = pDebugCertPkg;
+        uint32_t  *pCertFirst;
+        uint32_t  *pCertSecond;
+        uint32_t  *pCertThird;
+        unsigned long endAddr = (unsigned long)pDebugCertPkg + certPkgSize;
+
+        /* certificate offsets within package must be word aligned */
+        // Get the first certificate size
+        pCertFirst = pCertPkg;
+        rc = UTIL_Asn1ReadItemVerifyTagFW((uint8_t **)&pCertPkg, &asn1DataCert1, CC_X509_CERT_SEQ_TAG_ID, (unsigned long)pCertPkg, endAddr);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for cert1\n", rc);
+                goto end_with_error;
+        }
+
+        /* Make sure no wrap around */
+        if ((asn1DataCert1.itemSize + SIZE_OF_CERT_ASN1_HEADER) < asn1DataCert1.itemSize) {
+                CC_PAL_LOG_ERR("illegal value %d\n", asn1DataCert1.itemSize);
+                goto end_with_error;
+        }
+
+        /* Some sanity checks for certificate size*/
+        if (((asn1DataCert1.itemSize + SIZE_OF_CERT_ASN1_HEADER) > certPkgSize) || ((asn1DataCert1.itemSize + SIZE_OF_CERT_ASN1_HEADER) > CC_SB_MAX_ENABLER_CERT_SIZE_IN_BYTES)) {
+                CC_PAL_LOG_ERR("asn1Data.itemSize(0x%x) > certPkgSize(0x%x)\n", asn1DataCert1.itemSize, certPkgSize);
+                goto end_with_error;
+        }
+        numOfCert++;
+
+        /* Get the second certificate size */
+        cert2WordOffset = CALC_32BIT_WORDS_FROM_BYTES(asn1DataCert1.itemSize);
+        if ((cert2WordOffset * CC_32BIT_WORD_SIZE + SIZE_OF_CERT_ASN1_HEADER) > certPkgSize) {
+                CC_PAL_LOG_ERR("cert2WordOffset(0x%x) > certPkgSize(0x%x)\n", cert2WordOffset * CC_32BIT_WORD_SIZE, certPkgSize);
+                goto end_with_error;
+        }
+        pCertPkg += cert2WordOffset;
+        pCertSecond = pCertPkg;
+        rc = UTIL_Asn1ReadItemVerifyTagFW((uint8_t **)&pCertPkg, &asn1DataCert2, CC_X509_CERT_SEQ_TAG_ID, (unsigned long)pCertPkg, endAddr);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for cert2\n", rc);
+                goto end_with_error;
+        }
+
+        /* Verify no wrap around. */
+        if ((asn1DataCert2.itemSize + SIZE_OF_CERT_ASN1_HEADER) < asn1DataCert2.itemSize) {
+                CC_PAL_LOG_ERR("illegal value %d\n", asn1DataCert1.itemSize);
+                goto end_with_error;
+        }
+        if ((asn1DataCert2.itemSize + SIZE_OF_CERT_ASN1_HEADER) > (certPkgSize - (cert2WordOffset * CC_32BIT_WORD_SIZE)) ||
+            ((asn1DataCert2.itemSize + SIZE_OF_CERT_ASN1_HEADER) > CC_SB_MAX_ENABLER_CERT_SIZE_IN_BYTES)) { /* enabler certificate is the biggest certificate */
+                CC_PAL_LOG_ERR("asn1DataCert2.itemSize(0x%x) > (certPkgSize(0x%x)-cert2WordOffset(0x%x))\n",
+                               asn1DataCert2.itemSize, certPkgSize, cert2WordOffset);
+                goto end_with_error;
+        }
+        numOfCert++;
+
+        // Get the third certificate size - if the offset is outside of boundaries return (there are only 2 certificates).
+        cert3WordOffset = CALC_32BIT_WORDS_FROM_BYTES(asn1DataCert2.itemSize) + cert2WordOffset;
+        if (((cert3WordOffset * CC_32BIT_WORD_SIZE) + 2 * SIZE_OF_CERT_ASN1_HEADER) >= certPkgSize) {  // meaning only 2 certificates in chain
+                goto end;
+        }
+        pCertPkg += (cert3WordOffset - cert2WordOffset);
+        pCertThird = pCertPkg;
+        rc = UTIL_Asn1ReadItemVerifyTagFW((uint8_t **)&pCertPkg, &asn1DataCert3, CC_X509_CERT_SEQ_TAG_ID, (unsigned long)pCertPkg, endAddr);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for cert3\n", rc);
+                goto end_with_error;
+        }
+
+        if ((asn1DataCert3.itemSize + SIZE_OF_CERT_ASN1_HEADER) < asn1DataCert3.itemSize) {
+                CC_PAL_LOG_ERR("illegal value %d\n", asn1DataCert3.itemSize);
+                goto end_with_error;
+        }
+        if ((asn1DataCert3.itemSize + SIZE_OF_CERT_ASN1_HEADER) > (certPkgSize - (cert3WordOffset * CC_32BIT_WORD_SIZE)) ||
+            ((asn1DataCert3.itemSize + SIZE_OF_CERT_ASN1_HEADER) > CC_SB_MAX_ENABLER_CERT_SIZE_IN_BYTES)) {
+                CC_PAL_LOG_ERR("asn1DataCert3.itemSize(0x%x) > (certPkgSize(0x%x)-cert3WordOffset(0x%x))\n",
+                               asn1DataCert3.itemSize, certPkgSize, cert3WordOffset * CC_32BIT_WORD_SIZE);
+                goto end_with_error;
+        }
+        numOfCert++;
+
+end:
+        if (numOfCert == 2) {
+                pKeyCert->bufferSize = 0;
+                pKeyCert->pBuffer = NULL;
+                pEnablerCert->bufferSize = asn1DataCert1.itemSize;
+                pEnablerCert->pBuffer = pCertFirst;
+                pDeveloperCert->bufferSize = asn1DataCert2.itemSize;
+                pDeveloperCert->pBuffer = pCertSecond;
+        } else if (numOfCert == 3) {
+                pKeyCert->bufferSize = asn1DataCert1.itemSize;
+                pKeyCert->pBuffer = pCertFirst;
+                pEnablerCert->bufferSize = asn1DataCert2.itemSize;
+                pEnablerCert->pBuffer = pCertSecond;
+                pDeveloperCert->bufferSize = asn1DataCert3.itemSize;
+                pDeveloperCert->pBuffer = pCertThird;
+        }
+        return CC_OK;
+
+end_with_error:
+        pKeyCert->bufferSize = 0;
+        pKeyCert->pBuffer = NULL;
+        pEnablerCert->bufferSize = 0;
+        pEnablerCert->pBuffer = NULL;
+        pDeveloperCert->bufferSize = 0;
+        pDeveloperCert->pBuffer = NULL;
+
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+
+}
+
+
+/**
+   @brief This function load sizeof(CCSbCertAsn1Data_t ) from flash and get the
+   certificate size from it. Make sure size is within range
+   (smaller than workspace size not including the required space for N, Np and signature).
+   read the certificate according to size from header and copy the certificate content from Flash to RAM.
+ */
+uint32_t CCCertLoadCertificate(CCSbFlashReadFunc flashRead_func,
+                               void *userContext,
+                               CCAddr_t certAddress,
+                               uint32_t *pCert,
+                               uint32_t *pCertBufferWordSize)
+{
+        uint32_t rc = 0;
+        CCSbCertAsn1Data_t asn1DataCert1;
+        uint8_t *plCert = (uint8_t *)pCert;
+        uint32_t certSizeFullWords;
+
+        /* Verify that the certificate buffer size is big enough to contain the header */
+        if (*pCertBufferWordSize < (SIZE_OF_CERT_ASN1_HEADER / CC_32BIT_WORD_SIZE)) {
+                CC_PAL_LOG_ERR("certificate buff size too small to contain certificate header\n");
+                return CC_BOOT_IMG_VERIFIER_WORKSPACE_SIZE_TOO_SMALL;
+        }
+
+        /* Read the certificate header from the Flash */
+        rc = flashRead_func(certAddress,
+                            plCert,
+                            SIZE_OF_CERT_ASN1_HEADER,
+                            userContext);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("failed flashRead_func for certificate header\n");
+                return rc;
+        }
+
+        rc = UTIL_Asn1ReadItemVerifyTagFW((uint8_t **)&plCert,
+                                          &asn1DataCert1,
+                                          CC_X509_CERT_SEQ_TAG_ID,
+                                          (unsigned long)plCert,
+                                          (unsigned long)plCert + SIZE_OF_CERT_ASN1_HEADER);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for cert header\n", rc);
+                return rc;
+        }
+
+        certSizeFullWords = ALIGN_TO_4BYTES(asn1DataCert1.itemSize);
+
+        /* Verify no wrap around */
+        if ((*pCertBufferWordSize) * CC_32BIT_WORD_SIZE - SIZE_OF_CERT_ASN1_HEADER > (*pCertBufferWordSize) * CC_32BIT_WORD_SIZE) {
+                CC_PAL_LOG_ERR("Certificate size too big\n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+        /* Make sure certificate size is within range */
+        if (certSizeFullWords > ((*pCertBufferWordSize) * CC_32BIT_WORD_SIZE - SIZE_OF_CERT_ASN1_HEADER)) {
+                CC_PAL_LOG_ERR("Certificate size too big\n");
+                return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+        /* according to the header read the additional certificate buffer -
+          * not including the non-signed part in case of content certificate */
+        rc = flashRead_func(certAddress + SIZE_OF_CERT_ASN1_HEADER,
+                            (uint8_t *)plCert,
+                            asn1DataCert1.itemSize,
+                            userContext);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("failed flashRead_func for certificate\n");
+                return rc;
+        }
+
+        *pCertBufferWordSize = ((certSizeFullWords + SIZE_OF_CERT_ASN1_HEADER) / CC_32BIT_WORD_SIZE);
+
+        return CC_OK;
+
+}
+
+
+/**
+   @brief This function
+   call SB_X509_VerifyCertTbsHeader() to verify the X509 header and get the user Data and public key.
+   Copy the public key into workspace
+   Call SB_X509_ParseCertExtensions() to get pointers for:
+      Proprietary header pointer
+      Copy Np into workspace following N
+      Proprietary Certificate body pointer
+   Call UTIL_X509GetSignature(), and copy the signature into workspace, after Np.
+ */
+uint32_t CCCertFieldsParse(BufferInfo32_t  *pCertInfo,
+                           BufferInfo32_t  *pWorkspaceInfo,
+                           CertFieldsInfo_t  *pCertFields,
+                           uint32_t **ppCertStartSign,
+                           uint32_t *pCertSignedSize,
+                           BufferInfo32_t  *pX509HeaderInfo)
+{
+        uint32_t rc = 0;
+        uint32_t  certSignedSize = 0;
+        uint32_t    certStartOffest;
+        CCSbCertHeader_t *lpCertHeader;
+        uint8_t *lpNp;
+        CCSbSignature_t *lpSignature;
+        unsigned long startAddr = (unsigned long)pCertInfo->pBuffer;
+        unsigned long endAddr = (unsigned long)pCertInfo->pBuffer + pCertInfo->bufferSize + sizeof(CCSbCertAsn1Data_t);
+        CCX509CertHeaderInfo_t   *pX509UserData = NULL;
+        uint8_t     *pX509Cert = (uint8_t *)pCertInfo->pBuffer;
+        workspaceInt_t  *lpWorkspaceInt;
+
+        if ((pWorkspaceInfo == NULL) ||
+            (pWorkspaceInfo->pBuffer == NULL) ||
+            (pWorkspaceInfo->bufferSize < sizeof(workspaceInt_t))) {
+                CC_PAL_LOG_ERR("workspace and or sizes illegal\n");
+                return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+        }
+
+        if (startAddr > endAddr) {  /* Verify no overlap */
+                CC_PAL_LOG_ERR("buffer overlap detected \n");
+                return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+        }
+        lpWorkspaceInt = (workspaceInt_t  *)(pWorkspaceInfo->pBuffer);
+
+        if (pX509HeaderInfo != NULL) {
+                if (((pX509HeaderInfo->pBuffer == NULL) && (pX509HeaderInfo->bufferSize != 0)) ||
+                    ((pX509HeaderInfo->pBuffer != NULL) && (pX509HeaderInfo->bufferSize < sizeof(CCX509CertHeaderInfo_t)))) {
+                        CC_PAL_LOG_ERR("workspace and or sizes illegal\n");
+                        return CC_BSV_ILLEGAL_INPUT_PARAM_ERR;
+                }
+                pX509UserData = (CCX509CertHeaderInfo_t *)pX509HeaderInfo->pBuffer;
+        }
+
+        rc = SB_X509_VerifyCertTbsHeader(&pX509Cert,
+                                         pCertInfo->bufferSize,
+                                         &certSignedSize,
+                                         &certStartOffest,
+                                         (CCSbNParams_t *)&(lpWorkspaceInt->pubKey),
+                                         pX509UserData,
+                                         startAddr,
+                                         endAddr);
+
+        if ((rc != CC_OK) ||
+            (certSignedSize > pCertInfo->bufferSize - SB_CERT_RSA_KEY_SIZE_IN_BYTES)) {
+                CC_PAL_LOG_ERR("Failed SB_X509_VerifyCertTbsHeader 0x%x\n", rc);
+                goto error;
+        }
+
+        *ppCertStartSign = pCertInfo->pBuffer + 1;
+        *pCertSignedSize = certSignedSize;
+
+        /* Copy the proprietary header from the extension,
+           copy Np from the extension,
+           get the pointer to the certificate main */
+        rc = SB_X509_ParseCertExtensions(&pX509Cert,
+                                         certSignedSize,
+                                         &lpCertHeader,
+                                         &lpNp,
+                                         (uint8_t **)&pCertFields->pCertBody,
+                                         &pCertFields->certBodySize,
+                                         startAddr,
+                                         endAddr);
+        if ((rc != CC_OK) ||
+            (pCertFields->certBodySize > certSignedSize)) {
+                CC_PAL_LOG_ERR("Failed SB_X509_ParseCertExtensions 0x%x, or bodySize 0x%x too big 0x%x\n", rc, pCertFields->certBodySize, certSignedSize);
+                goto error;
+        }
+
+        UTIL_MemCopy((uint8_t *)&pCertFields->certHeader, (uint8_t *)lpCertHeader, sizeof(CCSbCertHeader_t));
+        UTIL_MemCopy((uint8_t *)&(lpWorkspaceInt->pubKey.Np), lpNp, RSA_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_BYTES);
+
+
+        lpSignature = (CCSbSignature_t *)&(lpWorkspaceInt->signature);
+        rc = UTIL_X509GetSignature(&pX509Cert, lpSignature, startAddr, endAddr);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed UTIL_X509GetSignature 0x%x\n", rc);
+                goto error;
+        }
+
+        return CC_OK;
+error:
+        UTIL_MemSet((uint8_t *)pCertFields, 0, sizeof(CertFieldsInfo_t));
+        *pCertSignedSize = 0;
+
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+}
+
+uint32_t CCCertGetUnsignedDataOffset(uint32_t *pCert,
+                     uint32_t *pUnsignedDataOffset)
+{
+        CCError_t rc = CC_OK;
+        uint8_t *plCert = (uint8_t *)pCert;
+        CCSbCertAsn1Data_t asn1DataCert1;
+        uint32_t certSizeFullWords;
+
+        if ((pCert == NULL)||(pUnsignedDataOffset == NULL)){
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+        rc = UTIL_Asn1ReadItemVerifyTagFW((uint8_t **)&plCert,
+                                          &asn1DataCert1,
+                                          CC_X509_CERT_SEQ_TAG_ID,
+                                          (unsigned long)plCert,
+                                          (unsigned long)plCert + SIZE_OF_CERT_ASN1_HEADER);
+        if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for cert header\n", rc);
+                return rc;
+        }
+
+        certSizeFullWords = ALIGN_TO_4BYTES(asn1DataCert1.itemSize);
+        *pUnsignedDataOffset = ((certSizeFullWords + SIZE_OF_CERT_ASN1_HEADER) / CC_32BIT_WORD_SIZE);
+
+        return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_cert_parser.c b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_cert_parser.c
new file mode 100644
index 0000000..39bf26a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_cert_parser.c
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+
+#include "secureboot_basetypes.h"
+#include "secureboot_stage_defs.h"
+#include "secureboot_defs.h"
+#include "cc_crypto_x509_defs.h"
+#include "secureboot_base_func.h"
+#include "sb_x509_error.h"
+#include "sb_x509_cert_parser.h"
+#include "util_asn1_parser.h"
+#include "util_base64.h"
+#include "util_x509_parser.h"
+#include "cc_pal_log.h"
+#include "cc_crypto_boot_defs.h"
+#ifdef CC_SB_SUPPORT_IOT
+#include "secureboot_stage_defs.h"
+#else
+#include "sbrom_bsv_api.h"
+#include "bootimagesverifierx509_def.h"
+#include "sbrom_bsv_error.h"
+#include "sb_x509_ext_parser.h"
+#endif
+
+/*!
+ * @brief Parse and validate TBS header certificate
+ *
+ * @param[in] ppAsn1Cert    - pointer to X509 certificate as ASN.1 byte array
+ * @param[in] certMaxSize   - certificate max size (according to certificate type)
+ * @param[out] pSignCertSize    - certificate TBS size, used for signature
+ * @param[out] pTbsStartOffset - certificate TBS start offset, used for signature
+ * @param[out] pOutPubKey       - certificate public key modulus (exponent is constant)
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from sbrom_bsv_error.h
+ */
+CCError_t SB_X509_VerifyCertTbsHeader(uint8_t    **ppAsn1Cert,
+                      uint32_t      certMaxSize,
+                      uint32_t      *pSignCertSize,
+                      uint32_t      *pTbsStartOffset,
+                      CCSbNParams_t     *pOutPubKey,
+                      CCX509CertHeaderInfo_t *pOutCertHeaderInfo,
+                      unsigned long startAddress,
+                      unsigned long endAddress)
+{
+    uint32_t    rc = 0;
+    uint32_t    strSize = 0;
+    CCSbCertAsn1Data_t asn1Data;
+    uint8_t     algId[] = CC_X509_CERT_SHA256RSAPSS_ID;
+    uint8_t objSha256Id[] = CC_X509_CERT_SHA256_ID;
+    uint8_t objMgf1Id[] = CC_X509_CERT_MGF1_ID;
+    uint32_t         notBeforeStrSize = 0;
+    uint32_t         notAfterStrSize  = 0;
+
+    /* validate inputs */
+    if ((NULL == ppAsn1Cert) ||
+        (NULL == pOutPubKey) ||
+        (NULL == pSignCertSize) ||
+        (NULL == pTbsStartOffset) ||
+        (certMaxSize == 0)) {
+        CC_PAL_LOG_ERR("Invalid inputs\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    /* set default output values */
+    *pSignCertSize = 0;
+    *pTbsStartOffset = 0;
+    UTIL_MemSet((uint8_t *)pOutPubKey, 0, sizeof(CCSbNParams_t));
+
+    /* 1. get certificate size , validate tag + size */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for CC_X509_CERT_SEQ_TAG_ID\n", rc);
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    if (asn1Data.itemSize > certMaxSize){
+        CC_PAL_LOG_ERR("asn1Data.itemSize > certTypeMaxSize[certType]\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    /* certificate signature is on all TBS */
+    *pTbsStartOffset = asn1Data.index;
+
+    /* 2. get TBS size - no need to verify size */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for CC_X509_CERT_SEQ_TAG_ID\n", rc);
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    /* certificate signature is on all TBS */
+    *pSignCertSize = asn1Data.itemSize + asn1Data.index;
+    if (*pSignCertSize > certMaxSize ){ /* the size of the certificate to be verified cannot be bigger than certMaxSize*/
+        CC_PAL_LOG_ERR("asn1Data.itemSize > certTypeMaxSize\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    /* 3. get version and verify it is v3 */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for CC_X509_CERT_CTX_SPEC_TAG_ID\n", rc);
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_INT_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to UTIL_Asn1ReadItemVerifyTagFW 0x%x for CC_X509_CERT_INT_TAG_ID\n", rc);
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    if (**ppAsn1Cert != CC_X509_CERT_VERSION ){
+        CC_PAL_LOG_ERR("Ilegal certificate version 0x%x\n", **ppAsn1Cert);
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+
+
+    /* 4. get the serial number */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_INT_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to CC_X509_CERT_INT_TAG_ID for serial number\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (pOutCertHeaderInfo != NULL){
+        UTIL_MemCopy((uint8_t*)&(pOutCertHeaderInfo->serialNum), (uint8_t*)*ppAsn1Cert, sizeof(uint32_t));
+#ifndef BIG__ENDIAN
+        UTIL_ReverseBuff((uint8_t*)&(pOutCertHeaderInfo->serialNum),sizeof(uint32_t));
+#endif
+        pOutCertHeaderInfo->setSerialNum = 1;
+    }
+
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* 5. get the alg id and verify it */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to CC_X509_CERT_SEQ_TAG_ID for algId\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK || asn1Data.itemSize != sizeof(algId)) {
+        CC_PAL_LOG_ERR("Failed to CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID for algId\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if ((rc = UTIL_MemCmp(*ppAsn1Cert, algId, sizeof(algId))) != CC_TRUE) {
+        CC_PAL_LOG_ERR("Failed to UTIL_MemCmp algId\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* verify sha256 + PSS + mgf1 attributes signature */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to CC_X509_CERT_SEQ_TAG_ID for PSS\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify sha256 */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if ((rc != CC_OK) || (asn1Data.itemSize != sizeof(objSha256Id))) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if ((rc = UTIL_MemCmp(*ppAsn1Cert, objSha256Id, sizeof(objSha256Id))) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+    /* verify mgf1 + sha256 */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG1_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify mgf1 */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if ((rc != CC_OK) || (asn1Data.itemSize != sizeof(objMgf1Id))) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if ((rc = UTIL_MemCmp(*ppAsn1Cert, objMgf1Id, sizeof(objMgf1Id))) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* verify sha256 */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_OBJ_IDENTIFIER_TAG_ID, startAddress, endAddress);
+    if ((rc != CC_OK) || (asn1Data.itemSize != sizeof(objSha256Id))) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if ((rc = UTIL_MemCmp(*ppAsn1Cert, objSha256Id, sizeof(objSha256Id))) != CC_TRUE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* verify last special tag size */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_CTX_SPEC_TAG2_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (asn1Data.itemSize != CC_X509_CERT_CTX_SPEC_TAG2_SIZE){
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* 6. get the issuer name and verify it */
+    rc = UTIL_X509VerifyStr(ppAsn1Cert, &strSize, startAddress, endAddress);
+    if (rc != CC_OK || strSize > X509_ISSUER_NAME_MAX_STRING_SIZE ) {
+        CC_PAL_LOG_ERR("Failed to UTIL_X509VerifyStr for issuer Name\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    if (pOutCertHeaderInfo != NULL){
+        if (strSize>0){
+            UTIL_MemCopy((uint8_t*)pOutCertHeaderInfo->IssuerName, (uint8_t*)*ppAsn1Cert, strSize);
+            pOutCertHeaderInfo->IssuerName[strSize]=0;
+            pOutCertHeaderInfo->setIssuerName = 1;
+        } else {
+            pOutCertHeaderInfo->setIssuerName = 0;
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+    }
+
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, strSize, startAddress, endAddress);
+
+    /* 7. skip over the validity period */
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_SEQ_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to CC_X509_CERT_SEQ_TAG_ID for vallidity period\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_UTC_TIME_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK || asn1Data.itemSize > X509_VALIDITY_PERIOD_MAX_STRING_SIZE) {
+        CC_PAL_LOG_ERR("Failed to CC_X509_CERT_UTC_TIME_TAG_ID for notBefore\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    if (pOutCertHeaderInfo != NULL) {
+        if ((asn1Data.itemSize>0) && (asn1Data.itemSize<sizeof(pOutCertHeaderInfo->NotBeforeStr))){
+            UTIL_MemCopy((uint8_t*)pOutCertHeaderInfo->NotBeforeStr, (uint8_t*)*ppAsn1Cert, asn1Data.itemSize);
+            pOutCertHeaderInfo->NotBeforeStr[asn1Data.itemSize] = 0;
+            notBeforeStrSize = asn1Data.itemSize;
+            pOutCertHeaderInfo->setNotBeforeStr = 1;
+        } else {
+            pOutCertHeaderInfo->setNotBeforeStr = 0;
+        }
+    }
+
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+
+    rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_UTC_TIME_TAG_ID, startAddress, endAddress);
+    if (rc != CC_OK) {
+        rc = UTIL_Asn1ReadItemVerifyTagFW(ppAsn1Cert, &asn1Data, CC_X509_CERT_GENERALIZED_TIME_TAG_ID, startAddress, endAddress);
+        if (rc != CC_OK || asn1Data.itemSize > X509_VALIDITY_PERIOD_MAX_STRING_SIZE) {
+            CC_PAL_LOG_ERR("Failed to CC_X509_CERT_GENERALIZED_TIME_TAG_ID for notAfter\n");
+            return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+        }
+    }
+    if (pOutCertHeaderInfo != NULL) {
+        if ((asn1Data.itemSize>0) && (asn1Data.itemSize<sizeof(pOutCertHeaderInfo->NotAfterStr))){
+            UTIL_MemCopy((uint8_t*)pOutCertHeaderInfo->NotAfterStr, (uint8_t*)*ppAsn1Cert, asn1Data.itemSize);
+            pOutCertHeaderInfo->NotAfterStr[asn1Data.itemSize] = 0;
+            notAfterStrSize = asn1Data.itemSize;
+            pOutCertHeaderInfo->setNotAfterStr = 1;
+        } else {
+            pOutCertHeaderInfo->setNotAfterStr = 0;
+        }
+
+        rc = CC_PalVerifyCertValidity(pOutCertHeaderInfo->NotBeforeStr,
+            notBeforeStrSize,
+            pOutCertHeaderInfo->setNotBeforeStr,
+            pOutCertHeaderInfo->NotAfterStr,
+            notAfterStrSize,
+            pOutCertHeaderInfo->setNotAfterStr);
+
+            if (rc != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to verify certificate validity\n");
+                return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+            }
+    }
+
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, asn1Data.itemSize, startAddress, endAddress);
+
+    /* 8. get the subject name and verify it */
+    rc = UTIL_X509VerifyStr(ppAsn1Cert, &strSize, startAddress, endAddress);
+    if (rc != CC_OK || strSize > X509_SUBJECT_NAME_MAX_STRING_SIZE) {
+        CC_PAL_LOG_ERR("Failed to UTIL_X509VerifyStr for subject Name\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+    if (pOutCertHeaderInfo != NULL){
+             UTIL_MemCopy((uint8_t*)pOutCertHeaderInfo->SubjectName, (uint8_t*)*ppAsn1Cert, strSize);
+             pOutCertHeaderInfo->SubjectName[strSize]=0;
+             pOutCertHeaderInfo->setSubjectName = 1;
+    }
+    UTIL_ASN1_GET_NEXT_ITEM_RET(*ppAsn1Cert, strSize, startAddress, endAddress);
+
+    /* 9. get the pub key */
+    rc = UTIL_X509VerifyPubKey(ppAsn1Cert, pOutPubKey, startAddress, endAddress);
+    if (rc != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to UTIL_X509VerifyPubKey\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+
+
+    return CC_OK;
+}
+
+
+/*!
+ * @brief Parse and validate certificate package header
+ *
+ * @param[in] pPkgHeader    - pointer to debug certificate package
+ * @param[in] pkgType       - certificate package type
+ * @param[out] pDbg2CertInfo    - secondary debug certificate offset and size
+ * @param[out] pHbkFormat   - HBK format for comparison with OTP
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from sbrom_bsv_error.h
+ */
+CCError_t SB_X509_ParseCertPkg(CCX509PkgHeader_t    *pPkgHeader,
+                  CCX509CertType_t      pkgType,
+                  CCX509CertInfo_t      *pDbg2CertInfo,
+                  CCSbPubKeyIndexType_t     *pHbkFormat)
+{
+    uint32_t            hbkFormat = 0;
+
+    /* verify Inputs */
+    if ((NULL == pPkgHeader) ||
+        (NULL == pDbg2CertInfo) ||
+        (NULL == pHbkFormat) ||
+        ((pkgType >= CC_X509_CERT_TYPE_MAX) || (pkgType <= CC_X509_CERT_TYPE_MIN))) {
+        CC_PAL_LOG_ERR("Invalid inputs\n");
+        return CC_SB_X509_CERT_PARSE_ILLEGAL_VAL;
+    }
+    /* set default outputs */
+    pDbg2CertInfo->certInfoWord = 0;
+    *pHbkFormat = CC_SB_HASH_BOOT_NOT_USED;
+
+    /* verify certificate package Token */
+    if (pPkgHeader->pkgToken != CC_X509_CERT_PKG_TOKEN) {
+        CC_PAL_LOG_ERR("Invalid Debug package Token 0x%X\n", pPkgHeader->pkgToken);
+        return CC_SB_X509_CERT_ILLEGAL_TOKEN;
+    }
+    /* verify certificate package Version */
+    if (pPkgHeader->pkgVer != CC_X509_CERT_PKG_VERSION) {
+        CC_PAL_LOG_ERR("Invalid Debug package Version 0x%X\n", pPkgHeader->pkgVer);
+        return CC_SB_X509_CERT_ILLEGAL_VERSION;
+    }
+    /* verify certificate package certificate type */
+    if (pPkgHeader->pkgFlags.pkgFlagsBits.certType != pkgType) {
+        CC_PAL_LOG_ERR("Invalid Debug package type 0x%X\n", pPkgHeader->pkgFlags.pkgFlagsBits.certType);
+        return CC_SB_X509_CERT_ILLEGAL_CERT_TYPE;
+    }
+    /* verify certificate package HBK format */
+    hbkFormat = pPkgHeader->pkgFlags.pkgFlagsBits.hbkType;
+    if ((hbkFormat != CC_SB_HASH_BOOT_KEY_0_128B) &&
+        (hbkFormat != CC_SB_HASH_BOOT_KEY_1_128B) &&
+        (hbkFormat != CC_SB_HASH_BOOT_KEY_256B) &&
+        ((hbkFormat == CC_SB_HASH_BOOT_NOT_USED) && (pkgType != CC_X509_CERT_TYPE_CONTENT))){
+        CC_PAL_LOG_ERR("Invalid Debug package HBK type 0x%X\n", hbkFormat);
+        return CC_SB_X509_CERT_INV_PARAM;
+    }
+    *pHbkFormat = (CCSbPubKeyIndexType_t)hbkFormat;
+
+    /* get certificate offset and size */
+    pDbg2CertInfo->certInfoWord = pPkgHeader->certInfo.certInfoWord;
+
+
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_cert_parser.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_cert_parser.h
new file mode 100644
index 0000000..a95daf0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_cert_parser.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SB_X509_CERT_PARSER_H
+#define _SB_X509_CERT_PARSER_H
+
+#include "cc_pal_x509_defs.h"
+#include "secureboot_parser_gen_defs.h"
+#include "secureboot_gen_defs.h"
+
+
+#define CC_X509_CERT_TYPE_KEY_MAX_SIZE      0x400
+#define CC_X509_CERT_TYPE_PRIM_DBG_MAX_SIZE 0x400
+#define CC_X509_CERT_TYPE_SCND_DBG_MAX_SIZE 0x400
+
+#ifdef CC_SB_CERT_USER_DATA_EXT
+/* user's data */
+typedef uint8_t CCSbUserData_t[X509_USER_DATA_MAX_SIZE_BYTES];
+#endif
+
+/* max Num of components in the header certificate arameter */
+#define CC_X509_CERT_LEN_NUM_OF_COMPS_MAX_SIZE             0x0000FFFFL
+
+typedef struct {
+    CCSbNParams_t       certPubKey;
+    CCSbSwVersion_t     nvCounter;
+    CCSbCertPubKeyHash_t    pubKeyHash;
+#ifdef CC_SB_CERT_USER_DATA_EXT
+/* user's data */
+    CCSbUserData_t      userData;
+#endif
+    CCSbSignature_t     certSign; /* address must be word aligned */
+}KeyCertInfo_t;
+
+typedef struct {
+    CCSbSignature_t     certSign; /* address must be word aligned */
+    CCSbNParams_t       certPubKey;
+    CCSbSwVersion_t     nvCounter;
+    CCSbNonce_t     nonce;
+    uint32_t        numOfImages;
+#ifdef CC_SB_CERT_USER_DATA_EXT
+/* user's data */
+    CCSbUserData_t      userData;
+#endif
+}ContentCertInfo_t;
+
+typedef struct {
+    CCSbNParams_t       certPubKey;
+    uint32_t        validLcs;
+    uint32_t        socSpecific;
+    uint32_t        rmaMode;
+    CCSbCertPubKeyHash_t    pubKeyHash;
+#ifdef CC_SB_CERT_USER_DATA_EXT
+/* user's data */
+    CCSbUserData_t      userData;
+#endif
+    CCSbSignature_t     certSign;  /* address must be word aligned */
+}primDbgCertInfo_t;
+
+typedef struct {
+    CCSbNParams_t       certPubKey;
+    CCSbCertSocId_t     socId;
+    uint32_t        socSpecific;
+#ifdef CC_SB_CERT_USER_DATA_EXT
+/* user's data */
+    CCSbUserData_t      userData;
+#endif
+    CCSbSignature_t     certSign; /* address must be word aligned */
+}scndDbgCertInfo_t;
+
+
+/*!
+ * @brief Parse and validate debug primary certificate
+ *
+ * @param[in] ppAsn1Cert    - pointer to X509 certificate as ASN.1 byte array
+ * @param[in] certMaxSize   - certificate max size (according to certificate type)
+ * @param[out] pSignCertSize    - certificate TBS size, used for signature
+ * @param[out] pTbsStartOffset - certificate TBS start offset, used for signature
+ * @param[out] pOutPubKey       - certificate public key modulus (exponent is constant)
+ * @param[out] pOutCertHeaderInfo  - certificate specfic header info
+ * @param[out] startAddress     - startAddress of certificate pointer
+ * @param[out] endAddress       - endAddress of certificate pointer (max address that certificate ponter may reach)
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from sbrom_bsv_error.h
+ */
+CCError_t SB_X509_VerifyCertTbsHeader(uint8_t       **ppAsn1Cert,
+                      uint32_t      certMaxSize,
+                      uint32_t      *pSignCertSize,
+                      uint32_t      *pTbsStartOffset,
+                      CCSbNParams_t     *pOutPubKey,
+                      CCX509CertHeaderInfo_t *pOutCertHeaderInfo,
+                      unsigned long startAddress,
+                      unsigned long endAddress);
+
+/*!
+ * @brief Parse and validate certificate package header
+ *
+ * @param[in] pPkgHeader    - pointer to debug certificate package
+ * @param[in] pkgType       - certificate package type
+ * @param[out] pDbg2CertInfo    - secondary debug certificate offset and size
+ * @param[out] pHbkFormat   - HBK format for comparison with OTP
+ *
+ * @return uint32_t         - On success: the value CC_OK is returned,
+ *                    On failure: a value from sbrom_bsv_error.h
+ */
+CCError_t SB_X509_ParseCertPkg(CCX509PkgHeader_t    *pPkgHeader,
+                  CCX509CertType_t      pkgType,
+                  CCX509CertInfo_t      *pDbg2CertInfo,
+                  CCSbPubKeyIndexType_t     *pHbkFormat);
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_error.h
new file mode 100644
index 0000000..0d6e069
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_cert_parser/sb_x509_error.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SB_X509_ERROR_H
+#define _SB_X509_ERROR_H
+
+#include "secureboot_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#define CC_SB_X509_CERT_INV_PARAM                       CC_SB_X509_CERT_BASE_ERROR + 0x00000001
+#define CC_SB_X509_CERT_ILLEGAL_TOKEN                   CC_SB_X509_CERT_BASE_ERROR + 0x00000002
+#define CC_SB_X509_CERT_PARSE_ILLEGAL_VAL               CC_SB_X509_CERT_BASE_ERROR + 0x00000003
+#define CC_SB_X509_CERT_ILLEGAL_SWVER_ID                CC_SB_X509_CERT_BASE_ERROR + 0x00000005
+#define CC_SB_X509_CERT_ILLEGAL_VERSION             CC_SB_X509_CERT_BASE_ERROR + 0x00000006
+#define CC_SB_X509_CERT_ILLEGAL_LCS                 CC_SB_X509_CERT_BASE_ERROR + 0x00000007
+#define CC_SB_X509_CERT_ILLEGAL_PKG_ADD                 CC_SB_X509_CERT_BASE_ERROR + 0x00000008
+#define CC_SB_X509_CERT_ILLEGAL_SOC_ID                  CC_SB_X509_CERT_BASE_ERROR + 0x00000009
+#define CC_SB_X509_CERT_ILLEGAL_CERT_TYPE           CC_SB_X509_CERT_BASE_ERROR + 0x0000000A
+#define CC_SB_X509_CERT_SIG_ALIGN_INCORRECT                 CC_SB_X509_CERT_BASE_ERROR + 0x0000000C
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_verifier/bootimagesverifierx509_error.h b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_verifier/bootimagesverifierx509_error.h
new file mode 100644
index 0000000..70fe40b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/codesafe/src/secure_boot_debug/x509_verifier/bootimagesverifierx509_error.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _BOOT_IMAGES_VERIFIER_X509_ERROR_H
+#define _BOOT_IMAGES_VERIFIER_X509_ERROR_H
+
+/*! @file
+@brief This file contains error code definitions used for the Secure Boot and Secure Debug X509 APIs.
+*/
+
+#include "secureboot_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! Defines error code for invalid input parameters. */
+#define CC_BOOT_IMG_VERIFIER_CERT_INV_PARAM                 CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR + 0x00000001
+/*! Defines error code for invalid token. */
+#define CC_BOOT_IMG_VERIFIER_CERT_ILLEGAL_TOKEN             CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR + 0x00000002
+/*! Defines error code for invalid certificate type. */
+#define CC_BOOT_IMG_VERIFIER_CERT_ILLEGAL_CERT_TYPE         CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR + 0x00000003
+/*! Defines error code for illegal workspace size. */
+#define CC_BOOT_IMG_VERIFIER_CERT_WSP_SIZE_TOO_SMALL        CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR + 0x00000004
+/*! Defines error code for unsupported hash algorithm. */
+#define CC_BOOT_IMG_VERIFIER_CERT_UNSUPPORTED_HASH_ALG          CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR + 0x00000005
+/*! Defines error code for unsupported certificate version. */
+#define CC_BOOT_IMG_VERIFIER_CERT_ILLEGAL_VERSION           CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR + 0x00000006
+/*! Defines error code for illegal X509 extension size. */
+#define CC_BOOT_IMG_VERIFIER_CERT_ILLEGAL_EXT_SIZE              CC_BOOT_IMG_VERIFIER_CERT_BASE_ERROR + 0x00000007
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/docs/cc312_cryptocell_runtime_software_developers_manual_101122_0103_01_en.pdf b/lib/ext/cryptocell-312-runtime/docs/cc312_cryptocell_runtime_software_developers_manual_101122_0103_01_en.pdf
new file mode 100755
index 0000000..47465a9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/docs/cc312_cryptocell_runtime_software_developers_manual_101122_0103_01_en.pdf
Binary files differ
diff --git a/lib/ext/cryptocell-312-runtime/docs/cc312_r1_oss_rt_sw-r1p3-00rel0_ReleaseNote.pdf b/lib/ext/cryptocell-312-runtime/docs/cc312_r1_oss_rt_sw-r1p3-00rel0_ReleaseNote.pdf
new file mode 100755
index 0000000..b6e9006
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/docs/cc312_r1_oss_rt_sw-r1p3-00rel0_ReleaseNote.pdf
Binary files differ
diff --git a/lib/ext/cryptocell-312-runtime/doxygen/additional_doc_files_cc312/doc_main.h b/lib/ext/cryptocell-312-runtime/doxygen/additional_doc_files_cc312/doc_main.h
new file mode 100644
index 0000000..d2dbf52
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/doxygen/additional_doc_files_cc312/doc_main.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*!
+
+  @mainpage CryptoCell-312 runtime-software API overview
+
+  This documentation describes the runtime APIs provided by Arm CryptoCell-312.
+  It provides the programmer with all information necessary for integrating
+  and using the runtime APIs in the target environment.\n
+  The API layer enables using the CryptoCell cryptographic algorithms, for example,
+  AES, hash, RSA and ECC.\n
+  Cryptographic algorithms can be divided into two main categories:
+  <ul><li>Symmetric algorithms are mostly used for message confidentiality.\n
+  The symmetric encryption algorithms are accessible via the generic cipher layer.
+  For more information, see mbedtls_cipher_setup().</li>
+  <li>Asymmetric algorithms are mostly used for key exchange and message integrity.\n
+  The asymmetric encryption algorithms are accessible via the generic public
+  key layer.</li></ul>
+  The following algorithms are provided:
+  <ul><li>Symmetric:<ul>
+    <li>AES. \ref cc_aes_hw_limit.</li></ul></li>
+    <li>Asymmetric:<ul>
+    <li>Diffie-Hellman-Merkle. See ::mbedtls_dhm_read_public(), ::mbedtls_dhm_make_public()
+      and ::mbedtls_dhm_calc_secret().</li>
+    <li>RSA. See ::mbedtls_rsa_public() and ::mbedtls_rsa_private().</li>
+    <li>Elliptic Curves over GF(p). See ::mbedtls_ecp_point_init().</li>
+    <li>Elliptic Curve Digital Signature Algorithm (ECDSA). See ::mbedtls_ecdsa_init().</li>
+    <li>Elliptic Curve Diffie Hellman (ECDH). See ::mbedtls_ecdh_init().</li></ul></li></ul>
+  The documentation is automatically generated from the source code using Doxygen.\n
+  For more information on Doxygen, see http://www.stack.nl/~dimitri/doxygen/.\n
+  The <b>Modules</b> section introduces the high-level module concepts used
+  throughout this documentation.
+ */
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/doxygen/arm_cc_rts_ss b/lib/ext/cryptocell-312-runtime/doxygen/arm_cc_rts_ss
new file mode 100644
index 0000000..719b382
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/doxygen/arm_cc_rts_ss
@@ -0,0 +1,86 @@
+# Generated by doxygen 1.8.13

+

+# Customized to map to New_Arm_St.dotm 12-Feb-2018 RVZ

+# Further customized 14-Jun-2018 RVZ

+

+# This file describes styles used for generating RTF output.

+# All text after a hash (#) is considered a comment and will be ignored.

+# Remove a hash to activate a line.

+

+ Heading1 = \s1\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs36\kerning36\cgrid \sbasedon0 \snext17 Heading 1

+ Heading2 = \s2\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext17 Heading 2

+ Heading3 = \s3\sb240\sa60\keepn\widctlpar\adjustright \b\f1\cgrid \sbasedon0 \snext17 Heading 3

+ Heading4 = \s4\sb240\sa60\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext17 Heading 4

+ Heading5 = \s5\sb90\sa30\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext17 Heading 5

+ Title = \s15\qc\sb240\sa60\widctlpar\outlinelevel0\adjustright \b\f1\fs32\kerning28\cgrid \sbasedon0 \snext17 Title

+ SubTitle = \s16\qc\sa60\widctlpar\outlinelevel1\adjustright \f1\cgrid \sbasedon0 \snext17 Arm section title

+ BodyText = \s17\sa60\sb30\widctlpar\qj \fs22\cgrid \sbasedon0 \snext17 Arm text

+ DenseText = \s18\widctlpar\fs22\cgrid \sbasedon0 \snext18 Arm text

+

+ Header = \s28\widctlpar\tqc\tx4320\tqr\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext28 Header

+ Footer = \s29\widctlpar\tqc\tx4320\tqr\tx8640\qr\adjustright \fs20\cgrid \sbasedon0 \snext29 Footer

+ GroupHeader = \s30\li360\sa60\sb120\keepn\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext30 GroupHeader

+ CodeExample0 = \s40\li0\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 1

+ CodeExample1 = \s41\li360\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 2

+ CodeExample2 = \s42\li720\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ CodeExample3 = \s43\li1080\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ CodeExample4 = \s44\li1440\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ CodeExample5 = \s45\li1800\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ CodeExample6 = \s46\li2160\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ CodeExample7 = \s47\li2520\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ CodeExample8 = \s48\li2880\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ CodeExample9 = \s49\li3240\widctlpar\adjustright \shading1000\cbpat8 \f2\fs16\cgrid \sbasedon0 Arm code block 3

+ ListContinue0 = \s50\li0\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 Arm text

+ ListContinue1 = \s51\li360\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext51 Arm list continue 1

+ ListContinue2 = \s52\li720\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext52 Arm list continue 2

+ ListContinue3 = \s53\li1080\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext53 Arm list continue 3

+ ListContinue4 = \s54\li1440\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext54 DX list continue 4

+ ListContinue5 = \s55\li1800\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext55 DX list continue 5

+ ListContinue6 = \s56\li2160\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext56 DX list continue 6

+ ListContinue7 = \s57\li2520\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext57 DX list continue 7

+ ListContinue8 = \s58\li2880\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext58 DX list continue 8

+ ListContinue9 = \s59\li3240\sa60\sb30\qj\widctlpar\qj\adjustright \fs20\cgrid \sbasedon0 \snext59 DX list continue 9

+ DescContinue0 = \s60\li0\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext17 Arm text

+ DescContinue1 = \s61\li360\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext61 Arm list continue 1

+ DescContinue2 = \s62\li720\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext62 Arm list continue 2

+ DescContinue3 = \s63\li1080\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext63 Arm list continue 3

+ DescContinue4 = \s64\li1440\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext64 DX list continue 4

+ DescContinue5 = \s65\li1800\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext65 DX list continue 5

+ DescContinue6 = \s66\li2160\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext66 DX list continue 6

+ DescContinue7 = \s67\li2520\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext67 DX list continue 7

+ DescContinue8 = \s68\li2880\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext68 DX list continue 8

+ DescContinue9 = \s69\li3240\widctlpar\ql\adjustright \fs20\cgrid \sbasedon0 \snext69 DX list continue 9

+# LatexTOC0 = \s70\li0\sa30\sb30\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext81 LatexTOC 0

+# LatexTOC1 = \s71\li360\sa27\sb27\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext82 LatexTOC 1

+# LatexTOC2 = \s72\li720\sa24\sb24\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext83 LatexTOC 2

+# LatexTOC3 = \s73\li1080\sa21\sb21\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext84 LatexTOC 3

+# LatexTOC4 = \s74\li1440\sa18\sb18\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext85 LatexTOC 4

+# LatexTOC5 = \s75\li1800\sa15\sb15\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext86 LatexTOC 5

+# LatexTOC6 = \s76\li2160\sa12\sb12\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext87 LatexTOC 6

+# LatexTOC7 = \s77\li2520\sa9\sb9\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext88 LatexTOC 7

+# LatexTOC8 = \s78\li2880\sa6\sb6\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 8

+# LatexTOC9 = \s79\li3240\sa3\sb3\widctlpar\tqr\tldot\tx8640\adjustright \fs20\cgrid \sbasedon0 \snext89 LatexTOC 9

+ ListBullet0 = \s80\fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlbody\ilvl0\ls1\pnrnot0\pndec }\ls1\adjustright \fs20\cgrid \sbasedon0 \snext80 \sautoupd Arm bullet 1

+ ListBullet1 = \s81\fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlbody\ilvl0\ls2\pnrnot0\pndec }\ls2\adjustright \fs20\cgrid \sbasedon0 \snext81 \sautoupd Arm bullet 2

+ ListBullet2 = \s82\fi-360\li1080\widctlpar\jclisttab\tx1080{\*\pn \pnlvlbody\ilvl0\ls3\pnrnot0\pndec }\ls3\adjustright \fs20\cgrid \sbasedon0 \snext82 \sautoupd Arm bullet 3

+ ListBullet3 = \s83\fi-360\li1440\widctlpar\jclisttab\tx1440{\*\pn \pnlvlbody\ilvl0\ls4\pnrnot0\pndec }\ls4\adjustright \fs20\cgrid \sbasedon0 \snext83 \sautoupd DX bullet 4

+ ListBullet4 = \s84\fi-360\li1800\widctlpar\jclisttab\tx1800{\*\pn \pnlvlbody\ilvl0\ls5\pnrnot0\pndec }\ls5\adjustright \fs20\cgrid \sbasedon0 \snext84 \sautoupd DX bullet 5

+ ListBullet5 = \s85\fi-360\li2160\widctlpar\jclisttab\tx2160{\*\pn \pnlvlbody\ilvl0\ls6\pnrnot0\pndec }\ls6\adjustright \fs20\cgrid \sbasedon0 \snext85 \sautoupd DX bullet 6

+ ListBullet6 = \s86\fi-360\li2520\widctlpar\jclisttab\tx2520{\*\pn \pnlvlbody\ilvl0\ls7\pnrnot0\pndec }\ls7\adjustright \fs20\cgrid \sbasedon0 \snext86 \sautoupd DX bullet 7

+ ListBullet7 = \s87\fi-360\li2880\widctlpar\jclisttab\tx2880{\*\pn \pnlvlbody\ilvl0\ls8\pnrnot0\pndec }\ls8\adjustright \fs20\cgrid \sbasedon0 \snext87 \sautoupd DX bullet 8

+# ListBullet8 = \s88\fi-360\li3240\widctlpar\jclisttab\tx3240{\*\pn \pnlvlbody\ilvl0\ls9\pnrnot0\pndec }\ls9\adjustright \fs20\cgrid \sbasedon0 \snext88 \sautoupd DX bullet 9

+# ListBullet9 = \s89\fi-360\li3600\widctlpar\jclisttab\tx3600{\*\pn \pnlvlbody\ilvl0\ls10\pnrnot0\pndec }\ls10\adjustright \fs20\cgrid \sbasedon0 \snext89 \sautoupd DX bullet 10

+ ListEnum0 = \s90\fi-360\li360\widctlpar\fs20\cgrid \sbasedon0 \snext90 \sautoupd Arm numbered list 1

+ ListEnum1 = \s91\fi-360\li720\widctlpar\fs20\cgrid \sbasedon0 \snext91 \sautoupd Arm numbered list 2

+ ListEnum2 = \s92\fi-360\li1080\widctlpar\fs20\cgrid \sbasedon0 \snext92 \sautoupd Arm numbered list 3

+ ListEnum3 = \s93\fi-360\li1440\widctlpar\fs20\cgrid \sbasedon0 \snext93 \sautoupd DX Numbered list 4

+ ListEnum4 = \s94\fi-360\li1800\widctlpar\fs20\cgrid \sbasedon0 \snext94 \sautoupd DX numbered list 5

+ ListEnum5 = \s95\fi-360\li2160\widctlpar\fs20\cgrid \sbasedon0 \snext95 \sautoupd DX numbered list 6

+ ListEnum6 = \s96\fi-360\li2520\widctlpar\fs20\cgrid \sbasedon0 \snext96 \sautoupd Dx numbered list 7

+ ListEnum7 = \s97\fi-360\li2880\widctlpar\fs20\cgrid \sbasedon0 \snext97 \sautoupd DX numbered list 8

+# ListEnum8 = \s98\fi-360\li3240\widctlpar\fs20\cgrid \sbasedon0 \snext98 \sautoupd DX numbered list 9

+# ListEnum9 = \s99\fi-360\li3600\widctlpar\fs20\cgrid \sbasedon0 \snext99 \sautoupd DX numbered list 10

+

+# Character styles

+

+ Monospace = \*\cs100 \additive \f3 \sbasedon0 Monospace
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/doxygen/doxygen_cc312.conf b/lib/ext/cryptocell-312-runtime/doxygen/doxygen_cc312.conf
new file mode 100755
index 0000000..4d51456
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/doxygen/doxygen_cc312.conf
@@ -0,0 +1,2546 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Doxyfile 1.8.14
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See
+# https://www.gnu.org/software/libiconv/ for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "Arm CryptoCell-312 API Documentation"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = api_docs_output
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = NO
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up
+# to that level are automatically included in the table of contents, even if
+# they do not have an id attribute.
+# Note: This feature currently applies only to Markdown headings.
+# Minimum value: 0, maximum value: 99, default value: 0.
+# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
+
+TOC_INCLUDE_HEADINGS   = 0
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# If one adds a struct or class to a group and this option is enabled, then also
+# any nested class or struct is added to the same group. By default this option
+# is disabled and one has to add nested compounds explicitly via \ingroup.
+# The default value is: NO.
+
+GROUP_NESTED_COMPOUNDS = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
+# a warning is encountered.
+# The default value is: NO.
+
+WARN_AS_ERROR          = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = doxygen_cc312_errors.txt
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = module_definitions.h \
+                         ../host/src/cc3x_lib/cc_lib.h \
+                         ../shared/include/crypto_api/cc_error.h \
+                         ../shared/include/proj/cc3x/cc_general_defs.h \
+                         ../shared/include/proj/cc3x/cc_address_defs.h \
+                         ../shared/include/crypto_api/cc_aes_defs.h \
+                         ../codesafe/src/mbedtls_api/mbedtls_ccm_common.h \
+                         ../shared/include/crypto_api/cc3x/cc_aes_defs_proj.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_cc_ecies.h \
+                         ../shared/include/crypto_api/cc_ecpki_types.h \
+                         ../shared/include/proj/cc3x/cc_ecpki_domains_defs.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_aes_ext_dma.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_chacha_ext_dma.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_hash_ext_dma.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_ext_dma_error.h \
+                         ../shared/include/crypto_api/cc_hash_defs.h \
+                         ../shared/include/crypto_api/cc3x/cc_hash_defs_proj.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_cc_sha512_t.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_cc_ccm_star.h \
+                         ../shared/include/cc_mng/mbedtls_cc_mng.h \
+                         ../shared/include/cc_mng/mbedtls_cc_mng_error.h \
+                         ../shared/include/pal/cc_pal_abort.h \
+                         ../shared/include/pal/cc_pal_barrier.h \
+                         ../shared/include/pal/cc_pal_compiler.h \
+                         ../shared/include/pal/cc_pal_error.h \
+                         ../shared/include/pal/cc_pal_init.h \
+                         ../shared/include/pal/cc_pal_log.h \
+                         ../shared/include/pal/cc_pal_mem.h \
+                         ../shared/include/pal/cc_pal_memmap.h \
+                         ../shared/include/pal/cc_pal_mutex.h \
+                         ../shared/include/pal/cc_pal_types.h \
+                         ../codesafe/src/secure_boot_debug/platform/pal/cc3x/cc_pal_sb_plat.h \
+                         ../shared/include/crypto_api/cc3x/cc_pka_defs_hw.h \
+                         ../shared/include/proj/cc3x/cc_pka_hw_plat_defs.h \
+                         ../shared/include/pal/cc_pal_pm.h \
+                         ../shared/include/pal/cc_pal_apbc.h \
+                         ../host/src/cc3x_productionlib/common/cc_prod.h \
+                         ../host/src/cc3x_productionlib/cmpu/cc_cmpu.h \
+                         ../host/src/cc3x_productionlib/dmpu/cc_dmpu.h \
+                         ../host/src/cc3x_productionlib/common/cc_prod_error.h \
+                         ../shared/include/crypto_api/cc3x/cc_rnd_common.h \
+                         ../host/src/cc3x_lib/mbedtls_cc_sbrt.h \
+                         ../codesafe/src/secure_boot_debug/cc3x_verifier/bootimagesverifier_def.h \
+                         ../codesafe/src/secure_boot_debug/platform/common/cc3x/secureboot_defs.h \
+                         ../codesafe/src/secure_boot_debug/secure_boot_gen/secureboot_gen_defs.h \
+                         ../shared/include/proj/cc3x/cc_sram_map.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_cc_srp.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_cc_srp_error.h \
+                         ../shared/include/pal/cc_pal_trng.h \
+                         ../shared/include/cc_util/mbedtls_cc_util_defs.h \
+                         ../shared/include/cc_util/mbedtls_cc_util_key_derivation.h \
+                         ../shared/include/cc_util/mbedtls_cc_util_key_derivation_defs.h \
+                         ../host/src/cc3x_lib/mbedtls_cc_util_asset_prov.h \
+                         ../shared/include/cc_util/cc_util_error.h \
+                         ../mbedtls/include/mbedtls/aes.h \
+                         ../mbedtls/include/mbedtls/ccm.h \
+                         ../mbedtls/include/mbedtls/cipher.h \
+                         ../mbedtls/include/mbedtls/cmac.h \
+                         ../mbedtls/include/mbedtls/ctr_drbg.h \
+                         ../mbedtls/include/mbedtls/dhm.h \
+                         ../mbedtls/include/mbedtls/ecdh.h \
+                         ../mbedtls/include/mbedtls/ecdsa.h \
+                         ../mbedtls/include/mbedtls/ecp.h \
+                         ../mbedtls/include/mbedtls/gcm.h \
+                         ../mbedtls/include/mbedtls/md.h \
+                         ../mbedtls/include/mbedtls/platform.h \
+                         ../mbedtls/include/mbedtls/rsa.h \
+                         ../mbedtls/include/mbedtls/sha1.h \
+                         ../mbedtls/include/mbedtls/sha256.h \
+                         ../mbedtls/include/mbedtls/sha512.h \
+                         ../mbedtls/include/mbedtls/hkdf.h \
+                         ../mbedtls/include/mbedtls/nist_kw.h \
+                         ../mbedtls/include/mbedtls/chacha20.h \
+                         ../mbedtls/include/mbedtls/poly1305.h \
+                         ../mbedtls/include/mbedtls/chachapoly.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_cc_ecdsa_edwards.h \
+                         ../shared/include/crypto_api/cc3x/mbedtls_cc_ecdh_edwards.h \
+                         additional_doc_files_cc312
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: https://www.gnu.org/software/libiconv/) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# read by doxygen.
+#
+# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
+# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
+# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
+# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
+# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf and *.qsf.
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = code_examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+#
+# Note that for custom extensions or not directly supported extensions you also
+# need to set EXTENSION_MAPPING for the extension otherwise the files are not
+# properly processed by doxygen.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = NO
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see https://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = NO
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+# If clang assisted parsing is enabled you can provide the clang parser with the
+# path to the compilation database (see:
+# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files
+# were built. This is equivalent to specifying the "-p" option to a clang tool,
+# such as clang-check. These options will then be pased to the parser.
+# Note: The availability of this option depends on whether or not doxygen was
+# generated with the -Duse-libclang=ON option for CMake.
+# The default value is: 0.
+
+CLANG_COMPILATION_DATABASE_PATH= 0
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = NO
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 192
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 143
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 176
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to YES can help to show when doxygen was last run and thus if the
+# documentation is up to date.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
+# documentation will contain a main index with vertical navigation menus that
+# are dynamically created via Javascript. If disabled, the navigation index will
+# consists of multiple levels of tabs that are statically embedded in every HTML
+# page. Disable this option to support browsers that do not have Javascript,
+# like the Qt help browser.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_MENUS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: https://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = YES
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# https://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from https://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: https://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: https://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. The package can be specified just
+# by its name or with the correct syntax as to be used with the LaTeX
+# \usepackage command. To get the times font for instance you can specify :
+# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
+# To use the option intlimits with the amsmath package you can specify:
+# EXTRA_PACKAGES=[intlimits]{amsmath}
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_TIMESTAMP        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = YES
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = YES
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = YES
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = arm_cc_rts_ss
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
+# the structure of the code including all documentation. Note that this feature
+# is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = __GNUC__ \
+                         min \
+                         max \
+                         CC_SB_X509_CERT_SUPPORTED \
+                         USE_MBEDTLS_CRYPTOCELL
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command. Disabling a call graph can be
+# accomplished by means of the command \hidecallgraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command. Disabling a caller graph can be
+# accomplished by means of the command \hidecallergraph.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. For an explanation of the image formats see the section
+# output formats in the documentation of the dot tool (Graphviz (see:
+# http://www.graphviz.org/)).
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo,
+# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
+# png:gdiplus:gdiplus.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      = 
+
+# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a
+# configuration file for plantuml.
+
+PLANTUML_CFG_FILE      = 
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/lib/ext/cryptocell-312-runtime/doxygen/module_definitions.h b/lib/ext/cryptocell-312-runtime/doxygen/module_definitions.h
new file mode 100644
index 0000000..12c8d1e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/doxygen/module_definitions.h
@@ -0,0 +1,982 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "aes.h"
+
+/*!
+ @defgroup cryptocell_api CryptoCell runtime library
+
+ @{
+ @}
+ */
+
+/*
+  ############################TOP-LEVEL APIs###################################
+ */
+/*!
+ @defgroup cc_top Basic CryptoCell library definitions
+ @brief Contains basic CryptoCell library definitions.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+/*!
+ @defgroup cc_lib Basic CryptoCell library APIs
+ @brief Contains basic CryptoCell library APIs.
+
+ This module lists the basic CryptoCell library APIs.
+
+ @{
+ @ingroup cc_top
+ @}
+ */
+
+  /*!
+ @defgroup cc_general_defs General CryptoCell definitions
+ @brief Contains general definitions of the CryptoCell runtime SW APIs.
+
+ @{
+ @ingroup cc_top
+ @}
+ */
+
+/*!
+ @defgroup cc_error General base error codes for CryptoCell
+ @brief Contains general base-error codes for CryptoCell.
+
+
+ @{
+ @ingroup cc_top
+ @}
+ */
+
+
+ /*
+  ################################AES APIs#####################################
+ */
+/*!
+  @defgroup cc_aes CryptoCell AES APIs
+
+  @ingroup cryptocell_api
+
+  @brief AES is a symmetric block cipher that uses a combination of both substitution
+  and permutation. It is fast in both software and hardware.
+
+  AES has a fixed block size of 128 bits, and supports the following key sizes:
+  <ul><li>128 bits.</li><li>192 bits.</li><li>256 bits.</li></ul>
+
+  For the implementation of AES, see aes.h.
+
+ */
+
+ /*!
+  @defgroup cc_aes_hw_limit CryptoCell-312 hardware limitations for AES
+
+  @ingroup cc_aes
+
+  The CrytoCell-312 hardware accelerates the following AES operations:
+  <ul><li>ECB.</li>
+  <li>CBC.</li>
+  <li>CTR.</li>
+  <li>CMAC. For the implementation of CMAC, see cmac.h.</li>
+  <li>OFB.</li>
+  <li>CCM. For the implementation of CCM, see ccm.h.</li>
+  <li>CCM star. For the implementation of CCM star, see mbedtls_cc_ccm_star.h and ccm.h.</li>
+  <li>GCM. For the implementation of GCM, see gcm.h.</li></ul>
+
+  To support the accelerated algorithms, the following conditions
+  must be met:
+  <ul><li>The input and output buffers must be DMA-able.</li>
+  <li>The input and output buffers must be physically contingous
+  blocks in memory.</li>
+  <li>Buffer size must be up to 64KB.</li>
+  <li>The context must also be DMA-able, as partial
+  and final results are written to the context.</li>
+  <li>Only integrated operations are supported for CCM, CCM star and GCM algorithms.</li></ul>
+ */
+
+ /*!
+  @defgroup cc_aes_typical Typical usage of AES in CryptoCell-312
+
+  @ingroup cc_aes
+
+  The following is a typical AES Block operation flow:
+  <ol><li>mbedtls_aes_init().</li>
+  <li>mbedtls_aes_setkey_enc().</li>
+  <li>mbedtls_aes_crypt_cbc().</li></ol>
+
+*/
+
+/*!
+ @defgroup cc_aesccm_star CryptoCell AES-CCM star APIs
+ @brief Contains the CryptoCell AES-CCM star APIs.
+
+ @{
+ @ingroup cc_aes
+ @}
+ */
+
+/*!
+ @defgroup cc_aes_defs Definitions of CryptoCell AES APIs
+ @brief Contains CryptoCell AES API type definitions.
+
+ @{
+ @ingroup cc_aes
+ @}
+ */
+
+/*!
+ @defgroup cc_aes_defs_proj Project definitions of CryptoCell AES APIs
+ @brief Contains CryptoCell AES API project type definitions.
+
+ @{
+ @ingroup cc_aes_defs
+ @}
+ */
+
+ /*!
+ @defgroup cc_aesccm_star_common Common definitions of the CryptoCell AES-CCM star APIs
+ @brief Contains the CryptoCell AES-CCM star APIs.
+
+ @{
+ @ingroup cc_aes_defs
+ @}
+ */
+
+
+ /*
+  ################################DHM APIs#####################################
+ */
+ /*!
+  @defgroup dhm_module CryptoCell DHM APIs
+
+  @ingroup cryptocell_api
+
+  @brief Diffie-Hellman-Merkle (DHM) is used to securely exchange cryptographic
+  keys over a public channel.
+
+  As described in <em>Public-Key Cryptography Standards (PKCS) #3: Diffie Hellman
+  Key Agreement Standard</em>:
+  "[T]wo parties, without any prior arrangements, can agree upon a secret key
+  that is known only to them...This secret key can then be used, for example,
+  to encrypt further communications between the parties."
+
+  The DHM module is implemented based on the definitions in the following
+  standards:
+  <ul><li><em>RFC-3526: More Modular Exponential (MODP) Diffie-Hellman groups
+  for Internet Key Exchange (IKE)</em>: defines a number of standardized
+  Diffie-Hellman groups for IKE.</li>
+  <li><em>RFC-5114: Additional Diffie-Hellman Groups for Use with IETF
+  Standards</em>: defines a number of standardized Diffie-Hellman
+  groups that can be used.</li></ul>
+
+  For the implementation of DHM, see dhm.h.
+ */
+
+ /*!
+  @defgroup cc_dhm_hw_limit CryptoCell-312 hardware limitations for DHM
+
+  @ingroup dhm_module
+
+  To support the accelerated algorithms, the following conditions
+  must be met:
+  <ul><li>The contexts must be DMA-able, as they might
+  be used for some symmetric operations.</li></ul>
+ */
+
+ /*!
+  @defgroup cc_dhm_typical Typical usage of DHM in CryptoCell-312
+
+  @ingroup dhm_module
+
+  The following is a typical DHM flow for one party:
+  <ol><li>mbedtls_dhm_init().</li>
+  <li>mbedtls_mpi_read_string().</li>
+  <li>mbedtls_mpi_read_string().</li>
+  <li>mbedtls_dhm_make_params().</li>
+  <li>mbedtls_dhm_read_public().</li>
+  <li>mbedtls_dhm_calc_secret().</li></ol>
+ */
+
+/*
+  ################################ECC APIs#####################################
+ */
+
+/*!
+ @defgroup cc_ecc CryptoCell Elliptic Curve APIs
+ @brief Contains all CryptoCell Elliptic Curve APIs.
+
+ Elliptic-curve cryptography (ECC) is defined in <em>Standards for Efficient
+ Cryptography Group (SECG): SEC1 Elliptic Curve Cryptography</em>.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+*/
+
+ /*!
+  @defgroup ecdh_module ECDH module overview
+
+  @ingroup cc_ecc
+
+  @brief Elliptic-curve Diffie–Hellman (ECDH) is an anonymous key agreement
+  protocol. It allows two parties to establish a shared secret over an
+  insecure channel. Each party must have an elliptic-curve public–private
+  key pair.
+
+  For more information, see <em>NIST SP 800-56A Rev. 2: Recommendation
+  for Pair-Wise Key Establishment Schemes Using Discrete Logarithm
+  Cryptography</em>.
+
+  For the implementation of ECDH, see ecdh.h.
+ */
+
+ /*!
+  @defgroup cc_ecdh_hw_limit CryptoCell-312 hardware limitations for ECDH
+
+  @ingroup ecdh_module
+
+  CryotoCell-312 does not support Brainpool curves.
+
+  */
+
+/*!
+  @defgroup cc_ecdh_typical Typical usage of ECDH in CryptoCell-312
+
+  @ingroup ecdh_module
+
+  The following is a typical ECDH operation flow:
+  <ol><li>mbedtls_ecp_group_init().</li>
+  <li>mbedtls_mpi_init() for each group parameter.</li>
+  <li>mbedtls_ecdh_gen_public().</li></ol>
+ */
+
+/*!
+ @defgroup ecdh_edwards CryptoCell ECDH Edwards curve APIs
+ @brief Contains the CryptoCell ECDH Edwards curve APIs.
+ @{
+ @ingroup ecdh_module
+ @}
+ */
+
+/*!
+  @defgroup ecdsa_module ECDSA module overview
+
+  @ingroup cc_ecc
+
+  @brief The Elliptic Curve Digital Signature Algorithm (ECDSA) is a used for
+  generating and validating digital signatures.
+
+  For the definition of ECDSA, see <em>Standards for Efficient Cryptography Group (SECG):
+  SEC1 Elliptic Curve Cryptography</em>.
+
+  For the use of ECDSA for TLS, see <em>RFC-4492: Elliptic Curve
+  Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)</em>.
+
+  For the implementation of ECDSA, see ecdsa.h.
+ */
+
+/*!
+  @defgroup cc_ecdsa_hw_limit CryptoCell-312 hardware limitations for ECDSA
+
+  @ingroup ecdsa_module
+
+  CryotoCell-312 does not support Brainpool curves.
+
+  \note Using hash functions with hash size greater than the EC modulus size
+        is not recommended.
+ */
+/*!
+  @defgroup cc_ecdsa_typical Typical usage of ECDSA in CryptoCell-312
+
+  @ingroup ecdsa_module
+
+  The following is a typical ECDSA operation flow:
+  <ol><li>mbedtls_ecp_group_init().</li>
+  <li>mbedtls_mpi_init() for each group parameter.</li>
+  <li>mbedtls_ecp_gen_keypair().</li>
+  <li>mbedtls_ecdsa_sign() or mbedtls_ecdsa_verify().</li></ol>
+ */
+
+/*!
+ @defgroup eddsa CryptoCell EDDSA Edwards curve APIs
+ @brief Contains the CryptoCell EDDSA Edwards curve APIs.
+ @{
+ @ingroup ecdsa_module
+ @}
+ */
+
+/*!
+ @defgroup cc_ecies CryptoCell ECIES APIs
+ @brief Contains the CryptoCell Elliptic Curve Integrated Encryption Scheme (ECIES) APIs.
+ @{
+
+ @ingroup cc_ecc
+ @}
+*/
+
+/*!
+ @defgroup cc_ecpki CryptoCell ECPKI APIs
+ @brief Contains all CryptoCell ECPKI APIs.
+
+ This module contains all definitions relating to Elliptic Curve Public Key Infrastructure.
+ @{
+ @ingroup cc_ecc
+ @}
+*/
+
+/*!
+ @defgroup cc_ecpki_domains_defs CryptoCell ECPKI supported domains
+ @brief Contains CryptoCell ECPKI domains supported by the project.
+
+ @{
+ @ingroup cc_ecpki
+ @}
+ */
+
+ /*!
+ @defgroup cc_ecpki_types CryptoCell ECPKI type definitions
+ @brief Contains CryptoCell ECPKI API type definitions.
+
+ @{
+ @ingroup cc_ecpki
+ @}
+ */
+
+/*
+  ##############################EXT DMA APIs###################################
+ */
+
+/*!
+ @defgroup ext_dma CryptoCell external DMA APIs
+ @brief Contains all CryptoCell external DMA API definitions.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+*/
+
+/*!
+ @defgroup aes_ext_dma CryptoCell AES external DMA APIs
+ @brief Contains CryptoCell AES external DMA API definitions.
+
+ @{
+ @ingroup ext_dma
+ @}
+*/
+
+/*!
+ @defgroup chacha_ext_dma CryptoCell ChaCha external DMA APIs
+ @brief Contains CryptoCell ChaCha external DMA APIs.
+
+ @{
+ @ingroup ext_dma
+ @}
+ */
+
+/*!
+ @defgroup hash_ext_dma CryptoCell hash external DMA APIs
+ @brief Contains CryptoCell hash external DMA APIs.
+
+ @{
+ @ingroup ext_dma
+ @}
+ */
+
+/*!
+ @defgroup ext_dma_errors Specific errors of the CryptoCell external DMA APIs
+ @brief Contains the CryptoCell external DMA-API error definitions.
+
+ @{
+ @ingroup ext_dma
+ @}
+ */
+
+
+/*
+  ###############################HASH APIs#####################################
+ */
+
+/*!
+ @defgroup cc_hash CryptoCell hash APIs
+ @brief Contains all CryptoCell hash APIs and definitions.
+
+  The hash or Message Digest (MD) module allows you to calculate
+  hash digests from data, and create signatures based on those hash digests.
+
+  HMAC is a wrapping algorithm that uses one of the supported
+  hash algorithms and a key, to generate a unique
+  authentication code over the input data.
+
+  All hash algorithms can be accessed via the generic MD layer.
+  For more information, see ::mbedtls_md_setup().
+
+  For more information on supported hash algorithms, @see cc_hash_hw_limit.
+
+  For the implementation of hash and HMAC, see md.h.
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+/*!
+  @defgroup cc_hash_hw_limit CryptoCell-312 hardware limitations for hash
+
+  @ingroup cc_hash
+
+  The CryptoCell-312 hardware supports accelerated hash operations for
+  the following modes:
+  <ul><li>SHA-1</li>
+  <li>SHA-224</li>
+  <li>SHA-256</li></ul>
+
+  SHA-384 and SHA-512 operations are only supported in a
+  non-accelerated software mode.
+
+  To support the accelerated algorithms, the following conditions
+  must be met:
+  <ul><li>The input buffer must be DMA-able.</li>
+  <li>The input buffer must be physically contingous
+  block in memory.</li>
+  <li>Buffer size must be up to 64KB.</li>
+  <li>The context must also be DMA-able, as partial
+  and final results are written to the context.</li></ul>
+ */
+
+/*!
+  @defgroup cc_hash_typical Typical usage of hash in CryptoCell-312
+
+  @ingroup cc_hash
+
+  The following is a typical hash Block operation flow
+  directly using the SHA module:
+  <ol><li>mbedtls_sha1_init().</li>
+  <li>mbedtls_sha1_starts_ret().</li>
+  <li>mbedtls_sha1_update_ret().</li>
+  <li>mbedtls_sha1_finish_ret().</li></ol>
+
+  The following is a typical HMAC Block operation flow
+  using the MD module:
+  <ol><li>mbedtls_md_setup().</li>
+  <li>mbedtls_md_hmac_starts().</li>
+  <li>mbedtls_md_hmac_update().</li>
+  <li>mbedtls_md_hmac_finish().</li></ol>
+ */
+
+ /*!
+ @defgroup cc_sha512_t_h CryptoCell SHA-512 truncated APIs
+
+ @ingroup cc_hash
+
+ @brief Contains all CryptoCell SHA-512 truncated APIs.
+
+ */
+
+ /*!
+ @defgroup cc_hash_defs CryptoCell hash API definitions
+ @brief Contains CryptoCell hash API definitions.
+
+ @{
+ @ingroup cc_hash
+ @}
+*/
+
+/*!
+ @defgroup cc_hash_defs_proj CryptoCell hash API project-specific definitions
+ @brief Contains the project-specific hash API definitions.
+
+ @{
+ @ingroup cc_hash
+ @}
+ */
+
+/*
+  ###############################MGMT APIs#####################################
+ */
+/*!
+ @defgroup cc_management CryptoCell management APIs
+ @brief Contains CryptoCell Management APIs.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+/*!
+ @defgroup cc_management_error Specific errors of the CryptoCell Management APIs
+ @brief Contains the CryptoCell management-API error definitions.
+
+ @{
+ @ingroup cc_management
+ @}
+*/
+
+/*
+  ################################PAL APIs#####################################
+ */
+/*!
+ @defgroup cc_pal CryptoCell PAL APIs
+ @brief Groups all PAL APIs and definitions.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+ /*!
+ @defgroup cc_pal_abort CryptoCell PAL abort operations
+ @brief Contains CryptoCell PAL abort operations.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_apbc CryptoCell PAL APB-C APIs
+ @brief Contains PAL APB-C APIs.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_sb_plat CryptoCell PAL definitions for Boot Services
+ @brief Contains CryptoCell PAL Secure Boot definitions.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_init CryptoCell PAL entry or exit point APIs
+ @brief Contains PAL initialization and termination APIs.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_log CryptoCell PAL logging APIs and definitions
+ @brief Contains CryptoCell PAL layer log definitions.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_mem CryptoCell PAL memory operations
+ @brief Contains memory-operation functions.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_barrier CryptoCell PAL memory Barrier APIs
+ @brief Contains memory-barrier implementation definitions and APIs.
+
+ @{
+ @ingroup cc_pal_mem
+ @}
+*/
+
+/*!
+ @defgroup cc_pal_memmap CryptoCell PAL memory mapping APIs
+ @brief Contains memory mapping functions.
+
+ @{
+ @ingroup cc_pal_mem
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_mutex CryptoCell PAL mutex APIs
+ @brief Contains resource management functions.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_types CryptoCell PAL platform-dependent definitions and types
+ @brief Contains CryptoCell PAL platform-dependent definitions and types.
+
+ @{
+ @ingroup cc_pal
+ @}
+*/
+
+/*!
+ @defgroup cc_pal_compiler CryptoCell PAL platform-dependent compiler-related definitions
+ @brief Contains CryptoCell PAL platform-dependent compiler-related definitions.
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+ /*!
+ @defgroup cc_pal_pm CryptoCell PAL power-management APIs
+ @brief Contains PAL power-management APIs.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_trng CryptoCell PAL TRNG APIs
+ @brief Contains APIs for retrieving TRNG user parameters.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*!
+ @defgroup cc_pal_error Specific errors of the CryptoCell PAL APIs
+ @brief Contains platform-dependent PAL-API error definitions.
+
+ @{
+ @ingroup cc_pal
+ @}
+ */
+
+/*
+  ################################PKA APIs#####################################
+ */
+/*!
+ @defgroup cc_pka CryptoCell PKA APIs
+ @brief Contains all CryptoCell PKA APIs.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+ /*!
+ @defgroup cc_pka_defs_hw CryptoCell PKA-specific definitions
+ @brief Contains the CryptoCell PKA API definitions.
+
+ @{
+ @ingroup cc_pka
+ @}
+ */
+
+/*!
+ @defgroup cc_pka_hw_plat_defs CryptoCell PKA-API platform-dependent types and definitions
+ @brief Contains the platform-dependent definitions of the CryptoCell PKA APIs.
+
+ @{
+ @ingroup cc_pka_defs_hw
+ @}
+ */
+
+
+/*
+  ###############################PROD APIs#####################################
+ */
+
+/*!
+ @addtogroup prod CryptoCell production-library APIs
+ @brief Contains CryptoCell production-library APIs.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+ /*!
+ @defgroup prod_mem CryptoCell production-library definitions
+ @brief Contains CryptoCell production-library definitions.
+
+ @{
+ @ingroup prod
+ @}
+ */
+
+/*!
+ @defgroup cc_cmpu CryptoCell ICV production library APIs
+ @brief Contains CryptoCell ICV production library APIs.
+
+ @{
+ @ingroup prod
+ @}
+ */
+
+/*!
+ @defgroup cc_dmpu CryptoCell OEM production library APIs
+ @brief Contains CryptoCell OEM production library APIs.
+
+ @{
+ @ingroup prod
+ @}
+ */
+
+/*!
+ @defgroup prod_errors Specific errors of the CryptoCell production-library APIs
+ @brief Contains the CryptoCell production-library-API error definitions.
+
+ @{
+ @ingroup prod
+ @}
+ */
+
+
+/*
+  ################################RNG APIs#####################################
+ */
+/*!
+  @defgroup rng_module CryptoCell RNG APIs
+
+  @brief The Random Number Generator (RNG) module supports random number
+  generation, as defined in <em>NIST SP 800-90A: Recommendation for Random
+  Number Generation Using Deterministic Random Bit Generators</em>.
+  See mbedtls_ctr_drbg_random().
+
+  The block-cipher counter-mode based deterministic random-bit
+  generator (CTR_DBRG). CryptoCell provides the source of entropy.
+
+  For the implementation of RNG, see ctr_drbg.h.
+  @{
+  @ingroup cryptocell_api
+  @}
+ */
+
+/*!
+ @defgroup cc_rnd CryptoCell random-number generation APIs.
+ @brief Contains the CryptoCell random-number generation APIs.
+ @{
+ @ingroup rng_module
+ @}
+ */
+
+
+ /*
+  ################################RSA APIs#####################################
+ */
+/*!
+  @defgroup rsa_module CryptoCell RSA APIs
+
+  @ingroup cryptocell_api
+
+  @brief RSA is an asymmetric algorithm used for secure-data transmission.
+
+  @note As it is considered slow, it is mainly used to pass encrypted shared
+  keys for symmetric key cryptography.
+
+  The RSA module implements the standards defined in <em>Public-Key Cryptography
+  Standards (PKCS) #1 v1.5: RSA Encryption</em> and <em>Public-Key
+  Cryptography Standards (PKCS) #1 v2.1: RSA Cryptography Specifications</em>.
+
+  @note CryptoCell-312 does not support blinding for RSA. If a function receives
+        random pointers as input, these may be NULL.
+
+  For the implementation of RSA, see rsa.h
+ */
+
+/*!
+  @defgroup cc_rsa_hw_limit CryptoCell-312 hardware limitations for RSA
+
+  @ingroup rsa_module
+
+  CryptoCell-312 supports the following RSA key sizes for private-public
+  operations:
+  <ul><li>256 bytes (2048 bits).</li>
+  <li>384 bytes (3072 bits).</li>
+  <li>512 bytes (4096 bits).</li></ul>
+
+  For key-generation, CryptoCell-312 supports the following RSA key sizes:
+  <ul><li>256 bytes (2048 bits).</li>
+  <li>384 bytes (3072 bits).</li></ul>
+ */
+
+/*!
+  @defgroup cc_rsa_typical Typical usage of RSA in CryptoCell-312
+
+  @ingroup rsa_module
+
+  The following is a typical RSA operation flow:
+  <ol><li>mbedtls_rsa_init().</li>
+  <li>mbedtls_rsa_gen_key().</li>
+  <li>mbedtls_rsa_pkcs1_encrypt().</li></ol>
+
+  @note CryptoCell-312 requires that the same \c hash_id used for
+        mbedtls_rsa_init() is used for all subsequent operations.
+        Otherwise, it returns an error.
+ */
+
+ /*!
+  @defgroup cc_rsa_typical_ki Typical insertion of keys in CryptoCell-312
+
+  @ingroup rsa_module
+
+  The following is a typical RSA key-insertion flow:
+  <ol><li>mbedtls_rsa_import() or mbedtls_rsa_import_raw().</li>
+  <li>mbedtls_rsa_complete().</li></ol>
+
+  If you insert keys that are not derived by CryptoCell-312,
+  the following restrictions apply:
+  <ul><li>The user may insert \c N, \c D, \c E, and the complete function does
+  not derive the \c P and \c Q (the CRT values).</li>
+  <li>The user may insert \c P and \c Q, and the complete function derives the
+  CRT values from that, but does not derive \c D.</li>
+  <li>Its Illegal to insert only part of the CRT key (only \c DP for example).</li>
+  <li> If all the required key parameters were inserted the function does nothing.</li></ul>
+ */
+
+/*
+  #############################Secure Boot APIs################################
+ */
+/*!
+ @defgroup cc_sb CryptoCell Secure Boot and Secure Debug APIs.
+ @brief Contains all Secure Boot and Secure Debug APIs and definitions.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+ /*!
+ @defgroup cc_sb_image_verifier CryptoCell Secure Boot and Secure Debug API definitions
+ @brief Contains definitions used for the Secure Boot and Secure Debug APIs.
+
+ @{
+ @ingroup cc_sb
+ @}
+ */
+
+ /*!
+ @defgroup cc_sb_basetypes CryptoCell Secure Boot basic type definitions
+ @brief Contains CryptoCell Secure Boot basic type definitions.
+ @{
+ @ingroup cc_sb
+ @}
+ */
+
+/*!
+ @defgroup cc_sbrt CryptoCell Secure Boot certificate-chain-processing APIs.
+ @brief Contains CryptoCell Secure Boot certificate-chain-processing APIs.
+
+ @{
+ @ingroup cc_sb
+ @}
+ */
+
+/*!
+ @defgroup cc_sb_defs CryptoCell Secure Boot type definitions
+ @brief Contains CryptoCell Secure Boot type definitions.
+ @{
+ @ingroup cc_sb
+ @}
+ */
+
+/*!
+ @defgroup cc_sb_gen_defs CryptoCell Secure Boot and Secure Debug definitions and structures
+ @brief Contains CryptoCell Secure Boot and Secure Debug definitions and structures.
+
+ @{
+ @ingroup cc_sb_defs
+ @}
+ */
+
+/*
+  ##############################SRAM MAP APIs###################################
+ */
+/*!
+ @defgroup cc_sram_map CryptoCell SRAM mapping APIs
+ @brief Contains internal SRAM mapping APIs.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+
+/*
+  ################################SRP APIs#####################################
+ */
+/*!
+ @defgroup cc_srp CryptoCell SRP APIs
+ @brief Contains CryptoCell SRP APIs.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+/*!
+ @defgroup cc_srp_errors Specific errors of the CryptoCell SRP APIs
+ @brief Contains the CryptoCell SRP-API error definitions.
+ @{
+ @ingroup cc_srp
+ @}
+ */
+
+
+ /*
+  ################################UTIL APIs####################################
+ */
+/*!
+ @defgroup cc_utils CryptoCell utility APIs
+ @brief This contains all utility APIs.
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+ /*!
+ @defgroup cc_util_asset_prov CryptoCell runtime-library asset-provisioning APIs
+ @brief Contains CryptoCell runtime-library ICV and OEM asset-provisioning APIs
+ and definitions.
+
+ @{
+ @ingroup cc_utils
+ @}
+ */
+
+ /*!
+ @defgroup cc_utils_defs CryptoCell utility APIs general definitions
+ @brief Contains CryptoCell utility APIs general definitions.
+ @{
+ @ingroup cc_utils
+ @}
+ */
+
+ /*!
+ @defgroup cc_utils_key_defs CryptoCell utility general key definitions
+ @brief Contains KDF API definitions.
+ @{
+ @ingroup cc_utils_key_derivation
+ @}
+ */
+
+ /*!
+ @defgroup cc_utils_key_derivation CryptoCell utility key-derivation APIs
+ @brief Contains the CryptoCell utility key-derivation function API.
+
+ @{
+ @ingroup cc_utils
+ @}
+ */
+
+/*!
+ @defgroup cc_utils_errors Specific errors of the CryptoCell utility module APIs
+ @brief Contains utility API error definitions.
+
+ @{
+ @ingroup cc_utils
+ @}
+ */
+
diff --git a/lib/ext/cryptocell-312-runtime/host/Makefile.defs b/lib/ext/cryptocell-312-runtime/host/Makefile.defs
new file mode 100644
index 0000000..83a4ec7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/Makefile.defs
@@ -0,0 +1,327 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile definitions common to all Host components build
+# This file should be included at the start of a Makefile
+
+# Note: The caller (or environment) should provide the following variables:
+# ARCH = Target architectore, e.g., powerpc
+# OS = Target OS, e.g., linux
+# HOST_PROJ_ROOT = The root of the host domain tree (where this file is located)
+
+# LOGFILE = log file name. Default is makelog.txt in the current dir.
+
+### Build platform commands (Currently assumes Linux/Unix/Cygwin machine)
+SHELL = /bin/bash -o pipefail
+RM = rm -f
+ECHO = echo
+MKDIR = mkdir -p
+RMDIR = rm -rf
+CP = cp -P
+CP_DEREF = cp -L
+SYMLINK = ln -s
+MAKE = make
+
+LOGFILE ?= ./makelog.txt
+
+### Build environment setup ###
+
+PWD = $(shell pwd)
+
+ifndef HOST_PROJ_ROOT
+$(error HOST_PROJ_ROOT is undefined)
+endif
+
+# Host domain root converted to absolut path
+HOST_PROJ_ROOT := $(shell cd $(HOST_PROJ_ROOT); pwd)
+HOST_SRCDIR := $(HOST_PROJ_ROOT)/src
+SHARED_DIR := $(HOST_PROJ_ROOT)/../shared
+SHARED_INCDIR := $(SHARED_DIR)/include
+SHARED_SRCDIR := $(SHARED_DIR)/src
+CODESAFE_DIR := $(HOST_PROJ_ROOT)/../codesafe
+CODESAFE_SRCDIR := $(CODESAFE_DIR)/src
+UTILS_DIR := $(HOST_PROJ_ROOT)/../utils
+UTILS_SRCDIR := $(UTILS_DIR)/src
+INCDIRS = ./ $(INCDIRS_EXTRA)
+INCDIRS += $(SHARED_INCDIR) $(SHARED_INCDIR)/proj/$(PROJ_PRD)
+# $(SHARED_INCDIR)/pal $(SHARED_INCDIR)/pal/$(TEE_OS) $(SHARED_INCDIR)/pal/$(TEE_OS)/include
+INCDIRS +=  $(HOST_PROJ_ROOT)/include
+LIBDIRS = ./ $(LIBDIRS_EXTRA) $(HOST_PROJ_ROOT)/lib
+
+HOST_LIBDIR = $(HOST_SRCDIR)/$(HOST_LIBNAME)
+
+# Release directories
+RELEASE_INCDIR = $(HOST_PROJ_ROOT)/include
+RELEASE_LIBDIR = $(HOST_PROJ_ROOT)/lib
+RELEASE_EXEDIR = $(HOST_PROJ_ROOT)/bin
+# SCRDIR for scripts
+RELEASE_SCRDIR = $(HOST_PROJ_ROOT)/bin
+# DATDIR for data/binary files
+RELEASE_DATDIR = $(HOST_PROJ_ROOT)/dat
+
+#Test directories
+ifeq ($(TEE_OS),freertos)
+KERNEL_LIB_DIR  := $(KERNEL_DIR)/lib
+KERNEL_TEST_DIR := $(KERNEL_DIR)/lib/tests
+endif
+
+### Toolchain setup ###
+ARCH_SUPPORTED = powerpc arm arm64 i686 x86 x86_64 x86win
+# i686 or x86_64 - compilation for i686(x86)/x86_64 Linux using native toolchain.
+# x86win - compilation for x86 Windows, using MinGW toolchain.
+
+# default ARCH
+ARCH ?= powerpc
+export ARCH
+#$(info ARCH=$(ARCH))
+
+ifeq ($(filter $(ARCH),$(ARCH_SUPPORTED)),)
+  $(error Unsupported ARCH==$(ARCH))
+endif
+
+#initiate variable to avoid concatinatation at every target level
+CFLAGS =
+
+# The following statements would be executed only if ARCH is one of the supported ones.
+ifeq ($(ARCH),powerpc)
+	CROSS_COMPILE := ppc_4xx-
+	ARCH_ENDIAN = BIG
+	CFLAGS += -isystem /opt/eldk/ppc_4xx/usr/include
+endif
+
+ifeq ($(ARCH),arm)
+	# For android NDK must define -ffreestanding to be able to build with Bionic library, etc.
+	CFLAGS += $(if $(filter arm-linux-androideabi-,$(CROSS_COMPILE)),-ffreestanding)
+	# Same requirement for arm-eabi (bare metal) due to use of RTOS (private) libc implementation
+	CFLAGS += $(if $(filter arm-eabi-,$(CROSS_COMPILE)),-ffreestanding)
+	ARCH_ENDIAN = LITTLE
+    ifeq ($(CROSS_COMPILE),arm-bcm2708hardfp-linux-gnueabi-)
+        # RaspberryPi (ARM11/ARMv6) support
+        $(info Assuming build for RaspberryPi)
+        CFLAGS += -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
+    else ifeq ($(CROSS_COMPILE),arm-none-eabi-)
+        ifeq ($(ARM_CPU), cortex-m33)
+            CFLAGS += -march=armv8-m.main
+            CFLAGS += -mcmse
+            CFLAGS += -DARCH_V8M
+        else
+            # For arm-none-eabi assume cortex-m3
+            ARM_CPU ?= cortex-m3
+            CFLAGS += -mcpu=$(ARM_CPU)
+        endif
+        CFLAGS += -mthumb
+        TEE_OS = no_os
+    else ifeq ($(CROSS_COMPILE),armcc)
+        ARM_CPU ?= cortex-m3
+        CFLAGS += --cpu $(ARM_CPU) --littleend
+        CFLAGS += --thumb
+    else ifeq ($(CROSS_COMPILE),armclang)
+        ifeq ($(ARM_CPU), cortex-m33)
+            CFLAGS += -march=armv8-m.main
+            CFLAGS += -mcmse
+            CFLAGS += -mfpu=none
+            CFLAGS += -DARCH_V8M
+        else
+            ARM_CPU ?= cortex-m3
+            CFLAGS += -mcpu=$(ARM_CPU)
+        endif
+        CFLAGS += --target=arm-arm-none-eabi -mlittle-endian
+        CFLAGS += -mthumb
+        CFLAGS += -DCC_TEE -DDX_PLAT_MPS2_PLUS
+    endif
+    # For arm-eabi- assume a15, otherwise assume a9 (zynq7000)
+    ARM_CPU ?= $(if $(filter arm-eabi-,$(CROSS_COMPILE)),cortex-a15,cortex-a9)
+    ifeq ($(filter arm ,$(CROSS_COMPILE)),$(CROSS_COMPILE))
+        CFLAGS += --cpu $(ARM_CPU) --littleend
+    endif
+    CFLAGS += $(if $(filter arm-eabi-,$(CROSS_COMPILE)),-DARCH_ARM -DARM_CPU_CORTEX_A15=1)
+    # for optee_os
+    ifeq ($(CROSS_COMPILE),arm-linux-gnueabihf-)
+        CFLAGS += -mfloat-abi=soft
+    endif #arm-linux-gnueabihf-
+
+    export CORTEX
+    export ARM_CPU
+endif #arm
+
+ifeq ($(ARCH),arm64)
+	# aarch64-linux-gnu-
+	CROSS_COMPILE := $(if $(filter aarch64-%,$(CROSS_COMPILE)),$(CROSS_COMPILE),aarch64-linux-gnu-)
+	ARCH_ENDIAN = LITTLE
+endif
+
+ifneq ($(filter i686 x86 x86win x86_64,$(ARCH)),) # x86* Arch.
+	ARCH_ENDIAN = LITTLE
+endif
+
+ifeq ($(ARCH),x86win)
+	# Compiling for x86-windows - using MinGW toolchain.
+	CROSS_COMPILE ?= i586-mingw32msvc-
+endif
+
+ifeq ($(filter arm arm-dsm- armcc ,$(CROSS_COMPILE)),$(CROSS_COMPILE))
+CC_DEF = 1
+CC = armcc
+LD = armcc
+AR = armar
+ifneq ($(CROSS_COMPILE),armcc)
+override TEE_OS = no_os
+endif
+endif
+
+ifeq ($(filter armclang ,$(CROSS_COMPILE)),$(CROSS_COMPILE))
+CC_DEF = 1
+CC = armclang
+LD = armlink
+AR = armar
+endif
+
+# subfolder for compilation/generation outcome/objects/binaries
+BUILDDIR = build-$(CROSS_COMPILE:%-=%)
+
+# Object file suffix
+OBJEXT = .o
+
+# Library prefix
+LIBPRE = lib
+
+# In Unix/Linux there is no extension to executables. Set to ".exe" for Windows.
+EXEEXT =
+
+
+ifeq ($(CC_DEF),)
+CC = $(CROSS_COMPILE)gcc
+CPP = $(CROSS_COMPILE)g++
+LD = $(CROSS_COMPILE)gcc
+AR = $(CROSS_COMPILE)ar
+RANLIB = $(CROSS_COMPILE)ranlib
+endif
+
+# Helper variables for complex string definitions
+comma := ,
+
+############
+# Logged execution "function". To be used with make's $(call...).
+# Its "parameter is the command to execute
+# The "function" puts all stdout into LOGFILE. The stderr is output to both terminal and a tmp file, than appends
+# the error to the LOGFILE.
+# This complexity is required because of pipe's nature which prevents appending while piping into the log file.
+ifeq ($(LOGFILE),-)
+	exec_logged = $(1)
+	#exec_logged_evaled = $(1)
+else
+	exec_logged = ( $(ECHO) $(shell date): "$(1)"  >> $(LOGFILE) ; ( $(1) ) >>$(LOGFILE) 2>logerr.tmp ; err=$$? ; cat logerr.tmp ; cat logerr.tmp >> $(LOGFILE) ; rm logerr.tmp ; exit $$err)
+	# nested version is to be $(call)ed from within another $(eval)
+	exec_logged_evaled = ( $(ECHO) $$(shell date): "$(1)"  >> $(LOGFILE) ; ( $(1) ) >>$(LOGFILE) 2>logerr.tmp ; err=$$$$? ; cat logerr.tmp ; cat logerr.tmp >> $(LOGFILE) ; rm logerr.tmp ; exit $$$$err)
+endif
+
+exec_logged_and_echo = $(ECHO) $(1) ; $(exec_logged)
+############
+
+
+# Generate dependency on existence only (i.e., don't care if newer).
+# To be used primarily for directories creation
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)),$(1))
+
+
+################################################
+### Handle project configuration definitions ###
+################################################
+
+PROJ_CFG_FNAME = proj.cfg
+PROJ_EXT_CFG_FNAME = proj.ext.cfg
+PROJ_CFG_PATH = $(HOST_PROJ_ROOT)/$(PROJ_CFG_FNAME)
+PROJ_EXT_CFG_PATH = $(HOST_PROJ_ROOT)/../$(PROJ_EXT_CFG_FNAME)
+CONFIGS_PATH = src/configs
+PROJ_CONFIGS_DIR = $(HOST_PROJ_ROOT)/$(CONFIGS_PATH)
+
+############ Special rules for project configuration selection ##############
+ifneq ($(wildcard $(PROJ_CFG_PATH)),$(PROJ_CFG_PATH)) # No proj.cfg linked
+
+all: # default in case there is no proj.cfg and setconfig_ was not used
+	$(info Invoke 'make setconfig_<config. name>' to select project configuration )
+	$(error 'proj.cfg' not found)
+
+setconfig_%: $(PROJ_CONFIGS_DIR)/proj-%.cfg
+	@$(info [CFG] $(CONFIGS_PATH)/proj-$*.cfg --> proj.cfg)
+	@cd $(HOST_PROJ_ROOT) && ln -s $(CONFIGS_PATH)/proj-$*.cfg $(PROJ_CFG_FNAME)
+	@$(if $(findstring cc312,$<), $(if $(findstring integration_tests,$<),,$(if $(or $(findstring devel,$<), $(findstring llhw,$<)), make -C tests copy_infra_suite,)),)
+
+$(PROJ_CONFIGS_DIR)/proj-%.cfg:
+	@$(error Unknown project configuration. $@ does not exist.)
+
+clrconfig:
+	$(info [CFG-CLN] No active configuration )
+
+.PHONY: all setconfig_% clrconfig
+
+else
+### proj.cfg exists. Include it to get project configuration definitions ###
+
+# The includes order is important here:
+# External configurations in proj.ext.cfg may be overriden by those in host proj.cfg
+include $(PROJ_EXT_CFG_PATH)
+include $(PROJ_CFG_PATH)
+
+# default TEE_OS
+REE_OS ?= linux
+TEE_OS ?= cc_linux
+export REE_OS
+export TEE_OS
+#$(info REE_OS=$(REE_OS))
+#$(info TEE_OS=$(TEE_OS))
+
+#TestAL defs
+TESTAL_PATH_PAL = $(HOST_SRCDIR)/tests/infrastructure_suite/pal/lib
+TESTAL_PATH_HAL = $(HOST_SRCDIR)/tests/infrastructure_suite/hal/lib
+ifeq ($(ARM_CPU),cortex-a9)
+TESTAL_PAL_ARCH = ca9
+endif
+ifeq ($(ARM_CPU),cortex-m3)
+TESTAL_PAL_ARCH = cm3
+endif
+ifeq ($(ARM_CPU),cortex-m33)
+TESTAL_PAL_ARCH = cm33
+endif
+ifeq ($(ARCH),arm64)
+TESTAL_PAL_ARCH = ca72.ca53
+endif
+TESTAL_PAL_OS = $(subst cc_,,$(TEE_OS))
+
+TESTAL_PAL_LIB = *PAL*$(TESTAL_PAL_OS)*$(CROSS_COMPILE)*$(TESTAL_PAL_ARCH)*.a
+TESTAL_HAL_LIB = *HAL*$(TESTAL_PAL_OS)*$(CROSS_COMPILE)*$(TESTAL_PAL_ARCH)*.a
+
+#Tests PAL HAL defs
+TESTS_PAL_LIB_NAME = libtests_pal.a
+TESTS_HAL_LIB_NAME = libtests_hal.a
+
+
+all: default
+
+# setconfig_/clrconfig are available only if $(PROJ_CONFIGS_DIR) exists
+# (i.e., eliminated on release trees)
+ifeq ($(wildcard $(PROJ_CONFIGS_DIR)),$(PROJ_CONFIGS_DIR))
+# Configuration rules
+setconfig_%:
+	$(if $(filter $(CONFIGS_PATH)/proj-$*.cfg,$(shell readlink $(PROJ_CFG_PATH))),$(info $* configuration is already set.),$(error Before changing configuration invoke 'make clrconfig'))
+
+clrconfig:
+	@$(ECHO) [CFG-CLN] X $(shell readlink $(PROJ_CFG_PATH))
+	@rm -f $(PROJ_CFG_PATH)
+	@$(ECHO) PROJ_NAME is $(PROJ_NAME)
+	@$(if $(findstring devel,$(PROJ_NAME)), echo calling clean_infra_suite && make -C tests clean_infra_suite, echo ff$(PROJ_NAME)ff clrconfig )
+endif
+
+endif
+
+# Provide lsconfig to list available configurations
+configs_list = $(foreach cfg_file,$(wildcard $(PROJ_CONFIGS_DIR)/proj-*.cfg),$(patsubst $(PROJ_CONFIGS_DIR)/proj-%.cfg,%,$(cfg_file)))
+lsconfig:
+	@$(info Available project configurations:)
+	@$(foreach cfg_file,$(configs_list),$(info $(cfg_file)))
+
+.PHONY: all setconfig_% clrconfig lsconfig
diff --git a/lib/ext/cryptocell-312-runtime/host/Makefile.freertos b/lib/ext/cryptocell-312-runtime/host/Makefile.freertos
new file mode 100644
index 0000000..0fedc99
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/Makefile.freertos
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+ifeq ($(TEE_OS), freertos)
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS/Source/include
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS-Plus-CLI
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS-Plus-TCP/include
+INCDIRS_EXTRA += $(KERNEL_DIR)/boards/MPS2+
+INCDIRS_EXTRA += $(KERNEL_DIR)/lib/main
+INCDIRS_EXTRA += $(KERNEL_DIR)/InterruptCtrl
+
+COMPILER_TYPE_DIR = $(shell echo $(COMPILER_TYPE) | tr a-z A-Z)
+
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS-Plus-TCP/portable/Compiler/$(COMPILER_TYPE_DIR)
+
+ifeq ($(ARM_CPU), cortex-m33)
+CFLAGS += -DSSE_200
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS/Source/portable/$(COMPILER_TYPE_DIR)/ARM_CM33
+else
+CFLAGS += -DARMCM3
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS/Source/portable/$(COMPILER_TYPE_DIR)/ARM_CM3
+endif
+
+endif
+
diff --git a/lib/ext/cryptocell-312-runtime/host/Makefile.rules b/lib/ext/cryptocell-312-runtime/host/Makefile.rules
new file mode 100644
index 0000000..bc83eb7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/Makefile.rules
@@ -0,0 +1,309 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Make rules common to all Host components build
+# This file should be included at the end of a Makefile
+# (that included Makefile.defs at its beginning)
+
+# Including Makefile should provide (define before including this file):
+# TARGET_LIBS = Target library names (without extention)
+# TARGET_EXES = Target executables (without extention)
+# SOURCES_<target name> = The list of source files to create the binary target (currently assumes C)
+# OBJECTS_EXTRA_<target name> = Additional objects that should be linked but their build is defined outside of Makefile.rules
+# DEPLIBS = Dependency libraries for executable linking
+# PUBLIC_INCLUDES = The list of public include files to export from this module (if a library)
+# TEST_INCLUDES = The list of test include files to export from this module (if a library)
+# PUBLIC_SCRIPTS = List of scripts to be released to /bin
+# PUBLIC_DATA = List of data (binary?) files that should be released (primarily for tests)
+# CFLAGS_EXTRA = Additional compiler flags to append to default flags
+# INCDIRS_EXTRA = Additional include directories in addition to the default (current dir., Host/include, Shared/include)
+# LIBDIRS_EXTRA = Additional library directories in addition to the default
+# HOST_PROJ_ROOT = Relative or absolute path of project's root (trunks' root)
+# DEBUG = Set to '1 to enable debug compilation
+
+# Note: Avoid choosing the same name for a library and an executable
+#Test directories for freertos
+ifeq ($(TEE_OS),freertos)
+KERNEL_LIB_DIR  = $(KERNEL_DIR)/lib
+KERNEL_TEST_DIR = $(KERNEL_DIR)/lib/tests
+endif
+
+### Compilation flags setup ###
+CFLAGS += -c -D$(ARCH_ENDIAN)__ENDIAN -DHASLONGLONG
+CFLAGS += $(foreach incdir,$(INCDIRS),-I$(incdir))
+ARFLAGS = rcs
+MM = -MM
+ifeq ($(CROSS_COMPILE),arm-dsm-)
+CFLAGS += -I/cadtools/arm/arm_realview/RVCT/Data/2.2/349/include/unix -D__ARM_DSM__
+else ifeq ($(CROSS_COMPILE),armcc)
+MM = --mm
+CFLAGS += -D__ARM_DS5__ --diag_error=warning #--strict --strict_warnings
+ARFLAGS = -rcs
+else ifeq ($(CROSS_COMPILE),arm)
+CFLAGS += -D__ARM_DS__ --c99 --strict --strict_warnings
+ARFLAGS = -rcs
+MM = --mm
+else ifeq ($(CROSS_COMPILE),armclang)
+CFLAGS += -Wall
+CFLAGS += -Wsign-compare
+CFLAGS += -Wextra
+CFLAGS += -Wpointer-arith
+CFLAGS += -Wcast-align
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -Wwrite-strings
+CFLAGS += -Wswitch-default
+CFLAGS += -Wunreachable-code
+CFLAGS += -Winit-self
+CFLAGS += -Wmissing-field-initializers
+CFLAGS += -Werror=undef
+CFLAGS += -Werror -Wfatal-errors
+ARFLAGS = -rcs
+else
+CFLAGS += -Wall
+CFLAGS += -Wsign-compare
+CFLAGS += -Wextra
+CFLAGS += -Wpointer-arith
+CFLAGS += -Wcast-align
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -Wwrite-strings
+CFLAGS += -Wswitch-default
+CFLAGS += -Wunreachable-code
+CFLAGS += -Winit-self
+CFLAGS += -Wjump-misses-init
+CFLAGS += -Wlogical-op
+CFLAGS += -Wmissing-field-initializers
+CFLAGS += -Werror=undef
+CFLAGS += -Werror -Wfatal-errors
+#CFLAGS += -finstrument-functions
+endif
+#CFLAGS += -D__STDC_VERSION__=19900L
+
+#ARFLAGS = rcs
+LDFLAGS = $(foreach libdir,$(LIBDIRS),-L$(libdir))
+
+LDFLAGS += -Wl,--start-group
+LDFLAGS += $(foreach lib,$(DEPLIBS),-l$(lib))
+LDFLAGS += -Wl,--end-group
+
+ifeq ($(CROSS_COMPILE),arm-none-eabi-)
+LDFLAGS += -lc -lm -lrdimon
+else
+ifneq ($(filter $(TEE_OS),no_os freertos),$(TEE_OS))
+LDFLAGS += -lpthread
+endif
+endif
+
+ifneq ($(filter $(CROSS_COMPILE),arm-dsm- armcc),$(CROSS_COMPILE))
+LDFLAGS += -Wl,-rpath=.
+endif
+
+# C++ compilation
+CXXFLAGS = $(CFLAGS)
+
+CFLAGS += -D__$(ARCH)__
+
+# Library suffix
+LIB_TYPE ?= static
+ifeq ($(LIB_TYPE),dynamic)
+    ifeq ($(ARCH),x86win)
+        LIBEXT = .dll
+        # -fPIC not needed for x86win.
+    else
+        LIBEXT = .so
+        CFLAGS += -fPIC
+    endif
+else
+    LIBEXT = .a
+endif
+
+DEPLIBS_FILES = $(foreach lib, $(strip $(DEPLIBS)), $(shell find $(LIBDIRS) -name $(LIBPRE)$(lib)$(LIBEXT) 2>/dev/null))
+
+#Optimization defs
+ifeq ($(DEBUG),1)
+    CFLAGS += -O0 -DDEBUG
+    ifeq ($(CROSS_COMPILE),armcc)
+        CFLAGS += -g
+    else
+        ifneq ($(CROSS_COMPILE),$(filter $(CROSS_COMPILE),arm-dsm- arm))
+            CFLAGS += -g3
+	endif
+    endif
+else
+    CFLAGS += -O2
+endif
+
+# Support module specific extra Cflags
+CFLAGS += $(CFLAGS_EXTRA)
+
+### Top level targets ###
+
+default: release test
+
+# Clean only build intermediate files (incl. log file) but leave released target
+clean_intermediate:
+	-$(RMDIR) $(BUILDDIR)
+	-$(RM) $(LOGFILE)
+
+clean: clean_intermediate
+	-$(if $(TARGET_EXES), $(RM) $(foreach exe, $(TARGET_EXES), $(RELEASE_EXEDIR)/$(exe)$(EXEEXT)))
+	-$(if $(TARGET_LIBS),$(RM) $(foreach lib, $(TARGET_LIBS), $(RELEASE_LIBDIR)/$(LIBPRE)$(lib)$(LIBEXT)))
+	-$(if $(PUBLIC_INCLUDES),$(RM) $(foreach inc, $(PUBLIC_INCLUDES), $(RELEASE_INCDIR)/$(notdir $(inc))))
+	-$(if $(subst freertos,,$(TEE_OS)),,$(if $(TEST_INCLUDES),$(RM) $(foreach inc, $(TEST_INCLUDES), $(KERNEL_TEST_DIR)/$(notdir $(inc)))))
+	-$(if $(PUBLIC_SCRIPTS),$(RM) $(foreach scr, $(PUBLIC_SCRIPTS), $(RELEASE_SCRDIR)/$(notdir $(scr))))
+	-$(if $(PUBLIC_DATA),$(RM) $(foreach scr, $(PUBLIC_DATA), $(RELEASE_DATDIR)/$(notdir $(scr))))
+
+.PHONY: default release test clean
+
+# Directory creation rule
+$(PWD)/$(BUILDDIR) $(RELEASE_INCDIR) $(RELEASE_LIBDIR) $(RELEASE_EXEDIR) $(RELEASE_DATDIR):
+	@if [ ! -d $@ ] ; then $(ECHO) [MKDIR] $@ ; fi
+	@if [ ! -d $@ ] ; then $(call exec_logged,$(MKDIR) $@ ) ; fi
+
+# Makefile variable print (for debug)
+PRINT_VAR_%:
+	@$(ECHO) $* = \'$($*)\'
+
+### Generate rules for releasing (non-built resources) files
+define release_file_rule
+$(RELEASE_$(2)DIR)/$(notdir $(1)): $(1) $(call DEPENDENCY_ON_EXISTENCE_OF,$(RELEASE_$(2)DIR))
+	@$(ECHO) [CP] $$< --\> $(RELEASE_$(2)DIR)
+	@$(call exec_logged_evaled,$(CP) $$< $(RELEASE_$(2)DIR) )
+
+release: $(RELEASE_$(2)DIR)/$(notdir $(1))
+
+endef
+
+define test_file_rule
+$(KERNEL_TEST_DIR)/$(notdir $(1)): $(1)
+	@$(ECHO) [CP] $$< --\> $(KERNEL_TEST_DIR)
+	@$(call exec_logged_evaled,$(CP) $$< $(KERNEL_TEST_DIR) )
+
+test: $(KERNEL_TEST_DIR)/$(notdir $(1))
+
+endef
+
+$(foreach hfile, $(PUBLIC_INCLUDES), $(eval $(call release_file_rule,$(hfile),INC)))
+$(if $(subst freertos,,$(TEE_OS)),,$(foreach hfile, $(TEST_INCLUDES), $(eval $(call test_file_rule,$(hfile),INC))))
+$(foreach scrfile, $(PUBLIC_SCRIPTS), $(eval $(call release_file_rule,$(scrfile),SCR)))
+$(foreach datfile, $(PUBLIC_DATA), $(eval $(call release_file_rule,$(datfile),DAT)))
+
+### LIB+EXE targets rules ###
+release: $(TARGET_LIBS) $(TARGET_EXES)
+
+# Generic rule for LIB+EXE targets
+# Usage: $(eval $(call RELEASE_RULE, <target_name>, [LIB|EXE]))
+define RELEASE_RULE
+# Map named target to target with extension at release dir
+$(1): $(RELEASE_$(2)DIR)/$($(2)PRE)$(1)$($(2)EXT)
+
+.PHONY: $(1)
+
+# Objects list for dependency generation
+C_SOURCES_$(1) = $$(filter %.c,$$(SOURCES_$(1)))
+CPP_SOURCES_$(1) = $$(filter %.cpp,$$(SOURCES_$(1)))
+OBJECTS_FROM_C_$(1) = $$(addprefix $(BUILDDIR)/,$$(patsubst %.c,%$(OBJEXT),$$(filter-out $(BUILDDIR)/%,$$(C_SOURCES_$(1)))))
+OBJECTS_FROM_GENERATED_C_$(1) = $$(patsubst %.c,%$(OBJEXT),$$(filter $(BUILDDIR)/%,$$(C_SOURCES_$(1))))
+OBJECTS_FROM_CPP_$(1) = $$(addprefix $(BUILDDIR)/,$$(patsubst %.cpp,%$(OBJEXT),$$(CPP_SOURCES_$(1))))
+OBJECTS_INTERNAL_$(1) = $$(OBJECTS_FROM_C_$(1)) $$(OBJECTS_FROM_GENERATED_C_$(1)) $$(OBJECTS_FROM_CPP_$(1))
+OBJECTS_$(1) =  $$(OBJECTS_INTERNAL_$(1)) $$(OBJECTS_EXTRA_$(1))
+OBJECTS_FROM_C += $$(OBJECTS_FROM_C_$(1))
+OBJECTS_FROM_GENERATED_C += $$(OBJECTS_FROM_GENERATED_C_$(1))
+OBJECTS_FROM_CPP += $$(OBJECTS_FROM_CPP_$(1))
+
+# Retain generated dependency files after a build
+.SECONDARY: $$(OBJECTS_$(1):%.o=%.dep)
+
+endef
+
+# Generate library targets rules
+$(foreach lib,$(TARGET_LIBS), $(eval $(call RELEASE_RULE,$(lib),LIB)))
+#include generated depedencies
+$(foreach lib,$(TARGET_LIBS), $(eval -include $(OBJECTS_INTERNAL_$(lib):%.o=%.dep)))
+
+
+TEST_COPY_RULE = $(if $(PROJ_TESTS),$(call exec_logged,$(CP) $(RELEASE_LIBDIR)/$(1) $(KERNEL_TEST_DIR)/$(1)),)
+LIB_COPY_RULE = $(if $(PROJ_TESTS),$(call exec_logged,$(CP) $(RELEASE_LIBDIR)/$(1) $(KERNEL_LIB_DIR)/$(1)),)
+TEST_ECHO_RULE = $(ECHO) [CP] $(RELEASE_LIBDIR)/$(1) $< --\> $(KERNEL_TEST_DIR)/$(1)
+LIB_ECHO_RULE = $(ECHO) [CP] $(RELEASE_LIBDIR)/$(1) $< --\> $(KERNEL_LIB_DIR)/$(1)
+IS_TEST = $(findstring test, $(1))
+
+# Implicit rule for libraries releasing
+$(RELEASE_LIBDIR)/$(LIBPRE)%$(LIBEXT): $(BUILDDIR)/$(LIBPRE)%$(LIBEXT) $(call DEPENDENCY_ON_EXISTENCE_OF,$(RELEASE_LIBDIR))
+	@$(ECHO) [CP] $< --\> $(RELEASE_LIBDIR)
+	@$(call exec_logged,$(CP) $< $(RELEASE_LIBDIR) )
+	@$(if $(subst freertos,,$(TEE_OS)),, $(if $(call IS_TEST,$(notdir $<)), $(call TEST_ECHO_RULE,$(notdir $<)), $(call LIB_ECHO_RULE,$(notdir $<)) ))
+	@$(if $(subst freertos,,$(TEE_OS)),, $(if $(call IS_TEST,$(notdir $<)), $(call TEST_COPY_RULE,$(notdir $<)), $(call LIB_COPY_RULE,$(notdir $<)) ))
+	@$(if $(subst freertos,,$(TEE_OS)),, $(foreach lib, $(DEPLIBS), $(ECHO) [CP] $(RELEASE_LIBDIR)/lib$(lib).a --\> $(KERNEL_LIB_DIR)/ ;))
+	@$(if $(subst freertos,,$(TEE_OS)),, $(foreach lib, $(DEPLIBS), $(CP) $(RELEASE_LIBDIR)/lib$(lib).a $(KERNEL_LIB_DIR)/ ;))
+
+ifeq ($(LIB_TYPE),dynamic)
+define LIB_LINK_RULE
+$(BUILDDIR)/$(LIBPRE)$(1)$(LIBEXT): $(OBJECTS_$(1))
+	@$(if $(SOURCES_$(1)), , echo Makefile is missing SOURCES_$(1) definition && exit 1)
+	@$(ECHO) [LD] $$^ --\> $$@ # Dynamic library linkage
+	@$(call exec_logged_evaled,$(CC) -shared -o $$@ $$^ )
+endef
+
+else # Static library
+define LIB_LINK_RULE
+$(BUILDDIR)/$(LIBPRE)$(1)$(LIBEXT): $(OBJECTS_$(1))
+	@$(if $(SOURCES_$(1)), , echo Makefile is missing SOURCES_$(1) definition && exit 1)
+	@$(ECHO) [AR] $$^ --\> $$@ # Library archive linkage
+	@$(call exec_logged_evaled,$(AR) $(ARFLAGS) $$@ $$^ )
+endef
+endif
+
+$(foreach lib,$(TARGET_LIBS), $(eval $(call LIB_LINK_RULE,$(lib))))
+
+
+# Generate executable targets rules
+$(foreach exe,$(TARGET_EXES), $(eval $(call RELEASE_RULE,$(exe),EXE)))
+#include generated depedencies
+$(foreach exe,$(TARGET_EXES), $(eval -include $(OBJECTS_INTERNAL_$(exe):%.o=%.dep)))
+# Implicit rule for executables releasing
+$(RELEASE_EXEDIR)/%$(EXEEXT): $(BUILDDIR)/%$(EXEEXT) $(call DEPENDENCY_ON_EXISTENCE_OF,$(RELEASE_EXEDIR))
+	@$(ECHO) [CP] $< --\> $(RELEASE_EXEDIR)
+	@$(call exec_logged,$(CP) $< $(RELEASE_EXEDIR) )
+
+define EXE_LINK_RULE
+$(BUILDDIR)/$(1)$(EXEEXT): $(OBJECTS_$(1)) $(DEPLIBS_FILES)
+	@$(if $(SOURCES_$(1)), , echo Makefile is missing SOURCES_$(1) definition && exit 1)
+	@$(ECHO) [LD] $$^ --\> $$@  # Executable linkage
+	@$(call exec_logged_evaled,$(LD) $$(filter-out %$(LIBEXT),$$^) $(LDFLAGS) -o $$@ )
+endef
+$(foreach exe,$(TARGET_EXES), $(eval $(call EXE_LINK_RULE,$(exe))))
+
+ifneq ($(OBJECTS_FROM_C),)
+# Default implicit compile rule assuming C source code (+dependency generation)
+$(OBJECTS_FROM_C): $(BUILDDIR)/%$(OBJEXT): %.c $(call DEPENDENCY_ON_EXISTENCE_OF,$(PWD)/$(BUILDDIR))
+	@$(ECHO) [CC] $< --\> $@  # Compilation
+	@$(call exec_logged,$(CC) $(CFLAGS) $< -o $@ )
+	@#$(ECHO) [MM] $(@:.o=.dep) \<-- $@   # Generate dependency of object when generated
+	@$(call exec_logged,$(CC) $(MM) $(CFLAGS) $< | sed 's/.*\.o:/$(BUILDDIR)\/&/' > $(BUILDDIR)/$*.dep )
+
+#	$(call exec_logged,$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; [ -s $@ ] || rm -f $@' )
+endif
+
+ifneq ($(OBJECTS_FROM_CPP),)
+# Default implicit compile rule assuming C++ source code (+dependency generation)
+$(OBJECTS_FROM_CPP): $(BUILDDIR)/%$(OBJEXT): %.cpp $(call DEPENDENCY_ON_EXISTENCE_OF,$(PWD)/$(BUILDDIR))
+	@$(ECHO) [CPP] $< --\> $@  # Compilation
+	@$(call exec_logged,$(CPP) $(CPPFLAGS) $< -o $@ )
+	@#$(ECHO) [MM] $(@:.o=.dep) \<-- $@   # Generate dependency of object when generated
+	@$(call exec_logged,$(CP) -MM $(CPPFLAGS) $< | sed 's/.*\.o:/$(BUILDDIR)\/&/' > $(BUILDDIR)/$*.dep )
+endif
+
+ifneq ($(OBJECTS_FROM_GENERATED_C),)
+# Default implicit compile rule assuming generated C stub source code (+dependency generation)
+$(OBJECTS_FROM_GENERATED_C): $(BUILDDIR)/%$(OBJEXT): $(PWD)/$(BUILDDIR)/%.c
+	@$(ECHO) [CC4GEN] $< --\> $@  # Compilation
+	@$(call exec_logged,$(CC) $(CFLAGS) $< -o $@ )
+	@#$(ECHO) [MM] $(@:.o=.dep) \<-- $@   # Generate dependency of object when generated
+	@$(call exec_logged,$(CC) -MM $(CFLAGS) $< | sed 's/.*\.o:/$(BUILDDIR)\/&/' > $(BUILDDIR)/$*.dep )
+endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/Makefile.test_suite b/lib/ext/cryptocell-312-runtime/host/Makefile.test_suite
new file mode 100644
index 0000000..bfd515b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/Makefile.test_suite
@@ -0,0 +1,76 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# designed to be used by any test in host/src/test that wishes to use the test pal layer.
+$(info adding test suite pal of board[${TEST_BOARD}] product[${TEST_PRODUCT}] no_pal[${NO_PAL}])
+
+################ Proj defines
+
+ifneq ($(findstring cc312,$(PROJ_NAME)),)
+TEST_PROJ_NAME = cc3x
+TEST_PROJ_SPEC_NAME = cc312_r1
+TEST_PROJ_SOURCES_BASIC = test_proj.c
+TEST_PROJ_SOURCES_BASIC += test_proj_map.c
+TEST_PROJ_SOURCES_BASIC += test_proj_hw.c
+TEST_PROJ_SOURCES += test_proj_otp.c
+TEST_PROJ_SOURCES += test_proj_otp_data.c
+TEST_PROJ_SOURCES += $(TEST_PROJ_SOURCES_BASIC)
+PROJ_VPATH = $(HOST_PROJ_ROOT)/src/tests/proj
+PROJ_VPATH += $(HOST_PROJ_ROOT)/src/tests/proj/$(TEST_PROJ_NAME)
+PROJ_VPATH += $(HOST_PROJ_ROOT)/src/tests/proj/$(TEST_PROJ_NAME)/$(TEST_PROJ_SPEC_NAME)
+TEST_PROJ_INCLUDE = $(HOST_PROJ_ROOT)/src/tests/proj/$(TEST_PROJ_NAME)
+TEST_PROJ_INCLUDE += $(HOST_PROJ_ROOT)/src/tests/proj/$(TEST_PROJ_NAME)/$(TEST_PROJ_SPEC_NAME)
+TEST_PROJ_INCLUDE += $(HOST_PROJ_ROOT)/src/tests/proj
+TEST_PROJ_INCLUDE += $(SHARED_INCDIR)/include/proj/$(TEST_PROJ_NAME)
+ifeq (,$(findstring sbrom, $(PROJ_NAME)))
+ifeq (,$(findstring llhw, $(PROJ_NAME)))
+ifeq (,$(findstring freertos, $(PROJ_NAME)))
+TEST_CCLIB_SOURCES += test_proj_cclib.c
+TEST_CCLIB_INCLUDE += $(SHARED_INCDIR)/crypto_api
+TEST_CCLIB_INCLUDE += $(SHARED_INCDIR)/crypto_api/cc3x
+TEST_CCLIB_INCLUDE += $(HOST_PROJ_ROOT)/src/cc3x_lib
+endif
+endif
+endif
+PROJ_SOURCES = $(TEST_PROJ_SOURCES) $(TEST_CCLIB_SOURCES)
+PROJ_INCLUDE = $(TEST_PROJ_INCLUDE) $(TEST_CCLIB_INCLUDE)
+endif
+
+################ Test helper defines
+TESTS_HELPER_INCLUDE = $(HOST_SRCDIR)/tests/tests_helper
+TESTS_HELPER_VPATH = $(HOST_SRCDIR)/tests/tests_helper
+TESTS_HELPER_SOURCES = tests_file.c
+TESTS_HELPER_SOURCES += tests_memory.c
+
+################ TestAL defines
+
+PAL_OS = $(subst cc_,,$(TEE_OS))
+$(info TEE_OS[${TEE_OS}]  PAL_OS[${PAL_OS}])
+
+TEST_AL_INCLUDE = $(SHARED_DIR)/hw/include
+TEST_AL_INCLUDE += $(SHARED_INCDIR)/pal
+TEST_AL_INCLUDE += $(SHARED_INCDIR)/pal/$(PAL_OS)
+TEST_AL_INCLUDE += $(SHARED_INCDIR)/pal/$(PAL_OS)/include
+
+ifneq ($(NO_PAL),1)
+TEST_AL_INCLUDE += $(HOST_LIBDIR)
+TEST_AL_INCLUDE += $(HOST_SRCDIR)/hal
+TEST_AL_INCLUDE += $(HOST_SRCDIR)/hal/$(TEST_PRODUCT)
+TEST_AL_INCLUDE += $(HOST_SRCDIR)/tests/infrastructure_suite/pal/include
+TEST_AL_INCLUDE += $(HOST_SRCDIR)/tests/infrastructure_suite/hal/include
+TEST_AL_INCLUDE += $(HOST_SRCDIR)/tests/TestAL/pal/include
+TEST_AL_INCLUDE += $(HOST_SRCDIR)/tests/TestAL/hal/include
+
+TEST_AL_LIBS = tests_pal
+TEST_AL_LIBS += tests_hal
+TEST_AL_LITE_LIBS = tests_pal_lite
+TEST_AL_LITE_LIBS += tests_hal_lite
+endif
+
+################ ATIS defines
+ATIS_INCLUDE = $(HOST_PROJ_ROOT)/src/tests/atis
+ATIS_LIB = atis
diff --git a/lib/ext/cryptocell-312-runtime/host/proj.cfg b/lib/ext/cryptocell-312-runtime/host/proj.cfg
new file mode 100644
index 0000000..8261db8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/proj.cfg
@@ -0,0 +1,71 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Project configuration for cc312 generic (development) host project
+PROJ_NAME = cc312
+TARGET_DIR = cc3x
+PROJ_PRD = cc3x
+HOST_LIBNAME = cc3x_lib
+
+ifeq ($(filter armclang armcc ,$(CROSS_COMPILE)),$(CROSS_COMPILE))
+TEE_OS = freertos
+TEST_BOARD = mps2+
+CFLAGS_EXTRA += -DDX_PLAT_MPS2_PLUS
+CFLAGS_EXTRA += -DMBEDTLS_CONFIG_FILE='<config-cc312-mps2-freertos.h>'
+endif
+
+ifeq ($(CROSS_COMPILE),arm-none-eabi-)
+TEE_OS = freertos
+TEST_BOARD = mps2+
+CFLAGS_EXTRA += -DDX_PLAT_MPS2_PLUS
+CFLAGS_EXTRA += -DMBEDTLS_CONFIG_FILE='<config-cc312-mps2-freertos.h>'
+endif
+
+
+TEE_OS ?= linux
+TEST_BOARD ?= zynq
+
+ifeq ($(TEE_OS),linux)
+CFLAGS_EXTRA += -DMBEDTLS_CONFIG_FILE='<config-cc312.h>'
+endif
+
+# Associated device indentification info.
+CC_HW_VERSION = 0xFF
+CC_TEE_HW_INC_DIR = hw/include
+
+# max buffer size for DLLI
+DLLI_MAX_BUFF_SIZE = 0x10000
+
+# List of targets to build for host/src
+PROJ_TARGETS += cc3x_lib cc3x_productionlib pal
+
+# Specific project definitions
+
+CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES =  8192
+CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES = 512
+
+# If the following flag = 1, then use specific ECC functions
+# with SCA protection on program level (different from HW level)
+CC_CONFIG_SUPPORT_ECC_SCA_SW_PROTECT = 0
+
+# Low level driver support
+FW_ENABLE_AES_DRIVER = 1
+
+# Specific project definitions for sbromlib
+CC_CONFIG_SB_INDIRECT_SRAM_ACCESS      = 1
+CC_CONFIG_SB_CERT_VERSION_MAJOR        = 1
+CC_CONFIG_SB_CERT_VERSION_MINOR        = 0
+CC_CONFIG_SB_CC3X		       = 1
+
+CFLAGS_EXTRA += -DCC_SRAM_INDIRECT_ACCESS
+
+
+
+CFLAGS_EXTRA += -DUSE_MBEDTLS_CRYPTOCELL
+
+
+TEST_PRODUCT = cc3x
diff --git a/lib/ext/cryptocell-312-runtime/host/src/Makefile b/lib/ext/cryptocell-312-runtime/host/src/Makefile
new file mode 100644
index 0000000..923397e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/Makefile
@@ -0,0 +1,208 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# "Root" Makefile for Host domain
+# This makefile invokes the relevant target specific makefile to build it (e.g., cclib)
+
+HOST_PROJ_ROOT ?= $(shell pwd)/..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+
+# List of known modules in host and shared domains
+ifeq ($(PROJ_PRD), softcrys)
+HOST_COMPONENTS = softcrys
+HOST_COMPONENTS += tests
+else
+HOST_COMPONENTS = cc_driver/$(CC_TYPE)/$(REE_OS) moc_ipsec/$(REE_OS) cc_ll_test
+HOST_COMPONENTS += tests sblib cc7x_sbromlib cc7x_sbromx509lib cc3x_sbromlib cc3x_lib cc3x_productionlib teelib cc7x_teelib tztrng_lib
+APPS = cmpu dmpu
+endif
+HOST_COMPONENTS += $(foreach app,$(APPS),apps/$(app))
+ifneq ($(filter $(CROSS_COMPILE),arm-dsm- armcc),$(CROSS_COMPILE))
+SHARED_COMPONENTS += libtom gmssl
+endif
+
+
+ifneq ($(PROJ_NAME),) # proj.cfg found
+
+ifneq ($(PLATFORM_IS_ANDROID),1)
+default: release
+
+$(info PROJ_NAME=$(PROJ_NAME))
+release: $(foreach target,$(PROJ_TARGETS),release_$(target))
+
+# Generic release rules recipes
+$(foreach module,$(filter-out cc_driver/public/linux ,$(HOST_COMPONENTS)),release_$(module)): release_%:
+	@$(ECHO) [REL] $*
+	@$(MAKE) -C $*
+
+# Exception for cc_driver/public/linux : requires Makefile.setup
+release_cc_driver/public/linux: release_%:
+	@$(ECHO) [REL] $*
+	@$(MAKE) -C $* -f Makefile.setup
+
+# Exception for host/src/pal/linux64/driver
+release_pal/linux64/driver: release_%:
+	@$(ECHO) [REL] $*
+	@$(MAKE) -C $* -f Makefile.setup
+
+# Similar recipes for shared components
+$(foreach module,$(SHARED_COMPONENTS),release_$(module)): release_%:
+	@$(ECHO) [REL] $*
+	@$(MAKE) -C $(SHARED_SRCDIR)/$* -f Makefile.host
+
+
+# Dependencies for known targets
+release_cclib: $(if $(filter $(PROJ_TARGETS),cc_driver/$(CC_TYPE)/$(REE_OS)),release_cc_driver/$(CC_TYPE)/$(REE_OS))
+
+#else
+
+# Similar recipes for shared components
+#$(foreach module,$(SHARED_COMPONENTS),release_$(module)): release_%:
+#	@$(ECHO)  [REL SHARED_COMP AND]  $*
+#	@$(MAKE) -C $(SHARED_SRCDIR)/$* -f Makefile.host
+
+
+# Tests dependencies (depends on PROJ_TARGETS)
+ifneq ($(filter $(CROSS_COMPILE),arm-dsm- armcc),$(CROSS_COMPILE))
+release_tests: release_libtom release_gmssl $(if $(NO_PAL_COMPILATION), , release_pal)
+endif
+
+else #($(PLATFORM_IS_ANDROID),1)
+default: release_tests
+	@export NDK_MODULE_PATH=$(PWD)/.. ; $(ANDROID_NDK_PATH)/ndk-build NDK_PROJECT_PATH=$(PWD) APP_BUILD_SCRIPT=$(PWD)/Android.mk APP_ABI=$(CC_NDK_APP_ABI)
+
+# Similar recipes for shared components
+$(foreach module,$(SHARED_COMPONENTS),release_$(module)): release_%:
+	@$(ECHO) [REL] $*
+	@$(MAKE) -C $(SHARED_SRCDIR)/$* -f Makefile.host
+
+release_tests: $(if $(PROJ_TESTS),release_libtom $(if $(NO_PAL_COMPILATION), , release_pal),)
+
+endif #($(PLATFORM_IS_ANDROID),1)
+
+ifneq ($(PLATFORM_IS_ANDROID),1)
+# Target installation rules
+# Default location of NFS root for target
+TARGET_ROOT ?= ~/work/nfsroot
+# Default location of work area on target
+TARGET_WORK_DIR ?= $(TARGET_DIR)
+target_install: $(if $(filter $(PROJ_TESTS),tee4sos),install_driver)
+target_install: $(if $(filter pal/linux64/driver cc_driver/$(CC_TYPE)/$(REE_OS),$(PROJ_TARGETS)),install_driver) $(call DEPENDENCY_ON_EXISTENCE_OF,$(TARGET_ROOT)/$(TARGET_WORK_DIR)/dat)
+	@$(if $(wildcard $(RELEASE_EXEDIR)/*),$(ECHO) [CP] $(foreach fl,$(wildcard $(RELEASE_EXEDIR)/*),$(notdir $(fl))) --\> $(TARGET_ROOT)/$(TARGET_WORK_DIR)/)
+	@$(if $(wildcard $(RELEASE_EXEDIR)/*),$(CP) $(RELEASE_EXEDIR)/* $(TARGET_ROOT)/$(TARGET_WORK_DIR)/)
+	@$(if $(wildcard $(RELEASE_LIBDIR)/*.so),$(ECHO) [CP] $(foreach fl,$(wildcard $(RELEASE_LIBDIR)/*.so),$(notdir $(fl))) --\> $(TARGET_ROOT)/$(TARGET_WORK_DIR)/)
+	@$(if $(wildcard $(RELEASE_LIBDIR)/*.so),$(CP) $(RELEASE_LIBDIR)/*.so $(TARGET_ROOT)/$(TARGET_WORK_DIR)/)
+	@$(if $(wildcard $(RELEASE_DATDIR)/*),$(ECHO) [CP] $(foreach fl,$(wildcard $(RELEASE_DATDIR)/*),$(notdir $(fl))) --\> $(TARGET_ROOT)/$(TARGET_WORK_DIR)/dat/)
+	@$(if $(wildcard $(RELEASE_DATDIR)/*),$(CP) $(RELEASE_DATDIR)/* $(TARGET_ROOT)/$(TARGET_WORK_DIR)/dat/)
+
+$(TARGET_ROOT)/$(TARGET_WORK_DIR)/dat:
+	$(MKDIR) $@
+
+# Driver release rules are special due to modules location
+MODULES_DIRS = $(notdir $(wildcard $(RELEASE_LIBDIR)/modules/*))
+TARGET_MODULES_DIR = $(foreach moddir,$(MODULES_DIRS),$(TARGET_ROOT)/lib/modules/$(moddir))
+RELEASE_FW_DIR = $(RELEASE_LIBDIR)/firmware
+TARGET_FW_DIR = $(TARGET_ROOT)/lib/firmware
+
+ifeq ($(PROJ_PRD),cc3x)
+release_pal: release_%
+	@$(ECHO) [REL] PAL TEE_OS[$(TEE_OS)]
+	@$(MAKE) -C pal
+else
+release_pal:
+	@$(ECHO)
+endif
+
+install_driver:  $(MODULES_DIRS:%=install_driver_%) install_fw
+
+$(MODULES_DIRS:%=install_driver_%): install_driver_%: $(call DEPENDENCY_ON_EXISTENCE_OF,$(TARGET_ROOT)/lib/modules/%)
+	@$(if $(shell ls $(RELEASE_LIBDIR)/modules/$*/),$(ECHO) [CP] $(foreach fl,$(shell ls $(RELEASE_LIBDIR)/modules/$*/),$*/$(fl)) --\> $(TARGET_ROOT)/lib/modules/$*/ )
+	@$(if $(shell ls $(RELEASE_LIBDIR)/modules/$*/),$(CP) $(foreach fl,$(shell ls $(RELEASE_LIBDIR)/modules/$*/),$(RELEASE_LIBDIR)/modules/$*/$(fl)) $(TARGET_ROOT)/lib/modules/$*/ )
+
+install_fw: $(call DEPENDENCY_ON_EXISTENCE_OF,$(TARGET_FW_DIR))
+	@$(if $(wildcard $(RELEASE_FW_DIR)/*),$(ECHO) [CP] $(foreach fl,$(wildcard $(RELEASE_FW_DIR)/*),$(notdir $(fl))) --\> $(TARGET_FW_DIR)/ )
+	@$(if $(wildcard $(RELEASE_FW_DIR)/*),$(CP) $(wildcard $(RELEASE_FW_DIR)/*) $(TARGET_FW_DIR)/)
+
+
+$(TARGET_MODULES_DIR) $(TARGET_FW_DIR):
+	@$(ECHO) [MKDIR] $@
+	@$(call exec_logged,$(MKDIR) $@ )
+
+else #($(PLATFORM_IS_ANDROID),1)
+target_install:
+	@export NDK_MODULE_PATH=$(PWD)/.. ; $(ANDROID_NDK_PATH)/ndk-build NDK_PROJECT_PATH=$(PWD) APP_BUILD_SCRIPT=$(PWD)/Android.mk APP_ABI=$(CC_NDK_APP_ABI) target_install
+
+endif #($(PLATFORM_IS_ANDROID),1)
+
+.PHONY: all target_install install_driver install_driver_% install_fw release_% clean_%
+
+endif # proj.cfg exists
+###########################################
+
+### Common rules (with or without proj.cfg) ###
+
+ifneq ($(PLATFORM_IS_ANDROID),1)
+# "clean" target only cleans host component
+# (shared components are "quasi-static" external components that we do not wish
+# to re-build each time. Use distclean for deeper clean which includes shared
+# components
+clean:	$(foreach target,$(PROJ_TARGETS),clean_$(target))
+
+
+# Clean only intermediate build files (leave released files)
+clean_intermediate: $(foreach target,$(PROJ_TARGETS),clean_intermediate_$(target))
+
+clean_shared: $(foreach target,$(SHARED_COMPONENTS),$(if $(wildcard $(SHARED_SRCDIR)/$(target)),clean_$(target)))
+
+$(foreach module,$(filter-out cc_driver/public/linux,$(HOST_COMPONENTS)),clean_$(module)): clean_%:
+	@$(ECHO) [CLN] $*
+	@$(MAKE) -s -C $* clean
+
+$(foreach module,$(filter-out cc_driver/public/linux,$(HOST_COMPONENTS)),clean_intermediate_$(module)): clean_intermediate_%:
+	@$(ECHO) [CLN-INT] $*
+	@$(MAKE) -s -C $* clean_intermediate
+
+# Exception for cc_driver/public/linux : requires Makefile.setup
+clean_cc_driver/public/linux: clean_%:
+	@$(ECHO) [CLN] $*
+	@$(MAKE) -s -C $* -f Makefile.setup clean
+
+# cleaning host/src/pal/linux64/driver
+clean_pal/linux64/driver: clean_%:
+	@$(ECHO) [CLN] $*
+	@$(MAKE) -s -C $* -f Makefile.setup clean
+
+# cleaning host/src/pal
+clean_pal:
+	@$(ECHO) [CLN] PAL
+	@$(MAKE) -s -C pal clean
+
+clean_intermediate_cc_driver/public/linux: clean_intermediate_%:
+	@$(ECHO) [CLN-INT] $*
+	@$(MAKE) -s -C $* -f Makefile.setup clean_intermediate
+
+$(foreach module,$(SHARED_COMPONENTS),clean_$(module)): clean_%:
+	@$(ECHO) [CLN] $*
+	@$(MAKE) -s -C $(SHARED_SRCDIR)/$* -f Makefile.host clean
+
+distclean: clean clean_shared clrconfig
+	@$(ECHO) [REL-CLN] $(RELEASE_EXEDIR)
+	@$(RMDIR) $(RELEASE_EXEDIR)
+	@$(ECHO) [REL-CLN] $(RELEASE_LIBDIR)
+	@$(RMDIR) $(RELEASE_LIBDIR)
+	@$(ECHO) [REL-CLN] $(RELEASE_INCDIR)
+	@$(RMDIR) $(RELEASE_INCDIR)
+	@$(ECHO) [REL-CLN] $(RELEASE_DATDIR)
+	@$(RMDIR) $(RELEASE_DATDIR)
+	-@$(RMDIR) tests/*/proj_integration_tests.cfg
+
+else #($(PLATFORM_IS_ANDROID),1)
+clean distclean:
+	@export NDK_MODULE_PATH=$(PWD)/.. ; $(ANDROID_NDK_PATH)/ndk-build NDK_PROJECT_PATH=$(PWD) APP_BUILD_SCRIPT=$(PWD)/Android.mk APP_ABI=$(CC_NDK_APP_ABI) $@
+endif #($(PLATFORM_IS_ANDROID),1)
+
+.PHONY: clean clean_intermediate clean_% distclean
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/Makefile b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/Makefile
new file mode 100755
index 0000000..10c9d3e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/Makefile
@@ -0,0 +1,330 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+
+API_DIR = $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/api
+DRV_DIR = $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/driver
+MBEDTLS_ALT_DIR = $(CODESAFE_SRCDIR)/mbedtls_api
+MBEDTLS_ALT_API = $(SHARED_INCDIR)/mbedtls
+MBEDTLS_ALT_API_TESTS = $(SHARED_SRCDIR)/mbedtls/tests
+MBEDTLS_ROOT = $(HOST_SRCDIR)/../../mbedtls
+SOFTCRYS_API = $(HOST_SRCDIR)/softcrys/softcrys_api
+CC_API = $(SHARED_INCDIR)/crypto_api
+CC_API_3x = $(SHARED_INCDIR)/crypto_api/$(PROJ_PRD)
+MANAGEMENT_API = $(HOST_SRCDIR)/cc_mng
+MANAGEMENT_INCLUDES = $(SHARED_INCDIR)/cc_mng
+UTILS_API = $(HOST_SRCDIR)/utils
+SBROM_DIR = $(CODESAFE_SRCDIR)/secure_boot_debug
+
+#TESTS_COMMON_API = $(HOST_SRCDIR)/tests/common
+
+
+TARGET_LIBS = cc_312
+
+ifeq ($(PKA_DEBUG),1)
+CFLAGS_EXTRA += -DPKA_DEBUG
+endif
+
+
+
+PUBLIC_INCLUDES += $(CC_API_3x)/cc_aes_defs_proj.h
+PUBLIC_INCLUDES += $(CODESAFE_SRCDIR)/mbedtls_api/mbedtls_ccm_common.h $(CC_API)/cc_ecpki_types.h $(CC_API_3x)/cc_pka_defs_hw.h
+PUBLIC_INCLUDES += $(CC_API)/cc_kdf.h $(CC_API)/cc_hash_defs.h# not to document
+PUBLIC_INCLUDES += $(CC_API)/cc_error.h $(CC_API)/cc_aes_defs.h
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_cc_sha512_t.h
+PUBLIC_INCLUDES += $(CC_API_3x)/cc_rnd_common.h
+
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_cc_ecies.h
+PUBLIC_INCLUDES += $(HOST_LIBDIR)/cc_lib.h $(HOST_LIBDIR)/mbedtls_cc_sbrt.h $(HOST_LIBDIR)/mbedtls_cc_util_asset_prov.h
+PUBLIC_INCLUDES += $(CC_API)/$(PROJ_PRD)/cc_hash_defs_proj.h
+PUBLIC_INCLUDES += $(MBEDTLS_ALT_API)/sha1_alt.h $(MBEDTLS_ALT_API)/sha256_alt.h $(MBEDTLS_ALT_API)/aes_alt.h
+PUBLIC_INCLUDES += $(MBEDTLS_ALT_API)/ccm_alt.h $(MBEDTLS_ALT_API)/gcm_alt.h $(MBEDTLS_ALT_API)/rsa_alt.h
+PUBLIC_INCLUDES += $(MBEDTLS_ALT_API)/config-cc312.h $(MBEDTLS_ALT_API)/config-cc312-mps2-freertos.h $(MBEDTLS_ALT_API)/config-cc312-mps2-no-os.h
+PUBLIC_INCLUDES += $(MBEDTLS_ALT_API)/cmac_alt.h $(MBEDTLS_ALT_API)/dhm_alt.h $(MBEDTLS_ALT_API)/chacha20_alt.h $(MBEDTLS_ALT_API)/poly1305_alt.h $(MBEDTLS_ALT_API)/chachapoly_alt.h
+PUBLIC_INCLUDES += $(MBEDTLS_ALT_API)/cc_ecc_internal.h $(CC_API_3x)/mbedtls_cc_ecdsa_edwards.h $(CC_API_3x)/mbedtls_cc_ecdh_edwards.h
+
+PUBLIC_INCLUDES += $(MANAGEMENT_INCLUDES)/mbedtls_cc_mng.h $(MANAGEMENT_INCLUDES)/mbedtls_cc_mng_error.h
+PUBLIC_INCLUDES += $(SHARED_INCDIR)/cc_util/mbedtls_cc_util_key_derivation.h $(SHARED_INCDIR)/cc_util/mbedtls_cc_util_key_derivation_defs.h $(SHARED_INCDIR)/cc_util/mbedtls_cc_util_defs.h
+PUBLIC_INCLUDES += $(SHARED_INCDIR)/cc_util/cc_util_error.h
+
+PUBLIC_INCLUDES += $(SHARED_INCDIR)/proj/cc3x/cc_general_defs.h $(SHARED_INCDIR)/proj/cc3x/cc_ecpki_domains_defs.h $(SHARED_INCDIR)/proj/cc3x/cc_sram_map.h
+PUBLIC_INCLUDES += $(SHARED_INCDIR)/proj/cc3x/cc_pka_hw_plat_defs.h
+
+#FFCDH
+PUBLIC_INCLUDES += $(CC_API)/cc_ffcdh.h $(CC_API)/cc_ffc_domain.h $(CC_API)/cc_ffcdh_error.h $(CC_API)/cc_ffc_domain_error.h
+
+#INCDIRS_EXTRA += $(TESTS_COMMON_API)
+#external DMA chacha include
+ifeq ($(CC_CONFIG_CC_CHACHA_POLY_SUPPORT),1)
+ifeq ($(CC_CONFIG_SUPPORT_EXT_DMA),1)
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_chacha_ext_dma.h
+endif
+endif
+
+ifeq ($(CC_CONFIG_SUPPORT_EXT_DMA),1)
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_aes_ext_dma.h
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_hash_ext_dma.h
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_ext_dma_error.h
+endif
+
+#lib sources
+SOURCES_cc_312 = cc_lib.c cc_hal.c
+SOURCES_cc_312 += bypass_driver.c aes_driver.c aesccm_driver.c
+SOURCES_cc_312 += aesgcm_driver.c driver_common.c
+SOURCES_cc_312 += mbedtls_cc_sha512_t.c
+
+#external DMA
+ifeq ($(CC_CONFIG_SUPPORT_EXT_DMA),1)
+SOURCES_cc_312 += aes_driver_ext_dma.c mbedtls_aes_ext_dma.c hash_driver_ext_dma.c mbedtls_hash_ext_dma.c
+endif
+
+ifeq ($(CC_CONFIG_CC_CHACHA_POLY_SUPPORT),1)
+ifeq ($(CC_CONFIG_SUPPORT_EXT_DMA),1)
+SOURCES_cc_312 += mbedtls_chacha_ext_dma.c chacha_driver_ext_dma.c
+endif
+endif
+
+#mbedtls_api
+SOURCES_cc_312 += sha1_alt.c sha256_alt.c mbedtls_hash_common.c aes_alt.c mbedtls_common.c ccm_alt.c gcm_alt.c trng_api.c mbedtls_ccm_internal.c
+SOURCES_cc_312 += rsa_alt.c ecp_common.c cc_ecp_internal.c ecdsa_alt.c ecdh_alt.c ecdsa_edwards.c
+SOURCES_cc_312 += cmac_alt.c dhm_alt.c chacha20_alt.c poly1305_alt.c chachapoly_alt.c
+##SOURCES_cc_312 += platform_alt.c
+
+#management
+SOURCES_cc_312 += mbedtls_cc_mng.c mbedtls_cc_mng_int.c
+
+
+#SB_RT
+ifeq ($(CC_CONFIG_SUPPORT_SB_RT),1)
+CFLAGS_EXTRA += -DCC_SB_SUPPORT_SB_RT
+PUBLIC_INCLUDES += $(CODESAFE_SRCDIR)/secure_boot_debug/platform/common/cc3x/secureboot_defs.h
+PUBLIC_INCLUDES += $(CODESAFE_SRCDIR)/secure_boot_debug/secure_boot_gen/secureboot_gen_defs.h
+PUBLIC_INCLUDES += $(CODESAFE_SRCDIR)/secure_boot_debug/secure_boot_gen/secureboot_basetypes.h
+PUBLIC_INCLUDES += $(CODESAFE_SRCDIR)/secure_boot_debug/platform/pal/cc3x/cc_pal_sb_plat.h
+PUBLIC_INCLUDES += $(CODESAFE_SRCDIR)/secure_boot_debug/cc3x_verifier/bootimagesverifier_def.h
+SOURCES_cc_312 += mbedtls_cc_sbrt.c sbrt_int_func.c bootimagesverifier_parser.c nvm_otp.c
+SOURCES_cc_312 += bootimagesverifier_swcomp.c secureboot_base_swimgverify.c
+SOURCES_cc_312 += rsa_verify.c rsa_exp.c rsa_pki_pka.c
+SOURCES_cc_312 += bootimagesverifier_base_single.c bsv_aes_driver.c bsv_hash_driver.c
+SOURCES_cc_312 += common_cert_verify.c  secureboot_base_func.c
+ifeq ($(CC_CONFIG_SB_X509_CERT_SUPPORTED),0)
+SOURCES_cc_312 += common_cert_parser.c
+else #x509 files
+CFLAGS_EXTRA += -DCC_SB_X509_CERT_SUPPORTED -DCC_SB_SUPPORT_IOT
+SOURCES_cc_312 += cc3x_sb_x509_parser.c
+SOURCES_cc_312 += util_asn1_parser.c util_x509_parser.c sb_x509_cert_parser.c cc3x_sb_x509_ext_parser.c cc_pal_x509_verify.c
+INCDIRS_EXTRA += $(SBROM_DIR)/util $(SHARED_INCDIR)/sbrom $(SBROM_DIR)/platform/pal $(SBROM_DIR)/x509_cert_parser $(SBROM_DIR)/x509_verifier
+endif #CC_CONFIG_SB_X509_CERT_SUPPORTED
+endif #CC_CONFIG_SUPPORT_SB_RT
+
+#util
+SOURCES_cc_312 += cc_util_cmac.c cc_hash_info.c mbedtls_cc_util_key_derivation.c mbedtls_cc_util_asset_prov.c
+
+# Asymmetric sources
+#common PKA functions
+SOURCES_cc_312 += pki.c pka.c
+#KDF
+SOURCES_cc_312 += cc_kdf.c
+
+#RSA and dependent functions
+
+ifeq ($(RSA_KG_NO_RND),1)
+	CFLAGS+= -DRSA_KG_NO_RND
+	SOURCES_cc_312 += rsa_kg_debug_data.c
+endif
+
+SOURCES_cc_312 += cc_rsa_info.c cc_rsa_build.c
+SOURCES_cc_312 += cc_rsa_oaep.c cc_rsa_schemes.c cc_rsa_pkcs_ver15_util.c cc_rsa_pss21_util.c cc_rsa_prim.c cc_rsa_verify.c
+SOURCES_cc_312 += cc_rsa_kg.c cc_rsa_sign.c
+SOURCES_cc_312 += rsa_public.c rsa_private.c rsa_genkey.c
+# ffcdh
+SOURCES_cc_312 += cc_ffc_domain.c
+
+
+ifeq ($(CC_CONFIG_CC_CHACHA_POLY_SUPPORT),1)
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_cc_chacha.h  $(CC_API_3x)/mbedtls_cc_chacha_error.h
+PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_cc_poly.h $(CC_API_3x)/mbedtls_cc_poly_error.h  $(CC_API_3x)/mbedtls_cc_chacha_poly.h $(CC_API_3x)/mbedtls_cc_chacha_poly_error.h
+SOURCES_cc_312 += chacha_driver.c mbedtls_cc_chacha.c  mbedtls_cc_chacha_poly.c   mbedtls_cc_poly.c poly.c
+endif
+
+
+#ECC(Canonic) CC
+SOURCES_cc_312 += cc_ecpki_info.c
+SOURCES_cc_312 += cc_ecpki_build_publ.c cc_ecpki_build_priv.c cc_ecdsa_verify.c cc_ecdsa_sign.c
+SOURCES_cc_312 += cc_ecpki_kg.c cc_ecdh.c mbedtls_cc_ecies.c ec_wrst_genkey.c
+#ECC(Canonic) LLF
+SOURCES_cc_312 += pki_modular_arithmetic.c
+SOURCES_cc_312 += pka_ec_wrst.c pka_ec_wrst_dsa_verify.c
+SOURCES_cc_312 += ec_wrst.c ec_wrst_dsa.c   cc_ecpki_domain.c
+SOURCES_cc_312 +=  cc_ecpki_domain_secp192r1.c
+SOURCES_cc_312 +=  cc_ecpki_domain_secp192k1.c cc_ecpki_domain_secp224r1.c cc_ecpki_domain_secp224k1.c cc_ecpki_domain_secp256r1.c
+SOURCES_cc_312 +=  cc_ecpki_domain_secp256k1.c cc_ecpki_domain_secp384r1.c cc_ecpki_domain_secp521r1.c
+
+#rng
+SOURCES_cc_312 += cc_rnd_common.c llf_rnd.c cc_rng_plat.c cc_common_math.c cc_common_conv_endian.c
+ifeq ($(CC_CONFIG_TRNG_MODE),0)
+        # FE TRNG
+        $(info FE TRNG: CC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE))
+        SOURCES_cc_312 += llf_rnd_fetrng.c
+	CFLAGS_EXTRA += -DCC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE)
+else ifeq ($(CC_CONFIG_TRNG_MODE),1)
+        # TRNG90B
+        $(info TRNG90B: CC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE))
+        SOURCES_cc_312 += llf_rnd_trng90b.c
+	CFLAGS_EXTRA += -DCC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE)
+else
+        $(error illegal TRNG: CC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE))
+endif
+
+# hash + hmac HW driver
+SOURCES_cc_312 += hash_driver.c
+CFLAGS += -DMD5_HASH_EXCLUDED
+CFLAGS += -DCC_KEYGEN_MAX_SIZE=$(CC_RSA_MAX_KEY_GENERATION_SIZE_BITS)
+
+ifeq ($(CC_CONFIG_SUPPORT_ECC_SCA_SW_PROTECT), 1)
+	SOURCES_cc_312 += pka_ec_wrst_smul_scap.c
+else
+	SOURCES_cc_312 += pka_ec_wrst_smul_no_scap.c
+endif
+
+
+ifeq ($(LIB_PERF),1)
+CFLAGS += -DLIB_PERF
+endif
+
+ifeq ($(DEBUG),1)
+CFLAGS += -DDEBUG
+endif
+
+ifeq ($(PKA_DEBUG),1)
+SOURCES_cc_312 += pki_dbg.c
+CFLAGS += -DPKA_DEBUG
+endif
+
+# always suppose to support smaller PKA and have the IOT flag
+CFLAGS_EXTRA += -DCC_IOT -DCC_SUPPORT_PKA_64_16
+
+
+# Include directories
+ifeq ($(TEE_OS),freertos)
+include  $(HOST_SRCDIR)/../Makefile.freertos
+endif
+
+ifeq ($(TEE_OS),mbedos)
+include  $(HOST_SRCDIR)/../Makefile.mbedos
+endif
+
+INCDIRS_EXTRA += $(HOST_SRCDIR)/pal/$(TEE_OS)
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/api $(CODESAFE_DIR)/src/crypto_api/cc3x_sym/driver $(SHARED_DIR)/hw/include $(SHARED_INCDIR)/cc_util $(SHARED_INCDIR)/crypto_api/$(PROJ_PRD)
+INCDIRS_EXTRA += $(SHARED_INCDIR) $(SHARED_INCDIR)/pal $(SHARED_INCDIR)/pal/$(TEE_OS) $(HOST_PROJ_ROOT)/src/hal $(HOST_PROJ_ROOT)/src/pal  $(HOST_PROJ_ROOT)/src/pal/$(TEE_OS)
+INCDIRS_EXTRA += $(SHARED_INCDIR)/crypto_api
+INCDIRS_EXTRA += $(HOST_INCDIR) $(CODESAFE_SRCDIR)/crypto_api/common $(SHARED_INCDIR)/trng/
+#INCDIRS_EXTRA += $(HOST_SRCDIR)/softcrys/hash_common
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/rnd_dma $(CODESAFE_SRCDIR)/crypto_api/rnd_dma/local
+#pka, rsa and ecc directories
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/pki/common $(CODESAFE_SRCDIR)/crypto_api/pki/ec_wrst $(CODESAFE_SRCDIR)/crypto_api/pki/rsa $(CODESAFE_SRCDIR)/crypto_api/pki/poly
+
+# ffc_domain and ffcdh directories
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/ffc_domain $(CODESAFE_SRCDIR)/crypto_api/ffcdh
+
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/rsa $(CODESAFE_SRCDIR)/crypto_api/ec_wrst $(CODESAFE_SRCDIR)/crypto_api/ec_wrst/ecc_domains
+
+#mbedtls headers
+INCDIRS_EXTRA += $(MBEDTLS_ROOT)/include/mbedtls $(MBEDTLS_ROOT)/include
+INCDIRS_EXTRA += $(UTILS_API) $(MANAGEMENT_API)
+INCDIRS_EXTRA += $(UTILS_API)
+INCDIRS_EXTRA += $(MBEDTLS_ALT_DIR)
+
+#SBROM
+INCDIRS_EXTRA += $(SBROM_DIR)/secure_boot_gen $(SBROM_DIR)/common
+INCDIRS_EXTRA += $(SBROM_DIR)/platform/common/cc3x $(SBROM_DIR)/platform/pal/cc3x $(SBROM_DIR)/platform/stage/rt/cc3x
+INCDIRS_EXTRA += $(SBROM_DIR)/secure_debug/cc3x $(SBROM_DIR)/crypto_driver $(SBROM_DIR)/crypto_driver/reg
+INCDIRS_EXTRA += $(SBROM_DIR)/cc3x_verifier $(HOST_SRCDIR)/cc3x_sbromlib
+INCDIRS_EXTRA += $(SBROM_DIR)/platform/nvm $(SBROM_DIR)/platform/nvm/cc3x_nvm_rt
+
+CFLAGS_EXTRA += -DDLLI_MAX_BUFF_SIZE=$(DLLI_MAX_BUFF_SIZE)
+CFLAGS_EXTRA += -DFW_VER_MAJOR=$(FW_VER_MAJOR) -DFW_VER_MINOR=$(FW_VER_MINOR) -DFW_VER_PATCH=$(FW_VER_PATCH)
+CFLAGS_EXTRA += -DCC_HW_VERSION=$(CC_HW_VERSION)
+
+# define flag for non supported RND_DMA
+ifeq ($(CC_CONFIG_RND_TEST_MODE),CC_RND_TEST_MODE)
+CFLAGS_EXTRA += -DCC_RND_TEST_MODE
+endif
+
+ifeq ($(CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES),)
+    #default
+    CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES = 8192
+endif
+
+ifeq ($(CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES),)
+    #default
+    CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES = 512
+endif
+
+CFLAGS_EXTRA += -DCC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES=$(CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES)
+CFLAGS_EXTRA += -DCC_MNG_MIN_BACKUP_SIZE_IN_BYTES=$(CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES)
+CFLAGS_EXTRA += -DCC_SB_CERT_VERSION_MAJOR=$(CC_CONFIG_SB_CERT_VERSION_MAJOR)
+CFLAGS_EXTRA += -DCC_SB_CERT_VERSION_MINOR=$(CC_CONFIG_SB_CERT_VERSION_MINOR)
+
+
+# List of drivers to enable/disable
+DRIVERS = AES
+CFLAGS_EXTRA += $(foreach driver,$(DRIVERS),$(if $(FW_ENABLE_$(driver)_DRIVER),-DENABLE_$(driver)_DRIVER=$(FW_ENABLE_$(driver)_DRIVER)))
+
+
+ifeq ($(CC_CONFIG_SUPPORT_SRP),1)
+	PUBLIC_INCLUDES += $(CC_API_3x)/mbedtls_cc_srp.h $(CC_API_3x)/mbedtls_cc_srp_error.h
+	VPATH += $(CODESAFE_SRCDIR)/crypto_api/pki/srp
+	INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/pki/srp
+	SOURCES_cc_312 += mbedtls_cc_srp.c srp_driver.c srp.c
+endif
+
+# EC Montgomery and EC Edwards includes and files
+
+#EC_MONT
+
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/ec_mont $(CODESAFE_SRCDIR)/crypto_api/pki/ec_mont
+SOURCES_cc_312 += cc_ec_mont.c ec_mont.c pka_ec_mont.c
+SOURCES_cc_312 += ec_mont_domain_curve25519.c
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/ec_mont $(CODESAFE_SRCDIR)/crypto_api/pki/ec_mont
+#EC_EDW
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/ec_edw $(CODESAFE_SRCDIR)/crypto_api/pki/ec_edw
+SOURCES_cc_312 += cc_ec_edw.c ec_edw.c pka_ec_edw.c
+SOURCES_cc_312 += ec_edw_domain_25519.c
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/ec_edw $(CODESAFE_SRCDIR)/crypto_api/pki/ec_edw
+
+
+
+
+# We should flatten the components source trees to avoid long search paths...
+VPATH += $(HOST_SRCDIR)/hal/$(PROJ_PRD) $(UTILS_API) $(MANAGEMENT_API)
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/api $(CODESAFE_DIR)/src/crypto_api/cc3x_sym/driver $(CODESAFE_SRCDIR)/crypto_api/kdf $(CODESAFE_SRCDIR)/crypto_api/rnd_dma
+VPATH += $(SHARED_SRCDIR)/proj/$(PROJ_PRD) $(CODESAFE_SRCDIR)/crypto_api/common
+#pka, rsa, dh, ffcdh etc. directories
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/pki/common $(CODESAFE_SRCDIR)/crypto_api/pki/ec_wrst $(CODESAFE_SRCDIR)/crypto_api/pki/rsa
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/rsa/ $(CODESAFE_SRCDIR)/crypto_api/ec_wrst $(CODESAFE_SRCDIR)/crypto_api/ec_wrst/ecc_domains
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/dh $(CODESAFE_SRCDIR)/crypto_api/pki/poly
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/ffcdh $(CODESAFE_SRCDIR)/crypto_api/ffc_domain
+VPATH += $(MBEDTLS_ALT_DIR)
+#sbrom
+VPATH += $(SBROM_DIR)/cc3x_verifier $(SBROM_DIR)/crypto_driver $(SBROM_DIR)/secure_boot_gen $(SBROM_DIR)/common
+VPATH += $(SBROM_DIR)/platform/common/cc3x $(SBROM_DIR)/platform/nvm/cc3x_nvm_rt $(HOST_SRCDIR)/cc3x_sbromlib
+VPATH += $(SBROM_DIR)/x509_cert_parser $(SBROM_DIR)/util $(SBROM_DIR)/platform/pal
+
+# SCA protection flag
+ifeq ($(CC_CONFIG_SUPPORT_ECC_SCA_SW_PROTECT), 1)
+        CFLAGS_EXTRA += -DCC_SUPPORT_ECC_SCA_SW_PROTECT
+endif
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
+
+ifeq ($(DEBUG),1)
+CFLAGS += -DTEST_DEBUG
+endif
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_fips_defs.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_fips_defs.h
new file mode 100644
index 0000000..abffe80
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_fips_defs.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_FIPS_DEFS_H
+#define  _CC_FIPS_DEFS_H
+
+//empty macro since FIPS not supported
+#define CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR()
+#define CHECK_AND_RETURN_UPON_FIPS_ERROR()
+#define CHECK_AND_RETURN_UPON_FIPS_STATE()
+#define CHECK_FIPS_SUPPORTED(supported) {supported = false;}
+#define FIPS_RSA_VALIDATE(rndContext_ptr,pCcUserPrivKey,pCcUserPubKey,pFipsCtx)  (CC_OK)
+#define FIPS_ECC_VALIDATE(pRndContext, pUserPrivKey, pUserPublKey, pFipsCtx)  (CC_OK)
+#define CC_FIPS_SET_RND_CONT_ERR()
+
+#endif  // _CC_FIPS_DEFS_H
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
new file mode 100644
index 0000000..0a97ce4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CCLIB
+
+#include "cc_pal_types.h"
+#include "cc_pal_log.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_lib.h"
+#include "cc_hal.h"
+#include "cc_pal_init.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_perf.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "dx_rng.h"
+#include "dx_reg_common.h"
+#include "llf_rnd_trng.h"
+#include "cc_rng_plat.h"
+#include "dx_id_registers.h"
+#include "cc_util_pm.h"
+#include "dx_nvm.h"
+#include "ctr_drbg.h"
+#include "entropy.h"
+#include "threading.h"
+#include "mbedtls_cc_mng_int.h"
+#include "mbedtls_cc_mng.h"
+#include "cc_rnd_common.h"
+#include "cc_int_general_defs.h"
+
+CC_PalMutex CCSymCryptoMutex;
+CC_PalMutex CCAsymCryptoMutex;
+CC_PalMutex *pCCRndCryptoMutex;
+CC_PalMutex CCApbFilteringRegMutex;
+CC_PalMutex CCRndCryptoMutex;
+
+static CCError_t RndStartupTest(
+        CCRndWorkBuff_t  *workBuff_ptr/*in/out*/)
+{
+        /* error identifier definition */
+        CCError_t error = CC_OK;
+        CCRndState_t   rndState;
+        CCRndParams_t  trngParams;
+
+        error = RNG_PLAT_SetUserRngParameters(&trngParams);
+        if (error != CC_SUCCESS) {
+                return error;
+        }
+
+        error = CC_PalMutexLock(pCCRndCryptoMutex, CC_INFINITE);
+        if (error != CC_SUCCESS) {
+                CC_PalAbort("Fail to acquire mutex\n");
+        }
+
+        /* verify that the device is not in fatal error state before activating the PKA engine */
+        CC_IS_FATAL_ERR_ON(error);
+        if (error == CC_TRUE) {
+                error = CC_LIB_RET_RND_INST_ERR;
+                goto EndUnlockMutex;
+        }
+
+        /* increase CC counter at the beginning of each operation */
+        error = CC_IS_WAKE;
+        if (error != CC_SUCCESS) {
+            CC_PalAbort("Fail to increase PM counter\n");
+        }
+
+        /* call on Instantiation mode */
+        error = LLF_RND_RunTrngStartupTest(&rndState, &trngParams, (uint32_t*)workBuff_ptr);
+
+        /* decrease CC counter at the end of each operation */
+        if (CC_IS_IDLE != CC_SUCCESS) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+        }
+
+EndUnlockMutex:
+        if (CC_PalMutexUnlock(pCCRndCryptoMutex) != CC_SUCCESS) {
+                CC_PalAbort("Fail to release mutex\n");
+        }
+        return error;
+}
+
+static CClibRetCode_t InitHukRma(CCRndContext_t *rndContext_ptr)
+{
+    uint32_t lcsVal = 0;
+    uint32_t kdrValues[CC_AES_KDR_MAX_SIZE_WORDS];
+    CCError_t error = CC_OK;
+    uint32_t i = 0;
+    CCRndGenerateVectWorkFunc_t RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
+
+    mbedtls_mng_lcsGet( &lcsVal );
+
+    if (lcsVal == CC_MNG_LCS_RMA){ /* in case lcs == RMA set the KDR*/
+        error = RndGenerateVectFunc((void *)rndContext_ptr->rndState,
+                        (unsigned char *)kdrValues, (size_t) CC_AES_KDR_MAX_SIZE_BYTES);
+        if (error != CC_OK){
+            return CC_LIB_RET_RND_INST_ERR;
+        }
+
+        /* set the random value to the KDR register */
+        for (i = 0; i < CC_AES_KDR_MAX_SIZE_WORDS; i++){
+            CC_HAL_WRITE_REGISTER( DX_HOST_SHADOW_KDR_REG_REG_OFFSET, kdrValues[i] );
+        }
+    }
+
+    return CC_LIB_RET_OK;
+}
+
+
+static CClibRetCode_t VerifyPidVal(void)
+{
+    uint32_t pidReg[CC_BSV_PID_SIZE_WORDS] = {0};
+    uint32_t pidVal1[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
+    uint32_t pidVal2[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_1_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
+
+    pidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_0));
+    pidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_1));
+    pidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_2));
+    pidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_3));
+    pidReg[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_4));
+
+    if ((CC_PalMemCmp((uint8_t*)pidVal1, (uint8_t*)pidReg, sizeof(pidVal1)) != 0) &&
+            (CC_PalMemCmp((uint8_t*)pidVal2, (uint8_t*)pidReg, sizeof(pidVal2)) != 0)) {
+        return CC_LIB_RET_EINVAL_PIDR;
+    }
+
+    return CC_LIB_RET_OK;
+}
+
+static CClibRetCode_t VerifyCidVal(void)
+{
+    uint32_t cidReg[CC_BSV_CID_SIZE_WORDS] = {0};
+    uint32_t cidVal[CC_BSV_CID_SIZE_WORDS] = {CC_BSV_CID_0_VAL, CC_BSV_CID_1_VAL, CC_BSV_CID_2_VAL, CC_BSV_CID_3_VAL};
+
+    cidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_0));
+    cidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_1));
+    cidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_2));
+    cidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_3));
+
+    if (CC_PalMemCmp((uint8_t*)cidVal, (uint8_t*)cidReg, sizeof(cidVal)) != 0){
+        return CC_LIB_RET_EINVAL_CIDR;
+    }
+
+    return CC_LIB_RET_OK;
+}
+
+
+/*!
+ * TEE (Trusted Execution Environment) entry point.
+ * Init CryptoCell for TEE.
+ *
+ * @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
+ * @param[in/out] rndWorkBuff_ptr  - Pointer to the RND scratch buffer.
+ *
+ * \return CClibRetCode_t one of the error codes defined in cc_lib.h
+ */
+CClibRetCode_t CC_LibInit(CCRndContext_t *rndContext_ptr, CCRndWorkBuff_t  *rndWorkBuff_ptr)
+{
+    int rc = 0;
+    CClibRetCode_t retCode = CC_LIB_RET_OK;
+    CCError_t error = CC_OK;
+    uint32_t reg = 0;
+    uint32_t tempVal = 0;
+
+    /* check parameters */
+    if (rndContext_ptr == NULL)
+        return CC_LIB_RET_EINVAL_CTX_PTR;
+    if (rndWorkBuff_ptr == NULL)
+        return CC_LIB_RET_EINVAL_WORK_BUF_PTR;
+    if (rndContext_ptr->rndState == NULL)
+        return CC_LIB_RET_EINVAL_CTX_PTR;
+    if (rndContext_ptr->entropyCtx == NULL)
+        return CC_LIB_RET_EINVAL_CTX_PTR;
+
+    rc = CC_HalInit();
+    if (rc != CC_LIB_RET_OK) {
+        retCode = CC_LIB_RET_HAL;
+        goto InitErr1;
+    }
+
+    rc = CC_PalInit();
+    if (rc != CC_LIB_RET_OK) {
+        retCode = CC_LIB_RET_PAL;
+        goto InitErr;
+    }
+
+    /* verify peripheral ID (PIDR) */
+    rc = VerifyPidVal();
+    if (rc != CC_LIB_RET_OK) {
+        retCode = CC_LIB_RET_EINVAL_PIDR;
+        goto InitErr2;
+    }
+
+    /* verify component ID (CIDR) */
+    rc = VerifyCidVal();
+    if (rc != CC_LIB_RET_OK) {
+        retCode = CC_LIB_RET_EINVAL_CIDR;
+        goto InitErr2;
+    }
+
+    /* turn off the DFA since Cerberus doen't support it */
+    reg = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, reg, 0x0);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,reg );
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_AO_LOCK_BITS));
+    if(tempVal != reg) {
+        retCode = CC_LIB_AO_WRITE_FAILED_ERR;
+        goto InitErr2;
+    }
+
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_DFA_ENABLE_LOCK, reg, CC_TRUE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,reg );
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_AO_LOCK_BITS));
+    if(tempVal != reg) {
+        retCode = CC_LIB_AO_WRITE_FAILED_ERR;
+        goto InitErr2;
+    }
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_DFA_IS_ON)  ,0x0UL );
+
+#ifdef BIG__ENDIAN
+/* Set DMA endianess to big */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+
+    CC_PAL_PERF_INIT();
+
+    /* Initialize RND module */
+    error = RndStartupTest(rndWorkBuff_ptr);
+    if (error != 0) {
+        retCode = CC_LIB_RET_RND_INST_ERR;
+        goto InitErr2;
+    }
+
+    /* Initialize mbedTLS random function*/
+    mbedtls_ctr_drbg_init(rndContext_ptr->rndState);
+    mbedtls_entropy_init( rndContext_ptr->entropyCtx );
+    error = mbedtls_ctr_drbg_seed(rndContext_ptr->rndState, mbedtls_entropy_func, rndContext_ptr->entropyCtx,
+            NULL, 0);
+    if (error != 0) {
+        retCode = CC_LIB_RET_RND_INST_ERR;
+        goto InitErr2;
+    }
+
+    error = CC_RndSetGenerateVectorFunc(rndContext_ptr, mbedtls_ctr_drbg_random);
+    if (error != 0) {
+        retCode = CC_LIB_RET_RND_INST_ERR;
+        goto InitErr2;
+    }
+    error = InitHukRma(rndContext_ptr);
+    if (error != 0) {
+        retCode = CC_LIB_RET_RND_INST_ERR;
+        goto InitErr2;
+    }
+    return CC_LIB_RET_OK;
+    InitErr2:
+    CC_HalTerminate();
+
+    InitErr1:
+    CC_PalTerminate();
+
+    InitErr:
+    return retCode;
+}
+
+
+/*!
+ * TEE (Trusted Execution Environment) exit point.
+ * Finalize CryptoCell for TEE operation, release associated resources.
+ *                                                                    .
+ * @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
+ */
+CClibRetCode_t CC_LibFini(CCRndContext_t *rndContext_ptr)
+{
+    CCError_t rc = CC_OK;
+    CClibRetCode_t retCode = CC_LIB_RET_OK;
+
+    /* check parameters */
+    if (rndContext_ptr == NULL)
+        return CC_LIB_RET_EINVAL_CTX_PTR;
+
+    rc = CC_HalTerminate();
+    if (rc != 0){
+        retCode = CC_LIB_RET_HAL;
+    }
+    CC_PalTerminate();
+
+    rndContext_ptr->rndGenerateVectFunc=NULL;
+    mbedtls_ctr_drbg_free( rndContext_ptr->rndState );
+    mbedtls_entropy_free( rndContext_ptr->entropyCtx );
+
+    CC_PAL_PERF_FIN();
+
+    return retCode;
+
+}
+
+void __cyg_profile_func_enter (void *this_fn, void *call_site) {
+    unsigned int i;
+    CC_UNUSED_PARAM(i);
+    CC_UNUSED_PARAM(this_fn);
+    CC_UNUSED_PARAM(call_site);
+
+    CC_PAL_LOG_ERR("Entering: %p -> %p (stack: %p)\n",
+                    call_site, this_fn, &i );
+}
+
+void __cyg_profile_func_exit (void *this_fn, void *call_site) {
+    unsigned int i;
+    CC_UNUSED_PARAM(i);
+    CC_UNUSED_PARAM(this_fn);
+    CC_UNUSED_PARAM(call_site);
+
+    CC_PAL_LOG_ERR("Exiting: %p <- %p (stack: %p)\n",
+                     call_site, this_fn, &i );
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.h
new file mode 100644
index 0000000..0e89c19
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_lib
+
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all of the basic APIs of the CryptoCell library,
+ their enums and definitions.
+ */
+
+
+#ifndef __CC_LIB_H__
+#define __CC_LIB_H__
+
+#include "cc_pal_types.h"
+#include "cc_rnd_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*! Definitions for error returns from ::CC_LibInit or ::CC_LibFini functions. */
+typedef enum {
+        /*! Success.*/
+        CC_LIB_RET_OK = 0,
+        /*! Illegal context pointer.*/
+        CC_LIB_RET_EINVAL_CTX_PTR,
+        /*! Illegal work-buffer pointer.*/
+        CC_LIB_RET_EINVAL_WORK_BUF_PTR,
+        /*! Error returned from the HAL layer.*/
+        CC_LIB_RET_HAL,
+        /*! Error returned from the PAL layer.*/
+        CC_LIB_RET_PAL,
+        /*! RND instantiation failed.*/
+        CC_LIB_RET_RND_INST_ERR,
+        /*! Invalid peripheral ID. */
+        CC_LIB_RET_EINVAL_PIDR,
+        /*! Invalid component ID. */
+        CC_LIB_RET_EINVAL_CIDR,
+        /*! Error returned from AO write operation. */
+        CC_LIB_AO_WRITE_FAILED_ERR,
+        /*! Reserved.*/
+        CC_LIB_RESERVE32B = 0x7FFFFFFFL
+} CClibRetCode_t;
+
+
+/*! Internal definition for the product register. */
+#define DX_VERSION_PRODUCT_BIT_SHIFT    0x18UL
+/*! Internal definition for the product register size. */
+#define DX_VERSION_PRODUCT_BIT_SIZE     0x8UL
+
+
+
+/*!
+ @brief This function performs global initialization of the CryptoCell runtime
+ library.
+
+ It must be called once per CryptoCell cold-boot cycle.
+ Among other initializations, this function initializes the CTR-DRBG context,
+ including the TRNG seeding. An initialized DRBG context is required for
+ calling DRBG APIs, as well as asymmetric-cryptography key-generation and
+ signatures.\n
+ The primary context returned by this function can be used as a single global
+ context for all DRBG needs. Alternatively, other contexts may be initialized
+ and used with a more limited scope, for specific applications or specific
+ threads.
+
+ @note If used, the Mutexes are initialized by this API. Therefore, unlike
+ other APIs in the library, this API is not thread-safe. \par
+ @note The \p rndWorkBuff_ptr parameter can be NULL in case full entropy mode
+ is used. \par
+
+ @return \c CC_LIB_RET_OK on success.
+ @return A non-zero value on failure.
+ */
+CClibRetCode_t CC_LibInit(
+        /*! [in/out] A pointer to the RND context buffer allocated by the user.
+        The context is used to maintain the RND state as well as
+        pointers to a function used for random vector generation.
+        This context must be saved and provided as a parameter to
+        any API that uses the RND module.*/
+        CCRndContext_t *rndContext_ptr,
+        /*! [in] A scratchpad for the work of the RND module. */
+        CCRndWorkBuff_t  *rndWorkBuff_ptr
+        );
+
+/*!
+ @brief This function finalizes library operations.
+
+ It performs the following operations:
+ <ul><li>Frees the associated resources (mutexes).</li>
+ <li>Calls the HAL and PAL terminate functions.</li>
+ <li>Cleans the DRBG context.</li></ul>
+
+ @return \c CC_LIB_RET_OK on success.
+ @return A non-zero value on failure.
+*/
+CClibRetCode_t CC_LibFini(
+        /*! [in/out] A pointer to the RND context buffer that was initialized
+        in #CC_LibInit.*/
+        CCRndContext_t *rndContext_ptr
+        );
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+@}
+ */
+
+#endif /*__CC_LIB_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_plat.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_plat.h
new file mode 100644
index 0000000..e7edd18
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_plat.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  CC_PLAT_H
+#define  CC_PLAT_H
+
+#define NULL_SRAM_ADDR ((CCSramAddr_t)0xFFFFFFFF)
+
+#define _WriteWordsToSram(addr, data, size) \
+do { \
+    uint32_t ii; \
+    volatile uint32_t dummy; \
+    CC_HAL_WRITE_REGISTER( CC_REG_OFFSET (HOST_RGF,SRAM_ADDR), (addr)); \
+    for( ii = 0 ; ii < size/sizeof(uint32_t) ; ii++ ) { \
+           CC_HAL_WRITE_REGISTER( CC_REG_OFFSET (HOST_RGF,SRAM_DATA), SWAP_TO_LE(((uint32_t *)data)[ii])); \
+           do { \
+             dummy = CC_HAL_READ_REGISTER( CC_REG_OFFSET (HOST_RGF, SRAM_DATA_READY)); \
+           }while(!(dummy & 0x1)); \
+    } \
+}while(0)
+
+#define _ReadWordsFromSram( addr , data , size ) \
+do { \
+    uint32_t ii; \
+    volatile uint32_t dummy; \
+    CC_HAL_WRITE_REGISTER( CC_REG_OFFSET (HOST_RGF,SRAM_ADDR) ,(addr) ); \
+    dummy = CC_HAL_READ_REGISTER( CC_REG_OFFSET (HOST_RGF,SRAM_DATA)); \
+    for( ii = 0 ; ii < size/sizeof(uint32_t) ; ii++ ) { \
+        do { \
+            dummy = CC_HAL_READ_REGISTER( CC_REG_OFFSET (HOST_RGF, SRAM_DATA_READY)); \
+        }while(!(dummy & 0x1)); \
+        dummy = CC_HAL_READ_REGISTER( CC_REG_OFFSET (HOST_RGF,SRAM_DATA));\
+        ((uint32_t*)data)[ii] = SWAP_TO_LE(dummy); \
+    } \
+    do { \
+        dummy = CC_HAL_READ_REGISTER( CC_REG_OFFSET (HOST_RGF, SRAM_DATA_READY)); \
+    }while(!(dummy & 0x1)); \
+}while(0)
+
+#define CLEAR_TRNG_SRC()
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_params.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_params.h
new file mode 100644
index 0000000..fd7baa2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_params.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  CC_RNG_PARAMS_H
+#define  CC_RNG_PARAMS_H
+
+
+/* Default RNG parameters are used when these parameters are set to 0 */
+#define CC_RNG_NUM_OF_ROSCS_ALLOWED_FLAG        0x0
+#define CC_RNG_SAMPL_RATIO_ON_SWEE_MODE       0
+
+
+/* Default, increment and mininimal values, for Sampling Ratio */
+#define CC_RNG_DEFAULT_ROSCS_ALLOWED_FLAG       0xF
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_plat.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_plat.c
new file mode 100644
index 0000000..c760999
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_plat.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include "dx_rng.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_rng_plat.h"
+#include "cc_pal_abort.h"
+#include "dx_crys_kernel.h"
+#include "cc_common_math.h"
+#include "cc_rnd_local.h"
+#include "cc_rnd_error.h"
+#include "llf_rnd.h"
+#include "llf_rnd_error.h"
+#include "bypass_driver.h"
+#include "cc_rng_params.h"
+#include "cc_address_defs.h"
+#include "cc_util_pm.h"
+#include "llf_rnd_trng.h"
+
+
+/****************************************************************************************/
+/**
+ *
+ * @brief The function retrievess the TRNG parameters, provided by the User trough NVM,
+ *        and sets them into structures given by pointers pRndContext and pTrngParams.
+ *
+ * @author reuvenl (6/26/2012)
+ *
+ * @param[out] pRndState - The pointer to structure, containing PRNG data and
+ *                            parameters.
+ * @param[out] pTrngParams - The pointer to structure, containing parameters
+ *                            of HW TRNG.
+ *
+ * @return CCError_t -  no return value
+ */
+CCError_t RNG_PLAT_SetUserRngParameters(
+        CCRndParams_t  *pTrngParams)
+{
+        CCError_t  error = CC_OK;
+        size_t  paramsSize = sizeof(CC_PalTrngParams_t);
+
+        /* FUNCTION LOGIC */
+        error = CC_PalTrngParamGet(&pTrngParams->userParams, &paramsSize);
+        if (error != CC_OK) {
+            return error;
+        }
+        // Verify PAL and run-time lib compiled with the same CC_CONFIG_TRNG_MODE
+        if (paramsSize != sizeof(CC_PalTrngParams_t)) {
+            error = CC_RND_MODE_MISMATCH_ERROR;
+            goto func_error;
+        }
+
+        /* Set TRNG parameters         */
+        /*-----------------------------*/
+        pTrngParams->TrngMode = CC_RND_FE;
+
+        /* Allowed ROSCs lengths b'0-3. If bit value 1 - appropriate ROSC is allowed. */
+        pTrngParams->RoscsAllowed = (((pTrngParams->userParams.SubSamplingRatio1 > 0) ? 0x1 : 0x0) |
+                ((pTrngParams->userParams.SubSamplingRatio2 > 0) ? 0x2 : 0x0) |
+                ((pTrngParams->userParams.SubSamplingRatio3 > 0) ? 0x4 : 0x0) |
+                ((pTrngParams->userParams.SubSamplingRatio4 > 0) ? 0x8 : 0x0));
+        pTrngParams->SubSamplingRatio = 0;
+        if (pTrngParams->RoscsAllowed == 0) {
+            error = CC_RND_STATE_VALIDATION_TAG_ERROR;
+            goto func_error;
+        }
+
+        return CC_OK;
+func_error:
+        CC_PalMemSetZero(pTrngParams, sizeof(CC_PalTrngParams_t));
+        return error;
+
+
+
+} /* End of RNG_PLAT_SetUserRngParameters */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_plat.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_plat.h
new file mode 100644
index 0000000..e7dde5c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_rng_plat.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_RNG_PLAT_H
+#define  _CC_RNG_PLAT_H
+
+#include "cc_rnd_local.h"
+#include "cc_plat.h"
+
+/****************  Defines  ********************/
+#define CC_RNG_OTP_SUB_SAMPL_RATIO_BIT_SIZE     7
+#define CC_RNG_OTP_SUB_SAMPL_RATIO_MAX_VAL      ((1UL << CC_RNG_OTP_SUB_SAMPL_RATIO_BIT_SIZE) - 1)
+
+/* Default TRNG parameters: used when in OTP set 0 in appropriate bits */
+#define CC_RNG_DEFAULT_ROSCS_ALLOWED_FLAG       0xF
+
+/* Default, increment and mininimal values, for Sampling Ratio */
+
+/* On  FE mode */
+#define CC_RNG_DEFAULT_SAMPL_RATIO_ON_FE_MODE 1000
+#define CC_RNG_SAMPL_RATIO_INCREM_ON_FE_MODE  50
+#define CC_RNG_MIN_SAMPL_RATIO_ON_FE_MODE     1000
+
+/* Maximal value of SamplingRatio */
+#define CC_RNG_MAX_SAMPL_RATIO_ON_SWEE_MODE     CC_RNG_OTP_SUB_SAMPL_RATIO_MAX_VAL
+#define CC_RNG_MAX_SAMPL_RATIO_ON_FE_MODE     (CC_RNG_MIN_SAMPL_RATIO_ON_FE_MODE + \
+                        CC_RNG_SAMPL_RATIO_INCREM_ON_FE_MODE * CC_RNG_OTP_SUB_SAMPL_RATIO_MAX_VAL)
+
+/****************************************************************************************/
+/**
+ *
+ * @brief The function retrievess the TRNG parameters, provided by the User trough NVM,
+ *        and sets them into structures given by pointers rndState_ptr and trngParams_ptr.
+ *
+ * @author reuvenl (6/26/2012)
+ *
+ * @param[out] trngParams_ptr - The pointer to structure, containing parameters
+ *                            of HW TRNG.
+ *
+ * @return CCError_t - no return value
+ */
+CCError_t RNG_PLAT_SetUserRngParameters(
+                        CCRndParams_t  *pTrngParams);
+
+
+#endif  /* _CC_RNG_PLAT_H */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_cmac.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_cmac.c
new file mode 100644
index 0000000..3e3625f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_cmac.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_util_int_defs.h"
+#include "mbedtls_cc_util_defs.h"
+#include "cc_util_error.h"
+#include "cc_aes_defs.h"
+#include "aes_driver.h"
+#include "driver_defs.h"
+#include "cc_util_cmac.h"
+#include "dx_crys_kernel.h"
+
+/************************************************************************************/
+/****************         CMAC key derivation    ************************************/
+/************************************************************************************/
+
+
+CCUtilError_t UtilCmacBuildDataForDerivation( const uint8_t               *pLabel,
+                                             size_t                      labelSize,
+                                             const uint8_t               *pContextData,
+                                             size_t                      contextSize,
+                                             uint8_t            *pDataIn,
+                                             size_t                 *pDataInSize,
+                                             size_t                      derivedKeySize)
+{
+        uint32_t      length = 0;
+        uint32_t      lengthReverse = 0;
+        uint32_t      i = 0;
+
+        /* Check Label, Context, DerivedKey sizes */
+        if (derivedKeySize > CC_UTIL_MAX_DERIVED_KEY_SIZE_IN_BYTES) {
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+        }
+
+        if (derivedKeySize * CC_BITS_IN_BYTE > 0xFF) {
+                length = CC_UTIL_FIX_DATA_MAX_SIZE_IN_BYTES;
+        } else {
+                length = CC_UTIL_FIX_DATA_MIN_SIZE_IN_BYTES;
+        }
+
+        if ( ((labelSize != 0) && (pLabel == NULL)) ||
+             (labelSize == 0) ||
+             (labelSize > CC_UTIL_MAX_LABEL_LENGTH_IN_BYTES) ) {
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+        }
+
+        if ( ((contextSize != 0) && (pContextData == NULL)) ||
+             (contextSize == 0) ||
+             (contextSize > CC_UTIL_MAX_CONTEXT_LENGTH_IN_BYTES) ) {
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+        }
+        if ((pDataIn == NULL) ||
+             (*pDataInSize == 0) ||
+             (*pDataInSize < (contextSize+labelSize+length)) ) {
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+        }
+
+        i = 1;
+        if (labelSize!=0) {
+                CC_PalMemCopy((pDataIn+i), pLabel, labelSize);
+                i+=labelSize;
+        }
+
+        pDataIn[i++] = 0x00;
+
+        if (contextSize!=0) {
+                CC_PalMemCopy((pDataIn+i), pContextData, contextSize);
+                i+=contextSize;
+        }
+
+        length = derivedKeySize * CC_BITS_IN_BYTE;
+        if (length > 0xFF) {
+                /* Reverse words order and bytes in each word */
+                lengthReverse = ((length & 0xFF00)>>8) | ((length & 0xFF)<<8);
+                CC_PalMemCopy((pDataIn+i), (uint8_t*)&lengthReverse, 2);
+                i += 2;
+        } else {
+                CC_PalMemCopy((pDataIn+i), (uint8_t*)&length, 1);
+                i += 1;
+        }
+        *pDataInSize = i;
+
+        return CC_OK;
+}
+CCUtilError_t UtilCmacDeriveKey(UtilKeyType_t       keyType,
+                CCAesUserKeyData_t      *pUserKey,
+                uint8_t         *pDataIn,
+                size_t                  dataInSize,
+                CCUtilAesCmacResult_t   pCmacResult)
+{
+        uint32_t      rc;
+        AesContext_t    aesCtxBuf;
+        CCBuffInfo_t inBuffInfo;
+        CCBuffInfo_t outBuffInfo;
+
+        /* Check inputs */
+        if (NULL == pDataIn) {
+                return CC_UTIL_DATA_IN_POINTER_INVALID_ERROR;
+        }
+        if (NULL == pCmacResult) {
+                return CC_UTIL_DATA_OUT_POINTER_INVALID_ERROR;
+        }
+        if ((dataInSize < CC_UTIL_CMAC_DERV_MIN_DATA_IN_SIZE) ||
+            (dataInSize > CC_UTIL_CMAC_DERV_MAX_DATA_IN_SIZE)) {
+                return CC_UTIL_DATA_IN_SIZE_INVALID_ERROR;
+        }
+
+        switch(keyType){
+        case UTIL_ROOT_KEY:
+                /* Set AES key to ROOT KEY */
+                aesCtxBuf.cryptoKey = RKEK_KEY;
+                aesCtxBuf.keySizeId = KEY_SIZE_256_BIT;
+                break;
+        case UTIL_KCP_KEY:
+                /* Set AES key to ROOT KEY */
+                aesCtxBuf.cryptoKey = KCP_KEY;
+                aesCtxBuf.keySizeId = KEY_SIZE_128_BIT;
+                break;
+        case UTIL_KPICV_KEY:
+                /* Set AES key to ROOT KEY */
+                aesCtxBuf.cryptoKey = KPICV_KEY;
+                aesCtxBuf.keySizeId = KEY_SIZE_128_BIT;
+                break;
+        case UTIL_USER_KEY:
+                if ((pUserKey->keySize != CC_UTIL_AES_128BIT_SIZE) &&
+                    (pUserKey->keySize != CC_UTIL_AES_192BIT_SIZE) &&
+                    (pUserKey->keySize != CC_UTIL_AES_256BIT_SIZE)) {
+                        return CC_UTIL_INVALID_USER_KEY_SIZE;
+                }
+                /* Set AES key to USER KEY, and copy the key to the context */
+                aesCtxBuf.cryptoKey = USER_KEY;
+                switch (pUserKey->keySize) {
+                case CC_UTIL_AES_128BIT_SIZE:
+                        aesCtxBuf.keySizeId = KEY_SIZE_128_BIT;
+                        break;
+                case CC_UTIL_AES_192BIT_SIZE:
+                        aesCtxBuf.keySizeId = KEY_SIZE_192_BIT;
+                        break;
+                case CC_UTIL_AES_256BIT_SIZE:
+                        aesCtxBuf.keySizeId = KEY_SIZE_256_BIT;
+                        break;
+                default:
+                        break;
+                }
+                CC_PalMemCopy(aesCtxBuf.keyBuf, pUserKey->pKey, pUserKey->keySize);
+                break;
+        default:
+                return CC_UTIL_INVALID_KEY_TYPE;
+        }
+
+
+        /* call CC_AES_Init with CMAC */
+        aesCtxBuf.mode               = CIPHER_CMAC;
+        aesCtxBuf.dir                = CRYPTO_DIRECTION_ENCRYPT;
+        aesCtxBuf.dataBlockType      = FIRST_BLOCK;
+        aesCtxBuf.inputDataAddrType  = DLLI_ADDR;
+        aesCtxBuf.outputDataAddrType = DLLI_ADDR;
+        CC_PalMemSetZero(aesCtxBuf.ivBuf, AES_IV_SIZE);
+
+        /* set data buffers structures */
+        rc = SetDataBuffersInfo(pDataIn, dataInSize, &inBuffInfo,
+                                pCmacResult, CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES, &outBuffInfo);
+        if (rc != 0) {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return CC_UTIL_FATAL_ERROR;
+        }
+
+        rc = FinishAesDrv(&aesCtxBuf, &inBuffInfo, &outBuffInfo, dataInSize);
+        if (rc != 0) {
+                return CC_UTIL_FATAL_ERROR;
+        }
+
+        CC_PalMemCopy(pCmacResult, aesCtxBuf.ivBuf, CC_AES_BLOCK_SIZE_IN_BYTES);
+
+        return CC_UTIL_OK;
+}
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_cmac.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_cmac.h
new file mode 100644
index 0000000..318fd53
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_cmac.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_UTIL_CMAC_H
+#define  _CC_UTIL_CMAC_H
+
+#include "cc_util_int_defs.h"
+
+/*! Defines the CMAC result buffer. */
+typedef uint8_t CCUtilAesCmacResult_t[CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES];
+
+CCUtilError_t UtilCmacBuildDataForDerivation( const uint8_t               *pLabel,
+                                             size_t                      labelSize,
+                                             const uint8_t               *pContextData,
+                                             size_t                      contextSize,
+                                             uint8_t            *pDataIn,
+                                             size_t                 *pDataInSize,
+                                             size_t                      derivedKeySize);
+/*!
+ * This function is used to generate bytes stream for key derivation purposes.
+ * The function gets an input data and can use use one of the following keys: KDR/Session/userKey.
+ *
+ * @param[in] keyType       - UTIL_USER_KEY / UTIL_ROOT_KEY
+ * @param[in] pUserKey      - A pointer to the user's key buffer (case of CC_UTIL_USER_KEY).
+ * @param[in] pDataIn       - A pointer to input buffer.
+ * @param[in] dataInSize    - Size of data in bytes.
+ * @param[out] pCmacResult  - A pointer to output buffer 16 bytes array.
+ *
+ * @return CC_UTIL_OK on success, otherwise failure
+ *
+ */
+CCUtilError_t UtilCmacDeriveKey(UtilKeyType_t       keyType,
+                CCAesUserKeyData_t      *pUserKey,
+                uint8_t         *pDataIn,
+                size_t                  dataInSize,
+                CCUtilAesCmacResult_t   pCmacResult);
+
+
+#endif /* _CC_UTIL_CMAC_H */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_int_defs.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_int_defs.h
new file mode 100644
index 0000000..1f4e0d6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_util_int_defs.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_UTIL_INT_DEFS_H
+#define  _CC_UTIL_INT_DEFS_H
+
+typedef enum  {
+    UTIL_USER_KEY = 0,
+    UTIL_ROOT_KEY = 1,
+    UTIL_KCP_KEY = 2,
+    UTIL_KCE_KEY = 3,
+    UTIL_KPICV_KEY = 4,
+    UTIL_KCEICV_KEY = 5,
+    UTIL_END_OF_KEY_TYPE = 0x7FFFFFFF
+}UtilKeyType_t;
+
+
+#endif /*_CC_UTIL_INT_DEFS_H*/
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_sbrt.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_sbrt.c
new file mode 100644
index 0000000..38eee44
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_sbrt.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_SECURE_BOOT
+
+/************* Include Files ****************/
+#include "secureboot_stage_defs.h"
+#include "bootimagesverifier_api.h"
+#include "bootimagesverifier_error.h"
+#include "bootimagesverifier_parser.h"
+#include "secdebug_defs.h"
+
+
+/************************ Defines ******************************/
+
+
+/************************ Enums ******************************/
+
+
+/************************ Typedefs ******************************/
+
+
+/************************ Global Data ******************************/
+
+/************************ Private functions  ******************************/
+
+/************************ Public functions  ******************************/
+
+CCError_t mbedtls_sb_cert_chain_cerification_init(CCSbCertInfo_t *certPkgInfo)
+{
+    return CC_SbCertChainVerificationInit(certPkgInfo);
+}
+
+
+CCError_t mbedtls_sb_cert_verify_single(CCSbFlashReadFunc flashReadFunc,
+                                void *userContext,
+                                CCAddr_t certStoreAddress,
+                                CCSbCertInfo_t *pCertPkgInfo,
+                                uint32_t *pHeader,     // used for X509 header
+                                uint32_t  headerSize,
+                                uint32_t *pWorkspace,
+                                uint32_t workspaceSize)
+{
+        return CC_SbCertVerifySingle(flashReadFunc,
+                      userContext,
+                      0, /* hwBaseAddress NA for RT */
+                      certStoreAddress,
+                      pCertPkgInfo,
+                      pHeader,
+                      headerSize,
+                      pWorkspace,
+                      workspaceSize);
+}
+
+
+CCError_t mbedtls_sb_sw_image_store_address_change(uint32_t *pCert, uint32_t maxCertSizeWords, CCAddr_t address, uint32_t indexOfAddress)
+{
+
+    CCError_t error = CC_OK;
+    uint32_t unsignedDataOffsetWords;
+    uint32_t *pCurrRecAddInfo = NULL;
+
+    /* Check inputs */
+    if (pCert == NULL){
+         CC_PAL_LOG_DEBUG("pCert is NULL\n");
+         return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+    if (maxCertSizeWords == 0){
+         CC_PAL_LOG_DEBUG("maxCertSizeWords is zero\n");
+         return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+        /* Get certificate offset(in words)to unsigned data part */
+        error = CCCertGetUnsignedDataOffset(pCert, &unsignedDataOffsetWords);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed CCCertGetUnsignedDataOffset 0x%x\n", error);
+            return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+        }
+
+    /* Check the buffer size boundaries (up to referred SW index) */
+    if ( ((unsignedDataOffsetWords + (indexOfAddress+1)*SW_REC_NONE_SIGNED_DATA_SIZE_IN_WORDS) > maxCertSizeWords ) ||
+         ((unsignedDataOffsetWords + (indexOfAddress+1)*SW_REC_NONE_SIGNED_DATA_SIZE_IN_WORDS) < unsignedDataOffsetWords) ) {
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+    /* Point to the relevant address and verify there is no wrap around in the memory */
+    pCurrRecAddInfo = pCert + unsignedDataOffsetWords + indexOfAddress*SW_REC_NONE_SIGNED_DATA_SIZE_IN_WORDS;
+    if (pCurrRecAddInfo < pCert){
+        return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+    CC_PAL_LOG_DEBUG("current address is 0x%x, new address is 0x%x\n", (CCAddr_t)(*pCurrRecAddInfo), address);
+
+    UTIL_MemCopy((uint8_t*)pCurrRecAddInfo, (uint8_t*)&address, sizeof(CCAddr_t));
+
+    return CC_OK;
+}
+
+
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_sbrt.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_sbrt.h
new file mode 100644
index 0000000..3b4bb46
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_sbrt.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+@addtogroup cc_sbrt
+@{
+ */
+
+/*!
+ @file
+ @brief This file contains CryptoCell Secure Boot certificate-chain processing APIs.
+ */
+
+#ifndef  _MBEDTLS_CC_SBRT_H
+#define  _MBEDTLS_CC_SBRT_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "secureboot_defs.h"
+#include "secureboot_gen_defs.h"
+/*!
+  @brief This function initializes the Secure Boot certificate-chain
+  processing.
+
+  It initializes the internal data fields of the certificate package.
+
+  @note This function must be the first API called when processing a Secure
+  Boot certificate chain.
+
+  @return \c CC_OK on success.
+  @return A non-zero value from bsv_error.h on failure.
+ */
+
+CCError_t mbedtls_sb_cert_chain_cerification_init(
+    /*! [in/out] A pointer to the information about the certificate package. */
+    CCSbCertInfo_t *certPkgInfo
+    );
+
+/*!
+  @brief This function verifies a single certificate package containing
+  either a key or content certificate.
+
+  It verifies the following:
+  <ul><li>The public key as saved in the certificate, against its hash.
+  Its hash is found in either the OTP memory (HBK) or in \p certPkgInfo.</li>
+  <li>The RSA signature of the certificate.</li>
+  <li>The SW version in the certificate is higher than or equal to the minimal
+  SW version, as recorded on the device and passed in \p certPkgInfo.</li>
+  <li>For content certificates: Each SW module against its hash in the
+  certificate.</li></ul>
+
+  @note The certificates may reside in the memory or in the flash. The
+  flashReadFunc() must be implemented accordingly. \par
+  @note The certificates and images must both be placed either in the
+  memory or in the flash. \par
+
+  @return \c CC_OK on success.
+  @return A non-zero value from bsv_error.h on failure.
+ */
+CCError_t mbedtls_sb_cert_verify_single(
+    /*! [in] A pointer to the flash-read function. */
+    CCSbFlashReadFunc flashReadFunc,
+        /*! [in] An additional pointer for flashRead() usage. May be NULL. */
+        void *userContext,
+        /*! [in] The address where the certificate is located. This address is
+        provided to \p flashReadFunc. */
+        CCAddr_t certStoreAddress,
+        /*! [in/out] A pointer to the certificate-package information. */
+        CCSbCertInfo_t *pCertPkgInfo,
+        /*! [in/out] A pointer to a buffer used for extracting the X.509 TBS
+        Headers. Note: Must be NULL for proprietary certificates. */
+        uint32_t *pHeader,
+        /*! [in] The size of \p pHeader in Bytes. Note: Must be 0 for
+        proprietary certificates. */
+        uint32_t  headerSize,
+        /*! [in] A buffer for the internal use of the function. */
+        uint32_t *pWorkspace,
+        /*! [in] The size of the workspace in bytes. Note: Must be at least
+        #CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES. */
+        uint32_t workspaceSize
+    );
+
+/*!
+  @brief This function changes the storage address of a specific SW image in
+  the content certificate.
+
+  @note The certificate must be loaded to the RAM before calling this
+  function. \par
+  @note The function does not verify the certificate before the address change. \par
+
+  @return \c CC_OK on success.
+  @return A non-zero value from bsv_error.h on failure.
+ */
+CCError_t mbedtls_sb_sw_image_store_address_change(
+    /*! [in] The certificate address after it has been loaded to memory. */
+    uint32_t *pCert,
+    /*! [in] The maximal memory size allocated for the certificate in words
+    (certificate boundaries). */
+    uint32_t maxCertSizeWords,
+    /*! [in] The new storage address to change to. */
+    CCAddr_t address,
+    /*! [in] The index of the SW image in the content certificate, starting
+    from 0. */
+    uint32_t indexOfAddress
+    );
+
+#ifdef __cplusplus
+}
+
+#endif /*_MBEDTLS_SBRT_H*/
+
+/*!
+ @}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_util_asset_prov.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_util_asset_prov.c
new file mode 100644
index 0000000..37f8863
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_util_asset_prov.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_util_int_defs.h"
+#include "mbedtls_cc_util_defs.h"
+#include "cc_util_error.h"
+#include "cc_aes_defs.h"
+#include "ccm.h"
+#include "aes_driver.h"
+#include "driver_defs.h"
+#include "cc_util_cmac.h"
+#include "mbedtls_cc_util_asset_prov.h"
+#include "cc_util_asset_prov_int.h"
+
+
+CCError_t mbedtls_util_asset_pkg_unpack(CCAssetProvKeyType_t        keyType,
+            uint32_t        assetId,
+            uint32_t        *pAssetPkgBuff,
+            size_t          assetPackageLen,
+            uint32_t        *pAssetData,
+            size_t          *pAssetDataLen)
+{
+    uint32_t  rc = CC_OK;
+    CCUtilAesCmacResult_t         keyProv = { 0 };
+    uint8_t     dataIn[CC_UTIL_MAX_KDF_SIZE_IN_BYTES] = { 0 };
+    size_t    dataInSize = CC_UTIL_MAX_KDF_SIZE_IN_BYTES;
+    uint8_t     provLabel = 'P';
+    CCAssetProvPkg_t   *pAssetPackage = NULL;
+    mbedtls_ccm_context ccmCtx;
+    uint8_t    ccmAddData[CC_ASSET_PROV_ADATA_SIZE] = { 0 };
+    uint8_t    ccmNonceData[CC_ASSET_PROV_NONCE_SIZE] = { 0 };
+    uint32_t    assetDataSize = 0;
+    uint32_t    constPkgSize = CC_ASSET_PROV_ADATA_SIZE+CC_ASSET_PROV_NONCE_SIZE+CC_ASSET_PROV_TAG_SIZE;
+    uint32_t    minPkgSize = constPkgSize+CC_ASSET_PROV_BLOCK_SIZE;
+
+    /* Validate Inputs */
+    if ((pAssetPkgBuff == NULL) ||
+        (pAssetData == NULL) ||
+        (pAssetDataLen == NULL) ||
+        (assetPackageLen > CC_ASSET_PROV_MAX_ASSET_PKG_SIZE) ||
+        (assetPackageLen < minPkgSize) ||
+        /* Overlapping verification */
+        (((unsigned long)pAssetPkgBuff + assetPackageLen) < (unsigned long)pAssetPkgBuff) ||
+        (assetPackageLen  % CC_32BIT_WORD_SIZE) ||
+        ((keyType != ASSET_PROV_KEY_TYPE_KPICV) && (keyType != ASSET_PROV_KEY_TYPE_KCP))) {
+            CC_PAL_LOG_ERR("Invalid params");
+            return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+    }
+    pAssetPackage = (CCAssetProvPkg_t *)pAssetPkgBuff;
+
+    /* Validate asset size, must be multiply of 16 bytes */
+    if ((pAssetPackage->assetSize > CC_ASSET_PROV_MAX_ASSET_SIZE) ||
+        (pAssetPackage->assetSize == 0) ||
+        (pAssetPackage->assetSize % CC_ASSET_PROV_BLOCK_SIZE)) {
+            CC_PAL_LOG_ERR("Invalid asset size 0x%x", pAssetPackage->assetSize);
+            return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+    }
+    /* Verify assetDataSize against assetPkgSize */
+    if ((assetPackageLen < (constPkgSize+pAssetPackage->assetSize)) ||
+        (*pAssetDataLen  < pAssetPackage->assetSize)) {
+            CC_PAL_LOG_ERR("Invalid asset size 0x%x", pAssetPackage->assetSize);
+            return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+    }
+    /* Verify package token and version */
+    if ((pAssetPackage->token != CC_ASSET_PROV_TOKEN) ||
+        (pAssetPackage->version != CC_ASSET_PROV_VERSION)) {
+            CC_PAL_LOG_ERR("Invalid token or version");
+            return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+    }
+
+    /* Generate dataIn buffer for CMAC: iteration || 'P' || 0x00 || asset Id || 0x80
+           since deruved key is 128 bits we have only 1 iteration */
+    rc = UtilCmacBuildDataForDerivation(&provLabel,sizeof(provLabel),
+                                          (uint8_t *)&assetId, sizeof(assetId),
+                                         dataIn, &dataInSize,
+                                         (size_t)CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES);
+    if (rc != 0) {
+            CC_PAL_LOG_ERR("Failed UtilCmacBuildDataForDerivation 0x%x", rc);
+            return rc;
+    }
+    dataIn[0] = 1;  // only 1 iteration
+    rc = UtilCmacDeriveKey((keyType == ASSET_PROV_KEY_TYPE_KPICV)?UTIL_KPICV_KEY:UTIL_KCP_KEY,
+                            NULL,
+                            dataIn, dataInSize,
+                            keyProv);
+    if (rc != 0) {
+            CC_PAL_LOG_ERR("Failed UtilCmacDeriveKey 0x%x", rc);
+            return rc;
+    }
+
+    /* Decrypt and authenticate the BLOB */
+    mbedtls_ccm_init(&ccmCtx);
+
+    rc = mbedtls_ccm_setkey(&ccmCtx, MBEDTLS_CIPHER_ID_AES, keyProv, CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES * CC_BITS_IN_BYTE);
+    if (rc != 0) {
+            CC_PAL_LOG_ERR("Failed to mbedtls_ccm_setkey 0x%x\n", rc);
+            return rc;
+    }
+
+    assetDataSize = pAssetPackage->assetSize;
+    CC_PalMemCopy(ccmNonceData, pAssetPackage->nonce, CC_ASSET_PROV_NONCE_SIZE);
+    CC_PalMemCopy(ccmAddData, (uint8_t *)pAssetPackage, CC_ASSET_PROV_ADATA_SIZE);
+    rc = mbedtls_ccm_auth_decrypt(&ccmCtx, pAssetPackage->assetSize,
+                                  ccmNonceData, CC_ASSET_PROV_NONCE_SIZE,
+                                  ccmAddData, CC_ASSET_PROV_ADATA_SIZE,
+                                  pAssetPackage->encAsset, (uint8_t *)pAssetData,
+                                  pAssetPackage->encAsset + pAssetPackage->assetSize, CC_ASSET_PROV_TAG_SIZE);
+    if (rc != 0) {
+            CC_PAL_LOG_ERR("Failed to mbedtls_ccm_auth_decrypt 0x%x\n", rc);
+            return rc;
+    }
+
+    // Set output data
+    *pAssetDataLen = assetDataSize;
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_util_asset_prov.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_util_asset_prov.h
new file mode 100644
index 0000000..136a48c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/mbedtls_cc_util_asset_prov.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_util_asset_prov
+ @{
+*/
+
+/*!
+ @file mbedtls_cc_util_asset_prov.h
+ @brief This file contains CryptoCell runtime-library ICV and OEM asset-provisioning APIs and definitions.
+ */
+
+
+#ifndef  _MBEDTLS_CC_UTIL_ASSET_PROV_H
+#define  _MBEDTLS_CC_UTIL_ASSET_PROV_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "cc_pal_types_plat.h"
+
+/*! The maximal size of an asset package. */
+#define CC_ASSET_PROV_MAX_ASSET_PKG_SIZE  4144
+
+/*! The type of key used to pack the asset. */
+typedef enum {
+       /*! The ICV provisioning key (Kpicv) key was used to pack the asset. */
+       ASSET_PROV_KEY_TYPE_KPICV = 1,
+       /*! The OEM provisioning key (Kcp) key was used to pack the asset. */
+       ASSET_PROV_KEY_TYPE_KCP = 2,
+       /*! Reserved. */
+       ASSET_PROV_KEY_TYPE_RESERVED    = 0x7FFFFFFF,
+} CCAssetProvKeyType_t;
+
+
+/*!
+ @brief This function securely provisions ICV or OEM assets to devices using
+ CryptoCell.
+
+ The function:
+ <ol>
+ <li>Receives an encrypted and autenticated asset package.
+ \note This asset package is produced by the ICV or OEM asset-packaging
+ offline utility (using AES-CCM with key derived from Kpicv or Kcp
+ respectively, and the asset identifier).</li>
+ <li>Authenticates the asset package.</li>
+ <li>Decrypts the asset package.</li>
+ <li>Returns the decrypted asset data to the caller.</li></ol>
+
+ @note  The function is valid in all life-cycle states. However, an error
+ is returned if the requested key is locked.
+
+ @return \c CC_UTIL_OK on success.
+ @return A non-zero value on failure, as defined in cc_util_error.h.
+ */
+CCError_t mbedtls_util_asset_pkg_unpack(
+        /*! [in] The type of key used to pack the asset.*/
+        CCAssetProvKeyType_t        keyType,
+        /*! [in] A 32-bit index identifying the asset, in big-endian order. */
+        uint32_t                    assetId,
+        /*! [in] The encrypted and authenticated asset package. */
+        uint32_t                    *pAssetPackage,
+        /*! [in] The length of the asset package. Must not exceed
+        CC_ASSET_PROV_MAX_ASSET_PKG_SIZE. */
+        size_t                      assetPackageLen,
+        /*! [out] The buffer for retrieving the decrypted asset data. */
+        uint32_t                    *pAssetData,
+        /*! [in, out] In: The size of the available asset-data buffer. Maximal
+        size is 4KB. Out: A pointer to the actual length of the decrypted
+        asset data. */
+        size_t                      *pAssetDataLen
+        );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /*_MBEDTLS_CC_UTIL_ASSET_PROV_H*/
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/sbrt_int_func.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/sbrt_int_func.c
new file mode 100644
index 0000000..1f53243
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/sbrt_int_func.c
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+
+#include "secureboot_defs.h"
+#include "secureboot_stage_defs.h"
+#include "secureboot_gen_defs.h"
+#include "bootimagesverifier_error.h"
+#include "bsv_error.h"
+#include "secdebug_defs.h"
+#include "secureboot_base_swimgverify.h"
+#include "cc_hal.h"
+#include "mbedtls_cc_mng_int.h"
+#include "mbedtls_cc_mng_error.h"
+#include "cc_util_pm.h"
+#include "cc_int_general_defs.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+extern CC_PalMutex CCAsymCryptoMutex;
+extern CC_PalMutex CCSymCryptoMutex;
+
+/************************ Private functions  ******************************/
+
+static CCError_t GetMngKeyIndex(CCSbPubKeyIndexType_t keyIndex, mbedtls_mng_pubKeyType_t *mngKeyIndex)
+{
+    switch (keyIndex) {
+        case CC_SB_HASH_BOOT_KEY_0_128B:
+            *mngKeyIndex = CC_MNG_HASH_BOOT_KEY_0_128B;
+            break;
+        case CC_SB_HASH_BOOT_KEY_1_128B:
+            *mngKeyIndex = CC_MNG_HASH_BOOT_KEY_1_128B;
+            break;
+        case CC_SB_HASH_BOOT_KEY_256B:
+            *mngKeyIndex = CC_MNG_HASH_BOOT_KEY_256B;
+            break;
+        case CC_SB_HASH_BOOT_NOT_USED:
+            *mngKeyIndex = CC_MNG_HASH_BOOT_NOT_USED;
+            break;
+        case CC_SB_HASH_MAX_NUM:
+            *mngKeyIndex = CC_MNG_HASH_MAX_NUM;
+            break;
+        default:
+            return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    return CC_OK;
+}
+
+/************************ Public functions  ******************************/
+
+CCError_t SBRT_ImageLoadAndVerify(CCSbFlashReadFunc preHashflashRead_func,
+                                  void *preHashUserContext,
+                                  unsigned long hwBaseAddress,
+                                  uint8_t isLoadFromFlash,
+                                  uint8_t isVerifyImage,
+                                  bsvCryptoMode_t cryptoMode,
+                                  CCBsvKeyType_t keyType,
+                                  AES_Iv_t AESIv,
+                                  uint8_t *pSwRecSignedData,
+                                  uint32_t *pSwRecNoneSignedData,
+                                  uint32_t *workspace_ptr,
+                                  uint32_t workspaceSize)
+{
+    CCError_t error = CC_OK;
+    ContentCertImageRecord_t cntImageRec;
+
+    /* Loading only is not supported for SBRT */
+    if (isVerifyImage == CC_FALSE){
+            return CC_BOOT_IMG_VERIFIER_INV_INPUT_PARAM;
+    }
+
+    /* In any case, loading operation shall be ignored (and not failed) and the image will be only verified. */
+    if (isLoadFromFlash == CC_TRUE){
+
+            /* Initialize parameters */
+            CC_PalMemCopy((uint8_t *)&cntImageRec, pSwRecSignedData, sizeof(ContentCertImageRecord_t));
+
+            /* overwrite load address to ignore loading */
+            cntImageRec.loadAddr = CC_SW_COMP_NO_MEM_LOAD_INDICATION;
+            CC_PalMemCopy(pSwRecSignedData, (uint8_t*)&cntImageRec, sizeof(ContentCertImageRecord_t));
+    }
+
+    /* lock mutex for more CC operations */
+    error = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+    if (error != 0) {
+            CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* increase CC counter at the beginning of each operation */
+    error = CC_IS_WAKE;
+    if (error != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+    }
+
+    error = CCSbImageLoadAndVerify(preHashflashRead_func, preHashUserContext,
+                                   hwBaseAddress, isLoadFromFlash, isVerifyImage,
+                                   cryptoMode, keyType, AESIv, pSwRecSignedData,
+                                   pSwRecNoneSignedData, workspace_ptr, workspaceSize);
+
+    /* decrease CC counter at the end of each operation */
+    if (CC_IS_IDLE != CC_SUCCESS) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+    }
+
+    /* release mutex */
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+            CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return error;
+}
+
+CCError_t SBRT_RSA_PSS_Verify(unsigned long hwBaseAddress,      /* [in] HW base address of registers. */
+                              CCHashResult_t mHash,         /* [in] Pointer to the SHA256 hash of the message. */
+                              uint32_t      *pN,                /* [in] Pointer to the RSA modulus (LE words array). */
+                              uint32_t      *pNp,           /* [in] Pointer to the Barrett tag of the RSA modulus (LE words array). */
+                              uint32_t      *pSign              /* [out] Pointer to the signature output (it is placed as BE bytes
+                                                                array into words buffer for alignments goal). */)
+{
+
+    CCError_t error = CC_OK;
+
+    error = CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE);
+    if (error != CC_SUCCESS) {
+            CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* verify that the device is not in fatal error state before activating the PKA engine */
+    CC_IS_FATAL_ERR_ON(error);
+    if (error == CC_TRUE) {
+            error = CC_BSV_FATAL_ERR_IS_LOCKED_ERR;
+            goto _EndUnlockMutex;
+    }
+
+    /* increase CC counter at the beginning of each operation */
+    error = CC_IS_WAKE;
+    if (error != CC_SUCCESS) {
+            CC_PalAbort("Fail to increase PM counter\n");
+    }
+
+    error = RSA_PSS_Verify(hwBaseAddress, mHash, pN, pNp, pSign);
+
+    /* decrease CC counter at the end of each operation */
+    if (CC_IS_IDLE != CC_SUCCESS) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+    }
+
+_EndUnlockMutex:
+    if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
+            CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return error;
+
+}
+
+void SBRT_HalClearInterruptBit(unsigned long hwBaseAddress, uint32_t data)
+{
+    CC_UNUSED_PARAM(hwBaseAddress);
+    CC_HalClearInterruptBit(data);
+    return;
+}
+
+void SBRT_HalMaskInterrupt(unsigned long hwBaseAddress, uint32_t data)
+{
+    CC_UNUSED_PARAM(hwBaseAddress);
+    CC_HalMaskInterrupt(data);
+    return;
+}
+
+CCError_t SBRT_HalWaitInterrupt(unsigned long hwBaseAddress, uint32_t data)
+{
+    CC_UNUSED_PARAM(hwBaseAddress);
+    return CC_HalWaitInterrupt(data);
+}
+
+CCError_t SBRT_LcsGet(unsigned long hwBaseAddress, uint32_t *pLcs)
+{
+
+    CC_UNUSED_PARAM(hwBaseAddress);
+    return mbedtls_mng_lcsGet(pLcs);
+}
+
+CCError_t SBRT_OTPWordRead(unsigned long hwBaseAddress, uint32_t otpAddress, uint32_t *pOtpWord)
+{
+    CC_UNUSED_PARAM(hwBaseAddress);
+    return mbedtls_mng_otpWordRead(otpAddress, pOtpWord);
+}
+
+CCError_t SBRT_SwVersionGet(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t *swVersion)
+{
+    CCError_t error = CC_OK;
+    mbedtls_mng_pubKeyType_t mngKeyIndex;
+
+    CC_UNUSED_PARAM(hwBaseAddress);
+
+    error = GetMngKeyIndex(keyIndex, &mngKeyIndex);
+    if (error != CC_OK)
+        return error;
+
+    return mbedtls_mng_swVersionGet(mngKeyIndex, swVersion);
+}
+
+CCError_t SBRT_PubKeyHashGet(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t *hashedPubKey, uint32_t hashResultSizeWords)
+{
+    CCError_t error = CC_OK;
+    mbedtls_mng_pubKeyType_t mngKeyIndex;
+
+    CC_UNUSED_PARAM(hwBaseAddress);
+
+    error = GetMngKeyIndex(keyIndex, &mngKeyIndex);
+    if (error != CC_OK)
+        return error;
+
+    return mbedtls_mng_pubKeyHashGet(mngKeyIndex, hashedPubKey, hashResultSizeWords);
+}
+
+CCError_t SBRT_SHA256( unsigned long        hwBaseAddress,
+                       uint8_t          *pDataIn,
+                       size_t                   dataSize,
+                       CCHashResult_t       hashBuff)
+{
+    CCError_t error = CC_OK;
+
+    /* verify that data is limited to 64KB */
+    if ( dataSize >= CC_BSV_SHA256_MAX_DATA_SIZE_IN_BYTES) {
+            return CC_BSV_INVALID_DATA_SIZE_ERROR;
+    }
+
+    /* verify valid buffer pointer */
+    if ( (pDataIn == NULL) && (dataSize!=0) ) {
+            return CC_BSV_INVALID_DATA_IN_POINTER_ERROR;
+    }
+
+    /* verify valid buffer pointer */
+    if (hashBuff == NULL) {
+            return CC_BSV_INVALID_RESULT_BUFFER_POINTER_ERROR;
+    }
+
+    /* lock mutex for more CC operations */
+    error = CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE);
+    if (error != 0) {
+            CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* increase CC counter at the beginning of each operation */
+    error = CC_IS_WAKE;
+    if (error != 0) {
+            CC_PalAbort("Fail to increase PM counter\n");
+    }
+
+    InitBsvHash(hwBaseAddress);
+
+    error = ProcessBsvHash(hwBaseAddress, (uint32_t)pDataIn, dataSize);
+    if (error != CC_OK){
+            // in case of error, ProcessBsvHash responsible to call FreeBsvHash
+            UTIL_MemSet((uint8_t*)hashBuff, 0, CC_BSV_SHA256_DIGEST_SIZE_IN_BYTES);
+            goto _END_SHA256;
+    }
+
+    FinishBsvHash(hwBaseAddress, hashBuff);
+
+_END_SHA256:
+    /* decrease CC counter at the end of each operation */
+    if (CC_IS_IDLE != CC_SUCCESS) {
+            CC_PalAbort("Fail to decrease PM counter\n");
+    }
+
+    /* release mutex */
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+            CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return error;
+}
+
+CCError_t SBRT_CryptoImageInit( unsigned long   hwBaseAddress,
+                                bsvCryptoMode_t mode,
+                                CCBsvKeyType_t  keyType)
+{
+    /* verify tunneling mode */
+    if ((mode!=BSV_CRYPTO_HASH) &&
+            (mode!=BSV_CRYPTO_AES_AND_HASH) &&
+            (mode!=BSV_CRYPTO_AES_TO_HASH_AND_DOUT)){
+            return CC_BSV_INVALID_CRYPTO_MODE_ERROR;
+    }
+
+    if(mode != BSV_CRYPTO_HASH){
+            /* for image decryption only KCE and KCEICV are supported */
+            if ((keyType!=CC_BSV_CE_KEY) && (keyType!=CC_BSV_ICV_CE_KEY)){
+                    return CC_BSV_INVALID_KEY_TYPE_ERROR;
+            }
+    }
+
+    /* initiate HW engines */
+    InitBsvHash(hwBaseAddress);
+
+    if (mode != BSV_CRYPTO_HASH){
+        InitBsvAes(hwBaseAddress);
+
+        /* overwrite crypto mode */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,mode);
+    }
+
+    return CC_OK;
+}
+
+CCError_t SBRT_CryptoImageUpdate( unsigned long     hwBaseAddress,
+                                  bsvCryptoMode_t   mode,
+                                  CCBsvKeyType_t        keyType,
+                                  uint32_t      *pCtrStateBuf,
+                                  uint8_t       *pDataIn,
+                                  uint8_t       *pDataOut,
+                                  size_t                dataSize,
+                                  CCHashResult_t        hashBuff,
+                                  uint8_t       isLoadIV)
+{
+    CCError_t error = CC_OK;
+
+    /* data in processing */
+    if (mode == BSV_CRYPTO_HASH){
+            error = ProcessBsvHash(hwBaseAddress, (uint32_t)pDataIn, dataSize);
+    } else {
+            error = ProcessBsvAes(hwBaseAddress, BSV_AES_CIPHER_CTR, keyType, NULL, CC_BSV_128BITS_KEY_SIZE_IN_BYTES,
+                                  pCtrStateBuf, (uint32_t)pDataIn, (uint32_t)pDataOut, dataSize, isLoadIV);
+    }
+
+    if (error != CC_OK){
+        FreeBsvHash(hwBaseAddress);
+        UTIL_MemSet((uint8_t*)hashBuff, 0, CC_BSV_SHA256_DIGEST_SIZE_IN_BYTES);
+    }
+
+    return error;
+}
+
+
+CCError_t SBRT_CryptoImageFinish( unsigned long     hwBaseAddress,
+                                  bsvCryptoMode_t   mode,
+                                  CCHashResult_t        hashBuff)
+{
+
+    /* close HW engines */
+
+    FinishBsvHash(hwBaseAddress, hashBuff);
+    if (mode != BSV_CRYPTO_HASH){
+            FinishBsvAes(hwBaseAddress, BSV_AES_CIPHER_CTR, NULL);
+    }
+
+    return CC_OK;
+}
+
+uint32_t SBRT_MemCmp( uint8_t *pBuff1 , uint8_t *pBuff2 , uint32_t size)
+{
+    /* same as ROM  code for security issues */
+
+    /* loop variable */
+    uint32_t i;
+    uint32_t stat = 0;
+
+    /* FUNCTION LOGIC */
+
+    for( i = 0; i < size; i++ ) {
+            stat |= (pBuff1[i] ^ pBuff2[i]);
+    }
+
+    if(stat == 0)
+        return CC_TRUE;
+    else
+        return CC_FALSE;
+
+}
+
+void SBRT_ReverseMemCopy( uint8_t *pDst, uint8_t *pSrc, uint32_t size)
+{
+    /* FUNCTION DECLARATIONS */
+
+    /* loop variable */
+    uint32_t i;
+    uint8_t tmp;
+
+    /* buffers position identifiers */
+    uint32_t dstPos, srcPos;
+
+    /* FUNCTION LOGIC */
+
+    /* initialize the source and the destination position */
+    dstPos = size - 1;
+    srcPos = 0;
+
+    /* execute the reverse copy in case of different buffers */
+    if (pDst != pSrc) {
+            for( i = 0 ; i < size ; i++ )
+                pDst[dstPos--] = pSrc[srcPos++];
+    } else {
+            /* execute the reverse copy in case of in-place reversing */
+            for( i = 0 ; i < size/2 ; i++ ) {
+                    tmp = pDst[dstPos];
+                    pDst[dstPos--] = pSrc[srcPos];
+                    pSrc[srcPos++] = tmp;
+            }
+    }
+
+    return;
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/sbrt_int_func.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/sbrt_int_func.h
new file mode 100644
index 0000000..32badb8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/sbrt_int_func.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _SBRT_INT_FUNC_H
+#define _SBRT_INT_FUNC_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "secureboot_gen_defs.h"
+
+/* The AES block size in words and in bytes */
+#define AES_BLOCK_SIZE_IN_WORDS 4
+/* The size of the AES KEY in words and bytes */
+#define AES_KEY_SIZE_IN_WORDS AES_BLOCK_SIZE_IN_WORDS
+/* The size of the IV or counter buffer */
+#define AES_IV_COUNTER_SIZE_IN_WORDS   AES_BLOCK_SIZE_IN_WORDS
+#define AES_IV_COUNTER_SIZE_IN_BYTES  (AES_IV_COUNTER_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/* Defines the AES key buffer */
+typedef uint32_t AES_Key_t[AES_KEY_SIZE_IN_WORDS];
+/* Defines the IV counter buffer  - 16 bytes array */
+typedef uint32_t AES_Iv_t[AES_IV_COUNTER_SIZE_IN_WORDS];
+
+CCError_t SBRT_ImageLoadAndVerify(CCSbFlashReadFunc preHashflashRead_func,
+                           void *preHashUserContext,
+                           unsigned long hwBaseAddress,
+                           uint8_t isLoadFromFlash,
+                           uint8_t isVerifyImage,
+                           bsvCryptoMode_t cryptoMode,
+                           CCBsvKeyType_t  keyType,
+                           AES_Iv_t AESIv,
+                           uint8_t *pSwRecSignedData,
+                           uint32_t *pSwRecNoneSignedData,
+                           uint32_t *workspace_ptr,
+                           uint32_t workspaceSize);
+
+CCError_t SBRT_RSA_PSS_Verify(unsigned long hwBaseAddress,      /* [in] HW base address of registers. */
+                  CCHashResult_t mHash,         /* [in] Pointer to the SHA256 hash of the message. */
+                  uint32_t      *pN,                /* [in] Pointer to the RSA modulus (LE words array). */
+                  uint32_t      *pNp,           /* [in] Pointer to the Barrett tag of the RSA modulus (LE words array). */
+                  uint32_t      *pSign              /* [out] Pointer to the signature output (it is placed as BE bytes
+                                                                array into words buffer for alignments goal). */);
+
+void SBRT_HalClearInterruptBit(unsigned long hwBaseAddress, uint32_t data);
+
+void SBRT_HalMaskInterrupt(unsigned long hwBaseAddress, uint32_t data);
+
+CCError_t SBRT_HalWaitInterrupt(unsigned long hwBaseAddress, uint32_t data);
+
+CCError_t SBRT_LcsGet(unsigned long hwBaseAddress, uint32_t *pLcs);
+
+CCError_t SBRT_OTPWordRead(unsigned long hwBaseAddress, uint32_t otpAddress, uint32_t *pOtpWord);
+
+CCError_t SBRT_SwVersionGet(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t *swVersion);
+
+CCError_t SBRT_PubKeyHashGet(unsigned long hwBaseAddress, CCSbPubKeyIndexType_t keyIndex, uint32_t *hashedPubKey, uint32_t hashResultSizeWords);
+
+CCError_t SBRT_SHA256( unsigned long        hwBaseAddress,
+            uint8_t         *pDataIn,
+                        size_t                  dataSize,
+                        CCHashResult_t          hashBuff);
+
+CCError_t SBRT_CryptoImageInit( unsigned long   hwBaseAddress,
+                bsvCryptoMode_t mode,
+                CCBsvKeyType_t  keyType);
+
+CCError_t SBRT_CryptoImageUpdate( unsigned long     hwBaseAddress,
+                  bsvCryptoMode_t   mode,
+                  CCBsvKeyType_t        keyType,
+                  uint32_t      *pCtrStateBuf,
+                  uint8_t       *pDataIn,
+                  uint8_t       *pDataOut,
+                  size_t                dataSize,
+                  CCHashResult_t        hashBuff,
+                  uint8_t       isLoadIV);
+
+CCError_t SBRT_CryptoImageFinish( unsigned long     hwBaseAddress,
+                  bsvCryptoMode_t   mode,
+                  CCHashResult_t        hashBuff);
+
+uint32_t SBRT_MemCmp( uint8_t *pBuff1 , uint8_t *pBuff2 , uint32_t size);
+
+void SBRT_ReverseMemCopy( uint8_t *pDst, uint8_t *pSrc, uint32_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/Makefile b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/Makefile
new file mode 100644
index 0000000..270e11d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/Makefile
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+SUB_DIRS = cmpu dmpu
+OS = no_os
+
+all: $(foreach sub_dir,$(SUB_DIRS),do_$(sub_dir))
+
+clean: $(foreach sub_dir,$(SUB_DIRS),clean_$(sub_dir))
+
+clean_%:
+	@make -C $* clean
+
+do_%:
+	@make -C $*
+
+.PHONY: all clean clean_% do_%
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/Makefile b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/Makefile
new file mode 100644
index 0000000..6226d73
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/Makefile
@@ -0,0 +1,18 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for cmpu utility
+HOST_PROJ_ROOT ?= $(shell pwd)/../../..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+#overwriting the OS defined in the config
+OS = no_os
+export
+
+include project_cmpu.mk
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cc_cmpu.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cc_cmpu.h
new file mode 100644
index 0000000..95f6477
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cc_cmpu.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_cmpu
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all of the ICV production library APIs, their
+ enums and definitions.
+*/
+
+
+#ifndef _CMPU_H
+#define _CMPU_H
+
+#include "cc_pal_types_plat.h"
+#include "cc_prod.h"
+
+/************************ Defines ******************************/
+
+/*! The size of the ICV production library workspace in bytes. This workspace
+is needed by the library for internal use. */
+#define CMPU_WORKSPACE_MINIMUM_SIZE  4096
+
+/*! The size of the ICV production library unique buffer in bytes:
+Hbk0 or user data. */
+#define PROD_UNIQUE_BUFF_SIZE   16
+/************************ Enums ********************************/
+
+/*! The unique data type. */
+typedef enum {
+        /*! The device uses the unique data as Hbk0. */
+        CMPU_UNIQUE_IS_HBK0 = 1,
+        /*! The device uses the unique data as a random value. Hbk0 is not
+        used for the device. */
+        CMPU_UNIQUE_IS_USER_DATA = 2,
+        /*! Reserved. */
+        CMPU_UNIQUE_RESERVED    = 0x7FFFFFFF,
+} CCCmpuUniqueDataType_t;
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+
+/*!
+  @brief The device use of the unique buffer.
+
+  If the device uses Hbk0, then the \p hbk0 field is used.
+  Otherwise, a random buffer for the \p userData field is used.
+ */
+typedef union {
+        /*! The Hbk0 buffer, if used by the device. */
+        uint8_t hbk0[PROD_UNIQUE_BUFF_SIZE];
+        /*! Any random value, if Hbk0 is not used by the device. */
+        uint8_t userData[PROD_UNIQUE_BUFF_SIZE];
+} CCCmpuUniqueBuff_t;
+
+
+/*! The ICV production library input options. */
+typedef struct {
+        /*! The unique data type: Hbk0 or a random user-defined data. */
+        CCCmpuUniqueDataType_t  uniqueDataType;
+        /*! The unique data buffer. */
+        CCCmpuUniqueBuff_t      uniqueBuff;
+        /*! The Kpicv asset type. Allowed values are: Not used,
+        Plain-asset, or Package. */
+        CCAssetType_t           kpicvDataType;
+        /*! The Kpicv buffer, if its type is Plain-asset or Package. */
+        CCAssetBuff_t           kpicv;
+        /*! The asset type of the Kceicv. Allowed values are: Not used,
+        Plain-asset, or Package. */
+        CCAssetType_t           kceicvDataType;
+        /*! The Kceicv buffer, if its type is Plain-asset or Package. */
+        CCAssetBuff_t           kceicv;
+        /*! The minimal SW version of the ICV. Valid only if Hbk0 is used. */
+        uint32_t                icvMinVersion;
+        /*! The ICV configuration word. */
+        uint32_t                icvConfigWord;
+        /*! The default DCU lock bits of the ICV. Valid only if Hbk0 is used.*/
+        uint32_t                icvDcuDefaultLock[PROD_DCU_LOCK_WORD_SIZE];
+}CCCmpuData_t;
+
+
+
+/************************ Functions *****************************/
+
+/*!
+ @brief This function burns all ICV assets into the OTP of the device.
+
+ The user must perform a power-on-reset (PoR) to trigger LCS change to DM LCS.
+
+ @return \c CC_OK on success.
+ @return A non-zero value from cc_prod_error.h on failure.
+*/
+CIMPORT_C CCError_t  CCProd_Cmpu(
+        /*! [in] The base address of CrytoCell HW registers. */
+        unsigned long    ccHwRegBaseAddr,
+        /*! [in] A pointer to the ICV defines structure. */
+        CCCmpuData_t     *pCmpuData,
+        /*! [in] The base address of the workspace for internal use. */
+        unsigned long    workspaceBaseAddr,
+        /*! [in] The size of the provided workspace. Must be at least
+        #CMPU_WORKSPACE_MINIMUM_SIZE. */
+        uint32_t         workspaceSize
+                                    );
+
+
+/*!
+ @}
+ */
+#endif  //_CMPU_H
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu.c
new file mode 100644
index 0000000..d1582da
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu.c
@@ -0,0 +1,363 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_otp_defs.h"
+#include "cc_pal_mem.h"
+#include "dx_crys_kernel.h"
+#include "prod_hw_defs.h"
+#include "cc_pal_log.h"
+#include "prod_util.h"
+#include "cc_prod_error.h"
+#include "cmpu_llf_rnd.h"
+#include "prod_crypto_driver.h"
+#include "cmpu_derivation.h"
+#include "mbedtls_cc_mng_int.h"
+#include "mbedtls_cc_mng.h"
+
+
+static uint32_t CC_PROD_CalcHuk(uint32_t *pBuffForOtp,
+                                uint32_t *pManufactorWord,
+                                unsigned long workspaceAddr)
+{
+    uint32_t error = 0;
+    uint32_t  zeroCount = 0;
+    uint8_t   pKey[CC_PROD_AES_Key256Bits_SIZE_IN_BYTES] = { 0 };
+    uint8_t   pIv[CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES] = { 0 };
+    uint32_t *pEntrSrc;
+    uint32_t  sourceSize;
+    uint32_t *pRndWorkBuff;
+
+    /*Call CC_PROD_LLF_RND_GetTrngSource to get entropy bits and to check entropy size*/
+    pRndWorkBuff = (uint32_t *)workspaceAddr;
+    error = CC_PROD_LLF_RND_GetTrngSource((uint32_t **)&pEntrSrc, &sourceSize, pRndWorkBuff);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed CC_PROD_LLF_RND_GetTrngSource, error is 0x%X\n", error);
+        return error;
+    }
+    error = CC_PROD_Derivation_Instantiate(pEntrSrc,
+                                           sourceSize,
+                                           pKey,
+                                           pIv);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed to CC_PROD_Derivation_Instantiate, error 0x%x\n", error);
+        return error;
+    }
+    error = CC_PROD_Derivation_Generate(pKey,
+                                        pIv,
+                                        pBuffForOtp,
+                                        CC_OTP_HUK_SIZE_IN_WORDS * sizeof(uint32_t));
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed to CC_PROD_Derivation_Generate, error 0x%x\n", error);
+        return error;
+    }
+
+    error = CC_PROD_LLF_RND_VerifyGeneration((uint8_t *)pBuffForOtp);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed to CC_PROD_LLF_RND_VerifyGeneration, error 0x%x\n", error);
+        return error;
+    }
+
+    /*Count number of zero bits in HUK OTP fileds*/
+    error  = CC_PROD_GetZeroCount(pBuffForOtp, CC_OTP_HUK_SIZE_IN_WORDS, &zeroCount);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Invalid Huk zero count\n");
+        return error;
+    }
+
+    SET_OTP_MANUFACTURE_FLAG(*pManufactorWord, HUK_ZERO_BITS, zeroCount);
+    return CC_OK;
+}
+
+static uint32_t CC_PROD_HandleHbk0(CCCmpuData_t *pCmpuData,
+                                   uint32_t *pHbk0BuffForOtp,
+                                   uint32_t *pDcuLockBuffForOtp,
+                                   uint32_t *pSwVerBuffForOtp,
+                                   uint32_t *pManufactorWord)
+{
+    uint32_t error = 0;
+    uint32_t  zeroCount = 0;
+    uint32_t  i = 0;
+    uint32_t icvOwnership = 0;
+    switch (pCmpuData->uniqueDataType){
+    case CMPU_UNIQUE_IS_USER_DATA:
+        /* If HBK not in use set the bit in manufactor flag */
+        SET_OTP_MANUFACTURE_FLAG(*pManufactorWord, HBK0_NOT_IN_USE, 1);
+        break;
+
+    case CMPU_UNIQUE_IS_HBK0:
+        /* Calculate HBK0 zeros */
+        CC_PalMemCopy(pHbk0BuffForOtp, pCmpuData->uniqueBuff.hbk0, CC_OTP_HBK0_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE);
+        error = CC_PROD_GetZeroCount(pHbk0BuffForOtp, PROD_KEY_TMP_CONTEXT_WORD_SIZE, &zeroCount);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Invalid Huk zero count\n");
+            return error;
+        }
+
+        /* Keep only ICV bit in DCU default locking */
+        for (i = 0; i < CC_OTP_DCU_SIZE_IN_WORDS; i++) {
+            icvOwnership = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_ICV_DCU_RESTRICTION_MASK0) + (i * CC_32BIT_WORD_SIZE));
+            pDcuLockBuffForOtp[i] = pCmpuData->icvDcuDefaultLock[i] & icvOwnership;
+        }
+
+        /* set ICV minimum SW version */
+        error = CC_PROD_BitListFromNum(pSwVerBuffForOtp, CC_OTP_HBK0_MIN_VERSION_SIZE_IN_WORDS, pCmpuData->icvMinVersion);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to get bit list from number\n");
+            return error;
+        }
+        break;
+
+    default:
+        CC_PAL_LOG_ERR("Invalid unique data type \n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+
+    SET_OTP_MANUFACTURE_FLAG(*pManufactorWord, HBK0_ZERO_BITS, zeroCount);
+    return CC_OK;
+}
+
+
+static uint32_t CC_PROD_HandleKpicv(CCCmpuData_t *pCmpuData,
+                                    uint32_t *pBuffForOtp,
+                                    uint32_t *pManufactorWord,
+                                    unsigned long workspaceAddr,
+                                    uint32_t     workspaceSize)
+{
+    uint32_t error = 0;
+    uint32_t  zeroCount = 0;
+
+    switch (pCmpuData->kpicvDataType) {
+    case  ASSET_NO_KEY:
+        SET_OTP_MANUFACTURE_FLAG(*pManufactorWord, KPICV_NOT_IN_USE, 1);
+        goto end_kpicv;
+    case  ASSET_PKG_KEY:
+        error = CC_PROD_PkgVerify((CCProdAssetPkg_t *)&pCmpuData->kpicv.pkgAsset,
+                                  (const uint8_t *)PROD_ICV_PROV_CONTEXT, PROD_KPROV_CONTEXT_SIZE,
+                                  (const uint8_t *)PROD_ICV_KEY_TMP_LABEL, PROD_KEY_TMP_LABEL_SIZE,
+                                  pCmpuData->uniqueBuff.hbk0, CC_OTP_HBK0_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE,
+                                  (uint8_t *  )pBuffForOtp,
+                                  workspaceAddr,
+                                  workspaceSize);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("failed to CC_PROD_PkgVerify fro Kpicv\n");
+            return error;
+        }
+        break;
+    case ASSET_PLAIN_KEY:
+        CC_PalMemCopy(pBuffForOtp, pCmpuData->kpicv.plainAsset, PROD_ASSET_SIZE);
+        break;
+    default:
+        CC_PAL_LOG_ERR("Inavlid key type for  Kpicv\n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+    error = CC_PROD_GetZeroCount(pBuffForOtp, PROD_KEY_TMP_CONTEXT_WORD_SIZE, &zeroCount);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Invalid zero count for Kpicv\n");
+        return error;
+    }
+end_kpicv:
+    SET_OTP_MANUFACTURE_FLAG(*pManufactorWord, KPICV_ZERO_BITS, zeroCount);
+    return CC_OK;
+}
+
+
+static uint32_t CC_PROD_HandleKceicv(CCCmpuData_t *pCmpuData,
+                                     uint32_t *pBuffForOtp,
+                                     uint32_t *pManufactorWord,
+                                     unsigned long workspaceAddr,
+                                     uint32_t     workspaceSize)
+{
+    uint32_t error = 0;
+    uint32_t  zeroCount = 0;
+
+    switch (pCmpuData->kceicvDataType) {
+    case  ASSET_NO_KEY:
+        SET_OTP_MANUFACTURE_FLAG(*pManufactorWord, KCEICV_NOT_IN_USE, 1);
+        goto end_kceicv;
+    case  ASSET_PKG_KEY:
+        error = CC_PROD_PkgVerify((CCProdAssetPkg_t *)&pCmpuData->kceicv.pkgAsset,
+                                  (const uint8_t *)PROD_ICV_ENC_CONTEXT, PROD_KPROV_CONTEXT_SIZE,
+                                  (const uint8_t *)PROD_ICV_KEY_TMP_LABEL, PROD_KEY_TMP_LABEL_SIZE,
+                                  pCmpuData->uniqueBuff.hbk0, CC_OTP_HBK0_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE,
+                                  (uint8_t *  )pBuffForOtp,
+                                  workspaceAddr,
+                                  workspaceSize);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("failed to CC_PROD_PkgVerify fro Kceicv\n");
+            return error;
+        }
+        break;
+    case ASSET_PLAIN_KEY:
+        CC_PalMemCopy(pBuffForOtp, pCmpuData->kceicv.plainAsset, PROD_ASSET_SIZE);
+        break;
+    default:
+        CC_PAL_LOG_ERR("Invalid key type for Kceicv\n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+
+    error = CC_PROD_GetZeroCount(pBuffForOtp, PROD_KEY_TMP_CONTEXT_WORD_SIZE, &zeroCount);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Invalid zerocount for Kceicv\n");
+        return error;
+    }
+
+end_kceicv:
+    SET_OTP_MANUFACTURE_FLAG(*pManufactorWord, KCEICV_ZERO_BITS, zeroCount);
+    return CC_OK;
+}
+
+
+
+CCError_t CCProd_Cmpu( unsigned long  ccHwRegBaseAddr,
+                       CCCmpuData_t   *pCmpuData,
+                       unsigned long  workspaceBaseAddr,
+                       uint32_t       workspaceSize)
+{
+    uint32_t error = 0;
+    uint32_t lcs = 0;
+    uint32_t manufactorWord = 0;
+    uint32_t hukBuffForOtp[CC_OTP_HUK_SIZE_IN_WORDS] = { 0 };
+    uint32_t hbk0BuffForOtp[CC_OTP_HBK0_SIZE_IN_WORDS] = { 0 };
+    uint32_t kpicvBuffForOtp[CC_OTP_KPICV_SIZE_IN_WORDS] = { 0 };
+    uint32_t kceicvBuffForOtp[CC_OTP_KCEICV_SIZE_IN_WORDS] = { 0 };
+    uint32_t icvLockBitsBuffForOtp[CC_OTP_DCU_SIZE_IN_WORDS] = { 0 };
+    uint32_t   icvMinSwVersion[CC_OTP_HBK0_MIN_VERSION_SIZE_IN_WORDS] = { 0 };
+
+    if (sizeof(CCProdAssetPkg_t) != PROD_ASSET_PKG_SIZE) {
+        CC_PAL_LOG_ERR("invalid Pkg size\n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+    if ((pCmpuData == NULL) ||
+            (workspaceBaseAddr == 0) ||  //can not be zero because it is cast to a pointer later
+            (workspaceBaseAddr % CC_32BIT_WORD_SIZE) ||   // workspace address must be word aligned
+            (workspaceSize < CMPU_WORKSPACE_MINIMUM_SIZE) ) {
+        CC_PAL_LOG_ERR("invalid params\n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+
+    gCcRegBase = ccHwRegBaseAddr;
+
+    error = CCProd_Init();
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to CCProd_Init 0x%x\n", error);
+        goto cmpuEnd;
+    }
+
+    /* Check LCS - CM only */
+    error = mbedtls_mng_lcsGet(&lcs);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to get LCS 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+    /* Verify LCS is CM */
+    if (lcs != CC_MNG_LCS_CM) {
+        CC_PAL_LOG_ERR("LCS is %d not valid\n", lcs);
+        error = CC_PROD_ILLEGAL_LCS_ERR;
+        goto cmpuEnd;
+    }
+
+    /* Genertae HUK  */
+    error = CC_PROD_CalcHuk(hukBuffForOtp, &manufactorWord, workspaceBaseAddr);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed to CC_PROD_CalcHuk 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+    /* Set HBK0 if exists, and calculate its zero count. or set HBK0 not in use
+           Handle HBK0  dependencies: DCU lock bits and ICV minimum version */
+    error = CC_PROD_HandleHbk0(pCmpuData, hbk0BuffForOtp, icvLockBitsBuffForOtp, icvMinSwVersion, &manufactorWord);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed to CC_PROD_HandleHbk0 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+    /* Handle Kpicv, or set Kpicv not in use */
+    error = CC_PROD_HandleKpicv(pCmpuData, kpicvBuffForOtp, &manufactorWord, workspaceBaseAddr, workspaceSize);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed to CC_PROD_HandleKpicv 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+
+    /* Handle Kceicv, , or set Kceicv not in use */
+    error = CC_PROD_HandleKceicv(pCmpuData, kceicvBuffForOtp, &manufactorWord, workspaceBaseAddr, workspaceSize);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed to CC_PROD_HandleKceicv 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+    /* First, Burn Manufactor flag, including not in use flags set by ahndle functions above  */
+    CC_PROD_OTP_WRITE_VERIFY_WORD(CC_OTP_MANUFACTURE_FLAG_OFFSET, manufactorWord, error);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+    /* Burn Huk */
+    CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_HUK_OFFSET, hukBuffForOtp, CC_OTP_HUK_SIZE_IN_WORDS, error);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+    /* Burn HBK0 and its dependencies: DCU lock bits and SW version */
+    if (pCmpuData->uniqueDataType == CMPU_UNIQUE_IS_HBK0) {
+        /* HBK0 */
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_HBK0_OFFSET, hbk0BuffForOtp, CC_OTP_HBK0_SIZE_IN_WORDS, error);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+            goto cmpuEnd;
+        }
+        /* DCU lock bits */
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_DCU_OFFSET, icvLockBitsBuffForOtp, CC_OTP_DCU_SIZE_IN_WORDS, error);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+            goto cmpuEnd;
+        }
+        /* SW version */
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_HBK0_MIN_VERSION_OFFSET, icvMinSwVersion, CC_OTP_HBK0_MIN_VERSION_SIZE_IN_WORDS, error);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+            goto cmpuEnd;
+        }
+    }
+    /* Burn Kpicv */
+    if (pCmpuData->kpicvDataType  != ASSET_NO_KEY)  {
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_KPICV_OFFSET, kpicvBuffForOtp, CC_OTP_KPICV_SIZE_IN_WORDS, error);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+            goto cmpuEnd;
+        }
+    }
+    /* Burn Kceicv*/
+    if (pCmpuData->kceicvDataType  != ASSET_NO_KEY)  {
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_KCEICV_OFFSET, kceicvBuffForOtp, CC_OTP_KCEICV_SIZE_IN_WORDS, error);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+            goto cmpuEnd;
+        }
+    }
+    /* Burn icv configuration word */
+    CC_PROD_OTP_WRITE_VERIFY_WORD(CC_OTP_ICV_GENERAL_PURPOSE_FLAG_OFFSET,
+                                  pCmpuData->icvConfigWord,
+                                  error);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+        goto cmpuEnd;
+    }
+
+cmpuEnd:
+    CC_PalMemSetZero((uint8_t *)workspaceBaseAddr, workspaceSize);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("CMPU failed, error = 0x%x \n", error);
+    }
+    CCPROD_Fini();
+    return error;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_derivation.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_derivation.c
new file mode 100644
index 0000000..c052b07
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_derivation.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include <stdint.h>
+#include <string.h>
+#include "cc_pal_log.h"
+#include "cc_prod_error.h"
+#include "prod_hw_defs.h"
+#include "prod_crypto_driver.h"
+#include "cmpu_derivation.h"
+#include "cc_pal_mem.h"
+#include "llf_rnd.h"
+#include "driver_defs.h"
+
+
+/* Description: Implementation of CTR_DRBG_Generate_algorithm, Taken from NIST SP800-90A, section 10.4.2
+   Parameters:
+    pInputBuff[IN] - the seed_material with some additional bytes to avoid copy of large buffers
+    actualInputDataSize[IN] - the actual size of teh seed without teh additions
+    pOutputBuff[OUT] - the generated buffer - 32 bytes
+ */
+static uint32_t Derivation_Block_Cipher_df(uint32_t   *pInputBuff,
+                                           uint32_t   actualInputDataSize,
+                                           uint32_t    *pOutput)
+{
+    uint32_t  error = CC_OK;
+    uint8_t *initMac_ptr;
+    uint32_t i;
+    uint32_t additionalBytesSize = 0;
+    uint8_t *inputPtr = (uint8_t*)pInputBuff;
+    uint8_t keyBuff[CC_PROD_AES_Key256Bits_SIZE_IN_BYTES];
+    uint8_t ivBuff[CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES];
+    uint32_t  outDataSizeBytes = CC_PROD_AES_Key256Bits_SIZE_IN_BYTES+CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES;
+    uint32_t inputDataSize = actualInputDataSize;
+    uint8_t Key[CC_PROD_AES_Key256Bits_SIZE_IN_BYTES] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
+            0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F};
+    uint8_t InitialMac256[3][16] = {{0xF2,0x90,0x00,0xB6,0x2A,0x49,0x9F,0xD0,0xA9,0xF3,0x9A,0x6A,0xDD,0x2E,0x77,0x80},
+            {0x9D,0xBA,0x41,0xA7,0x77,0xF3,0xB4,0x6A,0x37,0xB7,0xAA,0xAE,0x49,0xD6,0xDF,0x8D},
+            {0x2F,0x7A,0x3C,0x60,0x07,0x08,0xD1,0x24,0xAC,0xD3,0xC5,0xDE,0x3B,0x65,0x84,0x47}};
+
+    if ((NULL == pInputBuff) || (actualInputDataSize == 0) || (NULL == pOutput)) {
+        CC_PAL_LOG_ERR("invalid parameters\n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+    /* Steps from NIST - ignored
+       1. If (number_of_bits_to_return > max_number_of_bits), then return an ERROR_FLAG. */
+
+    /* Steps from NIST
+       2. L = len (input_string)/8. Comment: L is the bitstring represention of the integer resulting from len (input_string)/8. L shall be represented as a 32-bit integer.
+       3. N = number_of_bits_to_return/8. Comment : N is the bitstring represention of the integer resulting from number_of_bits_to_return/8                    .
+          N shall be represented as a 32-bit integer.
+       4. S = L || N || input_string || 0x80.
+          Comment : Pad S with zeros, if necessary.
+       5. While (len (S) mod outlen) 0, S = S || 0x00. */
+    /* convert L,N to little endian */
+    pInputBuff[0] = CC_PROD_SET_WORD_AS_BE(actualInputDataSize); /* L */
+    pInputBuff[1] = CC_PROD_SET_WORD_AS_BE(outDataSizeBytes);    /* N */
+
+    inputPtr[8+actualInputDataSize] = 0x80;
+    // pad with 0's the remaining bytes until we reach size which is outlenSize multiply
+    additionalBytesSize = CC_PROD_AES_BLOCK_SIZE_IN_BYTES - ((8+1+actualInputDataSize)&(CC_PROD_AES_BLOCK_SIZE_IN_BYTES-1));
+    CC_PalMemSetZero(&inputPtr[8+1+actualInputDataSize], additionalBytesSize);
+
+    /* size of input to AES-MAC, rounded up to AES block */
+    inputDataSize += (8/*2w*/ + 1/*0x80*/ + additionalBytesSize);
+
+
+    /* Steps from NIST
+       Comment : Compute the starting value.
+       6. temp = the Null string.
+       7. i = 0. Comment : i shall be represented as a 32-bit integer, i.e., len (i) = 32.
+       8. K = Leftmost keylen bits of 0x00010203...1D1E1F.
+       9. While len (temp) < keylen + outlen, do
+       9.1 IV = i || 0outlen - len (i). Comment: The 32-bit integer represenation of i is padded with zeros to outlen bits.
+       9.2 temp = temp || BCC (K, (IV || S)).
+       9.3 i = i + 1. */
+    for (i = 0; i < (outDataSizeBytes >> 4); i++) {
+        /* set pointer to initial precomputed IV  value */
+        initMac_ptr = (uint8_t*)&InitialMac256[i][0];
+
+        /* AES MAC */
+        error =  CC_PROD_Aes(CIPHER_CBC_MAC, CRYPTO_DIRECTION_ENCRYPT,
+                             USER_KEY,
+                             Key,sizeof(Key),
+                             initMac_ptr,CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES,
+                             pInputBuff,
+                             inputDataSize,
+                             pOutput + i*CC_PROD_AES_BLOCK_SIZE_IN_WORDS);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Failed to CC_PROD_Aes, error 0x%x\n", error);
+            return error;
+        }
+
+    }
+
+    /* Steps from NIST
+       Comment: Compute the requested number of bits.
+       10. K = Leftmost keylen bits of temp.
+       11. X = Next outlen bits of temp. */
+    CC_PalMemCopy(keyBuff, (uint8_t*)pOutput, sizeof(keyBuff));
+    CC_PalMemCopy(ivBuff, (uint8_t*)(pOutput + CC_PROD_AES_Key256Bits_SIZE_IN_WORDS), sizeof(ivBuff));
+
+
+    /* Steps from NIST
+       12. temp = the Null string.
+       13. While len (temp) < number_of_bits_to_return, do
+       13.1 X = Block_Encrypt (K, X).
+       13.2 temp = temp || X.
+       14. requested_bits = Leftmost number_of_bits_to_return of temp. */
+    /* Encrypt (K,IV) by AES-CBC using output buff */
+    CC_PalMemSetZero((uint8_t*)pOutput, outDataSizeBytes);
+    error = CC_PROD_Aes(CIPHER_CBC, CRYPTO_DIRECTION_ENCRYPT,
+                        USER_KEY,
+                        keyBuff, sizeof(keyBuff),
+                        ivBuff, CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES,
+                        pOutput,
+                        outDataSizeBytes,
+                        pOutput);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Failed to CC_PROD_Aes, error 0x%x\n", error);
+        return error;
+    }
+
+    /* Steps from NIST
+       15. Return SUCCESS and requested_bits.*/
+    return CC_OK;
+} /* END of Derivation_Block_Cipher_df */
+
+
+
+
+/* increment vector by value of 1 */
+static void Derivation_incrementVector(uint8_t *iv_ptr, uint32_t vecSizeInwords)
+{
+    int32_t i;
+    uint32_t tmp, curr, tmp1;
+
+    for (i = vecSizeInwords-1; i >= 0; i--) {
+        CC_PalMemCopy((uint8_t *)&tmp1, &iv_ptr[i*sizeof(uint32_t)], sizeof(tmp1));
+        tmp = CC_PROD_SET_WORD_AS_BE(tmp1);
+        curr = tmp;
+        tmp = ((tmp+1) & 0xFFFFFFFF);
+
+        /* inverse the bytes order in a word */
+        tmp1 = CC_PROD_SET_WORD_AS_BE(tmp);
+        CC_PalMemCopy(&iv_ptr[i*sizeof(uint32_t)], (uint8_t *)&tmp1, sizeof(tmp));
+        if (tmp > curr) {
+            break;
+        }
+    }
+}
+
+
+
+/* Description: Implementation of  CTR_DRBG_Update, Taken from NIST SP800-90A, section 10.2.1.2
+   Parameters:
+    provided_data[IN]: The data to be used. This must be exactly seedlen bits in length;
+            this length is guaranteed by the construction of the provided_data in the instantiate, reseed and generate functions.
+    Key[IN/OUT]: The current value of Key.
+    V[IN/OUT]: The current value of V.
+ */
+static uint32_t Derivation_DRBG_Update(uint32_t   *providedData_ptr,
+                                       uint8_t   *pKey,
+                                       uint8_t   *pIv)
+{
+
+    uint32_t  error = CC_OK;
+    uint32_t outDataSize = (CC_PROD_AES_Key256Bits_SIZE_IN_BYTES+CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES);
+    uint32_t  pOutput[CC_PROD_AES_Key256Bits_SIZE_IN_WORDS+CC_PROD_AES_IV_COUNTER_SIZE_IN_WORDS];
+    uint32_t i = 0;
+    AesContext_t aesCtx;
+
+    /* Steps taken from NIST
+       1. temp = Null.
+       2. While (len (temp) < seedlen) do
+       2.1 V = (V + 1) mod 2outlen.
+       2.2 output_block = Block_Encrypt (Key, V).
+       2.3 temp = temp || ouput_block.
+       3. temp = Leftmost seedlen bits of temp.
+       4 temp = temp XOR provided_data. */
+    error =  CC_PROD_AesInit(&aesCtx, CIPHER_CTR, CRYPTO_DIRECTION_ENCRYPT,
+                             USER_KEY,
+                             pKey,CC_PROD_AES_Key256Bits_SIZE_IN_BYTES,
+                             pIv,CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES);
+    if (error != CC_OK) {
+        return error;
+    }
+    // dummy block to increment IV
+    error =  CC_PROD_AesProcess(&aesCtx,
+                                providedData_ptr,  CC_PROD_AES_BLOCK_SIZE_IN_BYTES,
+                                pOutput);
+    if (error != CC_OK) {
+        return error;
+    }
+    for (i = 0; i < (outDataSize >> 4); i++) {
+        error =  CC_PROD_AesProcess(&aesCtx,
+                                    providedData_ptr + i*CC_PROD_AES_BLOCK_SIZE_IN_WORDS, CC_PROD_AES_BLOCK_SIZE_IN_BYTES,
+                                    pOutput + i*CC_PROD_AES_BLOCK_SIZE_IN_WORDS);
+        if (error != CC_OK) {
+            return error;
+        }
+    }
+
+    /* Steps taken from NIST
+       5. Key = Leftmost keylen bits of temp.
+       6. V = Rightmost outlen bits of temp. */
+    CC_PalMemCopy(pKey, (uint8_t*)pOutput, CC_PROD_AES_Key256Bits_SIZE_IN_BYTES);
+    CC_PalMemCopy(pIv, (uint8_t*)(pOutput+CC_PROD_AES_Key256Bits_SIZE_IN_WORDS), CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES);
+
+    /*Steps taken from NIST
+      7. Return the new values of Key and V. */
+    return CC_OK;
+}
+
+
+
+/* Description: Implementation of CTR_DRBG_Instantiate_algorithm, Taken from NIST SP800-90A, section 10.2.1.3.2
+   Parameters:
+    pKey[OUT] - the generated key
+    pIv[OUT] - the generated Iv
+ */
+uint32_t CC_PROD_Derivation_Instantiate (uint32_t *pEntrSrc,
+                                         uint32_t  sourceSize,
+                                         uint8_t *pKey,
+                                         uint8_t *pIv)
+{
+    uint32_t  error = CC_OK;
+    uint32_t   pDfOutput[CC_PROD_AES_Key256Bits_SIZE_IN_WORDS+CC_PROD_AES_IV_COUNTER_SIZE_IN_WORDS] = {0};
+
+    if ((NULL == pKey) || (NULL == pIv) || (NULL == pEntrSrc) || (0 == sourceSize) || (!IS_ALIGNED(sourceSize, sizeof(uint32_t)))) {
+        CC_PAL_LOG_ERR("invalid key parameters\n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+    /* Steps taken from NIST  - already done before calling CC_PROD_Derivation_Instantiate
+       1. seed_material = entropy_input || nonce || personalization_string.
+        (Comment: Ensure that the length of the seed_material is exactly seedlen bits.) */
+    /* Steps taken from NIST
+       2. seed_material = Derivation_Block_Cipher_df (seed_material, seedlen). */
+    error = Derivation_Block_Cipher_df(pEntrSrc, sourceSize, pDfOutput);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed Derivation_Block_Cipher_df, error is 0x%X\n", error);
+        return error;
+    }
+
+    /* Steps taken from NIST
+       3. Key = 0keylen. Comment: keylen bits of zeros.
+       4. V = 0outlen. Comment: outlen bits of zeros. */
+    CC_PalMemSetZero(pKey, CC_PROD_AES_Key256Bits_SIZE_IN_BYTES);
+    CC_PalMemSetZero(pIv, CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES);
+    /* Steps taken from NIST
+       5. (Key, V) = Derivation_DRBG_Update (seed_material, Key, V). */
+    error = Derivation_DRBG_Update(pDfOutput, pKey, pIv);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("failed Derivation_DRBG_Update, error is 0x%X\n", error);
+        return error;
+    }
+
+    /* Steps taken from NIST
+       6. reseed_counter = 1.  -- ignored here
+       7. Return V, Key, and reseed_counter as the initial_working_state. */
+    return CC_OK;
+
+}
+
+
+/* Description: Implementation of CTR_DRBG_Generate_algorithm, Taken from NIST SP800-90A, section 10.2.1.5.2
+   Parameters:
+    pKey[IN] - the generated key
+    pIv[IN] - the generated Iv
+    pOutputBuff[OUT] - the generated buffer - 32 bytes
+ */
+uint32_t CC_PROD_Derivation_Generate(uint8_t *pKey,
+                                     uint8_t *pIv,
+                                     uint32_t *pOutputBuff,
+                                     uint32_t  outDataSize)
+{
+    uint32_t  error = CC_OK;
+    uint32_t  i = 0;
+    uint32_t  numBlocks = (outDataSize >> 4);
+    uint32_t   temp[CC_PROD_AES_BLOCK_SIZE_IN_WORDS] = {0};
+#ifndef CMPU_KAT
+    uint32_t   firstDummyBytes[CC_PROD_AES_BLOCK_SIZE_IN_WORDS] = {0};
+#endif
+    AesContext_t aesCtx;
+
+    if ((pKey == NULL) || (pIv == NULL) || (pOutputBuff == NULL)) {
+        CC_PAL_LOG_ERR("Invalid input Param\n");
+        return CC_PROD_INVALID_PARAM_ERR;
+    }
+
+    /* Steps taken from NIST - all following are ignored, since th eworking state is one time
+       1. If reseed_counter > reseed_interval, then return an indication that a reseed is required.
+       2. If (additional_input Null), then
+       2.1 additional_input = Derivation_Block_Cipher_df (additional_input, seedlen).
+       2.2 (Key, V) = Derivation_DRBG_Update (additional_input, Key, V).
+       Else additional_input = 0seedlen. */
+
+
+
+    /* Steps taken from NIST
+       3. temp = Null.
+       4. While (len (temp) < requested_number_of_bits) do:
+       4.1 V = (V + 1) mod 2outlen.
+       4.2 output_block = Block_Encrypt (Key, V).
+       4.3 temp = temp || output_block.
+       5. returned_bits = Leftmost requested_number_of_bits of temp. */
+    /* Increment counter V = V+1 */
+    Derivation_incrementVector(pIv, CC_PROD_AES_IV_COUNTER_SIZE_IN_WORDS);
+    /* Init AES operation on CTR mode */
+    error = CC_PROD_AesInit(&aesCtx, CIPHER_CTR, CRYPTO_DIRECTION_ENCRYPT,
+                            USER_KEY,
+                            pKey, CC_PROD_AES_Key256Bits_SIZE_IN_BYTES,
+                            pIv, CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Faild to CC_PROD_AesInit, error 0x%x\n", error);
+        return error;
+    }
+#ifndef CMPU_KAT
+    error = CC_PROD_AesProcess(&aesCtx,
+                               temp, sizeof(temp),
+                               firstDummyBytes);
+    if (error != CC_OK) {
+        CC_PAL_LOG_ERR("Faild to CC_PROD_AesProcess, error 0x%x\n", error);
+        return error;
+    }
+#endif
+
+    /* generate full blocks of input data */
+    for (i = 0; i < numBlocks; i++) {
+        error = CC_PROD_AesProcess(&aesCtx,
+                                   temp, CC_PROD_AES_BLOCK_SIZE_IN_BYTES,
+                                   pOutputBuff + i*CC_PROD_AES_BLOCK_SIZE_IN_WORDS);
+        if (error != CC_OK) {
+            CC_PAL_LOG_ERR("Faild to CC_PROD_AesProcess, error 0x%x\n", error);
+            return error;
+        }
+    }
+
+    /* Steps taken from NIST - all following are ignored, since th eworking state is one time
+       6. (Key, V) = Derivation_DRBG_Update (additional_input, Key, V).
+       7. reseed_counter = reseed_counter + 1. */
+
+    /* Steps taken from NIST
+       8. Return SUCCESS and returned_bits; also return Key, V, and reseed_counter as the new_working_state. */
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_derivation.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_derivation.h
new file mode 100644
index 0000000..1ee7769
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_derivation.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CMPU_DERIVATION_H
+#define _CMPU_DERIVATION_H
+
+
+uint32_t CC_PROD_Derivation_Instantiate (uint32_t *pEntrSrc,
+                                         uint32_t  sourceSize,
+                                         uint8_t *pKey,
+                                         uint8_t *pIv);
+uint32_t CC_PROD_Derivation_Generate(uint8_t *pKey,
+                                     uint8_t *pIv,
+                                     uint32_t *pOutputBuff,
+                                     uint32_t  outDataSize);
+
+#endif  //_CMPU_DERIVATION_H
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_llf_rnd.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_llf_rnd.c
new file mode 100644
index 0000000..a844372
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_llf_rnd.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/************* Include Files ****************/
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include "cc_pal_log.h"
+#include "cc_prod_error.h"
+#include "prod_hw_defs.h"
+#include "cmpu_llf_rnd.h"
+#include "dx_rng.h"
+
+#include "cc_rng_plat.h"
+#include "llf_rnd_trng.h"
+#include "cc_general_defs.h"
+#include "cc_hal_plat.h"
+
+extern unsigned long gCcRegBase;
+
+extern uint32_t *pRndWorkBuff;
+
+/*******************************************************************************/
+/**
+ * @brief The CC_PROD_LLF_RND_GetTrngSource reads random source of needed size from TRNG.
+ *
+ *        The function is used in Self, Instantiation and Reseeding functions.
+ *
+  * @ppSourceOut[out] - The pointer to to pointer to the entropy source buffer.
+ *                   The buffer contains one empty word for using by CRYS level
+ *                   and then buffer for output the rng source.
+ * @pSourceOutSize[out] - The pointer to the size in bytes of entropy source
+ *                      in - required size, output - actual size.
+ *
+ * @return uint32_t - On success 0 is returned, otherwise indicates failure.
+ */
+uint32_t CC_PROD_LLF_RND_GetTrngSource(uint32_t           **ppSourceOut, /*out*/
+        uint32_t           *pSourceOutSize,
+                                       uint32_t *pRndWorkBuff)
+{
+        uint32_t error = 0;
+        CCRndState_t rndState;
+        CCRndParams_t  trngParams;
+
+        error = RNG_PLAT_SetUserRngParameters( &trngParams);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        error = LLF_RND_RunTrngStartupTest(&rndState, &trngParams, pRndWorkBuff);
+        if (error != CC_OK) {
+                return error;
+        }
+
+        error = LLF_RND_GetTrngSource(&rndState, &trngParams, CC_FALSE, NULL, ppSourceOut, pSourceOutSize, pRndWorkBuff, false);
+        return error;
+}
+
+
+uint32_t CC_PROD_LLF_RND_VerifyGeneration(uint8_t *pBuff)
+{
+        CC_UNUSED_PARAM(pBuff);
+        return CC_OK;
+
+} /* End of setUserRngParameters */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_llf_rnd.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_llf_rnd.h
new file mode 100644
index 0000000..63f3344
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/cmpu_llf_rnd.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CMPU_LLF_RND_DEFS_H
+#define _CMPU_LLF_RND_DEFS_H
+
+/************* Include Files ****************/
+#include "prod_hw_defs.h"
+#include "cc_otp_defs.h"
+
+#define CC_PROD_RND_Fast                                        0
+#define CC_PROD_REQUIRED_ENTROPY_BITS                           256
+
+uint32_t CC_PROD_LLF_RND_GetTrngSource(uint32_t           **ppSourceOut,
+                       uint32_t           *pSourceOutSize,
+                                       uint32_t *pRndWorkBuff);
+
+uint32_t CC_PROD_LLF_RND_VerifyGeneration(uint8_t *pBuff);
+
+#endif //_CMPU_LLF_RND_DEFS_H
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/project_cmpu.mk b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/project_cmpu.mk
new file mode 100644
index 0000000..fd03ec4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/cmpu/project_cmpu.mk
@@ -0,0 +1,104 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+TARGET_LIBS = cmpu
+
+SOURCES_cmpu = cmpu.c
+SOURCES_cmpu += cmpu_llf_rnd.c
+SOURCES_cmpu += cmpu_derivation.c
+SOURCES_cmpu += prod_crypto_driver.c
+SOURCES_cmpu += prod_util.c
+SOURCES_cmpu += cc_hal.c
+SOURCES_cmpu += aes_driver.c
+SOURCES_cmpu += driver_common.c
+SOURCES_cmpu += aesccm_driver.c
+SOURCES_cmpu += ccm_alt.c
+SOURCES_cmpu += mbedtls_ccm_internal.c
+SOURCES_cmpu += mbedtls_common.c
+SOURCES_cmpu += mbedtls_cc_mng_int.c
+SOURCES_cmpu += cc_common_conv_endian.c
+SOURCES_cmpu += cc_rng_plat.c
+SOURCES_cmpu += llf_rnd.c
+
+#pal sources:
+SOURCES_cmpu += cc_pal.c
+SOURCES_cmpu += cc_pal_mutex.c
+SOURCES_cmpu += cc_pal_memmap.c
+SOURCES_cmpu += cc_pal_dma.c
+SOURCES_cmpu += cc_pal_pm.c
+SOURCES_cmpu += cc_pal_interrupt_ctrl.c
+SOURCES_cmpu += cc_pal_buff_attr.c
+SOURCES_cmpu += cc_pal_mem.c
+SOURCES_cmpu += cc_pal_abort_plat.c
+SOURCES_cmpu += cc_pal_trng.c
+
+ifeq ($(DEBUG),1)
+   SOURCES_cmpu += cc_pal_log.c
+endif
+
+ifeq ($(CC_CONFIG_TRNG_MODE),0)
+        # FE TRNG
+        $(info FE TRNG: CC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE))
+        SOURCES_cmpu += llf_rnd_fetrng.c
+	CFLAGS_EXTRA += -DCC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE)
+else ifeq ($(CC_CONFIG_TRNG_MODE),1)
+        # TRNG90B
+        $(info TRNG90B: CC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE))
+        SOURCES_cmpu += llf_rnd_trng90b.c
+	CFLAGS_EXTRA += -DCC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE)
+else
+        $(error illegal TRNG: CC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE))
+endif
+
+ifeq ($(CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES),)
+    #default
+    CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES = 512
+endif
+
+VPATH +=  ../common
+VPATH +=  $(HOST_SRCDIR)/pal
+VPATH +=  $(HOST_SRCDIR)/pal/$(OS)
+VPATH +=  $(HOST_SRCDIR)/hal/cc3x
+VPATH +=  $(HOST_SRCDIR)/cc3x_lib
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/rnd_dma
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/driver
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/api
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/common
+VPATH += $(CODESAFE_SRCDIR)/mbedtls_api
+VPATH += $(HOST_SRCDIR)/cc_mng
+
+PUBLIC_INCLUDES += $(SHARED_DIR)/include/crypto_api/cc_error.h
+PUBLIC_INCLUDES += cc_cmpu.h ../common/cc_prod.h ../common/cc_prod_error.h
+
+INCDIRS_EXTRA +=  $(HOST_SRCDIR)/pal/$(OS)
+INCDIRS_EXTRA += $(SHARED_DIR)/$(CC_TEE_HW_INC_DIR)
+INCDIRS_EXTRA +=  ../common
+INCDIRS_EXTRA +=  $(SHARED_DIR)/include/crypto_api
+INCDIRS_EXTRA +=  $(SHARED_DIR)/include/pal
+INCDIRS_EXTRA +=  $(SHARED_DIR)/include/pal/$(OS)
+INCDIRS_EXTRA += $(SHARED_DIR)/include/mbedtls
+INCDIRS_EXTRA += $(SHARED_DIR)/include/proj/$(PROJ)
+INCDIRS_EXTRA +=  $(SHARED_DIR)/../mbedtls/include
+INCDIRS_EXTRA +=  $(SHARED_DIR)/../mbedtls/include/mbedtls
+INCDIRS_EXTRA += $(HOST_SRCDIR)/cc3x_lib
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal
+INCDIRS_EXTRA += $(HOST_SRCDIR)/cc_mng
+INCDIRS_EXTRA += $(SHARED_INCDIR)/trng
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/rnd_dma/local/
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/rnd_dma
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/
+INCDIRS_EXTRA +=  $(CODESAFE_SRCDIR)/crypto_api/common
+INCDIRS_EXTRA += $(SHARED_INCDIR)/crypto_api/$(PROJ_PRD)
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/driver
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/api
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/mbedtls_api
+
+CFLAGS +=  -DCC_TEE -DCC_IOT# used for register defines
+CFLAGS_EXTRA += -DDLLI_MAX_BUFF_SIZE=$(DLLI_MAX_BUFF_SIZE)
+CFLAGS_EXTRA += -DCC_MNG_MIN_BACKUP_SIZE_IN_BYTES=$(CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES)
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/cc_prod.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/cc_prod.h
new file mode 100644
index 0000000..d3d6f16
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/cc_prod.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup prod_mem
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all of the enums and definitions that are used for
+ the ICV and OEM production libraries.
+ */
+
+#ifndef _PROD_H
+#define _PROD_H
+
+
+/************************ Defines ******************************/
+
+/*! The definition of the number of bytes in a word. */
+#define CC_PROD_32BIT_WORD_SIZE    sizeof(uint32_t)
+/*! The size of the plain-asset in bytes. */
+#define PROD_ASSET_SIZE     16
+/*! The size of the asset-package in bytes. */
+#define PROD_ASSET_PKG_SIZE     64
+/*! The size of the asset-package in words. */
+#define PROD_ASSET_PKG_WORD_SIZE    (PROD_ASSET_PKG_SIZE/CC_PROD_32BIT_WORD_SIZE)
+/*! The number of words of the DCU lock. */
+#define PROD_DCU_LOCK_WORD_SIZE     4
+
+/************************ Enums ********************************/
+
+/*! The type of the provided asset. */
+typedef enum {
+    /*! The asset is not provided. */
+        ASSET_NO_KEY = 0,
+    /*! The asset is provided as plain, not in a package. */
+        ASSET_PLAIN_KEY = 1,
+    /*! The asset is provided as a package. */
+        ASSET_PKG_KEY = 2,
+    /*! Reserved. */
+        ASSET_TYPE_RESERVED     = 0x7FFFFFFF,
+} CCAssetType_t;
+
+/************************ Typedefs  ****************************/
+
+/*! Defines the buffer of the plain asset, as a 16-byte array. */
+typedef uint8_t CCPlainAsset_t[PROD_ASSET_SIZE];
+/*! Defines the buffer of the asset-package, as a 64-byte array. */
+typedef uint32_t CCAssetPkg_t[PROD_ASSET_PKG_WORD_SIZE];
+
+
+/************************ Structs  ******************************/
+
+/*! @brief The asset buffer.
+
+  If the asset is provided as plain asset, the \p plainAsset field is used.
+  Otherwise, the \p pkgAsset field is used.
+  */
+typedef union {
+    /*! Plain asset buffer. */
+        CCPlainAsset_t     plainAsset;
+    /*! Asset-package buffer. */
+        CCAssetPkg_t       pkgAsset;
+} CCAssetBuff_t;
+
+/*!
+ @}
+ */
+#endif  //_PROD_H
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/cc_prod_error.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/cc_prod_error.h
new file mode 100644
index 0000000..7c90552
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/cc_prod_error.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup prod_errors
+ @{
+ */
+
+/*!
+@file
+@brief This file contains the error definitions of the CryptoCell
+production-library APIs.
+*/
+
+#ifndef _PROD_ERROR_H
+#define _PROD_ERROR_H
+
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* The error base address of the production library module of CryptoCell - 0x00F02A00 */
+/*! Library initialization failure. */
+#define CC_PROD_INIT_ERR                        (CC_PROD_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal parameter. */
+#define CC_PROD_INVALID_PARAM_ERR               (CC_PROD_MODULE_ERROR_BASE + 0x02UL)
+/*! Invalid number of zeroes calculated. */
+#define CC_PROD_ILLEGAL_ZERO_COUNT_ERR          (CC_PROD_MODULE_ERROR_BASE + 0x03UL)
+/*! LCS is invalid for the operation. */
+#define CC_PROD_ILLEGAL_LCS_ERR                 (CC_PROD_MODULE_ERROR_BASE + 0x04UL)
+/*! Invalid asset-package fields. */
+#define CC_PROD_ASSET_PKG_PARAM_ERR             (CC_PROD_MODULE_ERROR_BASE + 0x05UL)
+/*! Failed to validate the asset package. */
+#define CC_PROD_ASSET_PKG_VERIFY_ERR            (CC_PROD_MODULE_ERROR_BASE + 0x06UL)
+/*! HAL Fatal error occured. */
+#define CC_PROD_HAL_FATAL_ERR                   (CC_PROD_MODULE_ERROR_BASE + 0x07UL)
+
+/*!
+ @}
+ */
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_crypto_driver.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_crypto_driver.c
new file mode 100644
index 0000000..123c216
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_crypto_driver.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include "cc_pal_log.h"
+#include "cc_prod_error.h"
+#include "prod_hw_defs.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "dx_crys_kernel.h"
+#include "prod_crypto_driver.h"
+#include "cc_pal_mem.h"
+#include "aes_driver.h"
+#include "driver_defs.h"
+#include "cc_production_asset.h"
+#include "cc_aes_defs.h"
+#include "ccm.h"
+
+/**
+ * This function is used to perform AES  operation.
+ *
+ * @param[in] pInternalKey  - a pointer to internal key
+ * @param[in] pDataIn       - a pointer to input buffer - address must be 32bit aligned
+ * @param[in] dataInSize    - size of data in bytes
+ * @param[in] pOutbuff      - a pointer to output buffer- address must be 32bit aligned
+ * @param[in] outbuffSize   - size of data out bytes
+ *
+ */
+
+uint32_t CC_PROD_AesCcmDecrypt(uint8_t *pKey,
+                               uint32_t  keySizeInBytes,
+                               uint8_t *pNonce,
+                               uint32_t  nonceSizeInBytes,
+                               uint8_t *pAddData,
+                               uint32_t  addDataSizeInBytes,
+                               uint8_t *pCipherData,
+                               uint32_t  dataSize,
+                               uint8_t *pPlainBuff,
+                               uint32_t  tagSize,
+                               uint8_t *pTagBuff,
+                               unsigned long workspaceAddr,
+                            uint32_t     workspaceSize)
+{
+
+        uint32_t rc = 0;
+        mbedtls_ccm_context *pCtx;
+
+        if (workspaceSize < sizeof(mbedtls_ccm_context) || (workspaceAddr % CC_32BIT_WORD_SIZE)) {
+                CC_PAL_LOG_ERR("invalid workspace\n");
+                return CC_PROD_INVALID_PARAM_ERR;
+        }
+        pCtx = (mbedtls_ccm_context *)workspaceAddr;
+
+        mbedtls_ccm_init(pCtx);
+
+        rc = mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, pKey, keySizeInBytes * CC_BITS_IN_BYTE);
+        if (rc != 0) {
+                CC_PAL_LOG_ERR("Failed to mbedtls_ccm_setkey 0x%x\n", rc);
+                return rc;
+        }
+
+        rc = mbedtls_ccm_auth_decrypt(pCtx, dataSize,
+                                      pNonce, nonceSizeInBytes,
+                                      pAddData, addDataSizeInBytes,
+                                      pCipherData, pPlainBuff,
+                                      pTagBuff, tagSize);
+        if (rc != 0) {
+                CC_PAL_LOG_ERR("Failed to mbedtls_ccm_auth_decrypt 0x%x\n", rc);
+        }
+
+        return rc;
+}
+
+
+/**
+ * This function is used to perform AES  operation.
+ *
+ * @param[in] pInternalKey  - a pointer to internal key
+ * @param[in] pDataIn       - a pointer to input buffer - address must be 32bit aligned
+ * @param[in] dataInSize    - size of data in bytes
+ * @param[in] pOutbuff      - a pointer to output buffer- address must be 32bit aligned
+ * @param[in] outbuffSize   - size of data out bytes
+ *
+ */
+uint32_t CC_PROD_Aes(aesMode_t cipherMode,
+                     cryptoDirection_t encDecDir,
+                     cryptoKeyType_t keyType,
+                     uint8_t *pKey,
+                     uint32_t  keySizeInBytes,
+                     uint8_t *pIv,
+                     uint32_t  ivSizeInBytes,
+                     uint32_t *pDataIn,
+                     uint32_t  dataInSize,
+                     uint32_t *pOutbuff)
+{
+        uint32_t error;
+        AesContext_t aesCtx;
+
+        error = CC_PROD_AesInit(&aesCtx,
+                                cipherMode,
+                                encDecDir,
+                                keyType, pKey, keySizeInBytes,
+                                pIv, ivSizeInBytes);
+        if (error != CC_OK) {
+                return error;
+        }
+        error = CC_PROD_AesProcess(&aesCtx,
+                                   pDataIn,  dataInSize,
+                                   pOutbuff);
+        if (error != CC_OK) {
+                return error;
+        }
+        if ((cipherMode == CIPHER_CBC_MAC) && (pOutbuff != NULL)){
+            CC_PalMemCopy((uint8_t *)pOutbuff, (uint8_t *)aesCtx.ivBuf, CC_AES_BLOCK_SIZE_IN_BYTES);
+        }
+        return CC_OK;
+}
+
+/**
+ * This function is used to perform AES CBC MAC operation.
+ *
+ * @param[in] pKey  - a pointer to internal key
+ * @param[in] pDataIn       - a pointer to input buffer
+ * @param[in] blockSize     - size of data in bytes
+ * @param[in] pCmacResult   - a pointer to output buffer
+ *
+ */
+uint32_t CC_PROD_AesInit(AesContext_t *pAesCtx,
+                         aesMode_t cipherMode,
+                         cryptoDirection_t encDecDir,
+                         cryptoKeyType_t keyType,
+                         uint8_t *pKey,
+                         uint32_t keySizeInBytes,
+                         uint8_t *pIv,
+                         uint32_t ivSizeInBytes)
+{
+        switch (keySizeInBytes) {
+        case 16:
+                pAesCtx->keySizeId = KEY_SIZE_128_BIT;
+                break;
+        case 24:
+                pAesCtx->keySizeId = KEY_SIZE_192_BIT;
+                break;
+        case 32:
+                pAesCtx->keySizeId = KEY_SIZE_256_BIT;
+                break;
+        default:
+                CC_PAL_LOG_ERR("NOT OK\n");
+                return 1;
+        }
+        pAesCtx->mode = cipherMode;
+        pAesCtx->dir = encDecDir;
+        pAesCtx->cryptoKey = keyType;
+        pAesCtx->padType = CRYPTO_PADDING_NONE;
+        pAesCtx->dataBlockType = FIRST_BLOCK;
+        pAesCtx->inputDataAddrType = DLLI_ADDR;
+        pAesCtx->outputDataAddrType = DLLI_ADDR;
+        CC_PalMemCopy((uint8_t *)pAesCtx->ivBuf, pIv, ivSizeInBytes);
+        if (keyType == USER_KEY) {
+                CC_PalMemCopy((uint8_t *)pAesCtx->keyBuf, pKey, keySizeInBytes);
+        }
+
+        return CC_OK;
+}
+
+
+/**
+ * This function is used to perform AES CBC MAC operation.
+ *
+ * @param[in] cipherMode    - the aes mode
+ * @param[in] pDataIn       - a pointer to input buffer - address must be 32bit aligned
+ * @param[in] dataInSize    - size of data in bytes
+ * @param[out] pOutbuff     - a pointer to output buffer - address must be 32bit aligned
+ * @param[in] outbuffSize   -  the expectedsize of output buffer in bytes
+ *
+ */
+uint32_t CC_PROD_AesProcess(AesContext_t *pAesCtx,
+                            uint32_t *pDataIn,
+                            uint32_t  dataInSize,
+                     uint32_t *pOutbuff)
+{
+    uint32_t error;
+    CCBuffInfo_t inBuffInfo;
+    CCBuffInfo_t outBuffInfo;
+
+    /* set data buffers structures */
+    error = SetDataBuffersInfo((uint8_t*)pDataIn, dataInSize, &inBuffInfo,
+                               (uint8_t*)pOutbuff, dataInSize, &outBuffInfo);
+    if (error != 0) {
+         CC_PAL_LOG_ERR("illegal data buffers\n");
+         return error;
+    }
+
+    return ProcessAesDrv(pAesCtx, &inBuffInfo, &outBuffInfo, dataInSize);
+}
+
+
+
+uint32_t  CC_PROD_KeyDerivation(cryptoKeyType_t keyType,
+                                uint8_t *pUserKey,
+                                const uint8_t               *pLabel,
+                                size_t                      labelSize,
+                                const uint8_t               *pContextData,
+                                size_t                      contextSize,
+                                uint8_t                     *pDerivedKey)
+{
+        uint32_t                dataInSize = 0;
+        drvError_t      drvRc;
+        AesContext_t    aesCtx;
+        uint8_t         dataIn[PROD_KEY_TMP_LABEL_SIZE + PROD_KEY_TMP_CONTEXT_SIZE + 3] = { 0 };
+        CCBuffInfo_t inBuffInfo;
+        CCBuffInfo_t outBuffInfo;
+
+        /* Check inputs */
+        if (((keyType != USER_KEY) && (keyType != RTL_KEY)) ||
+            ((keyType == USER_KEY) && (pUserKey == NULL)) ||
+            (labelSize > PROD_KEY_TMP_LABEL_SIZE) ||
+            (pLabel == NULL) ||
+            (contextSize > PROD_KEY_TMP_CONTEXT_SIZE) ||
+            (pContextData == NULL) ||
+            (pDerivedKey == NULL)) {
+                return CC_PROD_INVALID_PARAM_ERR;
+        }
+
+        /* Generate dataIn buffer for CMAC: iteration || Label || 0x00 || context || length
+               since deruved key is 128 bits we have only 1 iteration */
+        dataInSize = 0;
+        dataIn[dataInSize++] = 1;
+        CC_PalMemCopy((uint8_t *)&dataIn[dataInSize], pLabel, labelSize);
+        dataInSize += labelSize;
+
+        dataIn[dataInSize++] = 0x00;
+        CC_PalMemCopy((uint8_t *)&dataIn[dataInSize], pContextData, contextSize);
+        dataInSize += contextSize;
+        dataIn[dataInSize++] =  CC_AES_BLOCK_SIZE_IN_BYTES * CC_BITS_IN_BYTE;  // all derived keys are 128 bits
+
+        aesCtx.cryptoKey = keyType;
+        aesCtx.keySizeId = KEY_SIZE_128_BIT;
+        if (keyType == USER_KEY) {
+                CC_PalMemCopy(aesCtx.keyBuf, pUserKey, CC_AES_BLOCK_SIZE_IN_BYTES);
+        }
+
+        aesCtx.mode               = CIPHER_CMAC;
+        aesCtx.dir                = CRYPTO_DIRECTION_ENCRYPT;
+        aesCtx.dataBlockType      = FIRST_BLOCK;
+        aesCtx.inputDataAddrType  = DLLI_ADDR;
+        aesCtx.outputDataAddrType = DLLI_ADDR;
+        CC_PalMemSetZero(aesCtx.ivBuf, AES_IV_SIZE);
+
+        /* set data buffers structures */
+        drvRc = SetDataBuffersInfo((uint8_t*)dataIn, dataInSize, &inBuffInfo,
+                                   NULL, 0, &outBuffInfo);
+        if (drvRc != 0) {
+             CC_PAL_LOG_ERR("illegal data buffers\n");
+             return drvRc;
+        }
+        drvRc = FinishAesDrv(&aesCtx, &inBuffInfo, &outBuffInfo, dataInSize);
+        if (drvRc != 0) {
+                return drvRc;
+        }
+        CC_PalMemCopy(pDerivedKey, aesCtx.ivBuf, CC_AES_BLOCK_SIZE_IN_BYTES);
+        return CC_OK;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_crypto_driver.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_crypto_driver.h
new file mode 100644
index 0000000..4686a36
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_crypto_driver.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _PROD_CRYPTO_DRIVER_H
+#define _PROD_CRYPTO_DRIVER_H
+
+#include "cc_cmpu.h"
+#include "cc_otp_defs.h"
+#include "driver_defs.h"
+#include "aes_driver.h"
+
+/* The AES block size in words and in bytes */
+#define CC_PROD_AES_BLOCK_SIZE_IN_WORDS     4
+#define CC_PROD_AES_BLOCK_SIZE_IN_BYTES  (CC_PROD_AES_BLOCK_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE)
+
+/* The size of the IV or counter buffer */
+#define CC_PROD_AES_IV_COUNTER_SIZE_IN_WORDS   CC_PROD_AES_BLOCK_SIZE_IN_WORDS
+#define CC_PROD_AES_IV_COUNTER_SIZE_IN_BYTES  (CC_PROD_AES_IV_COUNTER_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE)
+
+#define CC_PROD_AES_Key256Bits_SIZE_IN_WORDS    8
+#define CC_PROD_AES_Key256Bits_SIZE_IN_BYTES    (CC_PROD_AES_Key256Bits_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE)
+
+
+uint32_t CC_PROD_AesCcmDecrypt(uint8_t *pKey,
+                     uint32_t  keySizeInBytes,
+                     uint8_t *pNonce,
+                     uint32_t  nonceSizeInBytes,
+                        uint8_t *pAddData,
+                        uint32_t  addDataSizeInBytes,
+                     uint8_t *pCipherData,
+                     uint32_t  dataSize,
+                     uint8_t *pPlainBuff,
+                               uint32_t  tagSize,
+                            uint8_t *pTagBuff,
+                               unsigned long workspaceAddr,
+                            uint32_t     workspaceSize);
+
+uint32_t CC_PROD_Aes(aesMode_t cipherMode,
+               cryptoDirection_t encDecDir,
+               cryptoKeyType_t keyType,
+               uint8_t *pKey,
+               uint32_t keySize,
+               uint8_t *pIv,
+               uint32_t ivSize,
+               uint32_t *pDataIn,
+               uint32_t  dataInSize,
+               uint32_t *pOutbuff);
+
+uint32_t CC_PROD_AesInit(AesContext_t *pAesCtx,
+                         aesMode_t cipherMode,
+               cryptoDirection_t encDecDir,
+               cryptoKeyType_t keyType,
+               uint8_t *pKey,
+               uint32_t keySize,
+               uint8_t *pIv,
+               uint32_t ivSize);
+
+uint32_t CC_PROD_AesProcess(AesContext_t *pAesCtx,
+                  uint32_t *pDataIn,
+                  uint32_t  dataInSize,
+                  uint32_t *pOutbuff);
+
+uint32_t  CC_PROD_KeyDerivation( cryptoKeyType_t             keyType,
+                                    uint8_t                 *pUserKey,
+                                    const uint8_t               *pLabel,
+                                    size_t                      labelSize,
+                                    const uint8_t               *pContextData,
+                                    size_t                      contextSize,
+                                    uint8_t                     *pDerivedKey);
+
+#endif  //_PROD_CRYPTO_DRIVER_H
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_hw_defs.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_hw_defs.h
new file mode 100644
index 0000000..a956736
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_hw_defs.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CMPU_HW_DEFS_H
+#define _CMPU_HW_DEFS_H
+
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_hal_plat.h"
+
+
+#define CC_PROD_AIB_ADDR_REG_READ_ACCESS_BIT_SHIFT    0x10UL
+#define CC_PROD_AIB_ADDR_REG_WRITE_ACCESS_BIT_SHIFT   0x11UL
+
+#define CC_PROD_ROT32(val) ( (val) >> 16 | (val) << 16 )
+#define CC_PROD_CONVERT_WORD_END(val) ( ((CC_PROD_ROT32((val)) & 0xff00ff00UL) >> 8) | ((CC_PROD_ROT32((val)) & 0x00ff00ffUL) << 8) )
+#ifdef BIG__ENDIAN
+/* inverse the bytes order in a word */
+#define CC_PROD_SET_WORD_AS_LE(val) ( CC_PROD_CONVERT_WORD_END(val) )
+#define CC_PROD_SET_WORD_AS_BE(val) (val)
+#else
+#define CC_PROD_SET_WORD_AS_LE(val) (val)
+#define CC_PROD_SET_WORD_AS_BE(val) ( CC_PROD_CONVERT_WORD_END(val) )
+#endif
+
+/* Poll on the AIB bit */
+#define CC_PROD_WAIT_ON_AIB_PROG_COMP_BIT() \
+do {\
+    uint32_t regVal;\
+    do {\
+        regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AIB_FUSE_PROG_COMPLETED));\
+    }while( !(regVal & 0x1 ));\
+}while(0)
+
+/*******************************************************  OTP defines  ******************************************************/
+/* read a word directly from OTP memory */
+#define  CC_PROD_OTP_READ(otpData, otpWordOffset)                           \
+    do {                                                                                \
+        otpData = CC_HAL_READ_REGISTER( CC_OTP_BASE_ADDR + ((otpWordOffset)*CC_32BIT_WORD_SIZE));   \
+    }while(0)
+
+/* write a word directly from OTP memory */
+#define CC_PROD_OTP_WRITE(otpData, otpWordOffset)                           \
+    do {                                                                                \
+        CC_HAL_WRITE_REGISTER(( CC_OTP_BASE_ADDR + ((otpWordOffset)*CC_32BIT_WORD_SIZE)), otpData); \
+        CC_PROD_WAIT_ON_AIB_PROG_COMP_BIT();                                    \
+    }while(0)
+
+
+#define CC_PROD_OTP_WRITE_VERIFY_WORD(otpWordOffset, wordValue, rc) {\
+    uint32_t  otpActualVal = 0;\
+        if (wordValue != 0x0) { \
+                CC_PROD_OTP_WRITE((wordValue), (otpWordOffset));\
+            CC_PROD_OTP_READ(otpActualVal, (otpWordOffset));\
+                if (otpActualVal !=(wordValue)) {\
+                        rc = CC_PROD_HAL_FATAL_ERR;\
+                } else { \
+                     rc = CC_OK;\
+                }\
+        } \
+        rc = CC_OK;\
+}
+
+#define CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(otpWordOffset, wordBuff, buffWordSize, rc) {\
+    uint32_t  ii = 0;\
+    for (ii =0; ii < (buffWordSize); ii++) { \
+           CC_PROD_OTP_WRITE_VERIFY_WORD((otpWordOffset+ii), wordBuff[ii], rc); \
+           if (rc != CC_OK) { \
+                break; \
+           } \
+        } \
+}
+
+
+#define SET_OTP_MANUFACTURE_FLAG(manufactorWord, bitField, fieldValue)  \
+                        BITFIELD_SET(manufactorWord,                             \
+                                            CC_OTP_MANUFACTURE_FLAG_ ## bitField ## _BIT_SHIFT,  \
+                                            CC_OTP_MANUFACTURE_FLAG_ ## bitField ## _BIT_SIZE,   \
+                                            fieldValue)
+
+#define SET_OTP_OEM_FLAG(manufactorWord, bitField, fieldValue)  \
+                        BITFIELD_SET(manufactorWord,                             \
+                                            CC_OTP_OEM_FLAG_ ## bitField ## _BIT_SHIFT,  \
+                                            CC_OTP_OEM_FLAG_ ## bitField ## _BIT_SIZE,   \
+                                            fieldValue)
+
+#define IS_HBK0_USED(icvWord)  (BITFIELD_GET(icvWord,      \
+                                                              CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SHIFT, \
+                                                              CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SIZE) == 0)
+
+
+
+#endif // _PROD_HW_DEFS_H
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_util.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_util.c
new file mode 100644
index 0000000..361d248
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_util.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <limits.h>
+#include "cc_otp_defs.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_init.h"
+#include "cc_pal_mutex_plat.h"
+#include "prod_hw_defs.h"
+#include "cc_production_asset.h"
+#include "cc_pal_log.h"
+#include "cc_prod_error.h"
+#include "prod_crypto_driver.h"
+#include "dx_crys_kernel.h"
+#include "dx_id_registers.h"
+#include "aes_driver.h"
+#include "prod_util.h"
+
+
+// These are empty mutexs  - no mutexes are needed in production pahse
+CC_PalMutex CCSymCryptoMutex;
+CC_PalMutex CCSymCryptoMutex;
+CC_PalMutex CCAsymCryptoMutex;
+CC_PalMutex CCRndCryptoMutex;
+CC_PalMutex *pCCRndCryptoMutex;
+CC_PalMutex CCApbFilteringRegMutex;
+
+/**
+ * @brief This function
+ *
+ * @param[in]       package buffer(64 bytes),
+ *                          asset ID(4 bytes),
+ *                          label(7 bytes),
+ *                          context (16 bytes)
+ *
+ * @param[out]     plain asset (16 bytes)
+ *
+ * @return 0 -success; otherwise failure
+
+ */
+uint32_t CC_PROD_PkgVerify(CCProdAssetPkg_t *pPkgAsset,
+                            const uint8_t      *pAssetId, uint32_t assetIdSize,
+                            const uint8_t     *pLabel, uint32_t labelSize,
+                            uint8_t     *pContext, uint32_t contextSize,
+                            CCPlainAsset_t plainAsset,
+                               unsigned long workspaceAddr,
+                            uint32_t     workspaceSize) {
+        uint32_t rc = 0;
+        uint8_t     tmpKey[PROD_KEY_TMP_KEY_SIZE] = { 0 };
+        uint8_t     provKey[PROD_KEY_TMP_KEY_SIZE] = { 0 };
+        uint8_t     provKeyLabel[] = PROD_LABEL;
+        CCProdAssetPkg_t localPkgAsset;
+
+        /* Verify Inputs */
+        if ((pPkgAsset == NULL) ||
+            (pAssetId == NULL) || (assetIdSize == 0) ||
+            (pLabel == NULL) || (labelSize == 0) ||
+            (pContext == NULL) || (contextSize == 0) ||
+            (plainAsset == NULL)) {
+                CC_PAL_LOG_ERR("Invalid inputs \n");
+                return CC_PROD_INVALID_PARAM_ERR;
+        }
+
+        /* Clear outputs */
+        CC_PalMemSetZero(plainAsset, sizeof(CCPlainAsset_t));
+
+        /* Verify Package header */
+        if ((pPkgAsset->token != PROD_ASSET_PROV_TOKEN) ||
+            (pPkgAsset->version != PROD_ASSET_PROV_VERSION) ||
+            (pPkgAsset->assetSize != PROD_ASSET_SIZE) ||
+            (pPkgAsset->reserved[0] != PROD_ASSET_RESERVED1_VAL) ||
+            (pPkgAsset->reserved[1] != PROD_ASSET_RESERVED2_VAL)) {
+                CC_PAL_LOG_ERR("Failed to parse Asset package \n");
+                return CC_PROD_ASSET_PKG_PARAM_ERR;
+        }
+
+        /* Derive temporary key */
+        // Calculate Ktmp = cmac(Krtl, 0x01 || ICV/OEM_label  || 0x0 || user context || 0x80)
+        rc = CC_PROD_KeyDerivation(RTL_KEY,   NULL,
+                                   pLabel, labelSize,
+                                   pContext, contextSize,
+                                   tmpKey);
+        if (rc != 0) {
+                CC_PAL_LOG_ERR("failed to derive Ktmp, rc %d\n", rc);
+                return CC_PROD_ASSET_PKG_VERIFY_ERR;
+        }
+
+        /* Derive provisioning key */
+        // Calculate Kprov= cmac(Ktmp, 0x01 || "P"  || 0x0 || asset_id || 0x80)
+        rc = CC_PROD_KeyDerivation(USER_KEY, tmpKey,
+                                   provKeyLabel, sizeof(provKeyLabel)-1,
+                                   pAssetId, assetIdSize,
+                                   (uint8_t *)provKey);
+        if (rc != 0) {
+                CC_PAL_LOG_ERR("failed to derive Kprov, rc %d\n", rc);
+                return CC_PROD_ASSET_PKG_VERIFY_ERR;
+        }
+
+        /* Decrypt and authenticate the asset */
+        // copy the package into local buffer to be physical and contig memory
+        CC_PalMemCopy((uint8_t *)&localPkgAsset, (uint8_t *)pPkgAsset, sizeof(CCProdAssetPkg_t));
+        rc = CC_PROD_AesCcmDecrypt(
+            provKey,         CC_PROD_AES_BLOCK_SIZE_IN_BYTES,
+            (uint8_t *)localPkgAsset.nonce, PROD_ASSET_NONCE_SIZE,
+            (uint8_t *)&localPkgAsset, PROD_ASSET_ADATA_SIZE,
+            (uint8_t *)localPkgAsset.encAsset, localPkgAsset.assetSize,
+            (uint8_t *)plainAsset,
+            PROD_ASSET_TAG_SIZE,  ((uint8_t *)localPkgAsset.encAsset) + localPkgAsset.assetSize,
+            workspaceAddr,
+            workspaceSize);
+        if (rc != 0) {
+                CC_PAL_LOG_ERR("failed to CC_CommonAesCmacEncrypt() for Kprov, rc %d\n", rc);
+                return CC_PROD_ASSET_PKG_VERIFY_ERR;
+        }
+
+        return CC_OK;
+}
+
+
+uint32_t  CC_PROD_BitListFromNum(uint32_t *pWordBuff,
+                                        uint32_t wordBuffSize,
+                                        uint32_t numVal)
+{
+        uint32_t  index = 0;
+        if (numVal != 0) {
+                for (index = 0; index < wordBuffSize; index++) {
+                        pWordBuff[index] = CC_32BIT_MAX_VALUE >> (CC_BITS_IN_32BIT_WORD - PROD_MIN(numVal, CC_BITS_IN_32BIT_WORD));
+                        numVal -= PROD_MIN(numVal, CC_BITS_IN_32BIT_WORD);
+                }
+                if (numVal > 0) {
+                        CC_PalMemSetZero(pWordBuff, (wordBuffSize)*CC_32BIT_WORD_SIZE);
+                        return CC_PROD_INVALID_PARAM_ERR;
+                }
+                return CC_OK;
+        }
+        return CC_OK;
+}
+
+
+/* Count number of zeroes in 32-bit word */
+uint32_t  CC_PROD_GetZeroCount(uint32_t *pBuff,
+                               uint32_t buffWordSize,
+                               uint32_t  *pZeroCount)               {
+        uint32_t val;
+        uint32_t index = 0;
+
+        *pZeroCount = 0;
+        for (index = 0; index < buffWordSize; index++) {
+                val = pBuff[index];
+                val = val - ((val >> 1) & 0x55555555);
+                val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
+                val = ((((val + (val >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);
+                *pZeroCount += (32 - val);
+        }
+        /* All 0's and all 1's is forbidden */
+        if ((*pZeroCount == 0) || (*pZeroCount == buffWordSize*CC_BITS_IN_32BIT_WORD)) {
+                *pZeroCount = 0;
+                return CC_PROD_ILLEGAL_ZERO_COUNT_ERR;
+        }
+        return CC_OK;
+}
+
+static uint32_t VerifyPidVal(void)
+{
+    uint32_t pidReg[CC_BSV_PID_SIZE_WORDS] = {0};
+    uint32_t pidVal1[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
+    uint32_t pidVal2[CC_BSV_PID_SIZE_WORDS] = {CC_BSV_PID_0_VAL, CC_BSV_PID_1_VAL, CC_BSV_PID_2_1_VAL, CC_BSV_PID_3_VAL, CC_BSV_PID_4_VAL};
+
+    pidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_0));
+    pidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_1));
+    pidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_2));
+    pidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_3));
+    pidReg[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_4));
+
+    if ((CC_PalMemCmp((uint8_t*)pidVal1, (uint8_t*)pidReg, sizeof(pidVal1)) != 0) &&
+            (CC_PalMemCmp((uint8_t*)pidVal2, (uint8_t*)pidReg, sizeof(pidVal2)) != 0)) {
+        return CC_PROD_INIT_ERR;
+    }
+
+    return CC_OK;
+}
+
+static uint32_t VerifyCidVal(void)
+{
+    uint32_t cidReg[CC_BSV_CID_SIZE_WORDS] = {0};
+    uint32_t cidVal[CC_BSV_CID_SIZE_WORDS] = {CC_BSV_CID_0_VAL, CC_BSV_CID_1_VAL, CC_BSV_CID_2_VAL, CC_BSV_CID_3_VAL};
+
+    cidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_0));
+    cidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_1));
+    cidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_2));
+    cidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_3));
+
+    if (CC_PalMemCmp((uint8_t*)cidVal, (uint8_t*)cidReg, sizeof(cidVal)) != 0){
+        return CC_PROD_INIT_ERR;
+    }
+
+    return CC_OK;
+}
+
+uint32_t  CCProd_Init(void)
+{
+    uint32_t rc = CC_OK;
+    uint32_t reg = 0, tempVal = 0;
+
+    rc = CC_PalInit();
+    if (rc != 0) {
+        return CC_PROD_INIT_ERR;
+    }
+
+    /* verify peripheral ID (PIDR) */
+    rc = VerifyPidVal();
+    if (rc != 0) {
+        rc = CC_PROD_INIT_ERR;
+        goto end_init;
+    }
+
+    /* verify component ID (CIDR) */
+    rc = VerifyCidVal();
+    if (rc != 0) {
+        rc = CC_PROD_INIT_ERR;
+        goto end_init;
+    }
+
+    /* turn off the DFA since Cerberus doen't support it */
+    reg = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, reg, 0x0);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,reg );
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_AO_LOCK_BITS));
+    if(tempVal != reg) {
+        rc = CC_PROD_INIT_ERR;
+        goto end_init;
+    }
+
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_DFA_ENABLE_LOCK, reg, CC_TRUE);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,reg );
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_AO_LOCK_BITS));
+    if(tempVal != reg) {
+        rc = CC_PROD_INIT_ERR;
+        goto end_init;
+    }
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AES_DFA_IS_ON), 0x0UL);
+
+#ifdef BIG__ENDIAN
+/* Set DMA endianess to big */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN), 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN), 0x00UL);
+#endif
+
+    end_init:
+    if (rc != CC_OK) {
+        CCPROD_Fini();
+    }
+    return rc;
+}
+
+
+void  CCPROD_Fini(void) {
+        CC_PalTerminate();
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_util.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_util.h
new file mode 100644
index 0000000..ad4b580
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/common/prod_util.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _PROD_UTIL_H
+#define _PROD_UTIL_H
+
+#include <stdint.h>
+#include "cc_production_asset.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define PROD_MIN(a , b ) ( ( (a) < (b) ) ? (a) : (b) )
+
+uint32_t CC_PROD_PkgVerify(CCProdAssetPkg_t *pPkgAsset,
+                            const uint8_t      *pAssetId, uint32_t assetIdSize,
+                          const uint8_t     *pLabel, uint32_t labelSize,
+                          uint8_t     *pContext, uint32_t contextSize,
+                                                    CCPlainAsset_t pPlainAsset,
+                               unsigned long workspaceAddr,
+                            uint32_t     workspaceSize);
+
+uint32_t  CC_PROD_BitListFromNum(uint32_t *pWordBuff,
+                                        uint32_t wordBuffSize,
+                                        uint32_t numVal);
+
+uint32_t  CC_PROD_GetZeroCount(uint32_t *pBuff,
+                               uint32_t buffWordSize,
+                               uint32_t  *pZeroCount);
+
+
+uint32_t  CCProd_Init(void);
+
+void  CCPROD_Fini(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif  //_PROD_UTIL_H
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/Makefile b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/Makefile
new file mode 100644
index 0000000..046f80e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/Makefile
@@ -0,0 +1,18 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for cmpu utility
+HOST_PROJ_ROOT ?= $(shell pwd)/../../..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+#overwriting the OS defined in the config
+OS = no_os
+export
+
+include project_dmpu.mk
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/cc_dmpu.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/cc_dmpu.h
new file mode 100644
index 0000000..52b9972
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/cc_dmpu.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_dmpu
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all of the OEM production library APIs, their enums
+ and definitions.
+ */
+
+#ifndef _DMPU_H
+#define _DMPU_H
+
+#include "cc_pal_types_plat.h"
+#include "cc_prod.h"
+
+/************************ Defines ******************************/
+
+/*! The size of the OEM production library workspace in bytes. This workspace
+is required by the library for internal use. */
+#define DMPU_WORKSPACE_MINIMUM_SIZE  1536
+
+/*! The size of the Hbk1 buffer in words. */
+#define DMPU_HBK1_SIZE_IN_WORDS  4
+
+/*! The size of the Hbk buffer in words. */
+#define DMPU_HBK_SIZE_IN_WORDS  8
+
+/************************ Enums ********************************/
+
+/*! The type of the unique data. */
+typedef enum {
+    /*! The device uses Hbk1. */
+        DMPU_HBK_TYPE_HBK1 = 1,
+    /*! The device uses a full Hbk. */
+        DMPU_HBK_TYPE_HBK = 2,
+    /*! Reserved. */
+        DMPU_HBK_TYPE_RESERVED  = 0x7FFFFFFF,
+} CCDmpuHBKType_t;
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+
+/*!
+  The device use of the Hbk buffer.
+
+  If the device uses Hbk0 and Hbk1, then the Hbk1 field is used.
+  Otherwise, the Hbk field is used.
+ */
+typedef union {
+        /*! The Hbk1 buffer, if used by the device. */
+        uint8_t hbk1[DMPU_HBK1_SIZE_IN_WORDS*CC_PROD_32BIT_WORD_SIZE];
+        /*! The full 256-bit Hbk buffer. */
+        uint8_t hbk[DMPU_HBK_SIZE_IN_WORDS*CC_PROD_32BIT_WORD_SIZE];
+} CCDmpuHbkBuff_t;
+
+
+
+/*! The OEM production library input defines .*/
+typedef struct {
+        /*! The type of Hbk: Hbk1 - 128 bits. Hbk - 256 bits. */
+        CCDmpuHBKType_t   hbkType;
+        /*! The Hbk buffer. */
+        CCDmpuHbkBuff_t   hbkBuff;
+        /*! The Kcp asset type: Not used, Plain-asset, or Package. */
+        CCAssetType_t     kcpDataType;
+        /*! The Kcp buffer, if \p kcpDataType is Plain-asset or package. */
+        CCAssetBuff_t     kcp;
+        /*! The Kce asset type: Not used, Plain-asset, or Package. */
+        CCAssetType_t     kceDataType;
+        /*! The Kce buffer, if \p kceDataType is Plain-asset or package. */
+        CCAssetBuff_t     kce;
+        /*! The minimal SW version of the OEM. */
+        uint32_t          oemMinVersion;
+        /*! The default DCU lock bits of the OEM. */
+        uint32_t          oemDcuDefaultLock[PROD_DCU_LOCK_WORD_SIZE];
+}CCDmpuData_t;
+
+
+
+/************************ Functions *****************************/
+
+/*!
+ @brief This function burns all OEM assets into the OTP of the device.
+
+ The user must perform a power-on-reset (PoR) to trigger LCS change to Secure.
+
+ @return \c CC_OK on success.
+ @return A non-zero value from cc_prod_error.h on failure.
+*/
+CIMPORT_C CCError_t  CCProd_Dmpu(
+        /*! [in] The base address of CrytoCell HW registers. */
+        unsigned long   ccHwRegBaseAddr,
+        /*! [in] A pointer to the defines structure of the OEM. */
+        CCDmpuData_t    *pDmpuData,
+        /*! [in] The base address of the workspace for internal use. */
+        unsigned long   workspaceBaseAddr,
+        /*! [in] The size of provided workspace. Must be at least
+        \p DMPU_WORKSPACE_MINIMUM_SIZE. */
+        uint32_t        workspaceSize
+) ;
+
+
+/*!
+ @}
+ */
+#endif  //_DMPU_H
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/dmpu.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/dmpu.c
new file mode 100644
index 0000000..001202f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/dmpu.c
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_dmpu.h"
+#include "cc_otp_defs.h"
+#include "cc_pal_mem.h"
+#include "dx_crys_kernel.h"
+#include "prod_hw_defs.h"
+#include "cc_pal_log.h"
+#include "prod_util.h"
+#include "cc_prod_error.h"
+#include "prod_crypto_driver.h"
+#include "mbedtls_cc_mng_int.h"
+#include "mbedtls_cc_mng.h"
+
+static uint32_t CC_PROD_HandleKcp(CCDmpuData_t *pDmpuData,
+                                    uint32_t *pBuffForOtp,
+                                    uint32_t *pManufactorWord,
+                               unsigned long workspaceAddr,
+                            uint32_t     workspaceSize)
+{
+        uint32_t error = 0;
+        uint32_t  zeroCount = 0;
+
+        switch (pDmpuData->kcpDataType) {
+        case  ASSET_NO_KEY:
+                SET_OTP_OEM_FLAG(*pManufactorWord, KCP_NOT_IN_USE, 1);
+                goto end_kcp;
+        case  ASSET_PKG_KEY:
+                error = CC_PROD_PkgVerify((CCProdAssetPkg_t *)&pDmpuData->kcp.pkgAsset,
+                                           (const uint8_t *)PROD_OEM_PROV_CONTEXT, PROD_KPROV_CONTEXT_SIZE,
+                                           (const uint8_t *)PROD_OEM_KEY_TMP_LABEL, PROD_KEY_TMP_LABEL_SIZE,
+                                          (uint8_t *)pDmpuData->hbkBuff.hbk, CC_OTP_HBK1_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE,
+                                           (uint8_t *  )pBuffForOtp,
+                                           workspaceAddr,
+                                           workspaceSize);
+                if (error != CC_OK) {
+                        CC_PAL_LOG_ERR("failed to CC_PROD_PkgVerify fro Kcp\n");
+                        return error;
+                }
+                break;
+        case ASSET_PLAIN_KEY:
+                CC_PalMemCopy(pBuffForOtp, pDmpuData->kcp.plainAsset, PROD_ASSET_SIZE);
+                break;
+        default:
+                CC_PAL_LOG_ERR("Inavlid key type for  Kcp\n");
+                return CC_PROD_INVALID_PARAM_ERR;
+        }
+        error = CC_PROD_GetZeroCount(pBuffForOtp, PROD_KEY_TMP_CONTEXT_WORD_SIZE, &zeroCount);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Invalid zero count for Kcp\n");
+                return error;
+        }
+end_kcp:
+        SET_OTP_OEM_FLAG(*pManufactorWord, KCP_ZERO_BITS, zeroCount);
+        return CC_OK;
+}
+
+
+static uint32_t CC_PROD_HandleKce(CCDmpuData_t *pDmpuData,
+                                     uint32_t *pBuffForOtp,
+                                     uint32_t *pManufactorWord,
+                               unsigned long workspaceAddr,
+                            uint32_t     workspaceSize)
+{
+        uint32_t error = 0;
+        uint32_t  zeroCount = 0;
+
+        switch (pDmpuData->kceDataType) {
+        case  ASSET_NO_KEY:
+                SET_OTP_OEM_FLAG(*pManufactorWord, KCE_NOT_IN_USE, 1);
+                goto end_kce;
+        case  ASSET_PKG_KEY:
+                error = CC_PROD_PkgVerify((CCProdAssetPkg_t *)&pDmpuData->kce.pkgAsset,
+                                           (const uint8_t *)PROD_OEM_ENC_CONTEXT, PROD_KPROV_CONTEXT_SIZE,
+                                           (const uint8_t *)PROD_OEM_KEY_TMP_LABEL, PROD_KEY_TMP_LABEL_SIZE,
+                                          (uint8_t *)pDmpuData->hbkBuff.hbk, CC_OTP_HBK1_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE,
+                                           (uint8_t *  )pBuffForOtp,
+                                           workspaceAddr,
+                                           workspaceSize);
+                if (error != CC_OK) {
+                        CC_PAL_LOG_ERR("failed to CC_PROD_PkgVerify fro Kce\n");
+                        return error;
+                }
+                break;
+        case ASSET_PLAIN_KEY:
+                CC_PalMemCopy(pBuffForOtp, pDmpuData->kce.plainAsset, PROD_ASSET_SIZE);
+                break;
+        default:
+                CC_PAL_LOG_ERR("Invalid key type for Kce\n");
+                return CC_PROD_INVALID_PARAM_ERR;
+        }
+
+        error = CC_PROD_GetZeroCount(pBuffForOtp, PROD_KEY_TMP_CONTEXT_WORD_SIZE, &zeroCount);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Invalid zerocount for Kce\n");
+                return error;
+        }
+
+end_kce:
+        SET_OTP_OEM_FLAG(*pManufactorWord, KCE_ZERO_BITS, zeroCount);
+        return CC_OK;
+}
+
+
+
+CCError_t CCProd_Dmpu( unsigned long             ccHwRegBaseAddr,
+    CCDmpuData_t *pDmpuData,
+                     unsigned long             workspaceBaseAddr,
+                     uint32_t                 workspaceSize)
+{
+        uint32_t error = 0;
+        uint32_t lcs = 0;
+        uint32_t manufactorWord = 0;
+        uint32_t icvWord = 0;
+        uint32_t  hbkSizeInWords = 0;
+        uint32_t  hbkOtpWordOffset = 0;
+        uint32_t  swVerSizeInWords = 0;
+        uint32_t  swVerOtpWordOffset = 0;
+        uint32_t  zeroCount = 0;
+        uint32_t  i = 0;
+        uint32_t icvOwnership = 0;
+        uint32_t hbkBuffForOtp[CC_OTP_HBK_SIZE_IN_WORDS] = { 0 };
+        uint32_t kcpBuffForOtp[CC_OTP_KCP_SIZE_IN_WORDS] = { 0 };
+        uint32_t kceBuffForOtp[CC_OTP_KCE_SIZE_IN_WORDS] = { 0 };
+        uint32_t dcuLockBitsBuffForOtp[CC_OTP_DCU_SIZE_IN_WORDS] = { 0 };
+        uint32_t   oemMinSwVersion[CC_OTP_HBK_MIN_VERSION_SIZE_IN_WORDS] = { 0 };
+
+        if (sizeof(CCProdAssetPkg_t) != PROD_ASSET_PKG_SIZE) {
+                CC_PAL_LOG_ERR("invalid Pkg size\n");
+                return CC_PROD_INVALID_PARAM_ERR;
+        }
+        if ((pDmpuData == NULL) ||
+            (workspaceBaseAddr == 0) ||  //can not be zero because it is cast to a pointer later
+            (workspaceBaseAddr % CC_32BIT_WORD_SIZE) ||   // workspace address must be word aligned
+            (workspaceSize < DMPU_WORKSPACE_MINIMUM_SIZE)) {
+                CC_PAL_LOG_ERR("invalid params\n");
+                return CC_PROD_INVALID_PARAM_ERR;
+        }
+
+        gCcRegBase = ccHwRegBaseAddr;
+
+        error = CCProd_Init();
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to CCProd_Init 0x%x\n", error);
+                goto dmpuEnd;
+        }
+
+        /* Check LCS - DM only */
+        error = mbedtls_mng_lcsGet(&lcs);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to get LCS 0x%x \n", error);
+                goto dmpuEnd;
+        }
+
+        /* Verify LCS is DM */
+        if (lcs != CC_MNG_LCS_DM) {
+                CC_PAL_LOG_ERR("LCS is %d not valid\n", lcs);
+                error = CC_PROD_ILLEGAL_LCS_ERR;
+                goto dmpuEnd;
+        }
+
+        /**************** Preparing and validating teh OEM assets  ******************/
+        /* First, read ICV  manufactor word to see if HBK0 exists */
+       CC_PROD_OTP_READ(icvWord, CC_OTP_MANUFACTURE_FLAG_OFFSET);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+                goto dmpuEnd;
+        }
+
+        switch (pDmpuData->hbkType) {
+        case DMPU_HBK_TYPE_HBK1:
+                if (!IS_HBK0_USED(icvWord)) {
+                        CC_PAL_LOG_ERR("HBK type is not valid\n");
+                        error = CC_PROD_ASSET_PKG_PARAM_ERR;
+                        goto dmpuEnd;
+                }
+                hbkSizeInWords = CC_OTP_HBK1_SIZE_IN_WORDS;
+                hbkOtpWordOffset = CC_OTP_HBK1_OFFSET;
+                swVerOtpWordOffset = CC_OTP_HBK1_MIN_VERSION_OFFSET;
+                swVerSizeInWords = CC_OTP_HBK1_MIN_VERSION_SIZE_IN_WORDS;
+                break;
+        case DMPU_HBK_TYPE_HBK:
+                if (IS_HBK0_USED(icvWord)) {
+                        CC_PAL_LOG_ERR("HBK type is not valid\n");
+                        error = CC_PROD_ASSET_PKG_PARAM_ERR;
+                        goto dmpuEnd;
+                }
+                hbkSizeInWords = CC_OTP_HBK_SIZE_IN_WORDS;
+                hbkOtpWordOffset = CC_OTP_HBK_OFFSET;
+                swVerOtpWordOffset = CC_OTP_HBK_MIN_VERSION_OFFSET;
+                swVerSizeInWords = CC_OTP_HBK_MIN_VERSION_SIZE_IN_WORDS;
+                break;
+        default:
+                CC_PAL_LOG_ERR("Invalid HBK type\n");
+                error = CC_PROD_ASSET_PKG_PARAM_ERR;
+                goto dmpuEnd;
+        }
+
+        /* Set HBK/1 buffer */
+        CC_PalMemCopy(hbkBuffForOtp, pDmpuData->hbkBuff.hbk, hbkSizeInWords * CC_32BIT_WORD_SIZE);
+        error = CC_PROD_GetZeroCount(hbkBuffForOtp, hbkSizeInWords, &zeroCount);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Invalid Huk zero count\n");
+                goto dmpuEnd;
+        }
+
+        if (pDmpuData->hbkType == DMPU_HBK_TYPE_HBK) {
+                SET_OTP_OEM_FLAG(manufactorWord, HBK_ZERO_BITS, zeroCount);
+        } else {  // type is DMPU_HBK_TYPE_HBK1
+                SET_OTP_OEM_FLAG(manufactorWord, HBK1_ZERO_BITS, zeroCount);
+        }
+        /* Set OEM minimum SW version according to HBK/1*/
+        error = CC_PROD_BitListFromNum(oemMinSwVersion, swVerSizeInWords, pDmpuData->oemMinVersion);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to get bit list from number\n");
+                goto dmpuEnd;
+        }
+
+        /* Handle Kcp, or set Kcp not in use */
+        error = CC_PROD_HandleKcp(pDmpuData, kcpBuffForOtp, &manufactorWord, workspaceBaseAddr, workspaceSize);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("failed to CC_PROD_HandleKcp 0x%x \n", error);
+                goto dmpuEnd;
+        }
+
+
+        /* Handle Kce, , or set Kce not in use */
+        error = CC_PROD_HandleKce(pDmpuData, kceBuffForOtp, &manufactorWord, workspaceBaseAddr, workspaceSize);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("failed to CC_PROD_HandleKce 0x%x \n", error);
+                goto dmpuEnd;
+        }
+
+        /* Keep only OEM bit in DCU default locking */
+        for (i = 0; i < CC_OTP_DCU_SIZE_IN_WORDS; i++) {
+                icvOwnership = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_ICV_DCU_RESTRICTION_MASK0) + (i * CC_32BIT_WORD_SIZE));
+                dcuLockBitsBuffForOtp[i] = pDmpuData->oemDcuDefaultLock[i] & (~icvOwnership);
+        }
+
+        /**************** Burning OTP  ******************/
+        /* First, Burn Manufactor flag, including not in use flags set by ahndle functions above  */
+        CC_PROD_OTP_WRITE_VERIFY_WORD(CC_OTP_OEM_FLAG_OFFSET, manufactorWord, error);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+                goto dmpuEnd;
+        }
+
+        /* Burn HBK or HBK1 */
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(hbkOtpWordOffset, hbkBuffForOtp, hbkSizeInWords, error);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+                goto dmpuEnd;
+        }
+        /* DCU lock bits */
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_DCU_OFFSET, dcuLockBitsBuffForOtp, CC_OTP_DCU_SIZE_IN_WORDS, error);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+                goto dmpuEnd;
+        }
+        /* SW version */
+        CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(swVerOtpWordOffset, oemMinSwVersion, swVerSizeInWords, error);
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+                goto dmpuEnd;
+        }
+
+        /* Burn Kcp */
+        if (pDmpuData->kcpDataType  != ASSET_NO_KEY)  {
+                CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_KCP_OFFSET, kcpBuffForOtp, CC_OTP_KCP_SIZE_IN_WORDS, error);
+                if (error != CC_OK) {
+                        CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+                        goto dmpuEnd;
+                }
+        }
+        /* Burn Kce*/
+        if (pDmpuData->kceDataType  != ASSET_NO_KEY)  {
+                CC_PROD_OTP_WRITE_VERIFY_WORD_BUFF(CC_OTP_KCE_OFFSET, kceBuffForOtp, CC_OTP_KCE_SIZE_IN_WORDS, error);
+                if (error != CC_OK) {
+                        CC_PAL_LOG_ERR("Failed to verify OTP write 0x%x \n", error);
+                        goto dmpuEnd;
+                }
+        }
+
+dmpuEnd:
+        if (error != CC_OK) {
+                CC_PAL_LOG_ERR("DMPU failed, error = 0x%x \n", error);
+        }
+        CCPROD_Fini();
+        return error;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/project_dmpu.mk b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/project_dmpu.mk
new file mode 100644
index 0000000..cbc2b59
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_productionlib/dmpu/project_dmpu.mk
@@ -0,0 +1,81 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+TARGET_LIBS = dmpu
+
+SOURCES_dmpu = dmpu.c
+SOURCES_dmpu += prod_crypto_driver.c
+SOURCES_dmpu += prod_util.c
+SOURCES_dmpu += cc_hal.c
+SOURCES_dmpu += aes_driver.c
+SOURCES_dmpu += aesccm_driver.c
+SOURCES_dmpu += driver_common.c
+SOURCES_dmpu += ccm_alt.c
+SOURCES_dmpu += mbedtls_common.c
+SOURCES_dmpu += mbedtls_ccm_internal.c
+SOURCES_dmpu += mbedtls_cc_mng.c
+SOURCES_dmpu += mbedtls_cc_mng_int.c
+SOURCES_dmpu += cc_common_conv_endian.c
+
+#pal sources
+SOURCES_dmpu += cc_pal.c
+SOURCES_dmpu += cc_pal_mutex.c
+SOURCES_dmpu += cc_pal_memmap.c
+SOURCES_dmpu += cc_pal_dma.c
+SOURCES_dmpu += cc_pal_pm.c
+SOURCES_dmpu += cc_pal_interrupt_ctrl.c
+SOURCES_dmpu += cc_pal_buff_attr.c
+SOURCES_dmpu += cc_pal_mem.c
+SOURCES_dmpu += cc_pal_abort_plat.c
+
+ifeq ($(DEBUG),1)
+   SOURCES_dmpu += cc_pal_log.c
+endif
+
+ifeq ($(CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES),)
+    #default
+    CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES = 512
+endif
+
+VPATH +=  ../common
+VPATH +=  $(HOST_SRCDIR)/pal/$(OS)
+VPATH +=  $(HOST_SRCDIR)/hal/cc3x
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/driver
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/api
+VPATH += $(CODESAFE_SRCDIR)/crypto_api/common
+VPATH += $(CODESAFE_SRCDIR)/mbedtls_api
+VPATH += $(HOST_SRCDIR)/cc_mng
+
+PUBLIC_INCLUDES += $(SHARED_DIR)/include/crypto_api/cc_error.h
+PUBLIC_INCLUDES += $(HOST_SRCDIR)/cc3x_productionlib/cmpu/cc_cmpu.h
+PUBLIC_INCLUDES += cc_dmpu.h ../common/cc_prod.h ../common/cc_prod_error.h
+
+INCDIRS_EXTRA += $(SHARED_DIR)/$(CC_TEE_HW_INC_DIR)
+INCDIRS_EXTRA +=  ../common
+INCDIRS_EXTRA +=  $(SHARED_DIR)/include/pal
+INCDIRS_EXTRA +=  $(SHARED_DIR)/include/crypto_api
+INCDIRS_EXTRA += $(HOST_SRCDIR)/pal/$(OS)
+INCDIRS_EXTRA +=  $(SHARED_DIR)/include/pal/$(OS)
+INCDIRS_EXTRA += $(SHARED_DIR)/include/mbedtls
+INCDIRS_EXTRA += $(SHARED_DIR)/include/proj/$(PROJ)
+INCDIRS_EXTRA +=  $(SHARED_DIR)/../mbedtls/include
+INCDIRS_EXTRA +=  $(SHARED_DIR)/../mbedtls/include/mbedtls
+INCDIRS_EXTRA += $(HOST_SRCDIR)/cc3x_lib
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal
+INCDIRS_EXTRA += $(HOST_SRCDIR)/cc_mng
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/
+INCDIRS_EXTRA +=  $(CODESAFE_SRCDIR)/crypto_api/common
+INCDIRS_EXTRA += $(SHARED_INCDIR)/crypto_api/$(PROJ_PRD)
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/driver
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/cc3x_sym/api
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/mbedtls_api
+
+CFLAGS +=  -DCC_TEE -DCC_IOT# used for register defines
+CFLAGS_EXTRA += -DDLLI_MAX_BUFF_SIZE=$(DLLI_MAX_BUFF_SIZE)
+CFLAGS_EXTRA += -DCC_MNG_MIN_BACKUP_SIZE_IN_BYTES=$(CC_CONFIG_MNG_MIN_BACKUP_SIZE_IN_BYTES)
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/Makefile b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/Makefile
new file mode 100644
index 0000000..b10304f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/Makefile
@@ -0,0 +1,16 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+
+CFLAGS_EXTRA += -DCC_TEE -DCC_SB_SUPPORT_IOT
+OS =no_os
+include project_sbromlib.mk
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_aes_driver.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_aes_driver.c
new file mode 100644
index 0000000..94616b4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_aes_driver.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "dx_nvm.h"
+#include "secureboot_general_hwdefs.h"
+#include "secureboot_stage_defs.h"
+#include "bsv_error.h"
+#include "bsv_otp_api.h"
+#include "cc_otp_defs.h"
+
+#ifdef CC_SB_SUPPORT_SB_RT
+#include "driver_defs.h"
+#include "cc_pal_buff_attr.h"
+#include "cc_error.h"
+#endif
+
+/**********************************************************************************************/
+/************************ Private declarations ************************************************/
+/**********************************************************************************************/
+
+static CCError_t LoadBsvAesKey(unsigned long    hwBaseAddress,
+            CCBsvKeyType_t          keyType,
+            uint32_t            *pUserKey,
+            size_t              userKeySize)
+{
+    CCError_t error = CC_OK;
+    uint32_t isKeyInUse = 0;
+
+        switch (keyType) {
+
+    case CC_BSV_HUK_KEY:
+        /* validate HUK key */
+        CC_BSV_IS_OTP_HUK_ERROR(hwBaseAddress, error);
+        if (error) {
+            error = CC_BSV_ILLEGAL_HUK_VALUE_ERR;
+        }
+                break;
+
+    case CC_BSV_RTL_KEY:
+                break;
+
+    case CC_BSV_PROV_KEY:
+        /* check if key in use */
+        CC_BSV_IS_KCP_IN_USE(hwBaseAddress, isKeyInUse, error);
+        if ( (error) || (isKeyInUse != CC_TRUE) ) {
+            error = CC_BSV_ILLEGAL_KCP_VALUE_ERR;
+            break;
+        }
+
+        /* validate provisioning key */
+        CC_BSV_IS_OTP_KCP_ERROR(hwBaseAddress, error);
+        if (error) {
+            error = CC_BSV_ILLEGAL_KCP_VALUE_ERR;
+        }
+                break;
+
+    case CC_BSV_CE_KEY:
+        /* check if key in use */
+        CC_BSV_IS_KCE_IN_USE(hwBaseAddress, isKeyInUse, error);
+        if ( (error) || (isKeyInUse != CC_TRUE) ) {
+            error = CC_BSV_ILLEGAL_KCE_VALUE_ERR;
+            break;
+        }
+
+        /* validate code encryption key */
+        CC_BSV_IS_OTP_KCE_ERROR(hwBaseAddress, error);
+        if (error) {
+            error = CC_BSV_ILLEGAL_KCE_VALUE_ERR;
+        }
+                break;
+
+    case CC_BSV_ICV_PROV_KEY:
+        /* check if key in use */
+        CC_BSV_IS_KPICV_IN_USE(hwBaseAddress, isKeyInUse, error);
+        if ( (error) || (isKeyInUse != CC_TRUE) ) {
+            error = CC_BSV_ILLEGAL_KPICV_VALUE_ERR;
+            break;
+        }
+
+        /* validate provisioning key */
+        CC_BSV_IS_OTP_KPICV_ERROR(hwBaseAddress, error);
+        if (error) {
+            error = CC_BSV_ILLEGAL_KPICV_VALUE_ERR;
+        }
+                break;
+
+    case CC_BSV_ICV_CE_KEY:
+        /* check if key in use */
+        CC_BSV_IS_KCEICV_IN_USE(hwBaseAddress, isKeyInUse, error);
+        if ( (error) || (isKeyInUse != CC_TRUE) ) {
+            error = CC_BSV_ILLEGAL_KCEICV_VALUE_ERR;
+            break;
+        }
+
+        /* validate provisioning key */
+        CC_BSV_IS_OTP_KCEICV_ERROR(hwBaseAddress, error);
+        if (error) {
+            error = CC_BSV_ILLEGAL_KCEICV_VALUE_ERR;
+        }
+                break;
+
+    case CC_BSV_USER_KEY:
+        /* load user key */
+                SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_0) ,pUserKey[0]);
+                SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_1) ,pUserKey[1]);
+                SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_2) ,pUserKey[2]);
+                SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_3) ,pUserKey[3]);
+
+        if(userKeySize == CC_BSV_256BITS_KEY_SIZE_IN_BYTES) {
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_4) ,pUserKey[4]);
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_5) ,pUserKey[5]);
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_6) ,pUserKey[6]);
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_KEY_0_7) ,pUserKey[7]);
+        }
+                break;
+
+    default:
+        /* NOTE: KCE and KCEICV are not supported for CMAC KDF */
+        error = CC_BSV_INVALID_KEY_TYPE_ERROR;
+                break;
+        }
+
+    /* load secret key (HUK / KRTL / KCP / KPICV) */
+    if ( (error==CC_OK) && (keyType!=CC_BSV_USER_KEY)) {
+                SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HOST_CRYPTOKEY_SEL) ,keyType);
+                SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_SK) ,0x1);
+    }
+
+        return error;
+}
+
+
+static void LoadBsvAesIVState(unsigned long hwBaseAddress)
+{
+        /* write the initial counter value according to mode */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_0) ,0);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_1) ,0);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_2) ,0);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_3) ,0);
+
+        return;
+}
+
+
+static void LoadBsvAesCtrState(unsigned long hwBaseAddress, uint32_t *pCtrStateBuf)
+{
+        /* write the initial counter value according to mode */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_0) ,pCtrStateBuf[0]);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_1) ,pCtrStateBuf[1]);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_2) ,pCtrStateBuf[2]);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CTR_0_3) ,pCtrStateBuf[3]);
+
+        return;
+}
+
+
+/**********************************************************************************************/
+/************************              Public Functions          ******************************/
+/**********************************************************************************************/
+
+void InitBsvAes(unsigned long hwBaseAddress)
+{
+        uint32_t regVal = 0;
+
+        /* enable clocks */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
+
+        /* make sure sym engines are ready to use */
+        CC_BSV_WAIT_ON_CRYPTO_BUSY();
+
+        /* clear all interrupts before starting the engine */
+    SB_HalClearInterruptBit(hwBaseAddress, 0xFFFFFFFFUL);
+
+        /* mask dma interrupts which are not required */
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, regVal, CC_TRUE);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, regVal, CC_TRUE);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, regVal, CC_TRUE);
+        CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, regVal, CC_TRUE);
+    SB_HalMaskInterrupt(hwBaseAddress, regVal);
+
+    /* configure CC to AES */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,BSV_CRYPTO_AES);
+
+    /* zero AES_REMAINING_BYTES */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_REMAINING_BYTES) ,0);
+
+    return;
+}
+
+
+void FreeBsvAes(unsigned long hwBaseAddress)
+{
+    /* disable clocks */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
+
+    return;
+}
+
+
+CCError_t ProcessBsvAes(unsigned long       hwBaseAddress,
+            bsvAesMode_t        mode,
+            CCBsvKeyType_t      keyType,
+            uint32_t            *pUserKey,
+            size_t              userKeySize,
+            uint32_t        *pCtrStateBuf,
+            uint32_t        inputDataAddr,
+            uint32_t        outputDataAddr,
+            uint32_t        dataSize,
+            uint8_t         isLoadIv)
+{
+    CCError_t error = CC_OK;
+    uint32_t irrVal = 0;
+    uint32_t aesCtrl = 0;
+
+#ifdef CC_SB_SUPPORT_SB_RT
+    drvError_t drvRet = CC_OK;
+    uint8_t  buffNs = 0;
+    uint32_t regVal = 0;
+#endif
+
+    /* set AES configuration word */
+    CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, DEC_KEY0, aesCtrl, BSV_AES_DIRECTION_ENCRYPT);
+    CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, MODE_KEY0, aesCtrl, mode);
+    if ( (keyType == CC_BSV_HUK_KEY) ||
+         ((keyType == CC_BSV_USER_KEY) && (userKeySize == CC_BSV_256BITS_KEY_SIZE_IN_BYTES)) ){
+        /* 256b keys: HUK, user key */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesCtrl, BSV_AES_KEY_SIZE_256BITS);
+    } else {
+        /* 128b keys: RTL, KCP, KCE, KPICV, KCEICV, user key */
+        CC_REG_FLD_SET(HOST_RGF, AES_CONTROL, NK_KEY0, aesCtrl, BSV_AES_KEY_SIZE_128BITS);
+    }
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CONTROL) ,aesCtrl);
+
+    /* load AES key */
+    error = LoadBsvAesKey(hwBaseAddress, keyType, pUserKey, userKeySize);
+    if(error != CC_OK) {
+        FreeBsvAes(hwBaseAddress);
+        return error;
+    }
+
+    if(mode == BSV_AES_CIPHER_CTR)  {
+        if (isLoadIv == CC_TRUE){
+            /* load ctr regs */
+            LoadBsvAesCtrState(hwBaseAddress, pCtrStateBuf);
+        }
+
+
+#ifdef CC_SB_SUPPORT_SB_RT
+        /* Need to verify the outputDataAddr memory type and configure CC's AHBM accordingly */
+        drvRet = CC_PalDataBufferAttrGet((uint8_t*)outputDataAddr, dataSize, OUTPUT_DATA_BUFFER, &buffNs);
+        if (drvRet != CC_OK){
+            FreeBsvAes(hwBaseAddress);
+            return CC_FATAL_ERROR;
+        }
+        /* set it in regVal just if we have an output */
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_WRITE_HNONSEC, regVal, buffNs);
+
+#endif
+        /* configure destination address in case of ctr */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DST_LLI_WORD0) ,outputDataAddr);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DST_LLI_WORD1) ,dataSize);
+
+    } else {
+        /* case CMAC */
+        if (isLoadIv == CC_TRUE){
+            /* load iv length */
+            LoadBsvAesIVState(hwBaseAddress);
+            /* initiate CMAC sub-keys calculation */
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CMAC_INIT) ,CC_TRUE);
+        }
+
+        /* set the remaining bytes */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_REMAINING_BYTES) ,dataSize);
+    }
+
+
+    /* if data size is 0, only set HW reg to 1 */
+    if(dataSize == 0)
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_CMAC_SIZE0_KICK) ,CC_TRUE);
+    else {
+
+#ifdef CC_SB_SUPPORT_SB_RT
+        /* Need to verify the outputDataAddr memory type and configure CC's AHBM accordingly */
+        drvRet = CC_PalDataBufferAttrGet((uint8_t*)inputDataAddr, dataSize, INPUT_DATA_BUFFER, &buffNs);
+        if (drvRet != CC_OK){
+            FreeBsvAes(hwBaseAddress);
+            return CC_FATAL_ERROR;
+        }
+        /* if we had and output regVal already contains the output attribute */
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, buffNs);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AHBM_HNONSEC) ,regVal);
+
+#endif
+
+        /* configure source address and size */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD0) ,inputDataAddr);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD1) ,dataSize);
+
+        /* set dma completion bit in irr */
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+        error = SB_HalWaitInterrupt(hwBaseAddress, irrVal);
+        if(error != CC_OK) {
+            FreeBsvAes(hwBaseAddress);
+        }
+    }
+
+    return error;
+}
+
+
+void FinishBsvAes(unsigned long hwBaseAddress,
+    bsvAesMode_t        mode,
+    CCBsvCmacResult_t   cmacResBuf)
+{
+
+    if(mode == BSV_AES_CIPHER_CMAC) {
+        /* read and store the hash data registers */
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_0), cmacResBuf[0]);
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_1), cmacResBuf[1]);
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_2), cmacResBuf[2]);
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, AES_IV_0_3), cmacResBuf[3]);
+    }
+
+    FreeBsvAes(hwBaseAddress);
+
+    return;
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_api.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_api.h
new file mode 100644
index 0000000..c083f1e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_api.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _BSV_CRYPTO_API_H
+#define _BSV_CRYPTO_API_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains cryptographic ROM APIs : SHA256, CMAC KDF, and CCM.
+*/
+
+#include "cc_pal_types.h"
+#include "bsv_crypto_defs.h"
+#include "cc_sec_defs.h"
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+@brief This function calculates SHA256 digest over contiguous memory in an integrated operation.
+
+@return CC_OK on success.
+@return A non-zero value from bsv_error.h on failure.
+*/
+CCError_t CC_BsvSHA256(
+    unsigned long   hwBaseAddress,      /*!< [in] CryptoCell HW registers' base address. */
+    uint8_t     *pDataIn,       /*!< [in] Pointer to the input data to be HASHed. Buffer must be contiguous. */
+    size_t      dataSize,       /*!< [in] The size of the data to be hashed in Bytes. Limited to 64KB. */
+    CCHashResult_t  hashBuff        /*!< [out] Pointer to a word-aligned 32 Byte buffer. */
+    );
+
+/*!
+@brief  The key derivation function is as specified in the "KDF in Counter Mode" section of
+    NIST Special Publication 800-108: Recommendation for Key Derivation Using Pseudorandom Functions.
+    Key derivation is based on length l, label L, context C and derivation key Ki.
+        AES-CMAC is used as the pseudorandom function (PRF).
+\note   When using this API the label and context for each use-case must be well defined.
+\note   We recommend to derive only 256-bit keys from HUK or 256-bit user keys.
+
+@return CC_OK on success.
+@return A non-zero value from bsv_error.h on failure.
+*/
+
+/*  A key derivation functions can iterates n times until l bits of keying material are generated.
+        For each of the iteration of the PRF, i=1 to n, do:
+        result(0) = 0;
+        K(i) = PRF (Ki, [i] || Label || 0x00 || Context || length);
+        results(i) = result(i-1) || K(i);
+
+        concisely, result(i) = K(i) || k(i-1) || .... || k(0)*/
+CCError_t CC_BsvKeyDerivation(
+    unsigned long       hwBaseAddress,  /*!< [in] CryptoCell HW registers' base address. */
+    CCBsvKeyType_t      keyType,    /*!< [in] One of the following key types used as an input to a key derivation function:
+                              <ul><li>HUK</li>
+                              <ul><li>Krtl</li>
+                              <ul><li>KCP</li>
+                              <ul><li>KPICV</li>
+                              <ul><li>128-bit User key</li>
+                              <ul><li>256-bit User Key.</li></ul> */
+    uint32_t            *pUserKey,  /*!< [in] A pointer to the user's key buffer. */
+    size_t              userKeySize,    /*!< [in] The user key size in Bytes (limited to 16Bytes or 32Bytes). */
+    const uint8_t       *pLabel,    /*!< [in] A string that identifies the purpose for the derived keying material.*/
+    size_t              labelSize,  /*!< [in] The label size. Must be in range of 1 to 8 Bytes in length. */
+    const uint8_t       *pContextData,  /*!< [in] A binary string containing the information related to the derived keying material. */
+    size_t              contextSize,    /*!< [in] The context size should be in range of 1 to 32 Bytes in length. */
+    uint8_t         *pDerivedKey,   /*!< [out] Keying material output. Must be at least the size of derivedKeySize. */
+    size_t          derivedKeySize  /*!< [in] Size of the derived keying material in Bytes. Limited to 128bits or 256bits. */
+    );
+
+
+/*!
+@brief This API allows a limited AES-CCM decrypt and verify operation, needed for AES-CCM verification during boot.
+AES-CCM combines counter mode encryption with CBC-MAC authentication.
+Input to CCM includes the following elements:
+<ul><li> Payload - text data that is both decrypted and verified.</li>
+<li> Associated data (Adata) - data that is authenticated but not encrypted, e.g., a header.</li>
+<li> Nonce - A unique value that is assigned to the payload and the associated data.</li></ul>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined bsv_error.h.
+*/
+CCError_t CC_BsvAesCcm(
+    unsigned long       hwBaseAddress,      /*!< [in] CryptoCell HW registers' base address. */
+    CCBsvCcmKey_t       keyBuf,             /*!< [in] Pointer to the 128bit AES-CCM key. */
+    CCBsvCcmNonce_t     nonceBuf,               /*!< [in] Pointer to the 12 Byte Nonce. */
+    uint8_t                 *pAssocData,        /*!< [in] Pointer to the associated data. The buffer must be contiguous. */
+    size_t                  assocDataSize,          /*!< [in] Byte size of the associated data limited to (2^16-2^8) bytes. */
+    uint8_t                 *pTextDataIn,       /*!< [in] Pointer to the cipher-text data for decryption. The buffer must be contiguous. */
+    size_t                  textDataSize,       /*!< [in] Byte size of the full text data limited to 64KB. */
+    uint8_t                 *pTextDataOut,      /*!< [out] Pointer to the output (plain text data). The buffer must be contiguous. */
+    CCBsvCcmMacRes_t        macBuf              /*!< [in] Pointer to the MAC result buffer. */
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_defs.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_defs.h
new file mode 100644
index 0000000..8e6ff12
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_defs.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _BSV_CRYPTO_DEFS_H
+#define _BSV_CRYPTO_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains cryptographic ROM APIs definitions.
+*/
+
+/*! AES CMAC result size in words. */
+#define CC_BSV_CMAC_RESULT_SIZE_IN_WORDS    4  /* 128b */
+/*! AES CMAC result size in Bytes. */
+#define CC_BSV_CMAC_RESULT_SIZE_IN_BYTES    16 /* 128b */
+/*! AES CCM 128bit key size in Bytes. */
+#define CC_BSV_CCM_KEY_SIZE_BYTES               16
+/*! AES CCM 128bit key size in words. */
+#define CC_BSV_CCM_KEY_SIZE_WORDS               4
+/*! AES CCM NONCE size in Bytes. */
+#define CC_BSV_CCM_NONCE_SIZE_BYTES     12
+
+
+/*! Definitions for AES key types. */
+typedef enum  {
+        /*! Root key (HUK).*/
+        CC_BSV_HUK_KEY = 0,
+        /*! RTL key (Krtl).*/
+        CC_BSV_RTL_KEY = 1,
+        /*! OEM Provision key (Kcp).*/
+        CC_BSV_PROV_KEY = 2,
+        /*! OEM Code encryption key (Kce).*/
+        CC_BSV_CE_KEY = 3,
+        /*! ICV Provision key (Kpicv).*/
+        CC_BSV_ICV_PROV_KEY = 4,
+        /*! ICV Code encryption key (Kceicv).*/
+        CC_BSV_ICV_CE_KEY = 5,
+        /*! User's key.*/
+        CC_BSV_USER_KEY = 6,
+        /*! Reserved.*/
+        CC_BSV_END_OF_KEY_TYPE = 0x7FFFFFFF
+}CCBsvKeyType_t;
+
+
+/*! CMAC result buffer. */
+typedef uint32_t CCBsvCmacResult_t[CC_BSV_CMAC_RESULT_SIZE_IN_WORDS];
+
+/*! AES_CCM key buffer definition.*/
+typedef uint32_t CCBsvCcmKey_t[CC_BSV_CCM_KEY_SIZE_WORDS];
+
+/*! AES_CCM nonce buffer definition.*/
+typedef uint8_t CCBsvCcmNonce_t[CC_BSV_CCM_NONCE_SIZE_BYTES];
+
+/*! AES_CCM MAC buffer definition.*/
+typedef uint8_t CCBsvCcmMacRes_t[CC_BSV_CMAC_RESULT_SIZE_IN_BYTES];
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_driver.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_driver.h
new file mode 100644
index 0000000..550ee01
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_crypto_driver.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _BSV_CRYPTO_DRIVER_H
+#define _BSV_CRYPTO_DRIVER_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_sec_defs.h"
+#include "bsv_crypto_defs.h"
+
+/*! @file
+@brief This file contains crypto driver definitions: SH256, CMAC KDF, and CCM.
+*/
+
+/************************ Defines ******************************/
+
+/*! SHA256 digest result in words. */
+#define CC_BSV_SHA256_DIGEST_SIZE_IN_WORDS  8
+/*! SHA256 digest result in bytes. */
+#define CC_BSV_SHA256_DIGEST_SIZE_IN_BYTES  CC_BSV_SHA256_DIGEST_SIZE_IN_WORDS*sizeof(uint32_t)
+
+/*! SHA256 maximal data size to be hashed */
+#define CC_BSV_SHA256_MAX_DATA_SIZE_IN_BYTES    0x00010000 /* 64KB */
+
+
+/*! The derived key size for 128 bits. */
+#define CC_BSV_128BITS_KEY_SIZE_IN_BYTES    16
+
+/*! The derived key size for 256 bits. */
+#define CC_BSV_256BITS_KEY_SIZE_IN_BYTES    32
+
+/*! Maximal label length in bytes. */
+#define CC_BSV_MAX_LABEL_LENGTH_IN_BYTES    8
+
+/*! Maximal context length in bytes. */
+#define CC_BSV_MAX_CONTEXT_LENGTH_IN_BYTES  32
+
+/*! KDF 128 bits key fixed data size in bytes. */
+#define CC_BSV_KDF_DATA_128BITS_SIZE_IN_BYTES   3 /*!< \internal 0x01, 0x00, lengt(-0x80) */
+/*! KDF 256 bits key fixed data size in bytes. */
+#define CC_BSV_KDF_DATA_256BITS_SIZE_IN_BYTES   4 /*!< \internal 0x02, 0x00, lengt(-0x0100) */
+
+/*! KDF data maximal size in bytes. */
+#define CC_BSV_KDF_MAX_SIZE_IN_BYTES (CC_BSV_KDF_DATA_256BITS_SIZE_IN_BYTES + CC_BSV_MAX_LABEL_LENGTH_IN_BYTES + CC_BSV_MAX_CONTEXT_LENGTH_IN_BYTES)
+
+
+/*! Maximal AES CCM associated data size in bytes. */
+#define CC_BSV_CCM_MAX_ASSOC_DATA_SIZE_IN_BYTES         0xff00  /* 2^16-2^8 */
+
+/*! Maximal AES CCM text data size in bytes. */
+#define CC_BSV_CCM_MAX_TEXT_DATA_SIZE_IN_BYTES      0x00010000  /* 64KB */
+
+/*! AES block size in bytes. */
+#define BSV_AES_BLOCK_SIZE_IN_BYTES 16
+/*! AES IV size in bytes. */
+#define BSV_AES_IV_SIZE_IN_BYTES        16
+/*! AES IV size in words. */
+#define BSV_AES_IV_SIZE_IN_WORDS        4
+
+/*! HASH SHA256 control value. */
+#define BSV_HASH_CTL_SHA256_VAL         0x2UL
+/*! HASH SHA256 padding configuration. */
+#define BSV_HASH_PAD_CFG_VAL            0x4UL
+
+/************************ Typedefs  *****************************/
+/*! Definitions of cryptographic mode. */
+typedef enum bsvCryptoMode {
+    /*! AES.*/
+    BSV_CRYPTO_AES = 1,
+    /*! AES and HASH.*/
+    BSV_CRYPTO_AES_AND_HASH = 3,
+    /*! HASH.*/
+    BSV_CRYPTO_HASH = 7,
+    /*! AES to HASH and to DOUT.*/
+    BSV_CRYPTO_AES_TO_HASH_AND_DOUT = 10,
+    /*! Reserved.*/
+    BSV_CRYPTO_RESERVE32B = INT32_MAX
+}bsvCryptoMode_t;
+
+/*! Definitions for AES modes. */
+typedef enum bsvAesMode {
+    /*! AES CTR mode.*/
+    BSV_AES_CIPHER_CTR = 2,
+    /*! AES CBC MAC mode.*/
+    BSV_AES_CIPHER_CBC_MAC = 3,
+    /*! AES CMAC mode.*/
+    BSV_AES_CIPHER_CMAC = 7,
+    /*! AES CCM PE mode.*/
+    BSV_AES_CIPHER_CCMPE = 9,
+    /*! AES CCM PD mode.*/
+    BSV_AES_CIPHER_CCMPD = 10,
+    /*! Reserved.*/
+    BSV_AES_CIPHER_RESERVE32B = INT32_MAX
+}bsvAesMode_t;
+
+/*! Definitions for AES directions. */
+typedef enum bsvAesDirection {
+    /*! Encrypt.*/
+    BSV_AES_DIRECTION_ENCRYPT = 0,
+    /*! Decrypt.*/
+    BSV_AES_DIRECTION_DECRYPT = 1,
+    /*! Reserved.*/
+    BSV_AES_DIRECTION_RESERVE32B = INT32_MAX
+}bsvAesDirection_t;
+
+/*! Defintions for AES key sizes. */
+typedef enum bsvAesKeySize {
+    /*! 128 bits AES key. */
+    BSV_AES_KEY_SIZE_128BITS = 0,
+    /*! 256 bits AES key. */
+    BSV_AES_KEY_SIZE_256BITS = 2,
+    /*! Reserved.*/
+    BSV_AES_KEY_SIZE_RESERVE32B = INT32_MAX
+}bsvAesKeySize_t;
+
+/***************************** function declaration **************************/
+
+
+CCError_t BsvAes(unsigned long          hwBaseAddress,
+            bsvAesMode_t        mode,
+            CCBsvKeyType_t          keyType,
+            uint32_t            *pUserKey,
+            size_t              userKeySize,
+            uint32_t        *pIvBuf,
+            uint8_t         *pDataIn,
+            uint8_t         *pDataOut,
+            size_t                  dataSize,
+            CCBsvCmacResult_t   cmacResBuf);
+
+CCError_t BsvCryptoImageInit( unsigned long     hwBaseAddress,
+            bsvCryptoMode_t     mode,
+            CCBsvKeyType_t      keyType);
+
+CCError_t BsvCryptoImageUpdate( unsigned long   hwBaseAddress,
+            bsvCryptoMode_t     mode,
+            CCBsvKeyType_t          keyType,
+            uint32_t        *pCtrStateBuf,
+            uint8_t         *pDataIn,
+            uint8_t         *pDataOut,
+            size_t                  dataSize,
+            CCHashResult_t          hashBuff,
+            uint8_t         isLoadIV);
+
+CCError_t BsvCryptoImageFinish( unsigned long   hwBaseAddress,
+            bsvCryptoMode_t     mode,
+            CCHashResult_t          hashBuff);
+
+
+/* SHA256 */
+void InitBsvHash(unsigned long hwBaseAddress);
+void FreeBsvHash(unsigned long hwBaseAddress);
+CCError_t ProcessBsvHash(unsigned long hwBaseAddress, uint32_t inputDataAddr, uint32_t dataInSize);
+void FinishBsvHash(unsigned long hwBaseAddress, CCHashResult_t  HashBuff);
+
+
+/* AES (CTR, CMAC ) */
+
+void InitBsvAes(unsigned long hwBaseAddress);
+void FreeBsvAes(unsigned long hwBaseAddress);
+CCError_t ProcessBsvAes(unsigned long   hwBaseAddress,
+        bsvAesMode_t        mode,
+        CCBsvKeyType_t      keyType,
+        uint32_t            *pUserKey,
+        size_t              userKeySize,
+        uint32_t        *pCtrStateBuf,
+        uint32_t        inputDataAddr,
+        uint32_t        outputDataAddr,
+        uint32_t        blockSize,
+        uint8_t         isLoadIv);
+
+void FinishBsvAes(unsigned long hwBaseAddress,
+    bsvAesMode_t        mode,
+    CCBsvCmacResult_t   cmacResBuf);
+
+/* AES-CCM */
+
+CCError_t ProcessBsvAesCcm(unsigned long    hwBaseAddress,
+            bsvAesMode_t    mode,
+            uint32_t    *pKeyBuf,
+            uint32_t    *pIvBuf,
+            uint32_t    *pCtrStateBuf,
+            uint32_t    inputDataAddr,
+            uint32_t    outputDataAddr,
+            uint32_t    blockSize);
+
+void FinishBsvAesCcm(unsigned long hwBaseAddress,
+        bsvAesMode_t    mode,
+        uint32_t    *pIvBuf,
+        uint32_t    *pCtrStateBuf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_defs.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_defs.h
new file mode 100644
index 0000000..6a61f8f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_defs.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _BSV_DEFS_H
+#define _BSV_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains definitions used for the Boot Services APIs.
+*/
+
+/*! Defines the maximal hash boot key size in words. */
+#define CC_BSV_MAX_HASH_SIZE_IN_WORDS       8
+/*! Defines the maximal hash boot key size in bytes. */
+#define CC_BSV_MAX_HASH_SIZE_IN_BYTES       (CC_BSV_MAX_HASH_SIZE_IN_WORDS*sizeof(uint32_t))
+/*! Defines the maximal full-hash boot key size in words. */
+#define CC_BSV_256B_HASH_SIZE_IN_WORDS      CC_BSV_MAX_HASH_SIZE_IN_WORDS
+/*! Defines the maximal dual-hash boot key size in words. */
+#define CC_BSV_128B_HASH_SIZE_IN_WORDS      CC_BSV_MAX_HASH_SIZE_IN_WORDS/2
+
+/*! ICV Firmware minimal version maximal size. */
+#define CC_BSV_MAX_HBK0_VERSION_COUNTER     64
+/*! OEM Firmware minimal version maximal size. */
+#define CC_BSV_MAX_HBK1_VERSION_COUNTER     96
+/*! OEM Firmware minimal version maximal size (no ICV). */
+#define CC_BSV_MAX_HBK_VERSION_COUNTER      160
+
+/*! HUK status bit definition. */
+#define DX_BSV_STAUS_HUK_ERR_BIT_SHIFT         0x0UL
+/*! HUK status size bit definition. */
+#define DX_BSV_STAUS_HUK_ERR_BIT_SIZE          0x1UL
+/*! Kpicv status bit definition. */
+#define DX_BSV_STAUS_KPICV_ERR_BIT_SHIFT         0x1UL
+/*! Kpicv status size bit definition. */
+#define DX_BSV_STAUS_KPICV_ERR_BIT_SIZE          0x1UL
+/*! Kceicv status bit definition. */
+#define DX_BSV_STAUS_KCEICV_ERR_BIT_SHIFT         0x2UL
+/*! Kceicv status size bit definition. */
+#define DX_BSV_STAUS_KCEICV_ERR_BIT_SIZE          0x1UL
+/*! Kcp status bit definition. */
+#define DX_BSV_STAUS_KCP_ERR_BIT_SHIFT         0x3UL
+/*! Kcp status size bit definition. */
+#define DX_BSV_STAUS_KCP_ERR_BIT_SIZE          0x1UL
+/*! Kce status bit definition. */
+#define DX_BSV_STAUS_KCE_ERR_BIT_SHIFT         0x4UL
+/*! Kce status size bit definition. */
+#define DX_BSV_STAUS_KCE_ERR_BIT_SIZE          0x1UL
+
+/*! Definition for all ones word. */
+#define CC_BSV_ALL_ONES_VALUE   0xffffffffUL
+/*! Definition for number of bits in a 32bit word. */
+#define CC_BSV_ALL_ONES_NUM_BITS 32
+
+/* ********************** Macros ******************************* */
+/*! This macro counts the number of zeroes in a 32bits word. */
+#define CC_BSV_COUNT_ZEROES(regVal, regZero)                    \
+    do {                                    \
+        uint32_t val = regVal;                                          \
+        val = val - ((val >> 1) & 0x55555555);                          \
+        val = (val & 0x33333333) + ((val >> 2) & 0x33333333);           \
+        val = ((((val + (val >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);   \
+        regZero += (32 - val);                      \
+    }while(0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_error.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_error.h
new file mode 100644
index 0000000..ddcc747
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_error.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _SBROM_BSV_ERROR_H
+#define _SBROM_BSV_ERROR_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file defines the error code types returned from the Boot Services API's.
+*/
+
+/*! Defines BSV base error. */
+#define CC_BSV_BASE_ERROR                           0x0B000000
+/*! Defines BSV cryptographic base error. */
+#define CC_BSV_CRYPTO_ERROR                         0x0C000000
+
+/*! Illegal input parameter error. */
+#define CC_BSV_ILLEGAL_INPUT_PARAM_ERR              (CC_BSV_BASE_ERROR + 0x00000001)
+/*! Illegal HUK value error. */
+#define CC_BSV_ILLEGAL_HUK_VALUE_ERR            (CC_BSV_BASE_ERROR + 0x00000002)
+/*! Illegal Kcp value error. */
+#define CC_BSV_ILLEGAL_KCP_VALUE_ERR            (CC_BSV_BASE_ERROR + 0x00000003)
+/*! Illegal Kce value error. */
+#define CC_BSV_ILLEGAL_KCE_VALUE_ERR            (CC_BSV_BASE_ERROR + 0x00000004)
+/*! Illegal Kpicv value error. */
+#define CC_BSV_ILLEGAL_KPICV_VALUE_ERR          (CC_BSV_BASE_ERROR + 0x00000005)
+/*! Illegal Kceicv value error. */
+#define CC_BSV_ILLEGAL_KCEICV_VALUE_ERR         (CC_BSV_BASE_ERROR + 0x00000006)
+/*! Hash boot key not programmed in the OTP error. */
+#define CC_BSV_HASH_NOT_PROGRAMMED_ERR          (CC_BSV_BASE_ERROR + 0x00000007)
+/*! Illegal Hash boot key zero count in the OTP error. */
+#define CC_BSV_HBK_ZERO_COUNT_ERR           (CC_BSV_BASE_ERROR + 0x00000008)
+/*! Illegal LCS error. */
+#define CC_BSV_ILLEGAL_LCS_ERR              (CC_BSV_BASE_ERROR + 0x00000009)
+/*! OTP write compare failure error. */
+#define CC_BSV_OTP_WRITE_CMP_FAIL_ERR           (CC_BSV_BASE_ERROR + 0x0000000A)
+/*! Erase key in OTP failed error. */
+#define CC_BSV_ERASE_KEY_FAILED_ERR         (CC_BSV_BASE_ERROR + 0x0000000B)
+/*! Illegal PIDR error. */
+#define CC_BSV_ILLEGAL_PIDR_ERR             (CC_BSV_BASE_ERROR + 0x0000000C)
+/*! Illegal CIDR error. */
+#define CC_BSV_ILLEGAL_CIDR_ERR             (CC_BSV_BASE_ERROR + 0x0000000D)
+/*! Device failed to move to fatal error state. */
+#define CC_BSV_FAILED_TO_SET_FATAL_ERR          (CC_BSV_BASE_ERROR + 0x0000000E)
+/*! Failed to set RMA LCS error. */
+#define CC_BSV_FAILED_TO_SET_RMA_ERR            (CC_BSV_BASE_ERROR + 0x0000000F)
+/*! Illegal RMA indication error. */
+#define CC_BSV_ILLEGAL_RMA_INDICATION_ERR       (CC_BSV_BASE_ERROR + 0x00000010)
+/*! BSV version is not initialized error. */
+#define CC_BSV_VER_IS_NOT_INITIALIZED_ERR       (CC_BSV_BASE_ERROR + 0x00000011)
+/*! APB secure mode is locked error. */
+#define CC_BSV_APB_SECURE_IS_LOCKED_ERR         (CC_BSV_BASE_ERROR + 0x00000012)
+/*! APB privilege mode is locked error. */
+#define CC_BSV_APB_PRIVILEG_IS_LOCKED_ERR       (CC_BSV_BASE_ERROR + 0x00000013)
+/*! Illegal operation error. */
+#define CC_BSV_ILLEGAL_OPERATION_ERR            (CC_BSV_BASE_ERROR + 0x00000014)
+/*! Illegal asset size error. */
+#define CC_BSV_ILLEGAL_ASSET_SIZE_ERR           (CC_BSV_BASE_ERROR + 0x00000015)
+/*! Illegal asset value error. */
+#define CC_BSV_ILLEGAL_ASSET_VAL_ERR            (CC_BSV_BASE_ERROR + 0x00000016)
+/*! Kpicv is locked error. */
+#define CC_BSV_KPICV_IS_LOCKED_ERR              (CC_BSV_BASE_ERROR + 0x00000017)
+/*! Illegal SW version error. */
+#define CC_BSV_ILLEGAL_SW_VERSION_ERR           (CC_BSV_BASE_ERROR + 0x00000018)
+/*! AO write operation error. */
+#define CC_BSV_AO_WRITE_FAILED_ERR              (CC_BSV_BASE_ERROR + 0x00000019)
+/*! Device is locked in fatal error state. */
+#define CC_BSV_FATAL_ERR_IS_LOCKED_ERR          (CC_BSV_BASE_ERROR + 0x0000001A)
+
+/*! Illegal data in pointer error. */
+#define CC_BSV_INVALID_DATA_IN_POINTER_ERROR        (CC_BSV_CRYPTO_ERROR + 0x00000001)
+/*! Illegal data out pointer error. */
+#define CC_BSV_INVALID_DATA_OUT_POINTER_ERROR       (CC_BSV_CRYPTO_ERROR + 0x00000002)
+/*! Illegal data size error. */
+#define CC_BSV_INVALID_DATA_SIZE_ERROR          (CC_BSV_CRYPTO_ERROR + 0x00000003)
+/*! Illegal key type error. */
+#define CC_BSV_INVALID_KEY_TYPE_ERROR           (CC_BSV_CRYPTO_ERROR + 0x00000004)
+/*! Illegal key size error. */
+#define CC_BSV_INVALID_KEY_SIZE_ERROR           (CC_BSV_CRYPTO_ERROR + 0x00000005)
+/*! Illegal KDF label error. */
+#define CC_BSV_ILLEGAL_KDF_LABEL_ERROR          (CC_BSV_CRYPTO_ERROR + 0x00000006)
+/*! Illegal KDF context error. */
+#define CC_BSV_ILLEGAL_KDF_CONTEXT_ERROR        (CC_BSV_CRYPTO_ERROR + 0x00000007)
+/*! Invalid CCM key error. */
+#define CC_BSV_CCM_INVALID_KEY_ERROR            (CC_BSV_CRYPTO_ERROR + 0x00000008)
+/*! Invalid CCM Nonce error. */
+#define CC_BSV_CCM_INVALID_NONCE_ERROR          (CC_BSV_CRYPTO_ERROR + 0x00000009)
+/*! Invalid CCM associated data error. */
+#define CC_BSV_CCM_INVALID_ASSOC_DATA_ERROR     (CC_BSV_CRYPTO_ERROR + 0x0000000A)
+/*! Invalid CCM text data error. */
+#define CC_BSV_CCM_INVALID_TEXT_DATA_ERROR      (CC_BSV_CRYPTO_ERROR + 0x0000000B)
+/*! Invalid CCM-MAC buffer error. */
+#define CC_BSV_CCM_INVALID_MAC_BUF_ERROR        (CC_BSV_CRYPTO_ERROR + 0x0000000C)
+/*! Output and input data are overlapping error. */
+#define CC_BSV_CCM_DATA_OUT_DATA_IN_OVERLAP_ERROR   (CC_BSV_CRYPTO_ERROR + 0x0000000D)
+/*! CCM-MAC comparison failed error. */
+#define CC_BSV_CCM_MAC_INVALID_ERROR            (CC_BSV_CRYPTO_ERROR + 0x0000000E)
+/*! Invalid CCM mode error. */
+#define CC_BSV_CCM_INVALID_MODE_ERROR           (CC_BSV_CRYPTO_ERROR + 0x0000000F)
+/*! Invalid out pointer error. */
+#define CC_BSV_INVALID_OUT_POINTER_ERROR        (CC_BSV_CRYPTO_ERROR + 0x00000010)
+/*! Illegal cryptographic mode error. */
+#define CC_BSV_INVALID_CRYPTO_MODE_ERROR        (CC_BSV_CRYPTO_ERROR + 0x00000011)
+/*! Illegal IV pointer error. */
+#define CC_BSV_INVALID_IV_POINTER_ERROR         (CC_BSV_CRYPTO_ERROR + 0x00000012)
+/*! Illegal result buffer pointer error. */
+#define CC_BSV_INVALID_RESULT_BUFFER_POINTER_ERROR  (CC_BSV_CRYPTO_ERROR + 0x00000013)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_hash_driver.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_hash_driver.c
new file mode 100644
index 0000000..0147384
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_hash_driver.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "secureboot_general_hwdefs.h"
+#include "secureboot_stage_defs.h"
+
+#ifdef CC_SB_SUPPORT_SB_RT
+#include "driver_defs.h"
+#include "cc_pal_buff_attr.h"
+#include "cc_error.h"
+#endif
+
+/**********************************************************************************************/
+/************************ Private declarations ************************************************/
+/**********************************************************************************************/
+
+/* initial HASH values */
+static const uint32_t BSV_HASH_SHA256[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
+
+
+/**********************************************************************************************/
+/************************              Public Functions          ******************************/
+/**********************************************************************************************/
+
+void InitBsvHash(unsigned long hwBaseAddress)
+{
+    uint32_t regVal = 0;
+
+    /* enable clocks */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_ENABLE);
+
+    /* make sure sym engines are ready to use */
+    CC_BSV_WAIT_ON_CRYPTO_BUSY();
+
+    /* clear all interrupts before starting the engine */
+    SB_HalClearInterruptBit(hwBaseAddress, 0xFFFFFFFFUL);
+
+    /* mask dma interrupts which are not required */
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, regVal, CC_TRUE);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, regVal, CC_TRUE);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, regVal, CC_TRUE);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, regVal, CC_TRUE);
+    SB_HalMaskInterrupt(hwBaseAddress, regVal);
+
+    /* configure CC to hash */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_CTL) ,BSV_CRYPTO_HASH);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_SEL_AES_MAC) ,0);
+
+    /* set hash operation mode */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CONTROL) ,BSV_HASH_CTL_SHA256_VAL);
+
+    /* enable HW padding */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_EN) ,CC_TRUE);
+
+    /* load the current length of message being processed */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CUR_LEN_0), 0);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CUR_LEN_1), 0);
+
+    /* initializing the init HASH values from context */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H7) ,BSV_HASH_SHA256[7]);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H6) ,BSV_HASH_SHA256[6]);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H5) ,BSV_HASH_SHA256[5]);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H4) ,BSV_HASH_SHA256[4]);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H3) ,BSV_HASH_SHA256[3]);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H2) ,BSV_HASH_SHA256[2]);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H1) ,BSV_HASH_SHA256[1]);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H0) ,BSV_HASH_SHA256[0]);
+
+    /* do NOT use HW padding (to enable non-integrated operations) */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AUTO_HW_PADDING) ,CC_FALSE);
+
+    return;
+}
+
+
+void FreeBsvHash(unsigned long hwBaseAddress)
+{
+    /* reset to default values in case of operation completion */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AUTO_HW_PADDING) ,CC_FALSE);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_CFG) ,CC_FALSE);
+
+    /* disable clocks */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, DMA_CLK_ENABLE) ,CC_BSV_CLOCK_DISABLE);
+
+    return;
+}
+
+
+CCError_t ProcessBsvHash( unsigned long hwBaseAddress,
+            uint32_t inputDataAddr,
+            uint32_t dataInSize)
+{
+    uint32_t irrVal = 0;
+    CCError_t error = CC_OK;
+    CCHashResult_t  tempBuff;
+
+#ifdef CC_SB_SUPPORT_SB_RT
+    drvError_t drvRet = CC_OK;
+    uint8_t  buffNs = 0;
+    uint32_t regVal = 0;
+#endif
+
+    if (dataInSize != 0) {
+
+#ifdef CC_SB_SUPPORT_SB_RT
+        /* Need to verify the DataIn memory type and configure CC's AHBM accordingly */
+        drvRet = CC_PalDataBufferAttrGet((uint8_t*)inputDataAddr, dataInSize, INPUT_DATA_BUFFER, &buffNs);
+        if (drvRet != CC_OK){
+            FreeBsvHash(hwBaseAddress);
+            return CC_FATAL_ERROR;
+        }
+
+        CC_REG_FLD_SET(HOST_RGF, AHBM_HNONSEC, AHB_READ_HNONSEC, regVal, buffNs);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, AHBM_HNONSEC) ,regVal);
+
+#endif
+        /* configure source address and size */
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD0) ,inputDataAddr);
+        SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, SRC_LLI_WORD1) ,dataInSize);
+
+        /* set dma completion bit in irr */
+        CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, irrVal, 1);
+        error = SB_HalWaitInterrupt(hwBaseAddress, irrVal);
+        if(error != CC_OK) {
+            /* Note: Hash operation should be completed also in case of error! */
+
+            /* Use DO_PAD to complete padding of full operation */
+            SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_CFG) ,BSV_HASH_PAD_CFG_VAL);
+
+            /* Empty Hash HW registers */
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H7), tempBuff[7]);
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H6), tempBuff[6]);
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H5), tempBuff[5]);
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H4), tempBuff[4]);
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H3), tempBuff[3]);
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H2), tempBuff[2]);
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H1), tempBuff[1]);
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H0), tempBuff[0]);
+
+            /* Reset Hash temporary results */
+            UTIL_MemSet((uint8_t*)tempBuff, 0, sizeof(CCHashResult_t));
+
+            FreeBsvHash(hwBaseAddress);
+        }
+
+    }
+
+    return error;
+}
+
+
+void FinishBsvHash(unsigned long hwBaseAddress, CCHashResult_t  hashBuff)
+{
+    int i;
+
+    /* use DO_PAD to complete padding of full operation */
+    SB_HAL_WRITE_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_PAD_CFG) ,BSV_HASH_PAD_CFG_VAL);
+
+    /* read and store the hash data registers */
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H7), hashBuff[7]);
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H6), hashBuff[6]);
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H5), hashBuff[5]);
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H4), hashBuff[4]);
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H3), hashBuff[3]);
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H2), hashBuff[2]);
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H1), hashBuff[1]);
+    SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, HASH_H0), hashBuff[0]);
+
+    /* reverse the bytes */
+    for ( i = 0 ; i < CC_BSV_SHA256_DIGEST_SIZE_IN_WORDS ; i++ ){
+        hashBuff[i] = UTIL_INVERSE_UINT32_BYTES(hashBuff[i]);
+    }
+
+    FreeBsvHash(hwBaseAddress);
+
+    return;
+
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_hw_defs.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_hw_defs.h
new file mode 100644
index 0000000..f4a955c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_hw_defs.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _BSV_HW_DEFS_H
+#define _BSV_HW_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* ********************** Macros ******************************* */
+
+/* poll NVM register to assure that the NVM boot is finished (and LCS and the keys are valid) */
+#define CC_BSV_WAIT_ON_NVM_IDLE_BIT(hwBaseAddress)                      \
+    do {                                            \
+        uint32_t regVal;                                \
+        do {                                        \
+            SB_HAL_READ_REGISTER( SB_REG_ADDR(hwBaseAddress, NVM_IS_IDLE), regVal); \
+            regVal = CC_REG_FLD_GET(0, NVM_IS_IDLE, VALUE, regVal);         \
+        }while( !regVal );                              \
+    }while(0)
+
+/* poll on the AIB acknowledge bit */
+#define CC_BSV_WAIT_ON_AIB_ACK_BIT(hwBaseAddress)       \
+    do {                                                \
+        uint32_t regVal;                                \
+        do {                                            \
+            SB_HAL_READ_REGISTER( SB_REG_ADDR(hwBaseAddress, AIB_FUSE_PROG_COMPLETED), regVal); \
+        }while( !(regVal & 0x1 ));                      \
+    }while(0)
+
+/* check HUK error bit in LCS register */
+#define CC_BSV_IS_OTP_HUK_ERROR(hwBaseAddress, regVal)                      \
+    do {                                            \
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, LCS_REG), regVal);      \
+        regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_KDR_ZERO_CNT, regVal);        \
+    }while(0)
+
+/* check KPICV error bit in LCS register */
+#define CC_BSV_IS_OTP_KPICV_ERROR(hwBaseAddress, regVal)                    \
+    do {                                            \
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, LCS_REG), regVal);      \
+        regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_KPICV_ZERO_CNT, regVal);      \
+    }while(0)
+
+/* check KCEICV error bit in LCS register */
+#define CC_BSV_IS_OTP_KCEICV_ERROR(hwBaseAddress, regVal)                   \
+    do {                                            \
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, LCS_REG), regVal);      \
+        regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_KCEICV_ZERO_CNT, regVal);     \
+    }while(0)
+
+/* check KCP error bit in LCS register */
+#define CC_BSV_IS_OTP_KCP_ERROR(hwBaseAddress, regVal)                      \
+    do {                                            \
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, LCS_REG), regVal);      \
+        regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_PROV_ZERO_CNT, regVal);       \
+    }while(0)
+
+/* check KCE error bit in LCS register */
+#define CC_BSV_IS_OTP_KCE_ERROR(hwBaseAddress, regVal)                      \
+    do {                                            \
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, LCS_REG), regVal);      \
+        regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_KCE_ZERO_CNT, regVal);        \
+    }while(0)
+
+/* read a word directly from OTP memory */
+#define CC_BSV_READ_OTP_WORD(hwBaseAddress, otpAddr, otpData)                           \
+    do {                                                                                \
+        SB_HAL_READ_REGISTER((hwBaseAddress + CC_OTP_BASE_ADDR + otpAddr), otpData);    \
+    }while(0)
+
+/* write a word directly from OTP memory */
+#define CC_BSV_WRITE_OTP_WORD(hwBaseAddress, otpAddr, otpData)                          \
+    do {                                                                                \
+        SB_HAL_WRITE_REGISTER((hwBaseAddress + CC_OTP_BASE_ADDR + otpAddr), otpData);   \
+        CC_BSV_WAIT_ON_AIB_ACK_BIT(hwBaseAddress);                                      \
+    }while(0)
+
+/* calc OTP memory length:
+   read RTL OTP address width. The supported sizes are 6 (for 2 Kbits),7,8,9,10,11 (for 64 Kbits).
+   convert value parameter to addresses of 32b words */
+#define CC_BSV_GET_OTP_LENGTH(hwBaseAddress, otpLength)                         \
+    do {                                                \
+        SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, OTP_ADDR_WIDTH_DEF), otpLength);    \
+        otpLength = CC_REG_FLD_GET(0, OTP_ADDR_WIDTH_DEF, VALUE, otpLength);            \
+        otpLength = (1 << otpLength);                               \
+    }while(0)
+
+/* check Hbk configuration in OTP memory */
+#define CC_BSV_IS_HBK_FULL(hwBaseAddress, isHbkFull, error)                             \
+    do {                                                        \
+        error = CC_BsvOTPWordRead(hwBaseAddress, CC_OTP_MANUFACTURE_FLAG_OFFSET, &isHbkFull);           \
+        isHbkFull = CC_REG_FLD_GET2(0, OTP_MANUFACTURE_FLAG, HBK0_NOT_IN_USE, isHbkFull);           \
+    }while(0)
+
+/* check OEM RMA flag bit in OTP memory */
+#define CC_BSV_IS_OEM_RMA_FLAG_SET(hwBaseAddress, isOemRmaFlag, error)                          \
+    do {                                                        \
+        error = CC_BsvOTPWordRead(hwBaseAddress, CC_OTP_OEM_FLAG_OFFSET, &isOemRmaFlag);            \
+        isOemRmaFlag = CC_REG_FLD_GET2(0, OTP_OEM_FLAG, OEM_RMA_MODE, isOemRmaFlag);                \
+    }while(0)
+
+/* check ICV RMA flag bit in OTP memory */
+#define CC_BSV_IS_ICV_RMA_FLAG_SET(hwBaseAddress, isIcvRmaFlag, error)                          \
+    do {                                                        \
+        error = CC_BsvOTPWordRead(hwBaseAddress, CC_OTP_OEM_FLAG_OFFSET, &isIcvRmaFlag);            \
+        isIcvRmaFlag = CC_REG_FLD_GET2(0, OTP_OEM_FLAG, ICV_RMA_MODE, isIcvRmaFlag);                \
+    }while(0)
+
+/* poll on the crypto busy till it is = 0 */
+#define CC_BSV_WAIT_ON_CRYPTO_BUSY()                                \
+    do {                                            \
+        uint32_t regVal=1;                              \
+        do {                                        \
+            SB_HAL_READ_REGISTER(SB_REG_ADDR(hwBaseAddress, CRYPTO_BUSY), regVal);  \
+                }while( regVal );                               \
+        }while(0)
+
+/* check KPICV "Not In Use" bit in OTP memory */
+#define CC_BSV_IS_KPICV_IN_USE(hwBaseAddress, isKpicvInUse, error)                          \
+    do {                                                        \
+        error = CC_BsvOTPWordRead(hwBaseAddress, CC_OTP_MANUFACTURE_FLAG_OFFSET, &isKpicvInUse);        \
+        isKpicvInUse = 0x1UL ^ (CC_REG_FLD_GET2(0, OTP_MANUFACTURE_FLAG, KPICV_NOT_IN_USE, isKpicvInUse));  \
+    }while(0)
+
+/* check KCEICV "Not In Use" bit in OTP memory */
+#define CC_BSV_IS_KCEICV_IN_USE(hwBaseAddress, isKceicvInUse, error)                            \
+    do {                                                        \
+        error = CC_BsvOTPWordRead(hwBaseAddress, CC_OTP_MANUFACTURE_FLAG_OFFSET, &isKceicvInUse);       \
+        isKceicvInUse = 0x1UL ^ (CC_REG_FLD_GET2(0, OTP_MANUFACTURE_FLAG, KCEICV_NOT_IN_USE, isKceicvInUse));   \
+    }while(0)
+
+/* check KCP "Not In Use" bit in OTP memory */
+#define CC_BSV_IS_KCP_IN_USE(hwBaseAddress, isKcpInUse, error)                      \
+    do {                                                \
+        error = CC_BsvOTPWordRead(hwBaseAddress, CC_OTP_OEM_FLAG_OFFSET, &isKcpInUse);      \
+        isKcpInUse = 0x1UL ^ (CC_REG_FLD_GET2(0, OTP_OEM_FLAG, KCP_NOT_IN_USE, isKcpInUse));    \
+    }while(0)
+
+/* check KCE "Not In Use" bit in OTP memory */
+#define CC_BSV_IS_KCE_IN_USE(hwBaseAddress, isKceInUse, error)                      \
+    do {                                                \
+        error = CC_BsvOTPWordRead(hwBaseAddress, CC_OTP_OEM_FLAG_OFFSET, &isKceInUse);      \
+        isKceInUse = 0x1UL ^ (CC_REG_FLD_GET2(0, OTP_OEM_FLAG, KCE_NOT_IN_USE, isKceInUse));    \
+    }while(0)
+
+
+
+/* ********************** Definitions ******************************* */
+
+/* HW clocks */
+#define CC_BSV_CLOCK_ENABLE     0x1UL
+#define CC_BSV_CLOCK_DISABLE        0x0UL
+
+/* Peripheral ID registers values */
+#define CC_BSV_PID_0_VAL        0x000000C0UL
+#define CC_BSV_PID_1_VAL        0x000000B0UL
+#define CC_BSV_PID_2_VAL        0x0000000BUL
+#define CC_BSV_PID_3_VAL        0x00000000UL
+#define CC_BSV_PID_4_VAL        0x00000004UL
+#define CC_BSV_PID_SIZE_WORDS       5
+
+/* Component ID registers values */
+#define CC_BSV_CID_0_VAL        0x0DUL
+#define CC_BSV_CID_1_VAL        0xF0UL
+#define CC_BSV_CID_2_VAL        0x05UL
+#define CC_BSV_CID_3_VAL        0xB1UL
+#define CC_BSV_CID_SIZE_WORDS       4
+
+/* Secret Key */
+#define CC_BSV_SK_ERASER_VAL            0xFFFFFFFFUL
+#define CC_BSV_256B_SK_INTEGRITY_ERASER_VAL 0xFFUL
+#define CC_BSV_128B_SK_INTEGRITY_ERASER_VAL 0x7FUL
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_otp_api.h b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_otp_api.h
new file mode 100644
index 0000000..1ebd84c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_sbromlib/bsv_otp_api.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _BSV_OTP_API_H
+#define _BSV_OTP_API_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*! @file
+@brief This file contains functions that access the OTP memory for read and write operations.
+\note This implementation can be replaced by the partner, depending on memory requirements.
+*/
+
+/*!
+@brief This function retrieves a 32-bit OTP memory word from a given address.
+
+@return CC_OK on success.
+@return A non-zero value from bsv_error.h on failure.
+*/
+CCError_t CC_BsvOTPWordRead(
+    unsigned long hwBaseAddress,    /*!< [in] CryptoCell HW registers' base address. */
+    uint32_t otpAddress,        /*!< [in] Word address in the OTP memory to read from. */
+    uint32_t *pOtpWord      /*!< [out] The OTP memory word's contents. */
+    );
+
+
+/*!
+@brief This function writes a 32-bit OTP memory word to a given address. Prior to writing,
+    the function reads the current value in the OTP memory word, and performs bit-wise OR to generate the expected value.
+        After writing, the word is read and compared to the expected value.
+
+
+@return CC_OK on success.
+@return A non-zero value from sbrom_bsv_error.h on failure.
+*/
+CCError_t CC_BsvOTPWordWrite(
+    unsigned long hwBaseAddress,    /*!< [in] CryptoCell HW registers' base address. */
+    uint32_t otpAddress,        /*!< [in] Word address in the OTP memory to write to. */
+    uint32_t otpWord        /*!< [in] The OTP memory word's contents. */
+    );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng.c b/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng.c
new file mode 100644
index 0000000..9e95c00
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng.c
@@ -0,0 +1,834 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "mbedtls_cc_mng.h"
+#include "mbedtls_cc_mng_error.h"
+#include "mbedtls_cc_mng_int.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_otp_defs.h"
+#include "dx_id_registers.h"
+#include "dx_crys_kernel.h"
+#include "driver_defs.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mutex.h"
+#include "cc_util_pm.h"
+#include "cc_util_apbc.h"
+
+
+extern CC_PalMutex CCSymCryptoMutex;
+extern CC_PalMutex CCAsymCryptoMutex;
+extern CC_PalMutex CCRndCryptoMutex;
+extern CC_PalMutex CCApbFilteringRegMutex;
+
+/************* Auxiliary API's *************/
+
+static CCError_t setHwKeyToShadowReg(mbedtls_mng_keytype keyType, uint32_t *pHwKey, size_t keySize)
+{
+    CCError_t rc = CC_OK;
+    uint32_t  wordIdx;
+    uint32_t  regAddr = 0;
+    uint32_t  regVal = 0;
+    uint32_t  shft = 0;
+
+    /* check input variables */
+    if (pHwKey == NULL) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+        switch (keyType) {
+    case CC_MNG_HUK_KEY:
+        if (AES_256_BIT_KEY_SIZE != keySize) {
+            return CC_MNG_ILLEGAL_HUK_SIZE_ERR;
+        }
+        regAddr = DX_HOST_SHADOW_KDR_REG_REG_OFFSET;
+                break;
+    case CC_MNG_PROV_KEY:
+        if (AES_128_BIT_KEY_SIZE != keySize) {
+            return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
+        }
+        shft    = CC_MNG_HOST_KCP_LOCK_BIT_SHFT;
+        regAddr = DX_HOST_SHADOW_KCP_REG_REG_OFFSET;
+                break;
+    case CC_MNG_CE_KEY:
+        if (AES_128_BIT_KEY_SIZE != keySize) {
+            return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
+        }
+        shft    = CC_MNG_HOST_KCE_LOCK_BIT_SHFT;
+        regAddr = DX_HOST_SHADOW_KCE_REG_REG_OFFSET;
+                break;
+    case CC_MNG_ICV_PROV_KEY:
+        if (AES_128_BIT_KEY_SIZE != keySize) {
+            return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
+        }
+        shft    = CC_MNG_HOST_KPICV_LOCK_BIT_SHFT;
+        regAddr = DX_HOST_SHADOW_KPICV_REG_REG_OFFSET;
+                break;
+    case CC_MNG_ICV_CE_KEY:
+        if (AES_128_BIT_KEY_SIZE != keySize) {
+            return CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR;
+        }
+        shft    = CC_MNG_HOST_KCEICV_LOCK_BIT_SHFT;
+        regAddr = DX_HOST_SHADOW_KCEICV_REG_REG_OFFSET;
+                break;
+    default:
+        rc = CC_MNG_INVALID_KEY_TYPE_ERROR;
+                break;
+        }
+
+        if ((CC_OK == rc) && (CC_MNG_HUK_KEY != keyType)) {
+        /* read APB slave accesses control register */
+        regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
+        /* check if relevant HW key is already locked */
+        if(CC_TRUE == ((regVal>>shft)&0x1)) {
+            rc = CC_MNG_HW_KEY_IS_LOCKED_ERR;
+        }
+        }
+
+        /* Load HW key (HUK / KCP / KCE / KPICV / KCEICV) */
+    if (CC_OK == rc) {
+        /* Set HW Key Value in the Shadow register */
+        for (wordIdx = 0; wordIdx < (keySize>>2); wordIdx++) {
+            CC_HAL_WRITE_REGISTER(regAddr, pHwKey[wordIdx]);
+        }
+    }
+
+        return rc;
+}
+
+static int VerifyReadPidVal(uint32_t *pidReg, size_t pidSize)
+{
+    uint32_t pidVal1[CC_MNG_PID_SIZE_WORDS] = {CC_MNG_PID_0_VAL, CC_MNG_PID_1_VAL, CC_MNG_PID_2_VAL, CC_MNG_PID_3_VAL, CC_MNG_PID_4_VAL};
+    uint32_t pidVal2[CC_MNG_PID_SIZE_WORDS] = {CC_MNG_PID_0_VAL, CC_MNG_PID_1_VAL, CC_MNG_PID_2_1_VAL, CC_MNG_PID_3_VAL, CC_MNG_PID_4_VAL};
+
+    if (pidReg == NULL || pidSize != CC_MNG_PID_SIZE_WORDS) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    pidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_0));
+    pidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_1));
+    pidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_2));
+    pidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_3));
+    pidReg[4] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, PERIPHERAL_ID_4));
+
+    if ((CC_PalMemCmp((uint8_t*)pidVal1, (uint8_t*)pidReg, sizeof(pidVal1)) != 0) &&
+            (CC_PalMemCmp((uint8_t*)pidVal2, (uint8_t*)pidReg, sizeof(pidVal2)) != 0)) {
+        return CC_MNG_ILLEGAL_PIDR_ERR;
+    }
+
+    return CC_OK;
+}
+
+static int VerifyCidVal(void)
+{
+    uint32_t cidReg[CC_BSV_CID_SIZE_WORDS] = {0};
+    uint32_t cidVal[CC_MNG_CID_SIZE_WORDS] = {CC_MNG_CID_0_VAL, CC_MNG_CID_1_VAL, CC_MNG_CID_2_VAL, CC_MNG_CID_3_VAL};
+
+    cidReg[0] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_0));
+    cidReg[1] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_1));
+    cidReg[2] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_2));
+    cidReg[3] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, COMPONENT_ID_3));
+
+    if (CC_PalMemCmp((uint8_t*)cidVal, (uint8_t*)cidReg, sizeof(cidVal)) != 0){
+        return CC_MNG_ILLEGAL_CIDR_ERR;
+    }
+
+    return CC_OK;
+}
+
+/***************** API's *******************/
+
+/* The function reads the OEM flags OTP word (see Table 41: OEM-Programmed Flags (word 0x21 in OTP memory))
+   and returns whether the RMA status is pending or not. */
+
+int mbedtls_mng_pending_rma_status_get(uint32_t *isPendingRMA)
+{
+    int       rc        = CC_OK;
+    uint32_t  regVal    = CC_MNG_INVALID_REG_VAL;
+    uint32_t  lcsVal    = 0;
+    uint32_t  isHbkFull = 0;
+    CCError_t error     = CC_OK;
+
+    if (isPendingRMA == NULL) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+    *isPendingRMA = CC_FALSE;
+
+    /* Read LCS Register */
+    rc = mbedtls_mng_lcsGet(&lcsVal);
+    if (CC_OK != rc) {
+        return rc;
+    }
+
+    /* Check LCS value */
+    if ((CC_MNG_LCS_DM != lcsVal) && (CC_MNG_LCS_SEC_ENABLED != lcsVal)) {
+        return CC_MNG_ILLEGAL_OPERATION_ERR;
+    }
+
+    /* Read OTP Word #21 */
+    rc = mbedtls_mng_otpWordRead(CC_OTP_OEM_FLAG_OFFSET, &regVal);
+    if (CC_OK != rc) {
+        return rc;
+    }
+
+    /* get HBK configuration */
+    CC_IS_HBK_FULL(isHbkFull, error);
+    if (CC_OK != error) {
+        return error;
+    }
+
+    /* if device supports full Hbk, return with error */
+    if (CC_TRUE == isHbkFull) {
+        return CC_MNG_ILLEGAL_OPERATION_ERR;
+    }
+
+    regVal >>= CC_MNG_OEM_RMA_SHFT;
+    regVal &= CC_MNG_OEM_RMA_MSK;
+
+    switch (regVal) {
+    case CC_MNG_NON_RMA:
+        *isPendingRMA = CC_FALSE;
+        break;
+    case CC_MNG_PENDING_RMA:
+        *isPendingRMA = CC_TRUE;
+        break;
+    case CC_MNG_ILLEGAL_STATE:
+        rc = CC_MNG_RMA_ILLEGAL_STATE_ERR;
+        *isPendingRMA = CC_FALSE;
+        break;
+    case CC_MNG_RMA:
+        *isPendingRMA = CC_FALSE;
+        break;
+    default:
+        break;
+    }
+
+    return rc;
+}
+
+int mbedtls_mng_hw_version_get(uint32_t *partNumber, uint32_t *revision)
+{
+    uint32_t pidReg[CC_MNG_PID_SIZE_WORDS] = {0};
+
+    if (partNumber == NULL || revision == NULL) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* verify peripheral ID (PIDR) */
+    if (0 != VerifyReadPidVal(pidReg, CC_MNG_PID_SIZE_WORDS) ) {
+        return CC_MNG_ILLEGAL_PIDR_ERR;
+    }
+
+    /* verify component ID (CIDR) */
+    if (0 != VerifyCidVal() ) {
+        return CC_MNG_ILLEGAL_CIDR_ERR;
+    }
+
+    *partNumber = (pidReg[0] & 0xFF) | ((pidReg[1] & 0x0F) << 8);
+    *revision   = (pidReg[2] >> 4) & 0x0F;
+
+    return CC_OK;
+}
+
+int mbedtls_mng_cc_sec_mode_set(CCBool_t isSecAccessMode, CCBool_t isSecModeLock)
+{
+    uint32_t rc     = CC_OK;
+    uint32_t regVal = 0, tempVal;
+
+    /* verify input parameters */
+    if((CC_TRUE != isSecAccessMode) && (CC_FALSE != isSecAccessMode)) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    if((CC_TRUE != isSecModeLock) && (CC_FALSE != isSecModeLock)) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* Lock mutexes for all hw operation */
+    if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCSymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCAsymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCRndCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCRndCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
+    }
+
+    /* read APB slave accesses control register */
+    regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+
+    /* check if security mode is already locked */
+    if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, ONLY_SEC_ACCESS_ALLOW_LOCK, regVal)) {
+        rc = CC_MNG_APB_SECURE_IS_LOCKED_ERR;
+        goto mbedtls_mng_setCCSecMode_END;
+    }
+
+    /* set security mode */
+    CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_SEC_ACCESS_ALLOW, regVal, isSecAccessMode);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+    if(tempVal != regVal) {
+        rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
+        goto mbedtls_mng_setCCSecMode_END;
+    }
+
+    /* set security lock */
+    CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_SEC_ACCESS_ALLOW_LOCK, regVal, isSecModeLock);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+    if(tempVal != regVal) {
+        rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
+        goto mbedtls_mng_setCCSecMode_END;
+    }
+
+mbedtls_mng_setCCSecMode_END:
+    /* Release mutexes */
+    if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
+    }
+
+    return rc;
+}
+
+int mbedtls_mng_cc_priv_mode_set(CCBool_t isPrivAccessMode, CCBool_t isPrivModeLock)
+{
+    uint32_t rc     = CC_OK;
+    uint32_t regVal = 0, tempVal = 0;
+
+    /* verify input parameters */
+    if((CC_TRUE != isPrivAccessMode) && (CC_FALSE != isPrivAccessMode)) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    if((CC_TRUE != isPrivModeLock) && (CC_FALSE != isPrivModeLock)) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* Lock mutexes for all hw operation */
+    if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCSymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCAsymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCRndCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCRndCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
+    }
+
+    /* read APB slave accesses control register */
+    regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+
+    /* check if privileged mode is already locked */
+    if( CC_REG_FLD_GET(0, AO_APB_FILTERING, ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal) == CC_TRUE) {
+        rc = CC_MNG_APB_PRIVILEGE_IS_LOCKED_ERR;
+        goto mbedtls_mng_setCCPrivMode_END;
+    }
+
+    /* set privileged mode */
+    CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_PRIV_ACCESS_ALLOW, regVal, isPrivAccessMode);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+    if(tempVal != regVal) {
+        rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
+        goto mbedtls_mng_setCCPrivMode_END;
+    }
+
+    /* set privileged lock */
+    CC_REG_FLD_SET(0, AO_APB_FILTERING, ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal, isPrivModeLock);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+    if(tempVal != regVal) {
+        rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
+        goto mbedtls_mng_setCCPrivMode_END;
+    }
+
+mbedtls_mng_setCCPrivMode_END:
+    /* Release mutexes */
+    if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
+    }
+
+    return rc;
+}
+
+int mbedtls_mng_debug_key_set(mbedtls_mng_keytype keyType, uint32_t *pHwKey, size_t keySize)
+{
+    int      rc     = CC_OK;
+    uint32_t lcsVal = 0;
+
+    /* Lock mutex for all hw operation */
+    if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* Read LCS Register */
+    rc = mbedtls_mng_lcsGet(&lcsVal);
+    if (CC_OK != rc) {
+        goto mbedtls_mng_setDebugKey_END;
+    }
+
+    /* Check LCS value */
+    if ((CC_MNG_LCS_DM != lcsVal) && (CC_MNG_LCS_CM != lcsVal)) {
+        rc = CC_MNG_ILLEGAL_OPERATION_ERR;
+        goto mbedtls_mng_setDebugKey_END;
+    }
+
+    rc = setHwKeyToShadowReg(keyType, pHwKey, keySize);
+
+mbedtls_mng_setDebugKey_END:
+    /* Release mutex */
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return rc;
+}
+
+int mbedtls_mng_gen_config_get(uint32_t *pOtpWord)
+{
+    int rc = 0;
+
+    rc = mbedtls_mng_otpWordRead(CC_OTP_ICV_GENERAL_PURPOSE_FLAG_OFFSET, pOtpWord);
+    if (CC_OK != rc) {
+        return rc;
+    }
+
+    return CC_OK;
+}
+
+int mbedtls_mng_oem_key_lock(CCBool_t kcpLock, CCBool_t kceLock)
+{
+    int      rc     = CC_OK;
+    uint32_t lcsVal = 0;
+    uint32_t regVal = 0, tempVal = 0;
+
+    /* Lock mutex for all hw operation */
+    if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire mutex\n");
+    }
+
+    /* Read LCS Register */
+    rc = mbedtls_mng_lcsGet(&lcsVal);
+    if (CC_OK != rc)
+    {
+        goto mbedtls_mng_lockOemKey_END;
+    }
+
+    /* Check LCS value */
+    if ((CC_MNG_LCS_SEC_ENABLED != lcsVal) && (CC_MNG_LCS_RMA != lcsVal))
+    {
+        goto mbedtls_mng_lockOemKey_END;
+    }
+
+    /* Verify input parameters */
+    if((CC_TRUE != kcpLock) && (CC_FALSE != kcpLock)) {
+        rc = CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+        goto mbedtls_mng_lockOemKey_END;
+    }
+
+    if((CC_TRUE != kceLock)  && (CC_FALSE != kceLock)) {
+        rc = CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+        goto mbedtls_mng_lockOemKey_END;
+    }
+
+    /* read AO Lock Bits register */
+    regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
+
+    /* check if Kcp is already locked and the user wants to lock it */
+    if((CC_TRUE == CC_REG_FLD_GET(0, HOST_AO_LOCK_BITS, HOST_KCP_LOCK, regVal)) &&
+       (CC_TRUE == kcpLock)) {
+        rc = CC_MNG_KCP_IS_LOCKED_ERR;
+        goto mbedtls_mng_lockOemKey_END;
+    }
+
+    /* check if Kce is already locked and the user wants to lock it */
+    if((CC_TRUE == CC_REG_FLD_GET(0, HOST_AO_LOCK_BITS, HOST_KCE_LOCK, regVal)) &&
+       (CC_TRUE == kceLock)) {
+        rc = CC_MNG_KCE_IS_LOCKED_ERR;
+        goto mbedtls_mng_lockOemKey_END;
+    }
+
+    /* Set lock only - do not unlock */
+    if (CC_TRUE == kcpLock) {
+        /* set Kcp lock */
+        CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_KCP_LOCK, regVal, kcpLock);
+    }
+
+    /* Set lock only - do not unlock */
+    if (CC_TRUE == kceLock) {
+        /* set Kce lock */
+        CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_KCE_LOCK, regVal, kceLock);
+    }
+
+    /* write APB slave accesses control register */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS), regVal);
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
+    if(tempVal != regVal) {
+        rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
+        goto mbedtls_mng_lockOemKey_END;
+    }
+
+mbedtls_mng_lockOemKey_END:
+    /* Release mutex */
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release mutex\n");
+    }
+
+    return rc;
+}
+
+static int mbedtls_mng_apbc_part_config(mbedtls_mng_apbcconfig *apbcConfig, uint32_t partId, uint32_t partCfg)
+{
+    if (partCfg >= CC_MNG_APBC_TOTAL_PARTS_CONFIG)
+    {
+            return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    switch (partCfg) {
+    case CC_MNG_APBC_NO_CHANGE:
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 0;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 0;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 0;
+    break;
+    case CC_MNG_APBC_ALLOW_0_ALLOWLOCK_0:
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 0;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 0;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
+    break;
+    case CC_MNG_APBC_ALLOW_0_ALLOWLOCK_1:
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 0;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 1;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
+    break;
+    case CC_MNG_APBC_ALLOW_1_ALLOWLOCK_0:
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 1;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 0;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
+    break;
+    case CC_MNG_APBC_ALLOW_1_ALLOWLOCK_1:
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllow = 1;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessAllowLock = 1;
+        apbcConfig->apbcPart[partId].apbcPartBits.accessModify = 1;
+    break;
+    default:
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    return 0;
+}
+
+int mbedtls_mng_apbc_config_set(mbedtls_mng_apbc_parts_config securePartCfg,
+                                mbedtls_mng_apbc_parts_config privPartCfg,
+                                mbedtls_mng_apbc_parts_config instPartCfg)
+{
+    uint32_t rc = CC_OK;
+    uint32_t regVal = 0, tempVal = 0;
+    mbedtls_mng_apbcconfig apbcConfig = {0};
+
+    /* Lock mutex for all hw operation */
+    if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0)
+    {
+        CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
+    }
+
+    /* Check that there is no access */
+    if (0 != CC_APBC_CNTR_GET)
+    {
+        rc = CC_MNG_APBC_ACCESS_IS_ON_ERR;
+        goto mbedtls_mng_setApbcConfig_END;
+    }
+
+    /* Set each part attributes according to the user inputs */
+    rc = mbedtls_mng_apbc_part_config(&apbcConfig, CC_MNG_APBC_SEC_ID, securePartCfg);
+    if (rc != 0)
+    {
+        goto mbedtls_mng_setApbcConfig_END;
+    }
+    rc = mbedtls_mng_apbc_part_config(&apbcConfig, CC_MNG_APBC_PRIV_ID, privPartCfg);
+    if (rc != 0)
+    {
+        goto mbedtls_mng_setApbcConfig_END;
+    }
+    rc = mbedtls_mng_apbc_part_config(&apbcConfig, CC_MNG_APBC_INST_ID, instPartCfg);
+    if (rc != 0)
+    {
+        goto mbedtls_mng_setApbcConfig_END;
+    }
+
+    /* read APB slave accesses control register */
+    regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+
+    // Secure part
+    if(apbcConfig.apbcPart[CC_MNG_APBC_SEC_ID].apbcPartBits.accessModify)
+    {
+            /* check if APBC security mode is already locked */
+            if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, APBC_ONLY_SEC_ACCESS_ALLOW_LOCK, regVal))
+            {
+                rc = CC_MNG_APBC_SECURE_IS_LOCKED_ERR;
+                goto mbedtls_mng_setApbcConfig_END;
+            }
+            else
+            {
+                /* set APBC security mode */
+                CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_SEC_ACCESS_ALLOW, regVal, apbcConfig.apbcPart[CC_MNG_APBC_SEC_ID].apbcPartBits.accessAllow);
+                CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_SEC_ACCESS_ALLOW_LOCK, regVal, apbcConfig.apbcPart[CC_MNG_APBC_SEC_ID].apbcPartBits.accessAllowLock);
+            }
+    }
+
+    // Privileged part
+    if(apbcConfig.apbcPart[CC_MNG_APBC_PRIV_ID].apbcPartBits.accessModify)
+    {
+            /* check if APBC privilege mode is already locked */
+            if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, APBC_ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal))
+            {
+                rc = CC_MNG_APBC_PRIVILEGE_IS_LOCKED_ERR;
+                goto mbedtls_mng_setApbcConfig_END;
+            }
+            else
+            {
+                /* set APBC security mode */
+                CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_PRIV_ACCESS_ALLOW, regVal, apbcConfig.apbcPart[CC_MNG_APBC_PRIV_ID].apbcPartBits.accessAllow);
+                CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_PRIV_ACCESS_ALLOW_LOCK, regVal, apbcConfig.apbcPart[CC_MNG_APBC_PRIV_ID].apbcPartBits.accessAllowLock);
+            }
+    }
+
+    // Instruction part
+    if(apbcConfig.apbcPart[CC_MNG_APBC_INST_ID].apbcPartBits.accessModify)
+    {
+            /* check if APBC Instruction mode is already locked */
+            if(CC_TRUE == CC_REG_FLD_GET(0, AO_APB_FILTERING, APBC_ONLY_INST_ACCESS_ALLOW_LOCK, regVal))
+            {
+                rc = CC_MNG_APBC_INSTRUCTION_IS_LOCKED_ERR;
+                goto mbedtls_mng_setApbcConfig_END;
+            }
+            else
+            {
+                /* set APBC security mode */
+                CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_INST_ACCESS_ALLOW, regVal, apbcConfig.apbcPart[CC_MNG_APBC_INST_ID].apbcPartBits.accessAllow);
+                CC_REG_FLD_SET(0, AO_APB_FILTERING, APBC_ONLY_INST_ACCESS_ALLOW_LOCK, regVal, apbcConfig.apbcPart[CC_MNG_APBC_INST_ID].apbcPartBits.accessAllowLock);
+            }
+    }
+
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING), regVal);
+    tempVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, AO_APB_FILTERING));
+    if(tempVal != regVal) {
+        rc = CC_MNG_AO_APB_WRITE_FAILED_ERR;
+        goto mbedtls_mng_setApbcConfig_END;
+    }
+
+mbedtls_mng_setApbcConfig_END:
+    /* Release mutex */
+    if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0)
+    {
+        CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
+    }
+
+    return rc;
+}
+
+int mbedtls_mng_apbc_access(CCBool_t isApbcAccessUsed)
+{
+    int rc = CC_OK;
+
+    if ((isApbcAccessUsed != CC_TRUE) && (isApbcAccessUsed != CC_FALSE)) {
+        return CC_MNG_APBC_ACCESS_FAILED_ERR;
+    }
+
+    /* Lock mutex for all hw operation */
+    if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0)
+    {
+        CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
+    }
+
+    if ((CC_FALSE == isApbcAccessUsed) && (0 == CC_APBC_CNTR_GET))
+    {
+        rc = CC_MNG_APBC_ACCESS_ALREADY_OFF_ERR;
+        goto mbedtls_mng_apbcAccess_END;
+    }
+
+    if (CC_TRUE == isApbcAccessUsed) {
+        /* increase APBC Access counter */
+        rc = CC_APBC_ACCESS_INC;
+        if (rc != CC_OK) {
+            CC_PalAbort("Fail to increase APBC Access counter\n");
+        }
+        if (1 == CC_APBC_CNTR_GET) {
+            /* increase PM counter at the beginning of first access */
+            rc = CC_IS_WAKE;
+            if (rc != CC_OK) {
+                CC_PalAbort("Fail to increase PM counter\n");
+            }
+        }
+    } else {
+        /* decrease APBC Access counter */
+        rc = CC_APBC_ACCESS_DEC;
+        if (rc != CC_OK) {
+            CC_PalAbort("Fail to decrease APBC Access counter\n");
+        }
+
+        if (0 == CC_APBC_CNTR_GET) {
+            /* decrease PM counter at the end of last access */
+            rc = CC_IS_IDLE;
+            if (rc != CC_OK) {
+                CC_PalAbort("Fail to decrease PM counter\n");
+            }
+        }
+    }
+
+mbedtls_mng_apbcAccess_END:
+    /* Release mutex */
+    if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0)
+    {
+        CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
+    }
+
+    return rc;
+}
+
+int mbedtls_mng_suspend(uint8_t *pBackupBuffer, size_t backupSize)
+{
+    int rc = CC_OK;
+    uint32_t regVal = 0;
+
+    /* check input parameters */
+    if ((pBackupBuffer != NULL) &&
+         ((backupSize <= 0) || (backupSize < CC_MNG_MIN_BACKUP_SIZE_IN_BYTES)) ){
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+    /* lock mutexes for all HW operation */
+    if (CC_PalMutexLock(&CCSymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCSymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCAsymCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCAsymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCRndCryptoMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCRndCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexLock(&CCApbFilteringRegMutex, CC_INFINITE) != 0) {
+        CC_PalAbort("Fail to acquire 'CCApbFilteringRegMutex'\n");
+    }
+
+    /* verify that the FW has no pending tasks */
+    if(CC_STATUS_GET != 0){
+        rc = CC_MNG_PM_SUSPEND_RESUME_FAILED_ERR;
+        goto mbedtls_mng_suspend_END;
+    }
+
+    /* verify HW is idle */
+    regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_CC_IS_IDLE));
+    if(CC_TRUE != CC_REG_FLD_GET(0, HOST_CC_IS_IDLE, HOST_CC_IS_IDLE, regVal)) {
+        rc = CC_MNG_PM_SUSPEND_RESUME_FAILED_ERR;
+        goto mbedtls_mng_suspend_END;
+    }
+
+    /* set HW register to notify about the coming event */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_POWERDOWN), CC_TRUE);
+
+    return CC_OK;
+
+mbedtls_mng_suspend_END:
+    /* release mutexes */
+    if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
+    }
+
+    return rc;
+}
+
+int mbedtls_mng_resume(uint8_t *pBackupBuffer, size_t backupSize)
+{
+    int rc = CC_OK;
+
+    /* check input parameters */
+    if ((pBackupBuffer != NULL) &&
+            ((backupSize <= 0) || (backupSize < CC_MNG_MIN_BACKUP_SIZE_IN_BYTES)) ){
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* set DMA endianess */
+#ifdef BIG__ENDIAN
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+
+    /* release mutexes */
+    if (CC_PalMutexUnlock(&CCApbFilteringRegMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCApbFilteringRegMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCRndCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCRndCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCAsymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCAsymCryptoMutex'\n");
+    }
+
+    if (CC_PalMutexUnlock(&CCSymCryptoMutex) != 0) {
+        CC_PalAbort("Fail to release 'CCSymCryptoMutex'\n");
+    }
+
+    return rc;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng_int.c b/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng_int.c
new file mode 100644
index 0000000..af0e13c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng_int.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "mbedtls_cc_mng.h"
+#include "mbedtls_cc_mng_error.h"
+#include "mbedtls_cc_mng_int.h"
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_otp_defs.h"
+#include "dx_id_registers.h"
+#include "dx_crys_kernel.h"
+#include "driver_defs.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_mutex.h"
+#include "cc_util_pm.h"
+
+/************* Auxiliary API's *************/
+int mbedtls_mng_otpWordRead(uint32_t otpAddress, uint32_t *pOtpWord)
+{
+    uint32_t regVal=0;
+
+    /* check input variables */
+    if (pOtpWord == NULL) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* check otp limits */
+    CC_GET_OTP_LENGTH(regVal);
+    if (otpAddress >= regVal) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* read OTP word */
+    CC_READ_OTP_WORD(otpAddress*sizeof(uint32_t), regVal);
+    *pOtpWord = regVal;
+
+    return CC_OK;
+}
+
+int mbedtls_mng_lcsGet(uint32_t *pLcs)
+{
+    uint32_t regVal = 0;
+
+    /* check input variables */
+    if (pLcs == NULL) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* poll NVM register to assure that the NVM boot is finished (and LCS and the keys are valid) */
+    CC_WAIT_ON_NVM_IDLE_BIT();
+
+    /* read LCS register */
+    regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    /* return the LCS value */
+    *pLcs = regVal;
+
+    return CC_OK;
+}
+
+int mbedtls_mng_swVersionGet(mbedtls_mng_pubKeyType_t keyIndex, uint32_t *swVersion)
+{
+    uint32_t i, regVal = 0, tmpVal = 0;
+    uint32_t versionBitCount = 0;
+    uint32_t cntrWidth=0, cntrOffset=0, cntrSwVersion;
+    CCError_t error = CC_OK;
+    uint32_t lcs = 0, isHbkFull = 0;
+    CCBool_t isNextWordZero = CC_FALSE;
+
+    /* check swVersion pointrer */
+    if (swVersion == NULL) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* clear version in case of error */
+    *swVersion = 0;
+
+    /* get lifecycle */
+    error = mbedtls_mng_lcsGet(&lcs);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    /* in case of RMA, return constant 0 */
+    if (lcs == CC_MNG_LCS_RMA){
+        return CC_OK;
+    }
+
+    /* get HBK configuration */
+    CC_IS_HBK_FULL(isHbkFull, error);
+    if (error != CC_OK)
+        return error;
+
+    /* check HBK configuration (in case of CM, get any counter needed) */
+    switch(keyIndex){
+    case CC_MNG_HASH_BOOT_KEY_256B:
+
+        /* verify correct HBK configuration for DM & SE */
+        if ((lcs != CC_MNG_LCS_CM) && (isHbkFull != CC_TRUE)) {
+            return CC_MNG_ILLEGAL_OPERATION_ERR;
+        }
+
+        cntrWidth = CC_OTP_HBK_MIN_VERSION_SIZE_IN_WORDS;
+        cntrOffset = CC_OTP_HBK_MIN_VERSION_OFFSET;
+        break;
+
+    case CC_MNG_HASH_BOOT_KEY_0_128B:
+
+        /* verify correct HBK configuration for DM & SE */
+        if ((lcs != CC_MNG_LCS_CM) && (isHbkFull == CC_TRUE)) {
+            return CC_MNG_ILLEGAL_OPERATION_ERR;
+        }
+
+        cntrWidth = CC_OTP_HBK0_MIN_VERSION_SIZE_IN_WORDS;
+        cntrOffset = CC_OTP_HBK0_MIN_VERSION_OFFSET;
+        break;
+
+    case CC_MNG_HASH_BOOT_KEY_1_128B:
+
+        /* verify correct HBK configuration for DM & SE */
+        if ((lcs != CC_MNG_LCS_CM) && (isHbkFull == CC_TRUE)) {
+            return CC_MNG_ILLEGAL_OPERATION_ERR;
+        }
+
+        cntrWidth = CC_OTP_HBK1_MIN_VERSION_SIZE_IN_WORDS;
+        cntrOffset = CC_OTP_HBK1_MIN_VERSION_OFFSET;
+        break;
+    default:
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* read the SW version from the OTP, and accumulate number of ones */
+    cntrSwVersion = 0;
+    for(i=0; i < cntrWidth; i++) {
+        error = mbedtls_mng_otpWordRead(cntrOffset+i, &regVal);
+        if (error != CC_OK)
+            return error;
+
+        CC_MNG_COUNT_ONE_BITS(regVal, versionBitCount);
+
+        /* verify legality of 1's bits */
+        if((isNextWordZero == CC_TRUE) && (regVal!=0)){
+            return CC_MNG_ILLEGAL_SW_VERSION_ERR;
+        }
+        if(versionBitCount < CC_MNG_ALL_ONES_NUM_BITS){
+            isNextWordZero = CC_TRUE;
+            }
+
+        /* convert versionBitCount to base-1 representation and compare to OTP word */
+        if(versionBitCount != 0){
+            tmpVal = CC_MNG_ALL_ONES_VALUE >> (CC_MNG_ALL_ONES_NUM_BITS - versionBitCount);
+        } else{
+            tmpVal = 0;
+        }
+        if (tmpVal != regVal) {
+            /* return error in case of invalid base-1 value */
+            return CC_MNG_ILLEGAL_SW_VERSION_ERR;
+        }
+
+        cntrSwVersion += versionBitCount;
+    }
+
+    *swVersion = cntrSwVersion;
+
+    return CC_OK;
+}
+
+int mbedtls_mng_pubKeyHashGet(mbedtls_mng_pubKeyType_t keyIndex, uint32_t *hashedPubKey, uint32_t hashResultSizeWords)
+{
+    uint32_t i, address;
+    uint32_t regVal = 0, cntZero = 0, zerosHash = 0;
+    uint32_t oemFlag = 0, icvFlag = 0;
+    CCError_t  error = CC_OK;
+    uint32_t lcs = 0, isHbkFull = 0;
+
+    /* check hash buffer pointer */
+    if (hashedPubKey == NULL) {
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* get lifecycle */
+    error = mbedtls_mng_lcsGet(&lcs);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    /* in case of CM, return error */
+    if (lcs == CC_MNG_LCS_CM) {
+        return CC_MNG_HASH_NOT_PROGRAMMED_ERR;
+    }
+
+    /* get HBK configuration */
+    CC_IS_HBK_FULL(isHbkFull, error);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    /* read icv flags word */
+    error = mbedtls_mng_otpWordRead(CC_OTP_MANUFACTURE_FLAG_OFFSET, &icvFlag);
+    if (error != CC_OK) {
+        return error;
+    }
+
+    /* read OEM programmer flags word */
+    error = mbedtls_mng_otpWordRead(CC_OTP_OEM_FLAG_OFFSET, &oemFlag);
+    if (error != CC_OK)
+        return error;
+
+    /* verify validity of key index, key size and mode of operation */
+    switch (keyIndex) {
+    case CC_MNG_HASH_BOOT_KEY_256B:
+        /* key size should hold 256b */
+        if (hashResultSizeWords != CC_MNG_256B_HASH_SIZE_IN_WORDS)
+            return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+        /* otp shuld support full HBK */
+        if (isHbkFull != CC_TRUE) {
+            return CC_MNG_ILLEGAL_OPERATION_ERR;
+        }
+        /* Hbk0 zero count should be cleared */
+        if (CC_REG_FLD_GET2(0, OTP_MANUFACTURE_FLAG, HBK0_ZERO_BITS, icvFlag) != 0) {
+            return CC_MNG_ILLEGAL_OPERATION_ERR;
+        }
+
+        /* DM lcs is illegal for Hbk */
+        if (lcs == CC_MNG_LCS_DM) {
+            return CC_MNG_HASH_NOT_PROGRAMMED_ERR;
+        }
+
+        zerosHash = CC_REG_FLD_GET2(0, OTP_OEM_FLAG, HBK_ZERO_BITS, oemFlag);
+        address = CC_OTP_HBK_OFFSET;
+        break;
+
+    case CC_MNG_HASH_BOOT_KEY_0_128B:
+        /* key size should hold 128b */
+        if (hashResultSizeWords != CC_MNG_128B_HASH_SIZE_IN_WORDS)
+            return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+        /* otp shuld support 2 HBK's */
+        if (isHbkFull == CC_TRUE) {
+            return CC_MNG_ILLEGAL_OPERATION_ERR;
+        }
+
+        zerosHash = CC_REG_FLD_GET2(0, OTP_MANUFACTURE_FLAG, HBK0_ZERO_BITS, icvFlag);
+        address = CC_OTP_HBK0_OFFSET;
+        break;
+
+    case CC_MNG_HASH_BOOT_KEY_1_128B:
+        /* key size should hold 128b */
+        if (hashResultSizeWords != CC_MNG_128B_HASH_SIZE_IN_WORDS)
+            return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+        /* otp shuld support 2 HBK's */
+        if (isHbkFull == CC_TRUE) {
+            return CC_MNG_ILLEGAL_OPERATION_ERR;
+        }
+        /* DM lcs is illegal for Hbk1 */
+        if (lcs == CC_MNG_LCS_DM)
+            return CC_MNG_HASH_NOT_PROGRAMMED_ERR;
+
+        zerosHash = CC_REG_FLD_GET2(0, OTP_OEM_FLAG, HBK1_ZERO_BITS, oemFlag);
+        address = CC_OTP_HBK1_OFFSET;
+        break;
+
+    default:
+        return CC_MNG_ILLEGAL_INPUT_PARAM_ERR;
+    }
+
+    /* read hash key from OTP */
+    for (i = 0; i < hashResultSizeWords; i++) {
+        error = mbedtls_mng_otpWordRead(address + i, &regVal);
+        if (error != CC_OK) {
+            goto _Err_GetPubKey;
+        }
+        *(hashedPubKey + i) = regVal;
+
+        /* accumulate number of zeroes */
+        CC_MNG_COUNT_ZEROES(regVal, cntZero);
+    }
+
+    /* verify number of "0" bits in the hash key */
+    if (zerosHash == cntZero) {
+        return CC_OK;
+    } else {
+        error = CC_MNG_HBK_ZERO_COUNT_ERR;
+    }
+
+    /* case of error, clean hash buffer */
+_Err_GetPubKey:
+    for (i = 0; i < hashResultSizeWords; i++) {
+        *(hashedPubKey + i) = 0;
+    }
+
+    return error;
+}
+
+
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng_int.h b/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng_int.h
new file mode 100644
index 0000000..ae42b18
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc_mng/mbedtls_cc_mng_int.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _MBEDTLS_CC_MNG_INT_H
+#define _MBEDTLS_CC_MNG_INT_H
+
+/************************ Includes ******************************/
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "dx_nvm.h"
+#include "cc_pal_types_plat.h"
+
+/************************ Enums ******************************/
+/*! HASH boot key definition. */
+typedef enum {
+    CC_MNG_HASH_BOOT_KEY_0_128B         = 0,        /*!< 128-bit truncated SHA256 digest of public key 0. */
+    CC_MNG_HASH_BOOT_KEY_1_128B     = 1,        /*!< 128-bit truncated SHA256 digest of public key 1. */
+    CC_MNG_HASH_BOOT_KEY_256B       = 2,        /*!< 256-bit SHA256 digest of public key. */
+    CC_MNG_HASH_BOOT_NOT_USED       = 0xF,
+    CC_MNG_HASH_MAX_NUM                 = 0x7FFFFFFF,   /*!\internal use external 128-bit truncated SHA256 digest */
+}mbedtls_mng_pubKeyType_t;
+
+/************************ Defines ******************************/
+#define CC_MNG_INVALID_REG_VAL          0xFFFFFFFF
+
+#define CC_MNG_OEM_RMA_SHFT         30
+#define CC_MNG_OEM_RMA_MSK          3
+
+#define CC_MNG_HOST_KPICV_LOCK_BIT_SHFT     1
+#define CC_MNG_HOST_KCEICV_LOCK_BIT_SHFT    2
+#define CC_MNG_HOST_KCP_LOCK_BIT_SHFT       3
+#define CC_MNG_HOST_KCE_LOCK_BIT_SHFT       4
+
+/* Peripheral ID registers values */
+#define CC_MNG_PID_0_VAL        0x000000C0UL
+#define CC_MNG_PID_1_VAL        0x000000B0UL
+#define CC_MNG_PID_2_VAL        0x0000000BUL
+#define CC_MNG_PID_3_VAL        0x00000000UL
+#define CC_MNG_PID_4_VAL        0x00000004UL
+#define CC_MNG_PID_SIZE_WORDS       5
+
+#define CC_MNG_PID_2_1_VAL      0x0000002BUL
+
+/* Component ID registers values */
+#define CC_MNG_CID_0_VAL        0x0DUL
+#define CC_MNG_CID_1_VAL        0xF0UL
+#define CC_MNG_CID_2_VAL        0x05UL
+#define CC_MNG_CID_3_VAL        0xB1UL
+#define CC_MNG_CID_SIZE_WORDS       4
+
+/*! Definition for all ones word. */
+#define CC_MNG_ALL_ONES_VALUE   0xffffffffUL
+/*! Definition for number of bits in a 32bit word. */
+#define CC_MNG_ALL_ONES_NUM_BITS 32
+
+/*! Defines the maximal hash boot key size in words. */
+#define CC_MNG_MAX_HASH_SIZE_IN_WORDS       8
+/*! Defines the maximal hash boot key size in bytes. */
+#define CC_MNG_MAX_HASH_SIZE_IN_BYTES       (CC_MNG_MAX_HASH_SIZE_IN_WORDS*sizeof(uint32_t))
+/*! Defines the maximal full-hash boot key size in words. */
+#define CC_MNG_256B_HASH_SIZE_IN_WORDS      CC_MNG_MAX_HASH_SIZE_IN_WORDS
+/*! Defines the maximal dual-hash boot key size in words. */
+#define CC_MNG_128B_HASH_SIZE_IN_WORDS      CC_MNG_MAX_HASH_SIZE_IN_WORDS/2
+
+/************************ Macros ******************************/
+/* calc OTP memory length:
+   read RTL OTP address width. The supported sizes are 6 (for 2 Kbits),7,8,9,10,11 (for 64 Kbits).
+   convert value parameter to addresses of 32b words */
+#define CC_GET_OTP_LENGTH(otpLength)                            \
+    do {                                                \
+        otpLength = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, OTP_ADDR_WIDTH_DEF));  \
+        otpLength = CC_REG_FLD_GET(0, OTP_ADDR_WIDTH_DEF, VALUE, otpLength);            \
+        otpLength = (1 << otpLength);                               \
+    }while(0)
+
+/* read a word directly from OTP memory */
+#define CC_READ_OTP_WORD(otpAddr, otpData)                          \
+    do {                                                                                \
+        otpData = CC_HAL_READ_REGISTER(CC_OTP_BASE_ADDR + otpAddr);     \
+    }while(0)
+
+/*! Poll NVM register to assure that the NVM boot is finished (and LCS and the keys are valid). */
+#define CC_WAIT_ON_NVM_IDLE_BIT()                                        \
+    do {                                             \
+        uint32_t regVal;                                 \
+        do {                                         \
+            regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, NVM_IS_IDLE));     \
+            regVal = CC_REG_FLD_GET(0, NVM_IS_IDLE, VALUE, regVal);          \
+        }while( !regVal );                               \
+    }while(0)
+
+/*! Check Hbk configuration in OTP memory. */
+#define CC_IS_HBK_FULL(isHbkFull, error)                               \
+    do {                                               \
+        error = mbedtls_mng_otpWordRead(CC_OTP_MANUFACTURE_FLAG_OFFSET, &isHbkFull);       \
+        isHbkFull = CC_REG_FLD_GET2(0, OTP_MANUFACTURE_FLAG, HBK0_NOT_IN_USE, isHbkFull);  \
+    }while(0)
+
+/*! Poll on the crypto busy till it is = 0. */
+#define CC_WAIT_ON_CRYPTO_BUSY()                                \
+    do {                                            \
+        uint32_t regVal=1;                              \
+        do {                                        \
+            regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, CRYPTO_BUSY));    \
+                }while( regVal );                               \
+        }while(0)
+
+/* MACRO to count one bits */
+#define CC_MNG_COUNT_ONE_BITS(number, BitCount) \
+    do \
+    { \
+          uint32_t tmp_num = number; \
+          BitCount = 0; \
+          while (tmp_num)   \
+          {         \
+        tmp_num = tmp_num & (tmp_num - 1); \
+        BitCount = BitCount + 1; \
+          }         \
+    } while (0)
+
+/*! This macro counts the number of zeroes in a 32bits word. */
+#define CC_MNG_COUNT_ZEROES(regVal, regZero)                    \
+    do {                                    \
+        uint32_t val = regVal;                                          \
+        val = val - ((val >> 1) & 0x55555555);                          \
+        val = (val & 0x33333333) + ((val >> 2) & 0x33333333);           \
+        val = ((((val + (val >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24);   \
+        regZero += (32 - val);                      \
+    }while(0)
+
+
+/************************ API's ******************************/
+/*!
+@brief This function reads an OTP word from from 'otpAddress' to 'pOtpWord'.
+
+@return CC_OK on success.
+@return A non-zero value from cc_manage.h on failure.
+ */
+int mbedtls_mng_otpWordRead(uint32_t otpAddress,            /*!< [in]       OTP Address: An Offset in Words in the OTP address space. */
+                uint32_t *pOtpWord);            /*!< [in/out]   OTP Word pointer: An address to store the read Word. */
+
+/*!
+@brief This function returns the LCS value'.
+
+@return CC_OK on success.
+@return A non-zero value from cc_manage.h on failure.
+ */
+int mbedtls_mng_lcsGet(uint32_t *pLcs);                 /*!< [in/out]   LCS Value: An address to store the LCS Value. */
+
+/*!
+@brief This function reads software revocation counter from OTP memory, according to the provided key index.
+
+@return CC_OK on success.
+@return A non-zero value from cc_manage.h on failure.
+*/
+int mbedtls_mng_swVersionGet(
+                mbedtls_mng_pubKeyType_t keyIndex,      /*!< [in] Enumeration defining the key hash to retrieve: 128-bit HBK0, 128-bit HBK1, or 256-bit HBK. */
+    uint32_t *swVersion                                 /*!< [out] The value of the requested counter as read from OTP memory. */
+    );
+
+/*!
+@brief This function retrieves the public key hash from OTP memory, according to the provided index.
+
+@return CC_OK on success.
+@return A non-zero value from cc_manage.h on failure.
+*/
+int mbedtls_mng_pubKeyHashGet(
+                mbedtls_mng_pubKeyType_t keyIndex,      /*!< [in] Enumeration defining the key hash to retrieve: 128-bit HBK0, 128-bit HBK1, or 256-bit HBK. */
+                uint32_t *hashedPubKey,                 /*!< [out] A buffer to contain the public key HASH. */
+                uint32_t hashResultSizeWords            /*!< [in] The size of the hash in 32-bit words:
+                                                        - Must be 4 for 128-bit hash.
+                                                        - Must be 8 for 256bit hash. */
+    );
+
+#endif // _MBEDTLS_CC_MNG_INT_H
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/hal/cc3x/cc_hal.c b/lib/ext/cryptocell-312-runtime/host/src/hal/cc3x/cc_hal.c
new file mode 100644
index 0000000..7332014
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/hal/cc3x/cc_hal.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define CC_PAL_LOG_CUR_COMPONENT CC_LOG_MASK_CCLIB
+
+#include "cc_regs.h"
+#include "cc_pal_memmap.h"
+#include "cc_hal.h"
+#include "dx_crys_kernel.h"
+#include "cc_pal_abort.h"
+#include "cc_error.h"
+#include "cc_regs.h"
+
+#include "cc_pal_interrupt_ctrl_plat.h"
+#include "dx_rng.h"
+
+/******************************************************************************
+*               DEFINITIONS
+******************************************************************************/
+#define DX_CC_REG_AREA_LEN 0x100000
+
+/******************************************************************************
+*               GLOBALS
+******************************************************************************/
+
+unsigned long gCcRegBase = 0;
+
+/******************************************************************************
+*               FUNCTIONS
+******************************************************************************/
+
+/*!
+ * HAL layer entry point.
+ * Mappes ARM CryptoCell regisers to the HOST virtual address space.
+ */
+int CC_HalInit(void)
+{
+    unsigned long *pVirtBuffAddr = NULL;
+
+    CC_PalMemMap(DX_BASE_CC, DX_CC_REG_AREA_LEN, (uint32_t**)&pVirtBuffAddr);
+    gCcRegBase = (unsigned long)pVirtBuffAddr;
+    return 0;
+}
+
+
+/*!
+ * HAL exit point.
+ * Unmaps ARM CryptoCell registers.
+ */
+int CC_HalTerminate(void)
+{
+    CC_PalMemUnMap((uint32_t *)gCcRegBase,DX_CC_REG_AREA_LEN);
+    gCcRegBase = 0;
+    return CC_HAL_OK;
+}
+
+
+void CC_HalClearInterruptBit(uint32_t data)
+{
+
+    CC_HAL_WRITE_REGISTER( CC_REG_OFFSET(HOST_RGF, HOST_ICR), data);
+
+    return;
+}
+
+void CC_HalMaskInterrupt(uint32_t data)
+{
+    CC_HAL_WRITE_REGISTER( CC_REG_OFFSET(HOST_RGF, HOST_IMR), data);
+
+    return;
+}
+
+/*!
+ * Wait upon Interrupt Request Register (IRR) signals.
+ * This function notifies for any ARM CryptoCell interrupt, it is the caller responsibility
+ * to verify and prompt the expected case interrupt source.
+ *
+ * @param[in] data  - input data for future use
+ * \return CCError_t    - CC_OK upon success
+ */
+CCError_t CC_HalWaitInterrupt(uint32_t data)
+{
+    CCError_t error = CC_OK;
+    if (0 == data) {
+        return CC_FATAL_ERROR;
+    }
+    error = CC_PalWaitInterrupt( data );
+
+    return error;
+}
+
+
+
+CCError_t CC_HalWaitInterruptRND(uint32_t data)
+{
+    uint32_t irr = 0;
+    CCError_t error = CC_OK;
+    if (0 == data) {
+        return CC_FATAL_ERROR;
+    }
+
+    /* busy wait upon IRR signal */
+    do {
+        irr = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRR));
+        /* check APB bus error from HOST */
+        if( CC_REG_FLD_GET(0, HOST_IRR, AHB_ERR_INT, irr) == CC_TRUE){
+            error = CC_FATAL_ERROR;
+            /*set data for clearing bus error*/
+            CC_REG_FLD_SET(HOST_RGF, HOST_ICR, AXI_ERR_CLEAR, data , 1);
+            break;
+        }
+    } while (!(irr & data));
+
+    /* clear interrupt */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), data); // IRR and ICR bit map is the same use data to clear interrupt in ICR
+
+    return error;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/hal/cc_hal_plat.h b/lib/ext/cryptocell-312-runtime/host/src/hal/cc_hal_plat.h
new file mode 100644
index 0000000..21dd81f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/hal/cc_hal_plat.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __CC_HAL_PLAT_H__
+#define __CC_HAL_PLAT_H__
+
+#include "dx_host.h"
+#include "cc_bitops.h"
+
+#include "dx_reg_common.h" /*temporary (missing HW defines)*/
+
+
+/******************************************************************************
+*               DEFINITIONS
+******************************************************************************/
+#define CC_LARGE_SECRET_KEY_NUM_OF_BYTES 32
+#define CC_SMALL_SECRET_KEY_NUM_OF_BYTES 16
+
+/* Peripheral ID registers values */
+#define CC_BSV_PID_0_VAL        0x000000C0UL
+#define CC_BSV_PID_1_VAL        0x000000B0UL
+#define CC_BSV_PID_2_VAL        0x0000000BUL
+#define CC_BSV_PID_3_VAL        0x00000000UL
+#define CC_BSV_PID_4_VAL        0x00000004UL
+#define CC_BSV_PID_SIZE_WORDS       5
+
+#define CC_BSV_PID_2_1_VAL      0x0000002BUL
+
+
+/* Component ID registers values */
+#define CC_BSV_CID_0_VAL        0x0DUL
+#define CC_BSV_CID_1_VAL        0xF0UL
+#define CC_BSV_CID_2_VAL        0x05UL
+#define CC_BSV_CID_3_VAL        0xB1UL
+#define CC_BSV_CID_SIZE_WORDS       4
+
+
+/******************************************************************************
+*                               MACROS
+******************************************************************************/
+extern unsigned long gCcRegBase;
+
+/******************************************************************************
+*                               MACROS
+******************************************************************************/
+/*get the size of the RKEK from HW */
+//(key_size >> DX_NVM_CC_BOOT_LARGE_RKEK_LOCAL_BIT_SHIFT) & DX_NVM_CC_BOOT_LARGE_RKEK_LOCAL_BIT_SIZE
+#define GET_ROOT_KEY_SIZE(key_size) \
+do{ \
+    key_size = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, NVM_CC_BOOT));\
+        if (CC_REG_FLD_GET(CRY_KERNEL, NVM_CC_BOOT, LARGE_RKEK_LOCAL, key_size)) \
+                key_size = CC_LARGE_SECRET_KEY_NUM_OF_BYTES; \
+        else \
+                key_size = CC_SMALL_SECRET_KEY_NUM_OF_BYTES; \
+}while (0)
+
+
+/*!
+ * Read CryptoCell memory-mapped-IO register.
+ *
+ * \param regOffset The offset of the ARM CryptoCell register to read
+ * \return uint32_t Return the value of the given register
+ */
+#define CC_HAL_READ_REGISTER(regOffset)                 \
+        (*((volatile uint32_t *)(gCcRegBase + (regOffset))))
+
+/*!
+ * Write CryptoCell memory-mapped-IO register.
+ * \note This macro must be modified to make the operation synchronous, i.e. the write operation must complete,
+ *       and the new value must be written to the register before the macro returns. The mechanisms required to
+ *       achieve this are architecture-dependent (e.g., the memory barrier in ARM architecture).
+ *
+ * \param regOffset The offset of the ARM CryptoCell register to write
+ * \param val The value to write
+ */
+#define CC_HAL_WRITE_REGISTER(regOffset, val)       \
+        (*((volatile uint32_t *)(gCcRegBase + (regOffset))) = (val))
+
+
+
+#endif /*__CC_HAL_PLAT_H__*/
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/Makefile b/lib/ext/cryptocell-312-runtime/host/src/pal/Makefile
new file mode 100644
index 0000000..d77d86a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/Makefile
@@ -0,0 +1,21 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+SUB_DIRS = $(TEE_OS)
+
+all: $(foreach sub_dir,$(SUB_DIRS),do_$(sub_dir))
+
+clean: $(foreach sub_dir,$(SUB_DIRS),clean_$(sub_dir))
+
+clean_%:
+	@make -C $* clean
+
+do_%:
+	@make -C $*
+
+.PHONY: all clean clean_% do_%
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/cc_pal_trng.c b/lib/ext/cryptocell-312-runtime/host/src/pal/cc_pal_trng.c
new file mode 100644
index 0000000..4af73d7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/cc_pal_trng.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_trng.h"
+#include "cc_pal_log.h"
+
+#if (CC_CONFIG_TRNG_MODE==0)
+#define CC_CONFIG_SAMPLE_CNT_ROSC_1     5000
+#define CC_CONFIG_SAMPLE_CNT_ROSC_2     1000
+#define CC_CONFIG_SAMPLE_CNT_ROSC_3     500
+#define CC_CONFIG_SAMPLE_CNT_ROSC_4     0
+#elif (CC_CONFIG_TRNG_MODE==1)
+/* amount of bytes for the required entropy bits = ROUND_UP(ROUND_UP(((required entropy bits)/(entropy per bit)), 1024), (EHR width in bytes)) / 8
+   (multiple of the window size 1024 bits and multiple of the EHR width 192 bits) */
+#define CC_CONFIG_TRNG90B_AMOUNT_OF_BYTES                      144  /* ROUND_UP(ROUND_UP((384/0.5), 1024), 192) / 8 = 144 */
+
+/*** NIST SP 800-90B (2nd Draft) 4.4.1 ***/
+/* C = ROUND_UP(1+(-log(W)/H)), W = 2^(-40), H=(entropy per bit) */
+#define CC_CONFIG_TRNG90B_REPETITION_COUNTER_CUTOFF            81  /* ROUND_UP(1+(40/0.5)) = 81 */
+
+/*** NIST SP 800-90B (2nd Draft) 4.4.2 ***/
+/* C =CRITBINOM(W, power(2,(-H)),1-a), W = 1024, a = 2^(-40), H=(entropy per bit) */
+#define CC_CONFIG_TRNG90B_ADAPTIVE_PROPORTION_CUTOFF           823      /* =CRITBINOM(1024, power(2,(-0.5)),1-2^(-40)) */
+
+/* sample count for each ring oscillator */
+/* for unallowed rosc, sample count = 0 */
+#define CC_CONFIG_SAMPLE_CNT_ROSC_1     1000
+#define CC_CONFIG_SAMPLE_CNT_ROSC_2     1000
+#define CC_CONFIG_SAMPLE_CNT_ROSC_3     500
+#define CC_CONFIG_SAMPLE_CNT_ROSC_4     0
+#else
+#error "CC_CONFIG_TRNG_MODE not defined or not supported"
+#endif
+
+
+/**
+ * @brief This function return the TRNG user parameters.
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalTrngParamGet(CC_PalTrngParams_t *pTrngParams, /*!< [out] A pointer to the TRNG user parameters. */
+                             size_t *pParamsSize)     /*!< [in/out] A poiinter to size of the TRNG user parameters structure used.
+                                                           As input: the function needs to verify its size is the same as CC_PalTrngParams_t.
+                                                           As output: return the size of CC_PalTrngParams_t for Library size verification */
+{
+    CCError_t  error = CC_OK;
+
+    if ((pTrngParams == NULL) ||
+             (pParamsSize == NULL) ||
+             (*pParamsSize != sizeof(CC_PalTrngParams_t))){
+            return CC_FAIL;
+    }
+
+    *pParamsSize = sizeof(CC_PalTrngParams_t);
+
+    pTrngParams->SubSamplingRatio1 = CC_CONFIG_SAMPLE_CNT_ROSC_1;
+    pTrngParams->SubSamplingRatio2 = CC_CONFIG_SAMPLE_CNT_ROSC_2;
+    pTrngParams->SubSamplingRatio3 = CC_CONFIG_SAMPLE_CNT_ROSC_3;
+    pTrngParams->SubSamplingRatio4 = CC_CONFIG_SAMPLE_CNT_ROSC_4;
+
+#if (CC_CONFIG_TRNG_MODE==1)
+    pTrngParams->trngModeParams.numOfBytes = CC_CONFIG_TRNG90B_AMOUNT_OF_BYTES;
+    pTrngParams->trngModeParams.repetitionCounterCutoff = CC_CONFIG_TRNG90B_REPETITION_COUNTER_CUTOFF;
+    pTrngParams->trngModeParams.adaptiveProportionCutOff = CC_CONFIG_TRNG90B_ADAPTIVE_PROPORTION_CUTOFF;
+
+#endif
+    return error;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/Makefile b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/Makefile
new file mode 100644
index 0000000..6c14d47
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/Makefile
@@ -0,0 +1,19 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for PAL for freertos
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../../..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+TARGET_LIBS = pal_freertos
+PLAT_OS = freertos
+
+include ../project_pal.mk
+include  $(HOST_PROJ_ROOT)/Makefile.freertos
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal.c
new file mode 100644
index 0000000..a149b82
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifdef CC_IOT
+
+/************* Include Files ****************/
+#include "cc_pal_init.h"
+#include "cc_pal_dma_plat.h"
+#include "cc_pal_log.h"
+#include "dx_reg_base_host.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_pm.h"
+#include "cc_pal_interrupt_ctrl_plat.h"
+
+extern CC_PalMutex CCSymCryptoMutex;
+extern CC_PalMutex CCAsymCryptoMutex;
+extern CC_PalMutex CCRndCryptoMutex;
+extern CC_PalMutex *pCCRndCryptoMutex;
+extern CC_PalMutex CCApbFilteringRegMutex;
+
+#define PAL_WORKSPACE_MEM_BASE_ADDR     0
+#define PAL_WORKSPACE_MEM_SIZE          0
+
+
+/**
+ * @brief   PAL layer entry point.
+ *          The function initializes customer platform sub components,
+ *           such as memory mapping used later by CRYS to get physical contiguous memory.
+ *
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+int CC_PalInit(void)
+{
+
+    CCError_t rc = CC_FAIL;
+
+    /* Currently in FreeRtos palDma is not needed - and therefore is implemented as empty. */
+    rc = CC_PalDmaInit(PAL_WORKSPACE_MEM_SIZE, PAL_WORKSPACE_MEM_BASE_ADDR);
+    if (rc != CC_SUCCESS)
+        {
+            return 1;
+        }
+
+    /* Initialize power management module */
+    CC_PalPowerSaveModeInit();
+
+    /* Initialize mutex that protects shared memory and crypto access */
+    rc = CC_PalMutexCreate(&CCSymCryptoMutex);
+    if (rc != CC_SUCCESS)
+        {
+            CC_PalAbort("Fail to create SYM mutex\n");
+        }
+    /* Initialize mutex that protects shared memory and crypto access */
+    rc = CC_PalMutexCreate(&CCAsymCryptoMutex);
+    if (rc != CC_SUCCESS)
+        {
+            CC_PalAbort("Fail to create ASYM mutex\n");
+        }
+    /* Initialize mutex that protects shared memory and crypto access */
+    rc = CC_PalMutexCreate(&CCRndCryptoMutex);
+    if (rc != CC_SUCCESS) {
+            CC_PalAbort("Fail to create RND mutex\n");
+    }
+    pCCRndCryptoMutex = &CCRndCryptoMutex;
+
+    /* Initialize mutex that protects APBC access */
+    rc = CC_PalMutexCreate(&CCApbFilteringRegMutex);
+    if (rc != 0) {
+            CC_PalAbort("Fail to create APBC mutex\n");
+    }
+
+    CC_PalInitIrq();
+
+    return 0;
+}
+
+
+/**
+ * @brief   PAL layer entry point.
+ *          The function initializes customer platform sub components,
+ *           such as memory mapping used later by CRYS to get physical contiguous memory.
+ *
+ *
+ * @return None
+ */
+void CC_PalTerminate(void)
+{
+    CCError_t err = CC_FAIL;
+
+    CC_PalDmaTerminate();
+    CC_PalFinishIrq();
+
+    err = CC_PalMutexDestroy(&CCSymCryptoMutex);
+    if (err != CC_SUCCESS)
+        {
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCSymCryptoMutex\n");
+        }
+
+    CC_PalMemSetZero(&CCSymCryptoMutex, sizeof(CC_PalMutex));
+
+    err = CC_PalMutexDestroy(&CCAsymCryptoMutex);
+    if (err != CC_SUCCESS)
+        {
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCAsymCryptoMutex\n");
+        }
+
+    CC_PalMemSetZero(&CCAsymCryptoMutex, sizeof(CC_PalMutex));
+
+    err = CC_PalMutexDestroy(&CCRndCryptoMutex);
+    if (err != CC_SUCCESS)
+        {
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCRndCryptoMutex\n");
+        }
+    CC_PalMemSetZero(&CCRndCryptoMutex, sizeof(CC_PalMutex));
+
+
+    err = CC_PalMutexDestroy(&CCApbFilteringRegMutex);
+    if (err != 0){
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCApbFilteringRegMutex\n");
+    }
+    CC_PalMemSetZero(&CCApbFilteringRegMutex, sizeof(CC_PalMutex));
+}
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_abort_plat.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_abort_plat.c
new file mode 100644
index 0000000..78dc4d5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_abort_plat.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_log.h"
+#include "stdlib.h"
+
+
+void CC_PalAbort(const char *exp)
+{
+    CC_PAL_LOG_ERR("ASSERT:%s:%d: %s", __FILE__, __LINE__, exp);
+    CC_UNUSED_PARAM(exp); /* to avoid compilation error in case DEBUG isn't defined*/
+    abort();
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_apbc.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_apbc.c
new file mode 100644
index 0000000..714c500
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_apbc.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "FreeRTOS.h"
+#include "task.h"
+
+int32_t g_apbcCntr;
+
+void CC_PalApbcCntrInit(void)
+{
+    g_apbcCntr = 0;
+    return;
+}
+
+int32_t CC_PalApbcCntrValue(void)
+{
+    return g_apbcCntr;
+}
+
+CCError_t CC_PalApbcModeSelect(CCBool isApbcInc)
+{
+    CCError_t rc = CC_OK;
+
+    switch (isApbcInc){
+    case CC_FALSE:
+        taskENTER_CRITICAL();
+        g_apbcCntr--;
+        taskEXIT_CRITICAL();
+        break;
+    case CC_TRUE:
+        taskENTER_CRITICAL();
+        g_apbcCntr++;
+        taskEXIT_CRITICAL();
+        break;
+    default:
+        return CC_FAIL;
+    }
+
+    if(g_apbcCntr < 0 ){
+        /* illegal state - exit with error */
+        return 1;
+    }
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_barrier.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_barrier.c
new file mode 100644
index 0000000..af03eb2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_barrier.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+void CC_PalWmb(void)
+{
+    return;
+}
+
+void CC_PalRmb(void)
+{
+    return;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_buff_attr.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_buff_attr.c
new file mode 100644
index 0000000..f84857e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_buff_attr.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_buff_attr.h"
+#include "cc_hal_plat.h"
+#include "dx_id_registers.h"
+#include "dx_crys_kernel.h"
+#include "cc_regs.h"
+#ifdef ARCH_V8M
+#include <arm_cmse.h>
+#endif
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+#ifdef ARCH_V8M
+CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer,     /*!< [in] Address of the buffer to map. */
+                                  size_t              buffSize,         /*!< [in] Buffer size in bytes. */
+                                  uint8_t             buffType,         /* ! [in] Input for read / output for write */
+                                  uint8_t             *pBuffNs          /*!< [out] HNONSEC buffer attribute (0 for secure, 1 for non-secure) */
+)
+{
+    cmse_address_info_t addInfo;
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(buffType);
+    *pBuffNs = DATA_BUFFER_IS_SECURE;
+
+    /* It is assumed that an object is allocated in a single MPU (Memory Protection Unit) region,
+     * so it is not needed to check the entire length of the buffer. */
+    addInfo = cmse_TT((unsigned char*)pDataBuffer);
+    if (addInfo.flags.secure == 0x00) {
+        *pBuffNs = DATA_BUFFER_IS_NONSECURE;
+    } else {
+    }
+
+    return CC_OK;
+}
+#else
+CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer,     /*!< [in] Address of the buffer to map. */
+                                  size_t              buffSize,         /*!< [in] Buffer size in bytes. */
+                                  uint8_t             buffType,         /* ! [in] Input for read / output for write */
+                                  uint8_t             *pBuffNs          /*!< [out] HNONSEC buffer attribute (0 for secure, 1 for non-secure) */
+)
+{
+    CC_UNUSED_PARAM(pDataBuffer);
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(buffType);
+
+    *pBuffNs = DATA_BUFFER_IS_SECURE;
+
+    return CC_OK;
+}
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_dma.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_dma.c
new file mode 100644
index 0000000..7636b71
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_dma.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_log.h"
+#include "cc_pal_dma.h"
+#include "cc_pal_memmap.h"
+#include "cc_pal_perf.h"
+#include "cc_address_defs.h"
+#include <string.h>
+
+
+/*******************************************************************************************************/
+/******* Public functions                                                       ************************/
+/*******************************************************************************************************/
+
+/**
+ * @brief  initialize cookies and memory used for dma operations
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] physBuffAddr - physical start address of the memory to map
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaInit(uint32_t  buffSize,
+                        CCDmaAddr_t  physBuffAddr)
+{
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(physBuffAddr);
+
+    return 0;
+}
+
+/**
+ * @brief   free system resources created in PD_PAL_DmaInit()
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ *
+ * @return void
+ */
+void CC_PalDmaTerminate(void)
+{
+    return;
+}
+
+
+/**
+ * @brief   Maps a given buffer of any type. Returns the list of DMA-able blocks that the buffer maps to.
+ *
+ * @param[in] pDataBuffer -  Address of the buffer to map
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[in] copyDirection - Copy direction of the buffer. Can be TO_DEVICE, FROM_DEVICE or BI_DIRECTION
+ * @param[in/out] numOfBlocks - maximum numOfBlocks to fill, as output the actual number
+ * @param[out] pDmaBlockList - List of DMA-able blocks that the buffer maps to
+ * @param[out] dmaBuffHandle - A handle to the mapped buffer private resources
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaBufferMap(uint8_t                   *pDataBuffer,
+                 uint32_t                     buffSize,
+                 CCPalDmaBufferDirection_t  copyDirection,
+                 uint32_t                     *pNumOfBlocks,
+                 CCPalDmaBlockInfo_t        *pDmaBlockList,
+                 CC_PalDmaBufferHandle       *dmaBuffHandle)
+{
+    CC_UNUSED_PARAM(pDataBuffer);
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(copyDirection);
+    CC_UNUSED_PARAM(pNumOfBlocks);
+    CC_UNUSED_PARAM(pDmaBlockList);
+    CC_UNUSED_PARAM(dmaBuffHandle);
+
+    return 0;
+}
+
+/**
+ * @brief   Unmaps a given buffer, and frees its associated resources, if exist
+ *
+ * @param[in] pDataBuffer -  Address of the buffer to map
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[in] copyDirection - Copy direction of the buffer. Can be TO_DEVICE, FROM_DEVICE or BI_DIRECTION
+ * @param[in] numOfBlocks - Number of DMA-able blocks that the buffer maps to
+ * @param[in] pDmaBlockList - List of DMA-able blocks that the buffer maps to
+ * @param[in] dmaBuffHandle - A handle to the mapped buffer private resources
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaBufferUnmap(uint8_t                       *pDataBuffer,
+                   uint32_t                     buffSize,
+                   CCPalDmaBufferDirection_t  copyDirection,
+                   uint32_t                     numOfBlocks,
+                   CCPalDmaBlockInfo_t        *pDmaBlockList,
+                   CC_PalDmaBufferHandle       dmaBuffHandle)
+{
+
+    CC_UNUSED_PARAM(pDataBuffer);
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(copyDirection);
+    CC_UNUSED_PARAM(numOfBlocks);
+    CC_UNUSED_PARAM(pDmaBlockList);
+    CC_UNUSED_PARAM(dmaBuffHandle);
+
+    return 0;
+
+}
+
+
+
+/**
+ * @brief   Allocates a DMA-contiguous buffer, and returns both its physical and virtual addresses
+ *
+ *
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[out] ppVirtBuffAddr - Virtual address of the allocated buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaContigBufferAllocate(uint32_t          buffSize,
+                    uint8_t          **ppVirtBuffAddr)
+{
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(ppVirtBuffAddr);
+
+    return 0;
+}
+
+
+
+/**
+ * @brief   free resources previuosly allocated by CC_PalDmaContigBufferAllocate
+ *
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] pVirtBuffAddr - virtual address of the buffer to free
+ *
+ * @return success/fail
+ */
+uint32_t CC_PalDmaContigBufferFree(uint32_t          buffSize,
+                    uint8_t          *pVirtBuffAddr)
+{
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(pVirtBuffAddr);
+
+    return 0;
+}
+
+
+
+/**
+ * @brief   release and free previously allocated buffers
+ *
+ * @param[in] pDataBuffer - User buffer address
+ * @param[in] buffSize - User buffer size
+ *
+ * @return Returns TRUE if the buffer is guaranteed to be a single contiguous DMA block, and FALSE otherwise.
+ */
+uint32_t CC_PalIsDmaBufferContiguous(uint8_t       *pDataBuffer,
+                      uint32_t       buffSize)
+{
+    CC_UNUSED_PARAM(pDataBuffer);
+    CC_UNUSED_PARAM(buffSize);
+    return 0; // false indication
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_fips.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_fips.c
new file mode 100644
index 0000000..de71e6f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_fips.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_fips.h"
+#include "cc_pal_mem.h"
+
+CCFipsStateData_t   gStateData = { CC_FIPS_STATE_CRYPTO_APPROVED, CC_TEE_FIPS_ERROR_OK, CC_FIPS_TRACE_NONE };
+
+
+CCError_t CC_PalFipsWaitForReeStatus(void)
+{
+    FipsSetReeStatus(CC_TEE_FIPS_REE_STATUS_OK);
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsStopWaitingRee(void)
+{
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsGetState(CCFipsState_t *pFipsState)
+{
+    *pFipsState = gStateData.state;
+
+    return CC_OK;
+}
+
+
+CCError_t CC_PalFipsGetError(CCFipsError_t *pFipsError)
+{
+    *pFipsError = gStateData.error;
+
+    return CC_OK;
+}
+
+
+CCError_t CC_PalFipsGetTrace(CCFipsTrace_t *pFipsTrace)
+{
+    *pFipsTrace = gStateData.trace;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetState(CCFipsState_t fipsState)
+{
+    gStateData.state = fipsState;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetError(CCFipsError_t fipsError)
+{
+    gStateData.error = fipsError;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetTrace(CCFipsTrace_t fipsTrace)
+{
+    gStateData.trace = (CCFipsTrace_t)(gStateData.trace | fipsTrace);
+
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_interrupt_ctrl.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_interrupt_ctrl.c
new file mode 100644
index 0000000..785e4b7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_interrupt_ctrl.c
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files *************************************************/
+#include "cc_pal_types.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_interrupt_ctrl_plat.h"
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_hal.h"
+/************************ Defines ********************************************/
+
+/************************ Enums **********************************************/
+
+/************************ Typedefs *******************************************/
+
+/************************ Global Data ****************************************/
+QueueHandle_t xQueue = NULL;
+
+/************************ Private Functions **********************************/
+eIrqReturn CC_Handler(uint32_t index, void *args);
+
+/************************ Public Functions ***********************************/
+/**
+ * @brief
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalInitIrq(void)
+{
+    uint32_t pxRxedMessage = 0;
+
+    uint32_t mask = 0;
+
+    /* clear all interrupts before starting the engine */
+    CC_HAL_WRITE_REGISTER( CC_REG_OFFSET(HOST_RGF, HOST_ICR), 0xFFFFFFFFUL);
+
+    /* unmask all interrupts except for RNG_INT */
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SRAM_TO_DIN_MASK, mask, 0);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_SRAM_MASK, mask, 0);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, MEM_TO_DIN_MASK, mask, 0);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, DOUT_TO_MEM_MASK, mask, 0);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, AXI_ERR_MASK, mask, 0);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, PKA_EXP_MASK, mask, 0);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, RNG_INT_MASK, mask, 1);
+    CC_REG_FLD_SET(HOST_RGF, HOST_IMR, SYM_DMA_COMPLETED_MASK, mask, 0);
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IMR), mask);
+
+    if (xQueue == NULL)
+    {
+        xQueue = xQueueCreate( 1, sizeof(uint32_t) );
+        if (xQueue == NULL){
+            return CC_FAIL;
+        }
+    }
+
+    /* initialize interrupt controller */
+    if(CC_PalRequestIrq( CRYPTOCELL_INTERRUPT, &CC_Handler,
+                "CC", sizeof("CC"), NULL)){
+        return CC_FAIL;
+    }
+
+    if(CC_PalEnableIrq(CRYPTOCELL_INTERRUPT)){
+        return CC_FAIL;
+    }
+
+    /*  if there is already an interrupt raised in the system the interrupt
+     *  handler will handle it and send message to the queue. in this case
+     *  the queue needs to be emptied by calling xQueueReceive().
+     *  return value is 0 for error and 1 for success - FreeRTOS logics*/
+
+    if (xQueueReceive( xQueue, &( pxRxedMessage ),  10 ) )
+    {
+        return CC_SUCCESS;
+    }
+    else
+    {
+       return CC_FAIL;
+    }
+
+}
+
+/**
+ * @brief This function removes the interrupt handler for
+ * cryptocell interrupts.
+ *
+ */
+void CC_PalFinishIrq(void)
+{
+    CC_PalFreeIrq(CRYPTOCELL_INTERRUPT);
+
+}
+
+/**
+ * @brief This function sets one of the handler function pointers that are
+ * in handlerFuncPtrArr, according to given index.
+ *
+ * @param[in]
+ * handlerIndx - Irq index.
+ * funcPtr - Address of the new handler function.
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalRequestIrq(uint32_t irq, IrqHandlerPtr funcPtr,
+            const char *name, uint8_t nameLength, void *args)
+{
+    CC_UNUSED_PARAM(nameLength);
+    if (!RequestIrq(irq, funcPtr, name, args))
+        return CC_FAIL;
+
+    return CC_SUCCESS;
+}
+
+/**
+ * @brief This function removes an interrupt handler.
+ *
+ * @param[in]
+ * irq - Irq index.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void CC_PalFreeIrq(uint32_t irq)
+{
+    FreeIrq(irq);
+}
+
+/**
+ * @brief This function enables an IRQ according to given index.
+ *
+ * @param[in]
+ * irq - Irq index.
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalEnableIrq(uint32_t irq)
+{
+    if (!EnableIrq(irq))
+        return CC_FAIL;
+
+    return CC_SUCCESS;
+}
+
+/**
+ * @brief This function disables an IRQ according to given index.
+ *
+ * @param[in]
+ * irq - Irq index.
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalDisableIrq(uint32_t irq)
+{
+    if (!DisableIrq(irq))
+        return CC_FAIL;
+
+    return CC_SUCCESS;
+}
+
+/* ISR handler for CryptoCell interrupts.
+ * Clears the IRR and sends the value of IRR to xQueue. The value is
+ * received and checked by CC_PalWaitInterrupt.
+ *
+ * */
+eIrqReturn CC_Handler(uint32_t index, void *args)
+{
+    uint32_t irr = CC_SUCCESS;
+    uint32_t intBits;
+
+    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+    CC_UNUSED_PARAM(index);
+    CC_UNUSED_PARAM(args);
+
+    irr = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRR)) ;
+
+    /* clear interrupt bits*/
+    CC_HAL_WRITE_REGISTER( CC_REG_OFFSET(HOST_RGF, HOST_ICR), irr);  // IRR and ICR bit map is the same use data to clear interrupt in ICR
+
+
+    /* Handle DMA interrupt */
+     intBits = 0;
+     CC_REG_FLD_SET(HOST_RGF, HOST_IRR, SYM_DMA_COMPLETED, intBits, 1);
+     if ((irr&intBits) == intBits){
+
+             /* Unblock the task waiting to be notified that the CryptoCell operation has ended. */
+             xQueueSendFromISR( xQueue, &irr, &xHigherPriorityTaskWoken );
+     }
+
+
+    /* Force a context switch if needed*/
+    portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+
+    return IRQ_HANDLED;
+}
+
+/*!
+ * This function notifies for any ARM CryptoCell interrupt.
+ * Sleep until there's an Interrupt from the cryptocell, caused when one of the
+ * Interrupt Request Register (IRR) signals is raised.
+ * it is the caller responsibility to verify and prompt the expected case
+ * interrupt source.
+ *
+ * @param[in] data      - expected value of IRR
+ * @return              - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalWaitInterrupt( uint32_t data){
+    CCError_t error = CC_SUCCESS;
+    uint32_t irr = 0;
+
+    /*Wait until an interrupt has occurred and a message is received from within the ISR*/
+    if(xQueueReceive( xQueue, &irr,  10000 ) == pdFALSE){
+        return CC_FAIL;
+    }
+
+    if( CC_REG_FLD_GET(0, HOST_IRR, AHB_ERR_INT, irr) == CC_TRUE) {
+        error = CC_FAIL;
+        /*set data for clearing bus error*/
+        CC_REG_FLD_SET(HOST_RGF, HOST_ICR, AXI_ERR_CLEAR, data , 1);
+    }
+
+    if ((irr & data) == 0){
+        return CC_FAIL;
+    }
+    return error;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_log.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_log.c
new file mode 100644
index 0000000..9edd40b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_log.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include <stdio.h>
+#include <stdarg.h>
+#include "cc_pal_types.h"
+#include "cc_pal_log.h"
+
+int CC_PAL_logLevel = CC_PAL_MAX_LOG_LEVEL;
+uint32_t CC_PAL_logMask = 0xFFFFFFFF;
+
+void CC_PalLogInit(void)
+{
+}
+
+void CC_PalLogLevelSet(int setLevel)
+{
+    CC_PAL_logLevel = setLevel;
+}
+
+void CC_PalLogMaskSet(uint32_t setMask)
+{
+    CC_PAL_logMask = setMask;
+}
+
+void CC_PalLog(int level, const char * format, ...)
+{
+    va_list args;
+    CC_UNUSED_PARAM(level);
+    va_start( args, format );
+
+    vprintf( format, args);
+    va_end(args);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_mem.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_mem.c
new file mode 100644
index 0000000..f00cbd0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_mem.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_error.h"
+#include "cc_pal_mem.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+
+/************************ Typedefs ******************************/
+
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to perform secured memory comparison between two given
+ *        buffers according to given size. The function will compare each byte till aSize
+ *        number of bytes was compared even if the bytes are different.
+ *        The function should be used to avoid security timing attacks.
+ *
+ *
+ * @param[in] aTarget - The target buffer to compare
+ * @param[in] aSource - The Source buffer to compare to
+ * @param[in] aSize - Number of bytes to compare
+ *
+ * @return The function will return CC_SUCCESS in case of success, else errors from
+ *         cc_pal_error.h will be returned.
+ */
+CCError_t CC_PalSecMemCmp(  const uint8_t* aTarget,
+                        const uint8_t* aSource,
+                        size_t  aSize       )
+{
+  /* internal index */
+  uint32_t i = 0;
+
+  /* error return */
+  uint32_t error = CC_SUCCESS;
+
+  /*------------------
+      CODE
+  -------------------*/
+
+  /* Go over aTarget till aSize is reached (even if its not equal) */
+  for (i = 0; i < aSize; i++)
+  {
+    if (aTarget[i] != aSource[i])
+    {
+      if (error != CC_SUCCESS)
+        continue;
+      else
+      {
+        if (aTarget[i] < aSource[i])
+          error = CC_PAL_MEM_BUF2_GREATER;
+        else
+          error = CC_PAL_MEM_BUF1_GREATER;
+      }
+    }
+  }
+
+  return error;
+}/* End of CC_PalSecMemCmp */
+
+
+int32_t CC_PalMemCmpPlat(  const void* aTarget, /*!< [in] The target buffer to compare. */
+                           const void* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */)
+{
+    return memcmp(aTarget, aSource, aSize);
+
+}/* End of CC_PalMemCmpPlat */
+
+void* CC_PalMemCopyPlat(     void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                               const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                               size_t      aSize     /*!< [in] Number of bytes to copy. */ ){
+    return memmove( aDestination,  aSource, aSize);
+}/* End of CC_PalMemCopyPlat */
+
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ * This function Supports overlapped buffers.
+ *
+ * @return void.
+ */
+void CC_PalMemMovePlat(   void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                          const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                          size_t      aSize     /*!< [in] Number of bytes to copy. */)
+{
+    memmove(aDestination, aSource, aSize);
+}/* End of CC_PalMemMovePlat */
+
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with aChar.
+ *
+ * @return void.
+ */
+void CC_PalMemSetPlat(   void* aTarget, /*!< [out]  The target buffer to set. */
+                         uint8_t aChar, /*!< [in] The char to set into aTarget. */
+                         size_t        aSize  /*!< [in] Number of bytes to set. */)
+{
+    memset(aTarget, aChar, aSize);
+}/* End of CC_PalMemSetPlat */
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with zeroes.
+ *
+ * @return void.
+ */
+void CC_PalMemSetZeroPlat(    void* aTarget, /*!< [out]  The target buffer to set. */
+                              size_t      aSize    /*!< [in] Number of bytes to set. */)
+{
+    memset(aTarget, 0x00, aSize);
+}/* End of CC_PalMemSetZeroPlat */
+
+/*!
+ * @brief This function purpose is to allocate a memory buffer according to aSize.
+ *
+ *
+ * @return The function returns a pointer to allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemMallocPlat(size_t  aSize /*!< [in] Number of bytes to allocate. */)
+{
+    return pvPortMalloc(aSize);
+}/* End of CC_PalMemMallocPlat */
+
+/*!
+ * @brief This function purpose is to reallocate a memory buffer according to aNewSize.
+ *        The content of the old buffer is moved to the new location.
+ *
+ * @return The function returns a pointer to the newly allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemReallocPlat(  void* aBuffer,     /*!< [in] Pointer to allocated buffer. */
+                             size_t  aNewSize   /*!< [in] Number of bytes to reallocate. */)
+{
+    return pvPortRealloc(aBuffer, aNewSize);
+}/* End of CC_PalMemReallocPlat */
+
+/*!
+ * @brief This function purpose is to free allocated buffer.
+ *
+ *
+ * @return void.
+ */
+void CC_PalMemFreePlat(void* aBuffer /*!< [in] Pointer to allocated buffer.*/)
+{
+    vPortFree(aBuffer);
+}/* End of CC_PalMemFreePlat */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_memmap.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_memmap.c
new file mode 100644
index 0000000..2179949
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_memmap.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_memmap.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to return the base virtual address that maps the
+ *        base physical address
+ *
+ * @param[in] physicalAddress - Starts physical address of the I/O range to be mapped.
+ * @param[in] mapSize - Number of bytes that were mapped
+ * @param[out] ppVirtBuffAddr - Pointer to the base virtual address to which the physical pages were mapped
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalMemMap(CCDmaAddr_t physicalAddress,
+                   uint32_t mapSize,
+               uint32_t **ppVirtBuffAddr)
+{
+    CC_UNUSED_PARAM(mapSize);
+    *ppVirtBuffAddr = (uint32_t *)physicalAddress;
+
+    return 0;
+}/* End of CC_PalMemMap */
+
+
+/**
+ * @brief This function purpose is to Unmaps a specified address range previously mapped
+ *        by CC_PalMemMap
+ *
+ *
+ * @param[in] pVirtBuffAddr - Pointer to the base virtual address to which the physical
+ *            pages were mapped
+ * @param[in] mapSize - Number of bytes that were mapped
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalMemUnMap(uint32_t *pVirtBuffAddr,
+                     uint32_t mapSize)
+{
+    CC_UNUSED_PARAM(pVirtBuffAddr);
+    CC_UNUSED_PARAM(mapSize);
+    return 0;
+}/* End of CC_PalMemUnMap */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_mutex.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_mutex.c
new file mode 100644
index 0000000..0932dcf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_mutex.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_mutex.h"
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include <stdio.h>
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+
+/**
+ * @brief This function purpose is to create a mutex.
+ *
+ *
+ * @param[out] pMutexId - Pointer to created mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexCreate(CC_PalMutex *pMutexId)
+{
+    *pMutexId = xSemaphoreCreateMutex(); // function returns SemaphoreHandle_t
+    if (*pMutexId != NULL)
+        return CC_SUCCESS;
+    return CC_FAIL;
+}
+
+
+/**
+ * @brief This function purpose is to destroy a mutex
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexDestroy(CC_PalMutex *pMutexId)
+{
+    vSemaphoreDelete(*pMutexId);
+    return CC_SUCCESS;
+}
+
+/**
+ * @brief This function purpose is to Wait for Mutex with aTimeOut. aTimeOut is
+ *        specified in milliseconds. (CC_INFINITE is blocking)
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ * @param[in] timeOut - timeout in mSec, or CC_INFINITE
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexLock(CC_PalMutex *pMutexId, uint32_t timeOut)
+{
+    if(!CC_INFINITE)
+        timeOut = timeOut / portTICK_PERIOD_MS;
+    else
+        timeOut = portMAX_DELAY;
+
+    return (xSemaphoreTake(*pMutexId, timeOut) ? CC_SUCCESS : CC_FAIL);
+}
+
+/**
+ * @brief This function purpose is to release the mutex.
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexUnlock(CC_PalMutex *pMutexId)
+{
+    return (xSemaphoreGive(*pMutexId) ? CC_SUCCESS : CC_FAIL);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_perf_plat.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_perf_plat.c
new file mode 100644
index 0000000..1ed444c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_perf_plat.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "stdio.h"
+#include "stdint.h"
+#include "math.h"
+
+#include "cc_pal_perf.h"
+#include "cc_pal_perf_plat.h"
+#include "dx_reg_base_host.h"
+#include "dx_env.h"
+#include "cc_hal.h"
+#include "cc_pal_mem.h"
+
+#include "FreeRTOS.h"
+
+#define MICROSECONDS         1000000
+
+/*!
+ * Read CryptoCell memory-mapped-IO Env register.
+ *
+ * \param regOffset The offset of the Env register to read
+ * \return uint32_t Return the value of the given register
+ */
+#define CC_PAL_PerfReadEnvRegister(regOffset)               \
+        (*((volatile uint32_t *)(DX_BASE_ENV_REGS + (regOffset))))
+
+/*!
+ * Write CryptoCell memory-mapped-IO Env register.
+ *
+ * \param regOffset The offset of the Env register to write
+ * \param val The value to write
+ */
+#define CC_PAL_PerfWriteEnvRegister(regOffset, val)         \
+        (*((volatile uint32_t *)(DX_BASE_ENV_REGS + (regOffset))) = (val))
+
+#define MAX(a,b)            (a) > (b) ? (a) : (b)
+#define MIN(a,b)            (a) < (b) ? (a) : (b)
+
+typedef struct PalPerfCounter_t {
+    uint32_t numOfEntries;
+
+    uint64_t totalCycles;
+    uint64_t totalStdDev;
+
+    CCPalPerfData_t max;
+    CCPalPerfData_t min;
+
+    CCPalPerfData_t prevCycles;
+    uint32_t totalCounts;
+}PalPerfCounter_t;
+
+/**
+ * An array of results per function. Each function updated the data.
+ */
+static PalPerfCounter_t resultsArr[PERF_TEST_TYPE_MAX];
+
+static CCPalPerfData_t CC_PalGetCycles(void);
+static CCPalPerfData_t CC_PalGetCycles(void)
+{
+    return CC_PAL_PerfReadEnvRegister(DX_ENV_COUNTER_RD_REG_OFFSET);
+}
+
+
+/**
+ *
+ * @param cycles
+ * @return          microSeconds
+ */
+static uint32_t CC_PalGetMicroSec(CCPalPerfData_t cycles);
+static uint32_t CC_PalGetMicroSec(CCPalPerfData_t cycles)
+{
+    return (uint32_t)(cycles * (uint64_t)MICROSECONDS / configCPU_CLOCK_HZ);
+}
+
+
+/**
+ * @brief   initialize performance test mechanism
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfInit(void)
+{
+    CCPalPerfType_t funcIndex;
+    for (funcIndex = (CCPalPerfType_t)0; funcIndex < PERF_TEST_TYPE_MAX; ++funcIndex)
+    {
+        PalPerfCounter_t* pCyclesData = &resultsArr[funcIndex];
+
+        pCyclesData->prevCycles = 0;
+        pCyclesData->totalCounts = 0;
+        pCyclesData->totalStdDev = 0;
+        pCyclesData->totalCycles = 0;
+        pCyclesData->max = 0;
+        pCyclesData->min = (CCPalPerfData_t)-1;
+    }
+}
+
+
+/**
+ * @brief   terminates resources used for performance tests
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfFin(void)
+{
+    // nothing to be done
+}
+/**
+ * @brief   opens new entry in perf buffer to record new entry
+ *
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+CCPalPerfData_t CC_PalPerfOpenNewEntry(CCPalPerfType_t entryType)
+{
+    PalPerfCounter_t* pCyclesData = &resultsArr[entryType];
+
+    CCPalPerfData_t cycles = CC_PalGetCycles();
+
+    pCyclesData->prevCycles = cycles;
+
+
+    return (CCPalPerfData_t)entryType;
+}
+
+
+/**
+ * @brief   closes entry in perf buffer previously opened by CC_PalPerfOpenNewEntry
+ *
+ * @param[in] idx -  index of the entry to be closed, the return value of CC_PalPerfOpenNewEntry
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+void CC_PalPerfCloseEntry(CCPalPerfData_t idx, CCPalPerfType_t entryType)
+{
+    PalPerfCounter_t* pCyclesData = &resultsArr[entryType];
+
+    CCPalPerfData_t cycles = CC_PalGetCycles();
+
+    cycles = cycles - pCyclesData->prevCycles;
+
+    pCyclesData->totalCycles += cycles;
+    pCyclesData->totalStdDev += cycles * cycles;
+    pCyclesData->totalCounts += 1;
+
+    pCyclesData->max = MAX(pCyclesData->max, cycles);
+    pCyclesData->min = MIN(pCyclesData->min, cycles);
+}
+
+
+/**
+ * @brief   dumps the performance buffer
+ *
+ * @param[in] None
+ *
+ * @return None
+ */
+void CC_PalPerfDump(void)
+{
+#define CC_PALPERFDUMP_LENGTH 256
+#define CC_PALPERFDUMP_SEPERATOR "----------------------------------------------------------------" \
+                "----------------------------------------------------------------" \
+                "----------------------------------------------------------------" \
+                "----------------------------------------------------------------"
+
+    CCPalPerfType_t i;
+    char buff[CC_PALPERFDUMP_LENGTH];
+
+    uint32_t length = snprintf(buff, CC_PALPERFDUMP_LENGTH, "| %-30.30s | %-10.10s | %-15.15s | %-15.15s | %-15.15s | %-15.15s | %-15.15s | %-15.15s |",
+           "Function", "countTests", "TimePerCall,uS", "CallsPerSec", "ClocksPerCall", "ClocksStDev", "ClocksMin", "ClocksMax");
+
+    // Print header
+    printf("%*.*s\n%s\n%*.*s\n", length, length, CC_PALPERFDUMP_SEPERATOR, buff, length, length, CC_PALPERFDUMP_SEPERATOR);
+
+    for (i = (CCPalPerfType_t)0; i < PERF_TEST_TYPE_MAX; i++)
+    {
+        CCPalPerfData_t totalCycles = 0;
+        uint32_t totalCounts = 0;
+        CCPalPerfData_t avgCycles;
+        CCPalPerfData_t min;
+        CCPalPerfData_t max;
+        uint64_t totalStdDev;
+        uint64_t stdDev;
+
+
+        totalCycles = resultsArr[i].totalCycles;
+        totalCounts = resultsArr[i].totalCounts;
+        totalStdDev = resultsArr[i].totalStdDev;
+        min = resultsArr[i].min;
+        max = resultsArr[i].max;
+
+        if (totalCounts == 0)
+        {
+            continue;
+        }
+
+        avgCycles = (0 != totalCounts) ? (CCPalPerfData_t)(totalCycles / totalCounts) : 0;
+        stdDev = sqrt(totalStdDev - totalCounts * avgCycles * avgCycles) / (totalCounts - 1);
+
+
+        printf("| %-30.30s | %10u | %15lu | %15lu | %15lu | %15lu | %15lu | %15lu |\n",
+               CC_PalPerfTypeStr(i, buff, CC_PALPERFDUMP_LENGTH), (uint32_t)totalCounts, (uint32_t)CC_PalGetMicroSec(avgCycles),
+               (uint32_t)(MICROSECONDS / CC_PalGetMicroSec(avgCycles)),
+               (uint32_t)avgCycles, (uint32_t)stdDev, (uint32_t)min, (uint32_t)max);
+    }
+
+    printf("%*.*s\n", length, length, CC_PALPERFDUMP_SEPERATOR);
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_pm.c b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_pm.c
new file mode 100644
index 0000000..e081cf4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/freertos/cc_pal_pm.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "FreeRTOS.h"
+#include "task.h"
+
+int32_t g_pmCntr;
+
+void CC_PalPowerSaveModeInit(void)
+{
+    g_pmCntr = 0;
+    return;
+}
+
+int32_t CC_PalPowerSaveModeStatus(void)
+{
+    return g_pmCntr;
+}
+
+CCError_t CC_PalPowerSaveModeSelect(CCBool isPowerSaveMode)
+{
+    CCError_t rc = CC_OK;
+
+    switch (isPowerSaveMode){
+    case CC_FALSE:
+        taskENTER_CRITICAL();
+         g_pmCntr++;
+        taskEXIT_CRITICAL();
+        break;
+    case CC_TRUE:
+        taskENTER_CRITICAL();
+        g_pmCntr--;
+        taskEXIT_CRITICAL();
+        break;
+    default:
+        return CC_FAIL;
+    }
+
+    if(g_pmCntr == 0){
+        /* once the counter is zero,
+         * an external callback shall be called to notify the PMU that ARM Cerberus might be powered down. */
+    }
+
+    if(g_pmCntr < 0 ){
+        /* illegal state - exit with error */
+        return CC_FAIL;
+    }
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/Makefile b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/Makefile
new file mode 100644
index 0000000..be5d265
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/Makefile
@@ -0,0 +1,17 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for pal for linux
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../../..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+TARGET_LIBS = pal_linux
+PLAT_OS=linux
+include ../project_pal.mk
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal.c
new file mode 100644
index 0000000..0bcfe7a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_init.h"
+#include "cc_pal_dma_plat.h"
+#include "cc_pal_log.h"
+#include "dx_reg_base_host.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_abort.h"
+#include "cc_pal_pm.h"
+
+extern CC_PalMutex CCSymCryptoMutex;
+extern CC_PalMutex CCAsymCryptoMutex;
+extern CC_PalMutex CCRndCryptoMutex;
+extern CC_PalMutex *pCCRndCryptoMutex;
+
+#ifndef CC_IOT
+extern CC_PalMutex CCGenVecMutex;
+extern CC_PalMutex *pCCGenVecMutex;
+#endif
+
+#ifdef CC_IOT
+extern CC_PalMutex CCApbFilteringRegMutex;
+#endif
+
+#ifdef DX_PLAT_ZYNQ7000
+/* Zynq EVBs have 1GB and we reserve the memory at offset 768M */
+#define PAL_WORKSPACE_MEM_BASE_ADDR     0x34000000
+#elif defined PLAT_VIRTEX5
+/* Virtex5 platforms (PPC) have 512MB and we reserve the memory at offset 256M */
+#define PAL_WORKSPACE_MEM_BASE_ADDR     0x10000000
+#elif defined DX_PLAT_JUNO
+/* Juno platforms (AARCH64)  */
+#define PAL_WORKSPACE_MEM_BASE_ADDR     0x8A0000000
+#endif
+#define PAL_WORKSPACE_MEM_SIZE      0x1000000
+
+/**
+ * @brief   PAL layer entry point.
+ *          The function initializes customer platform sub components,
+ *           such as memory mapping used later by CRYS to get physical contiguous memory.
+ *
+ *
+ * @return Virtual start address of contiguous memory
+ */
+int CC_PalInit(void)
+{
+    int rc = 0;
+
+    CC_PalLogInit();
+
+    rc = CC_PalDmaInit(PAL_WORKSPACE_MEM_SIZE, PAL_WORKSPACE_MEM_BASE_ADDR);
+    if (rc != 0) {
+            return 1;
+    }
+
+#ifdef CC_IOT
+    /* Initialize power management module */
+    CC_PalPowerSaveModeInit();
+#endif
+
+    /* Initialize mutex that protects shared memory and crypto access */
+    rc = CC_PalMutexCreate(&CCSymCryptoMutex);
+    if (rc != 0) {
+            CC_PalAbort("Fail to create SYM mutex\n");
+    }
+    /* Initialize mutex that protects shared memory and crypto access */
+    rc = CC_PalMutexCreate(&CCAsymCryptoMutex);
+    if (rc != 0) {
+            CC_PalAbort("Fail to create ASYM mutex\n");
+    }
+    /* Initialize mutex that protects shared memory and crypto access */
+    rc = CC_PalMutexCreate(&CCRndCryptoMutex);
+    if (rc != 0) {
+            CC_PalAbort("Fail to create RND mutex\n");
+    }
+    pCCRndCryptoMutex = &CCRndCryptoMutex;
+
+#ifndef CC_IOT
+    pCCGenVecMutex = &CCRndCryptoMutex;
+#endif
+
+#ifdef CC_IOT
+    /* Initialize mutex that protects APBC access */
+    rc = CC_PalMutexCreate(&CCApbFilteringRegMutex);
+    if (rc != 0) {
+            CC_PalAbort("Fail to create APBC mutex\n");
+    }
+#endif
+
+    return 0;
+}
+
+
+/**
+ * @brief   PAL layer entry point.
+ *          The function initializes customer platform sub components,
+ *           such as memory mapping used later by CRYS to get physical contiguous memory.
+ *
+ *
+ * @return None
+ */
+void CC_PalTerminate(void)
+{
+    CCError_t err = 0;
+
+    CC_PalDmaTerminate();
+
+    err = CC_PalMutexDestroy(&CCSymCryptoMutex);
+    if (err != 0){
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCSymCryptoMutex\n");
+    }
+    CC_PalMemSetZero(&CCSymCryptoMutex, sizeof(CC_PalMutex));
+
+    err = CC_PalMutexDestroy(&CCAsymCryptoMutex);
+    if (err != 0){
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCAsymCryptoMutex\n");
+    }
+    CC_PalMemSetZero(&CCAsymCryptoMutex, sizeof(CC_PalMutex));
+
+    err = CC_PalMutexDestroy(&CCRndCryptoMutex);
+    if (err != 0){
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCRndCryptoMutex\n");
+    }
+    CC_PalMemSetZero(&CCRndCryptoMutex, sizeof(CC_PalMutex));
+
+#ifdef CC_IOT
+    err = CC_PalMutexDestroy(&CCApbFilteringRegMutex);
+    if (err != 0){
+            CC_PAL_LOG_DEBUG("failed to destroy mutex CCApbFilteringRegMutex\n");
+    }
+    CC_PalMemSetZero(&CCApbFilteringRegMutex, sizeof(CC_PalMutex));
+#endif
+
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_abort_plat.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_abort_plat.c
new file mode 100644
index 0000000..99a0299
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_abort_plat.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_log.h"
+#include "stdlib.h"
+
+
+void CC_PalAbort(const char * exp)
+{
+    CC_PAL_LOG_ERR("ASSERT:%s:%d: %s", __FILE__, __LINE__, exp);
+    CC_UNUSED_PARAM(exp); /* to avoid compilation error in case DEBUG isn't defined*/
+    abort();
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_apbc.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_apbc.c
new file mode 100644
index 0000000..10d4c71
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_apbc.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+
+int32_t g_apbcCntr;
+
+void CC_PalApbcCntrInit(void)
+{
+    g_apbcCntr = 0;
+    return;
+}
+
+int32_t CC_PalApbcCntrValue(void)
+{
+    return g_apbcCntr;
+}
+
+CCError_t CC_PalApbcModeSelect(CCBool isApbcInc)
+{
+    CCError_t rc = CC_OK;
+    switch (isApbcInc){
+    case CC_FALSE:
+         __atomic_fetch_sub(&g_apbcCntr, 1, __ATOMIC_SEQ_CST);
+        break;
+    case CC_TRUE:
+        __atomic_fetch_add(&g_apbcCntr, 1, __ATOMIC_SEQ_CST);
+        break;
+    default:
+        return -1;
+    }
+
+    if(g_apbcCntr < 0 ){
+        /* illegal state - exit with error */
+        return 1;
+    }
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_barrier.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_barrier.c
new file mode 100644
index 0000000..4c3386d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_barrier.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_barrier.h"
+
+/* taken from arch/arm/include/asm/barrier.h */
+
+
+
+#if defined(__arm64__)
+/* This is memmory barrier for ARM64*/
+
+#define dsb(opt)        asm volatile("dsb " #opt : : : "memory")
+
+#elif defined(__arm__)
+/* This is memmory barrier for ARM*/
+
+#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
+
+#else
+#error This is a place holder for platform specific memory barrier implementation
+#define dsb()
+#endif
+/* This is a plac holder for L2 cache sync function*/
+#define CC_PAL_L2_CACHE_SYNC() do { } while (0)
+
+#if defined(__arm64__)
+#define mb()            dsb(sy)
+#define rmb()           dsb(ld)
+#define wmb()           dsb(st)
+#else
+#define mb()            do { dsb(); CC_PAL_L2_CACHE_SYNC(); } while (0)
+#define rmb()           dsb()
+#define wmb()           mb()
+#endif
+
+
+
+void CC_PalWmb(void)
+{
+    wmb();
+}
+
+void CC_PalRmb(void)
+{
+    rmb();
+}
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_buff_attr.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_buff_attr.c
new file mode 100644
index 0000000..a096769
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_buff_attr.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_buff_attr.h"
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer,     /*!< [in] Address of the buffer to map. */
+                                  size_t              buffSize,         /*!< [in] Buffer size in bytes. */
+                                  uint8_t             buffType,         /* ! [in] Input for read / output for write */
+                                  uint8_t             *pBuffNs           /*!< [out] HNONSEC buffer attribute (0 for secure, 1 for non-secure) */
+                                  )
+{
+    CC_UNUSED_PARAM(pDataBuffer);
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(buffType);
+
+    *pBuffNs = DATA_BUFFER_IS_SECURE;
+
+    return CC_OK;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_dma.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_dma.c
new file mode 100644
index 0000000..2139409
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_dma.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include <unistd.h>
+#include <string.h>
+#include "cc_pal_types.h"
+#include "cc_pal_dma.h"
+
+
+/**
+ * @brief   Initializes contiguous memory pool required for CC_PalDmaContigBufferAllocate() and CC_PalDmaContigBufferFree(). Our
+ *           implementation is to mmap 0x10000000 and call to bpool(), for use of bget() in CC_PalDmaContigBufferAllocate(),
+ *           and brel() in CC_PalDmaContigBufferFree().
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] physBuffAddr - physical start address of the memory to map
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaInit(uint32_t  buffSize,
+                        CCDmaAddr_t  physBuffAddr)
+{
+    buffSize = buffSize; // to remove compilation warnings
+    physBuffAddr = physBuffAddr;
+
+    return 0;
+}
+
+/**
+ * @brief   free system resources created in PD_PAL_DmaInit()
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ *
+ * @return void
+ */
+void CC_PalDmaTerminate(void)
+{
+    return;
+}
+
+#ifndef CC_IOT
+/**
+ * @brief   Maps a given buffer of any type. Returns the list of DMA-able blocks that the buffer maps to.
+ *
+ * @param[in] pDataBuffer -  Address of the buffer to map
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[in] copyDirection - Copy direction of the buffer. Can be TO_DEVICE, FROM_DEVICE or BI_DIRECTION
+ * @param[in/out] numOfBlocks - maximum numOfBlocks to fill, as output the actual number
+ * @param[out] pDmaBlockList - List of DMA-able blocks that the buffer maps to
+ * @param[out] dmaBuffHandle - A handle to the mapped buffer private resources
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaBufferMap(uint8_t                   *pDataBuffer,
+                 uint32_t                     buffSize,
+                 CCPalDmaBufferDirection_t  copyDirection,
+                 uint32_t                     *pNumOfBlocks,
+                 CCPalDmaBlockInfo_t        *pDmaBlockList,
+                 CC_PalDmaBufferHandle       *dmaBuffHandle)
+{
+
+    return (-1);
+}
+
+/**
+ * @brief   Unmaps a given buffer, and frees its associated resources, if exist
+ *
+ * @param[in] pDataBuffer -  Address of the buffer to map
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[in] copyDirection - Copy direction of the buffer. Can be TO_DEVICE, FROM_DEVICE or BI_DIRECTION
+ * @param[in] numOfBlocks - Number of DMA-able blocks that the buffer maps to
+ * @param[in] pDmaBlockList - List of DMA-able blocks that the buffer maps to
+ * @param[in] dmaBuffHandle - A handle to the mapped buffer private resources
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaBufferUnmap(uint8_t                     *pDataBuffer,
+                 uint32_t                     buffSize,
+                 CCPalDmaBufferDirection_t  copyDirection,
+                 uint32_t                     numOfBlocks,
+                 CCPalDmaBlockInfo_t        *pDmaBlockList,
+                 CC_PalDmaBufferHandle       dmaBuffHandle)
+{
+    return (-1);
+}
+
+
+
+/**
+ * @brief   Allocates a DMA-contiguous buffer, and returns both its physical and virtual addresses
+ *
+ *
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[out] ppVirtBuffAddr - Virtual address of the allocated buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaContigBufferAllocate(uint32_t          buffSize,
+                    uint8_t          **ppVirtBuffAddr)
+{
+    return (-1);
+}
+
+
+
+/**
+ * @brief   free resources previuosly allocated by CC_PalDmaContigBufferAllocate
+ *
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] pVirtBuffAddr - virtual address of the buffer to free
+ *
+ * @return success/fail
+ */
+uint32_t CC_PalDmaContigBufferFree(uint32_t          buffSize,
+                    uint8_t          *pVirtBuffAddr)
+{
+    return (-1);
+}
+
+
+/**
+ * @brief   Returns TRUE if the buffer is guaranteed to be a single contiguous DMA block, and FALSE otherwise.
+ *
+ *
+ * @param[in] pDataBuffer - User buffer address
+ * @param[in] buffSize - User buffer size
+ *
+ * @return Returns TRUE if the buffer is guaranteed to be a single contiguous DMA block, and FALSE otherwise.
+ */
+uint32_t CC_PalIsDmaBufferContiguous(uint8_t       *pDataBuffer,
+                      uint32_t       buffSize)
+{
+    return (-1);
+}
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_fips.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_fips.c
new file mode 100644
index 0000000..f13c29a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_fips.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "cc_pal_fips.h"
+#include "cc_pal_mem.h"
+
+CCFipsStateData_t   gStateData = { CC_FIPS_STATE_CRYPTO_APPROVED, CC_TEE_FIPS_ERROR_OK, CC_FIPS_TRACE_NONE };
+
+
+CCError_t CC_PalFipsWaitForReeStatus(void)
+{
+    FipsSetReeStatus(CC_TEE_FIPS_REE_STATUS_OK);
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsStopWaitingRee(void)
+{
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsGetState(CCFipsState_t *pFipsState)
+{
+    *pFipsState = gStateData.state;
+
+    return CC_OK;
+}
+
+
+CCError_t CC_PalFipsGetError(CCFipsError_t *pFipsError)
+{
+    *pFipsError = gStateData.error;
+
+    return CC_OK;
+}
+
+
+CCError_t CC_PalFipsGetTrace(CCFipsTrace_t *pFipsTrace)
+{
+    *pFipsTrace = gStateData.trace;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetState(CCFipsState_t fipsState)
+{
+    gStateData.state = fipsState;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetError(CCFipsError_t fipsError)
+{
+    gStateData.error = fipsError;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetTrace(CCFipsTrace_t fipsTrace)
+{
+    gStateData.trace = (gStateData.trace | fipsTrace);
+
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_interrupt_ctrl.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_interrupt_ctrl.c
new file mode 100644
index 0000000..63f0a26
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_interrupt_ctrl.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files *************************************************/
+#include "cc_pal_types.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_interrupt_ctrl_plat.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_hal.h"
+/************************ Defines ********************************************/
+
+/************************ Enums **********************************************/
+
+/************************ Typedefs *******************************************/
+
+/************************ Global Data ****************************************/
+
+/************************ Private Functions **********************************/
+
+/************************ Public Functions ***********************************/
+/**
+ * @brief
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalInitIrq(void)
+{
+    return CC_SUCCESS;
+}
+
+/**
+ * @brief This function removes the interrupt handler for
+ * cryptocell interrupts.
+ *
+ */
+void CC_PalFinishIrq(void)
+{
+}
+
+
+/*!
+ * Busy wait upon Interrupt Request Register (IRR) signals.
+ * This function notifys for any ARM CryptoCell interrupt, it is the caller responsiblity
+ * to verify and prompt the expected case interupt source.
+ *
+ * @param[in] data  - input data for future use
+ * \return  CCError_t   - CC_OK upon success
+ */
+CCError_t CC_PalWaitInterrupt( uint32_t data){
+    uint32_t irr = 0;
+    CCError_t error = CC_OK;
+
+    /* busy wait upon IRR signal */
+    do {
+        irr = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRR));
+        /* check APB bus error from HOST */
+        if( CC_REG_FLD_GET(0, HOST_IRR, AHB_ERR_INT, irr) == CC_TRUE){
+            error = CC_FAIL;
+            /*set data for clearing bus error*/
+            CC_REG_FLD_SET(HOST_RGF, HOST_ICR, AXI_ERR_CLEAR, data , 1);
+            break;
+        }
+    } while (!(irr & data));
+
+    /* clear interrupt */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), data); // IRR and ICR bit map is the same use data to clear interrupt in ICR
+
+    return error;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_log.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_log.c
new file mode 100644
index 0000000..af10979
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_log.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <syslog.h>
+#include <stdarg.h>
+#include "cc_pal_types.h"
+#include "cc_pal_log.h"
+
+#ifdef DEBUG
+#define SYSLOG_OPTIONS (LOG_CONS | LOG_NDELAY | LOG_PID | LOG_PERROR)
+#else
+#define SYSLOG_OPTIONS (LOG_CONS | LOG_NDELAY | LOG_PID)
+#endif
+
+int CC_PAL_logLevel = CC_PAL_MAX_LOG_LEVEL;
+uint32_t CC_PAL_logMask = 0xFFFFFFFF;
+
+void CC_PalLogInit(void)
+{
+    static int initOnce = 0;
+
+    if (!initOnce)
+        openlog("CC.Proc.", SYSLOG_OPTIONS, LOG_USER);
+    initOnce = 1;
+}
+
+void CC_PalLogLevelSet(int setLevel)
+{
+    CC_PAL_logLevel = setLevel;
+}
+
+void CC_PalLogMaskSet(uint32_t setMask)
+{
+    CC_PAL_logMask = setMask;
+}
+
+void CC_PalLog(int level, const char * format, ...)
+{
+    va_list args;
+    va_start( args, format );
+
+    vsyslog(level + LOG_ERR, format, args);
+    va_end(args);
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_mem.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_mem.c
new file mode 100644
index 0000000..ec22030
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_mem.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_error.h"
+#include "cc_pal_mem.h"
+
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+
+/************************ Typedefs ******************************/
+
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to perform secured memory comparison between two given
+ *        buffers according to given size. The function will compare each byte till aSize
+ *        number of bytes was compared even if the bytes are different.
+ *        The function should be used to avoid security timing attacks.
+ *
+ *
+ * @param[in] aTarget - The target buffer to compare
+ * @param[in] aSource - The Source buffer to compare to
+ * @param[in] aSize - Number of bytes to compare
+ *
+ * @return The function will return CC_SUCCESS in case of success, else errors from
+ *         cc_pal_error.h will be returned.
+ */
+CCError_t CC_PalSecMemCmp(  const uint8_t* aTarget,
+                        const uint8_t* aSource,
+                        size_t  aSize       )
+{
+    /* internal index */
+    uint32_t i = 0;
+
+    /* error return */
+    uint32_t error = CC_SUCCESS;
+
+    /*------------------
+    CODE
+    -------------------*/
+
+    /* Go over aTarget till aSize is reached (even if its not equal) */
+    for (i = 0; i < aSize; i++){
+        if (aTarget[i] != aSource[i]){
+            if (error != CC_SUCCESS)
+                continue;
+            else{
+                if (aTarget[i] < aSource[i])
+                    error = CC_PAL_MEM_BUF2_GREATER;
+                else
+                    error = CC_PAL_MEM_BUF1_GREATER;
+            }
+        }
+    }
+
+    return error;
+}/* End of CC_PalSecMemCmp */
+
+
+int32_t CC_PalMemCmpPlat(  const void* aTarget, /*!< [in] The target buffer to compare. */
+                           const void* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */)
+{
+    return memcmp(aTarget, aSource, aSize);
+
+}/* End of CC_PalMemCmpPlat */
+
+void* CC_PalMemCopyPlat(     void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                               const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                               size_t      aSize     /*!< [in] Number of bytes to copy. */ ){
+    return memmove( aDestination,  aSource, aSize);
+}/* End of CC_PalMemCopyPlat */
+
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ * This function Supports overlapped buffers.
+ *
+ * @return void.
+ */
+void CC_PalMemMovePlat(   void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                          const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                          size_t      aSize     /*!< [in] Number of bytes to copy. */)
+{
+    memmove(aDestination, aSource, aSize);
+}/* End of CC_PalMemMovePlat */
+
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with aChar.
+ *
+ * @return void.
+ */
+void CC_PalMemSetPlat(   void* aTarget, /*!< [out]  The target buffer to set. */
+                         uint8_t aChar, /*!< [in] The char to set into aTarget. */
+                         size_t        aSize  /*!< [in] Number of bytes to set. */)
+{
+    memset(aTarget, aChar, aSize);
+}/* End of CC_PalMemSetPlat */
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with zeroes.
+ *
+ * @return void.
+ */
+void CC_PalMemSetZeroPlat(    void* aTarget, /*!< [out]  The target buffer to set. */
+                              size_t      aSize    /*!< [in] Number of bytes to set. */)
+{
+    memset(aTarget, 0x00, aSize);
+}/* End of CC_PalMemSetZeroPlat */
+
+/*!
+ * @brief This function purpose is to allocate a memory buffer according to aSize.
+ *
+ *
+ * @return The function returns a pointer to allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemMallocPlat(size_t  aSize /*!< [in] Number of bytes to allocate. */)
+{
+    return malloc(aSize);
+}/* End of CC_PalMemMallocPlat */
+
+/*!
+ * @brief This function purpose is to reallocate a memory buffer according to aNewSize.
+ *        The content of the old buffer is moved to the new location.
+ *
+ * @return The function returns a pointer to the newly allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemReallocPlat(  void* aBuffer,     /*!< [in] Pointer to allocated buffer. */
+                             size_t  aNewSize   /*!< [in] Number of bytes to reallocate. */)
+{
+    return realloc(aBuffer, aNewSize);
+}/* End of CC_PalMemReallocPlat */
+
+/*!
+ * @brief This function purpose is to free allocated buffer.
+ *
+ *
+ * @return void.
+ */
+void CC_PalMemFreePlat(void* aBuffer /*!< [in] Pointer to allocated buffer.*/)
+{
+    free(aBuffer);
+}/* End of CC_PalMemFreePlat */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_memmap.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_memmap.c
new file mode 100644
index 0000000..f17ea5a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_memmap.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include "cc_pal_types.h"
+#include "cc_pal_memmap.h"
+
+/************************ Defines ******************************/
+static int halFileH = -1;
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to return the base virtual address that maps the
+ *        base physical address
+ *
+ * @param[in] physicalAddress - Starts physical address of the I/O range to be mapped.
+ * @param[in] mapSize - Number of bytes that were mapped
+ * @param[out] ppVirtBuffAddr - Pointer to the base virtual address to which the physical pages were mapped
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalMemMap(CCDmaAddr_t physicalAddress,
+                   uint32_t mapSize,
+               uint32_t **ppVirtBuffAddr)
+{
+        /* Open device file if not already opened */
+        if (halFileH >= 0) { /* already opened */
+            return 0;
+        }
+
+        halFileH = open("/dev/mem", O_RDWR|O_SYNC);
+        if (halFileH < 0) {
+            return 1;
+        }
+        (void)fcntl(halFileH, F_SETFD, FD_CLOEXEC);
+
+        *ppVirtBuffAddr = (uint32_t *)mmap(0, mapSize, PROT_READ|PROT_WRITE, MAP_SHARED, halFileH, physicalAddress);
+        if ((*ppVirtBuffAddr == NULL) || (*ppVirtBuffAddr == MAP_FAILED)) {
+            close(halFileH);
+            halFileH = -1;
+            return 2;
+        }
+        return 0;
+}/* End of CC_PalMemMap */
+
+
+/**
+ * @brief This function purpose is to Unmaps a specified address range previously mapped
+ *        by CC_PalMemMap
+ *
+ *
+ * @param[in] pVirtBuffAddr - Pointer to the base virtual address to which the physical
+ *            pages were mapped
+ * @param[in] mapSize - Number of bytes that were mapped
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalMemUnMap(uint32_t *pVirtBuffAddr,
+                     uint32_t mapSize)
+{
+        if (halFileH < 0) {
+            return 1;
+        }
+
+        munmap(pVirtBuffAddr, mapSize);
+        close(halFileH);
+        halFileH = -1;
+        return 0;
+}/* End of CC_PalMemUnMap */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_mutex.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_mutex.c
new file mode 100644
index 0000000..75c5c2d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_mutex.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include <time.h>
+#include "cc_pal_types.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_log.h"
+#include <stdio.h>
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to create a mutex.
+ *
+ *
+ * @param[out] pMutexId - Pointer to created mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexCreate(CC_PalMutex *pMutexId)
+{
+    int  rc = CC_SUCCESS;
+
+    rc = pthread_mutex_init(pMutexId, NULL);
+    if (rc != 0) {
+        printf /* CC_PAL_LOG_ERR */("pthread_mutex_init failed 0x%x", rc);
+        return CC_FAIL;
+    }
+    return CC_SUCCESS;
+}
+
+
+/**
+ * @brief This function purpose is to destroy a mutex
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexDestroy(CC_PalMutex *pMutexId)
+{
+    int  rc = CC_SUCCESS;
+
+    rc = pthread_mutex_destroy(pMutexId);
+    if (rc != 0) {
+        printf /* CC_PAL_LOG_ERR */("pthread_mutex_destroy failed 0x%x", rc);
+        return CC_FAIL;
+    }
+    return CC_SUCCESS;
+}
+
+
+/**
+ * @brief This function purpose is to Wait for Mutex with aTimeOut. aTimeOut is
+ *        specified in milliseconds. (CC_INFINITE is blocking)
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ * @param[in] timeOut - timeout in mSec, or CC_INFINITE
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexLock (CC_PalMutex *pMutexId, uint32_t timeOut)
+{
+    int  rc = CC_SUCCESS;
+
+    timeOut = timeOut; // to remove compilation warnings
+
+    rc = pthread_mutex_lock(pMutexId);
+    if (rc != 0) {
+        printf /* CC_PAL_LOG_ERR */("pthread_mutex_lock failed 0x%x", rc);
+        return CC_FAIL;
+    }
+    return CC_SUCCESS;
+}
+
+
+
+/**
+ * @brief This function purpose is to release the mutex.
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexUnlock (CC_PalMutex *pMutexId)
+{
+    int  rc = CC_SUCCESS;
+
+    rc = pthread_mutex_unlock(pMutexId);
+    if (rc != 0) {
+        printf /* CC_PAL_LOG_ERR */("pthread_mutex_unlock failed 0x%x", rc);
+        return CC_FAIL;
+    }
+    return CC_SUCCESS;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_pm.c b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_pm.c
new file mode 100644
index 0000000..b4dc37f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/linux/cc_pal_pm.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+
+int32_t g_pmCntr;
+
+void CC_PalPowerSaveModeInit(void)
+{
+    g_pmCntr = 0;
+    return;
+}
+
+int32_t CC_PalPowerSaveModeStatus(void)
+{
+    return g_pmCntr;
+}
+
+CCError_t CC_PalPowerSaveModeSelect(CCBool isPowerSaveMode)
+{
+    CCError_t rc = CC_OK;
+    switch (isPowerSaveMode){
+    case CC_FALSE:
+         __atomic_fetch_add(&g_pmCntr, 1, __ATOMIC_SEQ_CST);
+        break;
+    case CC_TRUE:
+        __atomic_fetch_sub(&g_pmCntr, 1, __ATOMIC_SEQ_CST);
+        break;
+    default:
+        return -1;
+    }
+
+    if(g_pmCntr == 0){
+        /* once the counter is zero,
+         * an external callback shall be called to notify the PMU that ARM Cerberus might be powered down. */
+    }
+
+    if(g_pmCntr < 0 ){
+        /* illegal state - exit with error */
+        return 1;
+    }
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/Makefile b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/Makefile
new file mode 100644
index 0000000..e112a60
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/Makefile
@@ -0,0 +1,17 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for pal for linux
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../../..
+include $(HOST_PROJ_ROOT)/Makefile.defs
+TARGET_LIBS = pal_no_os
+PLAT_OS=no_os
+include ../project_pal.mk
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal.c
new file mode 100644
index 0000000..3185eb7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_init.h"
+#include "cc_pal_dma_plat.h"
+#include "cc_pal_log.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_pm.h"
+
+/**
+ * @brief   PAL layer entry point.
+ *          The function initializes customer platform sub components,
+ *           such as memory mapping used later by CRYS to get physical contiguous memory.
+ *
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+int CC_PalInit(void)
+{  // IG - need to use palInit of cc_linux for all PALs
+    uint32_t rc = CC_OK;
+
+    CC_PalLogInit();
+
+    rc =    CC_PalDmaInit(0, 0);
+    if (rc != CC_OK) {
+            return rc;
+    }
+
+#ifdef CC_IOT
+/* Initialize power management module */
+    CC_PalPowerSaveModeInit();
+#endif
+
+    return rc;
+}
+
+
+/**
+ * @brief   PAL layer entry point.
+ *          The function initializes customer platform sub components,
+ *           such as memory mapping used later by CRYS to get physical contiguous memory.
+ *
+ *
+ * @return None
+ */
+void CC_PalTerminate(void)
+{
+    CC_PalDmaTerminate();
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_abort_plat.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_abort_plat.c
new file mode 100644
index 0000000..c4b2f9d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_abort_plat.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "cc_pal_log.h"
+#include "stdlib.h"
+
+void CC_PalAbort(const char * exp)
+{
+    CC_PAL_LOG_ERR("ASSERT:%s:%d: %s", __FILE__, __LINE__, exp);
+    CC_UNUSED_PARAM(exp); /* to avoid compilation error in case DEBUG isn't defined*/
+    abort();
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_apbc.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_apbc.c
new file mode 100644
index 0000000..a3dbdd5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_apbc.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+
+void CC_PalApbcCntrInit(void)
+{
+    return;
+}
+
+void CC_PalApbcCntrValue(void)
+{
+    return;
+}
+
+CCError_t CC_PalApbcModeSelect(CCBool isApbcInc)
+{
+    CC_UNUSED_PARAM(isApbcInc);
+
+    return 0;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_barrier.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_barrier.c
new file mode 100644
index 0000000..af03eb2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_barrier.c
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+void CC_PalWmb(void)
+{
+    return;
+}
+
+void CC_PalRmb(void)
+{
+    return;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_buff_attr.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_buff_attr.c
new file mode 100644
index 0000000..d6cff7b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_buff_attr.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_buff_attr.h"
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer,       /*!< [in] Address of the buffer to map. */
+                                  size_t              buffSize,           /*!< [in] Buffer size in bytes. */
+                                  uint8_t             buffType,         /* ! [in] Input for read / output for write */
+                                  uint8_t             *pBuffNs           /*!< [out] HNONSEC buffer attribute (0 for secure, 1 for non-secure) */
+                                  )
+{
+    CC_UNUSED_PARAM(pDataBuffer);
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(buffType);
+
+    *pBuffNs = DATA_BUFFER_IS_SECURE;
+
+    return CC_OK;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_dma.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_dma.c
new file mode 100644
index 0000000..c7b89c9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_dma.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_dma.h"
+#include "cc_address_defs.h"
+
+
+/**
+ * @brief   Initializes contiguous memory pool required for CC_PalDmaContigBufferAllocate() and CC_PalDmaContigBufferFree(). Our
+ *           implementation is to mmap 0x10000000 and call to bpool(), for use of bget() in CC_PalDmaContigBufferAllocate(),
+ *           and brel() in CC_PalDmaContigBufferFree().
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] physBuffAddr - physical start address of the memory to map
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaInit(uint32_t  buffSize,
+                        CCDmaAddr_t  physBuffAddr)
+{
+    CC_UNUSED_PARAM(buffSize);
+    CC_UNUSED_PARAM(physBuffAddr);
+
+    return 0;
+}
+
+/**
+ * @brief   free system resources created in PD_PAL_DmaInit()
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ *
+ * @return void
+ */
+void CC_PalDmaTerminate(void)
+{
+    return;
+}
+
+#ifndef CC_IOT
+/**
+ * @brief   Maps a given buffer of any type. Returns the list of DMA-able blocks that the buffer maps to.
+ *
+ * @param[in] pDataBuffer -  Address of the buffer to map
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[in] copyDirection - Copy direction of the buffer. Can be TO_DEVICE, FROM_DEVICE or BI_DIRECTION
+ * @param[in/out] numOfBlocks - maximum numOfBlocks to fill, as output the actual number
+ * @param[out] pDmaBlockList - List of DMA-able blocks that the buffer maps to
+ * @param[out] dmaBuffHandle - A handle to the mapped buffer private resources
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaBufferMap(uint8_t                   *pDataBuffer,
+                 uint32_t                     buffSize,
+                 CCPalDmaBufferDirection_t  copyDirection,
+                 uint32_t                     *pNumOfBlocks,
+                 CCPalDmaBlockInfo_t        *pDmaBlockList,
+                 CC_PalDmaBufferHandle       *dmaBuffHandle)
+{
+
+    return (-1);
+}
+
+/**
+ * @brief   Unmaps a given buffer, and frees its associated resources, if exist
+ *
+ * @param[in] pDataBuffer -  Address of the buffer to map
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[in] copyDirection - Copy direction of the buffer. Can be TO_DEVICE, FROM_DEVICE or BI_DIRECTION
+ * @param[in] numOfBlocks - Number of DMA-able blocks that the buffer maps to
+ * @param[in] pDmaBlockList - List of DMA-able blocks that the buffer maps to
+ * @param[in] dmaBuffHandle - A handle to the mapped buffer private resources
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaBufferUnmap(uint8_t                     *pDataBuffer,
+                 uint32_t                     buffSize,
+                 CCPalDmaBufferDirection_t  copyDirection,
+                 uint32_t                     numOfBlocks,
+                 CCPalDmaBlockInfo_t        *pDmaBlockList,
+                 CC_PalDmaBufferHandle       dmaBuffHandle)
+{
+    return (-1);
+}
+
+
+
+/**
+ * @brief   Allocates a DMA-contiguous buffer, and returns both its physical and virtual addresses
+ *
+ *
+ * @param[in] buffSize - Buffer size in bytes
+ * @param[out] ppVirtBuffAddr - Virtual address of the allocated buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalDmaContigBufferAllocate(uint32_t          buffSize,
+                    uint8_t          **ppVirtBuffAddr)
+{
+    return (-1);
+}
+
+
+
+/**
+ * @brief   free resources previuosly allocated by CC_PalDmaContigBufferAllocate
+ *
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] pVirtBuffAddr - virtual address of the buffer to free
+ *
+ * @return success/fail
+ */
+uint32_t CC_PalDmaContigBufferFree(uint32_t          buffSize,
+                    uint8_t          *pVirtBuffAddr)
+{
+    return (-1);
+}
+
+
+/**
+ * @brief   Returns TRUE if the buffer is guaranteed to be a single contiguous DMA block, and FALSE otherwise.
+ *
+ *
+ * @param[in] pDataBuffer - User buffer address
+ * @param[in] buffSize - User buffer size
+ *
+ * @return Returns TRUE if the buffer is guaranteed to be a single contiguous DMA block, and FALSE otherwise.
+ */
+uint32_t CC_PalIsDmaBufferContiguous(uint8_t       *pDataBuffer,
+                      uint32_t       buffSize)
+{
+    return (-1);
+}
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_fips.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_fips.c
new file mode 100644
index 0000000..d61efd6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_fips.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+#include "cc_pal_fips.h"
+#include "cc_pal_mem.h"
+
+CCFipsStateData_t   gStateData = { CC_FIPS_STATE_CRYPTO_APPROVED, CC_TEE_FIPS_ERROR_OK, CC_FIPS_TRACE_NONE };
+
+
+CCError_t CC_PalFipsWaitForReeStatus(void)
+{
+    FipsSetReeStatus(CC_TEE_FIPS_REE_STATUS_OK);
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsStopWaitingRee(void)
+{
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsGetState(CCFipsState_t *pFipsState)
+{
+    *pFipsState = gStateData.state;
+
+    return CC_OK;
+}
+
+
+CCError_t CC_PalFipsGetError(CCFipsError_t *pFipsError)
+{
+    *pFipsError = gStateData.error;
+
+    return CC_OK;
+}
+
+
+CCError_t CC_PalFipsGetTrace(CCFipsTrace_t *pFipsTrace)
+{
+    *pFipsTrace = gStateData.trace;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetState(CCFipsState_t fipsState)
+{
+    gStateData.state = fipsState;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetError(CCFipsError_t fipsError)
+{
+    gStateData.error = fipsError;
+
+    return CC_OK;
+}
+
+CCError_t CC_PalFipsSetTrace(CCFipsTrace_t fipsTrace)
+{
+    gStateData.trace = (CCFipsTrace_t)(gStateData.trace | fipsTrace);
+
+    return CC_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_interrupt_ctrl.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_interrupt_ctrl.c
new file mode 100644
index 0000000..63f0a26
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_interrupt_ctrl.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files *************************************************/
+#include "cc_pal_types.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_interrupt_ctrl_plat.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "cc_hal.h"
+/************************ Defines ********************************************/
+
+/************************ Enums **********************************************/
+
+/************************ Typedefs *******************************************/
+
+/************************ Global Data ****************************************/
+
+/************************ Private Functions **********************************/
+
+/************************ Public Functions ***********************************/
+/**
+ * @brief
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalInitIrq(void)
+{
+    return CC_SUCCESS;
+}
+
+/**
+ * @brief This function removes the interrupt handler for
+ * cryptocell interrupts.
+ *
+ */
+void CC_PalFinishIrq(void)
+{
+}
+
+
+/*!
+ * Busy wait upon Interrupt Request Register (IRR) signals.
+ * This function notifys for any ARM CryptoCell interrupt, it is the caller responsiblity
+ * to verify and prompt the expected case interupt source.
+ *
+ * @param[in] data  - input data for future use
+ * \return  CCError_t   - CC_OK upon success
+ */
+CCError_t CC_PalWaitInterrupt( uint32_t data){
+    uint32_t irr = 0;
+    CCError_t error = CC_OK;
+
+    /* busy wait upon IRR signal */
+    do {
+        irr = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRR));
+        /* check APB bus error from HOST */
+        if( CC_REG_FLD_GET(0, HOST_IRR, AHB_ERR_INT, irr) == CC_TRUE){
+            error = CC_FAIL;
+            /*set data for clearing bus error*/
+            CC_REG_FLD_SET(HOST_RGF, HOST_ICR, AXI_ERR_CLEAR, data , 1);
+            break;
+        }
+    } while (!(irr & data));
+
+    /* clear interrupt */
+    CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_ICR), data); // IRR and ICR bit map is the same use data to clear interrupt in ICR
+
+    return error;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_log.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_log.c
new file mode 100644
index 0000000..e48917c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_log.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include "cc_pal_types.h"
+#include "cc_pal_log.h"
+#include <stdarg.h>
+
+int CC_PAL_logLevel = CC_PAL_MAX_LOG_LEVEL;
+uint32_t CC_PAL_logMask = 0xFFFFFFFF;
+
+void CC_PalLogInit(void)
+{
+}
+
+void CC_PalLogLevelSet(int setLevel)
+{
+    CC_PAL_logLevel = setLevel;
+}
+
+void CC_PalLogMaskSet(uint32_t setMask)
+{
+    CC_PAL_logMask = setMask;
+}
+
+void CC_PalLog(int level, const char * format, ...)
+{
+    va_list args;
+    CC_UNUSED_PARAM(level);
+    va_start( args, format );
+    vprintf(format, args);
+    va_end(args);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_mem.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_mem.c
new file mode 100644
index 0000000..b7086bf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_mem.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_error.h"
+#include "cc_pal_mem.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+
+/************************ Typedefs ******************************/
+
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to perform secured memory comparison between two given
+ *        buffers according to given size. The function will compare each byte till aSize
+ *        number of bytes was compared even if the bytes are different.
+ *        The function should be used to avoid security timing attacks.
+ *
+ *
+ * @param[in] aTarget - The target buffer to compare
+ * @param[in] aSource - The Source buffer to compare to
+ * @param[in] aSize - Number of bytes to compare
+ *
+ * @return The function will return CC_SUCCESS in case of success, else errors from
+ *         cc_pal_error.h will be returned.
+ */
+CCError_t CC_PalSecMemCmp(  const uint8_t* aTarget,
+                        const uint8_t* aSource,
+                        size_t  aSize       )
+{
+  /* internal index */
+  uint32_t i = 0;
+
+  /* error return */
+  uint32_t error = CC_SUCCESS;
+
+  /*------------------
+      CODE
+  -------------------*/
+
+  /* Go over aTarget till aSize is reached (even if its not equal) */
+  for (i = 0; i < aSize; i++)
+  {
+    if (aTarget[i] != aSource[i])
+    {
+      if (error != CC_SUCCESS)
+        continue;
+      else
+      {
+        if (aTarget[i] < aSource[i])
+          error = CC_PAL_MEM_BUF2_GREATER;
+        else
+          error = CC_PAL_MEM_BUF1_GREATER;
+      }
+    }
+  }
+
+  return error;
+}/* End of CC_PalSecMemCmp */
+
+
+int32_t CC_PalMemCmpPlat(  const void* aTarget, /*!< [in] The target buffer to compare. */
+                                  const void* aSource, /*!< [in] The Source buffer to compare to. */
+                                  size_t      aSize    /*!< [in] Number of bytes to compare. */)
+{
+    return memcmp(aTarget, aSource, aSize);
+
+}/* End of CC_PalMemCmpPlat */
+
+void* CC_PalMemCopyPlat(     void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                                      const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                                      size_t      aSize     /*!< [in] Number of bytes to copy. */ ){
+    return memmove( aDestination,  aSource, aSize);
+}/* End of CC_PalMemCopyPlat */
+
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ * This function Supports overlapped buffers.
+ *
+ * @return void.
+ */
+void CC_PalMemMovePlat(   void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                                  const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                                  size_t      aSize     /*!< [in] Number of bytes to copy. */)
+{
+    memmove(aDestination, aSource, aSize);
+}/* End of CC_PalMemMovePlat */
+
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with aChar.
+ *
+ * @return void.
+ */
+void CC_PalMemSetPlat(   void* aTarget, /*!< [out]  The target buffer to set. */
+                                 uint8_t aChar, /*!< [in] The char to set into aTarget. */
+                                 size_t        aSize  /*!< [in] Number of bytes to set. */)
+{
+    memset(aTarget, aChar, aSize);
+}/* End of CC_PalMemSetPlat */
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with zeroes.
+ *
+ * @return void.
+ */
+void CC_PalMemSetZeroPlat(    void* aTarget, /*!< [out]  The target buffer to set. */
+                                     size_t      aSize    /*!< [in] Number of bytes to set. */)
+{
+    memset(aTarget, 0x00, aSize);
+}/* End of CC_PalMemSetZeroPlat */
+
+/*!
+ * @brief This function purpose is to allocate a memory buffer according to aSize.
+ *
+ *
+ * @return The function returns a pointer to allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemMallocPlat(size_t  aSize /*!< [in] Number of bytes to allocate. */)
+{
+    return malloc(aSize);
+}/* End of CC_PalMemMallocPlat */
+
+/*!
+ * @brief This function purpose is to reallocate a memory buffer according to aNewSize.
+ *        The content of the old buffer is moved to the new location.
+ *
+ * @return The function returns a pointer to the newly allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemReallocPlat(  void* aBuffer,     /*!< [in] Pointer to allocated buffer. */
+                                     size_t  aNewSize   /*!< [in] Number of bytes to reallocate. */)
+{
+    return realloc(aBuffer, aNewSize);
+}/* End of CC_PalMemReallocPlat */
+
+/*!
+ * @brief This function purpose is to free allocated buffer.
+ *
+ *
+ * @return void.
+ */
+void CC_PalMemFreePlat(void* aBuffer /*!< [in] Pointer to allocated buffer.*/)
+{
+    free(aBuffer);
+}/* End of CC_PalMemFreePlat */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_memmap.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_memmap.c
new file mode 100644
index 0000000..73f2c84
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_memmap.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_memmap.h"
+
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to return the base virtual address that maps the
+ *        base physical address
+ *
+ * @param[in] physicalAddress - Starts physical address of the I/O range to be mapped.
+ * @param[in] mapSize - Number of bytes that were mapped
+ * @param[out] ppVirtBuffAddr - Pointer to the base virtual address to which the physical pages were mapped
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalMemMap(CCDmaAddr_t physicalAddress,
+                   uint32_t mapSize,
+               uint32_t **ppVirtBuffAddr)
+{
+    CC_UNUSED_PARAM(mapSize);
+    *ppVirtBuffAddr = (uint32_t *)physicalAddress;
+
+    return 0;
+}/* End of CC_PalMemMap */
+
+
+/**
+ * @brief This function purpose is to Unmaps a specified address range previously mapped
+ *        by CC_PalMemMap
+ *
+ *
+ * @param[in] pVirtBuffAddr - Pointer to the base virtual address to which the physical
+ *            pages were mapped
+ * @param[in] mapSize - Number of bytes that were mapped
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+uint32_t CC_PalMemUnMap(uint32_t *pVirtBuffAddr,
+                     uint32_t mapSize)
+{
+    CC_UNUSED_PARAM(pVirtBuffAddr);
+    CC_UNUSED_PARAM(mapSize);
+    return 0;
+}/* End of CC_PalMemUnMap */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_mutex.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_mutex.c
new file mode 100644
index 0000000..75ecb06
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_mutex.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+
+#include "cc_pal_mutex.h"
+/************************ Defines ******************************/
+
+/************************ Enums ******************************/
+
+/************************ Typedefs ******************************/
+
+/************************ Global Data ******************************/
+
+/************************ Private Functions ******************************/
+
+/************************ Public Functions ******************************/
+
+/**
+ * @brief This function purpose is to create a mutex.
+ *
+ *
+ * @param[out] pMutexId - Pointer to created mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexCreate(CC_PalMutex *pMutexId)
+{
+    CC_UNUSED_PARAM(pMutexId);
+        return 0;
+}
+
+
+/**
+ * @brief This function purpose is to destroy a mutex
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexDestroy(CC_PalMutex *pMutexId)
+{
+    CC_UNUSED_PARAM(pMutexId);
+    return 0;
+}
+
+
+/**
+ * @brief This function purpose is to Wait for Mutex with aTimeOut. aTimeOut is
+ *        specified in milliseconds. (CC_INFINITE is blocking)
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ * @param[in] timeOut - timeout in mSec, or CC_INFINITE
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexLock (CC_PalMutex *pMutexId, uint32_t timeOut)
+{
+    CC_UNUSED_PARAM(pMutexId);
+    CC_UNUSED_PARAM(timeOut);
+        return 0;
+}
+
+
+
+/**
+ * @brief This function purpose is to release the mutex.
+ *
+ *
+ * @param[in] pMutexId - pointer to Mutex handle
+ *
+ * @return returns 0 on success, otherwise indicates failure
+ */
+CCError_t CC_PalMutexUnlock (CC_PalMutex *pMutexId)
+{
+    CC_UNUSED_PARAM(pMutexId);
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_perf_plat.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_perf_plat.c
new file mode 100644
index 0000000..3e888cc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_perf_plat.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_perf.h"
+#include "cc_pal_perf_plat.h"
+#include "dx_reg_base_host.h"
+#include "dx_env.h"
+#include "cc_hal.h"
+#include "stdint.h"
+#include "cc_pal_mem.h"
+
+#define PERF_TRACE_CMPLT_BIT 0x80000000
+
+#define MAX_PERF_COUNT_ENTRIES 256
+
+#define PERF_LOG_ADDRESS  0x18001000
+
+
+/*!
+ * Read CryptoCell memory-mapped-IO Env register.
+ *
+ * \param regOffset The offset of the Env register to read
+ * \return uint32_t Return the value of the given register
+ */
+#define CC_PAL_PerfReadEnvRegister(regOffset)               \
+        (*((volatile uint32_t *)(DX_BASE_ENV_REGS + (regOffset))))
+
+/*!
+ * Write CryptoCell memory-mapped-IO Env register.
+ *
+ * \param regOffset The offset of the Env register to write
+ * \param val The value to write
+ */
+#define CC_PAL_PerfWriteEnvRegister(regOffset, val)         \
+        (*((volatile uint32_t *)(DX_BASE_ENV_REGS + (regOffset))) = (val))
+
+
+typedef struct {
+    unsigned int          countType;
+    unsigned int          countVal;
+}PalPerfCounter_t;
+
+
+uint8_t  *perfBuffAddr = (uint8_t *)PERF_LOG_ADDRESS;
+static uint8_t  perfBuffNextIdx = 0;
+
+#ifdef ARM_DSM
+/**
+ * @brief   initialize performance test mechanism
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfInit(void)
+{
+    CC_PAL_PerfWriteEnvRegister(DX_ENV_COUNTER_CLR_REG_OFFSET/*0x118*/, 0);
+    perfBuffNextIdx = 0;
+    CC_PalMemSetZero(perfBuffAddr, MAX_PERF_COUNT_ENTRIES * sizeof(PalPerfCounter_t));
+}
+
+
+/**
+ * @brief   terminates resources used for performance tests
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfFin(void)
+{
+    // nothing to be done
+}
+/**
+ * @brief   opens new entry in perf buffer to record new entry
+ *
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+CCPalPerfData_t CC_PalPerfOpenNewEntry(CCPalPerfType_t entryType)
+{
+    PalPerfCounter_t *counterEntry;
+    if (0 == perfBuffAddr){
+        return -2;
+    }
+
+    if(perfBuffNextIdx >= MAX_PERF_COUNT_ENTRIES) {
+        counterEntry = &(((PalPerfCounter_t *)perfBuffAddr)[MAX_PERF_COUNT_ENTRIES]);
+        counterEntry->countVal++;
+        return (-1);
+    }
+    counterEntry = &(((PalPerfCounter_t *)perfBuffAddr)[perfBuffNextIdx]);
+    counterEntry->countType = (entryType & ~(PERF_TRACE_CMPLT_BIT));
+    counterEntry->countVal = CC_PAL_PerfReadEnvRegister(DX_ENV_COUNTER_RD_REG_OFFSET/*0x11C*/);
+    return perfBuffNextIdx++;
+}
+
+
+/**
+ * @brief   closes entry in perf buffer previously opened by CC_PalPerfOpenNewEntry
+ *
+ * @param[in] idx -  index of the entry to be closed, the return value of CC_PalPerfOpenNewEntry
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+void CC_PalPerfCloseEntry(CCPalPerfData_t idx, CCPalPerfType_t entryType)
+{
+    PalPerfCounter_t *counterEntry;
+    uint32_t regVal;
+
+    if ((0 == perfBuffAddr) ||
+        (idx >= MAX_PERF_COUNT_ENTRIES)) {
+        return;
+    }
+    counterEntry = &(((PalPerfCounter_t *)perfBuffAddr)[idx]);
+    if(counterEntry->countType != (entryType & ~(PERF_TRACE_CMPLT_BIT))) {
+        counterEntry = &(((PalPerfCounter_t *)perfBuffAddr)[MAX_PERF_COUNT_ENTRIES]);
+        counterEntry->countType++;
+        return;
+    }
+
+    regVal = CC_PAL_PerfReadEnvRegister(DX_ENV_COUNTER_RD_REG_OFFSET/*0x11C*/);
+    counterEntry->countType |= PERF_TRACE_CMPLT_BIT;
+    counterEntry->countVal = (regVal-counterEntry->countVal);
+}
+
+
+/**
+ * @brief   dumps the performance buffer
+ *
+ * @param[in] None
+ *
+ * @return None
+ */
+void CC_PalPerfDump(void)
+{
+    uint32_t i;
+    PalPerfCounter_t *counterEntry;
+
+    if (0 == perfBuffAddr){
+        return;
+    }
+
+    counterEntry = &(((PalPerfCounter_t *)perfBuffAddr)[0]);
+    for (i=0; (i< MAX_PERF_COUNT_ENTRIES) && (counterEntry->countType != 0); i++) {
+        CC_PAL_PerfWriteEnvRegister(DX_ENV_DUMMY_ADDR_REG_OFFSET/*0x108*/, counterEntry->countType);
+        CC_PAL_PerfWriteEnvRegister(DX_ENV_DUMMY_ADDR_REG_OFFSET/*0x108*/, counterEntry->countVal);
+        counterEntry++;
+    }
+}
+
+
+/**
+ * @brief   DSM environment bug - sometimes very long write operation.
+ *     to overcome this bug we added while to make sure write opeartion is completed
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalDsmWorkarround()
+{
+    CCPalPerfData_t perfIdx = 0;
+    uint32_t tmpCount = 2000;
+
+    perfIdx = CC_PalPerfOpenNewEntry(PERF_TEST_TYPE_CMPLT_SLEEP);
+    while(tmpCount--);
+    CC_PalPerfCloseEntry(perfIdx, PERF_TEST_TYPE_CMPLT_SLEEP);
+}
+
+#else ARM_DSM
+/**
+ * @brief   initialize performance test mechanism
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfInit(void)
+{
+}
+
+
+/**
+ * @brief   terminates resources used for performance tests
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfFin(void)
+{
+}
+/**
+ * @brief   opens new entry in perf buffer to record new entry
+ *
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+CCPalPerfData_t CC_PalPerfOpenNewEntry(CCPalPerfType_t entryType)
+{
+}
+
+
+/**
+ * @brief   closes entry in perf buffer previously opened by CC_PalPerfOpenNewEntry
+ *
+ * @param[in] idx -  index of the entry to be closed, the return value of CC_PalPerfOpenNewEntry
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+void CC_PalPerfCloseEntry(CCPalPerfData_t idx, CCPalPerfType_t entryType)
+{
+}
+
+
+/**
+ * @brief   dumps the performance buffer
+ *
+ * @param[in] None
+ *
+ * @return None
+ */
+void CC_PalPerfDump(void)
+{
+}
+#endif // ARM_DSM
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_pm.c b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_pm.c
new file mode 100644
index 0000000..7eb5c6b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/no_os/cc_pal_pm.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "cc_pal_types.h"
+
+
+void CC_PalPowerSaveModeInit(void)
+{
+    return;
+}
+
+void CC_PalPowerSaveModeStatus(void)
+{
+    return;
+}
+
+CCError_t CC_PalPowerSaveModeSelect(CCBool isPowerSaveMode)
+{
+    CC_UNUSED_PARAM(isPowerSaveMode);
+
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/pal/project_pal.mk b/lib/ext/cryptocell-312-runtime/host/src/pal/project_pal.mk
new file mode 100644
index 0000000..bebae14
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/pal/project_pal.mk
@@ -0,0 +1,50 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+CFLAGS_EXTRA += -DCC_IOT
+
+SOURCES_pal_$(PLAT_OS) += cc_pal.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_mutex.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_memmap.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_dma.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_pm.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_interrupt_ctrl.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_mem.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_buff_attr.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_abort_plat.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_trng.c
+SOURCES_pal_$(PLAT_OS) += cc_pal_apbc.c
+
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal/$(PLAT_OS)
+
+INCDIRS_EXTRA +=  $(SHARED_DIR)/hw/include # for dx_reg_base_host.h, included in cc_pal.c
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal # for cc_pal_interrupt_ctrl.c
+
+ifeq ($(ARCH),arm)
+ifeq ($(CROSS_COMPILE),arm-none-eabi-)
+ifeq ($(ARM_CPU), cortex-m33)
+CFLAGS += -DSSE_200
+endif
+endif
+endif
+
+ifeq ($(DEBUG),1)
+   SOURCES_pal_$(PLAT_OS) += cc_pal_log.c
+   CFLAGS += -DDEBUG
+endif
+
+$(info TRNG: CC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE))
+CFLAGS_EXTRA += -DCC_CONFIG_TRNG_MODE=$(CC_CONFIG_TRNG_MODE)
+
+ifeq ($(LIB_PERF),1)
+SOURCES_pal_$(PLAT_OS) += cc_pal_perf_plat.c
+CFLAGS += -DLIB_PERF
+endif
+
+VPATH += $(HOST_SRCDIR)/pal $(HOST_SRCDIR)/pal/$(PLAT_OS)
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/Makefile b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/Makefile
new file mode 100755
index 0000000..193027e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/Makefile
@@ -0,0 +1,252 @@
+# ******************************************************************************
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# ******************************************************************************
+
+# ************
+# Project Name
+# ************
+PROJECT_NAME	= TestAL
+
+# ***********
+# Executables
+# ***********
+RM		= rm -f
+ECHO		= echo
+MKDIR		= mkdir -p
+RMDIR		= rm -rf
+CP		= cp -R
+MV		= mv
+
+# ****************
+# Path Definitions
+# ****************
+PAL_DIR		= $(CURDIR)/pal
+HAL_DIR		= $(CURDIR)/hal
+CONFIGS_DIR	= $(CURDIR)/configs
+
+# ****************
+# Config Files
+# ****************
+PROJ_CFG_PATH	= proj.cfg
+
+ifeq ($(wildcard $(PROJ_CFG_PATH)),$(PROJ_CFG_PATH))
+include $(PROJ_CFG_PATH)
+endif
+
+# ********
+# Includes
+# ********
+INCLUDES_PAL	= $(PAL_DIR)/include
+INCLUDES_HAL	= $(HAL_DIR)/include
+
+ifeq ($(OS),linux)
+INCLUDES	= $(INCLUDES_PAL) $(if $(findstring target,$(DEVICE)), $(INCLUDES_HAL))
+
+else ifeq ($(OS),freertos)
+INCLUDES 	= $(INCLUDES_PAL) $(INCLUDES_HAL)
+
+COMPILER_TYPE_DIR = $(shell echo $(COMPILER_TYPE) | tr a-z A-Z)
+INCLUDES_FREERTOS = $(KERNEL_DIR)/OS/FreeRTOS/Source/include
+INCLUDES_FREERTOS += $(KERNEL_DIR)/OS/FreeRTOS/Source/portable/$(COMPILER_TYPE_DIR)/ARM_$(CORTEX_SHORT)
+INCLUDES_FREERTOS += $(KERNEL_DIR)/OS/FreeRTOS-Plus-CLI
+INCLUDES_FREERTOS += $(KERNEL_DIR)/OS/FreeRTOS-Plus-TCP/include
+INCLUDES_FREERTOS += $(KERNEL_DIR)/OS/FreeRTOS-Plus-TCP/portable/Compiler/$(COMPILER_TYPE_DIR)
+INCLUDES_FREERTOS += $(KERNEL_DIR)/boards/$(BOARD)
+INCLUDES_FREERTOS += $(KERNEL_DIR)/boards/$(BOARD)/$(CMSIS_DRIVER)
+INCLUDES_EXTRA	= $(INCLUDES_FREERTOS)
+
+else ifeq ($(OS),mbedos)
+INCLUDES 	= $(INCLUDES_PAL) $(INCLUDES_HAL)
+
+INCLUDES_MBEDOS	= $(KERNEL_DIR)/rtos/rtx5/TARGET_CORTEX_M
+INCLUDES_MBEDOS	+= $(KERNEL_DIR)/platform
+INCLUDES_EXTRA	= $(INCLUDES_MBEDOS)
+
+else ifeq ($(OS),no_os)
+INCLUDES 	= $(INCLUDES_PAL) $(INCLUDES_HAL)
+INCLUDES_EXTRA 	= $(PAL_DIR)/$(OS)
+
+endif
+
+# **************
+# Make variables
+# **************
+ifeq ($(COMPILER_TYPE), armcc)
+CC 		= armcc
+LD 		= armlink
+AR		= armar
+AS 		= armasm
+
+else ifeq ($(COMPILER_TYPE), armclang)
+CC 		= armclang
+LD 		= armlink
+AR		= armar
+AS 		= armclang
+
+else ifeq ($(COMPILER_TYPE), gcc)
+CXX		= $(CROSS_COMPILE)g++
+CC		= $(CROSS_COMPILE)gcc
+LD		= $(CROSS_COMPILE)ld
+AR		= $(CROSS_COMPILE)ar
+AS		= $(CROSS_COMPILE)as
+endif
+
+# ****************
+# Project Definitions
+# ****************
+SRCS_PAL	= $(shell find $(PAL_DIR)/$(OS) -name '*.c' | grep -v malloc.c)
+SRCS_HAL	= $(shell find $(HAL_DIR)/$(BOARD) -name '*.c')
+
+OBJS_PAL	= $(SRCS_PAL:.c=.o)
+OBJS_HAL	= $(SRCS_HAL:.c=.o)
+
+BIN_PAL		= libPAL__$(OS)__$(CC)__$(shell echo $(CORTEX_SHORT) | tr A-Z a-z).a
+BIN_HAL		= libHAL__$(OS)__$(CC)__$(shell echo $(CORTEX_SHORT) | tr A-Z a-z).a
+
+# *****
+# Flags
+# *****
+ifeq ($(COMPILER_TYPE), armcc)
+CFLAGS		+= --cpu=$(CORTEX)
+CFLAGS		+= --thumb
+CFLAGS		+= -DTEST_DEBUG
+CFLAGS		+= -DCMSDK_$(CORTEX_SHORT)
+CFLAGS		+= -D__CC_ARM -DFPGA_IMAGE
+CFLAGS		+= -DportREMOVE_STATIC_QUALIFIER
+CFLAGS		+= -DINCLUDE_xTaskGetIdleTaskHandle=1
+CFLAGS		+= -DconfigQUEUE_REGISTRY_SIZE=8
+CFLAGS		+= -DDX_PLAT_MPS2_PLUS
+CFLAGS		+= -O0 -g
+CFLAGS		+= -DCC_TEE -DCC_IOT -DCC_REE
+CFLAGS		+= $(foreach incdir, $(INCLUDES), -I$(incdir))
+CFLAGS		+= $(foreach incdir, $(INCLUDES_EXTRA), -I$(incdir))
+
+CFLAGS		+= $(if $(findstring freertos,$(OS)), -D$(CMSIS_DRIVER))
+
+ARFLAGS		= -rcs
+
+else ifeq ($(COMPILER_TYPE), armclang)
+LDFLAGS		+= --cpu=$(CORTEX)
+LDFLAGS		+= --map --verbose
+LDFLAGS		+= --list=$(PROJ_NAME).map
+LDFLAGS		+= --entry=Reset_Handler
+LDFLAGS		+= --dangling_debug_address 0xF0000000 # Moves unneeded debug sections
+
+CFLAGS		+= --target=arm-arm-none-eabi
+CFLAGS		+= $(if $(strip $(M_ARCH)),-march=$(M_ARCH),-mcpu=$(CORTEX))
+CFLAGS		+= -mlittle-endian
+CFLAGS		+= -xc -O0 -g -Wno-pragma-pack
+CFLAGS		+= -mthumb
+CFLAGS		+= $(if $(findstring 1,$(TZM)), -mcmse -DTZM) # Supports CMSE
+CFLAGS		+= -DCORTEX_$(CORTEX_SHORT)
+CFLAGS		+= -D$(CMSIS_DRIVER)
+CFLAGS		+= -DARM$(CORTEX_SHORT)
+CFLAGS		+= -DconfigQUEUE_REGISTRY_SIZE=8U
+CFLAGS		+= -DCC_TEE -DDX_PLAT_MPS2_PLUS
+CFLAGS		+= $(if $(findstring SSE_200,$(CMSIS_DRIVER)), -mfpu=none)
+CFLAGS		+= $(if $(findstring SSE_200,$(CMSIS_DRIVER)), -mcmse)
+CFLAGS		+= $(foreach incdir, $(INCLUDES), -I$(incdir))
+CFLAGS		+= $(foreach incdir, $(INCLUDES_EXTRA), -I$(incdir))
+
+ARFLAGS		= -rcs
+
+else # aarch64-linux-gnu- , arm-xilinx-linux-gnueabi- , arm-none-eabi-, arm-buildroot-linux-gnueabi-,
+# aarch64-buildroot-linux-gnu- and native
+CFLAGS		+= $(if $(findstring target,$(DEVICE)), \
+		   $(if $(strip $(M_ARCH)),-march=$(M_ARCH),-mcpu=$(CORTEX)),)
+CFLAGS		+= -DTEST_DEBUG  -DLITTLE__ENDIAN -DHASLONGLONG
+CFLAGS		+= -Wall -Wsign-compare -Wextra
+CFLAGS		+= -Wstrict-prototypes -Wwrite-strings
+CFLAGS		+= -Wswitch-default -Wunreachable-code
+CFLAGS		+= -Winit-self -Wjump-misses-init -Wlogical-op
+CFLAGS		+= -o2 -g
+CFLAGS		+= $(if $(findstring 1,$(TZM)), -mcmse -DTZM) # Supports CMSE
+
+CFLAGS		+= $(foreach incdir, $(INCLUDES), -I$(incdir))
+CFLAGS		+= $(foreach incdir, $(INCLUDES_EXTRA), -I$(incdir))
+
+CFLAGS		+= $(if $(findstring freertos,$(OS)), -D$(CMSIS_DRIVER))
+
+CFLAGS		+= $(if $(findstring mbedos,$(OS)), -Wno-missing-field-initializers, -Wmissing-field-initializers)
+CFLAGS		+= $(if $(findstring mbedos,$(OS)), -Wno-unused-parameter)
+CFLAGS		+= $(if $(findstring mbedos,$(OS)), -DMBED_DEBUG -DMBED_TRAP_ERRORS_ENABLED=1)
+CFLAGS		+= $(if $(findstring mbedos,$(OS)), -std=gnu99 -c)
+CFLAGS		+= $(if $(findstring mbedos,$(OS)), -fmessage-length=0 -fno-exceptions -fno-builtin)
+CFLAGS		+= $(if $(findstring mbedos,$(OS)), -ffunction-sections -fdata-sections -funsigned-char)
+CFLAGS		+= $(if $(findstring mbedos,$(OS)), -fno-delete-null-pointer-checks -fomit-frame-pointer)
+
+ARFLAGS		= -rcs
+endif
+
+# ****************
+# Build Operations
+# ****************
+############ Special rules for configuration selection ##############
+ifneq ($(wildcard $(PROJ_CFG_PATH)),$(PROJ_CFG_PATH))
+
+all: # default in case there is no proj.cfg and setconfig_ was not used
+	$(info Invoke 'make setconfig_<config. name>' to select project configuration )
+
+setconfig_%: $(CONFIGS_DIR)/proj-%.cfg
+	$(info [CFG] $< --> $(PROJ_CFG_PATH))
+	@ln -s $< $(PROJ_CFG_PATH)
+
+$(CONFIGS_DIR)/proj-%.cfg:
+	@$(info Unknown project configuration. $@ does not exist.)
+	@exit 1;
+
+clrconfig:
+	$(info No active configuration )
+
+############ Special rules for project configuration selection ##############
+else
+
+all : check_var print_var pal $(if $(findstring target,$(DEVICE)),hal) passed
+
+check_var: guard-OS guard-CORTEX\
+$(if $(findstring target,$(DEVICE)),guard-CROSS_COMPILE guard-BOARD) \
+$(if $(findstring freertos,$(OS)),guard-KERNEL_DIR) \
+$(if $(findstring mbedos,$(OS)),guard-KERNEL_DIR)
+
+guard-%:
+	@ if [ "${${*}}" = "" ]; then \
+	echo "$* is undefined"; \
+	exit 1; \
+	fi
+
+print_var:
+	@echo "\033[42m*********************************************\033[0m"
+	@echo "\033[42m board[$(BOARD)] device[$(DEVICE)] OS[$(OS)] \033[0m"
+	@echo "\033[42m*********************************************\033[0m"
+
+pal: $(OBJS_PAL)
+	$(AR) $(ARFLAGS) $(BIN_PAL) $(OBJS_PAL)
+
+hal: $(OBJS_HAL)
+	$(AR) $(ARFLAGS) $(BIN_HAL) $(OBJS_HAL) $(PAL_BIN)
+
+passed:
+	@echo "\033[42m***************\033[0m"
+	@echo "\033[42m* P A S S E D *\033[0m"
+	@echo "\033[42m***************\033[0m"
+
+clrconfig:
+	$(RM) $(PROJ_CFG_PATH)
+
+
+
+endif
+
+clean:
+	$(shell find . -name '*.d' -delete)
+	$(shell find . -name '*.o' -delete)
+
+distclean: clrconfig clean
+	$(shell find . -name '*.a' -delete)
+	$(RMDIR) $(shell find $(HAL_DIR) -name 'includes*')
+	$(RMDIR) Release
+
+# END PAL Makefile
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/ReadMe.txt b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/ReadMe.txt
new file mode 100755
index 0000000..d41a422
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/ReadMe.txt
@@ -0,0 +1,29 @@
+********** Building Process **********
+There are two ways to build the TestAL libraries:
+
+1. USING build_config.sh
+
+	1. Export KERNEL_DIR in case of mbedOS or FreeRTOS.
+	2. Run the build_config.sh script, with or without a configuration number.
+	3. The static libraries will be located in the project directory.
+
+2. BUILDING MANUALLY
+	1. Configure the toolchain.
+	2. Run "make distclean".
+	3. Run "make setconfig_testal_<OS>_<TARGET>"
+	4. Run "make"
+	5. The static libraries will be located in the project directory.
+
+********** Cleaning Process **********
+For cleaning object files, config file and static libraries:
+	1. Run “make distclean".
+
+For cleaning object files:
+	1. Run “make clean".
+
+For cleaning the current config file:
+	1. Run "make clrconfig".
+
+--------------
+
+Copyright (c) 2001-2019, Arm Limited. All rights reserved.
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/build_config.sh b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/build_config.sh
new file mode 100755
index 0000000..823f29c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/build_config.sh
@@ -0,0 +1,118 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#!/bin/bash
+
+# This script defines only the necessary environment variables for TestAL makefile.
+# Note that it does not run our internal script set_toolchain.sh as it is
+# supposed to be used by external users (e.g. costumers) or another projects
+# makefiles, which usually configures their own environment.
+
+choice=$1
+
+SUPPORTED_CONFIGURATIONS="SUPPORTED CONFIGURATIONS
+|----------------------------------------------------------------------|
+|ConfNum|    OS    |    CPU     |      Toolchain      | Device | Board |
+|----------------------------------------------------------------------|
+|   1   |  linux   | cortex-a9  |      arm-xilinx     | target | Zynq  |
+|   2   |          |            |     Deprecated      |        |       |
+|   3   |  linux   |    x86     |        native       |  host  |       |
+|   4   | freertos | cortex-m3  |    arm-compiler-5   | target | MPS2+ |
+|   5   |          |            |     Deprecated      |        |       |
+|   6   |  no_os   | cortex-m3  |    arm-compiler-5   | target | MPS2+ |
+|   7   | freertos | cortex-m33 |     arm-none-eabi   | target | MPS2+ |
+|   8   |  linux   | cortex-a9  |      arm-br-7.3     | target | Zynq  |
+|   9   | freertos | cortex-m3  |     arm-none-eabi   | target | MPS2+ |
+|   10  |  linux   |  a72 a53   |    aarch64-br-7.3   | target | Juno  |
+|   11  | freertos | cortex-m33 |    arm-compiler-6   | target | MPS2+ |
+|   12  | freertos | cortex-m3  |    arm-compiler-6   | target | MPS2+ |
+|----------------------------------------------------------------------|
+
+There is an option to run this script with ConfNum as an argument.
+
+Please enter your choice: "
+
+if [ -z $1 ]; then echo "$SUPPORTED_CONFIGURATIONS"; read choice; fi
+
+make clean
+make clrconfig
+
+case $choice in
+1)
+#set_toolchain arm-xilinx-14.7
+make setconfig_testal_linux_ca9
+;;
+2)
+echo "Deprecated configuration!"
+exit 0;
+;;
+3)
+#set_toolchain native
+make setconfig_testal_linux_x86
+;;
+4)
+#set_toolchain arm-compiler-5
+make setconfig_testal_freertos_cm3
+if [ -z $KERNEL_DIR ]; then echo "Please enter freertos KERNEL_DIR path:"; read KERNEL_DIR;
+export KERNEL_DIR; fi
+;;
+5)
+echo "Deprecated configuration!"
+exit 0;
+;;
+6)
+#set_toolchain arm-compiler-5
+make setconfig_testal_no_os_cm3
+;;
+7)
+#set_toolchain arm-none-eabi
+make setconfig_testal_freertos_cm33
+if [ -z $KERNEL_DIR ]; then echo "Please enter freertos KERNEL_DIR path:"; read KERNEL_DIR;
+export KERNEL_DIR; fi
+;;
+8)
+#set_toolchain arm-br-7.3
+make setconfig_testal_linux_ca9
+;;
+9)
+#set_toolchain arm-none-eabi
+make setconfig_testal_freertos_cm3
+if [ -z $KERNEL_DIR ]; then echo "Please enter freertos KERNEL_DIR path:"; read KERNEL_DIR;
+export KERNEL_DIR; fi
+;;
+10)
+#set_toolchain aarch64-br-7.3
+make setconfig_testal_linux_ca72.ca53
+;;
+11)
+#set_toolchain arm-compiler-6
+make setconfig_testal_freertos_cm33
+;;
+12)
+#set_toolchain arm-compiler-6
+make setconfig_testal_freertos_cm3
+;;
+*)
+echo "Configuration number $1 is undefined"
+exit 1;
+;;
+esac
+
+echo
+
+make
+if [ $? -gt 0 ]; then
+	status=1
+	echo -e "\033[1;41m========\033[0m"
+	echo -e "\033[1;41m= FAIL =\033[0m"
+	echo -e "\033[1;41m========\033[0m"
+	exit 1
+fi
+make clean
+make clrconfig
+
+echo
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_freertos_cm3.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_freertos_cm3.cfg
new file mode 100644
index 0000000..6e6c784
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_freertos_cm3.cfg
@@ -0,0 +1,26 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Configuration: freertos_cm3
+# Supported Toolchains: arm-compiler-5, arm-compiler-6, arm-none-eabi
+
+OS=freertos
+
+DEVICE=target
+BOARD=MPS2+
+
+# M_ARCH specifies a target architecture. If empty, target is
+# determined by CORTEX
+M_ARCH=
+
+CMSIS_DRIVER=ARMCM3
+CORTEX=cortex-m3
+CORTEX_SHORT=CM3
+
+# TZM indicates whether the configuration supports TrustZone-M or not.
+# By default, TZM equals to 0.
+TZM=0
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_freertos_cm33.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_freertos_cm33.cfg
new file mode 100644
index 0000000..e742b83
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_freertos_cm33.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Configuration: freertos_cm33
+# Supported Toolchains: arm-none-eabi arm-compiler-6
+
+OS=freertos
+
+CC_TYPE=GCC
+
+DEVICE=target
+BOARD=MPS2+
+
+CMSIS_DRIVER=SSE_200
+M_ARCH=armv8-m.main
+CORTEX=8-M.Main
+CORTEX_SHORT=CM33
+
+# TZM indicates whether the configuration supports TrustZone-M or not.
+# By default, TZM equals to 0.
+TZM=1
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_ca72.ca53.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_ca72.ca53.cfg
new file mode 100644
index 0000000..d730e2a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_ca72.ca53.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Configuration: linux_ca72.ca53
+# Supported Toolchains: aarch64-linaro-5.3 , aarch64-br-7.3
+
+OS=linux
+
+DEVICE=target
+BOARD=Juno
+
+CORTEX=cortex-a72.cortex-a53
+CORTEX_SHORT=CA72.CA53
+
+# TZM indicates whether the configuration supports TrustZone-M or not.
+# By default, TZM equals to 0.
+TZM=0
+
+# M_ARCH specifies a target architecture. If empty, target is
+# determined by CORTEX
+M_ARCH=
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_ca9.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_ca9.cfg
new file mode 100644
index 0000000..f587e32
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_ca9.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Configuration: linux_ca9
+# Supported Toolchains: arm-xilinx , arm-br-7.3
+
+OS=linux
+
+DEVICE=target
+BOARD=Zynq
+
+CORTEX=cortex-a9
+CORTEX_SHORT=CA9
+
+# TZM indicates whether the configuration supports TrustZone-M or not.
+# By default, TZM equals to 0.
+TZM=0
+
+# M_ARCH specifies a target architecture. If empty, target is
+# determined by CORTEX
+M_ARCH=
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_x86.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_x86.cfg
new file mode 100644
index 0000000..ca5f9be
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_linux_x86.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Configuration: linux_x86
+# Supported Toolchains: native
+
+OS=linux
+
+DEVICE=host
+BOARD=
+
+CORTEX=x86
+CORTEX_SHORT=x86
+
+# TZM indicates whether the configuration supports TrustZone-M or not.
+# By default, TZM equals to 0.
+TZM=0
+
+# M_ARCH specifies a target architecture. If empty, target is
+# determined by CORTEX
+M_ARCH=
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_mbedos_cm33.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_mbedos_cm33.cfg
new file mode 100644
index 0000000..8c65f0b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_mbedos_cm33.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Configuration: mbedos_cm33
+# Supported Toolchains: arm-none-eabi
+
+OS=mbedos
+
+DEVICE=target
+BOARD=MPS2+
+
+CORTEX=cortex-m33
+CORTEX_SHORT=CM33
+
+# TZM indicates whether the configuration supports TrustZone-M or not.
+# By default, TZM equals to 0.
+TZM=0
+
+# M_ARCH specifies a target architecture. If empty, target is
+# determined by CORTEX
+M_ARCH=
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_no_os_cm3.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_no_os_cm3.cfg
new file mode 100644
index 0000000..692697b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/configs/proj-testal_no_os_cm3.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Configuration: no_os_cm3
+# Supported Toolchains: arm-compiler-5
+
+OS=no_os
+
+DEVICE=target
+BOARD=MPS2+
+
+CORTEX=cortex-m3
+CORTEX_SHORT=CM3
+
+# TZM indicates whether the configuration supports TrustZone-M or not.
+# By default, TZM equals to 0.
+TZM=0
+
+# M_ARCH specifies a target architecture. If empty, target is
+# determined by CORTEX
+M_ARCH=
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/Juno/board_configs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/Juno/board_configs.c
new file mode 100644
index 0000000..6b505c5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/Juno/board_configs.c
@@ -0,0 +1,90 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "board_configs.h"
+
+#include "test_pal_mem.h"
+#include "test_pal_map_addrs.h"
+#include "test_pal_log.h"
+
+#define TEST_HAL_MEM_DMA_BASE_ADDR      0x8A1000000
+#define TEST_HAL_MEM_UNMANAGED_BASE_ADDR    0x8B0000000
+#define TEST_HAL_MEM_DMA_AREA_LEN       0x00F000000 /* 240MB */
+#define TEST_HAL_MEM_UNMANAGED_AREA_LEN     0x000100000 /* 1MB */
+
+/******************************************************************************/
+uint32_t Test_HalBoardInit(void)
+{
+    unsigned long DMABaseAddr;
+    unsigned long unmanagedBaseAddr;
+
+    /* maps the DMA base address */
+    DMABaseAddr = (unsigned long)Test_PalMapAddr(
+                (void *)TEST_HAL_MEM_DMA_BASE_ADDR,
+                 (void *)TEST_HAL_MEM_DMA_BASE_ADDR,
+                 "/dev/cc_linux_driver",
+                 TEST_HAL_MEM_DMA_AREA_LEN,
+                 BM_READ|BM_WRITE|BM_EXEC|BM_SHARED|BM_FIXED);
+
+    if (!VALID_MAPPED_ADDR(DMABaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for DMABaseAddr\n");
+        goto end_with_error;
+    }
+
+    TEST_PRINTF("DMABaseAddr = 0x%lx\n", DMABaseAddr);
+
+    /* maps the unmanaged memory base address */
+    unmanagedBaseAddr = (unsigned long)Test_PalMapAddr(
+                 (void *)TEST_HAL_MEM_UNMANAGED_BASE_ADDR,
+                 (void *)TEST_HAL_MEM_UNMANAGED_BASE_ADDR,
+                 "/dev/cc_linux_driver",
+                 TEST_HAL_MEM_UNMANAGED_AREA_LEN,
+                 BM_READ|BM_WRITE|BM_EXEC|BM_SHARED|BM_FIXED);
+
+    if (!VALID_MAPPED_ADDR(unmanagedBaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for unmanagedBaseAddr\n");
+        goto end_with_error;
+    }
+    TEST_PRINTF("unmanagedBaseAddr = 0x%lx\n", unmanagedBaseAddr);
+
+    if (Test_PalMemInit(DMABaseAddr, unmanagedBaseAddr,
+                TEST_HAL_MEM_DMA_AREA_LEN)) {
+        TEST_PRINTF_ERROR("Error: MemInit failed\n");
+        goto end_with_error;
+    }
+
+    return 0;
+
+    end_with_error:
+    Test_HalBoardFree();
+    return 1;
+}
+
+/******************************************************************************/
+void Test_HalBoardFree(void)
+{
+    if (Test_PalGetDMABaseAddr() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetDMABaseAddr(),
+                TEST_HAL_MEM_DMA_AREA_LEN);
+    }
+
+    if (Test_PalGetUnmanagedBaseAddr() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetUnmanagedBaseAddr(),
+                TEST_HAL_MEM_UNMANAGED_AREA_LEN);
+    }
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/MPS2+/board_configs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/MPS2+/board_configs.c
new file mode 100644
index 0000000..ee746c3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/MPS2+/board_configs.c
@@ -0,0 +1,138 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Located in kernel directory */
+#include "board_addrs.h"
+
+#include "board_configs.h"
+#include "test_pal_mem.h"
+#include "test_pal_map_addrs.h"
+#include "test_pal_log.h"
+
+#ifdef TZM
+#include "test_pal_mem_s.h"
+#endif
+
+/******************************************************************************/
+uint32_t Test_HalBoardInit(void)
+{
+    unsigned long DMABaseAddr;
+    unsigned long unmanagedBaseAddr;
+#ifdef TZM
+    unsigned long DMABaseAddr_s;
+#endif
+
+    /* maps the unmanaged memory base address */
+    unmanagedBaseAddr = (unsigned long)Test_PalMapAddr(
+                (void *)MPS2_GetUnmanagedbaseAddr(),
+                NULL, NULL, 0, 0);
+
+    if (!VALID_MAPPED_ADDR(unmanagedBaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for unmanagedBaseAddr\n");
+        goto end_with_error;
+    }
+    TEST_PRINTF("unmanagedBaseAddr = 0x%lx\n", unmanagedBaseAddr);
+
+#ifndef TZM
+    /* maps the DMA base address */
+    DMABaseAddr = (unsigned long)Test_PalMapAddr(
+                (void *)MPS2_GetDMAbaseAddr(),
+                NULL, NULL, 0, 0);
+
+    if (!VALID_MAPPED_ADDR(DMABaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for DMABaseAddr\n");
+        goto end_with_error;
+    }
+
+    TEST_PRINTF("DMABaseAddr = 0x%lx\n", DMABaseAddr);
+
+    if (Test_PalMemInit(DMABaseAddr, unmanagedBaseAddr,
+                MPS2_GetDMAAreaLen())) {
+        TEST_PRINTF_ERROR("Error: MemInit failed\n");
+        goto end_with_error;
+    }
+
+#else
+    /* maps secure DMA base address */
+    DMABaseAddr_s = (unsigned long)Test_PalMapAddr(
+            (void *)MPS2_Get_S_DMAbaseAddr(),
+            NULL, NULL, 0, 0);
+
+    TEST_PRINTF("DMABaseAddr_s = 0x%lx\n", DMABaseAddr_s);
+
+    if (Test_PalMemInit_s(DMABaseAddr_s, unmanagedBaseAddr,
+                MPS2_Get_S_DMAAreaLen())) {
+        TEST_PRINTF_ERROR("Error: Secure MemInit failed\n");
+        goto end_with_error;
+    }
+
+    /* maps non-secure DMA base address */
+    DMABaseAddr = (unsigned long)Test_PalMapAddr(
+            (void *)MPS2_Get_NS_DMAbaseAddr(),
+            NULL, NULL, 0, 0);
+
+    TEST_PRINTF("DMABaseAddr_ns = 0x%lx\n", DMABaseAddr);
+
+    if (Test_PalMemInit(DMABaseAddr, 0,
+                MPS2_Get_NS_DMAAreaLen())) {
+        TEST_PRINTF_ERROR("Error: non-secure MemInit failed\n");
+        goto end_with_error;
+    }
+#endif
+
+    return 0;
+
+    end_with_error:
+    Test_HalBoardFree();
+    return 1;
+}
+
+/******************************************************************************/
+void Test_HalBoardFree(void)
+{
+#ifndef TZM
+    /* Unmaps DMA base address and unmanaged memory base address */
+    if (Test_PalGetUnmanagedBaseAddr() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetUnmanagedBaseAddr(),
+                MPS2_GetUnmanagedAreaLen());
+    }
+
+    if (Test_PalGetDMABaseAddr() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetDMABaseAddr(),
+                MPS2_GetDMAAreaLen());
+    }
+
+#else
+    /* Unmaps secure DMA base address and unmanaged memory base address */
+    if (Test_PalGetUnmanagedBaseAddr_s() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetUnmanagedBaseAddr_s(),
+                MPS2_GetUnmanagedAreaLen());
+    }
+
+    if (Test_PalGetDMABaseAddr_s() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetDMABaseAddr_s(),
+                MPS2_Get_S_DMAAreaLen());
+    }
+
+    /* Unmaps non-secure DMA base address */
+    if (Test_PalGetDMABaseAddr() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetDMABaseAddr(),
+                MPS2_Get_NS_DMAAreaLen());
+    }
+
+#endif
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/Zynq/board_configs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/Zynq/board_configs.c
new file mode 100644
index 0000000..65b9204
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/Zynq/board_configs.c
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "board_configs.h"
+
+#include "test_pal_mem.h"
+#include "test_pal_map_addrs.h"
+#include "test_pal_log.h"
+
+#define TEST_HAL_MEM_DMA_BASE_ADDR      0x30100000
+#define TEST_HAL_MEM_UNMANAGED_BASE_ADDR    0x30000000
+#define TEST_HAL_MEM_DMA_AREA_LEN       0x0F000000  /* 240MB */
+#define TEST_HAL_MEM_UNMANAGED_AREA_LEN     0x00100000  /* 1MB */
+
+/******************************************************************************/
+uint32_t Test_HalBoardInit(void)
+{
+    unsigned long DMABaseAddr;
+    unsigned long unmanagedBaseAddr;
+
+    /* maps the DMA base address */
+    DMABaseAddr = (unsigned long)Test_PalMapAddr(
+                 (void *)TEST_HAL_MEM_DMA_BASE_ADDR,
+                 (void *)TEST_HAL_MEM_DMA_BASE_ADDR,
+                 "/dev/mem",
+                 TEST_HAL_MEM_DMA_AREA_LEN,
+                 BM_READ|BM_WRITE|BM_EXEC|BM_SHARED|BM_FIXED);
+
+    if (!VALID_MAPPED_ADDR(DMABaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for DMABaseAddr\n");
+        goto end_with_error;
+    }
+
+    TEST_PRINTF("DMABaseAddr = 0x%lx\n", DMABaseAddr);
+
+    /* maps the unmanaged memory base address */
+    unmanagedBaseAddr = (unsigned long)Test_PalMapAddr(
+                 (void *)TEST_HAL_MEM_UNMANAGED_BASE_ADDR,
+                 (void *)TEST_HAL_MEM_UNMANAGED_BASE_ADDR,
+                 "/dev/mem",
+                 TEST_HAL_MEM_UNMANAGED_AREA_LEN,
+                 BM_READ|BM_WRITE|BM_EXEC|BM_SHARED|BM_FIXED);
+
+    if (!VALID_MAPPED_ADDR(unmanagedBaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for unmanagedBaseAddr\n");
+        goto end_with_error;
+    }
+    TEST_PRINTF("unmanagedBaseAddr = 0x%lx\n", unmanagedBaseAddr);
+
+    if (Test_PalMemInit(DMABaseAddr, unmanagedBaseAddr,
+                TEST_HAL_MEM_DMA_AREA_LEN)) {
+        TEST_PRINTF_ERROR("Error: MemInit failed\n");
+        goto end_with_error;
+    }
+
+    return 0;
+
+    end_with_error:
+    Test_HalBoardFree();
+    return 1;
+}
+
+/******************************************************************************/
+void Test_HalBoardFree(void)
+{
+    if (Test_PalGetDMABaseAddr() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetDMABaseAddr(),
+                TEST_HAL_MEM_DMA_AREA_LEN);
+    }
+
+    if (Test_PalGetUnmanagedBaseAddr() != 0) {
+        Test_PalUnmapAddr((void *)Test_PalGetUnmanagedBaseAddr(),
+                TEST_HAL_MEM_UNMANAGED_AREA_LEN);
+    }
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/include/board_configs.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/include/board_configs.h
new file mode 100644
index 0000000..04354db
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/hal/include/board_configs.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_HAL_H_
+#define TEST_HAL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+/*
+ * @brief This function initializes the board.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_HalBoardInit(void);
+
+/******************************************************************************/
+/*
+ * @brief This function unmaps the addresses related to the board.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_HalBoardFree(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_HAL_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_cli.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_cli.c
new file mode 100644
index 0000000..ab61761
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_cli.c
@@ -0,0 +1,34 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "FreeRTOS_CLI.h"
+#include "test_pal_cli.h"
+
+/******************************************************************************/
+uint32_t Test_PalCLIRegisterCommand(struct Test_PalCliCommand *commandToRegister)
+{
+    if (FreeRTOS_CLIRegisterCommand(
+        (CLI_Command_Definition_t *)commandToRegister) == pdFAIL)
+        return 1;
+
+    return 0;
+}
+
+/******************************************************************************/
+const char *Test_PalCLIGetParameter(const char *commandString,
+            uint32_t wantedParamIndx, uint32_t *paramStringLength)
+{
+    return FreeRTOS_CLIGetParameter(commandString, wantedParamIndx,
+                    (BaseType_t *)paramStringLength);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_file.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_file.c
new file mode 100644
index 0000000..13d40b0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_file.c
@@ -0,0 +1,22 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/******************************************************************************/
+size_t Test_PalFetchDataFromFile(const char *data_fname, uint8_t **data_pp)
+{
+    (void)data_fname;
+    (void)data_pp;
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_log.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_log.c
new file mode 100644
index 0000000..282663e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_log.c
@@ -0,0 +1,135 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include "test_pal_log.h"
+
+/******************************************************************************/
+void Test_PalPrintfError(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    printf("%s(): ", function);
+    vprintf(format, args);
+    printf("\n");
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalFprintfError(void *fd, const char *function, const char *format, ...)
+{
+    (void)fd;
+    (void)function;
+    (void)format;
+}
+
+/******************************************************************************/
+void Test_PalPrintfMessage(const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    vprintf(format, args);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalPrintf(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    if (function)
+        printf("%s(): ", function);
+    vprintf(format, args);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalFprintf(void *fd, const char *function, const char *format, ...)
+{
+    (void)fd;
+    (void)function;
+    (void)format;
+}
+
+/******************************************************************************/
+void Test_PalPrintByteBuff(const char *function, const char *buffName,
+                        uint8_t *buff, uint32_t size)
+{
+    unsigned int i = 0;
+
+    Test_PalPrintf(function, "printing %s, byte size %d\n", buffName,
+            (unsigned int)size);
+
+    for (i = 0; i < size; i++) {
+        if (!(i%16))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%02X ",
+                (unsigned char)(*((unsigned char *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/******************************************************************************/
+void Test_PalFprintByteBuff(void *fd, const char *function,
+            const char *buffName, uint8_t *buff, uint32_t size)
+{
+    (void)fd;
+    (void)function;
+    (void)buffName;
+    (void)buff;
+    (void)size;
+}
+
+/******************************************************************************/
+void Test_PalFprintfByteBuffMax(void *fd, const char *function,
+    const char *buffName, uint8_t *buff, uint32_t size, uint32_t maxSize)
+{
+    (void)fd;
+    (void)function;
+    (void)buffName;
+    (void)buff;
+    (void)size;
+    (void)maxSize;
+}
+
+/******************************************************************************/
+void Test_PalPrintWordBuff(const char *function, const char *buffName,
+                        uint32_t *buff, uint32_t size)
+{
+    uint8_t i = 0;
+
+    Test_PalPrintf(function, "printing %s, word size %d\n", buffName,
+                            (uint32_t)size);
+    for (i = 0; i < size; i++) {
+        if (!(i%4))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%08X  ",
+                (unsigned int)(*((unsigned int *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/* inline void TEST_PRINT_BYTE_BUFFP(buffName, buff, size);
+   inline void TEST_FPRINT_LONG_NUM(const char *fd, const char *buffName,
+   uint32_t *buff, uint32_t size); */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_map_addrs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_map_addrs.c
new file mode 100644
index 0000000..ae840d6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_map_addrs.c
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "test_pal_map_addrs.h"
+
+/******************************************************************************/
+void *Test_PalIOMap(void *physAddr, size_t size)
+{
+    (void)size;
+    return physAddr;
+}
+
+/******************************************************************************/
+void *Test_PalMapAddr(void *physAddr, void *startingAddr, const char *filename,
+                size_t size, uint8_t protAndFlagsBitMask)
+{
+    (void)startingAddr;
+    (void)filename;
+    (void)size;
+    (void)protAndFlagsBitMask;
+    return physAddr;
+}
+
+/******************************************************************************/
+void Test_PalUnmapAddr(void *virtAddr, size_t size)
+{
+    (void)virtAddr;
+    (void)size;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_mem.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_mem.c
new file mode 100644
index 0000000..5c934ea
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_mem.c
@@ -0,0 +1,119 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdint.h>
+#include "FreeRTOS.h"
+#include "test_pal_log.h"
+#include "test_pal_mem.h"
+
+static unsigned long unmanagedBaseAddr = 0;
+static uint8_t memInitialised = 0;
+
+/******************************************************************************/
+/* Note: When TrustZone-M is supported, the following functions use NON SECURE*/
+/* memory by default.                                                         */
+/******************************************************************************/
+#ifndef TZM
+void *(*PalMalloc)(size_t) = pvPortMalloc;
+void (*PalFree)(void *) = vPortFree;
+void *(*PalRealloc)(void *, size_t) = pvPortRealloc;
+#else
+void *(*PalMalloc)(size_t) = pvPortMalloc_ns;
+void (*PalFree)(void *) = vPortFree_ns;
+void *(*PalRealloc)(void *, size_t) = pvPortRealloc_ns;
+#endif
+
+
+/******************************************************************************/
+void *Test_PalMalloc(size_t size)
+{
+    if (!size)
+        return NULL;
+
+    return PalMalloc(size);
+}
+
+/******************************************************************************/
+void Test_PalFree(void *pvAddress)
+{
+    if (pvAddress == NULL)
+        return;
+
+    PalFree(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalRealloc(void *pvAddress, size_t newSize)
+{
+    if (pvAddress == NULL)
+        return NULL;
+
+    return PalRealloc(pvAddress, newSize);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferAlloc(size_t size)
+{
+    return Test_PalMalloc(size);
+}
+
+/******************************************************************************/
+void Test_PalDMAContigBufferFree(void *pvAddress)
+{
+    Test_PalFree(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferRealloc(void *pvAddress, size_t newSize)
+{
+    return Test_PalRealloc(pvAddress, newSize);
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetDMABaseAddr(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetUnmanagedBaseAddr(void)
+{
+    return unmanagedBaseAddr;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemInit(unsigned long newDMABaseAddr,
+             unsigned long newUnmanagedBaseAddr,
+             size_t DMAsize)
+{
+    if(memInitialised) {
+        TEST_PRINTF_ERROR("Memory is already initialised");
+        return 1;
+    }
+
+    (void)newDMABaseAddr;
+    (void)DMAsize;
+    unmanagedBaseAddr = newUnmanagedBaseAddr;
+    memInitialised = 1;
+
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemFin(void)
+{
+    unmanagedBaseAddr = 0;
+    memInitialised = 0;
+
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_mem_s.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_mem_s.c
new file mode 100644
index 0000000..805f8f6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_mem_s.c
@@ -0,0 +1,209 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdint.h>
+
+#ifdef TZM
+#include "FreeRTOS.h"
+#include "test_pal_log.h"
+#include "test_pal_mem.h"
+#include "test_pal_mem_s.h"
+#include <arm_cmse.h>
+#endif
+
+#ifndef TZM
+/******************************************************************************/
+void *Test_PalMalloc_s(size_t size)
+{
+    (void)size;
+    return NULL;
+}
+
+/******************************************************************************/
+void Test_PalFree_s(void *pvAddress)
+{
+    (void)pvAddress;
+}
+
+/******************************************************************************/
+void *Test_PalRealloc_s(void *pvAddress, size_t newSize)
+{
+    (void)pvAddress;
+    (void)newSize;
+    return NULL;
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferAlloc_s(size_t size)
+{
+    (void)size;
+    return NULL;
+}
+
+/******************************************************************************/
+void Test_PalDMAContigBufferFree_s(void *pvAddress)
+{
+    (void)pvAddress;
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferRealloc_s(void *pvAddress, size_t newSize)
+{
+    (void)pvAddress;
+    (void)newSize;
+    return NULL;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetDMABaseAddr_s(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetUnmanagedBaseAddr_s(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemInit_s(unsigned long newDMABaseAddr,
+               unsigned long newUnmanagedBaseAddr,
+               size_t DMAsize)
+{
+    (void)newDMABaseAddr;
+    (void)newUnmanagedBaseAddr;
+    (void)DMAsize;
+    return 1;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemFin_s(void)
+{
+    return 1;
+}
+
+#else
+
+static unsigned long unmanagedBaseAddr_s = 0;
+static uint8_t memInitialised_s = 0;
+
+/******************************************************************************/
+void *Test_PalMalloc_s(size_t size)
+{
+    /* A non-secure caller */
+    if (cmse_is_nsfptr(&Test_PalMalloc_s))
+        return NULL;
+
+    /* A secure caller */
+    if (!size)
+        return NULL;
+
+    return pvPortMalloc(size);
+}
+
+/******************************************************************************/
+void Test_PalFree_s(void *pvAddress)
+{
+    /* A non-secure caller */
+    if (cmse_is_nsfptr(&Test_PalFree_s))
+        return;
+
+    /* A secure caller */
+    if (pvAddress == NULL)
+        return;
+
+    vPortFree(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalRealloc_s(void *pvAddress, size_t newSize)
+{
+    /* A non-secure caller */
+    if (cmse_is_nsfptr(&Test_PalRealloc_s))
+        return NULL;
+
+    /* A secure caller */
+    if (pvAddress == NULL)
+        return NULL;
+
+    return pvPortRealloc(pvAddress, newSize);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferAlloc_s(size_t size)
+{
+    return Test_PalMalloc_s(size);
+}
+
+/******************************************************************************/
+void Test_PalDMAContigBufferFree_s(void *pvAddress)
+{
+    Test_PalFree_s(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferRealloc_s(void *pvAddress, size_t newSize)
+{
+    return Test_PalRealloc_s(pvAddress, newSize);
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetDMABaseAddr_s(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetUnmanagedBaseAddr_s(void)
+{
+    return unmanagedBaseAddr_s;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemInit_s(unsigned long newDMABaseAddr_s,
+               unsigned long newUnmanagedBaseAddr_s,
+               size_t SDMAsize)
+{
+    /* A non-secure caller */
+    if (cmse_is_nsfptr(&Test_PalMemInit_s))
+        return 1;
+
+    /* A secure caller */
+    if(memInitialised_s) {
+        TEST_PRINTF_ERROR("Secure memory is already initialised");
+        return 1;
+    }
+
+    (void)newDMABaseAddr_s;
+    (void)SDMAsize;
+    unmanagedBaseAddr_s = newUnmanagedBaseAddr_s;
+    memInitialised_s = 1;
+
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemFin_s(void)
+{
+    /* A non-secure caller */
+    if (cmse_is_nsfptr(&Test_PalMemFin_s))
+        return 1;
+
+    /* A secure caller */
+    unmanagedBaseAddr_s = 0;
+    memInitialised_s = 0;
+
+    return 0;
+}
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_semphr.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_semphr.c
new file mode 100644
index 0000000..3fb076b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_semphr.c
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include "test_pal_semphr.h"
+#include "FreeRTOS.h"
+#include "semphr.h"
+
+/******************************************************************************/
+uint8_t Test_PalMutexCreate(Test_PalMutex *ppMutexId)
+{
+    *ppMutexId = xSemaphoreCreateMutex(); /* function returns
+    SemaphoreHandle_t */
+
+    if (*ppMutexId == NULL)
+        return 1;
+
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexDestroy(Test_PalMutex *ppMutexId)
+{
+    vSemaphoreDelete(*ppMutexId);
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexLock(Test_PalMutex *ppMutexId, uint32_t timeout)
+{
+    if (!INFINITE)
+        timeout = timeout / portTICK_PERIOD_MS;
+    else
+        timeout = portMAX_DELAY;
+
+    return xSemaphoreTake(*ppMutexId, timeout) ? 0:1;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexUnlock(Test_PalMutex *ppMutexId)
+{
+    return xSemaphoreGive(*ppMutexId) ? 0:1;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreCreate(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    *ppBinSemphrId = xSemaphoreCreateBinary(); /* function returns
+    SemaphoreHandle_t */
+
+    if (*ppBinSemphrId == NULL)
+        return 1;
+
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreDestroy(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    vSemaphoreDelete(*ppBinSemphrId);
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreTake(Test_PalBinarySemaphore *ppBinSemphrId,
+                            uint32_t timeout)
+{
+    if (!INFINITE)
+        timeout = timeout / portTICK_PERIOD_MS;
+    else
+        timeout = portMAX_DELAY;
+
+    return xSemaphoreTake(*ppBinSemphrId, timeout) ? 0:1;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreGive(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    return xSemaphoreGive(*ppBinSemphrId) ? 0:1;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_socket.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_socket.c
new file mode 100644
index 0000000..93fbef8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_socket.c
@@ -0,0 +1,263 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include "FreeRTOS.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include <stdint.h>
+
+#include "test_pal_socket.h"
+#include "test_pal_mem.h"
+
+/* Sending timeout */
+#define TIMEOUT_MS  20000
+
+/******************************************************************************/
+uint32_t Test_PalSocket(tp_socket *s, enum tp_sock_domain domain,
+        enum tp_sock_type type, enum tp_sock_protocol protocol,
+        const uint32_t recvTimeout_ms)
+{
+    const TickType_t xTimeout = TIMEOUT_MS/portTICK_PERIOD_MS;
+    const TickType_t xReceiveTimeout = (recvTimeout_ms == MAX_DELAY) ?\
+            portMAX_DELAY:(recvTimeout_ms/portTICK_PERIOD_MS);
+
+    Socket_t sfd;
+    BaseType_t xDomain;
+    BaseType_t xType;
+    BaseType_t xProtocol;
+
+    if (s == NULL)
+        return 1;
+
+    /* initial the socket parameters */
+    xDomain = (domain == TP_AF_INET) ? FREERTOS_AF_INET : 0;
+    xType   = (type == TP_SOCK_DGRAM) ? FREERTOS_SOCK_DGRAM :
+                        FREERTOS_SOCK_STREAM;
+    xProtocol = (protocol == TP_IPPROTO_UDP) ? FREERTOS_IPPROTO_UDP :
+                        FREERTOS_IPPROTO_TCP;
+
+    /* Attempt to open the socket. */
+    sfd = FreeRTOS_socket(xDomain, xType, xProtocol);
+
+    /* Check if socket was created. */
+    configASSERT(sfd != FREERTOS_INVALID_SOCKET);
+    *s = (tp_socket)sfd;
+    /* If FREERTOS_SO_RCVBUF or FREERTOS_SO_SNDBUF are to be used with
+    FreeRTOS_setsockopt() to change the buffer sizes from their default
+    then do it here!.  (see the FreeRTOS_setsockopt() documentation. */
+
+    /* If ipconfigUSE_TCP_WIN is set to 1 and FREERTOS_SO_WIN_PROPERTIES is
+    be used with FreeRTOS_setsockopt() to change the sliding window size
+    from to its default then do it here! (see the FreeRTOS_setsockopt()
+    documentation. */
+
+    /* Set send and receive time outs. */
+    FreeRTOS_setsockopt(sfd,
+            0,
+            FREERTOS_SO_RCVTIMEO,
+            &xReceiveTimeout,
+            sizeof(xReceiveTimeout));
+
+    FreeRTOS_setsockopt(sfd,
+            0,
+            FREERTOS_SO_SNDTIMEO,
+            &xTimeout,
+            sizeof(xTimeout));
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalCloseSocket(tp_socket s)
+{
+    Socket_t sfd = (Socket_t)s;
+
+    FreeRTOS_closesocket(sfd);
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalConnect(tp_socket s, const uint8_t *addr, uint32_t port)
+{
+    struct freertos_sockaddr xRemoteAddress;
+    Socket_t sfd = (Socket_t)s;
+
+    /* Set the IP address and port of the remote socket
+    to which this client socket will transmit. */
+    xRemoteAddress.sin_port = FreeRTOS_htons(port);
+    xRemoteAddress.sin_addr = FreeRTOS_inet_addr((const char *)addr);
+
+    /* Connect to the remote socket.  The socket has not previously been
+    bound to a local port number so will get automatically bound to a
+    local port inside the FreeRTOS_connect() function. */
+    return FreeRTOS_connect(sfd, &xRemoteAddress,
+                sizeof(xRemoteAddress));
+
+}
+
+/******************************************************************************/
+uint32_t Test_PalBind(tp_socket s, uint32_t port)
+{
+    struct freertos_sockaddr xBindAddress;
+    Socket_t sfd = (Socket_t)s;
+    BaseType_t rc;
+    /* Set the listening port  */
+    xBindAddress.sin_port = FreeRTOS_htons((uint16_t)port);
+
+    /* Bind the socket to the port number */
+    rc = FreeRTOS_bind(sfd, &xBindAddress,
+            sizeof(xBindAddress));
+    return (rc == 0) ? 0 : 1;
+}
+
+/******************************************************************************/
+uint32_t Test_PalListen(tp_socket s, uint32_t backlog)
+{
+    BaseType_t rc;
+    Socket_t sfd = (Socket_t)s;
+
+    rc = FreeRTOS_listen(sfd, backlog);
+    return (rc == 0) ? 0 : 1;
+}
+
+/******************************************************************************/
+uint32_t Test_PalAccept(tp_socket s, tp_socket *acptS, uint8_t *addr,
+             uint32_t *port)
+{
+    struct freertos_sockaddr xSourceAddress;
+    Socket_t sfd = (Socket_t)s;
+    Socket_t xConnectedSfd;
+    socklen_t xAddressLength = 0;
+
+
+    xConnectedSfd = FreeRTOS_accept(sfd, &xSourceAddress, &xAddressLength);
+    if ((xConnectedSfd == FREERTOS_INVALID_SOCKET) ||
+        (xConnectedSfd == NULL)) {
+        /* failed to accept new connection  */
+        return 1;
+    }
+    *acptS = (tp_socket)xConnectedSfd;
+    /* copy IP address converting it to a string. */
+    FreeRTOS_inet_ntoa(xSourceAddress.sin_addr,
+                addr);
+    /* update the received port number */
+    *port = FreeRTOS_ntohs(xSourceAddress.sin_port);
+    return 0;
+}
+
+/******************************************************************************/
+tp_socket Test_PalShutdown(tp_socket s)
+{
+    uint32_t rc = 0;
+    Socket_t sfd = (Socket_t)s;
+
+    /* shutdown active close before close */
+    rc = FreeRTOS_shutdown(sfd, FREERTOS_SHUT_RDWR);
+    return (rc == 0) ? 0 : 1;
+}
+
+/******************************************************************************/
+uint32_t Test_PalSend(tp_socket s, const uint8_t *buf,
+              size_t len)
+{
+    uint32_t byteSent = 0;
+    Socket_t sfd = (Socket_t)s;
+    /* Send message size */
+    byteSent = (uint32_t)FreeRTOS_send(sfd, buf,
+                        len, 0);
+    return byteSent;
+}
+
+/******************************************************************************/
+uint32_t Test_PalSendTo(tp_socket s, const uint8_t *buf,
+            size_t len, const uint8_t *addr, uint32_t port)
+{
+    uint32_t byteSent = 0;
+    Socket_t sfd = (Socket_t)s;
+    /* Send message size */
+    struct freertos_sockaddr xDestinationAddress;
+    /* Fill in the destination address and port number */
+    xDestinationAddress.sin_addr = FreeRTOS_inet_addr((const char *)addr);
+    xDestinationAddress.sin_port = FreeRTOS_htons(port);
+    /* Send the buffer with ulFlags set to 0, so the
+    FREERTOS_ZERO_COPY bit is clear. */
+    byteSent = FreeRTOS_sendto(sfd, buf, len,
+                0, &xDestinationAddress,
+                sizeof(xDestinationAddress));
+    /* check that byte had been successfully queued for sending */
+    return (byteSent == len) ? byteSent : 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalRecvFrom(tp_socket s, const uint8_t *buf,
+            size_t len, uint8_t *addr, uint32_t *port)
+{
+    struct freertos_sockaddr xSourceAddress;
+    int32_t byteRecv;
+    Socket_t sfd = (Socket_t)s;
+    socklen_t xAddressLength = 0;
+
+    /* Receive into the buffer with ulFlags set to 0,
+    so the FREERTOS_ZERO_COPY bit is clear. */
+    byteRecv = FreeRTOS_recvfrom(sfd, (void *)buf, len,
+                    0, &xSourceAddress, &xAddressLength);
+
+    if (byteRecv > 0) {
+        /* Data was received from the socket.
+        copy IP address converting it to a string. */
+        FreeRTOS_inet_ntoa(xSourceAddress.sin_addr,
+                    addr);
+        /* update the received port number */
+        *port = FreeRTOS_ntohs(xSourceAddress.sin_port);
+        return byteRecv;
+    }
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalRecv(tp_socket s, const uint8_t *buf,
+              size_t len)
+{
+    int32_t byteRecv;
+    Socket_t sfd = (Socket_t)s;
+
+    /* Receive into the buffer with ulFlags set to 0,
+    so the FREERTOS_ZERO_COPY bit is clear. */
+    byteRecv = FreeRTOS_recv(sfd, (void *)buf, len,
+                    0);
+    /* in case of error return 0 */
+    return (byteRecv > 0) ? byteRecv : 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalHtonl(uint32_t val)
+{
+    return FreeRTOS_htonl(val);
+}
+
+/******************************************************************************/
+uint16_t Test_PalHtons(uint16_t val)
+{
+    return FreeRTOS_htons(val);
+}
+
+/******************************************************************************/
+uint32_t Test_PalNtohl(uint32_t val)
+{
+    return FreeRTOS_ntohl(val);
+}
+
+/******************************************************************************/
+uint16_t Test_PalNtohs(uint16_t val)
+{
+    return FreeRTOS_ntohs(val);
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_thread.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_thread.c
new file mode 100644
index 0000000..612013b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_thread.c
@@ -0,0 +1,220 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include "task.h"
+#include "projdefs.h"
+#include "test_pal_thread.h"
+#include "test_pal_mem.h"
+#include "test_pal_log.h"
+#ifdef TZM
+#include <arm_cmse.h>
+#include "test_pal_mem_s.h"
+#endif
+
+struct ThreadStr {
+    TaskHandle_t    taskHandle;     /* Thread handle */
+
+    TaskHandle_t    parentTaskHandle;   /* Handle of the task who called
+                         * Test_PalThreadCreate */
+
+    void        *(*taskFunc)(void *);   /* thread function pointer */
+
+    void        *arg;           /* Arguments received by thread
+                         * function. */
+};
+
+/* FreeRTOS Priorities */
+#define FREERTOS_HIGHEST_TASK_PRIORITY      (configMAX_PRIORITIES - 1)
+#define FREERTOS_LOWEST_TASK_PRIORITY       tskIDLE_PRIORITY
+#define FREERTOS_DEFAULT_TASK_PRIORITY      2
+/* FREERTOS_DEFAULT_TASK_PRIORITY Depends on other tasks in the FreeRTOS
+ *  environment. See FreeRTOSConfig.h */
+
+#define FREERTOS_MINIMAL_STACK_SIZE_WORDS   configMINIMAL_STACK_SIZE
+
+/******************************************************************************/
+/*              Internal API                      */
+/******************************************************************************/
+void Test_PalThreadFunc(void *pvParameter)
+{
+    /* Calls task function */
+    struct ThreadStr *threadStr = pvParameter;
+
+    threadStr->taskFunc(threadStr->arg);
+
+    /* Sends a notification for the parent task */
+    if (threadStr->parentTaskHandle != NULL)
+        xTaskNotifyGive(threadStr->parentTaskHandle);
+
+    threadStr->taskHandle = NULL;
+
+    /* suicide */
+    vTaskDelete(NULL);
+}
+
+/******************************************************************************/
+/* Note: When TrustZone-M is supported, it is required to ask whether the     */
+/* caller is non-secure or secure in order to allocate a stack with the same  */
+/* attribute                                                                  */
+/******************************************************************************/
+
+static void *PalMalloc(size_t size)
+{
+#ifndef TZM
+    return Test_PalMalloc(size);
+#else
+    if (cmse_is_nsfptr(&PalMalloc)) /* A non-secure caller */
+        return Test_PalMalloc(size);
+    return Test_PalMalloc_s(size); /* A secure caller */
+#endif
+}
+
+static void PalFree(void *pvAddress)
+{
+#ifndef TZM
+    Test_PalFree(pvAddress);
+#else
+    if (cmse_is_nsfptr(&PalFree)) /* A non-secure caller */
+        Test_PalFree(pvAddress);
+    Test_PalFree_s(pvAddress); /* A secure caller */
+#endif
+}
+
+/******************************************************************************/
+/*              External API                      */
+/******************************************************************************/
+size_t Test_PalGetMinimalStackSize(void)
+{
+    return FREERTOS_MINIMAL_STACK_SIZE_WORDS*4;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetHighestPriority(void)
+{
+    return FREERTOS_HIGHEST_TASK_PRIORITY;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetLowestPriority(void)
+{
+    return FREERTOS_LOWEST_TASK_PRIORITY;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetDefaultPriority(void)
+{
+    return FREERTOS_DEFAULT_TASK_PRIORITY;
+}
+
+/******************************************************************************/
+ThreadHandle Test_PalThreadCreate(size_t stackSize,
+                  void *(*threadFunc)(void *),
+                  int priority, void *arg,
+                  const char *threadName,
+                  uint8_t nameLen, uint8_t dmaAble)
+{
+    char buff[8];
+    size_t stackSizeInWords, minimalStackSize;
+    struct ThreadStr *threadStr;
+    (void)dmaAble;
+
+    /* Checks argument validity */
+    minimalStackSize = Test_PalGetMinimalStackSize();
+    if (stackSize < minimalStackSize) {
+        TEST_PRINTF_ERROR("Stack size is too small. Changed to"
+                "minimal stack size in bytes: %d\n",
+                minimalStackSize);
+        stackSize = minimalStackSize;
+    }
+    /* Casting is used in order to avoid compilation warnings */
+    if ((priority < (int)FREERTOS_LOWEST_TASK_PRIORITY) ||
+        (priority > (int)FREERTOS_HIGHEST_TASK_PRIORITY)) {
+        TEST_PRINTF_ERROR("Priority is not vaild\n");
+        return NULL;
+    }
+
+#ifdef TZM
+    /* Thread function must have the same security attribute as
+     * TestAL's (either secure or non-secure) */
+    if(cmse_is_nsfptr(threadFunc) != cmse_is_nsfptr(&Test_PalThreadCreate))
+        return NULL;
+#endif
+
+    /* Allocates ThreadStr */
+    threadStr = PalMalloc(sizeof(struct ThreadStr));
+    if (threadStr == NULL) {
+        TEST_PRINTF_ERROR("threadStr allocation failed\n");
+        return NULL;
+    }
+
+    /* Initializes ThreadStr */
+    threadStr->taskFunc = threadFunc;
+    threadStr->arg = arg;
+
+    memset(buff, 0, sizeof(buff));
+    memcpy(buff, threadName, ((nameLen > 8) ? 8:nameLen));
+    stackSizeInWords = (stackSize + 3) >> 2;
+
+    /* Creates thread */
+    if (xTaskCreate(Test_PalThreadFunc, buff, stackSizeInWords, threadStr,
+            priority, &threadStr->taskHandle) == pdFAIL) {
+        TEST_PRINTF_ERROR("thread creation failed\n");
+        PalFree(threadStr);
+        return NULL;
+    }
+
+    /* New task was created. Save current task handle for future
+     * notifications */
+    threadStr->parentTaskHandle = xTaskGetCurrentTaskHandle();
+    return threadStr;
+}
+
+/******************************************************************************/
+uint32_t Test_PalThreadJoin(ThreadHandle threadHandle, void **threadRet)
+{
+    struct ThreadStr *threadStr = (struct ThreadStr *)threadHandle;
+    (void)threadRet;
+
+    if(threadStr->taskHandle != NULL )
+        ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
+
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalThreadDestroy(ThreadHandle threadHandle)
+{
+    /* Remember the value of the variable as it
+    will be set to NULL. */
+    struct ThreadStr *threadStr = (struct ThreadStr *)threadHandle;
+    TaskHandle_t xTask = threadStr->taskHandle;
+
+    vTaskSuspendAll();
+
+    if(threadStr->taskHandle != NULL ) {
+        /* The task is going to be deleted. Set the handle to NULL */
+        threadStr->taskHandle = NULL;
+
+        /* Delete using the copy of the handle. */
+        vTaskDelete( xTask );
+    }
+    xTaskResumeAll();
+
+    PalFree(threadStr);
+
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_time.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_time.c
new file mode 100644
index 0000000..4972739
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/freertos/test_pal_time.c
@@ -0,0 +1,27 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "test_pal_time.h"
+
+/******************************************************************************/
+void Test_PalDelay(const uint32_t usec)
+{
+    vTaskDelay(usec / (1000 * portTICK_PERIOD_MS));
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetTimestamp(void)
+{
+    return (xTaskGetTickCount() * portTICK_PERIOD_MS);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_cli.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_cli.h
new file mode 100644
index 0000000..e9b9c32
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_cli.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_CLI_H_
+#define TEST_PAL_CLI_H_
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int (*COMMAND_CALLBACK)(char *pcWriteBuffer, size_t xWriteBufferLen,
+    const char *pcCommandString);
+
+struct Test_PalCliCommand {
+    /* The command that causes pxCommandInterpreter to be executed.
+     * For example "help".  Must be all lower case. */
+    const char          *const pcCommand;
+    /* String that describes how to use the command. Should start
+     * with the command itself, and end with "\r\n".
+     * For example "help: Returns a list of all the commands\r\n". */
+    const char          *const pcHelpString;
+    /* A pointer to the callback function that will return the output
+     * generated by the command. */
+    const COMMAND_CALLBACK      pxCommandInterpreter;
+    int8_t              cExpectedNumberOfParameters;
+};
+
+/******************************************************************************/
+/*
+ * @brief This function registers a new CLI command.
+ *
+ * @param[in]
+ * commandToRegister - Command structure.
+ *
+ * @param[out]
+ *
+ * @return - 0 for success and 1 for failure.
+ */
+uint32_t Test_PalCLIRegisterCommand(struct Test_PalCliCommand
+                    *commandToRegister);
+
+/******************************************************************************/
+/*
+ * @brief This function obtains a parameter string by its index and stores the
+ * parameter string length.
+ *
+ * @param[in]
+ * commandString - The command string itself.
+ * wantedParamIndx - Parameter index.
+ *
+ * @param[out]
+ * paramStringLength - Parameter string length.
+ *
+ * @return - Parameter string for success or NULL for failure.
+ */
+const char *Test_PalCLIGetParameter(const char *commandString,
+        uint32_t wantedParamIndx, uint32_t *paramStringLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_CLI_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_file.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_file.h
new file mode 100644
index 0000000..fdd1919
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_file.h
@@ -0,0 +1,41 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+
+#ifndef TEST_PAL_FILE_H_
+#define TEST_PAL_FILE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+/*
+ * @brief This function reads dump data from given file in CryptoRef
+ * (this test dump) format (comma seperated hex byte values) and put in
+ * allocated buffer.
+ *
+ * @param[in]
+ * data_fname - File name.
+ *
+ * @param[out]
+ * data_pp - A pointer to the allocated data buffer.
+ *
+ * @return - Data size in bytes.
+ */
+size_t Test_PalFetchDataFromFile(const char *data_fname, uint8_t **data_pp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_FILE_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_log.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_log.h
new file mode 100644
index 0000000..ce2e8c8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_log.h
@@ -0,0 +1,408 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_LOG_H_
+#define TEST_PAL_LOG_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* In order to print the name of the function, while implementing
+ * a generic declaration and an OS-dependent definition, we use a macro that
+ * calls a PAL function with __FUNCTION__ as an argument.
+ */
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints to stderr with or without the name of
+ * the calling function.
+ * When function is NULL, the name of the function is not printed.
+ *
+ * @param[in]
+ * function - The name of the calling function (can be NULL).
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalPrintfError(const char *function, const char *format, ...);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints to stderr and to a file with or without
+ * the name of the calling function.
+ * When function is NULL, the name of the function is not printed.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * function - The name of the calling function (can be NULL).
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalFprintfError(void *fd, const char *function,
+        const char *format, ...);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints messages to stderr.
+ *
+ * @param[in]
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalPrintfMessage(const char *format, ...);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints strings to stdout with or without
+ * the name of the calling function.
+ * When function is NULL, the name of the function is not printed.
+ *
+ * @param[in]
+ * function - The name of the calling function (can be NULL).
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalPrintf(const char *function, const char *format, ...);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints strings to stdout and to a file
+ * with or without the name of the calling function.
+ * When function is NULL, the name of the function is not printed.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * function - The name of the calling function (can be NULL).
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalFprintf(void *fd, const char *function, const char *format, ...);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints bytes in a buffer to stdout
+ * with or without the name of the calling function.
+ * When function is NULL, the name of the function is not printed.
+ *
+ * @param[in]
+ * function - The name of the calling function (can be NULL).
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalPrintByteBuff(const char *function, const char *buffName,
+                        uint8_t *buff, uint32_t size);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints bytes in a buffer to a file
+ * with or without the name of the calling function.
+ * When function is NULL, the name of the function is not printed.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * function - The name of the calling function (can be NULL).
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalFprintByteBuff(void *fd, const char *function,
+            const char *buffName, uint8_t *buff, uint32_t size);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints bytes in a buffer to a file
+ * with or without the name of the calling function.
+ * When function is NULL, the name of the function is not printed.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * function - The name of the calling function (can be NULL).
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ * maxSize - Maximum size to print.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalFprintfByteBuffMax(void *fd, const char *function,
+            const char *buffName, uint8_t *buff, uint32_t size,
+            uint32_t maxSize);
+
+/******************************************************************************/
+/*
+ * @brief This variadic function prints words in a buffer with or without the
+ * name of the calling function.
+ * When function is NULL, the name of the function is not printed (can be NULL).
+ *
+ * @param[in]
+ * function - The name of the calling function.
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalPrintWordBuff(const char *function, const char *buffName,
+            uint32_t *buff, uint32_t size);
+
+/******************************************************************************/
+/*
+ * @brief This macro prints errors with the name of the calling function.
+ *
+ * @param[in]
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_PRINTF_ERROR(format, ...)  {\
+    Test_PalPrintfError(__FUNCTION__, format, ##__VA_ARGS__);\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints to a file with the name of the calling function.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_FPRINTF_ERROR(fd, format, ...)  {\
+    Test_PalFprintfError(fd, __FUNCTION__, format, ##__VA_ARGS__);\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints messages.
+ *
+ * @param[in]
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_PRINTF_MESSAGE(format, ...)  {\
+    Test_PalPrintfMessage(format, ##__VA_ARGS__);\
+}
+
+#ifdef TEST_DEBUG
+
+/******************************************************************************/
+/*
+ * @brief This macro prints strings with the name of the calling function.
+ *
+ * @param[in]
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_PRINTF(format, ...)  {\
+    Test_PalPrintf(__FUNCTION__, format, ##__VA_ARGS__);\
+    Test_PalPrintf(NULL, "\n");\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints strings to a file with the name of the calling function.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_FPRINTF(fd, format, ...)  {\
+    Test_PalFprintf(fd, __FUNCTION__, format, ##__VA_ARGS__);\
+    Test_PalFprintf(fd, NULL, "\n");\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints strings without the name of the calling function.
+ *
+ * @param[in]
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_PRINTF_NO_FUNC(format, ...)  {\
+    Test_PalPrintf(NULL, format, ##__VA_ARGS__);\
+    Test_PalPrintf(NULL, "\n");\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints strings to a file without the name of the calling function.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * format - The printed string.
+ * ... - Arguments
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_FPRINTF_NO_FUNC(fd, format, ...)  {\
+    Test_PalFprintf(fd, NULL, format, ##__VA_ARGS__);\
+    Test_PalFprintf(fd, NULL, "\n");\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints bytes in a buffer with the name of the calling
+ * function.
+ *
+ * @param[in]
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_PRINT_BYTE_BUFF(buffName, buff, size)  {\
+    Test_PalPrintByteBuff(__FUNCTION__, buffName, buff, size);\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints bytes in a buffer to a file with
+ * the name of the calling function.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_FPRINT_BYTE_BUFF(fd, buffName, buff, size)  {\
+    Test_PalFprintByteBuff(fd, __FUNCTION__, buffName, buff, size);\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints bytes in a buffer to a file with the name of the
+ * calling function.
+ *
+ * @param[in]
+ * fd - File descriptor.
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ * maxSize - Maximum size to print.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_FPRINT_BYTE_BUFF_MAX(fd, buffName, buff, size, maxSize) {\
+    Test_PalFprintfByteBuffMax(fd, __FUNCTION__, buffName, buff, size,\
+                maxSize);\
+}
+
+/******************************************************************************/
+/*
+ * @brief This macro prints words in a buffer with the name of the calling
+ * function.
+ *
+ * @param[in]
+ * buffName - The name of the buffer.
+ * buff - Buffer address.
+ * size - The size of the buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+#define TEST_PRINT_WORD_BUFF(buffName, buff, size) {\
+    Test_PalPrintWordBuff(__FUNCTION__, buffName, buff, size);\
+}
+
+/* void TEST_PRINT_BYTE_BUFFP(buffName, buff, size);
+   void TEST_FPRINT_LONG_NUM(const char *fd, const char *buffName,
+   uint32_t *buff, uint32_t size); */
+#else
+#define TEST_PRINTF(format, ...) do { } while (0)
+#define TEST_FPRINTF(fd, format, ...) do { } while (0)
+#define TEST_PRINTF_NO_FUNC(format, ...) do { } while (0)
+#define TEST_FPRINTF_NO_FUNC(fd, format, ...) do { } while (0)
+#define TEST_PRINT_BYTE_BUFF(buffName, buff, size) do { } while (0)
+#define TEST_FPRINT_BYTE_BUFF(fd, buffName, buff, size) do { } while (0)
+#define TEST_FPRINT_BYTE_BUFF_MAX(fd, buffName, buff, size, maxSize) do { } while (0)
+#define TEST_PRINT_WORD_BUFF(buffName, buff, size) do { } while (0)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_LOG_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_map_addrs.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_map_addrs.h
new file mode 100644
index 0000000..341871c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_map_addrs.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_MAP_ADDRS_H_
+#define TEST_PAL_MAP_ADDRS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define VALID_MAPPED_ADDR(addr) ((addr != 0) && (addr != 0xFFFFFFFF))
+
+/* Bit Masks - Used by Linux */
+#define BM_READ     0x01 /* Pages may be read */
+#define BM_WRITE    0x02 /* Pages may be written */
+#define BM_EXEC     0x04 /* Pages may be executed */
+#define BM_NONE     0x08 /* Pages may not be accessed */
+#define BM_SHARED   0x10 /* Share this mapping */
+#define BM_PRIVATE  0x20 /* Create a private copy-on-write mapping */
+#define BM_FIXED    0x40 /* Don't interpret addr as a hint:
+                place the mapping at exactly that address. */
+
+/******************************************************************************/
+/*
+ * @brief This function maps IO physical address to OS accessible address.
+ * @param[in]
+ * physAddr - a physical address.
+ * size - size in bytes.
+ *
+ * @param[out]
+ *
+ * @return a valid virtual address or null in case of failure.
+ */
+void *Test_PalIOMap(void *physAddr, size_t size);
+
+/******************************************************************************/
+/*
+ * @brief This function maps a physical address to a virtual address.
+ * @param[in]
+ * physAddr - a physical address.
+ * startingAddr - preferred static address for mapping.
+ * filename - File name.
+ * size - size in bytes.
+ * protAndFlagsBitMask - prot and flags bit mask.
+ *
+ * @param[out]
+ *
+ * @return a valid virtual address or null in case of failure.
+ */
+void *Test_PalMapAddr(void *physAddr, void *startingAddr, const char *filename,
+                size_t size, uint8_t protAndFlagsBitMask);
+
+/******************************************************************************/
+/*
+ * @brief This function unmaps a virtual address.
+ * @param[in] virtual address and size in bytes.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalUnmapAddr(void *virtAddr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_MAP_ADDRS_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_mem.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_mem.h
new file mode 100644
index 0000000..eab5c17
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_mem.h
@@ -0,0 +1,184 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_MEM_H_
+#define TEST_PAL_MEM_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+/* Note: When TrustZone-M is supported, the following functions use NON SECURE*/
+/* memory by default.                                                         */
+/******************************************************************************/
+
+/******************************************************************************/
+/*
+ * @brief This function allocates "size" bytes.
+ * When TZM is supported, it is used only for NON SECURE memory allocations.
+ *
+ * @param[in] size in bytes.
+ *
+ * @param[out]
+ *
+ * @return pointer to the allocated memory.
+ */
+void *Test_PalMalloc(size_t size);
+
+/******************************************************************************/
+/*
+ * @brief This function frees allocated memory pointed by pvAddress.
+ * When TZM is supported, it is used only for NON SECURE memory blocks.
+ *
+ * @param[in] pvAddress - pointer to the allocated memory.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalFree(void *pvAddress);
+
+/******************************************************************************/
+/*
+ * @brief This function changes the size of the memory block pointed by
+ * pvAddress.
+ * If the function fails to allocate the requested block of memory:
+ * 1. a null pointer is returned.
+ * 2. The memory block pointed by argument pvAddress is NOT deallocated.
+ * When TZM is supported, it is used only for NON SECURE memory blocks.
+ *
+ * @param[in]
+ * pvAddress - Pointer to the allocated memory.
+ * newSize - New size.
+ *
+ * @param[out]
+ *
+ * @return - a pointer to the new allocated memory or NULL in case of failure.
+ */
+void *Test_PalRealloc(void *pvAddress, size_t newSize);
+
+/******************************************************************************/
+/*
+ * @brief This function allocates a DMA-contiguous buffer and returns its
+ * address.
+ * When TZM is supported, it is used only for NON SECURE buffer allocations.
+ *
+ * @param[in] size - Buffer size in bytes.
+ *
+ * @param[out]
+ *
+ * @return an address of the allocated buffer.
+ */
+void *Test_PalDMAContigBufferAlloc(size_t size);
+
+/******************************************************************************/
+/*
+ * @brief This function frees resources previously allocated by
+ * Test_PalDMAContigBufferAlloc.
+ *
+ * When TZM is supported, it is used only for NON SECURE buffers.
+ *
+ * @param[in] pvAddress - address of the allocated buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalDMAContigBufferFree(void *pvAddress);
+
+/******************************************************************************/
+/*
+ * @brief This function changes the size of the memory block pointed by
+ * pvAddress.
+ * If the function fails to allocate the requested block of memory:
+ * 1. a null pointer is returned.
+ * 2. The memory block pointed by argument pvAddress is NOT deallocated.
+ * When TZM is supported, it is used only for NON SECURE buffers.
+ *
+ * @param[in]
+ * pvAddress - Pointer to the allocated memory.
+ * newSize - New size in bytes.
+ *
+ * @param[out]
+ *
+ * @return - a pointer to the new allocated memory.
+ */
+void *Test_PalDMAContigBufferRealloc(void *pvAddress, size_t newSize);
+
+/******************************************************************************/
+/*
+ * @brief This function returns DMA base address, i.e. the start address
+ * of the DMA region.
+ * When TZM is supported, it returns the NON SECURE DMA base address.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - DMABaseAddr.
+ */
+unsigned long Test_PalGetDMABaseAddr(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the unmanaged base address.
+ * When TZM is supported, it returns the NON SECURE unmanaged base address.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - UnmanagedBaseAddr.
+ */
+unsigned long Test_PalGetUnmanagedBaseAddr(void);
+
+/******************************************************************************/
+/*
+ * @brief This function initializes DMA memory management.
+ * When TZM is supported, it initializes the NON SECURE DMA memory management.
+ *
+ * @param[in]
+ * newDMABaseAddr - new DMA start address.
+ * newUnmanagedBaseAddr - new unmanaged start address.
+ * DMAsize - DMA region size.
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalMemInit(unsigned long newDMABaseAddr,
+             unsigned long newUnmanagedBaseAddr,
+             size_t DMAsize);
+
+/******************************************************************************/
+/*
+ * @brief This function sets this driver to its initial state.
+ * When TZM is supported, it sets the NON SECURE management to its initial
+ * state.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalMemFin(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_MEM_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_mem_s.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_mem_s.h
new file mode 100644
index 0000000..50fb1f8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_mem_s.h
@@ -0,0 +1,173 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_MEM_S_H_
+#define TEST_PAL_MEM_S_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+/*      Secure API - ONLY WHEN TRUSTZONE-M IS SUPPORTED                       */
+/*      Otherwise, please use only test_pal_mem API.                          */
+/******************************************************************************/
+
+/******************************************************************************/
+/*
+ * @brief This function allocates SECURE "size" bytes.
+ *
+ * @param[in] size in bytes.
+ *
+ * @param[out]
+ *
+ * @return pointer to the allocated memory.
+ */
+void *Test_PalMalloc_s(size_t size);
+
+/******************************************************************************/
+/*
+ * @brief This function frees SECURE allocated memory pointed by pvAddress.
+ *
+ * @param[in] pvAddress - pointer to the allocated memory.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalFree_s(void *pvAddress);
+
+/******************************************************************************/
+/*
+ * @brief This function changes the size of a SECURE memory block pointed by
+ * pvAddress.
+ * If the function fails to allocate the requested block of memory:
+ * 1. a null pointer is returned.
+ * 2. The memory block pointed by argument pvAddress is NOT deallocated.
+ *
+ * @param[in]
+ * pvAddress - Pointer to the allocated memory.
+ * newSize - New size.
+ *
+ * @param[out]
+ *
+ * @return - a pointer to the new allocated memory or NULL in case of failure.
+ */
+void *Test_PalRealloc_s(void *pvAddress, size_t newSize);
+
+/******************************************************************************/
+/*
+ * @brief This function allocates a DMA-contiguous buffer in a SECURE memory
+ * region and returns its address.
+ *
+ * @param[in] size - Buffer size in bytes.
+ *
+ * @param[out]
+ *
+ * @return an address of the secure allocated buffer.
+ */
+void *Test_PalDMAContigBufferAlloc_s(size_t size);
+
+/******************************************************************************/
+/*
+ * @brief This function frees resources in a SECURE region previously allocated
+ * by Test_PalDMAContigBufferAlloc_s.
+ *
+ * @param[in] pvAddress - address of the secure allocated buffer.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalDMAContigBufferFree_s(void *pvAddress);
+
+/******************************************************************************/
+/*
+ * @brief This function changes the size of the SECURE memory block pointed by
+ * pvAddress.
+ * If the function fails to allocate the requested block of memory:
+ * 1. a null pointer is returned.
+ * 2. The memory block pointed by argument pvAddress is NOT deallocated.
+ *
+ * @param[in]
+ * pvAddress - Pointer to the secure allocated memory.
+ * newSize - New size in bytes.
+ *
+ * @param[out]
+ *
+ * @return - a pointer to the new secure allocated memory.
+ */
+void *Test_PalDMAContigBufferRealloc_s(void *pvAddress, size_t newSize);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the SECURE DMA base address, i.e. the start
+ * address of the SECURE DMA region.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - Secure DMABaseAddr.
+ */
+unsigned long Test_PalGetDMABaseAddr_s(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the SECURE unmanaged base address.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - DMABaseAddr.
+ */
+unsigned long Test_PalGetUnmanagedBaseAddr_s(void);
+
+/******************************************************************************/
+/*
+ * @brief This function initializes the SECURE DMA memory management.
+ *
+ * @param[in]
+ * newDMABaseAddr_s - new secure DMA start address.
+ * newUnmanagedBaseAddr_s - new secure unmanaged start address.
+ * SDMAsize - secure DMA region size.
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalMemInit_s(unsigned long newDMABaseAddr_s,
+               unsigned long newUnmanagedBaseAddr_s,
+               size_t SDMAsize);
+
+/******************************************************************************/
+/*
+ * @brief This function sets the SECURE memory management driver to its initial
+ * state.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalMemFin_s(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_MEM_S_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_semphr.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_semphr.h
new file mode 100644
index 0000000..b2c7a72
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_semphr.h
@@ -0,0 +1,139 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_SEMPHR_H_
+#define TEST_PAL_SEMPHR_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define INFINITE 0xFFFFFFFF
+
+typedef void *Test_PalMutex;
+typedef void *Test_PalBinarySemaphore;
+
+/******************************************************************************/
+/**
+ * @brief This function creates a mutex.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ * ppMutexId - pointer to the created Test_PalMutex.
+ *
+ * @return - 0 on success, 1 for failure.
+ */
+uint8_t Test_PalMutexCreate(Test_PalMutex *ppMutexId);
+
+/******************************************************************************/
+/**
+ * @brief This function destroys a mutex.
+ *
+ * @param[in]
+ * ppMutexId - pointer to Test_PalMutex.
+ *
+ * @param[out]
+ *
+ * @return - 0.
+ */
+uint8_t Test_PalMutexDestroy(Test_PalMutex *ppMutexId);
+
+/******************************************************************************/
+/**
+ * @brief This function waits for a mutex with timeout. The timeout is
+ * specified in milliseconds. INFINITE is blocking.
+ *
+ * @param[in]
+ * ppMutexId - pointer to Test_PalMutex.
+ * timeout - Timeout in msec, or INFINITE.
+ *
+ * @return - 0 on success, 1 for failure.
+ */
+uint8_t Test_PalMutexLock(Test_PalMutex *ppMutexId, uint32_t timeout);
+
+/******************************************************************************/
+/**
+ * @brief This function releases a mutex.
+ * Must not be used from an ISR.
+ *
+ * @param[in]
+ * ppMutexId - pointer to Test_PalMutex.
+ *
+ * @param[out]
+ *
+ * @return - 0 on success, 1 for failure.
+ */
+uint8_t Test_PalMutexUnlock(Test_PalMutex *ppMutexId);
+
+/******************************************************************************/
+/**
+ * @brief This function creates a binary semaphore.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ * ppBinSemphrId - Pointer to the created Test_PalBinarySemaphore.
+ *
+ * @return - 0 on success, 1 for failure.
+ */
+uint8_t Test_PalBinarySemaphoreCreate(Test_PalBinarySemaphore *ppBinSemphrId);
+
+/******************************************************************************/
+/**
+ * @brief This function destroys a binary semaphore.
+ *
+ * @param[in]
+ * ppBinSemphrId - Pointer to Test_PalBinarySemaphore.
+ *
+ * @param[out]
+ *
+ * @return - 0.
+ */
+uint8_t Test_PalBinarySemaphoreDestroy(Test_PalBinarySemaphore *ppBinSemphrId);
+
+/******************************************************************************/
+/**
+ * @brief This function waits for a binary semaphore with timeout. The timeout
+ * is specified in milliseconds. INFINITE is blocking.
+ *
+ * @param[in]
+ * ppBinSemphrId - Pointer to Test_PalBinarySemaphore.
+ * timeout - Timeout in msec, or INFINITE.
+ *
+ * @param[out]
+ *
+ * @return - 0 on success, 1 for failure.
+ */
+uint8_t Test_PalBinarySemaphoreTake(Test_PalBinarySemaphore *ppBinSemphrId,
+                            uint32_t timeout);
+
+/******************************************************************************/
+/**
+ * @brief This function releases a binary semaphore.
+ *
+ * @param[in]
+ * ppBinSemphrId - Pointer to Test_PalBinarySemaphore.
+ *
+ * @param[out]
+ *
+ * @return - 0 on success, 1 for failure.
+ */
+uint8_t Test_PalBinarySemaphoreGive(Test_PalBinarySemaphore *ppBinSemphrId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_SEMPHR_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_socket.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_socket.h
new file mode 100644
index 0000000..7568026
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_socket.h
@@ -0,0 +1,288 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TP_SOCKET_H_
+#define TP_SOCKET_H_
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_DELAY 0xFFFFFFFF
+
+typedef uint32_t tp_socket;
+
+/** tp_sock_domain - communication domain
+ *
+ * @TP_AF_INET - internet IP protocol
+ */
+enum tp_sock_domain {
+    TP_AF_INET  = 1
+};
+
+
+/** tp_sock_type - Socket types
+ *
+ * @TP_SOCK_DGRAM - datagram (conn.less) socket
+ * @TP_SOCK_STREAM - stream (connection) socket
+ */
+enum tp_sock_type {
+    TP_SOCK_DGRAM   = 1,
+    TP_SOCK_STREAM  = 2
+};
+
+/** test_pal_sock_protocol - protocol types
+ *
+ * @TP_IPPROTO_TCP - TCP socket
+ * @TP_IPPROTO_UDP - UDP socket
+ */
+enum tp_sock_protocol {
+    TP_IPPROTO_TCP  = 1,
+    TP_IPPROTO_UDP  = 2
+};
+
+/******************************************************************************/
+/*
+ * @brief This function creates an endpoint for communication.
+ *
+ * @param[in]
+ * domain   - specifies a communication domain.
+ * type     - indicated type, which specifies the communication semantics.
+ * protocol - specifies a particular protocol to be used with the socket.
+ * recvTimeout_ms - specifies receive timeout in milliseconds. MAX_DELAY is
+ * blocking.
+ *
+ * @param[out]
+ * s - Socket structure pointer.
+ *
+ * @return - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalSocket(tp_socket *s, enum tp_sock_domain domain,
+            enum tp_sock_type type, enum tp_sock_protocol protocol,
+            const uint32_t recvTimeout_ms);
+
+/******************************************************************************/
+/*
+ * @brief This function close an endpoint for communication
+ *
+ * @param[in]
+ * s   - socket handler to be closed.
+ *
+ * @param[out]
+ *
+ * @return - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalCloseSocket(tp_socket s);
+
+/******************************************************************************/
+/*
+ * @brief This function initiate a connection on a socket
+ *
+ * @param[in]
+ * s      - Socket handler.
+ * addr   - destination IP address.
+ * port   - destination port number.
+ *
+ * @param[out]
+ *
+ * @return - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalConnect(tp_socket s, const uint8_t *addr, uint32_t port);
+
+/******************************************************************************/
+/*
+ * @brief This function assigns the local  address to the socket
+ *
+ * @param[in]
+ * s      - Socket handler.
+ * port   - socket local port number
+ *
+ * @param[out]
+ *
+ * @return - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalBind(tp_socket s, uint32_t port);
+
+/******************************************************************************/
+/*
+ * @brief This function listen for incoming connection on socket
+ *
+ * @param[in]
+ * s       - Socket handler.
+ * backlog - puts a limit on the number of simultaneously connected clients
+ *
+ * @param[out]
+ *
+ * @return - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalListen(tp_socket s, uint32_t backlog);
+
+/******************************************************************************/
+/*
+ * @brief This function accept connection on a socket
+ *
+ * @param[in]
+ * s      - the listening socket on which new connections are to be accepted.
+ *
+ * @param[out]
+ * acptS  - handle of the accepted socket created
+ * addr   - IP Addr of the socket from which a connection was accepted.
+ * port   - port number of the socket from which a connection was accepted.
+ *
+ * @return - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalAccept(tp_socket s, tp_socket *acptS, uint8_t *addr,
+             uint32_t *port);
+
+/******************************************************************************/
+/*
+ * @brief This function disable reads and writes on a connected TCP socket
+ *
+ * @param[in]
+ * s      - Socket handler.
+ *
+ * @param[out]
+ *
+ * @return - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalShutdown(tp_socket s);
+
+/******************************************************************************/
+/**
+ * @brief This function sends messages via a specified socket.
+ *
+ * @param[in]
+ * s   - active connected socket-descriptor.
+ * buf - pointer to data buffer prepared by user.
+ * len - buffer size.
+ *
+ * @param[out]
+ *
+ * @return - number of bytes sent for success, 0 for failure.
+ */
+uint32_t Test_PalSend(tp_socket s, const uint8_t *buf,
+              size_t len);
+
+/******************************************************************************/
+/**
+ * @brief This function sends messages via a specified socket.
+ *
+ * @param[in]
+ * s   - active connected socket-descriptor.
+ * buf - pointer to data buffer prepared by user.
+ * len - buffer size.
+ *
+ * @param[out]
+ *
+ * @return - number of bytes sent for success, 0 for failure.
+ */
+uint32_t Test_PalSendTo(tp_socket s, const uint8_t *buf,
+            size_t len, const uint8_t *addr, uint32_t port);
+
+/******************************************************************************/
+/**
+ * @brief This function sends messages via a specified socket.
+ *
+ * @param[in]
+ * s   - active socket-descriptor.
+ * buf - pointer to data buffer prepared by user.
+ * len - buffer size.
+ *
+ * @param[out]
+ * addr   - received IP address.
+ * port   - received port number.
+ *
+ * @return - number of bytes recv for success, 0 for failure.
+ */
+uint32_t Test_PalRecvFrom(tp_socket s, const uint8_t *buf,
+            size_t len, uint8_t *addr, uint32_t *port);
+
+/******************************************************************************/
+/**
+ * @brief This function sends messages via a specified socket.
+ *
+ * @param[in]
+ * s   - active socket-descriptor.
+ * buf - pointer to data buffer prepared by user.
+ * len - buffer size.
+ *
+ * @param[out]
+ *
+ * @return - number of bytes recv for success, 0 for failure.
+ */
+uint32_t Test_PalRecv(tp_socket s, const uint8_t *buf,
+              size_t len);
+
+/******************************************************************************/
+/**
+ * @brief This function set the Byte Order and Endian of the host
+ * to network long.
+ *
+ * @param[in]
+ * val - value to convert.
+ *
+ * @param[out]
+ *
+ * @return - the converted value.
+ */
+uint32_t Test_PalHtonl(uint32_t val);
+
+/******************************************************************************/
+/**
+ * @brief This function set the Byte Order and Endian of the host
+ * to network short.
+ *
+ * @param[in]
+ * val - value to convert.
+ *
+ * @param[out]
+ *
+ * @return - the converted value.
+ */
+uint16_t Test_PalHtons(uint16_t val);
+
+/******************************************************************************/
+/**
+ * @brief This function set the Byte Order and Endian of the network
+ * to host long.
+ *
+ * @param[in]
+ * val - value to convert.
+ *
+ * @param[out]
+ *
+ * @return - the converted value.
+ */
+uint32_t Test_PalNtohl(uint32_t val);
+
+/******************************************************************************/
+/**
+ * @brief This function set the Byte Order and Endian of the network
+ * to host short.
+ *
+ * @param[in]
+ * val - value to convert.
+ *
+ * @param[out]
+ *
+ * @return - the converted value.
+ */
+uint16_t Test_PalNtohs(uint16_t val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TP_SOCKET_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_thread.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_thread.h
new file mode 100644
index 0000000..6d58972
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_thread.h
@@ -0,0 +1,150 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_THREAD_H_
+#define TEST_PAL_THREAD_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *ThreadHandle;
+
+/******************************************************************************/
+/*
+ * @brief This function returns the minimal stack size in bytes.
+ *
+ * @param[in]
+
+ * @param[out]
+ *
+ * @return - Minimal stack size in bytes.
+ */
+size_t Test_PalGetMinimalStackSize(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the highest thread priority.
+ *
+ * @param[in]
+
+ * @param[out]
+ *
+ * @return - Highest thread priority.
+ */
+uint32_t Test_PalGetHighestPriority(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the lowest thread priority.
+ *
+ * @param[in]
+
+ * @param[out]
+ *
+ * @return - Lowest thread priority.
+ */
+uint32_t Test_PalGetLowestPriority(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the default thread priority.
+ *
+ * @param[in]
+
+ * @param[out]
+ *
+ * @return - Default thread priority.
+ */
+uint32_t Test_PalGetDefaultPriority(void);
+
+/******************************************************************************/
+/*
+ * @brief This function creates a thread. The user should call
+ * Test_PalThreadJoin() in order to wait until the thread ends and then to
+ * Test_PalThreadDestroy() in order to free resources.
+ * In case of a thread without an end, the user shouldn't call
+ * Test_PalThreadJoin() which will not return. Instead, the user should call
+ * Test_PalThreadDestroy() which will cancel the thread and free
+ * its resources.
+ *
+ * @param[in]
+ * stackSize - Thread stack size in bytes. The allocated stack size will be the
+ * biggest between stackSize and the minimal stack size.
+ * threadFunc - Thread function. The function shall return a pointer to the
+ * returned value or NULL. In case TZM is supported, this function must have the
+ * same security attribute as TestAL's (either secure or non-secure).
+ * priority - Thread priority. Highest and lowest priorities can be received
+ * by calling Test_PalGetLowestPriority() and Test_PalGetHighestPriority()
+ * accordingly.
+ * args - Function input arguments.
+ * threadName - Thread name. Not in use for Linux.
+ * nameLen - Thread name length. Not in use for Linux.
+ * dmaAble - Determines whether the stack should be DMA-able (true)
+ * or not (false).
+ *
+ * @param[out]
+ *
+ * @return - threadHandle address for success, NULL for failure.
+ */
+ThreadHandle Test_PalThreadCreate(size_t stackSize,
+                  void *(*threadFunc)(void *),
+                  int priority, void *args,
+                  const char *threadName,
+                  uint8_t nameLen, uint8_t dmaAble);
+
+/******************************************************************************/
+/*
+ * @brief This function waits for a thread to terminate (BLOCKING).
+ * If that thread has already terminated it returns immediately.
+ *
+ * @param[in]
+ * threadHandle - Thread structure. Not in use for FreeRTOS.
+ * threadRet - A pointer to pointer to the returned value of the target thread.
+ * Note that threadRet is not changed, yet *threadRet is changed and
+ * can be NULL. Hence, the user shall not try accessing **threadRet without
+ * checking that *threadRet in not NULL.
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalThreadJoin(ThreadHandle threadHandle, void **threadRet);
+
+/******************************************************************************/
+/*
+ * @brief This function destroys a thread (if it's still running) and frees
+ * its resources.
+ * In order to free thread resources only after thread's end this function
+ * should be called after Test_PalThreadJoin.
+ * In order to cancel the thread immediately and free its resources, this
+ * function should be called alone (i.e. without Test_PalThreadJoin).
+ * It must eventually be called in any case.
+ * Note that this function doesn't deallocate the memory that the
+ * thread itself allocates. This needs to be done by the thread itself.
+ *
+ * @param[in]
+ * threadHandle - Thread structure.
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_PalThreadDestroy(ThreadHandle threadHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_THREAD_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_time.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_time.h
new file mode 100644
index 0000000..76eb6a0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/include/test_pal_time.h
@@ -0,0 +1,51 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#ifndef TEST_PAL_TIME_H_
+#define TEST_PAL_TIME_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************************************************************/
+/*
+ * @brief This function suspends execution of the calling thread
+ * for microsecond intervals.
+ *
+ * @param[in] time to suspend in microseconds.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_PalDelay(const uint32_t usec);
+
+/******************************************************************************/
+/*
+ * @brief This function returns a timestamp in milliseconds.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - timestamp in milliseconds.
+ */
+uint32_t Test_PalGetTimestamp(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* TEST_PAL_TIME_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_cli.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_cli.c
new file mode 100644
index 0000000..63c83a0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_cli.c
@@ -0,0 +1,32 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdint.h>
+#include "test_pal_cli.h"
+
+/******************************************************************************/
+uint32_t Test_PalCLIRegisterCommand(struct Test_PalCliCommand *commandToRegister)
+{
+    (void)commandToRegister;
+    return 0;
+}
+
+/******************************************************************************/
+const char *Test_PalCLIGetParameter(const char *commandString,
+            uint32_t wantedParamIndx, uint32_t *paramStringLength)
+{
+    (void)commandString;
+    (void)wantedParamIndx;
+    (void)paramStringLength;
+    return NULL;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_file.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_file.c
new file mode 100644
index 0000000..f872cdf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_file.c
@@ -0,0 +1,56 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include "test_pal_log.h"
+
+/******************************************************************************/
+size_t Test_PalFetchDataFromFile(const char *data_fname, uint8_t **data_pp)
+{
+    FILE *data_file;
+    size_t data_size = 0;
+    uint8_t *cur_buf_pos;
+    unsigned int tmp;
+
+    data_file = fopen(data_fname, "r");
+
+    if (data_file == NULL) {
+        TEST_PRINTF_ERROR("Failed opening %s\n", data_fname);
+        exit(1);
+    }
+
+    /* Data size is unknown so the first reading just for calculating the
+     * number of bytes */
+    while (!feof(data_file) && fscanf(data_file, "0x%02X,", &tmp))
+        data_size++;
+
+    if (data_size > 0) {
+        *data_pp = malloc(data_size);
+        if (*data_pp == NULL) {
+            TEST_PRINTF_ERROR("Failed allocating %d B for data"
+                    " of %s\n", (int)data_size, data_fname);
+            exit(1);
+        }
+        cur_buf_pos = *data_pp;
+        rewind(data_file);
+        while (!feof(data_file) && fscanf(data_file, "0x%02X,", &tmp)) {
+            *cur_buf_pos = tmp;
+            cur_buf_pos++;
+        }
+    }
+
+    fclose(data_file);
+
+    TEST_PRINTF_MESSAGE("Read %d B from %s\n", (int)data_size, data_fname);
+
+    return data_size;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_log.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_log.c
new file mode 100644
index 0000000..2938c0b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_log.c
@@ -0,0 +1,182 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include "test_pal_log.h"
+
+/******************************************************************************/
+void Test_PalPrintfError(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    if (function)
+        fprintf(stderr, "%s(): ", function);
+    vfprintf(stderr, format, args);
+    fprintf(stderr, "\n");
+    fflush(stderr);
+
+    va_end(args);
+}
+
+
+/******************************************************************************/
+void Test_PalFprintfError(void *fd, const char *function, const char *format, ...)
+{
+    FILE *fd_l = (FILE *)fd;
+    va_list args;
+
+    va_start(args, format);
+
+    if (function)
+        fprintf(fd_l, "%s(): ", function);
+    vfprintf(fd_l, format, args);
+    fprintf(fd_l, "\n");
+    fflush(fd_l);
+
+    if (function)
+        fprintf(stderr, "%s(): ", function);
+    vfprintf(stderr, format, args);
+    fprintf(stderr, "\n");
+    fflush(stderr);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalPrintfMessage(const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    vfprintf(stderr, format, args);
+    fflush(stderr);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalPrintf(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    if (function)
+        fprintf(stdout, "%s(): ", function);
+    vfprintf(stdout, format, args);
+    fflush(stdout);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalFprintf(void *fd, const char *function, const char *format, ...)
+{
+    FILE *fd_l = (FILE *)fd;
+    va_list args;
+
+    va_start(args, format);
+
+    if (function)
+        fprintf(fd_l, "%s(): ", function);
+    vfprintf(fd_l, format, args);
+    fflush(fd_l);
+
+    if (function)
+        fprintf(stdout, "%s(): ", function);
+    vfprintf(stdout, format, args);
+    fflush(stdout);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalPrintByteBuff(const char *function, const char *buffName,
+                    uint8_t *buff, uint32_t size)
+{
+    unsigned int i = 0;
+
+    Test_PalPrintf(function, "printing %s, byte size %d\n",
+                buffName, (unsigned int)size);
+    for (i = 0; i < size; i++) {
+        if (!(i%16))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%02X ",
+                (unsigned char)(*((unsigned char *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/******************************************************************************/
+void Test_PalFprintByteBuff(void *fd, const char *function,
+            const char *buffName, uint8_t *buff, uint32_t size)
+{
+    FILE *fd_l = (FILE *)fd;
+    unsigned int i = 0;
+
+    Test_PalFprintf(fd_l, function, "printing %s, byte size %d", buffName,
+                            (unsigned int)size);
+    for (i = 0; i < size; i++) {
+        if (!(i%16))
+            Test_PalFprintf(fd_l, NULL, "\n\t");
+        Test_PalFprintf(fd_l, NULL, "0x%02X ",
+                (unsigned char)(*((unsigned char *)buff+i)));
+    }
+    Test_PalFprintf(fd_l, NULL, "\n");
+}
+
+/******************************************************************************/
+void Test_PalFprintfByteBuffMax(void *fd, const char *function,
+    const char *buffName, uint8_t *buff, uint32_t size, uint32_t maxSize)
+{
+    int i = 0;
+    FILE *fd_l = (FILE *)fd;
+    int minSize = ((size > maxSize) ? maxSize:size);
+
+    Test_PalFprintf(fd_l, function, "printing %s, buff size %d, max size %d",
+            buffName, (unsigned int)size, (unsigned int)maxSize);
+
+    for (i = 0; i < minSize; i++) {
+        if (!(i%16))
+            Test_PalFprintf(fd_l, NULL, "\n\t");
+        Test_PalFprintf(fd_l, NULL, "0x%02X ",
+                (unsigned char)(*((unsigned char *)buff+i)));
+    }
+    Test_PalFprintf(fd_l, NULL, "\n");
+}
+
+/******************************************************************************/
+void Test_PalPrintWordBuff(const char *function, const char *buffName,
+                uint32_t *buff, uint32_t size)
+{
+    uint8_t i = 0;
+
+    Test_PalPrintf(function, "printing %s, word size %d\n", buffName,
+                            (unsigned int)size);
+    for (i = 0; i < size; i++) {
+        if (!(i%4))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%08X  ",
+                (unsigned int)(*((unsigned int *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/* inline void TEST_PRINT_BYTE_BUFFP(buffName, buff, size);
+   inline void TEST_FPRINT_LONG_NUM(const char *fd, const char *buffName,
+   uint32_t *buff, uint32_t size); */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_map_addrs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_map_addrs.c
new file mode 100644
index 0000000..36969b4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_map_addrs.c
@@ -0,0 +1,166 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include "test_pal_map_addrs.h"
+#include "test_pal_log.h"
+
+#define FD_MAX_NUM          10
+#define FD_FILENAME_MAX_LEN     50
+
+/* Each address has its own file descriptor for simplicity */
+struct FdInfo {
+    void    *physAddr;
+    void    *virtAddr;
+    char    filename[FD_FILENAME_MAX_LEN];
+    int fd;
+};
+
+static struct FdInfo fdList[FD_MAX_NUM] = { {0} };
+uint8_t fdNum = 0;
+
+static int Test_PalOpenFd(void *physAddr, const char *filename);
+static void Test_PalCloseFd(void *virtAddr);
+static void Test_SetMmapFlags(int *prot, int *flags, uint8_t bitMask);
+
+/******************************************************************************/
+void *Test_PalIOMap(void *physAddr, size_t size)
+{
+    return Test_PalMapAddr(physAddr, NULL, "/dev/mem", size,
+                     BM_READ|BM_WRITE|BM_SHARED);
+}
+
+/******************************************************************************/
+void *Test_PalMapAddr(void *physAddr, void *startingAddr, const char *filename,
+                size_t size, uint8_t protAndFlagsBitMask)
+{
+    int fdIndx = Test_PalOpenFd(physAddr, filename);
+    int prot = 0;
+    int flags = 0;
+
+    if (fdIndx < 0)
+        return NULL;
+
+    Test_SetMmapFlags(&prot, &flags, protAndFlagsBitMask);
+
+    fdList[fdIndx].virtAddr = mmap((unsigned long *)startingAddr,
+                size,
+                prot,
+                flags, /* must use MAP_FIXED to align
+                with secure boot image table */
+                fdList[fdIndx].fd,
+                (unsigned long)physAddr);
+
+    if (!VALID_MAPPED_ADDR((unsigned long)fdList[fdIndx].virtAddr)) {
+        Test_PalCloseFd(fdList[fdIndx].virtAddr);
+        return NULL;
+    }
+
+    return fdList[fdIndx].virtAddr;
+}
+
+/******************************************************************************/
+void Test_PalUnmapAddr(void *virtAddr, size_t size)
+{
+    Test_PalCloseFd(virtAddr);
+    munmap(virtAddr, size);
+}
+
+/******************************************************************************/
+/*              Internal API                      */
+/******************************************************************************/
+static int Test_PalOpenFd(void *physAddr, const char *filename)
+{
+    int i;
+    int fdIndx = -1;
+
+    /* Finds fd index in fdList */
+    for (i = 0; i < fdNum; i++) {
+        if (fdList[i].physAddr == physAddr)
+            fdIndx = i;
+    }
+
+    /* physAddr was not found. Adds a new fd to fdList */
+    if (fdIndx < 0) {
+        if (fdNum < FD_MAX_NUM) {
+            fdIndx = fdNum;
+            fdList[fdIndx].physAddr = physAddr;
+            fdList[fdIndx].virtAddr = 0;
+            memset(fdList[fdIndx].filename, 0, FD_FILENAME_MAX_LEN);
+            memcpy(fdList[fdIndx].filename, filename,
+                            FD_FILENAME_MAX_LEN);
+            fdList[fdIndx].fd = -1;
+            fdNum++;
+        } else {
+            TEST_PRINTF_ERROR("Error: Too many fd\n");
+            return -1;
+        }
+    }
+
+    /* Opens fd */
+    if (fdList[fdIndx].fd < 0) {
+        fdList[fdIndx].fd = open(fdList[fdIndx].filename,
+                        O_RDWR|O_SYNC);
+        if (fdList[fdIndx].fd < 0) {
+            TEST_PRINTF_ERROR("Error: Can not open %s\n",
+                    fdList[fdIndx].filename);
+            return -1;
+        }
+    }
+    return fdIndx;
+}
+
+/******************************************************************************/
+static void Test_PalCloseFd(void *virtAddr)
+{
+    int i;
+    int fdIndx = -1;
+
+    /* Finds fd index in fdList */
+    for (i = 0; i < fdNum; i++) {
+        if (fdList[i].virtAddr == virtAddr)
+            fdIndx = i;
+    }
+
+    /* physAddr was found. Close fd if necessary. */
+    if ((fdIndx >= 0) && (fdList[fdIndx].fd >= 0)) {
+        close(fdList[fdIndx].fd);
+        fdList[fdIndx].fd = -1;
+    }
+}
+
+/******************************************************************************/
+static void Test_SetMmapFlags(int *prot, int *flags, uint8_t bitMask)
+{
+    if (bitMask & BM_READ)
+        *prot |= PROT_READ;
+    if (bitMask & BM_WRITE)
+        *prot |= PROT_WRITE;
+    if (bitMask & BM_EXEC)
+        *prot |= PROT_EXEC;
+    if (bitMask & BM_NONE)
+        *prot |= PROT_NONE;
+    if (bitMask & BM_SHARED)
+        *flags |= MAP_SHARED;
+    if (bitMask & BM_PRIVATE)
+        *flags |= MAP_PRIVATE;
+    if (bitMask & BM_FIXED)
+        *flags |= MAP_FIXED;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_mem.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_mem.c
new file mode 100644
index 0000000..cee8192
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_mem.c
@@ -0,0 +1,168 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include "test_pal_log.h"
+#include "test_pal_mem.h"
+
+#define RESERVED_STACK      500000
+
+static unsigned long dmableBaseAddr = 0;
+static unsigned long unmanagedBaseAddr = 0;
+static unsigned long dmableEndAddr = 0;
+static unsigned long nextToAlloc = 0;
+
+static uint8_t memInitialised = 0;
+pthread_mutex_t testMemMutex;
+
+/******************************************************************************/
+void *Test_PalMalloc(size_t size)
+{
+    if (!size)
+        return NULL;
+
+    return malloc(size);
+}
+
+/******************************************************************************/
+void Test_PalFree(void *pvAddress)
+{
+    if (pvAddress == NULL)
+        return;
+
+    free(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalRealloc(void *pvAddress, size_t newSize)
+{
+    if (pvAddress == NULL)
+        return NULL;
+
+    return realloc(pvAddress, newSize);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferAlloc(size_t size)
+{
+    unsigned long currAddr;
+    unsigned long bitShiftOffset = (1UL << 4);
+    unsigned long maskAlignAddr = (-1UL)&(~(bitShiftOffset-1));
+
+    if(!size) {
+        TEST_PRINTF_ERROR("Size cannot be zero");
+        goto end_with_error;
+    }
+
+    /* increase size with the requested alignment in our case 0x10 */
+    size += bitShiftOffset;
+
+    if((dmableBaseAddr == 0) || (dmableEndAddr == 0)) {
+        TEST_PRINTF_ERROR("DMA memory allocator wasn't initialized");
+        goto end_with_error;
+    }
+
+    /* Exceeds the maximum memory size */
+    if(nextToAlloc + size > dmableEndAddr) {
+        nextToAlloc = dmableBaseAddr + RESERVED_STACK;
+
+        if(nextToAlloc + size > dmableEndAddr) {
+            TEST_PRINTF_ERROR("End of range! size needs to be less "
+                "than %d",(dmableEndAddr - nextToAlloc));
+            goto end_with_error;
+        }
+    }
+
+    if (pthread_mutex_lock(&testMemMutex) != 0) {
+        TEST_PRINTF_ERROR("pthread_mutex_lock failed");
+        goto end_with_error;
+    }
+
+    currAddr = nextToAlloc;
+    nextToAlloc += size;
+
+    if(pthread_mutex_unlock(&testMemMutex) != 0) {
+        nextToAlloc -= size;
+        goto end_with_error;
+    }
+    currAddr = (currAddr + bitShiftOffset) & maskAlignAddr;
+
+    return (void *)(currAddr);
+
+end_with_error:
+    return NULL;
+}
+
+/******************************************************************************/
+void Test_PalDMAContigBufferFree(void *pvAddress)
+{
+    (void)pvAddress;
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferRealloc(void *pvAddress, size_t newSize)
+{
+    (void)pvAddress;
+    (void)newSize;
+    return NULL;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetDMABaseAddr(void)
+{
+    return dmableBaseAddr;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetUnmanagedBaseAddr(void)
+{
+    return unmanagedBaseAddr;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemInit(unsigned long newDMABaseAddr,
+             unsigned long newUnmanagedBaseAddr,
+             size_t DMAsize)
+{
+    if(memInitialised) {
+        TEST_PRINTF_ERROR("Memory is already initialised");
+        return 1;
+    }
+
+    dmableBaseAddr = newDMABaseAddr;
+    dmableEndAddr = newDMABaseAddr + DMAsize;
+    nextToAlloc = newDMABaseAddr;
+    unmanagedBaseAddr = newUnmanagedBaseAddr;
+    memInitialised = 1;
+
+    if(pthread_mutex_init(&testMemMutex, NULL) != 0) {
+        TEST_PRINTF_ERROR("pthread_mutex_init failed");
+        return 1;
+    }
+
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemFin(void)
+{
+    if(pthread_mutex_destroy(&testMemMutex) != 0) {
+        TEST_PRINTF_ERROR("pthread_mutex_destroy failed");
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_semphr.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_semphr.c
new file mode 100644
index 0000000..9fc003a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_semphr.c
@@ -0,0 +1,155 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <pthread.h>
+#include "test_pal_semphr.h"
+#include "test_pal_mem.h"
+#include "test_pal_log.h"
+
+struct binary_semaphore {
+    pthread_mutex_t mutex;
+    pthread_cond_t cvar;
+    int val;
+};
+
+typedef struct binary_semaphore *pBinary_semaphore;
+
+/******************************************************************************/
+uint8_t Test_PalMutexCreate(Test_PalMutex *ppMutexId)
+{
+    pthread_mutex_t *mtx = Test_PalMalloc(sizeof(pthread_mutex_t));
+    if (mtx == NULL)
+        return 1;
+
+    if (pthread_mutex_init(mtx, NULL)) {
+        Test_PalFree(mtx);
+        return 1;
+    }
+
+    *ppMutexId = mtx;
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexDestroy(Test_PalMutex *ppMutexId)
+{
+    pthread_mutex_t *mtx = *ppMutexId;
+    if (pthread_mutex_destroy(mtx))
+        return 1;
+
+    Test_PalFree(mtx);
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexLock(Test_PalMutex *ppMutexId, uint32_t timeout)
+{
+    pthread_mutex_t *mtx = *ppMutexId;
+    (void)timeout;
+    return pthread_mutex_lock(mtx) ? 1 : 0 ;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexUnlock(Test_PalMutex *ppMutexId)
+{
+    pthread_mutex_t *mtx = *ppMutexId;
+    return pthread_mutex_unlock(mtx) ? 1 : 0 ;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreCreate(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    pBinary_semaphore pLocal = Test_PalMalloc(
+                    sizeof(struct binary_semaphore));
+    if (pLocal == NULL)
+        return 1;
+
+    if (pthread_mutex_init(&pLocal->mutex, NULL)) {
+        Test_PalFree(pLocal);
+        return 1;
+    }
+
+    pthread_cond_init(&pLocal->cvar, NULL);
+    pLocal->val = 0;
+    *ppBinSemphrId = pLocal;
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreDestroy(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    pBinary_semaphore pLocal = *ppBinSemphrId;
+
+    pthread_cond_destroy(&pLocal->cvar);
+
+    if (pthread_mutex_destroy(&pLocal->mutex))
+        return 1;
+
+    Test_PalFree(pLocal);
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreTake(Test_PalBinarySemaphore *ppBinSemphrId,
+                            uint32_t timeout)
+{
+    pBinary_semaphore pLocal = *ppBinSemphrId;
+    struct timeval tod;
+    struct timespec ts;
+
+    pthread_mutex_lock(&pLocal->mutex);
+
+    while (!pLocal->val) {
+        if (timeout == INFINITE) {
+            pthread_cond_wait(&pLocal->cvar, &pLocal->mutex);
+        } else {
+            gettimeofday(&tod, NULL);
+            ts.tv_sec = time(NULL) + timeout / 1000;
+            ts.tv_nsec = tod.tv_usec * 1000 + 1000 * 1000 * (timeout % 1000);
+            ts.tv_sec += ts.tv_nsec / (1000 * 1000 * 1000);
+            ts.tv_nsec %= (1000 * 1000 * 1000);
+
+            if (pthread_cond_timedwait(&pLocal->cvar,
+            &pLocal->mutex, (const struct timespec *)&ts)) {
+                pthread_mutex_unlock(&pLocal->mutex);
+                return 1;
+            }
+        }
+    }
+
+    pLocal->val -= 1;
+
+    pthread_mutex_unlock(&pLocal->mutex);
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreGive(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    pBinary_semaphore pLocal = *ppBinSemphrId;
+
+    pthread_mutex_lock(&pLocal->mutex);
+
+    if (pLocal->val == 1) {
+        pthread_mutex_unlock(&pLocal->mutex);
+        return 1;
+    }
+
+    pLocal->val += 1;
+    pthread_cond_signal(&pLocal->cvar);
+
+    pthread_mutex_unlock(&pLocal->mutex);
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_socket.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_socket.c
new file mode 100644
index 0000000..44f628b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_socket.c
@@ -0,0 +1,253 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+#include <stdint.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include <sys/types.h>
+#include <netdb.h>
+#include <stdlib.h>
+
+#include "test_pal_socket.h"
+#include "test_pal_mem.h"
+
+/******************************************************************************/
+uint32_t Test_PalSocket(tp_socket *s, enum tp_sock_domain domain,
+        enum tp_sock_type type, enum tp_sock_protocol protocol,
+        const uint32_t recvTimeout_ms)
+{
+    int sfd;
+    int xDomain;
+    int xType;
+    int xProtocol;
+    (void)recvTimeout_ms;
+
+    if (s == NULL)
+        return 1;
+
+    /* initial the socket parameters */
+    xDomain = (domain == TP_AF_INET) ? AF_INET : 0;
+    xType   = (type == TP_SOCK_DGRAM) ? SOCK_DGRAM : SOCK_STREAM;
+    xProtocol = (protocol == TP_IPPROTO_UDP) ? IPPROTO_UDP : IPPROTO_TCP;
+    /* Attempt to open the socket. */
+    sfd = socket(xDomain, xType, xProtocol);
+    if (sfd == -1)
+        return 1;
+    *s = sfd;
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalCloseSocket(tp_socket s)
+{
+    int sfd = (int)s;
+
+    close(sfd);
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalConnect(tp_socket s, const uint8_t *addr, uint32_t port)
+{
+    struct addrinfo hints;
+    struct addrinfo *srv;
+    int sfd = (int)s;
+    char   portstr[10];
+    int32_t rc;
+
+    sprintf(portstr, "%d", port);
+    memset(&hints, 0, sizeof(struct addrinfo));
+    hints.ai_family = AF_INET;
+    hints.ai_socktype = SOCK_STREAM;
+
+    /* Set the IP address and port of the remote socket
+    to which this client socket will transmit. */
+    if (getaddrinfo((const char *)addr, portstr, &hints, &srv) != 0) {
+        /* failed to initiate the address */
+        return 1;
+    }
+
+    /* Connect to the remote socket.  The socket has not previously been
+    bound to a local port number so will get automatically bound to a
+    local port inside function. */
+    rc = connect(sfd, srv->ai_addr, srv->ai_addrlen);
+    return (rc == -1) ? 1 : 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalBind(tp_socket s, uint32_t port)
+{
+    struct sockaddr_in saddr;
+    int sfd = (int)s;
+
+    memset(&saddr, 0, sizeof(saddr));
+    saddr.sin_family = AF_INET;
+    /* indicate to use the local ip addr */
+    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    /* Set the listening port  */
+    saddr.sin_port = htons(port);
+    /* bind the local port & IP to the socket */
+    if (bind(sfd, (struct sockaddr *) &saddr,
+        sizeof(saddr)) < 0) {
+        return 1;
+    }
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalListen(tp_socket s, uint32_t backlog)
+{
+    int rc;
+    int sockfd = (int)s;
+
+    rc = listen(sockfd, (int)backlog);
+    return (rc == 0) ? 0 : 1;
+}
+
+/******************************************************************************/
+uint32_t Test_PalAccept(tp_socket s, tp_socket *acptS, uint8_t *addr,
+             uint32_t *port)
+{
+    struct sockaddr_in si;
+    int sfd = (int)s;
+    int acceptedSocket;
+    socklen_t silen = sizeof(si);
+    char *addrstr;
+
+    acceptedSocket = accept(sfd, (struct sockaddr *)&si, &silen);
+
+    if (acceptedSocket > 0) {
+        /* Data was received from the socket.
+        copy IP address converting it to a string. */
+        addrstr = inet_ntoa(si.sin_addr);
+        if (addrstr == NULL)
+            return 0;
+        strcpy((char *)addr, addrstr);
+        /* update the received port number */
+        *port = ntohs(si.sin_port);
+        *acptS = acceptedSocket;
+        return 0;
+    }
+    return 1;
+}
+
+/******************************************************************************/
+tp_socket Test_PalShutdown(tp_socket s)
+{
+    uint32_t rc = 0;
+    /* shutdown active close before close */
+    rc = shutdown(s, SHUT_RDWR);
+    return (rc == 0) ? 0 : 1;
+}
+
+/******************************************************************************/
+uint32_t Test_PalSend(tp_socket s, const uint8_t *buf,
+            size_t len)
+{
+    uint32_t byteSent = 0;
+    int sfd = (int)s;
+    /* Send message size */
+    byteSent = (uint32_t)send(sfd, buf,
+                len, 0);
+    return byteSent;
+}
+
+/******************************************************************************/
+uint32_t Test_PalSendTo(tp_socket s, const uint8_t *buf,
+            size_t len, const uint8_t *addr, uint32_t port)
+{
+    uint32_t byteSent = 0;
+    int sfd = (int)s;
+    /* Send message size */
+    struct sockaddr_in xDestAddr;
+    socklen_t xDestAddrLen = sizeof(xDestAddr);
+    /* Fill in the destination address and port number */
+    inet_aton((const char *)addr, &xDestAddr.sin_addr);
+    xDestAddr.sin_port = htons(port);
+    /* Send the buffer with ulFlags set to 0 */
+    byteSent = sendto(sfd, buf, len,
+                0, (const struct sockaddr *)(&xDestAddr),
+                xDestAddrLen);
+    /* check that byte had been successfully queued for sending */
+    return (byteSent == len) ? byteSent : 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalRecvFrom(tp_socket s, const uint8_t *buf,
+            size_t len, uint8_t *addr, uint32_t *port)
+{
+    struct sockaddr_in si;
+    int32_t byteRecv;
+    int sfd = (int)s;
+    socklen_t silen = sizeof(si);
+    char *addrstr;
+
+    /* Receive into the buffer with ulFlags set to 0,
+    so the FREERTOS_ZERO_COPY bit is clear. */
+    byteRecv = recvfrom(sfd, (void *)buf, len,
+            0, (struct sockaddr *)&si, &silen);
+
+    if (byteRecv > 0) {
+        /* Data was received from the socket.
+        copy IP address converting it to a string. */
+        addrstr = inet_ntoa(si.sin_addr);
+        if (addrstr == NULL)
+            return 0;
+        strcpy((char *)addr, addrstr);
+        /* update the received port number */
+        *port = ntohs(si.sin_port);
+        return byteRecv;
+    }
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalRecv(tp_socket s, const uint8_t *buf,
+              size_t len)
+{
+    int32_t byteRecv;
+    int sfd = (int)s;
+
+    /* Receive into the buffer with ulFlags set to 0,
+    so the FREERTOS_ZERO_COPY bit is clear. */
+    byteRecv = recv(sfd, (void *)buf, len,
+            0);
+    /* in case of error return 0 */
+    return (byteRecv > 0) ? byteRecv : 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalHtonl(uint32_t val)
+{
+    return htonl(val);
+}
+
+/******************************************************************************/
+uint16_t Test_PalHtons(uint16_t val)
+{
+    return htons(val);
+}
+
+/******************************************************************************/
+uint32_t Test_PalNtohl(uint32_t val)
+{
+    return ntohl(val);
+}
+
+/******************************************************************************/
+uint16_t Test_PalNtohs(uint16_t val)
+{
+    return ntohs(val);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_thread.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_thread.c
new file mode 100644
index 0000000..26fe284
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_thread.c
@@ -0,0 +1,241 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+
+#include "test_pal_thread.h"
+#include "test_pal_mem.h"
+#include "test_pal_log.h"
+
+
+struct ThreadStr {
+    pthread_t   threadId;   /* Thread ID */
+
+    void        *(*threadFunc)(void *); /* thread function pointer */
+
+    void        *arg;       /* Arguments received by thread
+                     * function. */
+
+    void        *stackAddrToFree; /* Stack Address that needs to be
+                       * freed. If NULL, stack is not
+                       * dma-able and was allocated by
+                       * the OS. */
+
+    uint8_t     isJoined;   /* Indicates whether pthread_join
+                     * was called or not. This function is
+                     * necessary for cleaning up any
+                     * resources associated with the thread.
+                     * Can be called only once. */
+
+    uint8_t     isCompleted;    /* Indicates whether the thread finished
+                     * to run. */
+};
+
+/* minimum stack size is 1MB */
+#define LINUX_MINIMAL_STACK_SIZE_BYTES  0x100000
+/* stack alignment to page size */
+#define STACK_ALIGN         (sysconf(_SC_PAGESIZE))
+
+/******************************************************************************/
+void *Test_PalThreadFunc(void *ctx)
+{
+    struct ThreadStr *threadStr = ctx;
+    void *ret = NULL;
+
+    /* The thread is cancelable */
+    if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL)) {
+        TEST_PRINTF_ERROR("pthread_setcancelstate failed\n");
+        goto exit;
+    }
+
+    /* The thread can be cancelled at any time. */
+    if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) {
+        TEST_PRINTF_ERROR("pthread_setcanceltype failed\n");
+        goto exit;
+    }
+
+    ret = threadStr->threadFunc(threadStr->arg);
+    threadStr->isCompleted = true;
+
+exit:
+    pthread_exit(ret);
+    /*Should not reach here. The line below prevents a compilation warning*/
+    return ret;
+}
+
+/******************************************************************************/
+size_t Test_PalGetMinimalStackSize(void)
+{
+    return LINUX_MINIMAL_STACK_SIZE_BYTES;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetHighestPriority(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetLowestPriority(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetDefaultPriority(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+ThreadHandle Test_PalThreadCreate(size_t stackSize,
+                  void *(*threadFunc)(void *),
+                  int priority, void *arg,
+                  const char *threadName,
+                  uint8_t nameLen, uint8_t dmaAble)
+{
+    (void)threadName;
+    (void)nameLen;
+    (void)priority;
+    struct ThreadStr *threadStr = NULL;
+    void *stackAddr = NULL;
+    pthread_attr_t attr;
+
+    /* Checks argument validity */
+    if (stackSize < LINUX_MINIMAL_STACK_SIZE_BYTES) {
+        TEST_PRINTF_ERROR("Stack size is too small. Changed to "
+                "minimal stack size in bytes: 0x%08lx\n",
+                LINUX_MINIMAL_STACK_SIZE_BYTES);
+        stackSize = LINUX_MINIMAL_STACK_SIZE_BYTES;
+    }
+
+    /* Allocates ThreadStr */
+    threadStr = Test_PalMalloc(sizeof(struct ThreadStr));
+    if (threadStr == NULL) {
+        TEST_PRINTF_ERROR("threadStr allocation failed\n");
+        goto error;
+    }
+
+    /* Initializes thread attribute */
+    if (pthread_attr_init(&attr) != 0) {
+        TEST_PRINTF_ERROR("pthread_attr_init failed\n");
+        goto error_freeStr;
+    }
+
+    /* Initializes ThreadStr */
+    threadStr->threadFunc = threadFunc;
+    threadStr->arg = arg;
+    threadStr->stackAddrToFree = NULL;
+    threadStr->isJoined = false;
+    threadStr->isCompleted = false;
+
+    /* Allocates thread stack */
+    if (dmaAble) {
+        /* Allocate the stack + extra for page alignment */
+        threadStr->stackAddrToFree = Test_PalDMAContigBufferAlloc(
+                stackSize + LINUX_MINIMAL_STACK_SIZE_BYTES);
+        if (threadStr->stackAddrToFree == NULL) {
+            TEST_PRINTF_ERROR("thread stack allocation failed\n");
+            goto error_freeStr;
+        }
+        /* Align stack size to be multiple of page size. */
+        stackAddr = (void *)(threadStr->stackAddrToFree +
+                    STACK_ALIGN - 1);
+        stackAddr = (void *)((size_t)stackAddr & (-STACK_ALIGN));
+
+        if (pthread_attr_setstack(&attr, stackAddr, stackSize) != 0) {
+            TEST_PRINTF_ERROR("pthread_attr_setstack failed\n");
+            goto error_freeAll;
+        }
+    }
+    else {
+        if (pthread_attr_setstacksize(&attr, stackSize) != 0) {
+            TEST_PRINTF_ERROR("pthread_attr_setstacksize failed\n");
+            goto error_freeStr;
+        }
+    }
+
+    /* Creates thread */
+    if (pthread_create(&threadStr->threadId, &attr,
+               Test_PalThreadFunc, threadStr)) {
+        TEST_PRINTF_ERROR("pthread_create failed\n");
+        goto error_freeAll;
+    }
+
+    /* Cannot free thread stack and context in case destroy attribute
+     * fails as the thread is already running */
+    if (pthread_attr_destroy(&attr))
+        TEST_PRINTF_ERROR("pthread_attr_destroy failed\n");
+
+    return threadStr;
+
+error_freeAll:
+    if (dmaAble)
+        Test_PalDMAContigBufferFree(threadStr->stackAddrToFree);
+error_freeStr:
+    Test_PalFree(threadStr);
+error:
+    return NULL;
+}
+
+/******************************************************************************/
+uint32_t Test_PalThreadJoin(ThreadHandle threadHandle, void **threadRet)
+{
+    struct ThreadStr *threadStr = (struct ThreadStr *)threadHandle;
+
+    /* Calling to pthread_join. threadRet is not changed. *threadRet is
+       Changed and can be set to NULL */
+    if (pthread_join(threadStr->threadId, threadRet)) {
+        TEST_PRINTF_ERROR("pthread_join failed\n");
+        return 1;
+    }
+
+    threadStr->isJoined = true;
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalThreadDestroy(ThreadHandle threadHandle)
+{
+    struct ThreadStr *threadStr = (struct ThreadStr *)threadHandle;
+
+    if (threadStr->isCompleted == false) {
+        if (pthread_cancel(threadStr->threadId)) {
+            TEST_PRINTF_ERROR("pthread_cancel failed\n");
+            return 1;
+        }
+        threadStr->isCompleted = true;
+    }
+
+    /* pthread_join is necessary for cleaning up any resources associated
+     * with the thread. Can be called only once */
+    if (threadStr->isJoined == false) {
+        /* Cannot return because thread is already cancelled.
+         * Must continue freeing resources */
+        if (pthread_join(threadStr->threadId, NULL)) {
+            TEST_PRINTF_ERROR("pthread_join failed\n");
+        }
+        threadStr->isJoined = true;
+    }
+
+    /* Frees stack only in case its Dma-able */
+    if (threadStr->stackAddrToFree != NULL)
+        Test_PalDMAContigBufferFree(threadStr->stackAddrToFree);
+
+    Test_PalFree(threadStr);
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_time.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_time.c
new file mode 100644
index 0000000..29b3d29
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/linux/test_pal_time.c
@@ -0,0 +1,37 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "test_pal_time.h"
+
+/******************************************************************************/
+void Test_PalDelay(const uint32_t usec)
+{
+    usleep(usec);
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetTimestamp(void)
+{
+    struct timeval te;
+    uint32_t ms;
+
+    /* Gets current time */
+    gettimeofday(&te, NULL);
+
+    /* Calculates timestamp in milliseconds */
+    ms = te.tv_sec*1000LL + te.tv_usec/1000;
+
+    return ms;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_log.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_log.c
new file mode 100644
index 0000000..c8f6e54
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_log.c
@@ -0,0 +1,135 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include "test_pal_log.h"
+
+/******************************************************************************/
+void Test_PalPrintfError(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    printf("%s(): ", function);
+    vprintf(format, args);
+    printf("\n");
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalFprintfError(void *fd, const char *function, const char *format, ...)
+{
+    (void)fd;
+    (void)function;
+    (void)format;
+}
+
+/******************************************************************************/
+void Test_PalPrintfMessage(const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    vprintf(format, args);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalPrintf(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    if (function)
+        printf("%s(): ", function);
+    vprintf(format, args);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalFprintf(void *fd, const char *function, const char *format, ...)
+{
+    (void)fd;
+    (void)function;
+    (void)format;
+}
+
+/******************************************************************************/
+void Test_PalPrintByteBuff(const char *function, const char *buffName,
+                uint8_t *buff, uint32_t size)
+{
+    unsigned int i = 0;
+
+    Test_PalPrintf(function, "printing %s, byte size %d\n", buffName,
+            (unsigned int)size);
+
+    for (i = 0; i < size; i++) {
+        if (!(i%16))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%02X ",
+                (unsigned char)(*((unsigned char *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/******************************************************************************/
+void Test_PalFprintByteBuff(void *fd, const char *function,
+            const char *buffName, uint8_t *buff, uint32_t size)
+{
+    (void)fd;
+    (void)function;
+    (void)buffName;
+    (void)buff;
+    (void)size;
+}
+
+/******************************************************************************/
+void Test_PalFprintfByteBuffMax(void *fd, const char *function,
+    const char *buffName, uint8_t *buff, uint32_t size, uint32_t maxSize)
+{
+    (void)fd;
+    (void)function;
+    (void)buffName;
+    (void)buff;
+    (void)size;
+    (void)maxSize;
+}
+
+/******************************************************************************/
+void Test_PalPrintWordBuff(const char *function, const char *buffName,
+                uint32_t *buff, uint32_t size)
+{
+    uint8_t i = 0;
+
+    Test_PalPrintf(function, "printing %s, word size %d\n", buffName,
+                            (uint32_t)size);
+    for (i = 0; i < size; i++) {
+        if (!(i%4))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%08X  ",
+                (unsigned int)(*((unsigned int *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/* inline void TEST_PRINT_BYTE_BUFFP(buffName, buff, size);
+   inline void TEST_FPRINT_LONG_NUM(const char *fd, const char *buffName,
+   uint32_t *buff, uint32_t size); */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_map_addrs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_map_addrs.c
new file mode 100644
index 0000000..58538cd
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_map_addrs.c
@@ -0,0 +1,44 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "test_pal_map_addrs.h"
+
+/******************************************************************************/
+void *Test_PalIOMap(void *physAddr, size_t size)
+{
+    (void)size;
+    return physAddr;
+}
+
+/******************************************************************************/
+void *Test_PalMapAddr(void *physAddr, void *startingAddr, const char *filename,
+                size_t size, uint8_t protAndFlagsBitMask)
+{
+    (void)startingAddr;
+    (void)filename;
+    (void)size;
+    (void)protAndFlagsBitMask;
+    return physAddr;
+}
+
+/******************************************************************************/
+void Test_PalUnmapAddr(void *virtAddr, size_t size)
+{
+    (void)virtAddr;
+    (void)size;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_mem.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_mem.c
new file mode 100644
index 0000000..ea97cc8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_mem.c
@@ -0,0 +1,105 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include "test_pal_log.h"
+#include "test_pal_mem.h"
+
+static unsigned long unmanagedBaseAddr = 0;
+static uint8_t memInitialised = 0;
+
+/******************************************************************************/
+void *Test_PalMalloc(size_t size)
+{
+    if (!size)
+        return NULL;
+
+    return malloc(size);
+}
+
+/******************************************************************************/
+void Test_PalFree(void *pvAddress)
+{
+    if (pvAddress == NULL)
+        return;
+
+    free(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalRealloc(void *pvAddress, size_t newSize)
+{
+    if (pvAddress == NULL)
+        return NULL;
+
+    return realloc(pvAddress, newSize);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferAlloc(size_t size)
+{
+    return Test_PalMalloc(size);
+}
+
+/******************************************************************************/
+void Test_PalDMAContigBufferFree(void *pvAddress)
+{
+    Test_PalFree(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferRealloc(void *pvAddress, size_t newSize)
+{
+    return Test_PalRealloc(pvAddress, newSize);
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetDMABaseAddr(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetUnmanagedBaseAddr(void)
+{
+    return unmanagedBaseAddr;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemInit(unsigned long newDMABaseAddr,
+             unsigned long newUnmanagedBaseAddr,
+             size_t DMAsize)
+{
+    if(memInitialised) {
+        TEST_PRINTF_ERROR("Memory is already initialised");
+        return 1;
+    }
+
+    (void)newDMABaseAddr;
+    (void)DMAsize;
+    unmanagedBaseAddr = newUnmanagedBaseAddr;
+    memInitialised = 1;
+
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemFin(void)
+{
+    unmanagedBaseAddr = 0;
+    memInitialised = 0;
+
+    return 0;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_time.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_time.c
new file mode 100644
index 0000000..2342127
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/mbedos/test_pal_time.c
@@ -0,0 +1,27 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include "cmsis_os2.h"
+#include "mbed_wait_api.h"
+#include "test_pal_time.h"
+
+/******************************************************************************/
+void Test_PalDelay(const uint32_t usec)
+{
+    wait_us((int)usec);
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetTimestamp(void)
+{
+    return (us_ticker_read() / 1000);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/board_addrs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/board_addrs.c
new file mode 100644
index 0000000..92a085a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/board_addrs.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "board_addrs.h"
+
+/******************************************************************************/
+unsigned long MPS2_GetDMAbaseAddr(void)
+{
+    return (unsigned long)MPS2_PLUS_MEM_DMA_BASE_ADDR;
+}
+
+/******************************************************************************/
+unsigned long MPS2_GetDMAAreaLen(void)
+{
+    return (unsigned long)MPS2_PLUS_MEM_DMA_AREA_LEN;
+}
+
+/******************************************************************************/
+unsigned long MPS2_GetUnmanagedbaseAddr(void)
+{
+    return (unsigned long)MPS2_PLUS_MEM_UNMANAGED_BASE_ADDR;
+}
+
+/******************************************************************************/
+unsigned long MPS2_GetUnmanagedAreaLen(void)
+{
+    return (unsigned long)MPS2_PLUS_MEM_UNMANAGED_AREA_LEN;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/board_addrs.h b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/board_addrs.h
new file mode 100644
index 0000000..39515b6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/board_addrs.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef _BOARD_ADDRS_
+#define _BOARD_ADDRS_
+
+/* Stored in TestAL only for no_os
+ * In other cases, these are stored in kernel's directory */
+
+#define MPS2_PLUS_MEM_SYSTEM_RAM            0x20000000
+#define MPS2_PLUS_MEM_SYSTEM_RAM_LEN        0x007FFFFF
+
+#define MPS2_PLUS_MEM_PSRAM                 0x21000000
+#define MPS2_PLUS_MEM_PSRAM_LEN             0x21FFFFFF /* 16MB */
+
+#define MPS2_PLUS_MEM_UNMANAGED_BASE_ADDR   MPS2_PLUS_MEM_PSRAM
+#define MPS2_PLUS_MEM_UNMANAGED_AREA_LEN    0x001FFFFF /* 2MB */
+
+#define MPS2_PLUS_MEM_DMA_BASE_ADDR         0x21200000
+#define MPS2_PLUS_MEM_DMA_AREA_LEN          0x00DFFFFF /* 14MB */
+
+/******************************************************************************/
+/* board_addrs.h definitions are supposed to be used by other projects.
+ * Some of them are supplied after compilation (e.g. TestAL).
+ * The following getter functions were created in order to allow the ability
+ * to change definitions values without forcing additional compilation
+ * of the dependent projects.
+ */
+/******************************************************************************/
+/*
+ * @brief This function returns the DMA base address, i.e. the start address
+ * of the DMA region.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - MPS2_PLUS_MEM_DMA_BASE_ADDR.
+ */
+unsigned long MPS2_GetDMAbaseAddr(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the DMA region length.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - MPS2_PLUS_MEM_DMA_AREA_LEN.
+ */
+unsigned long MPS2_GetDMAAreaLen(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the unmanaged base address.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - MPS2_PLUS_MEM_UNMANAGED_BASE_ADDR.
+ */
+unsigned long MPS2_GetUnmanagedbaseAddr(void);
+
+/******************************************************************************/
+/*
+ * @brief This function returns the unmanaged region length.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return - MPS2_PLUS_MEM_UNMANAGED_AREA_LEN.
+ */
+unsigned long MPS2_GetUnmanagedAreaLen(void);
+
+#endif // _BOARD_ADDRS_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_cli.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_cli.c
new file mode 100644
index 0000000..088aa45
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_cli.c
@@ -0,0 +1,27 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include "test_pal_cli.h"
+
+/******************************************************************************/
+uint32_t Test_PalCLIRegisterCommand(struct Test_PalCliCommand *commandToRegister)
+{
+    return 0;
+}
+
+/******************************************************************************/
+const char *Test_PalCLIGetParameter(const char *commandString,
+            uint32_t wantedParamIndx, uint32_t *paramStringLength)
+{
+    return NULL;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_file.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_file.c
new file mode 100644
index 0000000..4032960
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_file.c
@@ -0,0 +1,20 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/******************************************************************************/
+size_t Test_PalFetchDataFromFile(const char *data_fname, uint8_t **data_pp)
+{
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_log.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_log.c
new file mode 100644
index 0000000..c8f6e54
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_log.c
@@ -0,0 +1,135 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include "test_pal_log.h"
+
+/******************************************************************************/
+void Test_PalPrintfError(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    printf("%s(): ", function);
+    vprintf(format, args);
+    printf("\n");
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalFprintfError(void *fd, const char *function, const char *format, ...)
+{
+    (void)fd;
+    (void)function;
+    (void)format;
+}
+
+/******************************************************************************/
+void Test_PalPrintfMessage(const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    vprintf(format, args);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalPrintf(const char *function, const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+
+    if (function)
+        printf("%s(): ", function);
+    vprintf(format, args);
+
+    va_end(args);
+}
+
+/******************************************************************************/
+void Test_PalFprintf(void *fd, const char *function, const char *format, ...)
+{
+    (void)fd;
+    (void)function;
+    (void)format;
+}
+
+/******************************************************************************/
+void Test_PalPrintByteBuff(const char *function, const char *buffName,
+                uint8_t *buff, uint32_t size)
+{
+    unsigned int i = 0;
+
+    Test_PalPrintf(function, "printing %s, byte size %d\n", buffName,
+            (unsigned int)size);
+
+    for (i = 0; i < size; i++) {
+        if (!(i%16))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%02X ",
+                (unsigned char)(*((unsigned char *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/******************************************************************************/
+void Test_PalFprintByteBuff(void *fd, const char *function,
+            const char *buffName, uint8_t *buff, uint32_t size)
+{
+    (void)fd;
+    (void)function;
+    (void)buffName;
+    (void)buff;
+    (void)size;
+}
+
+/******************************************************************************/
+void Test_PalFprintfByteBuffMax(void *fd, const char *function,
+    const char *buffName, uint8_t *buff, uint32_t size, uint32_t maxSize)
+{
+    (void)fd;
+    (void)function;
+    (void)buffName;
+    (void)buff;
+    (void)size;
+    (void)maxSize;
+}
+
+/******************************************************************************/
+void Test_PalPrintWordBuff(const char *function, const char *buffName,
+                uint32_t *buff, uint32_t size)
+{
+    uint8_t i = 0;
+
+    Test_PalPrintf(function, "printing %s, word size %d\n", buffName,
+                            (uint32_t)size);
+    for (i = 0; i < size; i++) {
+        if (!(i%4))
+            Test_PalPrintf(NULL, "\n\t");
+        Test_PalPrintf(NULL, "0x%08X  ",
+                (unsigned int)(*((unsigned int *)buff+i)));
+    }
+    Test_PalPrintf(NULL, "\n");
+}
+
+/* inline void TEST_PRINT_BYTE_BUFFP(buffName, buff, size);
+   inline void TEST_FPRINT_LONG_NUM(const char *fd, const char *buffName,
+   uint32_t *buff, uint32_t size); */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_map_addrs.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_map_addrs.c
new file mode 100644
index 0000000..ae840d6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_map_addrs.c
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "test_pal_map_addrs.h"
+
+/******************************************************************************/
+void *Test_PalIOMap(void *physAddr, size_t size)
+{
+    (void)size;
+    return physAddr;
+}
+
+/******************************************************************************/
+void *Test_PalMapAddr(void *physAddr, void *startingAddr, const char *filename,
+                size_t size, uint8_t protAndFlagsBitMask)
+{
+    (void)startingAddr;
+    (void)filename;
+    (void)size;
+    (void)protAndFlagsBitMask;
+    return physAddr;
+}
+
+/******************************************************************************/
+void Test_PalUnmapAddr(void *virtAddr, size_t size)
+{
+    (void)virtAddr;
+    (void)size;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_mem.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_mem.c
new file mode 100644
index 0000000..815a5e8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_mem.c
@@ -0,0 +1,145 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "test_pal_log.h"
+#include "test_pal_mem.h"
+
+static unsigned long dmableBaseAddr = 0;
+static unsigned long unmanagedBaseAddr = 0;
+static unsigned long dmableEndAddr = 0;
+static unsigned long nextToAlloc = 0;
+
+static uint8_t memInitialised = 0;
+
+/******************************************************************************/
+void *Test_PalMalloc(size_t size)
+{
+    if (!size)
+        return NULL;
+
+    return (void *)malloc(size);
+}
+
+/******************************************************************************/
+void Test_PalFree(void *pvAddress)
+{
+    if (pvAddress == NULL)
+        return;
+
+    free(pvAddress);
+}
+
+/******************************************************************************/
+void *Test_PalRealloc(void *pvAddress, size_t newSize)
+{
+    if (pvAddress == NULL)
+        return NULL;
+
+    return realloc(pvAddress, newSize);
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferAlloc(size_t size)
+{
+    unsigned long currAddr;
+
+    if(!size) {
+        TEST_PRINTF_ERROR("Size cannot be zero");
+        goto end_with_error;
+    }
+
+    /* increase size with the requested alignment in our case 0x10 */
+    size += 0x10;
+
+    if((dmableBaseAddr == 0) || (dmableEndAddr == 0)) {
+        TEST_PRINTF_ERROR("DMA memory allocator wasn't initialized");
+        goto end_with_error;
+    }
+
+    /* Exceeds the maximum memory size */
+    if(nextToAlloc + size > dmableEndAddr) {
+        nextToAlloc = dmableBaseAddr;
+
+        if(nextToAlloc + size > dmableEndAddr) {
+            TEST_PRINTF_ERROR("End of range! size needs to be less "
+                "than %d",(dmableEndAddr - nextToAlloc));
+            goto end_with_error;
+        }
+    }
+
+    currAddr = nextToAlloc;
+    nextToAlloc += size;
+
+    return (void *)((currAddr + 0x10) & 0xfffffff0);
+
+end_with_error:
+    return NULL;
+}
+
+/******************************************************************************/
+void Test_PalDMAContigBufferFree(void *pvAddress)
+{
+    (void)pvAddress;
+}
+
+/******************************************************************************/
+void *Test_PalDMAContigBufferRealloc(void *pvAddress, size_t newSize)
+{
+    (void)pvAddress;
+    (void)newSize;
+    return NULL;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetDMABaseAddr(void)
+{
+    return dmableBaseAddr;
+}
+
+/******************************************************************************/
+unsigned long Test_PalGetUnmanagedBaseAddr(void)
+{
+    return unmanagedBaseAddr;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemInit(unsigned long newDMABaseAddr,
+             unsigned long newUnmanagedBaseAddr,
+             size_t DMAsize)
+{
+    if(memInitialised) {
+        TEST_PRINTF_ERROR("Memory is already initialised");
+        return 1;
+    }
+
+    dmableBaseAddr = newDMABaseAddr;
+    dmableEndAddr = newDMABaseAddr + DMAsize;
+    nextToAlloc = newDMABaseAddr;
+    unmanagedBaseAddr = newUnmanagedBaseAddr;
+    memInitialised = 1;
+
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalMemFin(void)
+{
+    dmableBaseAddr = 0;
+    unmanagedBaseAddr = 0;
+    dmableEndAddr = 0;
+    nextToAlloc = 0;
+    memInitialised = 0;
+
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_semphr.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_semphr.c
new file mode 100644
index 0000000..cef2b41
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_semphr.c
@@ -0,0 +1,64 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdio.h>
+#include "test_pal_semphr.h"
+
+/******************************************************************************/
+uint8_t Test_PalMutexCreate(Test_PalMutex *ppMutexId)
+{
+    *ppMutexId =  NULL;
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexDestroy(Test_PalMutex *ppMutexId)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexLock(Test_PalMutex *ppMutexId, uint32_t timeout)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalMutexUnlock(Test_PalMutex *ppMutexId)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreCreate(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreDestroy(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreTake(Test_PalBinarySemaphore *ppBinSemphrId,
+                            uint32_t timeout)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint8_t Test_PalBinarySemaphoreGive(Test_PalBinarySemaphore *ppBinSemphrId)
+{
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_socket.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_socket.c
new file mode 100644
index 0000000..fbc40d0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_socket.c
@@ -0,0 +1,118 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+
+#include "test_pal_socket.h"
+#include "test_pal_mem.h"
+
+/* the time to wait for sent/recive replay */
+#define TIMEOUT_MS  100
+
+/******************************************************************************/
+uint32_t Test_PalSocket(tp_socket *s, enum tp_sock_domain domain,
+        enum tp_sock_type type, enum tp_sock_protocol protocol,
+        const uint32_t recvTimeout_ms)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalCloseSocket(tp_socket s)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalConnect(tp_socket s, const uint8_t *addr, uint32_t port)
+{
+    return 0;
+
+}
+
+/******************************************************************************/
+uint32_t Test_PalBind(tp_socket s, uint32_t port)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalListen(tp_socket s, uint32_t backlog)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalAccept(tp_socket s, tp_socket *acptS, uint8_t *addr,
+             uint32_t *port)
+{
+    return 0;
+}
+
+/******************************************************************************/
+tp_socket Test_PalShutdown(tp_socket s)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalSend(tp_socket s, const uint8_t *buf,
+              size_t len)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalSendTo(tp_socket s, const uint8_t *buf,
+            size_t len, const uint8_t *addr, uint32_t port)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalRecvFrom(tp_socket s, const uint8_t *buf,
+            size_t len, uint8_t *addr, uint32_t *port)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalRecv(tp_socket s, const uint8_t *buf,
+              size_t len)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalHtonl(uint32_t val)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint16_t Test_PalHtons(uint16_t val)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalNtohl(uint32_t val)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint16_t Test_PalNtohs(uint16_t val)
+{
+    return 0;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_thread.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_thread.c
new file mode 100644
index 0000000..a1f787b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_thread.c
@@ -0,0 +1,64 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include "test_pal_log.h"
+#include "test_pal_thread.h"
+
+/******************************************************************************/
+size_t Test_PalGetMinimalStackSize(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetHighestPriority(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetLowestPriority(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalGetDefaultPriority(void)
+{
+    return 0;
+}
+
+/******************************************************************************/
+ThreadHandle Test_PalThreadCreate(size_t stackSize,
+                  void *(*threadFunc)(void *),
+                  int priority, void *args,
+                  const char *threadName,
+                  uint8_t nameLen, uint8_t dmaAble)
+{
+    return NULL;
+}
+
+/******************************************************************************/
+uint32_t Test_PalThreadJoin(ThreadHandle threadHandle, void **threadRet)
+{
+    return 0;
+}
+
+/******************************************************************************/
+uint32_t Test_PalThreadDestroy(ThreadHandle threadHandle)
+{
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_time.c b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_time.c
new file mode 100644
index 0000000..016fb36
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/TestAL/pal/no_os/test_pal_time.c
@@ -0,0 +1,30 @@
+/*******************************************************************************
+* The confidential and proprietary information contained in this file may      *
+* only be used by a person authorised under and to the extent permitted        *
+* by a subsisting licensing agreement from ARM Limited or its affiliates.      *
+*   (C) COPYRIGHT [2001-2017] ARM Limited or its affiliates.                   *
+*       ALL RIGHTS RESERVED                                                    *
+* This entire notice must be reproduced on all copies of this file             *
+* and copies of this file may only be made by a person if such person is       *
+* permitted to do so under the terms of a subsisting license agreement         *
+* from ARM Limited or its affiliates.                                          *
+*******************************************************************************/
+
+#include <stdint.h>
+#include <time.h>
+#include <math.h>
+#include "test_pal_time.h"
+
+/******************************************************************************/
+/* The smallest resolution in no_os is seconds */
+void Test_PalDelay(const uint32_t usec)
+{
+    /* Rounds up */
+    uint32_t secs = (usec + 999) / 1000;
+
+    /* Gets the end time */
+    uint32_t retTime = time(0) + secs;
+
+    /* Loop until end time arrives */
+    while (time(0) < retTime);
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/applet_list.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/applet_list.c
new file mode 100644
index 0000000..ba5b5a9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/applet_list.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+
+#include "applet_list.h"
+#include "sep_test_agent.h"
+
+/*
+* @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+uint8_t getLoadedApplets(IN_PARAM int fd , OUT_PARAM uint8_t *pBuff)
+{
+
+    uint32_t      mem_shared_adr = 0;
+    uint32_t      max_polling = MAX_POLLING_COUNT;
+    uint8_t       stat= 0;
+    uint8_t       lock_state = APP_BUFF_LOCKED;
+    /*mmap RAM for shared buffer status loaded/unloaded applets*/
+    mem_shared_adr = (unsigned int)mmap(0, APP_LOADING_SHARED_MEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, APP_LOADING_START_SHARED_ADDR);
+    if (mem_shared_adr == 0 || mem_shared_adr == 0xFFFFFFFF) {
+        fprintf(stderr, "Error:setAppletLoadState: mem mmap failed (%s)\n", strerror(errno));
+        return 1;
+    }
+    TRY_ACQUIRE_LOCK(mem_shared_adr,stat,max_polling,lock_state);
+    if (stat) {
+        return 1; /* failed to acquire lock */
+    }
+    memcpy(pBuff,(uint8_t*)mem_shared_adr,MAX_APPLET_SLOT_NUM);
+    RELEASE_LOCK(mem_shared_adr);
+    return 0;
+}
+/*
+* @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+uint8_t clearAllApplets(IN_PARAM int fd)
+{
+
+    uint32_t      mem_shared_adr = 0;
+    uint32_t      max_polling = MAX_POLLING_COUNT;
+    uint8_t       stat= 0;
+    uint8_t       lock_state = APP_BUFF_LOCKED;
+    /*mmap RAM for shared buffer status loaded/unloaded applets*/
+    mem_shared_adr = (unsigned int)mmap(0, APP_LOADING_SHARED_MEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, APP_LOADING_START_SHARED_ADDR);
+    if (mem_shared_adr == 0 || mem_shared_adr == 0xFFFFFFFF) {
+        fprintf(stderr, "Error:clearAllApplets: mem mmap failed (%s)\n", strerror(errno));
+        return 1;
+    }
+    TRY_ACQUIRE_LOCK((uint8_t *)mem_shared_adr,stat,max_polling,lock_state);
+    if (stat) {
+        return 1; /* failed to acquire lock */
+    }
+    memset((uint8_t*)mem_shared_adr,APP_UNLOADED, MAX_APPLET_SLOT_NUM);
+    RELEASE_LOCK(mem_shared_adr);
+    return 0;
+}
+/*
+* @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+uint8_t loadApplet(IN_PARAM int fd , uint8_t slotId)
+{
+
+    uint32_t      mem_shared_adr = 0;
+    uint32_t      max_polling = MAX_POLLING_COUNT;
+    uint8_t       stat= 0;
+    uint8_t       lock_state = APP_BUFF_LOCKED;
+
+    mem_shared_adr = (unsigned int)mmap(0, APP_LOADING_SHARED_MEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, APP_LOADING_START_SHARED_ADDR);
+    if (mem_shared_adr == 0 || mem_shared_adr == 0xFFFFFFFF) {
+        fprintf(stderr, "Error:loadApplet: mem mmap failed (%s)\n", strerror(errno));
+        return 1;
+    }
+    TRY_ACQUIRE_LOCK((uint8_t *)mem_shared_adr,stat,max_polling,lock_state);
+    if (stat) {
+        return 1; /* failed to acquire lock */
+    }
+    memset(((uint8_t *)mem_shared_adr)+slotId, APP_LOADED, 1);
+    RELEASE_LOCK(mem_shared_adr);
+    return 0;
+}
+/*
+* @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+uint8_t unloadApplet(IN_PARAM int fd , OUT_PARAM uint8_t *pBuff,uint8_t slotId)
+{
+
+    uint32_t      mem_shared_adr = 0;
+    uint32_t      max_polling = MAX_POLLING_COUNT;
+    uint8_t       stat= 0;
+    uint8_t       lock_state = APP_BUFF_LOCKED;
+
+    mem_shared_adr = (unsigned int)mmap(0, APP_LOADING_SHARED_MEM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, APP_LOADING_START_SHARED_ADDR);
+    if (mem_shared_adr == 0 || mem_shared_adr == 0xFFFFFFFF) {
+        fprintf(stderr, "Error:unloadApplet: mem mmap failed (%s)\n", strerror(errno));
+        return 1;
+    }
+    TRY_ACQUIRE_LOCK((uint8_t *)mem_shared_adr,stat,max_polling,lock_state);
+    if (stat) {
+        return 1; /* failed to acquire lock */
+    }
+    memset(((uint8_t *)mem_shared_adr)+slotId, APP_UNLOADED, 1);
+    RELEASE_LOCK(mem_shared_adr);
+    return 0;
+}
+/*
+* @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+void appList_buildList(OUT_PARAM int8_t *appList,
+               IN_PARAM  uint8_t *loadedAppsList,
+               IN_PARAM  uint8_t appletListNum,
+               IN_PARAM  uint8_t currentSlot,
+               IN_PARAM  bool  isLastPriv)
+{
+    uint8_t       slotsNum = 0;
+    uint8_t       nextSlot = 0;
+    bool        isSramInList = false;
+
+    if ((NULL == appList) ||
+        (NULL == loadedAppsList)) {
+        return;
+    }
+
+    memset(appList, (-1), MAX_APPLET_SLOT_NUM);
+    appList[NEXT_SLOT_INDEX] = 0;
+
+    if ((appletListNum >= MAX_APPLET_SLOT_NUM) ||
+        (appletListNum <= 1) ||
+        (currentSlot >= MAX_APPLET_SLOT_NUM)) {
+        return;
+    }
+
+    // Update sramFlag according to slot number
+    isSramInList |= IS_SRAM_SLOT(currentSlot);
+    while (slotsNum < (appletListNum-1)) {
+        GET_NEXT_SLOT(currentSlot, nextSlot, loadedAppsList);
+        // non-priv slot must not appear in the list after SRAM slot,
+        // if last slot must be priv check that, otherwise just check last is not SRAM since SRAM can only forward command to other applet
+        if (IS_NEXT_SLOT_LEGAL(isSramInList, nextSlot)) {
+            if ((isLastPriv)) {
+                if (IS_LAST_PRIV_SLOT(nextSlot, slotsNum, appletListNum)) {
+                    isSramInList |= IS_SRAM_SLOT(currentSlot);
+                    appList[slotsNum] = nextSlot;
+                    slotsNum++;
+                    currentSlot = nextSlot;
+                }
+            } else {
+                if (IS_NOT_LAST_SRAM_SLOT(nextSlot, slotsNum, appletListNum)) {
+                    isSramInList |= IS_SRAM_SLOT(currentSlot);
+                    appList[slotsNum] = nextSlot;
+                    slotsNum++;
+                    currentSlot = nextSlot;
+                }
+            }
+        }
+    }
+
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/applet_list.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/applet_list.h
new file mode 100644
index 0000000..cf98389
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/applet_list.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* \file applet_list.h
+ * Definition of building list of applets for applet to applet tests
+ */
+
+#ifndef __APPLET_LIST_H__
+#define __APPLET_LIST_H__
+
+#include <stdbool.h>
+#include "cc_pal_types.h"
+#include "cc_pal_types_plat.h"
+
+#define IN_PARAM
+#define OUT_PARAM
+#define IN_OUT_PARAM
+#define APP_IS_LOADED 1
+
+enum {
+     AppSuccess,
+     AppFail
+};
+
+#define GET_NEXT_SLOT(currentSlot, nextSlot, loadedAppsList) {\
+    do {\
+        if (IS_SRAM_SLOT(currentSlot)) {\
+               nextSlot = rand() % (1 + MAX_PRIVILEGED_APPLET_ID);\
+        } else {\
+               nextSlot = rand() % MAX_APPLET_SLOT_NUM;\
+        }\
+        if (APP_IS_LOADED == loadedAppsList[nextSlot]) break;\
+    } while (1);\
+}
+
+
+// if sram slot is in the list no-priv slot mustn't follow
+#define IS_NEXT_SLOT_LEGAL(isSramInList, slot) ((IS_NON_PRIV_SLOT(slot) && (isSramInList))?0:1)
+
+// if last slot in the list, it must be priviledge , if not last in list it's legal
+#define IS_LAST_PRIV_SLOT(slot, index, numSlots) ((index == numSlots-2)?IS_PRIV_SLOT(slot):1)
+
+// if last slot in the list is SARM
+#define IS_NOT_LAST_SRAM_SLOT(slot, index, numSlots) ((index == numSlots-2)?(!(IS_SRAM_SLOT(slot))):1)
+
+
+extern void appList_buildList(OUT_PARAM int8_t *appList,
+            IN_PARAM  uint8_t *loadedAppsList,
+            IN_PARAM  uint8_t appletListNum,
+            IN_PARAM  uint8_t currentSlot,
+            IN_PARAM  bool  isLastPriv);
+
+extern  uint8_t getLoadedApplets(IN_PARAM int fd , OUT_PARAM uint8_t *pBuff);
+extern  uint8_t clearAllApplets(IN_PARAM int fd);
+extern  uint8_t loadApplet(IN_PARAM int fd , uint8_t slotId);
+extern  uint8_t unloadApplet(IN_PARAM int fd , OUT_PARAM uint8_t *pBuff,uint8_t slotId);
+
+#endif // __APPLET_LIST_H__
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/linux64/load_pal_driver.sh b/lib/ext/cryptocell-312-runtime/host/src/tests/common/linux64/load_pal_driver.sh
new file mode 100755
index 0000000..541e781
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/linux64/load_pal_driver.sh
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#!/bin/sh
+LINUX64_DRIVER_NAME="cc_linux_drv"
+is_load=$1
+is_driver_loaded=`lsmod| grep $LINUX64_DRIVER_NAME| wc -l`
+#unload driver in any case
+if [[ $is_driver_loaded -ne 0 ]]; then
+        echo Unloading driver $LINUX64_DRIVER_NAME
+        modprobe -r $LINUX64_DRIVER_NAME
+        echo lsmod
+        lsmod
+fi
+
+if [[ $is_load == "load" ]]; then
+        echo Loading driver $LINUX64_DRIVER_NAME
+        modprobe $LINUX64_DRIVER_NAME
+        echo lsmod
+        lsmod
+fi
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/multi2_soft.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/multi2_soft.c
new file mode 100644
index 0000000..5f56a51
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/multi2_soft.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/* file multi2_soft.c
+ * This code is a patch for multi2 (based on libtomcrypt-1.17
+ *   It includes the following additions:
+ *  1) bug fix when num_of_rounds%4 !=0
+ *  2) num_rounds is not restricted to 128
+ *  3) support cbc mode (with IV)
+ */
+
+#include "tomcrypt.h"
+
+unsigned char cbc_iv[8];
+
+static void pi1(ulong32 *p)
+{
+   p[1] ^= p[0];
+}
+
+static void pi2(ulong32 *p, ulong32 *k)
+{
+   ulong32 t;
+   t = (p[1] + k[0]) & 0xFFFFFFFFUL;
+   t = (ROL(t, 1) + t - 1)  & 0xFFFFFFFFUL;
+   t = (ROL(t, 4) ^ t)  & 0xFFFFFFFFUL;
+   p[0] ^= t;
+}
+
+static void pi3(ulong32 *p, ulong32 *k)
+{
+   ulong32 t;
+   t = p[0] + k[1];
+   t = (ROL(t, 2) + t + 1)  & 0xFFFFFFFFUL;
+   t = (ROL(t, 8) ^ t)  & 0xFFFFFFFFUL;
+   t = (t + k[2])  & 0xFFFFFFFFUL;
+   t = (ROL(t, 1) - t)  & 0xFFFFFFFFUL;
+   t = ROL(t, 16) ^ (p[0] | t);
+   p[1] ^= t;
+}
+
+static void pi4(ulong32 *p, ulong32 *k)
+{
+   ulong32 t;
+   t = (p[1] + k[3])  & 0xFFFFFFFFUL;
+   t = (ROL(t, 2) + t + 1)  & 0xFFFFFFFFUL;
+   p[0] ^= t;
+}
+
+static void setup(ulong32 *dk, ulong32 *k, ulong32 *uk)
+{
+   int n, t;
+   ulong32 p[2];
+
+   p[0] = dk[0]; p[1] = dk[1];
+
+   t = 4;
+   n = 0;
+      pi1(p);
+      pi2(p, k);
+      uk[n++] = p[0];
+      pi3(p, k);
+      uk[n++] = p[1];
+      pi4(p, k);
+      uk[n++] = p[0];
+      pi1(p);
+      uk[n++] = p[1];
+      pi2(p, k+t);
+      uk[n++] = p[0];
+      pi3(p, k+t);
+      uk[n++] = p[1];
+      pi4(p, k+t);
+      uk[n++] = p[0];
+      pi1(p);
+      uk[n++] = p[1];
+}
+
+static void encrypt(ulong32 *p, int N, ulong32 *uk)
+{
+   int n, t;
+   for (t = n = 0; ; ) {
+      pi1(p); if (++n == N) break;
+      pi2(p, uk+t); if (++n == N) break;
+      pi3(p, uk+t); if (++n == N) break;
+      pi4(p, uk+t); if (++n == N) break;
+      t ^= 4;
+   }
+}
+
+static void decrypt(ulong32 *p, int N, ulong32 *uk)
+{
+   int n, t;
+   for (t = 4*(((N-1)>>2)&1), n = N; ;  ) {
+      switch (n<=4 ? n : ((n-1)%4)+1) {
+         case 4: pi4(p, uk+t); --n;
+         case 3: pi3(p, uk+t); --n;
+         case 2: pi2(p, uk+t); --n;
+         case 1: pi1(p); --n; break;
+     case 0: return;
+     default: return;
+      }
+      t ^= 4;
+   }
+}
+
+int  multi2_soft_ecb_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
+{
+   ulong32 sk[8], dk[2];
+   int      x;
+
+   LTC_ARGCHK(key  != NULL);
+   LTC_ARGCHK(skey != NULL);
+
+   if (keylen != 40) return CRYPT_INVALID_KEYSIZE;
+
+   skey->multi2.N = num_rounds;
+   for (x = 0; x < 8; x++) {
+       LOAD32H(sk[x], key + x*4);
+   }
+   LOAD32H(dk[0], key + 32);
+   LOAD32H(dk[1], key + 36);
+   setup(dk, sk, skey->multi2.uk);
+
+   zeromem(sk, sizeof(sk));
+   zeromem(dk, sizeof(dk));
+   return CRYPT_OK;
+}
+
+/**
+  Encrypts a block of text with multi2
+  @param pt The input plaintext (8 bytes)
+  @param ct The output ciphertext (8 bytes)
+  @param skey The key as scheduled
+  @return CRYPT_OK if successful
+*/
+int multi2_soft_ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_key *skey)
+{
+   ulong32 p[2];
+   LTC_ARGCHK(pt   != NULL);
+   LTC_ARGCHK(ct   != NULL);
+   LTC_ARGCHK(skey != NULL);
+
+   if (len % 8) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   while (len) {
+
+       LOAD32H(p[0], pt);
+       LOAD32H(p[1], pt+4);
+       encrypt(p, skey->multi2.N, skey->multi2.uk);
+       STORE32H(p[0], ct);
+       STORE32H(p[1], ct+4);
+
+       ct  += 8;
+       pt  += 8;
+       len -= 8;
+   }
+
+   return CRYPT_OK;
+}
+
+/**
+  Decrypts a block of text with multi2
+  @param ct The input ciphertext (8 bytes)
+  @param pt The output plaintext (8 bytes)
+  @param skey The key as scheduled
+  @return CRYPT_OK if successful
+*/
+int multi2_soft_ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_key *skey)
+{
+   ulong32 p[2];
+   LTC_ARGCHK(pt   != NULL);
+   LTC_ARGCHK(ct   != NULL);
+   LTC_ARGCHK(skey != NULL);
+
+   if (len % 8) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   while (len) {
+
+       LOAD32H(p[0], ct);
+       LOAD32H(p[1], ct+4);
+       decrypt(p, skey->multi2.N, skey->multi2.uk);
+       STORE32H(p[0], pt);
+       STORE32H(p[1], pt+4);
+
+       ct  += 8;
+       pt  += 8;
+       len -= 8;
+   }
+
+   return CRYPT_OK;
+}
+
+int  multi2_soft_cbc_setup(const unsigned char *iv, const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
+{
+   ulong32 sk[8], dk[2];
+   int      x;
+
+   LTC_ARGCHK(key  != NULL);
+   LTC_ARGCHK(skey != NULL);
+   LTC_ARGCHK(iv != NULL);
+
+   if (keylen != 40) return CRYPT_INVALID_KEYSIZE;
+   //if (num_rounds == 0) num_rounds = 128;
+
+   skey->multi2.N = num_rounds;
+   for (x = 0; x < 8; x++) {
+       LOAD32H(sk[x], key + x*4);
+   }
+   LOAD32H(dk[0], key + 32);
+   LOAD32H(dk[1], key + 36);
+   setup(dk, sk, skey->multi2.uk);
+
+   zeromem(sk, sizeof(sk));
+   zeromem(dk, sizeof(dk));
+
+   /* copy IV */
+   memcpy(&cbc_iv,iv,8);
+
+   return CRYPT_OK;
+}
+
+/**
+  Encrypts a block of text with multi2
+  @param pt The input plaintext (8 bytes)
+  @param ct The output ciphertext (8 bytes)
+  @param skey The key as scheduled
+  @return CRYPT_OK if successful
+*/
+int multi2_soft_cbc_encrypt(unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_key *skey)
+{
+   int      x;
+   ulong32 p[2];
+   LTC_ARGCHK(pt   != NULL);
+   LTC_ARGCHK(ct   != NULL);
+   LTC_ARGCHK(skey != NULL);
+
+   if (len % 8) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   while (len) {
+       /* xor IV against plaintext */
+       for (x = 0; x < 8; x++) {
+           pt[x] ^= cbc_iv[x];
+       }
+
+       /* encrypt */
+       LOAD32H(p[0], pt);
+       LOAD32H(p[1], pt+4);
+       encrypt(p, skey->multi2.N, skey->multi2.uk);
+       STORE32H(p[0], ct);
+       STORE32H(p[1], ct+4);
+
+       /* store IV [ciphertext] for a future block */
+       for (x = 0; x < 8; x++) {
+           cbc_iv[x] = ct[x];
+       }
+
+       ct  += 8;
+       pt  += 8;
+       len -= 8;
+   }
+
+   return CRYPT_OK;
+}
+
+/**
+  Decrypts a block of text with multi2
+  @param ct The input ciphertext (8 bytes)
+  @param pt The output plaintext (8 bytes)
+  @param skey The key as scheduled
+  @return CRYPT_OK if successful
+*/
+int multi2_soft_cbc_decrypt(unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_key *skey)
+{
+   int      x;
+   ulong32 p[2];
+   LTC_ARGCHK(pt   != NULL);
+   LTC_ARGCHK(ct   != NULL);
+   LTC_ARGCHK(skey != NULL);
+
+   if (len % 8) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   while (len) {
+
+       /* decrypt */
+       LOAD32H(p[0], ct);
+       LOAD32H(p[1], ct+4);
+       decrypt(p, skey->multi2.N, skey->multi2.uk);
+       STORE32H(p[0], pt);
+       STORE32H(p[1], pt+4);
+
+       /* xor IV against plaintext */
+       for (x = 0; x < 8; x++) {
+           pt[x] ^= cbc_iv[x];
+       }
+
+       /* store IV [ciphertext] for a future block */
+       for (x = 0; x < 8; x++) {
+           cbc_iv[x] = ct[x];
+       }
+
+       ct  += 8;
+       pt  += 8;
+       len -= 8;
+   }
+
+   return CRYPT_OK;
+}
+
+
+/** Terminate the context
+   @param skey    The scheduled key
+*/
+void multi2_soft_done(symmetric_key *skey)
+{
+}
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/multi2_soft.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/multi2_soft.h
new file mode 100644
index 0000000..cf8fb9b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/multi2_soft.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* file multi2_soft.h
+ *  Soft implementatoion for Multi2 (missing in tomcrypt library).
+ *  Cipher mode valid: ecb, cbc.
+ */
+
+#ifndef __MULTI2_SOFT_H__
+#define __MULTI2_SOFT_H__
+
+#include "tomcrypt.h"
+
+int  multi2_soft_ecb_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+
+int multi2_soft_ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_key *skey);
+
+int multi2_soft_ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_key *skey);
+
+int  multi2_soft_cbc_setup(const unsigned char *iv, const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+
+int multi2_soft_cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_key *skey);
+
+int multi2_soft_cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_key *skey);
+
+void multi2_soft_done(symmetric_key *skey);
+
+#endif  // __MULTI2_SOFT_H__
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/test_log.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/test_log.h
new file mode 100644
index 0000000..149c7b9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/test_log.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __TST_HOST_LOG_H__
+#define __TST_HOST_LOG_H__
+
+#include <stdint.h>
+#include <stdio.h>
+
+
+#define TEST_PRINTF_ERROR(format, ...)  {\
+        fprintf(stderr, "%s(): " format, __FUNCTION__, ##__VA_ARGS__);\
+        fprintf(stderr, "\n");\
+        fflush(stderr);\
+}
+#define TEST_FPRINTF_ERROR(fd, format, ...)  {\
+        fprintf(fd, "%s(): " format, __FUNCTION__, ##__VA_ARGS__);\
+        fprintf(fd, "\n");\
+        fflush(fd);\
+        fprintf(stderr, "%s(): " format, __FUNCTION__, ##__VA_ARGS__);\
+        fprintf(stderr, "\n");\
+        fflush(stderr);\
+}
+#define TEST_PRINTF_MESSAGE(format, ...)  {\
+        fprintf(stderr, format, ##__VA_ARGS__);\
+        fflush(stderr);\
+}
+
+//to print buffers during fips tests without debug compilation
+#define TEST_PRINT_WORD_BUFF_TRACE(buffName, size, buff) {\
+    unsigned int i = 0;\
+    TEST_PRINTF_MESSAGE("printing %s, word size %d", buffName, (unsigned int)size);\
+    for (i=0; i< size; i++) {\
+        if (!(i%4)) {\
+            TEST_PRINTF_MESSAGE("\n\t");\
+        }\
+        TEST_PRINTF_MESSAGE("  0x%08X  ", (unsigned int)(*((unsigned int *)buff+i)));\
+    }\
+    TEST_PRINTF_MESSAGE("\n");\
+}
+
+#define TEST_PRINT_BYTE_BUFF_TRACE(buffName, size, buff) {\
+    unsigned int i = 0;\
+    TEST_PRINTF_MESSAGE("printing %s, byte size %d", buffName, (unsigned int)size);\
+    for (i=0; i< size; i++) {\
+        if (!(i%16)) {\
+            TEST_PRINTF_MESSAGE("\n\t");\
+        }\
+        TEST_PRINTF_MESSAGE("0x%02X ", (unsigned char)(*((unsigned char *)buff+i)));\
+    }\
+    TEST_PRINTF_MESSAGE("\n");\
+}
+
+#define TEST_PRINTF_TRACE(format, ...)  {\
+    fprintf(stdout, "%s(): " format, __FUNCTION__, ##__VA_ARGS__);\
+    fprintf(stdout, "\n");\
+    fflush(stdout);\
+}
+
+#ifdef TEST_DEBUG
+#define TEST_FPRINTF(fd, format, ...)  {\
+     fprintf(fd, "%s(): " format, __FUNCTION__, ##__VA_ARGS__);\
+     fprintf(fd, "\n");\
+     fflush(fd);\
+}
+#define TEST_PRINTF(format, ...)  {\
+     fprintf(stdout, "%s(): " format, __FUNCTION__, ##__VA_ARGS__);\
+     fprintf(stdout, "\n");\
+     fflush(stdout);\
+}
+
+#define TEST_PRINTF1(format, ...)  {\
+     fprintf(stdout, " " format, ##__VA_ARGS__);\
+     fflush(stdout);\
+}
+
+#define TEST_FPRINTF1(fd, format, ...)  {\
+     fprintf(fd, " " format, ##__VA_ARGS__);\
+     fflush(fd);\
+}
+
+#define TEST_PRINT_WORD_BUFF(buffName, size, buff) {\
+    unsigned int i = 0;\
+    TEST_PRINTF("printing %s, word size %d", buffName, (unsigned int)size);\
+    for (i=0; i< size; i++) {\
+        if (!(i%4)) {\
+            TEST_PRINTF1("\n\t");\
+        }\
+        TEST_PRINTF1("  0x%08X  ", (unsigned int)(*((unsigned int *)buff+i)));\
+    }\
+    TEST_PRINTF1("\n");\
+}
+
+
+#define TEST_PRINT_BYTE_BUFF(buffName, size, buff) {\
+    unsigned int i = 0;\
+    TEST_PRINTF("printing %s, byte size %d", buffName, (unsigned int)size);\
+    for (i=0; i< size; i++) {\
+        if (!(i%16)) {\
+            TEST_PRINTF1("\n\t");\
+        }\
+        TEST_PRINTF1("0x%02X ", (unsigned char)(*((unsigned char *)buff+i)));\
+    }\
+    TEST_PRINTF1("\n");\
+}
+
+#define TEST_PRINT_BYTE_BUFFP(buffName, size, buff) {\
+    unsigned int idxT = 0;\
+    uint8_t *buffP = (uint8_t *)(buff);\
+    TEST_PRINTF("printing %s, byte size %d", buffName, (unsigned int)size);\
+    for (idxT=0; idxT< size; idxT++) {\
+        if (!(idxT%16)) {\
+            TEST_PRINTF1("\n\t");\
+        }\
+        TEST_PRINTF1("0x%02X ", buffP[idxT]);\
+    }\
+    TEST_PRINTF1("\n");\
+}
+
+#define TEST_FPRINT_LONG_NUM(fd, buffName, buff, size) {\
+    unsigned int i = 0;\
+    TEST_FPRINTF(fd, "printing %s, byte size %d", buffName, (unsigned int)size);\
+    TEST_FPRINTF1(fd, "0x");\
+    for (i=0; i< size; i++) {\
+        fprintf(fd, "%02X", (unsigned char)(*((unsigned char *)buff+i)));\
+    }\
+    fprintf(fd, "\n");\
+}
+
+#define TEST_FPRINT_BYTE_BUFF(fd, buffName, buff, size) {\
+    unsigned int i = 0;\
+    TEST_FPRINTF(fd, "printing %s, byte size %d", buffName, (unsigned int)size);\
+    for (i=0; i< size; i++) {\
+        if (!(i%16)) {\
+            TEST_FPRINTF1(fd, "\n\t");\
+        }\
+        TEST_FPRINTF1(fd, "0x%02X ", (unsigned char)(*((unsigned char *)buff+i)));\
+    }\
+    TEST_FPRINTF1(fd, "\n");\
+}
+
+#define TEST_FPRINT_BYTE_BUFF_MAX(fd, buffName, buff, size, maxSize) {\
+    int i = 0;\
+    int minSize = ((size>maxSize)?maxSize:size);\
+    TEST_FPRINTF(fd, "printing %s, buff size %d, max size %d", buffName, (unsigned int)size, (unsigned int)maxSize);\
+    for (i=0; i< minSize; i++) {\
+        if (!(i%16)) {\
+            TEST_FPRINTF1(fd, "\n\t");\
+        }\
+        TEST_FPRINTF1(fd, "0x%02X ", (unsigned char)(*((unsigned char *)buff+i)));\
+    }\
+    TEST_FPRINTF1(fd, "\n");\
+}
+
+#else
+#define TEST_FPRINTF(fd, format, ...)  do{ }while(0)
+#define TEST_PRINTF(format, ...)  do{ }while(0)
+#define TEST_PRINTF1(format, ...)  do{ }while(0)
+#define TEST_PRINT_BYTE_BUFF(str, size, buff) do{ }while(0)
+#define TEST_PRINT_BYTE_BUFFP(buffName, size, buff) do{ }while(0)
+#define TEST_PRINT_WORD_BUFF(str, size, buff) do{ }while(0)
+#define TEST_FPRINT_LONG_NUM(fd, buffName, buff, size)  do{ }while(0)
+#define TEST_FPRINT_BYTE_BUFF(fd, buffName, buff, size)  do{ }while(0)
+#define TEST_FPRINT_BYTE_BUFF_MAX(fd, buffName, buff, size, maxSize)  do{ }while(0)
+#endif
+#endif /*__TST_HOST_LOG_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access.c
new file mode 100644
index 0000000..b7027b1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access.c
@@ -0,0 +1,441 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include "cc_pal_types.h"
+#include "dx_env.h"
+#include "dx_reg_base_host.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "tests_hw_access.h"
+#include "tests_phys_map.h"
+#include "test_log.h"
+#include "dx_crys_kernel.h"
+
+
+
+/////////////////////////////////////
+//         macro defines           //
+/////////////////////////////////////
+
+
+/*************************/
+/*   Global variables    */
+/*************************/
+
+
+/******************************/
+/*   function definitions     */
+/*****************************/
+unsigned int testCheckLcs(unsigned int  nextLcs)
+{
+    unsigned int regVal = 0;
+    unsigned int error = TEST_OK;
+
+    /* Wait on LCS valid before reading the LCS register */
+    do {
+        regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_IS_VALID));
+        regVal = CC_REG_FLD_GET(0, LCS_IS_VALID, VALUE, regVal);
+    }while (!regVal);
+
+    /* Read the LCS register */
+    regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+    TEST_PRINTF_ERROR("regVal is 0x%x", regVal);
+
+    /* Verify lcs */
+    if(regVal != nextLcs) {
+        TEST_PRINTF_ERROR("Failed to verify new LCS !!!\n");
+        return TEST_BURN_OTP_LCS_ERR;
+    }
+
+    /* Check HW errors */
+    switch(nextLcs){
+    case TESTS_LCS_SEC_ENABLED:
+        /* Check RKEK error bit */
+        regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+        regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_KDR_ZERO_CNT, regVal);
+        if (regVal) {
+            error = TEST_BURN_OTP_KDR_ERR;
+            break;
+        }
+        /* FALLTHROUGH */
+
+    case TESTS_LCS_DM:
+        /* Check Provision (Scp) error bit */
+        regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+        regVal = CC_REG_FLD_GET(0, LCS_REG, ERROR_PROV_ZERO_CNT, regVal);
+        if (regVal) {
+            error = TEST_BURN_OTP_SCP_ERR;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return error;
+}
+
+
+/* Global Reset of CC and AO and env regs */
+void performPowerOnReset(void)
+{
+    /* Call sw reset to reset the CC before starting to work with it */
+    WRITE_ENV(DX_ENV_CC_POR_N_ADDR_REG_OFFSET , 0x1UL);
+    usleep(1000);
+
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, AXIM_CACHE_PARAMS), 0x277UL);
+    usleep(1000);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+    return;
+
+}
+
+
+/* Reset both CC and AO regs */
+void performColdReset(void)
+{
+    /* perform global reset */
+    WRITE_ENV(DX_ENV_CC_COLD_RST_REG_OFFSET , 0x1UL);
+    usleep(1000);
+
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, AXIM_CACHE_PARAMS), 0x277UL);
+    usleep(1000);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+    return;
+}
+
+
+/* Reset only CC regs */
+void performWarmReset(void)
+{
+    WRITE_ENV(DX_ENV_CC_RST_N_REG_OFFSET , 0x1UL);
+    usleep(1000);
+
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, AXIM_CACHE_PARAMS), 0x277UL);
+    usleep(1000);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+    return;
+
+}
+
+unsigned int testBurnOtp(unsigned int  *otp, unsigned int  nextLcs)
+{
+
+    CCError_t error = TEST_OK;
+    unsigned int i = 0;
+
+#if 0
+    /* Clear OTP is not needed any more since we call to powerOnReset to clear env regs */
+    error = testClearOtp();
+    if (error) {
+        TEST_PRINTF_ERROR("Failed to clear OTP!!!\n");
+        return error;
+    }
+#endif
+
+    /*  Perform SW reset to reach CM LCS */
+    performPowerOnReset();
+
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+                TEST_PRINTF("writing Otp [%d] 0x%X", i, otp[i]);
+        WRITE_OTP(i, otp[i]);
+        usleep(1000);
+
+    }
+#ifdef DEBUG
+    uint32_t tempOtp;
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        tempOtp = READ_OTP(i);
+        TEST_PRINTF_ERROR("tempOtp [%d] 0x%X", i, tempOtp);
+
+        }
+#endif
+
+    /*  Perform SW reset after writing to OTP new values */
+    performPowerOnReset();
+
+    /* verify LCS */
+    error = testCheckLcs(nextLcs);
+    if (error == TEST_OK) {
+        TEST_PRINTF(" OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
+    } else {
+        TEST_PRINTF_ERROR("Error: Failed to burn OTP lcs is %d!!!\n", nextLcs);
+    }
+
+    return error;
+}
+
+
+unsigned int testClearOtp(void)
+{
+    CCError_t error = TEST_OK;
+    unsigned int i = 0;
+
+    /*  Perform SW reset to reach CM LCS */
+    performPowerOnReset();
+
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        WRITE_OTP(i, 0);
+        usleep(1000);
+
+    }
+#ifdef DEBUG
+    uint32_t tempOtp;
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        tempOtp = READ_OTP(i);
+        TEST_PRINTF_ERROR("tempOtp [%d] 0x%X", i, tempOtp);
+
+        }
+#endif
+
+    /*  Perform SW reset after writing to OTP new values */
+    performPowerOnReset();
+
+    /* verify LCS */
+    error = testCheckLcs(0);
+    if (error == TEST_OK) {
+        TEST_PRINTF(" OTP burn succeeded with new LCS = CM \n");
+    } else {
+        TEST_PRINTF_ERROR("Error: Failed to burn OTP \n");
+    }
+
+    return error;
+}
+
+
+
+unsigned int testSetScpInOtpBuff(unsigned int *otp, unsigned char *scpBuff)
+{
+    int  i = 0;
+    int  zeroCount = 0;
+    int scpZeroSize = ((0x1 << OTP_MANUFACTOR_FLAG_SCP_ZEROS_NUM_BITS)-1);
+    int scpZeroMask = (scpZeroSize << OTP_MANUFACTOR_FLAG_SCP_ZEROS_BIT_OFFSET);
+
+    if ((NULL == otp) ||
+        (NULL == scpBuff)) {
+        TEST_PRINTF_ERROR("testSetScpInOtpBuff ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    for (i=0; i< OTP_SCP_SIZE_IN_WORDS; i++) {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&scpBuff[i*sizeof(uint32_t)], otp[OTP_SCP_START_WORD_OFFSET+i])
+    }
+
+    TEST_CALC_BUFF_ZEROS(&otp[OTP_SCP_START_WORD_OFFSET], OTP_SCP_SIZE_IN_WORDS, zeroCount);
+    otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] &= ~(scpZeroMask);
+    otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] |= (zeroCount)<<OTP_MANUFACTOR_FLAG_SCP_ZEROS_BIT_OFFSET;
+    return TEST_OK;
+
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetKdrInOtpBuff(unsigned int *otp, unsigned char *kdrBuff)
+{
+    int  i = 0;
+    int  zeroCount = 0;
+    int kdrZeroSize = ((0x1 << OTP_MANUFACTOR_FLAG_KDR_ZEROS_NUM_BITS)-1);
+    int kdrZeroMask = (kdrZeroSize << OTP_MANUFACTOR_FLAG_KDR_ZEROS_BIT_OFFSET);
+
+    if ((NULL == otp) ||
+        (NULL == kdrBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    for (i=0; i< OTP_KRD_SIZE_IN_WORDS; i++) {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&kdrBuff[i*sizeof(uint32_t)], otp[OTP_KRD_START_WORD_OFFSET+i])
+    }
+
+    TEST_CALC_BUFF_ZEROS(&otp[OTP_KRD_START_WORD_OFFSET], OTP_KRD_SIZE_IN_WORDS, zeroCount);
+    otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] &= ~(kdrZeroMask);
+    otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] |= (zeroCount)<<OTP_MANUFACTOR_FLAG_KDR_ZEROS_BIT_OFFSET;
+    return TEST_OK;
+
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetHbkInOtpBuff(unsigned int *otp, unsigned char *hbkBuff, OtpHbkTypes_t type)
+{
+    int  i = 0;
+    int  zeroCount = 0;
+    int otpStartOffset = (type == TEST_OTP_HBK1_TYPE)?OTP_HBK1_START_WORD_OFFSET:OTP_HBK0_START_WORD_OFFSET;
+    int hbkStartOffset = (type == TEST_OTP_HBK1_TYPE)?OTP_HBK0_SIZE_IN_WORDS:0;
+    int hbkWordSize;
+    int hbkZeroSizeBits = 0;
+    int hbkZeroMaskBits = 0;
+
+
+    if ((NULL == otp) ||
+        (NULL == hbkBuff)) {
+        TEST_PRINTF_ERROR("testSetHbkInOtpBuff ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    TEST_PRINTF_ERROR("type %d\n", type);
+    if ((type == TEST_OTP_HBK0_TYPE) ||
+        (type == TEST_OTP_HBK1_TYPE)) {
+        hbkWordSize = OTP_HBK0_SIZE_IN_WORDS;
+    } else if ((type == TEST_OTP_HBK_256_TYPE) ||
+           (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE))) {
+        hbkWordSize = OTP_HBK0_SIZE_IN_WORDS+OTP_HBK1_SIZE_IN_WORDS;
+    } else {
+        TEST_PRINTF_ERROR("ilegal type %d\n", type);
+        return TEST_INVALID_PARAM_ERR;
+    }
+    TEST_PRINTF_ERROR("writing hbk otpStartOffset %d, hbkWordSize %d\n", otpStartOffset, hbkWordSize);
+    for (i=0; i< hbkWordSize; i++) {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&hbkBuff[(hbkStartOffset+i)*sizeof(uint32_t)], otp[otpStartOffset+i]);
+    }
+
+    /* calculate HBK's zeros and save in OTP */
+    if (type == TEST_OTP_HBK0_TYPE) {
+        memset(&otp[OTP_HBK1_START_WORD_OFFSET], 0, OTP_HBK1_SIZE_IN_WORDS);
+    }
+    if (type == TEST_OTP_HBK1_TYPE) {
+        memset(&otp[OTP_HBK0_START_WORD_OFFSET], 0, OTP_HBK0_SIZE_IN_WORDS);
+    }
+    otp[OTP_DM_DEF_START_WORD_OFFSET] &= ~(0xFFFF);
+    if (type == TEST_OTP_HBK_256_TYPE) {
+        otp[OTP_DM_DEF_START_WORD_OFFSET] |= 0xFF00;
+    }
+    if (type & TEST_OTP_HBK1_TYPE) {
+        hbkZeroSizeBits = ((0x1 << OTP_DM_DEF_HBK1_ZEROS_NUM_BITS)-1);
+        hbkZeroMaskBits = (hbkZeroSizeBits << OTP_DM_DEF_HBK1_ZEROS_BIT_OFFSET);
+        TEST_CALC_BUFF_ZEROS(&otp[OTP_HBK1_START_WORD_OFFSET], OTP_HBK1_SIZE_IN_WORDS, zeroCount);
+        otp[OTP_DM_DEF_START_WORD_OFFSET] &= ~(hbkZeroMaskBits);
+        otp[OTP_DM_DEF_START_WORD_OFFSET] |= (zeroCount)<<OTP_DM_DEF_HBK1_ZEROS_BIT_OFFSET;
+        TEST_PRINTF_ERROR("zeros for HBK1 %d\n", zeroCount);
+    }
+    if (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE)) {
+        hbkWordSize = OTP_HBK0_SIZE_IN_WORDS; // OTP_HBK1_SIZE_IN_WORDS  was already writen
+    }
+    if ((type & TEST_OTP_HBK0_TYPE) ||
+        (type == TEST_OTP_HBK_256_TYPE)) {
+        hbkZeroSizeBits = ((0x1 << OTP_DM_DEF_HBK0_ZEROS_NUM_BITS)-1);
+        hbkZeroMaskBits = (hbkZeroSizeBits << OTP_DM_DEF_HBK0_ZEROS_BIT_OFFSET);
+        TEST_CALC_BUFF_ZEROS(&otp[OTP_HBK0_START_WORD_OFFSET], hbkWordSize, zeroCount);
+        otp[OTP_DM_DEF_START_WORD_OFFSET] &= ~(hbkZeroMaskBits);
+        otp[OTP_DM_DEF_START_WORD_OFFSET] |= (zeroCount)<<OTP_DM_DEF_HBK0_ZEROS_BIT_OFFSET;
+        TEST_PRINTF_ERROR("zeros for HBK0 %d\n", zeroCount);
+    }
+    TEST_PRINTF_ERROR("otp[OTP_DM_DEF_START_WORD_OFFSET] 0x%x\n", otp[OTP_DM_DEF_START_WORD_OFFSET]);
+
+    return TEST_OK;
+
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetSecureInOtpBuff(unsigned int *otp, unsigned char enFlag)
+{
+    int   secEnSizeBits = ((0x1 << OTP_MANUFACTOR_FLAG_SEC_EN_NUM_BITS)-1);
+    int   secEnMaskBits = (secEnSizeBits << OTP_MANUFACTOR_FLAG_SEC_EN_BIT_OFFSET);
+    if (NULL == otp) {
+        TEST_PRINTF_ERROR("testSetSecureInOtpBuff ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] &= ~(secEnMaskBits);
+    otp[OTP_MANUFACTOR_FLAG_START_WORD_OFFSET] |= (enFlag)<<OTP_MANUFACTOR_FLAG_SEC_EN_BIT_OFFSET;
+    return TEST_OK;
+}
+
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+
+
+int testReadKdrZeros()
+{
+    int otpVal = 0;
+    int ZeroSize = 0;
+    int ZeroMask = 0;
+
+    ZeroSize = ((0x1 << OTP_MANUFACTOR_FLAG_KDR_ZEROS_NUM_BITS)-1);
+    ZeroMask = (ZeroSize << OTP_MANUFACTOR_FLAG_KDR_ZEROS_BIT_OFFSET);
+
+    /* NOTE! manufacturer word bits[15:0] acn be read only if LCS is CM or DM */
+    READ_AIB(OTP_MANUFACTOR_FLAG_START_WORD_OFFSET*sizeof(uint32_t), otpVal);
+
+    return (otpVal&ZeroMask);
+}
+
+unsigned int testReadOtp(unsigned int offset, unsigned int size, uint32_t *buff)
+{
+        unsigned int i = 0;
+
+        if ((size == 0) || (buff == NULL)) {
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+        for (i = 0; i < size; i++) {
+                buff[i] = READ_OTP(offset+i);
+                TEST_PRINTF("buff[%d] 0x%X", i, buff[i]);
+        }
+
+    return TEST_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access.h
new file mode 100644
index 0000000..f3708b9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __TST_HW_ACCESS_H__
+#define __TST_HW_ACCESS_H__
+
+#include <stdint.h>
+
+extern unsigned long    g_testHwRegBaseAddr;
+extern unsigned long    g_testHwReeRegBaseAddr;
+extern unsigned long    g_testHwEnvBaseAddr;
+
+/* rotate 32-bits word by 16 bits */
+#define ROT32(x) ( (x) >> 16 | (x) << 16 )
+
+/* inverse the bytes order in a word */
+#define REVERSE32(x)  ( ((ROT32((x)) & 0xff00ff00UL) >> 8) | ((ROT32((x)) & 0x00ff00ffUL) << 8) )
+
+#ifndef BIG__ENDIAN
+/* define word endiannes*/
+#define  SET_WORD_ENDIANESS
+#else
+#define  SET_WORD_ENDIANESS(val) REVERSE32(val)
+#endif
+
+
+#define SESSION_KEY_LEN_IN_BYTES 16
+
+/* LCS */
+#define TESTS_LCS_CM        0x0
+#define TESTS_LCS_DM        0x1
+#define TESTS_LCS_SEC_DISABLED  0x3
+#define TESTS_LCS_SEC_ENABLED   0x5
+#define TESTS_LCS_RMA       0x7
+
+/* errors */
+#define TEST_OK         0
+#define TEST_BURN_OTP_ERR   1
+#define TEST_BURN_OTP_KDR_ERR   2
+#define TEST_BURN_OTP_SCP_ERR   3
+#define TEST_BURN_OTP_LCS_ERR   4
+#define TEST_INVALID_PARAM_ERR  5
+
+
+/* OTP memeory mapping */
+
+#define ENV_OTP_START_OFFSET        0x800UL
+#define TEST_OTP_SIZE_IN_WORDS      0x25
+
+#define OTP_KRD_START_WORD_OFFSET    0x00
+#define OTP_KRD_SIZE_IN_WORDS        0x08
+#define OTP_KRD_SIZE_IN_BYTES        (OTP_KRD_SIZE_IN_WORDS * sizeof(uint32_t))
+#define OTP_SCP_START_WORD_OFFSET    0x08
+#define OTP_SCP_SIZE_IN_WORDS        0x02
+
+#define OTP_MANUFACTOR_FLAG_START_WORD_OFFSET 0x0A
+#define OTP_MANUFACTOR_FLAG_SIZE_IN_WORDS     0x01
+#define OTP_MANUFACTOR_FLAG_KDR_ZEROS_BIT_OFFSET 0x00
+#define OTP_MANUFACTOR_FLAG_KDR_ZEROS_NUM_BITS 0x08
+#define OTP_MANUFACTOR_FLAG_SCP_ZEROS_BIT_OFFSET 0x08
+#define OTP_MANUFACTOR_FLAG_SCP_ZEROS_NUM_BITS 0x07
+#define OTP_MANUFACTOR_FLAG_SEC_EN_BIT_OFFSET 0x10
+#define OTP_MANUFACTOR_FLAG_SEC_EN_NUM_BITS   0x04
+#define OTP_MANUFACTOR_FLAG_SEC_ENABLE 0x3
+#define OTP_MANUFACTOR_FLAG_SEC_DISABLE 0xC
+
+
+#define OTP_DM_DEF_START_WORD_OFFSET 0x0B
+#define OTP_DM_DEF_SIZE_IN_WORDS     0x02
+#define OTP_DM_DEF_HBK0_ZEROS_BIT_OFFSET 0x00
+#define OTP_DM_DEF_HBK0_ZEROS_NUM_BITS 0x08
+#define OTP_DM_DEF_HBK1_ZEROS_BIT_OFFSET 0x08
+#define OTP_DM_DEF_HBK1_ZEROS_NUM_BITS 0x08
+
+#define OTP_KCE_START_WORD_OFFSET    0x0C
+#define OTP_KCE_SIZE_IN_WORDS        0x04
+#define OTP_HBK0_START_WORD_OFFSET   0x10
+#define OTP_HBK0_SIZE_IN_WORDS       0x04
+#define OTP_HBK1_START_WORD_OFFSET   0x14
+#define OTP_HBK1_SIZE_IN_WORDS       0x04
+#define OTP_SB_VER_START_WORD_OFFSET 0x18
+#define OTP_SB_VER_SIZE_IN_WORDS     0x01
+
+
+#define AIB_ADDR_REG_READ_ACCESS_BIT_SHIFT    0x10UL
+#define AIB_ADDR_REG_WRITE_ACCESS_BIT_SHIFT   0x11UL
+
+#define OTP_BASE_ADDR                0x00
+#define OTP_WRITE_ADDR               (0x1 << AIB_ADDR_REG_WRITE_ACCESS_BIT_SHIFT)
+#define OTP_READ_ADDR                (0x1 << AIB_ADDR_REG_READ_ACCESS_BIT_SHIFT)
+
+#ifdef BIG__ENDIAN
+#define TEST_CONVERT_BYTE_ARR_TO_WORD(inPtr, outWord) {\
+    outWord = (*inPtr<<24);\
+    outWord |= (*(inPtr+1)<<16);\
+    outWord |= (*(inPtr+2)<<8);\
+    outWord |= (*(inPtr+3));\
+}
+#else
+#define TEST_CONVERT_BYTE_ARR_TO_WORD(inPtr, outWord) {\
+    outWord = (*(inPtr+3))<<24;\
+    outWord |= (*(inPtr+2))<<16;\
+    outWord |= (*(inPtr+1))<<8;\
+    outWord |= (*inPtr);\
+}
+#endif
+
+
+#define TEST_CALC_BUFF_ZEROS(wordBuf, buffWordSize, zeros) {\
+    int i = 0;\
+    int j = 0;\
+    int mask = 0;\
+    zeros = 0;\
+    for (i = 0; i< buffWordSize; i++) {\
+        for (j = 0; j<32; j++) {\
+            mask = 0x1;\
+            if (!(*(wordBuf+i) & (mask << j))) {\
+                zeros++;\
+            }\
+        }\
+    }\
+}
+
+
+#define READ_REG(offset) \
+        *(volatile uint32_t *)(g_testHwRegBaseAddr + (offset))
+
+#define WRITE_REG(offset, val)  { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwRegBaseAddr + (offset))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++); \
+}
+
+
+#define READ_REE_REG(offset) \
+        (*(volatile uint32_t *)(g_testHwReeRegBaseAddr + (offset)));
+
+#define WRITE_REE_REG(offset, val)   { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwReeRegBaseAddr + (offset))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++); \
+}
+
+
+#define GET_LCS(val) {\
+    do {\
+            val = READ_REG(DX_LCS_IS_VALID_REG_OFFSET);\
+    }while( !(val & 0x1));\
+    val = READ_REG(DX_LCS_REG_REG_OFFSET);\
+    val &= 0xFF;\
+    }
+
+#define WRITE_ENV(offset, val) { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwEnvBaseAddr + (offset))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++);\
+}
+
+#define READ_ENV(offset) \
+    *(volatile uint32_t *)(g_testHwEnvBaseAddr + (offset))
+
+
+#define WRITE_OTP(wordOffset, val) { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwEnvBaseAddr + ENV_OTP_START_OFFSET+ ((wordOffset)*sizeof(uint32_t)))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++);\
+}
+
+#define READ_OTP(wordOffset) \
+    (*(volatile uint32_t *)(g_testHwEnvBaseAddr + ENV_OTP_START_OFFSET+ ((wordOffset)*sizeof(uint32_t))))
+
+
+
+/* Poll on the AIB bit */
+#define WAIT_ON_AIB_PROG_COMP_BIT() \
+do {\
+    int regVal;\
+    do {\
+        regVal = READ_REG(DX_AIB_FUSE_PROG_COMPLETED_REG_OFFSET);\
+    }while( !(regVal & 0x1 ));\
+}while(0)
+
+/* Poll on the AIB acknowledge bit */
+#define WAIT_ON_AIB_ACK_BIT() \
+do {\
+    int regVal;\
+    do {\
+        regVal = READ_REG(DX_AIB_FUSE_ACK_REG_OFFSET);\
+    }while( !(regVal & 0x1));\
+}while(0)
+
+#define WRITE_AIB(addr, val) { \
+            WRITE_REG(DX_HOST_AIB_WDATA_REG_REG_OFFSET, val);\
+            WRITE_REG(DX_HOST_AIB_ADDR_REG_REG_OFFSET, (OTP_BASE_ADDR|OTP_WRITE_ADDR)+addr);\
+            WAIT_ON_AIB_ACK_BIT();\
+            WAIT_ON_AIB_PROG_COMP_BIT();\
+}
+
+#define READ_AIB(addr, val) { \
+        WRITE_REG(DX_HOST_AIB_ADDR_REG_REG_OFFSET, (OTP_BASE_ADDR|OTP_READ_ADDR)+addr); \
+        WAIT_ON_AIB_ACK_BIT(); \
+        val = READ_REG(DX_HOST_AIB_RDATA_REG_REG_OFFSET); \
+}
+
+typedef enum otpHbkTypes_t{
+    TEST_OTP_HBK0_TYPE = 1, //HBK0
+    TEST_OTP_HBK1_TYPE = 2, //HBK1
+    TEST_OTP_HBK_256_TYPE = 4, //HBK
+}OtpHbkTypes_t;
+
+
+/******************************/
+/*   function declaration     */
+/*****************************/
+
+unsigned int testBurnOtp(unsigned int  *otp, unsigned int  nextLcs);
+unsigned int testClearOtp(void);
+int testReadKdrZeros(void);
+
+void performPowerOnReset(void);
+void performColdReset(void);
+void performWarmReset(void);
+unsigned int testCheckLcs(unsigned int  nextLcs);
+
+unsigned int testSetKdrInOtpBuff(unsigned int *otp, unsigned char *kdrBuff);
+unsigned int testSetScpInOtpBuff(unsigned int *otp, unsigned char *scpBuff);
+unsigned int testSetHbkInOtpBuff(unsigned int *otp, unsigned char *hbkBuff, OtpHbkTypes_t type);
+unsigned int testSetSecureInOtpBuff(unsigned int *otp, unsigned char enFlag);
+unsigned int testReadOtp(unsigned int offset, unsigned int size, uint32_t *buff);
+
+#endif //__TST_HW_ACCESS_H__
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access_iot.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access_iot.c
new file mode 100644
index 0000000..d1b6606
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access_iot.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include "cc_pal_types.h"
+#include "dx_env.h"
+#include "dx_nvm.h"
+#include "cc_regs.h"
+#include "dx_host.h"
+#include "tests_hw_access_iot.h"
+#include "tests_phys_map.h"
+#include "test_log.h"
+#include "dx_crys_kernel.h"
+#include "cc_otp_defs.h"
+
+
+
+/******************************/
+/*   function definitions     */
+/*****************************/
+
+unsigned int testCheckLcs(unsigned int  nextLcs)
+{
+    unsigned int regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE(regVal);
+
+    /* Read the LCS register */
+    regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    /* Verify lcs */
+    if(regVal != nextLcs) {
+                TEST_PRINTF_ERROR("actual LCS %d != expected LCS %d", regVal, nextLcs);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+unsigned int testCheckLcsAndError(unsigned int  nextLcs)
+{
+    unsigned int regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE(regVal);
+
+    /* Read the LCS register */
+    regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    /* Verify lcs */
+    if(regVal != nextLcs) {
+                TEST_PRINTF_ERROR("actual LCS %d != expected LCS %d", regVal, nextLcs);
+        return -1;
+    }
+
+    if ((CC_REG_FLD_GET(0, LCS_REG, ERROR_KDR_ZERO_CNT, regVal) != 0) ||
+            (CC_REG_FLD_GET(0, LCS_REG, ERROR_KPICV_ZERO_CNT, regVal) != 0) ||
+            (CC_REG_FLD_GET(0, LCS_REG, ERROR_KCEICV_ZERO_CNT, regVal) != 0) ||
+        (CC_REG_FLD_GET(0, LCS_REG, ERROR_PROV_ZERO_CNT, regVal) != 0) ||
+            (CC_REG_FLD_GET(0, LCS_REG, ERROR_KCE_ZERO_CNT, regVal) != 0)) {
+                TEST_PRINTF_ERROR("regVal 0x%x indicates error for LCS %d", regVal, nextLcs);
+        return -1;
+    }
+
+    return 0;
+}
+
+
+unsigned int testGetLcs(unsigned int  *lcs)
+{
+    unsigned int regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE(regVal);
+
+    /* Read the LCS register */
+    regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    *lcs = regVal;
+
+    return 0;
+}
+
+
+unsigned int testGetOtpSize(unsigned int * size)
+{
+    unsigned int regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE(regVal);
+
+    /* Read the LCS register */
+    regVal = READ_REG(DX_OTP_ADDR_WIDTH_DEF_REG_OFFSET);
+    regVal = CC_REG_FLD_GET(0, OTP_ADDR_WIDTH_DEF, VALUE, regVal);
+
+    *size = regVal;
+
+    return 0;
+}
+
+
+/* Global Reset of CC and AO and env regs */
+void performPowerOnReset(void)
+{
+    WRITE_ENV(DX_ENV_CC_POR_N_ADDR_REG_OFFSET , 0x1UL);
+    usleep(1000);
+
+    /* poll NVM register to assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE(regVal);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+
+    /* turn off the DFA since Cerberus doesn't support it */
+    TURN_DFA_OFF();
+    return;
+
+}
+
+
+/* Reset both CC and AO regs */
+void performColdReset(void)
+{
+    WRITE_ENV(DX_ENV_CC_COLD_RST_REG_OFFSET , 0x1UL);
+    usleep(1000);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+    /* turn off the DFA since Cerberus doesn't support it */
+    TURN_DFA_OFF();
+    return;
+}
+
+
+/* Reset only CC regs */
+void performWarmReset(void)
+{
+    WRITE_ENV(DX_ENV_CC_RST_N_REG_OFFSET , 0x1UL);
+    usleep(1000);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+    return;
+
+}
+
+unsigned int testBurnOtp(unsigned int  *otpBuf, unsigned int  nextLcs)
+{
+
+    CCError_t error = 0;
+    unsigned int i = 0;
+
+    /* Clean OTP */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        WRITE_OTP(i, 0);
+        usleep(1000);
+    }
+
+    /* Perform SW reset to reach CM LCS */
+    performPowerOnReset();
+    usleep(1000);
+
+    /* Copy new OTP buffer */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+                TEST_PRINTF("writing Otp [0x%X] 0x%X", i, otpBuf[i]);
+        WRITE_OTP(i, otpBuf[i]);
+        usleep(1000);
+    }
+
+    /*  Perform SW reset after writing to OTP new values */
+    performPowerOnReset();
+
+    /* verify LCS */
+    error = testCheckLcs(nextLcs);
+    if (error == 0) {
+        TEST_PRINTF(" OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
+    } else {
+        TEST_PRINTF_ERROR("Error: Failed to burn OTP!!\n");
+    }
+
+    return error;
+}
+
+
+uint32_t initPlatform(void)
+{
+    unsigned int rc = 0;
+
+    rc = TestMapCCRegs();
+    if (rc != 0) {
+        TEST_PRINTF_ERROR("Failed to TestMapCCRegs");
+        return rc;
+    }
+
+    TST_SET_ENV_TO_SECURE();
+
+    return 0;
+}
+
+void freePlatform(void)
+{
+    TestUnmapCCRegs();
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetKdrInOtpBuff(unsigned int *otp, unsigned char *kdrBuff)
+{
+    int  i = 0;
+    int  zeroCount = 0;
+    int kdrZeroSize = ((0x1 << CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SIZE)-1);
+    int kdrZeroMask = (kdrZeroSize << CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SHIFT);
+
+    if ((NULL == otp) ||
+        (NULL == kdrBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    for (i=0; i< CC_OTP_HUK_SIZE_IN_WORDS; i++) {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&kdrBuff[i*sizeof(uint32_t)], otp[CC_OTP_START_OFFSET+i])
+    }
+
+    TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_START_OFFSET], CC_OTP_HUK_SIZE_IN_WORDS, zeroCount);
+    otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(kdrZeroMask);
+    otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SHIFT;
+    return TEST_OK;
+
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetHbkInOtpBuff(unsigned int *otp, unsigned char *hbkBuff, OtpHbkTypes_t type)
+{
+    int  i = 0;
+    int  zeroCount = 0;
+    int otpStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK1_OFFSET:CC_OTP_HBK0_OFFSET;
+    int hbkStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK0_SIZE_IN_WORDS:0;
+    int hbkWordSize;
+
+
+    if ((NULL == otp) ||
+        (NULL == hbkBuff)) {
+        TEST_PRINTF_ERROR("testSetHbkInOtpBuff ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    TEST_PRINTF_ERROR("type %d\n", type);
+    if ((type == TEST_OTP_HBK0_TYPE) ||
+        (type == TEST_OTP_HBK1_TYPE)) {
+        hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS;
+    } else if ((type == TEST_OTP_HBK_256_TYPE) ||
+           (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE))) {
+        hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS+CC_OTP_HBK1_SIZE_IN_WORDS;
+    } else {
+        TEST_PRINTF_ERROR("ilegal type %d\n", type);
+        return TEST_INVALID_PARAM_ERR;
+    }
+    //clear OEM HBK and its zero count
+    memset(&otp[CC_OTP_HBK1_OFFSET], 0, CC_OTP_HBK1_SIZE_IN_WORDS);
+    otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
+    //clear ICV HBK
+    memset(&otp[CC_OTP_HBK0_OFFSET], 0, CC_OTP_HBK0_SIZE_IN_WORDS);
+    //clear ICV HBK zero count
+    otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
+    // clear HBK0 usage
+    otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (1<<CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SHIFT);
+    TEST_PRINTF_ERROR("writing hbk otpStartOffset %d, hbkWordSize %d\n", otpStartOffset, hbkWordSize);
+    for (i=0; i< hbkWordSize; i++) {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&hbkBuff[(hbkStartOffset+i)*sizeof(uint32_t)], otp[otpStartOffset+i]);
+    }
+
+    if (type & TEST_OTP_HBK0_TYPE) {
+        TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK0_OFFSET], CC_OTP_HBK0_SIZE_IN_WORDS, zeroCount);
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_MANUFACTURE_FLAG_HBK0_ZERO_BITS_BIT_SHIFT;
+        TEST_PRINTF_ERROR("zeros for HBK1 %d\n", zeroCount);
+    }
+    if (type & TEST_OTP_HBK1_TYPE) {
+        TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK1_OFFSET], CC_OTP_HBK1_SIZE_IN_WORDS, zeroCount);
+        otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
+        otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
+        TEST_PRINTF_ERROR("zeros for HBK1 %d\n", zeroCount);
+    }
+    if (type == TEST_OTP_HBK_256_TYPE) {
+        TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK_OFFSET], hbkWordSize, zeroCount);
+        otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
+        otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount)<<CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
+        TEST_PRINTF_ERROR("zeros for HBK0 %d\n", zeroCount);
+    }
+    TEST_PRINTF_ERROR("otp[0x%lx] 0x%x, otp[0x%lx] 0x%x\n", CC_OTP_OEM_FLAG_OFFSET,
+        otp[CC_OTP_OEM_FLAG_OFFSET], CC_OTP_MANUFACTURE_FLAG_OFFSET, otp[CC_OTP_MANUFACTURE_FLAG_OFFSET]);
+
+    return TEST_OK;
+}
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetKpicvInOtpBuff(unsigned int *otpBuf, unsigned int *kpicvBuff)
+{
+    int  zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) ||
+        (NULL == kpicvBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *)(otpBuf+CC_OTP_KPICV_OFFSET), (uint8_t *)kpicvBuff, CC_OTP_KPICV_SIZE_IN_WORDS*sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KPICV_OFFSET], CC_OTP_KPICV_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetKceicvOtpBuff(unsigned int *otpBuf, unsigned int *kceicvBuff)
+{
+    int  zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) ||
+        (NULL == kceicvBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *)(otpBuf+CC_OTP_KCEICV_OFFSET), (uint8_t *)kceicvBuff, CC_OTP_KCEICV_SIZE_IN_WORDS*sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCEICV_OFFSET], CC_OTP_KCEICV_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetKcpOtpBuff(unsigned int *otpBuf, unsigned int *kcpBuff)
+{
+    int  zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) ||
+        (NULL == kcpBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *)(otpBuf+CC_OTP_KCP_OFFSET), (uint8_t *)kcpBuff, CC_OTP_KCP_SIZE_IN_WORDS*sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCP_OFFSET], CC_OTP_KCP_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetKceOtpBuff(unsigned int *otpBuf, unsigned int *kceBuff)
+{
+    int  zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) ||
+        (NULL == kceBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *)(otpBuf+CC_OTP_KCE_OFFSET), (uint8_t *)kceBuff, CC_OTP_KCE_SIZE_IN_WORDS*sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCE_OFFSET], CC_OTP_KCE_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+
+/*
+ * @brief This function suggegst that all keys are already set, and set manufacture and oem flags appropriately
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+unsigned int testSetLcsOtpBuff(unsigned int *otpBuf, unsigned int lcsState)
+{
+        //if RMA => set ICV_RMA and OEM_RMA bits
+        //if CM => man_flag[31:0]=0 && oem_flag[7:0] = 0
+        //if DM => oem_flag[7:0] = 0
+        // otherwise SE
+
+        uint32_t hwWord = 0;
+
+        switch (lcsState) {
+        case TESTS_LCS_RMA:
+                hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+                CC_REG_FLD_SET2(0, OTP_OEM_FLAG, ICV_RMA_MODE, hwWord, 1);
+                CC_REG_FLD_SET2(0, OTP_OEM_FLAG, OEM_RMA_MODE, hwWord, 1);
+                otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+                break;
+        case TESTS_LCS_CM:
+                otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = 0;
+                // continue to clean oem_flag[7:0] bits as for DM
+        case TESTS_LCS_DM:
+                hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+                CC_REG_FLD_SET2(0, OTP_OEM_FLAG, HBK_ZERO_BITS, hwWord, 0);
+                otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+                break;
+
+        case TESTS_LCS_SEC_DISABLED:
+        case TESTS_LCS_SEC_ENABLED:
+                break;
+        default:
+                TEST_PRINTF_ERROR(" ilegal lcs params\n");
+                return TEST_INVALID_PARAM_ERR;
+        }
+        return TEST_OK;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access_iot.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access_iot.h
new file mode 100644
index 0000000..08e8635
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_hw_access_iot.h
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __TST_HW_ACCESS_H__
+#define __TST_HW_ACCESS_H__
+
+#include <stdint.h>
+
+#include "dx_reg_base_host.h"
+#include "dx_env.h"
+
+/* rotate 32-bits word by 16 bits */
+#define ROT32(x) ( (x) >> 16 | (x) << 16 )
+
+/* inverse the bytes order in a word */
+#define REVERSE32(x)  ( ((ROT32((x)) & 0xff00ff00UL) >> 8) | ((ROT32((x)) & 0x00ff00ffUL) << 8) )
+
+#ifndef BIG__ENDIAN
+/* define word endiannes*/
+#define  SET_WORD_ENDIANESS
+#else
+#define  SET_WORD_ENDIANESS(val) REVERSE32(val)
+#endif
+
+/* LCS */
+#define TESTS_LCS_CM        0x0
+#define TESTS_LCS_DM        0x1
+#define TESTS_LCS_SEC_DISABLED  0x3
+#define TESTS_LCS_SEC_ENABLED   0x5
+#define TESTS_LCS_RMA       0x7
+
+/* errors */
+#define TEST_OK         0
+#define TEST_BURN_OTP_ERR   1
+#define TEST_BURN_OTP_KDR_ERR   2
+#define TEST_BURN_OTP_SCP_ERR   3
+#define TEST_BURN_OTP_LCS_ERR   4
+#define TEST_INVALID_PARAM_ERR  5
+
+/* OTP memeory mapping */
+#define ENV_OTP_START_OFFSET        0x2000UL
+#define TEST_OTP_SIZE_IN_WORDS      0x2C
+#define MAX_OTP_SIZE_IN_WORDS       0x7FF
+
+typedef enum otpHbkTypes_t{
+    TEST_OTP_HBK0_TYPE = 1, //HBK0
+    TEST_OTP_HBK1_TYPE = 2, //HBK1
+    TEST_OTP_HBK_256_TYPE = 4, //HBK
+}OtpHbkTypes_t;
+
+#ifdef BIG__ENDIAN
+#define TEST_CONVERT_BYTE_ARR_TO_WORD(inPtr, outWord) {\
+    outWord = (*inPtr<<24);\
+    outWord |= (*(inPtr+1)<<16);\
+    outWord |= (*(inPtr+2)<<8);\
+    outWord |= (*(inPtr+3));\
+}
+#else
+#define TEST_CONVERT_BYTE_ARR_TO_WORD(inPtr, outWord) {\
+    outWord = (*(inPtr+3))<<24;\
+    outWord |= (*(inPtr+2))<<16;\
+    outWord |= (*(inPtr+1))<<8;\
+    outWord |= (*inPtr);\
+}
+#endif
+
+
+#define TEST_CALC_BUFF_ZEROS(wordBuf, buffWordSize, zeros) {\
+    int i = 0;\
+    int j = 0;\
+    int mask = 0;\
+    zeros = 0;\
+    for (i = 0; i< buffWordSize; i++) {\
+        for (j = 0; j<32; j++) {\
+            mask = 0x1;\
+            if (!(*(wordBuf+i) & (mask << j))) {\
+                zeros++;\
+            }\
+        }\
+    }\
+}
+
+
+
+#define READ_REG(offset) \
+        *(volatile uint32_t *)(g_testHwRegBaseAddr + (offset))
+
+#define WRITE_REG(offset, val)  { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwRegBaseAddr + (offset))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++); \
+}
+
+#define WRITE_REG_OTP(offset, val)  { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwRegBaseAddr + CC_OTP_BASE_ADDR +(offset*sizeof(uint32_t)))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++); \
+}
+
+#define READ_REG_OTP(offset)   \
+    *(volatile uint32_t *)(g_testHwRegBaseAddr + CC_OTP_BASE_ADDR+ (offset))
+
+#define WRITE_ENV(offset, val) { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwEnvBaseAddr + (offset))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++);\
+}
+
+#define READ_ENV(offset) \
+    *(volatile uint32_t *)(g_testHwEnvBaseAddr + (offset))
+
+
+#define WRITE_OTP(wordOffset, val) { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(g_testHwEnvBaseAddr + ENV_OTP_START_OFFSET+ ((wordOffset)*sizeof(uint32_t)))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++);\
+}
+
+#define READ_OTP(wordOffset) \
+    *(volatile uint32_t *)(g_testHwEnvBaseAddr + ENV_OTP_START_OFFSET + ((wordOffset)*sizeof(uint32_t)))
+
+#ifdef DX_PLAT_ZYNQ7000
+#define TST_SET_ENV_TO_SECURE()                                 \
+        do {                                                        \
+        WRITE_ENV( DX_ENV_APB_PPROT_OVERRIDE_REG_OFFSET, 0x9);  \
+    }while(0)
+#else
+#define TST_SET_ENV_TO_SECURE()                     \
+    do {                                \
+    }while(0)
+#endif
+
+
+/* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+#define WAIT_NVM_IDLE(regVal) \
+    do {                                            \
+        uint32_t regVal;                                \
+        do {                                        \
+            regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, NVM_IS_IDLE));            \
+            regVal = CC_REG_FLD_GET(0, NVM_IS_IDLE, VALUE, regVal);         \
+        }while( !regVal );                              \
+    }while(0)
+
+/* turn off DFA  */
+#define TURN_DFA_OFF() {\
+    uint32_t regVal;                            \
+    regVal = READ_REG(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));          \
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, regVal, 0); \
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_DFA_ENABLE_LOCK, regVal, 1);  \
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,regVal );    \
+    WRITE_REG(CC_REG_OFFSET(HOST_RGF, AES_DFA_IS_ON)  ,0 );         \
+}
+
+
+#define SET_OTP_DCU_LOCK(otpBuff, val) {\
+    uint32_t ii = 0; \
+    for (ii = 0; ii < CC_OTP_DCU_SIZE_IN_WORDS; ii++) { \
+        otpBuff[CC_OTP_DCU_OFFSET+ii] = val; \
+    } \
+}
+
+/* calc OTP memory length:
+   read RTL OTP address width. The supported sizes are 6 (for 2 Kbits),7,8,9,10,11 (for 64 Kbits).
+   convert value parameter to addresses of 32b words */
+#define GET_OTP_LENGTH(otpLength)                           \
+    do {                                                \
+        otpLength = READ_REG(CC_REG_OFFSET(HOST_RGF, OTP_ADDR_WIDTH_DEF));  \
+        otpLength = CC_REG_FLD_GET(0, OTP_ADDR_WIDTH_DEF, VALUE, otpLength);            \
+        otpLength = (1 << otpLength);                               \
+    }while(0)
+
+
+/******************************/
+/*   function declaration     */
+/*****************************/
+
+void performPowerOnReset(void);
+unsigned int testBurnOtp(unsigned int  *otp, unsigned int  nextLcs);
+void dumpOTP(void);
+unsigned int testGetLcs(unsigned int  *lcs);
+unsigned int testGetOtpSize(unsigned int * size);
+unsigned int testCheckLcs(unsigned int  nextLcs);
+unsigned int testCheckLcsAndError(unsigned int  nextLcs);
+
+// hash key
+unsigned int testSetHbkInOtpBuff(unsigned int *otp, unsigned char *hbkBuff, OtpHbkTypes_t type);
+
+// huk key
+unsigned int testSetKdrInOtpBuff(unsigned int *otp, unsigned char *kdrBuff);
+
+// OEM keys
+unsigned int testSetKcpOtpBuff(unsigned int *otp, unsigned int *kpicvBuff);
+unsigned int testSetKceOtpBuff(unsigned int *otp, unsigned int *kpicvBuff);
+
+// ICV keys
+unsigned int testSetKpicvInOtpBuff(unsigned int *otp, unsigned int *kpicvBuff);
+unsigned int testSetKceicvOtpBuff(unsigned int *otp, unsigned int *kpicvBuff);
+
+unsigned int testSetLcsOtpBuff(unsigned int *otpBuf, unsigned int lcsState);
+
+uint32_t initPlatform(void);
+void freePlatform(void);
+
+#endif //__TST_HW_ACCESS_IOT_H__
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_otp.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_otp.c
new file mode 100644
index 0000000..829e639
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_otp.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "tests_otp.h"
+#include <stdio.h>
+#include <string.h>
+
+#include "cc_pal_types.h"
+#include "cc_regs.h"
+#include "cc_otp_defs.h"
+
+#include "board_configs.h"
+#include "test_pal_log.h"
+#include "test_pal_time.h"
+
+#include "hw_access.h"
+
+uint32_t Test_SetLcsOtpBuff(uint32_t *otpBuf, uint32_t lcsState)
+{
+    //if RMA => set ICV_RMA and OEM_RMA bits
+    //if CM => man_flag[31:0]=0 && oem_flag[7:0] = 0
+    //if DM => oem_flag[7:0] = 0
+    // otherwise SE
+
+    uint32_t hwWord = 0;
+
+    switch (lcsState) {
+        case TESTS_LCS_RMA:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, ICV_RMA_MODE, hwWord, 1);
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, OEM_RMA_MODE, hwWord, 1);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TESTS_LCS_CM:
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = 0;
+            /* fall-through */
+            // to clean oem_flag[7:0] bits as for DM
+        case TESTS_LCS_DM:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, HBK_ZERO_BITS, hwWord, 0);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+
+        case TESTS_LCS_SEC_DISABLED:
+        case TESTS_LCS_SEC_ENABLED:
+            break;
+        default:
+            TEST_PRINTF_ERROR("ERROR: ilegal lcs params\n");
+            return TEST_INVALID_PARAM_ERR;
+    }
+    return TEST_OK;
+}
+
+
+uint32_t Test_SetNotInUseOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value)
+{
+    uint32_t hwWord;
+
+    switch (keyType){
+        // TBD HBK
+        case TEST_KCP_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCE_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KPICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCEICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_HUK_KEY:
+        default:
+            TEST_PRINTF_ERROR("ERROR: can't set notInUse bit for this type of key\n");
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+    return TEST_OK;
+}
+
+uint32_t Test_SetZeroBitsOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value)
+{
+    uint32_t hwWord;
+
+    // TBD HBK??
+    switch (keyType){
+        case TEST_KCP_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCE_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KPICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCEICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_HUK_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, HUK_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        default:
+            TEST_PRINTF_ERROR("ERROR: can't set notInUse bit for this type of key\n");
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+    return TEST_OK;
+}
+
+uint32_t Test_SetKeyOtpBuff(uint32_t *otpBuf, uint32_t *keyBuff, uint32_t keyType)
+{
+    uint32_t zeroCount = 0;
+    uint32_t keySizeInWords = 0;
+    uint32_t keyOffsetInOtp = 0;
+    uint32_t rc = TEST_OK;
+
+    if ((NULL == otpBuf) || (NULL == keyBuff))
+    {
+        TEST_PRINTF_ERROR("ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+    // TBD HBK??
+    switch (keyType)
+    {
+        case TEST_HUK_KEY:
+            keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_HUK_OFFSET;
+            break;
+        case TEST_KCP_KEY:
+            keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCP_OFFSET;
+            break;
+        case TEST_KCE_KEY:
+            keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCE_OFFSET;
+            break;
+        case TEST_KPICV_KEY:
+            keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KPICV_OFFSET;
+            break;
+        case TEST_KCEICV_KEY:
+            keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCEICV_OFFSET;
+            break;
+        default:
+            TEST_PRINTF_ERROR("ERROR: key type is not supported\n")
+            ;
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+
+    memcpy((uint8_t *) (otpBuf + keyOffsetInOtp), (uint8_t *) keyBuff, keySizeInWords * sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(keyBuff, keySizeInWords, zeroCount);
+
+    if (keyType != TEST_HUK_KEY)
+    {
+        rc = Test_SetNotInUseOtpBuff(otpBuf, keyType, 0);
+    }
+
+    rc = rc & Test_SetZeroBitsOtpBuff(otpBuf, keyType, zeroCount);
+
+    return rc;
+}
+
+/**
+ * This function gets hw key and its size from otp buffer to user buffer
+ *
+ */
+uint32_t Test_GetKeyOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t *keySizeInWords, uint32_t *keyBuff )
+{
+    uint32_t keyOffsetInOtp = 0;
+    uint32_t rc = TEST_OK;
+
+    if ((NULL == otpBuf) || (NULL == keyBuff) || (NULL == keySizeInWords)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+    // TBD HBK??
+    switch (keyType){
+        case TEST_HUK_KEY:
+            *keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_HUK_OFFSET;
+            break;
+        case TEST_KCP_KEY:
+            *keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCP_OFFSET;
+            break;
+        case TEST_KCE_KEY:
+            *keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCE_OFFSET;
+            break;
+        case TEST_KPICV_KEY:
+            *keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KPICV_OFFSET;
+            break;
+        case TEST_KCEICV_KEY:
+            *keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCEICV_OFFSET;
+            break;
+        default:
+            *keySizeInWords = 0;
+            TEST_PRINTF_ERROR("ERROR: key type is not supported\n");
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+    memcpy((uint8_t *)keyBuff, (uint8_t *)(otpBuf + keyOffsetInOtp), (*keySizeInWords)*sizeof(uint32_t));
+
+    return rc;
+}
+
+
+uint32_t Test_SetHbkInOtpBuff(uint32_t *otp, uint8_t *hbkBuff, OtpHbkTypes_t type)
+{
+    uint32_t  i = 0;
+    uint32_t  zeroCount = 0;
+    int otpStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK1_OFFSET:CC_OTP_HBK0_OFFSET;
+    int hbkStartOffset = (type == TEST_OTP_HBK1_TYPE)?CC_OTP_HBK0_SIZE_IN_WORDS:0;
+    uint32_t hbkWordSize;
+
+
+    if ((NULL == otp) || (NULL == hbkBuff))
+    {
+        TEST_PRINTF_ERROR("testSetHbkInOtpBuff ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+    if ((type == TEST_OTP_HBK0_TYPE) || (type == TEST_OTP_HBK1_TYPE))
+    {
+        hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS;
+    }
+    else if ((type == TEST_OTP_HBK_256_TYPE) || (type == (TEST_OTP_HBK0_TYPE | TEST_OTP_HBK1_TYPE)))
+    {
+        hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS + CC_OTP_HBK1_SIZE_IN_WORDS;
+    }
+    else
+    {
+        TEST_PRINTF_ERROR("Illegal type %d\n", type);
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+    //clear OEM HBK and its zero count
+    memset(&otp[CC_OTP_HBK1_OFFSET], 0, CC_OTP_HBK1_SIZE_IN_WORDS);
+    otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
+
+    if (type != TEST_OTP_HBK1_TYPE)
+    {
+        //clear ICV HBK zero count and clear HBK0 usage
+        memset(&otp[CC_OTP_HBK0_OFFSET], 0, CC_OTP_HBK0_SIZE_IN_WORDS);
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
+
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (1U << CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SHIFT);
+    }
+
+    for (i = 0; i < hbkWordSize; i++)
+    {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&hbkBuff[(hbkStartOffset + i) * sizeof(uint32_t)], otp[otpStartOffset + i]);
+    }
+
+    if (type & TEST_OTP_HBK0_TYPE)
+    {
+        TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK0_OFFSET], CC_OTP_HBK0_SIZE_IN_WORDS, zeroCount);
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount) << CC_OTP_MANUFACTURE_FLAG_HBK0_ZERO_BITS_BIT_SHIFT;
+    }
+
+    if (type & TEST_OTP_HBK1_TYPE)
+    {
+        TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK1_OFFSET], CC_OTP_HBK1_SIZE_IN_WORDS, zeroCount);
+        otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
+        otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount) << CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
+    }
+
+    if (type == TEST_OTP_HBK_256_TYPE)
+    {
+        TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_HBK_OFFSET], hbkWordSize, zeroCount);
+        otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
+        otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount) << CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
+    }
+
+    return TEST_OK;
+}
+
+uint32_t Test_SetSwVerInOtpBuff(uint32_t *otp, uint32_t offset, uint32_t max_size)
+{
+    uint32_t i;
+
+    for (i=0; i<max_size ; i++)
+    {
+        if (otp[offset + i] < 0xFFFFFFFF)
+        {
+            memset(&otp[offset+i+1], 0x0, (max_size-i-1)* sizeof(uint32_t));
+            break;
+        }
+    }
+
+    return TEST_OK;
+}
+
+
+void Test_SetDefaultOtp(uint32_t* otpValues, uint32_t otpSize, uint32_t lcsState)
+{
+
+    uint32_t huk[]    = {0xCAFE1111, 0xCAFE1222, 0xCAFE1333, 0xCAFE1444, 0xCAFE1555, 0xCAFE1666, 0xCAFE1777, 0xCAFE1888};
+    uint32_t kpicv[]  = {0xCAFE2111, 0xCAFE2222, 0xCAFE2333, 0xCAFE2444};
+    uint32_t kceicv[] = {0xCAFE3111, 0xCAFE3222, 0xCAFE3333, 0xCAFE3444};
+    uint32_t kcp[]    = {0xCAFE4111, 0xCAFE4222, 0xCAFE4333, 0xCAFE4444};
+    uint32_t kce[]    = {0xCAFE5111, 0xCAFE5222, 0xCAFE5333, 0xCAFE5444};
+    uint32_t hbk[]    = {0xCAFE6111, 0xCAFE6222, 0xCAFE6333, 0xCAFE6444, 0xCAFE6555, 0xCAFE6666, 0xCAFE6777, 0xCAFE6888};
+
+    memset(otpValues, 0, otpSize);
+
+    Test_SetHbkInOtpBuff     (otpValues, (unsigned char*)hbk, TEST_OTP_HBK_256_TYPE);
+
+    Test_SetKeyOtpBuff   (otpValues, huk, TEST_HUK_KEY);
+
+    Test_SetKeyOtpBuff   (otpValues, kcp, TEST_KCP_KEY);
+
+    Test_SetKeyOtpBuff   (otpValues, kce, TEST_KCE_KEY);
+
+    Test_SetKeyOtpBuff   (otpValues, kceicv, TEST_KCEICV_KEY);
+
+    Test_SetKeyOtpBuff   (otpValues, kpicv, TEST_KPICV_KEY);
+
+    Test_SetLcsOtpBuff       (otpValues, lcsState);
+}
+
+
+uint32_t Test_BurnOtp(uint32_t  *otpBuf, uint32_t  nextLcs)
+{
+
+    CCError_t error = 0;
+    uint32_t i = 0;
+
+    /* Clean OTP */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        WRITE_OTP(i, 0);
+        Test_PalDelay(1000);
+    }
+
+    /* Perform SW reset to reach CM LCS */
+    Test_HalPerformPowerOnReset();
+    Test_PalDelay(1000);
+
+    /* Copy new OTP buffer */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        //                TEST_PRINTF("writing Otp [0x%X] 0x%X\n", i, otpBuf[i]);
+        WRITE_OTP(i, otpBuf[i]);
+        Test_PalDelay(1000);
+    }
+
+    /*  Perform SW reset after writing to OTP new values */
+    Test_HalPerformPowerOnReset();
+
+    /* verify LCS */
+    error = Test_HalCheckLcs(nextLcs);
+    if (error == 0) {
+        TEST_PRINTF(" OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
+    } else {
+        TEST_PRINTF_ERROR("Error: Failed to burn OTP!!\n");
+    }
+
+    return error;
+}
+
+/**
+ * This function burns otp image through "back door", performs reset, and check if system booted to required lcs
+ *
+ */
+uint32_t Test_GetKeySizeInWordsOtp(uint32_t keyType, uint32_t* keySizeInWords)
+{
+    // TBD HBK??
+    switch (keyType){
+        case TEST_HUK_KEY:
+            *keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
+            break;
+        case TEST_KCP_KEY:
+            *keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
+            break;
+        case TEST_KCE_KEY:
+            *keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
+            break;
+        case TEST_KPICV_KEY:
+            *keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
+            break;
+        case TEST_KCEICV_KEY:
+            *keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
+            break;
+        default:
+            *keySizeInWords = 0;
+            TEST_PRINTF_ERROR("ERROR: key type %d is not supported\n", keyType);
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+    return 0;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_otp.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_otp.h
new file mode 100644
index 0000000..615348e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_otp.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __TST_OTP_H__
+#define __TST_OTP_H__
+
+#include <stdint.h>
+
+
+/* TBD later should these definitions should be taken from shared cc_*.h */
+
+/* LCS */
+#define TESTS_LCS_CM        0x0
+#define TESTS_LCS_DM        0x1
+#define TESTS_LCS_SEC_DISABLED  0x3
+#define TESTS_LCS_SEC_ENABLED   0x5
+#define TESTS_LCS_RMA       0x7
+
+/* HW KEYS */
+#define TEST_HUK_KEY            0
+#define TEST_RTL_KEY            1
+#define TEST_KCP_KEY            2
+#define TEST_KCE_KEY            3
+#define TEST_KPICV_KEY          4
+#define TEST_KCEICV_KEY         5
+
+#define TEST_HBK0_KEY           16
+#define TEST_HBK1_KEY           17
+#define TEST_HBK_FULL_KEY       18
+
+typedef enum otpHbkTypes_t{
+    TEST_OTP_HBK0_TYPE = 1, //HBK0
+    TEST_OTP_HBK1_TYPE = 2, //HBK1
+    TEST_OTP_HBK_256_TYPE = 4, //HBK
+}OtpHbkTypes_t;
+
+
+/******************************/
+/*   function declaration     */
+/*****************************/
+
+/*
+unsigned int testBurnOtp(unsigned int  *otp, unsigned int  nextLcs);
+unsigned int testGetLcs(unsigned int  *lcs);
+unsigned int testGetOtpSize(unsigned int * size);
+unsigned int testCheckLcs(unsigned int  nextLcs);
+*/
+// hash key
+
+// tbd - move functionality to general functions
+/**
+ * This function sets HBK to otp buffer and update "NotInUse" and "ZerosBits"
+ *
+ */uint32_t Test_SetHbkInOtpBuff(
+         uint32_t *otp,         //!< [out] otp image
+         uint8_t *hbkBuff,      //!< [in]  hbk value
+         OtpHbkTypes_t type     //!< [in]  hbk type
+         );
+
+ /**
+  * This function pads with '0's the remaining SW version field after the first '0'
+  *
+  */uint32_t Test_SetSwVerInOtpBuff(
+         uint32_t *otp,         //!< [out] otp image
+         uint32_t offset,       //!< [in]  offset within the otp
+         uint32_t max_size      //!< [in]  max field size in words
+         );
+
+/**
+ * This function sets hw key itself to otp buffer and update "NotInUse" and "ZerosBits"
+ *
+ */
+uint32_t Test_SetKeyOtpBuff(
+        uint32_t *otpBuf,       //!< [out] otp image
+        uint32_t *keyBuff,      //!< [in]  key value
+        uint32_t keyType        //!< [in]  hw key type
+        );
+
+/**
+ * This function gets hw key and its size from otp buffer to user buffer
+ *
+ */
+uint32_t Test_GetKeyOtpBuff(
+        uint32_t *otpBuf,         //!< [in] otp image
+        uint32_t keyType,         //!< [in] key type
+        uint32_t *keySizeInWords, //!< [in] size in words
+        uint32_t *keyBuff         //!< [out] hw key value
+        );
+
+/**
+ * This function sets "notInUse" bit for appropriate hw key
+ *
+ */
+uint32_t Test_SetNotInUseOtpBuff(
+        uint32_t *otpBuf,       //!< [out] otp image
+        uint32_t keyType,       //!< [in]  hw key type
+        uint32_t value          //!< [in] "in use" bit value to set
+        );
+
+/**
+ * This function sets "ZeroBits" bits for appropriate hw key
+ *
+ */
+uint32_t Test_SetZeroBitsOtpBuff(
+        uint32_t *otpBuf,       //!< [out] otp image
+        uint32_t keyType,       //!< [in]  hw key type
+        uint32_t value          //!< [in]  value
+        );
+
+/**
+ * This function sets manufacture and oem flags accordingly to reuired LCS state
+ *
+ */
+uint32_t Test_SetLcsOtpBuff(
+        uint32_t *otpBuf,       //!< [out] otp image
+        uint32_t lcsState       //!< [in] lifecycle state
+        );
+
+/**
+ * This function sets entire OTP image with set of keys and lcs as parameter
+ *
+ */
+void Test_SetDefaultOtp(
+        uint32_t* otpValues,     //!< [out] otp image
+        uint32_t otpSize,        //!< [in] otp size
+        uint32_t lcsState        //!< [in] lcs
+        );
+
+/**
+ * This function burns otp image through "back door", performs reset, and check if system booted to required lcs
+ *
+ */
+uint32_t Test_GetKeySizeInWordsOtp(
+        uint32_t  keyType,         //!< [in] key Type
+        uint32_t* keySizeInWords   //!< [out] key Size in words
+        );
+
+/**
+ * This function burns otp image through "back door", performs reset, and check if system booted to required lcs
+ *
+ */
+uint32_t Test_BurnOtp(
+        uint32_t  *otp,         //!< [in] otp image
+        uint32_t  nextLcs       //!< [in] lcs that system should boot to
+        );
+
+
+
+#endif //__TST_OTP_H__
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_phys_map.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_phys_map.c
new file mode 100644
index 0000000..f3bb20f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_phys_map.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include "dx_reg_base_host.h"
+#include "test_log.h"
+#include "tests_phys_map.h"
+
+
+
+/////////////////////////////////////
+//         macro defines           //
+/////////////////////////////////////
+
+#define MAX_MAPPED_ALLOWED  5
+/*************************/
+/*   Global variables    */
+/*************************/
+int32_t       g_reeHwFd = 0;
+int32_t       processHwFd = 0;
+int32_t       userSpaceFd = 0;
+uint32_t       map_used = 0;
+
+unsigned long    g_testHwEnvBaseAddr = 0;
+unsigned long    g_testHwRegBaseAddr = 0;
+unsigned long    g_testHwReeRegBaseAddr = 0;
+unsigned long    g_testHwRndCtxBaseAddr = 0;
+unsigned long    g_testHwRndWorkBuffBaseAddr = 0;
+unsigned long    g_testHwUserStackBaseAddr = 0;
+unsigned long    g_testHwUserBaseAddr = 0;
+
+
+#define VALID_MAPPED_ADDR(addr) ((addr != 0) && (addr != 0xFFFFFFFF))
+
+ProcessMappingArea_t processMap;
+
+/******************************/
+/*   function definitions     */
+/*****************************/
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * caution: the user will get unexpected results using that API  with MEM_MAP_USR_DATA flag while using dx_cclib or sbrom testser
+ *      since all use the same user physical continues address space!!!
+ *
+ * @return void -
+ */
+unsigned int TestMapCCRegs(void)
+{
+    unsigned int rc;
+
+    rc = TestMapProcessAddrs(0, &processMap);
+    if (rc != 0){
+        TEST_PRINTF_ERROR("TestMapProcessAddrs Failed\n");
+        return 1;
+    }
+    g_testHwRndCtxBaseAddr = processMap.processHwRndCtxBaseAddr;
+    g_testHwRndWorkBuffBaseAddr = g_testHwRndCtxBaseAddr + PROCESS_RND_WORKBUFF_OFFSET;
+    g_testHwUserStackBaseAddr = g_testHwRndCtxBaseAddr + PROCESS_RND_CTX_SIZE;  // the address and size of teh stack must be page aligned
+    g_testHwUserBaseAddr = g_testHwUserStackBaseAddr + THREAD_STACK_SIZE;
+    TEST_PRINTF("g_testHwRndCtxBaseAddr = 0x%lx\n", (unsigned long)g_testHwRndCtxBaseAddr);
+    TEST_PRINTF("g_testHwRndWorkBuffBaseAddr = 0x%lx\n", (unsigned long)g_testHwRndWorkBuffBaseAddr);
+    TEST_PRINTF("g_testHwUserStackBaseAddr = 0x%lx\n", (unsigned long)g_testHwUserStackBaseAddr);
+    TEST_PRINTF("g_testHwUserBaseAddr = 0x%lx\n", (unsigned long)g_testHwUserBaseAddr);
+
+    return 0;
+
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+void TestUnmapCCRegs(void)
+{
+    TestMunMapProcessAddrs(&processMap);
+    g_testHwRndCtxBaseAddr = 0;
+    g_testHwRndWorkBuffBaseAddr = 0;
+    g_testHwUserStackBaseAddr = 0;
+    g_testHwUserBaseAddr = 0;
+}
+
+
+unsigned int mapUserSpace(uint32_t numOfThreads, ProcessMappingArea_t *processMap, uint32_t userSpaceSize)
+{
+    uint32_t i = 0;
+    uint32_t threadSize = 0;
+    unsigned long threadOffset = 0;
+#ifdef DX_PLAT_JUNO
+    char drvName[50] = "/dev/cc_linux_driver";
+#endif
+
+
+    if (processMap == NULL) {
+        TEST_PRINTF_ERROR("Invalid processMap, exiting...\n");
+        return 1;
+    }
+    if (userSpaceSize < PROCESS_RND_CTX_SIZE) {
+        TEST_PRINTF_ERROR("userSpaceSize Too small, exiting...\n");
+        return 1;
+    }
+    if (userSpaceSize > USER_WORKSPACE_MEM_SIZE) {
+        TEST_PRINTF_ERROR("userSpaceSize Too big, exiting...\n");
+        return 1;
+    }
+    if (numOfThreads > TEST_MAX_THREADS) {
+        TEST_PRINTF_ERROR("Too many threads, exiting...\n");
+        return 1;
+    }
+
+    //TEST_PRINTF("about to open\n");
+#ifdef DX_PLAT_JUNO
+    // need special driver that overwrites the Linux mmap.
+    // Linux threats this memory as device memory, therfore each access to that memory must be word ligned.
+    // and we need to have byte access.
+    userSpaceFd = open(drvName, O_RDWR|O_SYNC);
+    if (userSpaceFd < 0) {
+        TEST_PRINTF_ERROR("Failed openning %s\n", drvName);
+        goto end_error;
+    }
+#else
+    userSpaceFd = processHwFd;
+#endif
+    //TEST_PRINTF("about to mmap for WORKSPACE for RND_CTX\n");
+    processMap->processHwRndCtxBaseAddr = (unsigned long)mmap((unsigned int *)USER_WORKSPACE_MEM_BASE_ADDR,
+                           userSpaceSize,
+                           PROT_READ|PROT_WRITE|PROT_EXEC,
+                           MAP_SHARED|MAP_FIXED,   // must use MAP_FIXED to align with secure boot image table
+                           userSpaceFd,
+                           USER_WORKSPACE_MEM_BASE_ADDR);
+    if (!VALID_MAPPED_ADDR(processMap->processHwRndCtxBaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for processHwRndCtxBaseAddr\n");
+        goto end_error;
+    }
+    processMap->userSpaceSize = userSpaceSize;
+    processMap->processHwRndWorkBuffBaseAddr = processMap->processHwRndCtxBaseAddr + PROCESS_RND_WORKBUFF_OFFSET;
+    //TEST_PRINTF("processHwRndCtxBaseAddr = 0x%lx\n", (unsigned long)processMap->processHwRndCtxBaseAddr);
+    if (numOfThreads == 0) {
+        g_testHwRndCtxBaseAddr = processMap->processHwRndCtxBaseAddr;
+        g_testHwRndWorkBuffBaseAddr = g_testHwRndCtxBaseAddr + PROCESS_RND_WORKBUFF_OFFSET;
+        g_testHwUserStackBaseAddr = g_testHwRndCtxBaseAddr + PROCESS_RND_CTX_SIZE;
+        g_testHwUserBaseAddr = g_testHwUserStackBaseAddr + THREAD_STACK_SIZE;
+        return 0;
+    }
+    processMap->numOfThreads = numOfThreads;
+    threadOffset = processMap->processHwRndCtxBaseAddr + PROCESS_RND_CTX_SIZE;
+    threadSize = (userSpaceSize-PROCESS_RND_CTX_SIZE)/numOfThreads;
+    if (threadSize <= (THREAD_RND_CTX_SIZE+THREAD_STACK_SIZE)) {
+        TEST_PRINTF_ERROR("Error: threadSize too small\n");  // should not happen
+        goto end_error;
+    }
+    for (i = 0; i < numOfThreads; i++) {
+        processMap->threadMapAddr[i].threadHwRndCtxBaseAddr = threadOffset;
+        processMap->threadMapAddr[i].threadHwRndWorkBuffBaseAddr = processMap->threadMapAddr[i].threadHwRndCtxBaseAddr + PROCESS_RND_WORKBUFF_OFFSET;
+        processMap->threadMapAddr[i].threadHwUserStackBaseAddr = processMap->threadMapAddr[i].threadHwRndCtxBaseAddr + THREAD_RND_CTX_SIZE;
+        processMap->threadMapAddr[i].threadHwUserBaseAddr = processMap->threadMapAddr[i].threadHwUserStackBaseAddr + THREAD_STACK_SIZE;
+        threadOffset += threadSize;
+
+        TEST_PRINTF("threadHwRndCtxBaseAddr = 0x%lx\n", (unsigned long)processMap->threadMapAddr[i].threadHwRndCtxBaseAddr);
+        TEST_PRINTF("UserStackBaseAddr for thread #%d = 0x%lx\n", i, (unsigned long)processMap->threadMapAddr[i].threadHwUserStackBaseAddr);
+        TEST_PRINTF("UserBaseAddr for thread #%d = 0x%lx\n", i, (unsigned long)processMap->threadMapAddr[i].threadHwUserBaseAddr);
+    }
+    return 0;
+end_error:
+    if (processMap->processHwRndCtxBaseAddr != 0) {
+        munmap((void *)processMap->processHwRndCtxBaseAddr, processMap->userSpaceSize);
+    }
+#ifdef DX_PLAT_JUNO
+    close(userSpaceFd);
+#endif
+    return 1;
+}
+
+
+// workspace mapping supports 1 process and up to 16 threads:
+// process RND CTX - 16KB
+// for each thread:
+//      RND CTX - 16KB
+//      stack - 16KB
+//      user Data - (((256MB-16KB)/16)-32KB)
+unsigned int TestMapProcessAddrs(uint32_t numOfThreads, ProcessMappingArea_t *processMap)
+{
+    uint32_t rc = 0;
+
+    if (processMap == NULL) {
+        TEST_PRINTF_ERROR("Invalid processMap, exiting...\n");
+        return 1;
+    }
+    if (map_used > 0) {
+        if (map_used == MAX_MAPPED_ALLOWED) {
+            TEST_PRINTF_ERROR("too many mapping, exiting...\n");
+            return 1;
+        }
+        map_used++;
+        TEST_PRINTF_ERROR("process FD already opened, nothing to map\n");
+        return 0;
+    }
+
+    map_used++;
+    memset(processMap, 0, sizeof(ProcessMappingArea_t));
+
+    processHwFd = open("/dev/mem", O_RDWR|O_SYNC);
+    if(processHwFd < 0) {
+        TEST_PRINTF_ERROR("Error: Can not open /dev/mem\n");
+        goto end_with_error;
+    }
+    processMap->numOfThreads = 0;
+    processMap->processHwRegBaseAddr = (unsigned long)mmap(NULL, REG_MAP_AREA_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, processHwFd, DX_BASE_CC);
+    if (!VALID_MAPPED_ADDR(processMap->processHwRegBaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for processHwRegBaseAddr 0x%lx\n", (unsigned long)processMap->processHwRegBaseAddr);
+        goto end_with_error;
+    }
+    TEST_PRINTF("processHwRegBaseAddr = 0x%lx\n", (unsigned long)processMap->processHwRegBaseAddr);
+
+    processMap->processHwEnvBaseAddr = (unsigned long)mmap(NULL, REG_MAP_AREA_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, processHwFd, DX_BASE_ENV_REGS);
+    if (!VALID_MAPPED_ADDR(processMap->processHwEnvBaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for processHwEnvBaseAddr\n");
+        goto end_with_error;
+    }
+    TEST_PRINTF("processHwEnvBaseAddr = 0x%lx\n", (unsigned long)processMap->processHwEnvBaseAddr);
+
+    rc = mapUserSpace(numOfThreads, processMap, USER_WORKSPACE_MEM_SIZE);
+    if (rc != 0) {
+        TEST_PRINTF_ERROR("Error: failed for mapUserSpace %d\n", rc);
+        goto end_with_error;
+    }
+    g_testHwRegBaseAddr = processMap->processHwRegBaseAddr;
+    g_testHwEnvBaseAddr = processMap->processHwEnvBaseAddr;
+
+    return 0;
+end_with_error:
+    TestMunMapProcessAddrs(processMap);
+    return 1;
+
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+void TestMunMapProcessAddrs(ProcessMappingArea_t *processMap)
+{
+
+    if (processMap == NULL) {
+        TEST_PRINTF_ERROR("processMap == NULL\n");
+        return;
+    }
+    if (map_used > 0) {
+        map_used--;
+    } else {
+        TEST_PRINTF_ERROR("nothing is mapped. returning...\n");
+        return;
+    }
+    if (map_used > 0) {
+        TEST_PRINTF_ERROR("waiting for others to Munmap before closing...\n");
+        return;
+    }
+    if (processMap->processHwRegBaseAddr != 0) {
+        munmap((void *)processMap->processHwRegBaseAddr, REG_MAP_AREA_LEN);
+    }
+    if (processMap->processHwEnvBaseAddr != 0) {
+        munmap((void *)processMap->processHwEnvBaseAddr, REG_MAP_AREA_LEN);
+    }
+    if (processMap->processHwRndCtxBaseAddr != 0) {
+        munmap((void *)processMap->processHwRndCtxBaseAddr, processMap->userSpaceSize);
+    }
+#ifdef DX_PLAT_JUNO
+    close(userSpaceFd);
+#endif
+    close(processHwFd);
+    memset((uint8_t *)processMap, 0, sizeof(ProcessMappingArea_t));
+    g_testHwRegBaseAddr = 0;
+    g_testHwEnvBaseAddr = 0;
+    userSpaceFd = 0;
+    processHwFd = 0;
+}
+
+
+// map the REE CC HW base, to write to some registers to enable TEE works
+unsigned int TestMapRee(void)
+{
+    //TEST_PRINTF("about to open\n");
+    g_reeHwFd = open("/dev/mem", O_RDWR|O_SYNC);
+    if(g_reeHwFd < 0) {
+        TEST_PRINTF_ERROR("Error: Can not open /dev/mem\n");
+        goto end_error;
+    }
+    TEST_PRINTF("about to mmap for DX_REE_BASE_CC 0x%lx", (unsigned long)DX_REE_BASE_CC);
+    g_testHwReeRegBaseAddr = (unsigned long)mmap(NULL, REG_MAP_AREA_LEN, PROT_READ|PROT_WRITE, MAP_SHARED, g_reeHwFd, DX_REE_BASE_CC);
+    if (!VALID_MAPPED_ADDR(g_testHwReeRegBaseAddr)) {
+        TEST_PRINTF_ERROR("Error: mmap failed for g_testHwReeRegBaseAddr\n");
+        goto end_error;
+    }
+    TEST_PRINTF("g_testHwReeRegBaseAddr = 0x%lx\n", (unsigned long)g_testHwReeRegBaseAddr);
+    return 0;
+
+end_error:
+    TestMunMapRee();
+
+    return 1;
+
+}
+
+
+/*
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+void TestMunMapRee(void)
+{
+
+
+    if (g_testHwReeRegBaseAddr != 0) {
+        munmap((void *)g_testHwReeRegBaseAddr, REG_MAP_AREA_LEN);
+    }
+    g_testHwReeRegBaseAddr = 0;
+
+    if (g_reeHwFd > 0) {
+        close(g_reeHwFd);
+    }
+    g_reeHwFd = 0;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_phys_map.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_phys_map.h
new file mode 100644
index 0000000..abebb71
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tests_phys_map.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __TST_PHYS_MEM_H__
+#define __TST_PHYS_MEM_H__
+
+#include <stdint.h>
+
+#ifdef DX_PLAT_ZYNQ7000
+    #define USER_WORKSPACE_MEM_BASE_ADDR    0x30000000
+    #define DX_REE_BASE_CC          0x80000000
+#elif defined DX_PLAT_JUNO
+    #define USER_WORKSPACE_MEM_BASE_ADDR    0x8B0000000
+    #define DX_REE_BASE_CC          0x60010000
+#endif
+
+#define USER_WORKSPACE_MEM_SIZE         0x10000000
+#define BOOT_FREE_MEM_LEN           0x50000
+
+// workspace mapping supports 1 process and up to 16 threads:
+// process RND CTX - 16KB
+// for each thread:
+//      RND CTX - 16KB
+//      stack - 16KB
+//      user Data - (((256MB-16KB)/16)-32KB)
+#define REG_MAP_AREA_LEN        0x20000
+#define TEST_MAX_PROCESSES      1
+#define TEST_MAX_THREADS        16
+#define PROCESS_RND_CTX_OFFSET      0
+   #define PROCESS_RND_WORKBUFF_OFFSET  (10*1024)
+   #define PROCESS_RND_WORKBUFF_SIZE    (6*1024) // rnd working buff needs 2KB, we take 6KB within total size of context
+#define PROCESS_RND_CTX_SIZE        (16*1024) // rnd ctx needs 7KB, we take 16KB
+
+#define TOTAL_USR_THREAD_MAPPING_SIZE   ((USER_WORKSPACE_MEM_SIZE-PROCESS_RND_CTX_SIZE)/TEST_MAX_THREADS)  // each thread gets workspace size [(256MB-16KB)/16] = [16MB-1KB]
+#define THREADS_START_OFFSET        (PROCESS_RND_CTX_OFFSET+PROCESS_RND_CTX_SIZE)
+#define THREAD_RND_CTX_OFFSET       0
+#define THREAD_RND_CTX_SIZE     PROCESS_RND_CTX_SIZE
+#define THREAD_STACK_OFFSET     (THREAD_RND_CTX_OFFSET+THREAD_RND_CTX_SIZE)
+#define THREAD_STACK_SIZE       (128*1024) // stack has 128KB for 64bit CPU
+#define USER_DATA_OFFSET        (THREAD_STACK_OFFSET+THREAD_STACK_SIZE)
+#define USER_DATA_SIZE          (TOTAL_USR_THREAD_MAPPING_SIZE-THREAD_RND_CTX_SIZE-THREAD_STACK_SIZE) // {[16MB-1KB]-32KB} = 16MB-33KB
+// devide by 6 for: dataIn, dataOut, expectedData, ccm-aData, hmac-keySize, other-key, iv, tag...
+#define USER_DATA_INPUT_MAX_SIZE    (USER_DATA_SIZE/6)  // {16MB-33KB}/6 =
+
+typedef enum memMapTypes_t {
+        MEM_MAP_REGS = 1,
+        MEM_MAP_ENV = 2,
+        MEM_MAP_USR_DATA = 4,
+        MEM_MAP_USR_STACK = 8,
+        MEM_MAP_RND_CTX = 0x10
+
+}MemMapTypes_t;
+
+
+typedef struct {
+    unsigned long      threadHwRndCtxBaseAddr;
+    unsigned long      threadHwRndWorkBuffBaseAddr;
+    unsigned long      threadHwUserStackBaseAddr;
+    unsigned long      threadHwUserBaseAddr;
+}ThreadMappingArea_t;
+
+typedef struct {
+    unsigned long       processHwRegBaseAddr;
+    unsigned long       processHwEnvBaseAddr;
+    unsigned long       processHwRndCtxBaseAddr;
+    unsigned long       processHwRndWorkBuffBaseAddr;
+    uint32_t            userSpaceSize;
+    uint32_t            numOfThreads;
+    ThreadMappingArea_t     threadMapAddr[TEST_MAX_THREADS];
+}ProcessMappingArea_t;
+
+
+/******************************/
+/*   function declaration     */
+/*****************************/
+
+unsigned int TestMapCCRegs(void);
+void TestUnmapCCRegs(void);
+
+unsigned int TestMapRee(void);
+void TestMunMapRee(void);
+
+unsigned int TestMapProcessAddrs(uint32_t numOfThreads, ProcessMappingArea_t *processMap);
+void TestMunMapProcessAddrs(ProcessMappingArea_t *processMap);
+
+extern unsigned long     g_testHwEnvBaseAddr;
+extern unsigned long     g_testHwRegBaseAddr;
+extern unsigned long     g_testHwReeRegBaseAddr;
+extern unsigned long     g_testHwRndCtxBaseAddr;
+extern unsigned long     g_testHwRndWorkBuffBaseAddr;
+extern unsigned long     g_testHwUserStackBaseAddr;
+extern unsigned long     g_testHwUserBaseAddr;
+
+#endif //__TST_PHYS_MEM_H__
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common.c
new file mode 100644
index 0000000..f42adbc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include "tst_common.h"
+#include "test_log.h"
+#include "tests_phys_map.h"
+#include "tst_common.h"
+
+#ifdef CC_IOT
+#include "tests_hw_access_iot.h"
+#else
+#include "tests_hw_access.h"
+#endif
+
+#ifdef CC_SUPPORT_FIPS
+#define CC_REE_BASE  0x80000000 // same as shared/hw/ree_include/dx_reg_base_host.h DX_BASE_CC
+#define CC_REE_AREA_LEN  0x100000
+#define DX_HOST_GPR0_REG_OFFSET     0xA70UL   // taken from ree_include/dx_host.h
+
+int testSetReeFipsError(uint32_t  reeError, CCFipsState_t expfipsState)
+{
+    uint32_t rc;
+    CCFipsState_t fipsState;
+    uint32_t maxRetries = 20;
+
+    rc = TestMapRee();
+    if (rc != 0) {
+        return 1;
+    }
+    WRITE_REE_REG(DX_HOST_GPR0_REG_OFFSET, (unsigned int)(reeError));
+
+    TestMunMapRee();
+
+    TEST_PRINTF("waiting for fips stat to be %d\n", expfipsState);
+    do {
+        rc = CC_FipsStateGet(&fipsState, NULL);
+        if (rc != 0) {
+            return 1;
+        }
+        usleep(100); // wait 100 milisecond
+        TEST_PRINTF("fips stat is %d\n", fipsState);
+    } while ((fipsState != expfipsState) && (maxRetries-- > 0));
+    if ((maxRetries == 0) && (fipsState != expfipsState)) {
+        return 1;
+    }
+    TEST_PRINTF("doen OK\n");
+    return 0;
+}
+#endif
+
+/**
+ * The function copies src buffer to dst with reversed bytes order.
+ *
+ * Note: Overlapping is not allowed, besides reversing of the buffer in place.
+ *
+ * @param dst
+ * @param src
+ * @param sizeInBytes
+ */
+int TST_MemCpyReversed( void* dst_ptr, void* src_ptr, unsigned int sizeInBytes)
+{
+    unsigned int i;
+    unsigned char *dst, *src;
+
+    src = (unsigned char *)src_ptr;
+    dst = (unsigned char *)dst_ptr;
+
+    if (((dst < src) && (dst+sizeInBytes > src)) ||
+        ((src < dst) && (src+sizeInBytes > dst)))
+        return -1;
+
+    if (dst == src) {
+        unsigned char tmp;
+        for (i=0; i<sizeInBytes/2; i++) {
+            tmp = dst[sizeInBytes-i-1];
+            dst[sizeInBytes-i-1] = src[i];
+            src[i] = tmp;
+        }
+    } else {
+        for (i=0; i<sizeInBytes; i++) {
+            dst[i] = src[sizeInBytes-i-1];
+        }
+    }
+
+    return 0;
+}
+
+
+
+#ifdef CC_IOT
+
+ void* Test_LibInit(void *params ){
+    uint32_t rc;
+    uint8_t             *pRc =NULL;
+    LibInitArgs* threadArgs = (LibInitArgs*)params;
+
+    pRc = (uint8_t *)malloc(sizeof(uint8_t));
+    rc = CC_LibInit(threadArgs->rndContext_ptr, threadArgs->rndWorkBuff_ptr);
+    *pRc =rc;
+    return((void *)pRc);
+
+}
+int tests_CC_libInit(CCRndContext_t* rndContext_ptr, CCRndWorkBuff_t * rndWorkBuff_ptr, unsigned long* stackAddress){
+    int rc = 0;
+    void *res;
+    pthread_t threadId;
+    pthread_attr_t threadAttr;
+    LibInitArgs threadArgs;
+    threadArgs.rndContext_ptr=rndContext_ptr;
+    threadArgs.rndWorkBuff_ptr=rndWorkBuff_ptr;
+    rc = pthread_attr_init(&threadAttr);
+
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = pthread_attr_setstack(&threadAttr,  stackAddress, THREAD_STACK_SIZE);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = pthread_create(&threadId, &threadAttr, Test_LibInit, (void *)&threadArgs);
+
+    rc = pthread_join(threadId, (void**)&res);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = pthread_attr_destroy(&threadAttr);
+
+    return rc;
+}
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common.h
new file mode 100644
index 0000000..19c8302
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ /*
+  Common  functions prototypes and definitions used in CRYS tests
+  */
+
+#ifndef __TST_COMMON_H__
+#define __TST_COMMON_H__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#if (!defined CC_SW) && (!defined CC_IOT)
+#include "cc_fips.h"
+#endif
+#include "cc_lib.h"
+
+/**
+ * The function copies src buffer to dst with reversed bytes order.
+ *
+ * Note: Overlapping is not allowed, besides reversing of the buffer in place.
+ *
+ * @param dst
+ * @param src
+ * @param sizeInBytes
+ */
+int TST_MemCpyReversed( void* dst, void* src, unsigned int sizeInBytes);
+
+
+#ifndef CC_SW
+#ifdef CC_IOT
+#define TST_CC_LIB_INIT(rc, rndContext_ptr, rndWorkBuff_ptr)       rc = CC_LibInit(rndContext_ptr, rndWorkBuff_ptr)
+int tests_CC_libInit(CCRndContext_t* rndContext_ptr, CCRndWorkBuff_t * rndWorkBuff_ptr, unsigned long* stackAddress);
+void* Test_LibInit(void *params );
+
+typedef struct LibInitArgs {
+    CCRndContext_t * rndContext_ptr;
+    CCRndWorkBuff_t * rndWorkBuff_ptr;
+    //RC - should also be a void* for entropy context (currently saved inside rndContext)
+} LibInitArgs;
+
+#else
+CCFipsKatContext_t  fipsCtx;
+#ifdef CC_SUPPORT_FIPS
+int testSetReeFipsError(uint32_t  reeError, CCFipsState_t expfipsState);
+// set REE error value to be REE ok, same value as CC_FIPS_SYNC_REE_STATUS|CC_FIPS_SYNC_MODULE_OK
+#define TST_CC_LIB_INIT(rc, rndContext_ptr, rndWorkBuff_ptr)       {\
+    rc = CC_LibInit(rndContext_ptr, rndWorkBuff_ptr, false, &fipsCtx);\
+    if (rc == 0) {\
+        rc = testSetReeFipsError((0x4|0x0), CC_FIPS_STATE_NOT_SUPPORTED);\
+    }\
+}
+#else
+#define TST_CC_LIB_INIT(rc, rndContext_ptr, rndWorkBuff_ptr)       {\
+    rc = CC_LibInit(rndContext_ptr, rndWorkBuff_ptr, false, &fipsCtx);\
+}
+#endif
+#endif
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common_init.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common_init.c
new file mode 100644
index 0000000..44a3925
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common_init.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "tst_common.h"
+#include "tst_common_init.h"
+#include "test_log.h"
+
+int tests_CC_libInit_wrap(CCRndContext_t* rndContext_ptr, CCRndWorkBuff_t * rndWorkBuff_ptr){
+    uint32_t rc = 0;
+    int threadRc;
+    void *threadRet;
+    ThreadHandle threadHandle;
+    LibInitArgs params;
+    params.rndContext_ptr=rndContext_ptr;
+    params.rndWorkBuff_ptr=rndWorkBuff_ptr;
+
+    threadHandle = Test_PalThreadCreate(THREAD_STACK_SIZE, (void *)Test_LibInit, &params, NULL, 0, true);
+    if (threadHandle == NULL) {
+        TEST_PRINTF_ERROR("Test_PalThreadCreate failed\n");
+        return -1;
+    }
+
+    /* Wait till thread is complete before main continues */
+    threadRc = Test_PalThreadJoin(threadHandle, &threadRet);
+    if (threadRc != 0) {
+        TEST_PRINTF_ERROR("Test_PalThreadJoin failed\n");
+        return -1;
+    }
+
+    rc =*((uint32_t *)*&threadRet);
+
+    threadRc = Test_PalThreadDestroy(threadHandle);
+    if (threadRc != 0) {
+        TEST_PRINTF_ERROR("pthread_attr_destroy failed\n");
+    }
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common_init.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common_init.h
new file mode 100644
index 0000000..f67b1f3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_common_init.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __TST_COMMON_INIT_H__
+#define __TST_COMMON_INIT_H__
+
+#include "test_pal_thread.h"
+#include "board_configs.h"
+
+
+int tests_CC_libInit_wrap(CCRndContext_t* rndContext_ptr, CCRndWorkBuff_t * rndWorkBuff_ptr);
+
+
+#endif /* __TST_COMMON_INIT_H__ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_perf.c b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_perf.c
new file mode 100644
index 0000000..5c9e221
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_perf.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>  //memset()
+#include <limits.h>
+#include <unistd.h>
+#include "tst_perf.h"
+#include "cc_pal_perf.h"
+
+const char * tstPerfOp2Str[TST_PERF_OP_NUM] = {
+    /* TST_PERF_OP_NULL,          */   "null",
+    /* TST_PERF_OP_RSA_ENC_PRIM,  */   "RSA_ENC_PRIM",
+    /* TST_PERF_OP_RSA_ENC_1_5 ,  */   "RSA_ENC_1_5 ",
+    /* TST_PERF_OP_RSA_ENC_2_1 ,  */   "RSA_ENC_2_1 ",
+    /* TST_PERF_OP_RSA_DEC_PRIM,  */   "RSA_DEC_PRIM",
+    /* TST_PERF_OP_RSA_DEC_1_5 ,  */   "RSA_DEC_1_5 ",
+    /* TST_PERF_OP_RSA_DEC_2_1 ,  */   "RSA_DEC_2_1 ",
+    /* TST_PERF_OP_RSA_SIGN_1_5,  */   "RSA_SIGN_1_5",
+    /* TST_PERF_OP_RSA_SIGN_2_1,  */   "RSA_SIGN_2_1",
+    /* TST_PERF_OP_RSA_VER_1_5 ,  */   "RSA_VER_1_5 ",
+    /* TST_PERF_OP_RSA_VER_2_1 ,  */   "RSA_VER_2_1 ",
+    /* TST_PERF_OP_ECC_SIGN ,  */      "ECC_SIGN ",
+    /* TST_PERF_OP_ECC_VER ,  */       "ECC_VER ",
+};
+
+/* Performance statistics for init/process/finalize/integrated */
+PerfStats_t perfStats[TST_PERF_OP_NUM];
+
+
+/*!
+ * Accumulate given cycles or latency (in nSec) to the statistics
+ *
+ * \param val cycles/time in nsec
+ * \param opType Operation type
+ */
+void StatsValAccum(CCPalPerfData_t val,  TST_PerfOpType_t opType)
+{
+    perfStats[opType].opCount++;
+    perfStats[opType].totalVal += val;
+    if ((val < perfStats[opType].minVal) ||
+        (1 == perfStats[opType].opCount)) {
+        perfStats[opType].minVal = val;
+    }
+    if (val > perfStats[opType].maxVal) {
+        perfStats[opType].maxVal = val;
+    }
+
+}
+
+
+/*!
+ * Initialize statistics infrastructure
+ */
+void TST_PerfStatsCycleInit(void)
+{
+    memset(&perfStats, 0, sizeof(perfStats));
+}
+
+/*!
+ * Initialize statistics infrastructure
+ */
+void TST_PerfStatsCycleFin(void)
+{
+    memset(&perfStats, 0, sizeof(perfStats));
+}
+
+/*!
+ * Start code segment cycle measurement
+ *
+ * \param cycleCount Container for current time sample
+ */
+CCPalPerfData_t TST_PerfStatsCycleStart(void)
+{
+    CCPalPerfData_t tmp = 0;
+    CC_PAL_PERF_OPEN_NEW_ENTRY(tmp, 0); // type has no meaning
+    return tmp;
+}
+
+/*!
+ * End code segment cycle measurement and append statistics to given operation
+ *
+ * \param startCycles Data initialize with TST_PerfStatsCycleStart
+ * \param opType test operation type
+ */
+void TST_PerfStatsCycleEnd(CCPalPerfData_t startCycles, TST_PerfOpType_t opType)
+{
+    CCPalPerfData_t curCycles = 0;
+    CCPalPerfData_t totalVal = 0;
+
+    if ((opType >= TST_PERF_OP_NUM) ||
+        (0 == startCycles)) {
+        printf("%s Invalid opType=%d or startCycles %lld\n", __FUNCTION__, opType, startCycles);
+        return;
+    }
+    CC_PAL_PERF_OPEN_NEW_ENTRY(curCycles, opType); // type has no meaning
+    if (0 == curCycles) {
+        printf("Test operations stats:\n");
+        return;
+    }
+    if (curCycles < startCycles) {
+        totalVal = (UINT64_MAX-startCycles)+curCycles;
+    } else {
+        totalVal = curCycles - startCycles;
+    }
+    StatsValAccum(totalVal,  opType);
+}
+
+/*!
+ * Output to stdout the current statistics
+ */
+void TST_PerfStatsCycleReport(void)
+{
+    int i;
+    CCPalPerfData_t avgCycles;
+
+    CC_PAL_PERF_DUMP();
+    printf("Test operations stats:\n");
+    for (i = 1; i < TST_PERF_OP_NUM; i++) {
+        if (perfStats[i].opCount != 0) {
+            avgCycles = perfStats[i].totalVal / perfStats[i].opCount;
+        } else {
+            continue;
+        }
+        printf("%s: count=%d  cycles=[min,avg,max,sum] %lld %lld %lld %lld \n",
+               tstPerfOp2Str[i], perfStats[i].opCount, perfStats[i].minVal, avgCycles, perfStats[i].maxVal, perfStats[i].totalVal );
+    }
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_perf.h b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_perf.h
new file mode 100644
index 0000000..531eda8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/common/tst_perf.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ /*
+  CRYS tester performance statistics functions
+  */
+
+#ifndef __TST_PERF_H__
+#define __TST_PERF_H__
+
+#include <stdint.h>
+
+typedef enum {
+    TST_PERF_OP_NULL,
+    TST_PERF_OP_RSA_ENC_PRIM,
+    TST_PERF_OP_RSA_ENC_1_5,
+    TST_PERF_OP_RSA_ENC_2_1,
+    TST_PERF_OP_RSA_DEC_PRIM,
+    TST_PERF_OP_RSA_DEC_1_5,
+    TST_PERF_OP_RSA_DEC_2_1,
+    TST_PERF_OP_RSA_SIGN_1_5,
+    TST_PERF_OP_RSA_SIGN_2_1,
+    TST_PERF_OP_RSA_VER_1_5,
+    TST_PERF_OP_RSA_VER_2_1,
+    TST_PERF_OP_ECC_SIGN,
+    TST_PERF_OP_ECC_VER,
+    TST_PERF_OP_NUM
+} TST_PerfOpType_t;
+
+
+typedef struct {
+    uint32_t opCount; /* Number of operations measured */
+    uint64_t totalVal; /* Accumulated cycles/uSec */
+    uint64_t maxVal; /* Maximum cycles/usec */
+    uint64_t minVal; /* Minimum cycles/usec */
+} PerfStats_t;
+
+#ifdef TST_PERF
+/* Performance data */
+#define TST_PERF_INIT  TST_PerfStatsCycleInit
+#define TST_PERF_START(perfData)  perfData = TST_PerfStatsCycleStart()
+#define TST_PERF_END(perfData, op) TST_PerfStatsCycleEnd(perfData, op)
+#define TST_PERF_REPORT TST_PerfStatsCycleReport
+#define TST_PERF_FIN  TST_PerfStatsCycleFin
+void TST_PerfStatsCycleInit(void);
+uint64_t TST_PerfStatsCycleStart(void);
+void TST_PerfStatsCycleEnd(uint64_t startCycles, TST_PerfOpType_t opType);
+void TST_PerfStatsCycleReport(void);
+void TST_PerfStatsCycleFin(void);
+#else
+#define TST_PERF_INIT()
+#define TST_PERF_START(perfData) (perfData = 0)
+#define TST_PERF_END(perfData, op)
+#define TST_PERF_REPORT()
+#define TST_PERF_FIN()
+#endif
+
+
+
+#endif /*__TST_PERF_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/Makefile b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/Makefile
new file mode 100755
index 0000000..15de532
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/Makefile
@@ -0,0 +1,98 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for integration tests
+HOST_PROJ_ROOT ?= $(shell pwd)/../../..
+
+TEST_AL_PATH = ../TestAL
+TEST_AL_GIT =
+TEST_AL_GIT_TAG = TAG_TESTAL_VER_3.02
+
+
+include $(HOST_PROJ_ROOT)/Makefile.defs
+$(info PROJ_PRD $(PROJ_PRD))
+copy_integ_cfg := $(shell test -f $(HOST_PROJ_ROOT)/src/tests/integration_$(PROJ_PRD)/proj_integration_tests.cfg || cp $(HOST_PROJ_ROOT)/proj.cfg  $(HOST_PROJ_ROOT)/src/tests/integration_$(PROJ_PRD)/proj_integration_tests.cfg)
+include $(HOST_PROJ_ROOT)/src/tests/integration_$(PROJ_PRD)/proj_integration_tests.cfg
+
+ifeq ($(TEE_OS), freertos)
+include  $(HOST_SRCDIR)/../Makefile.freertos
+endif
+export
+
+INTEGRATION_TESTS = $(INTEG_TESTS)
+RELEASE_INTEGRATION_TESTS = $(foreach module,$(INTEGRATION_TESTS),release_$(module))
+CLEAN_INTEGRATION_TESTS = $(foreach module,$(INTEGRATION_TESTS),clean_$(module))
+CLEAN_INTRMD_TARGETS = $(foreach module,$(INTEGRATION_TESTS),clean_intermediate_$(module))
+
+RELEASE_INTEGRATION_SCRIPTS = $(foreach script,$(TESTER_INTEGRATION_SCRIPTS),release_$(script))
+CLEAN_INTEGRATION_SCRIPTS = $(foreach script,$(TESTER_INTEGRATION_SCRIPTS),clean_$(script))
+
+#|--------------------------TestAL_3.02---------------------------------|
+#|ConfNum|    OS    |    CPU     |      Toolchain      | Device | Board |
+#|----------------------------------------------------------------------|
+#|   1   |  linux   | cortex-a9  |      arm-xilinx     | target | Zynq  |
+#|   2   |          |            |     Deprecated      |        |       |
+#|   3   |  linux   |    x86     |        native       |  host  |       |
+#|   4   | freertos | cortex-m3  |    arm-compiler-5   | target | MPS2+ |
+#|   5   |          |            |     Deprecated      |        |       |
+#|   6   |  no_os   | cortex-m3  |    arm-compiler-5   | target | MPS2+ |
+#|   7   | freertos | cortex-m33 |     arm-none-eabi   | target | MPS2+ |
+#|   8   |  linux   | cortex-a9  |      arm-br-7.3     | target | Zynq  |
+#|   9   | freertos | cortex-m3  |     arm-none-eabi   | target | MPS2+ |
+#|   10  |  linux   |  a72 a53   |    aarch64-br-7.3   | target | Juno  |
+#|   11  | freertos | cortex-m33 |    arm-compiler-6   | target | MPS2+ |
+#|   12  | freertos | cortex-m3  |    arm-compiler-6   | target | MPS2+ |
+#|----------------------------------------------------------------------|
+# for sbrom use run_all_sbrom_integration_tests.sh otherwise use run_all_integration_tests.sh
+TEST_AL_CONFIG_NUM =$(if $(findstring cortex-a9,${ARM_CPU} ), 1,)
+
+ifeq ($(CROSS_COMPILE), armcc)
+TEST_AL_CONFIG_NUM = 4
+else ifeq ($(CROSS_COMPILE), armclang)
+TEST_AL_CONFIG_NUM =$(if $(findstring cortex-m33,${ARM_CPU} ), 11 , 12)
+else ifeq ($(CROSS_COMPILE), arm-none-eabi-)
+TEST_AL_CONFIG_NUM =$(if $(findstring cortex-m33,${ARM_CPU} ), 7 , 9)
+endif
+
+default: build_test_al $(RELEASE_INTEGRATION_TESTS) $(RELEASE_INTEGRATION_SCRIPTS)
+#generate_run_all_integration_tests
+
+clean: $(CLEAN_INTEGRATION_TESTS) $(CLEAN_INTEGRATION_SCRIPTS)
+
+clean_intermediate: $(CLEAN_INTRMD_TARGETS)
+
+
+# Generic release rules recipes
+
+build_test_al: clean_test_al
+	if [ ! -d $(TEST_AL_PATH) ]; then git clone  $(TEST_AL_GIT) $(TEST_AL_PATH); cd $(TEST_AL_PATH) && git checkout $(TEST_AL_GIT_TAG) && ./TestAL-Lite/testal_lite.sh; fi
+	echo [RUN] "./build_config.sh $(TEST_AL_CONFIG_NUM)"
+	cd $(TEST_AL_PATH) && ./build_config.sh $(TEST_AL_CONFIG_NUM)
+	mv $(TEST_AL_PATH)/libHAL* $(HOST_PROJ_ROOT)/lib/libtests_hal_lite.a
+	mv $(TEST_AL_PATH)/libPAL* $(HOST_PROJ_ROOT)/lib/libtests_pal_lite.a
+	@$(if $(subst freertos,,$(TEE_OS)),, $(ECHO) [CP] $(HOST_PROJ_ROOT)/lib/libtests*.a --\> $(KERNEL_DIR)/lib)
+	@$(if $(subst freertos,,$(TEE_OS)),, $(CP) $(HOST_PROJ_ROOT)/lib/libtests*.a $(KERNEL_DIR)/lib)
+
+$(RELEASE_INTEGRATION_TESTS): release_%:
+	@$(ECHO) [REL] $*
+	@$(MAKE) -s -C $*
+
+$(CLEAN_INTEGRATION_TESTS): clean_%:
+	@$(ECHO) [CLN] $*
+	@$(MAKE) -s -C $* clean
+
+$(CLEAN_INTRMD_TARGETS): clean_intermediate_%:
+	@$(ECHO) [CLN-INT] $*
+	@$(MAKE) -s -C $* clean_intermediate
+
+clean_test_al:
+	@$(ECHO) [CLN-TEST-AL]
+	@$(RM) ../TestAL/*.a
+
+.PHONY: default build_test_al clean_test_al clean clean_intermediate $(RELEASE_INTEGRATION_TESTS) $(CLEAN_INTEGRATION_TESTS) $(CLEAN_INTRMD_TARGETS) $(RELEASE_INTEGRATION_SCRIPTS) $(CLEAN_INTEGRATION_SCRIPTS) generate_run_all_integration_tests
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/Makefile b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/Makefile
new file mode 100644
index 0000000..265c905
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/Makefile
@@ -0,0 +1,27 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../../../..
+
+ifneq (,$(findstring gnu,$(CROSS_COMPILE)))
+TEE_OS = linux
+else
+TEE_OS = freertos
+endif
+
+ifneq ($(wildcard $(HOST_PROJ_ROOT)/../configs/proj-cc312-sbrom_integration_tests.cfg),)
+$(info Compiling for Internal ARM use)
+ARM_INTERNAL=1
+else
+ARM_INTERNAL=0
+endif
+
+include $(HOST_PROJ_ROOT)/Makefile.defs
+
+include cmpu_integration_test.mk
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_helper.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_helper.h
new file mode 100644
index 0000000..3013aef
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_helper.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CMPU_INTEGRATION_HELPER_H_
+#define _CMPU_INTEGRATION_HELPER_H_
+
+#include "test_pal_mem.h"
+#include "test_pal_mem_s.h"
+
+#ifdef ARCH_V8M
+#define CMPUIT_TEST_PAL_ALLOC    Test_PalDMAContigBufferAlloc_s
+#define CMPUIT_TEST_PAL_FREE     Test_PalDMAContigBufferFree_s
+#else
+#define CMPUIT_TEST_PAL_ALLOC    Test_PalDMAContigBufferAlloc
+#define CMPUIT_TEST_PAL_FREE     Test_PalDMAContigBufferFree
+#endif
+
+#define FREE_IF_NOT_NULL(_buff)    \
+                do { \
+                    if (_buff != NULL) {     \
+                        CMPUIT_TEST_PAL_FREE(_buff);    \
+                        _buff = NULL; \
+                    } \
+                }while(0)
+
+#define ALLOC32(_pBuff, _pBuffAligned, _wantedSize) \
+                do { \
+                    uint32_t address = 0; \
+                    uint32_t remainder = 0; \
+                    _pBuff = (void*)CMPUIT_TEST_PAL_ALLOC(_wantedSize); \
+                    address = (uint32_t)_pBuff; \
+                    remainder = (sizeof(uint32_t) - (address % sizeof(uint32_t))) % sizeof(uint32_t); \
+                    if (_pBuff == NULL) goto bail; \
+                    _pBuffAligned = (void*)(address + remainder); \
+                }while(0)
+/**
+ *
+ * Assert Macros
+ *
+ */
+#define CMPUIT_ASSERT_WITH_RESULT(_c, _exp)                                            \
+                do {                                                                  \
+                    int _ret = 0;                                                     \
+                    if( ( _ret = (int)_c) != _exp )                                   \
+                    {                                                                 \
+                        CMPUIT_PRINT_ERROR( "failed with rc 0x%08x\n", _ret );         \
+                        rc = CMPUIT_ERROR__FAIL;                                       \
+                        goto bail;                                                    \
+                    }                                                                 \
+                } while(0)
+
+#define CMPUIT_ASSERT(_c)                                                              \
+                do {                                                                  \
+                    if( !(_c))                                                        \
+                    {                                                                 \
+                        CMPUIT_PRINT_ERROR( "failed\n" );                              \
+                        rc = CMPUIT_ERROR__FAIL;                                       \
+                        goto bail;                                                    \
+                    }                                                                 \
+                }                                                                     \
+                while(0)
+
+#define CMPUIT_API(_c)                                                                 \
+                do {                                                                  \
+                    CMPUIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _c;                                                               \
+                } while(0)
+
+#define CMPUIT_API_ASSIGNMENT(_res, _c)                                                \
+                do {                                                                  \
+                    CMPUIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _res = _c;                                                        \
+                } while(0)
+
+#define CMPUIT_ASSERT_API(_c)                                                          \
+                do {                                                                  \
+                    CMPUIT_ASSERT(_c);                                                 \
+                } while(0)
+
+/************************************************************
+ *
+ * type decelerations
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * externs
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * function prototypes
+ *
+ ************************************************************/
+
+#endif //_CMPU_INTEGRATION_HELPER_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.c
new file mode 100644
index 0000000..e4e47ad
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.c
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* system includes */
+#include <stdlib.h>
+#include <string.h>
+
+
+/* cc_productionLib */
+#include "cc_cmpu.h"
+#include "cc_pal_types.h"
+
+/* shared */
+#include "dx_reg_base_host.h"
+
+/* pal/hal */
+#include "board_configs.h"
+#include "test_pal_time.h"
+#include "test_pal_mem.h"
+#include "test_pal_thread.h"
+#include "test_proj.h"
+#include "test_proj_defs.h"
+#include "test_proj_otp.h"
+
+/* internal */
+#include "cmpu_integration_test.h"
+#include "cmpu_integration_helper.h"
+#include "cmpu_integration_pal_log.h"
+
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define CMPUIT_PTHREAD_STACK_MIN                 16384
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static CmpuItError_t cmpuIt_cmpuTest(void);
+static void* cmpuIt_executer(void *params);
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+static const CCCmpuUniqueDataType_t  UNIQUE_DATA_TYPE = CMPU_UNIQUE_IS_USER_DATA;
+static const uint8_t USER_DATA[PROD_UNIQUE_BUFF_SIZE] = { 0x06, 0xb5, 0x3e, 0xe9, 0x2b, 0x75, 0xde, 0x4a, 0x59, 0xb3, 0x46, 0x9b, 0xf7, 0x0a, 0x72, 0x1b, };
+static const CCPlainAsset_t KCP_BUFF = { 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x10, };
+static const CCAssetPkg_t KCE_BUFF = { 0x50726f64, 0x00010000, 0x00000010, 0x52657631, 0x52657632, 0xab6b3e7f, 0x7f4544b2, 0xe53d0952, 0xb66e49b3, 0x5e639bd6, 0x731bd98a, 0xb1ed2ae4, 0x36371f61, 0x8f4e9404, 0x36262e12, 0x267232c8, };
+static const uint32_t ICV_DCU_DEFAULT_LOCK[PROD_DCU_LOCK_WORD_SIZE] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
+
+/* pass result between executer and main thread */
+CmpuItError_t g_cmpuIt_executerRc = CMPUIT_ERROR__FAIL;
+
+static uint32_t CMPUIT_OTP_CM_VALUES[] = {
+
+    /*  [0x00-0x07]: 256bit Device root key (HUK) */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x08-0x0B]: 128bit ICV Provosioning secret (Kpicv) */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x0C-0x0F]: 128bit ICV Provosioning secret (Kceicv) */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x10]: manufacturer programmed flag */
+    0x00000000,
+    /*  [0x11-0x18]: a single 256b SHA256 (Hbk), or, two 128b truncated SHA256 HBK0 and HBK1 */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x19-0x1C]: 128bit OEM provisioning secret (Kcp) */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x1D-0x20]: 128bit OEM code encryption secret (Kce) */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x21]: OEM programmed flag */
+    0x00000000,
+    /*  [0x22-0x26]: Hbk trusted FW min version */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x27]: general purpose configuration flag */
+    0x00000000,
+    /*  [0x28-0x2B] - 128b DCU lock mask */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static CmpuItError_t cmpuIt_cmpuTest(void)
+{
+    CmpuItError_t rc = CMPUIT_ERROR__OK;
+
+    unsigned long ccHwRegBaseAddr = processMap.processTeeHwRegBaseAddr;
+    uint8_t *pWorkspaceBuf = NULL;
+    uint32_t *pWorkspace = NULL;
+    CCCmpuData_t cmpuData;
+
+    const char* TEST_NAME = "CMPU";
+    CMPUIT_TEST_START(TEST_NAME);
+
+    /* workspace should be 32bit aligned */
+    ALLOC32(pWorkspaceBuf, pWorkspace, CMPU_WORKSPACE_MINIMUM_SIZE);
+
+    /* populate cmpuData with data */
+    cmpuData.uniqueDataType = UNIQUE_DATA_TYPE;
+    memcpy(cmpuData.uniqueBuff.userData, USER_DATA, sizeof(USER_DATA));
+    cmpuData.kpicvDataType = ASSET_PLAIN_KEY;
+    memcpy(cmpuData.kpicv.plainAsset, KCP_BUFF, sizeof(cmpuData.kpicv.plainAsset));
+    cmpuData.kceicvDataType = ASSET_PKG_KEY;
+    memcpy(cmpuData.kceicv.pkgAsset, KCE_BUFF, sizeof(cmpuData.kceicv.pkgAsset));
+    cmpuData.icvMinVersion = 5;
+    cmpuData.icvConfigWord = 0x12345678;
+    memcpy(cmpuData.icvDcuDefaultLock, ICV_DCU_DEFAULT_LOCK, sizeof(ICV_DCU_DEFAULT_LOCK));
+
+    /* debug pointers */
+    CMPUIT_PRINT_DBG("pWorkspace[%p]\n", pWorkspace);
+    CMPUIT_PRINT_DBG("ccHwRegBaseAddr[%p]\n", (void*)ccHwRegBaseAddr);
+    CMPUIT_PRINT_DBG("CMPU_WORKSPACE_MINIMUM_SIZE[%d]\n", CMPU_WORKSPACE_MINIMUM_SIZE);
+
+    /* call API */
+    CMPUIT_ASSERT_WITH_RESULT(CCProd_Cmpu(ccHwRegBaseAddr,
+                                          &cmpuData,
+                                          (unsigned long)pWorkspace,
+                                          CMPU_WORKSPACE_MINIMUM_SIZE), CC_OK);
+
+    /* Perform SW reset to reach DM LCS */
+    Test_ProjPerformPowerOnReset();
+    Test_PalDelay(1000);
+
+    /* verify LCS */
+    CMPUIT_ASSERT(Test_ProjCheckLcs(TEST_PROJ_LCS_DM) == 0);
+
+bail:
+    FREE_IF_NOT_NULL(pWorkspaceBuf);
+
+    CMPUIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+
+/**
+ * @brief               Executor function. Called from a side thread to perform the sequence of tests.
+ * @note                This is a workaround the issue that CC API requires DMA-able stack.
+ *                      When using Test_PalThreadCreate we are able to ensure that the stack is DMA-able.
+ * @param params        Not used
+ */
+static void* cmpuIt_executer(void *params)
+{
+    CmpuItError_t rc = CMPUIT_ERROR__OK;
+    const char* TEST_NAME = "All Tests";
+
+    CC_UNUSED_PARAM(params);
+
+    CMPUIT_PRINT("cc312 cmpu integration test\n");
+    CMPUIT_PRINT("---------------------------------------------------------------\n");
+
+
+    CMPUIT_TEST_START(TEST_NAME);
+
+    rc += cmpuIt_cmpuTest();
+
+    g_cmpuIt_executerRc = rc;
+
+    CMPUIT_TEST_RESULT(TEST_NAME);
+
+    /* continue to next test only if all passed */
+    CMPUIT_ASSERT(rc == CMPUIT_ERROR__OK);
+
+bail:
+    return NULL;
+}
+
+CmpuItError_t cmpuIt_all(void)
+{
+    CmpuItError_t rc = CMPUIT_ERROR__OK;
+    ThreadHandle threadHandle = NULL;
+    const char* TASK_NAME = "cmpuIt_executer";
+    uint32_t priority = Test_PalGetDefaultPriority();
+
+    /* init platform and map memory */
+    CMPUIT_ASSERT(Test_ProjInit() == 0);
+    CMPUIT_ASSERT(Test_ProjBurnOtp(CMPUIT_OTP_CM_VALUES, TEST_PROJ_LCS_CM, TEST_CHIP_STATE_NOT_INITIALIZED) == 0);
+
+    /* Create a task that will allocate a DMA -able stack */
+    threadHandle = Test_PalThreadCreate(CMPUIT_PTHREAD_STACK_MIN,
+                                        cmpuIt_executer,
+                                        priority,
+                                        NULL,
+                                        (char*)TASK_NAME,
+                                        sizeof(TASK_NAME),
+                                        true);
+
+    /* Verify task was created successfully */
+    CMPUIT_ASSERT(threadHandle != NULL);
+
+    /* Wait for task to complete */
+    Test_PalThreadJoin(threadHandle, NULL);
+
+    /* Finalize task's resources */
+    Test_PalThreadDestroy(threadHandle);
+
+    /* Read result code */
+    rc = g_cmpuIt_executerRc;
+
+bail:
+    /* Free platform */
+    Test_ProjFree();
+
+    return rc;
+}
+
+#if defined(DX_PLAT_ZYNQ7000)
+int main(int argc, char** argv)
+{
+    ((void)argc);
+    ((void)argv);
+
+    cmpuIt_all();
+
+    return 0;
+}
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.h
new file mode 100644
index 0000000..5752caf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CMPU_INTEGRATION_TEST_H_
+#define _CMPU_INTEGRATION_TEST_H_
+
+/* system includes */
+#include "stdio.h"
+#include "stdint.h"
+
+/************************************************************
+ *
+ * type decelerations
+ *
+ ************************************************************/
+/**
+ * Error Codes
+ */
+typedef enum CmpuItError_t
+{
+    CMPUIT_ERROR__OK = 0,
+    CMPUIT_ERROR__FAIL = 0x0000FFFF,
+}CmpuItError_t;
+
+/************************************************************
+ *
+ * externs
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * function prototypes
+ *
+ ************************************************************/
+CmpuItError_t cmpuIt_all(void);
+#endif //_CMPU_INTEGRATION_TEST_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.mk b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.mk
new file mode 100644
index 0000000..7cd70fb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test.mk
@@ -0,0 +1,60 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+include ../proj_integration_tests.cfg
+include $(HOST_PROJ_ROOT)/Makefile.test_suite
+include $(HOST_PROJ_ROOT)/../proj.ext.cfg
+
+ifneq ($(TEE_OS),linux)
+TARGET_LIBS = cmpu_integration_test
+else
+TARGET_EXES = cmpu_integration_test
+DEPLIBS = cmpu
+DEPLIBS += $(TEST_AL_LITE_LIBS)
+endif
+
+# Unit test dependencies
+SOURCES_cmpu_integration_test = cmpu_integration_test.c
+SOURCES_cmpu_integration_test += cmpu_integration_test_arm.c
+SOURCES_cmpu_integration_test += $(filter-out test_proj_cclib.c,$(PROJ_SOURCES))
+
+ifeq ($(TEST_DEBUG),1)
+CFLAGS_EXTRA += -DTEST_DEBUG=1# use to toggle debug
+endif
+
+CFLAGS_EXTRA+=-DCC_TEE
+
+TEST_INCLUDES += $(CURDIR)/cmpu_integration_test.h
+INCDIRS_EXTRA += $(CURDIR)/pal/include
+
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal/$(TEE_OS)
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal/$(TEE_OS)/include
+INCDIRS_EXTRA += $(SHARED_INCDIR)/proj/cc3x
+INCDIRS_EXTRA += $(SHARED_DIR)/include/proj/cc3x
+
+INCDIRS_EXTRA += $(HOST_PROJ_ROOT)/include
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal/$(TEST_PRODUCT)
+INCDIRS_EXTRA += $(HOST_SRCDIR)/cc3x_productionlib/cmpu
+INCDIRS_EXTRA += $(HOST_SRCDIR)/cc3x_productionlib/common
+INCDIRS_EXTRA += $(PROJ_INCLUDE)
+INCDIRS_EXTRA += $(TEST_AL_INCLUDE)
+
+INCDIRS_EXTRA += $(SHARED_DIR)/hw/include
+
+ifeq ($(TEE_OS), freertos)
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS/Source/include
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS-Plus-CLI
+INCDIRS_EXTRA += $(KERNEL_DIR)/board/MPS2+
+INCDIRS_EXTRA += $(KERNEL_DIR)/lib/main
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS/Source/portable/RVDS/ARM_CM3
+endif
+
+VPATH += $(CURDIR)/pal/$(TEE_OS)
+VPATH += $(CURDIR)/hal/$(TEST_PRODUCT)
+VPATH += $(PROJ_VPATH)
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test_arm.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test_arm.c
new file mode 100644
index 0000000..3e74a1a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/cmpu_integration_test_arm.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "stdlib.h"
+#include "stdint.h"
+#include <string.h>
+
+#include "cc_pal_types.h"
+#include "test_pal_cli.h"
+#include "dx_reg_base_host.h"
+
+#include "cmpu_integration_test.h"
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static int cmpuIt_cliCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+/**
+ * @brief A wrapper function for the "all" command
+ */
+static int cmpuIt_cliCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString)
+{
+    CC_UNUSED_PARAM(pcWriteBuffer);
+    CC_UNUSED_PARAM(xWriteBufferLen);
+    CC_UNUSED_PARAM(pcCommandString);
+
+    cmpuIt_all();
+
+    return 0;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+/**
+ * This function will be called by freertos before the scheduler starts running.
+ * it's main responsibility is to register the test to the cli interface.
+ *
+ * @return    0 on success
+ */
+int libcmpu_integration_test_initLib(void)
+{
+    int rc = 0;
+
+    static struct Test_PalCliCommand cmdAll =
+    {
+        "cmpu",
+        "\r\nc: \r\n Run CMPU test\r\n",
+        cmpuIt_cliCommand,
+        0
+    };
+
+    static struct Test_PalCliCommand cmdAlias =
+    {
+        "c",
+        "\r\nc: \r\n Run CMPU test\r\n",
+        cmpuIt_cliCommand,
+        0
+    };
+
+    rc += Test_PalCLIRegisterCommand(&cmdAll);
+    rc += Test_PalCLIRegisterCommand(&cmdAlias);
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/pal/include/cmpu_integration_pal_log.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/pal/include/cmpu_integration_pal_log.h
new file mode 100644
index 0000000..bc90ef6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/cmpu_integration_test/pal/include/cmpu_integration_pal_log.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CMPU_INTEGRATION_PAL_LOG_H_
+#define _CMPU_INTEGRATION_PAL_LOG_H_
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+/** Print the function name, line and debug level */
+#define CMPUIT_PRINT_FUNC_AND_LEVEL(_lvl) \
+                do { \
+                    char _buff[50]; \
+                    snprintf(_buff, 49, "%-.25s:%d", __func__, __LINE__); \
+                    printf("%-35.35s: %-5.5s: ", _buff, _lvl); \
+                }while(0)
+
+/** print a line */
+#define CMPUIT_PRINT(format, ...)  \
+                printf(format, ##__VA_ARGS__)
+
+/** print the test result */
+#define CMPUIT_TEST_RESULT(_testName) \
+                do {\
+                    printf("Test: %-50.50s %-10.10s\n", _testName, rc == CMPUIT_ERROR__OK ? "Passed" : "Failed"); \
+                } while(0)
+
+/** print the test start line */
+#define CMPUIT_TEST_START(_testName) \
+                do {\
+                    /* printf("Test: %-50.50s %-10.10s\n", _testName, "Started...."); */ \
+                } while(0)
+
+/** print an error message */
+#define CMPUIT_PRINT_ERROR(format, ...)  \
+                do {\
+                    CMPUIT_PRINT_FUNC_AND_LEVEL("error"); \
+                    CMPUIT_PRINT(format, ##__VA_ARGS__); \
+                } while(0)
+
+/** print an debug message */
+#if defined(TEST_DEBUG)
+#define CMPUIT_PRINT_DBG(format, ...)   \
+                do {\
+                    CMPUIT_PRINT_FUNC_AND_LEVEL("debug"); \
+                    CMPUIT_PRINT(format, ##__VA_ARGS__); \
+                } while(0)
+#else
+#define CMPUIT_PRINT_DBG(format, ...) \
+                do {\
+                } while(0)
+#endif
+
+#endif //_CMPU_INTEGRATION_PAL_LOG_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/Makefile b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/Makefile
new file mode 100644
index 0000000..20a0623
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/Makefile
@@ -0,0 +1,27 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../../../..
+
+ifneq (,$(findstring gnu,$(CROSS_COMPILE)))
+TEE_OS = linux
+else
+TEE_OS = freertos
+endif
+
+ifneq ($(wildcard $(HOST_PROJ_ROOT)/../configs/proj-cc312-sbrom_integration_tests.cfg),)
+$(info Compiling for Internal ARM use)
+ARM_INTERNAL=1
+else
+ARM_INTERNAL=0
+endif
+
+include $(HOST_PROJ_ROOT)/Makefile.defs
+
+include dmpu_integration_test.mk
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_helper.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_helper.h
new file mode 100644
index 0000000..1580fe7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_helper.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _DMPU_INTEGRATION_HELPER_H_
+#define _DMPU_INTEGRATION_HELPER_H_
+
+#include "test_pal_mem.h"
+#include "test_pal_mem_s.h"
+
+#ifdef ARCH_V8M
+#define DMPUIT_TEST_PAL_ALLOC    Test_PalDMAContigBufferAlloc_s
+#define DMPUIT_TEST_PAL_FREE     Test_PalDMAContigBufferFree_s
+#else
+#define DMPUIT_TEST_PAL_ALLOC    Test_PalDMAContigBufferAlloc
+#define DMPUIT_TEST_PAL_FREE     Test_PalDMAContigBufferFree
+#endif
+
+#define FREE_IF_NOT_NULL(_buff)    \
+                do { \
+                    if (_buff != NULL) {     \
+                        DMPUIT_TEST_PAL_FREE(_buff);    \
+                        _buff = NULL; \
+                    } \
+                }while(0)
+
+#define ALLOC32(_pBuff, _pBuffAligned, _wantedSize) \
+                do { \
+                    uint32_t address = 0; \
+                    uint32_t remainder = 0; \
+                    _pBuff = (void*)DMPUIT_TEST_PAL_ALLOC(_wantedSize); \
+                    address = (uint32_t)_pBuff; \
+                    remainder = (sizeof(uint32_t) - (address % sizeof(uint32_t))) % sizeof(uint32_t); \
+                    if (_pBuff == NULL) goto bail; \
+                    _pBuffAligned = (void*)(address + remainder); \
+                }while(0)
+/**
+ *
+ * Assert Macros
+ *
+ */
+#define DMPUIT_ASSERT_WITH_RESULT(_c, _exp)                                            \
+                do {                                                                  \
+                    int _ret = 0;                                                     \
+                    if( ( _ret = (int)_c) != _exp )                                   \
+                    {                                                                 \
+                        DMPUIT_PRINT_ERROR( "failed with rc 0x%08x\n", _ret );         \
+                        rc = DMPUIT_ERROR__FAIL;                                       \
+                        goto bail;                                                    \
+                    }                                                                 \
+                } while(0)
+
+#define DMPUIT_ASSERT(_c)                                                              \
+                do {                                                                  \
+                    if( !(_c))                                                        \
+                    {                                                                 \
+                        DMPUIT_PRINT_ERROR( "failed\n" );                              \
+                        rc = DMPUIT_ERROR__FAIL;                                       \
+                        goto bail;                                                    \
+                    }                                                                 \
+                }                                                                     \
+                while(0)
+
+#define DMPUIT_API(_c)                                                                 \
+                do {                                                                  \
+                    DMPUIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _c;                                                               \
+                } while(0)
+
+#define DMPUIT_API_ASSIGNMENT(_res, _c)                                                \
+                do {                                                                  \
+                    DMPUIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _res = _c;                                                        \
+                } while(0)
+
+#define DMPUIT_ASSERT_API(_c)                                                          \
+                do {                                                                  \
+                    DMPUIT_ASSERT(_c);                                                 \
+                } while(0)
+
+/************************************************************
+ *
+ * type decelerations
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * externs
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * function prototypes
+ *
+ ************************************************************/
+
+#endif //_DMPU_INTEGRATION_HELPER_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.c
new file mode 100644
index 0000000..9fc139d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* system includes */
+#include "dmpu_integration_test.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/* cc_productionLib */
+#include "cc_dmpu.h"
+#include "cc_pal_types.h"
+
+/* shared */
+#include "dx_reg_base_host.h"
+
+/* pal/hal */
+#include "board_configs.h"
+#include "test_pal_time.h"
+#include "test_pal_mem.h"
+#include "test_pal_thread.h"
+#include "test_proj.h"
+#include "test_proj_defs.h"
+#include "test_proj_otp.h"
+
+/* internal */
+#include "dmpu_integration_helper.h"
+#include "dmpu_integration_pal_log.h"
+
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define DMPUIT_PTHREAD_STACK_MIN                 16384
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static DmpuItError_t dmpuIt_dmpuTest(void);
+static void* dmpuIt_executer(void *params);
+
+static const uint8_t HBK[] = {0xe4, 0xf3, 0x28, 0x86, 0xdd, 0xf9, 0x7a, 0xcc, 0x8d, 0x27, 0xc6, 0x16, 0x85, 0x4c, 0xc9, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,};
+static const CCAssetPkg_t KCP_BUFF_ASSET = { 0x50726f64, 0x00010000, 0x00000010, 0x52657631, 0x52657632, 0x7f37da03, 0x2ed0e4cd, 0x36ec18c0, 0x40b8680d, 0xa0178f19, 0x907ede6b, 0x53c71ac2, 0xd36d22f5, 0x3ba4d98b, 0x457644de, 0x7a609102 };
+static const CCAssetPkg_t KCE_BUFF_ASSET = { 0x50726f64, 0x00010000, 0x00000010, 0x52657631, 0x52657632, 0x5dfa0a1e, 0x958aa4be, 0xe9b43a65, 0x67d057c5, 0x286066f0, 0x45a84078, 0xedb95c0b, 0xf6f194c5, 0x2d37d205, 0x8e4e6b52, 0x96d44168 };
+static const uint32_t ICV_DCU_DEFAULT_LOCK[PROD_DCU_LOCK_WORD_SIZE] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff };
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+/* pass result between executer and main thread */
+DmpuItError_t g_dmpuIt_executerRc = DMPUIT_ERROR__FAIL;
+
+static uint32_t DMPUIT_OTP_DM_VALUES[] = {
+    /*  [0x00-0x07]: 256bit Device root key (HUK) */
+    0xb1467c29, 0xf2ad05eb, 0x385e8808, 0x423833d1, 0xa9698203, 0x7c9f71d6, 0x63a605e8, 0x460a5ab1,
+    /*  [0x08-0x0B]: 128bit ICV Provosioning secret (Kpicv) */
+    0x14131211, 0x18171615, 0x1c1b1a19, 0x101f1e1d,
+    /*  [0x0C-0x0F]: 128bit ICV Provosioning secret (Kceicv) */
+    0x222222ff, 0xffffffff, 0xff1111ff, 0xffffffff,
+    /*  [0x10]: manufacturer programmed flag */
+    0x801e508c,
+    /*  [0x11-0x14]:  HBK0 */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x15-0x18]:  HBK1 */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x19-0x1C]: 128bit OEM provisioning secret (Kcp) */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x1D-0x20]: 128bit OEM code encryption secret (Kce) */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+    /*  [0x21]: OEM programmed flag */
+    0x00000000,
+    /*  [0x22-0x23]: Hbk0 trusted FW min version */
+    0x00000000, 0x00000000,
+    /*  [0x24-0x26]: Hbk1 trusted FW min version */
+    0x00000000, 0x00000000, 0x00000000,
+    /*  [0x27]: general purpose configuration flag */
+    0x12345678,
+    /*  [0x28-0x2B] - 128b DCU lock mask */
+    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+};
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static DmpuItError_t dmpuIt_dmpuTest(void)
+{
+    DmpuItError_t rc = DMPUIT_ERROR__OK;
+
+    unsigned long ccHwRegBaseAddr = processMap.processTeeHwRegBaseAddr;
+    uint8_t *pWorkspaceBuf = NULL;
+    uint32_t *pWorkspace = NULL;
+    CCDmpuData_t dmpuData;
+
+    const char* TEST_NAME = "DMPU";
+    DMPUIT_TEST_START(TEST_NAME);
+
+    /* workspace should be 32bit aligned */
+    ALLOC32(pWorkspaceBuf, pWorkspace, DMPU_WORKSPACE_MINIMUM_SIZE);
+
+    /* populate dmpuData with data */
+    dmpuData.hbkType = DMPU_HBK_TYPE_HBK;
+    memcpy(dmpuData.hbkBuff.hbk, HBK, sizeof(HBK));
+    dmpuData.kcpDataType = ASSET_PKG_KEY;
+    memcpy(dmpuData.kcp.pkgAsset, KCP_BUFF_ASSET, sizeof(dmpuData.kcp.pkgAsset));
+    dmpuData.kceDataType = ASSET_PKG_KEY;
+    memcpy(dmpuData.kce.pkgAsset, KCE_BUFF_ASSET, sizeof(dmpuData.kce.pkgAsset));
+    dmpuData.oemMinVersion = 5;
+    memcpy(dmpuData.oemDcuDefaultLock, ICV_DCU_DEFAULT_LOCK, sizeof(ICV_DCU_DEFAULT_LOCK));
+
+    /* debug pointers */
+    DMPUIT_PRINT_DBG("pWorkspace[%p]\n", pWorkspace);
+    DMPUIT_PRINT_DBG("ccHwRegBaseAddr[%p]\n", (void*)ccHwRegBaseAddr);
+    DMPUIT_PRINT_DBG("DMPU_WORKSPACE_MINIMUM_SIZE[%d]\n", DMPU_WORKSPACE_MINIMUM_SIZE);
+
+    /* call API */
+    DMPUIT_ASSERT_WITH_RESULT(CCProd_Dmpu(ccHwRegBaseAddr,
+                              &dmpuData,
+                              (unsigned long)pWorkspace,
+                              DMPU_WORKSPACE_MINIMUM_SIZE), CC_OK);
+
+    /* Perform SW reset to reach DM LCS */
+    Test_ProjPerformPowerOnReset();
+    Test_PalDelay(1000);
+
+    /* verify LCS */
+    DMPUIT_ASSERT(Test_ProjCheckLcs(TEST_PROJ_LCS_SECURE) == 0);
+
+bail:
+    FREE_IF_NOT_NULL(pWorkspaceBuf);
+
+    DMPUIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+
+/**
+ * @brief               Executor function. Called from a side thread to perform the sequence of tests.
+ * @note                This is a workaround the issue that CC API requires DMA-able stack.
+ *                      When using Test_PalThreadCreate we are able to ensure that the stack is DMA-able.
+ * @param params        Not used
+ */
+static void* dmpuIt_executer(void *params)
+{
+    DmpuItError_t rc = DMPUIT_ERROR__OK;
+    const char* TEST_NAME = "All Tests";
+
+    CC_UNUSED_PARAM(params);
+
+    DMPUIT_PRINT("cc312 dmpu integration test\n");
+    DMPUIT_PRINT("---------------------------------------------------------------\n");
+
+
+    DMPUIT_TEST_START(TEST_NAME);
+
+    rc += dmpuIt_dmpuTest();
+
+    g_dmpuIt_executerRc = rc;
+
+    DMPUIT_TEST_RESULT(TEST_NAME);
+
+    /* continue to next test only if all passed */
+    DMPUIT_ASSERT(rc == DMPUIT_ERROR__OK);
+
+bail:
+    return NULL;
+}
+
+DmpuItError_t dmpuIt_all(void)
+{
+    DmpuItError_t rc = DMPUIT_ERROR__OK;
+    ThreadHandle threadHandle = NULL;
+    const char* TASK_NAME = "dmpuIt_executer";
+    uint32_t priority = Test_PalGetDefaultPriority();
+
+    /* init platform and map memory */
+    DMPUIT_ASSERT(Test_ProjInit() == 0);
+    DMPUIT_ASSERT(Test_ProjBurnOtp(DMPUIT_OTP_DM_VALUES, TEST_PROJ_LCS_DM, TEST_CHIP_STATE_TEST) == 0);
+
+    /* Create a task that will allocate a DMA -able stack */
+    threadHandle = Test_PalThreadCreate(DMPUIT_PTHREAD_STACK_MIN,
+                                        dmpuIt_executer,
+                                        priority,
+                                        NULL,
+                                        (char*)TASK_NAME,
+                                        sizeof(TASK_NAME),
+                                        true);
+
+    /* Verify task was created successfully */
+    DMPUIT_ASSERT(threadHandle != NULL);
+
+    /* Wait for task to complete */
+    Test_PalThreadJoin(threadHandle, NULL);
+
+    /* Finalize task's resources */
+    Test_PalThreadDestroy(threadHandle);
+
+    /* Read result code */
+    rc = g_dmpuIt_executerRc;
+
+bail:
+    /* Free platform */
+    Test_ProjFree();
+
+    return rc;
+}
+
+#if defined(DX_PLAT_ZYNQ7000)
+int main(int argc, char** argv)
+{
+    ((void)argc);
+    ((void)argv);
+
+    dmpuIt_all();
+
+    return 0;
+}
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.h
new file mode 100644
index 0000000..44b2e8f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _DMPU_INTEGRATION_TEST_H_
+#define _DMPU_INTEGRATION_TEST_H_
+
+/* system includes */
+#include "stdio.h"
+#include "stdint.h"
+
+/************************************************************
+ *
+ * type decelerations
+ *
+ ************************************************************/
+/**
+ * Error Codes
+ */
+typedef enum DmpuItError_t
+{
+    DMPUIT_ERROR__OK = 0,
+    DMPUIT_ERROR__FAIL = 0x0000FFFF,
+}DmpuItError_t;
+
+/************************************************************
+ *
+ * externs
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * function prototypes
+ *
+ ************************************************************/
+DmpuItError_t dmpuIt_all(void);
+#endif //_DMPU_INTEGRATION_TEST_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.mk b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.mk
new file mode 100644
index 0000000..ed847f6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test.mk
@@ -0,0 +1,59 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+include ../proj_integration_tests.cfg
+include $(HOST_PROJ_ROOT)/Makefile.test_suite
+include $(HOST_PROJ_ROOT)/../proj.ext.cfg
+
+ifneq ($(TEE_OS),linux)
+TARGET_LIBS = dmpu_integration_test
+else
+TARGET_EXES = dmpu_integration_test
+DEPLIBS = dmpu
+DEPLIBS += $(TEST_AL_LITE_LIBS)
+
+endif
+
+# Unit test dependencies
+SOURCES_dmpu_integration_test = dmpu_integration_test.c
+SOURCES_dmpu_integration_test += dmpu_integration_test_arm.c
+SOURCES_dmpu_integration_test += $(filter-out test_proj_cclib.c,$(PROJ_SOURCES))
+
+ifeq ($(TEST_DEBUG),1)
+CFLAGS_EXTRA += -DTEST_DEBUG=1# use to toggle debug
+endif
+
+CFLAGS_EXTRA+=-DCC_TEE
+
+TEST_INCLUDES += $(CURDIR)/dmpu_integration_test.h
+INCDIRS_EXTRA += $(CURDIR)/pal/include
+
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal/$(TEE_OS)
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal/$(TEE_OS)/include
+INCDIRS_EXTRA += $(SHARED_DIR)/include/proj/cc3x
+INCDIRS_EXTRA += $(PROJ_INCLUDE)
+INCDIRS_EXTRA += $(TEST_AL_INCLUDE)
+
+INCDIRS_EXTRA += $(HOST_PROJ_ROOT)/include
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal/$(TEST_PRODUCT)
+INCDIRS_EXTRA += $(HOST_SRCDIR)/cc3x_productionlib/dmpu
+
+INCDIRS_EXTRA += $(SHARED_DIR)/hw/include
+
+ifeq ($(TEE_OS), freertos)
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS/Source/include
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS-Plus-CLI
+INCDIRS_EXTRA += $(KERNEL_DIR)/board/MPS2+
+INCDIRS_EXTRA += $(KERNEL_DIR)/lib/main
+INCDIRS_EXTRA += $(KERNEL_DIR)/OS/FreeRTOS/Source/portable/RVDS/ARM_CM3
+endif
+
+VPATH += $(CURDIR)/pal/$(TEE_OS)
+VPATH += $(CURDIR)/hal/$(TEST_PRODUCT)
+VPATH += $(PROJ_VPATH)
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test_arm.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test_arm.c
new file mode 100644
index 0000000..cfbd295
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/dmpu_integration_test_arm.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "stdlib.h"
+#include "stdint.h"
+#include <string.h>
+
+#include "cc_pal_types.h"
+#include "dmpu_integration_test.h"
+#include "test_pal_cli.h"
+#include "dx_reg_base_host.h"
+
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static int dmpuIt_cliCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+/**
+ * @brief A wrapper function for the "all" command
+ */
+static int dmpuIt_cliCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString)
+{
+    CC_UNUSED_PARAM(pcWriteBuffer);
+    CC_UNUSED_PARAM(xWriteBufferLen);
+    CC_UNUSED_PARAM(pcCommandString);
+
+    dmpuIt_all();
+
+    return 0;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+/**
+ * This function will be called by freertos before the scheduler starts running.
+ * it's main responsibility is to register the test to the cli interface.
+ *
+ * @return    0 on success
+ */
+int libdmpu_integration_test_initLib(void)
+{
+    int rc = 0;
+
+    static struct Test_PalCliCommand cmdAll =
+    {
+        "dmpu",
+        "\r\nd: \r\n Run DMPU test\r\n",
+        dmpuIt_cliCommand,
+        0
+    };
+
+    static struct Test_PalCliCommand cmdAlias =
+    {
+        "d",
+        "\r\nd: \r\n Run DMPU test\r\n",
+        dmpuIt_cliCommand,
+        0
+    };
+
+    rc += Test_PalCLIRegisterCommand(&cmdAll);
+    rc += Test_PalCLIRegisterCommand(&cmdAlias);
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/pal/include/dmpu_integration_pal_log.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/pal/include/dmpu_integration_pal_log.h
new file mode 100644
index 0000000..f46d4e8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/dmpu_integration_test/pal/include/dmpu_integration_pal_log.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _DMPU_INTEGRATION_PAL_LOG_H_
+#define _DMPU_INTEGRATION_PAL_LOG_H_
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+/** Print the function name, line and debug level */
+#define DMPUIT_PRINT_FUNC_AND_LEVEL(_lvl) \
+                do { \
+                    char _buff[50]; \
+                    snprintf(_buff, 49, "%-.25s:%d", __func__, __LINE__); \
+                    printf("%-35.35s: %-5.5s: ", _buff, _lvl); \
+                }while(0)
+
+/** print a line */
+#define DMPUIT_PRINT(format, ...)  \
+                printf(format, ##__VA_ARGS__)
+
+/** print the test result */
+#define DMPUIT_TEST_RESULT(_testName) \
+                do {\
+                    printf("Test: %-50.50s %-10.10s\n", _testName, rc == DMPUIT_ERROR__OK ? "Passed" : "Failed"); \
+                } while(0)
+
+/** print the test start line */
+#define DMPUIT_TEST_START(_testName) \
+                do {\
+                    /* printf("Test: %-50.50s %-10.10s\n", _testName, "Started...."); */ \
+                } while(0)
+
+/** print an error message */
+#define DMPUIT_PRINT_ERROR(format, ...)  \
+                do {\
+                    DMPUIT_PRINT_FUNC_AND_LEVEL("error"); \
+                    DMPUIT_PRINT(format, ##__VA_ARGS__); \
+                } while(0)
+
+/** print an debug message */
+#if defined(TEST_DEBUG)
+#define DMPUIT_PRINT_DBG(format, ...)   \
+                do {\
+                    DMPUIT_PRINT_FUNC_AND_LEVEL("debug"); \
+                    DMPUIT_PRINT(format, ##__VA_ARGS__); \
+                } while(0)
+#else
+#define DMPUIT_PRINT_DBG(format, ...) \
+                do {\
+                } while(0)
+#endif
+
+#endif //_DMPU_INTEGRATION_PAL_LOG_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/proj_integration_tests.cfg b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/proj_integration_tests.cfg
new file mode 100644
index 0000000..fb31cbc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/proj_integration_tests.cfg
@@ -0,0 +1,56 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Project configuration for cc312 generic (development) host project
+PROJ_NAME = cc312_integration_tests
+TARGET_DIR = cc3x
+PROJ_PRD = cc3x
+HOST_LIBNAME = cc3x_lib
+
+
+ifneq (,$(findstring gnu,$(CROSS_COMPILE)))
+TEE_OS = linux
+TEST_BOARD = zynq
+TEST_PRODUCT = cc3x
+else
+TEE_OS = freertos
+TEST_BOARD = mps2+
+TEST_PRODUCT = cc3x
+endif
+
+# Associated device identification info.
+CC_HW_VERSION = 0xFF
+CC_TEE_HW_INC_DIR = hw/include
+
+# max buffer size for DLLI
+DLLI_MAX_BUFF_SIZE = 0x10000
+
+# List of targets to build for host/src
+PROJ_TARGETS += cc3x_lib cc3x_productionlib tests pal
+PROJ_TESTS = integration_cc3x
+INTEG_TESTS = runtime_integration_test # cmpu_integration_test dmpu_integration_test
+
+# If the following flag = 1, then use specific ECC functions
+# with SCA protection on program level (different from HW level)
+CC_CONFIG_SUPPORT_ECC_SCA_SW_PROTECT = 0
+
+# Low level driver support
+FW_ENABLE_AES_DRIVER = 1
+
+CC_CONFIG_SB_CERT_VERSION_MAJOR        = 1
+CC_CONFIG_SB_CERT_VERSION_MINOR        = 0
+
+CFLAGS_EXTRA += -DCC_SRAM_INDIRECT_ACCESS
+CFLAGS_EXTRA += -DUSE_MBEDTLS_CRYPTOCELL
+
+ifneq (,$(findstring gnu,$(CROSS_COMPILE)))
+CFLAGS_EXTRA += -DMBEDTLS_CONFIG_FILE='<config-cc312.h>'
+else
+CFLAGS_EXTRA += -DDX_PLAT_MPS2_PLUS
+CFLAGS_EXTRA += -DMBEDTLS_CONFIG_FILE='<config-cc312-mps2-freertos.h>'
+endif
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/Makefile b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/Makefile
new file mode 100644
index 0000000..edd0c20
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/Makefile
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+HOST_PROJ_ROOT ?= $(shell pwd)/../../../..
+
+ifneq (,$(findstring gnu,$(CROSS_COMPILE)))
+TEE_OS = linux
+else
+TEE_OS = freertos
+endif
+
+ifneq ($(wildcard $(HOST_PROJ_ROOT)/../configs/proj-cc312_integration_tests.cfg),)
+$(info Compiling for Internal ARM use)
+ARM_INTERNAL=1
+else
+ARM_INTERNAL=0
+endif
+
+
+include $(HOST_PROJ_ROOT)/Makefile.defs
+
+include run_integration_test.mk
+
+
+include $(HOST_PROJ_ROOT)/Makefile.rules
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/README.txt b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/README.txt
new file mode 100755
index 0000000..f0e568e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/README.txt
@@ -0,0 +1,30 @@
+The purpose of the integration tests is to test and verify the user's system integration,

+including the CryptoCell hardware and Software,

+including the HAL and PAL layers required by the cc_lib.

+The HAL and PAL layers are assumed to be implemented by the user for the user's system.

+

+These integration tests use simple scenarios for verifying successful

+integration of Arm's product on the customer's platform.

+

+The user is advised to read the following:

+- Chapter "Appendix C - Integration test" in the Software Integrators Manual

+  document, in order to implement a subset of a function to serve as an

+  abstraction layer between the integration test and the operating system of the user's choice.

+- Chapter "2.2.1 Unpacking the shipment" in the Release Notes document - for

+  the compilation process of the supplied code, which is as an example only.

+

+

+The integration tests package was tested for the following environment:

+.     MPS2+ board, deployed with Cortex M3.

+.     Customized FreeRTOS

+.     arm-compiler-5 5.06 compiler.

+

+Assumptions :

+1.    The user created a dedicated PAL and HAL layers, which match the user's platform.

+2.    The user compiled mbedtls libraries (according to the instructions in the Release Notes).

+4.    The code is extracted and compiled according to the description in the Release Notes document.

+5.    The environment variables CROSS_COMPILE,KERNEL_DIR, ARCH and CORTEX are set prior to the compilation.

+

+--------------

+

+Copyright (c) 2001-2019, Arm Limited. All rights reserved.
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_log.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_log.h
new file mode 100644
index 0000000..c454157
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_log.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _RUN_INTEGRATION_PAL_LOG_H_
+#define _RUN_INTEGRATION_PAL_LOG_H_
+
+#include <inttypes.h>
+
+#include "test_pal_thread.h"
+#include "dx_reg_base_host.h"
+#include "dx_env.h"
+#include "test_proj.h"
+
+#define RUNIT_DEBUG_STACK 0
+
+#if defined(DX_PLAT_ZYNQ7000)
+#define CLOCK_HZ 666000000
+#define RUNIT_DEBUG_EXEC_TIME 0
+#elif defined(DX_PLAT_MPS2_PLUS)
+#define CLOCK_HZ 25000000
+#define RUNIT_DEBUG_EXEC_TIME 1
+#endif
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+extern uint8_t gRunItPrintEnable;
+
+/** print a line */
+#define RUNIT_PRINT(format, ...)  \
+                printf(format, ##__VA_ARGS__)
+
+#if RUNIT_DEBUG_EXEC_TIME
+#define RUNIT_START_EXEC_TIME() \
+    do { \
+    } while(0)
+#define RUNIT_PRINT_EXEC_TIME() \
+    do { \
+        printf(" %8"PRIu32"ms", runIt_getMicroSecPublic(runIt_getCyclesPublic() - startTime) / 1000) ;\
+    } while(0)
+#else
+#define RUNIT_START_EXEC_TIME() do {} while(0)
+#define RUNIT_PRINT_EXEC_TIME() do {} while(0)
+#endif /* RUNIT_DEBUG_STACK */
+
+#if RUNIT_DEBUG_STACK
+#define RUNIT_PRINT_STACK()  \
+                if (gRunItPrintEnable == 1) {\
+                    char stack[10]; \
+                    snprintf(stack, 9, "%d", gRunItStackSize - Test_PalThreadStackHighestWatermark(NULL)); \
+                    RUNIT_PRINT(" %5.5s", stack); \
+                } while(0)
+#else
+#define RUNIT_PRINT_STACK() do {} while(0)
+#endif /* RUNIT_DEBUG_STACK */
+
+/** Print the function name, line and debug level */
+#define RUNIT_PRINT_HEADER() \
+                if (gRunItPrintEnable == 1) { \
+                    char dash[] = "------------------------------------------------------------------------------------------------------------------------------------"; \
+                    RUNIT_PRINT("       %-44.44s %-75.75s %-10.10s", "test_name", "description", "status"); \
+                    if (RUNIT_DEBUG_STACK) printf(" %-5.5s", "stack"); \
+                    if (RUNIT_DEBUG_EXEC_TIME) printf(" %-10.10s", "exec time"); \
+                    RUNIT_PRINT("\n      %-44.44s %-75.75s %-10.10s", dash, dash, dash); \
+                    if (RUNIT_DEBUG_STACK) printf(" %-5.5s", dash); \
+                    if (RUNIT_DEBUG_EXEC_TIME) printf(" %-10.10s", dash); \
+                    RUNIT_PRINT("\n"); \
+                }
+
+#define RUNIT_PRINT_FUNC_AND_LEVEL(_lvl) \
+                if (gRunItPrintEnable == 1) { \
+                    char _buff[50]; \
+                    snprintf(_buff, 49, "%-.25s:%d", __func__, __LINE__); \
+                    RUNIT_PRINT("%-35.35s: %-5.5s: ", _buff, _lvl); \
+                }
+
+/** print the test result */
+#define RUNIT_TEST_RESULT(_testName) \
+                if (gRunItPrintEnable == 1) {\
+                    char label[121] = {0}; \
+                    snprintf(label, 120, "%s.........................................................................................................", _testName); \
+                    RUNIT_PRINT("Test: %-120.120s %-10.10s", label, rc == RUNIT_ERROR__OK ? "Passed" : "Failed"); \
+                    RUNIT_PRINT_STACK(); \
+                    RUNIT_PRINT_EXEC_TIME(); \
+                    RUNIT_PRINT("\n"); \
+                }
+
+
+#define RUNIT_SUB_TEST_RESULT_W_PARAMS(_testName, _format, ...) \
+                if (gRunItPrintEnable == 1) {\
+                    char buff[100]; \
+                    snprintf(buff, 99, _format, ##__VA_ARGS__); \
+                    RUNIT_PRINT("Test:     %-40.40s %-75.75s %-10.10s", _testName, buff, rc == RUNIT_ERROR__OK ? "Passed" : "Failed"); \
+                    RUNIT_PRINT_STACK(); \
+                    RUNIT_PRINT_EXEC_TIME(); \
+                    RUNIT_PRINT("\n"); \
+                }
+
+#define RUNIT_SUB_TEST_RESULT(_testName) \
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(_testName, " ")
+
+/** print the test start line */
+#define RUNIT_TEST_START(_testName) \
+                uint32_t startTime = runIt_getCyclesPublic(); \
+                (void)startTime; \
+                if (gRunItPrintEnable == 1) {\
+                    RUNIT_PRINT("Test: %-120.120s %-10.10s", _testName, "                  "); \
+                    RUNIT_PRINT_STACK(); \
+                    RUNIT_START_EXEC_TIME(); \
+                    RUNIT_PRINT("\n"); \
+                }
+
+/** print the sub test start line */
+#define RUNIT_SUB_TEST_START(_testName) \
+                uint32_t startTime = runIt_getCyclesPublic(); \
+                (void)startTime; \
+                do { \
+                    RUNIT_START_EXEC_TIME(); \
+                } while(0)
+
+
+/** print an error message */
+#define RUNIT_PRINT_ERROR(format, ...)  \
+                do {\
+                    RUNIT_PRINT_FUNC_AND_LEVEL("error"); \
+                    RUNIT_PRINT(format, ##__VA_ARGS__); \
+                } while(0)
+
+
+
+/** print an debug message */
+#if defined(TEST_DEBUG)
+#define RUNIT_PRINT_DBG(format, ...)    \
+                do {\
+                    RUNIT_PRINT_FUNC_AND_LEVEL("debug"); \
+                    RUNIT_PRINT(format, ##__VA_ARGS__); \
+                } while(0)
+
+/** print an error message */
+#define RUNIT_PRINT_BUF(_buff, _size, _label)  \
+                do {\
+                    uint32_t i = 0, j = 0;\
+                    for (i = 0; i * 16 + j < _size; i++, j = 0)\
+                    { \
+                        char tmpBuff[256] = {0}; \
+                        for (j = 0; i * 16 + j < _size && j < 16; j++) \
+                        { \
+                            sprintf(tmpBuff + strlen(tmpBuff), "%02x", ((uint8_t*)_buff)[i * 16 + j]); \
+                        } \
+                        RUNIT_PRINT_FUNC_AND_LEVEL("debug"); \
+                        RUNIT_PRINT("%-10.10s %04"PRIx32": %s\n", _label, i * 16, tmpBuff); \
+                    } \
+                } while(0)
+#else
+#define RUNIT_PRINT_DBG(format, ...) do {} while(0)
+#define RUNIT_PRINT_BUF(_buff, _size, _label) do {} while(0)
+#endif
+
+static __inline uint32_t runIt_getCyclesPublic(void);
+static __inline uint32_t runIt_getCyclesPublic(void)
+{
+    return *(volatile uint32_t *)(processMap.processTeeHwEnvBaseAddr + DX_ENV_COUNTER_RD_REG_OFFSET);
+}
+
+
+/**
+*
+* @param cycles
+* @return          microSeconds
+*/
+static __inline uint32_t runIt_getMicroSecPublic(uint32_t cycles);
+static __inline uint32_t runIt_getMicroSecPublic(uint32_t cycles)
+{
+    static const uint32_t MICROSECONDS = 1000000;
+
+    return (uint32_t)((uint64_t)cycles * (uint64_t)MICROSECONDS / CLOCK_HZ);
+}
+
+
+#endif //_RUN_INTEGRATION_PAL_LOG_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_otp.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_otp.h
new file mode 100644
index 0000000..c4f62af
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_otp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _RUN_INTEGRATION_PAL_OTP_H_
+#define _RUN_INTEGRATION_PAL_OTP_H_
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+/** Write OTP value */
+#define RUNIT_WRITE_OTP(wordOffset, val) { \
+                volatile uint32_t ii1; \
+                (*(volatile uint32_t *)(processMap.processTeeHwEnvBaseAddr + RUNIT_ENV_OTP_START_OFFSET+ ((wordOffset)*sizeof(uint32_t)))) = (uint32_t)(val); \
+                for(ii1=0; ii1<500; ii1++);\
+}
+
+/** Read OTP value */
+#define RUNIT_READ_OTP(wordOffset) \
+                *(volatile uint32_t *)(processMap.processTeeHwEnvBaseAddr + RUNIT_ENV_OTP_START_OFFSET + ((wordOffset)*sizeof(uint32_t)))
+
+#endif //_RUN_INTEGRATION_PAL_OTP_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_reg.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_reg.h
new file mode 100644
index 0000000..52aa7a2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/pal/include/run_integration_pal_reg.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _RUN_INTEGRATION_PAL_REG_H_
+#define _RUN_INTEGRATION_PAL_REG_H_
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+/** Write to register at offset (in words)*/
+#define RUNIT_READ_REG(offset) \
+        *(volatile uint32_t *)(processMap.processTeeHwRegBaseAddr + (offset))
+
+/** Read from register at offset (in words) into val */
+#define RUNIT_WRITE_REG(offset, val)  { \
+    (*(volatile uint32_t *)(processMap.processTeeHwRegBaseAddr + (offset))) = (uint32_t)(val); \
+}
+
+#endif //_RUN_INTEGRATION_PAL_REG_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_flash.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_flash.c
new file mode 100644
index 0000000..98c0737
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_flash.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "stdint.h"
+#include <string.h>
+#include <inttypes.h>
+
+#include "run_integration_pal_log.h"
+#include "run_integration_flash.h"
+#include "run_integration_helper.h"
+
+#include "test_pal_log.h"
+
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_flashValidateInput(uint32_t addr, size_t len, uint8_t* buff);
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+/** Holds the address of memory allocated for the flash chunk */
+uint8_t *gFlashBaseAddr = NULL;
+
+/** Holds the size of the allocated Flash size. */
+uint32_t gFlashSize = 0;
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_flashValidateInput(uint32_t addr, size_t len, uint8_t* buff)
+{
+    int32_t remainder;
+
+    /* validate null values */
+    if (buff == NULL)
+    {
+        RUNIT_PRINT_ERROR("output buffer is NULL\n");
+        return RUNIT_ERROR__FAIL;
+    }
+
+    /* validate address in range */
+    remainder = ((int32_t)gFlashSize) - (addr + len);
+    if (remainder < 0)
+    {
+        RUNIT_PRINT_ERROR("Attempting to read behind flash partition by %"PRId32" bytes\n", remainder * (-1));
+        return RUNIT_ERROR__FAIL;
+    }
+
+    return RUNIT_ERROR__OK;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_flashFinalize(void)
+{
+    if (gFlashBaseAddr != NULL)
+    {
+        RUNIT_PRINT_DBG("finialize flash\n");
+
+        RUNIT_TEST_PAL_FREE(gFlashBaseAddr);
+        gFlashSize = 0;
+        gFlashBaseAddr = NULL;
+    }
+
+    return RUNIT_ERROR__OK;
+
+}
+
+RunItError_t runIt_flashInit(size_t flashSize)
+{
+    /* if already allocated, print to log and return error */
+    if (gFlashBaseAddr != NULL)
+    {
+        RUNIT_PRINT_DBG("Attempting to initialize flash 2nd time\n");
+        return RUNIT_ERROR__OK;
+    }
+
+    RUNIT_PRINT_DBG("init flash\n");
+
+    /* allocate mem */
+    gFlashBaseAddr = (uint8_t*) RUNIT_TEST_PAL_ALLOC(flashSize);
+
+    /* Validate */
+    if (gFlashBaseAddr == NULL)
+    {
+        RUNIT_PRINT_ERROR("Failed to allocate %zu bytes for flash\n", flashSize);
+        return RUNIT_ERROR__FAIL;
+    }
+
+    gFlashSize = flashSize;
+
+    return RUNIT_ERROR__OK;
+}
+
+RunItError_t runIt_flashWrite(uint32_t addr, uint8_t* pBuff, size_t len)
+{
+    RunItError_t rc = runIt_flashValidateInput(addr, len, pBuff);
+    if (rc != RUNIT_ERROR__OK)
+    {
+        RUNIT_PRINT_ERROR("Failed input validation\n");
+        return RUNIT_ERROR__FAIL;
+    }
+
+    /* memcpy from buff */
+    memcpy(gFlashBaseAddr + addr, pBuff, len);
+
+    return rc;
+
+}
+
+RunItError_t runIt_flashRead(uint32_t addr, uint8_t* pBuff, size_t len)
+{
+    RunItError_t rc = runIt_flashValidateInput(addr, len, pBuff);
+    if (rc != RUNIT_ERROR__OK)
+    {
+        RUNIT_PRINT_ERROR("Failed input validation\n");
+        return RUNIT_ERROR__FAIL;
+    }
+
+    /* memcpy to buff */
+    memcpy(pBuff, gFlashBaseAddr + addr, len);
+
+    return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_flash.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_flash.h
new file mode 100644
index 0000000..2bce227
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_flash.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _BSV_INTEGRATION_FLASH_H_
+#define _BSV_INTEGRATION_FLASH_H_
+
+#include "stdint.h"
+#include "run_integration_test.h"
+
+/**
+ * @brief                   Initiate the flash module, should be called before other flash operations.
+ *                          The init function should initiate all that is needed to imitate flash operations
+ *
+ * @param flashSize         [input] size of flash to initialize
+ *
+ * @return                  RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_flashInit(size_t flashSize);
+
+/**
+ * @brief                   Take the necessary step to close resource allocated in favor of Flash PAL module.
+ *                          Could be deallocation or reset of some kind
+ *
+ * @return                  RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_flashFinalize(void);
+
+/**
+ * @brief                   Write to flash at a certain offset.
+ *
+ * @param addr              [input] the offset from the start of the flash
+ * @param buff              [input] the buffer which to write to flash
+ * @param len               [input] length of data to write to flash
+ *
+ * @return                  RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_flashWrite(uint32_t addr, uint8_t* buff, size_t len);
+
+/**
+ * @brief                   Read from flash to buffer
+ *
+ * @param addr              [input] the offset from the start of the flash
+ * @param buff              [output] the buffer to fill
+ * @param len               [input] length of data to read from flash
+ *
+ * @return                  RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_flashRead(uint32_t addr, uint8_t* buff, size_t len);
+
+#endif //_BSV_INTEGRATION_FLASH_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_helper.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_helper.c
new file mode 100644
index 0000000..3da049a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_helper.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "cc_pal_types.h"
+#include "mbedtls/ctr_drbg.h"
+
+#include "run_integration_helper.h"
+#include "run_integration_test.h"
+#include "run_integration_pal_log.h"
+#include "run_integration_flash.h"
+
+/**
+ * Assigns into ppBuffAligned the next aligned 32bit address relative to pBuff.
+ *
+ * @param pBuff
+ * @param ppBuffAligned
+ */
+void runIt_buffAlign32(uint8_t* pBuff, uint32_t **ppBuffAligned, uint32_t wantedBuffSize, const char * name)
+{
+    uint32_t address = (uint32_t)pBuff;
+    uint32_t remainder = (sizeof(uint32_t) - (address % sizeof(uint32_t))) % sizeof(uint32_t);
+    *ppBuffAligned = (uint32_t*)(address + remainder);
+
+    CC_UNUSED_PARAM(wantedBuffSize);
+    CC_UNUSED_PARAM(name);
+
+#if defined(RUNIT_DEBUG_ALLOC)
+    RUNIT_PRINT_DBG("%-30.30s pBuff[%"PRIxPTR"] ppBuffAligned[%"PRIxPTR"] wantedBuffSize[%04"PRIu32"]\n", name, (uintptr_t)pBuff, (uintptr_t)*ppBuffAligned, wantedBuffSize);
+#endif
+}
+
+int runIt_unhexify(unsigned char *obuf, const char *ibuf)
+{
+    #define assert(a) do{} while(0)
+    unsigned char c, c2;
+    int len = strlen(ibuf) / 2;
+    assert(strlen( ibuf ) % 2 == 0); /* must be even number of bytes */
+
+    while (*ibuf != 0)
+    {
+        c = *ibuf++;
+        if (c >= '0' && c <= '9')
+            c -= '0';
+        else if (c >= 'a' && c <= 'f')
+            c -= 'a' - 10;
+        else if (c >= 'A' && c <= 'F')
+            c -= 'A' - 10;
+        else
+            assert(0);
+
+        c2 = *ibuf++;
+        if (c2 >= '0' && c2 <= '9')
+            c2 -= '0';
+        else if (c2 >= 'a' && c2 <= 'f')
+            c2 -= 'a' - 10;
+        else if (c2 >= 'A' && c2 <= 'F')
+            c2 -= 'A' - 10;
+        else
+            assert(0);
+
+        *obuf++ = (c << 4) | c2;
+    }
+
+    return len;
+}
+
+void runIt_hexify(unsigned char *obuf, const unsigned char *ibuf, int len)
+{
+    unsigned char l, h;
+
+    while (len != 0)
+    {
+        h = *ibuf / 16;
+        l = *ibuf % 16;
+
+        if (h < 10)
+            *obuf++ = '0' + h;
+        else
+            *obuf++ = 'a' + h - 10;
+
+        if (l < 10)
+            *obuf++ = '0' + l;
+        else
+            *obuf++ = 'a' + l - 10;
+
+        ++ibuf;
+        len--;
+    }
+}
+
+/**
+ * This function just returns data from rand().
+ * Although predictable and often similar on multiple
+ * runs, this does not result in identical random on
+ * each run. So do not use this if the results of a
+ * test depend on the random data that is generated.
+ *
+ * rng_state shall be NULL.
+ */
+static int runIt_rndStdRand(void *rng_state, unsigned char *output, size_t len)
+{
+#if !defined(__OpenBSD__)
+    size_t i;
+
+    if (rng_state != NULL)
+        rng_state = NULL;
+
+    for (i = 0; i < len; ++i)
+        output[i] = rand();
+#else
+    if( rng_state != NULL )
+    rng_state = NULL;
+
+    arc4random_buf( output, len );
+#endif /* !OpenBSD */
+
+    return (0);
+}
+
+/**
+ * This function returns random based on a buffer it receives.
+ *
+ * rng_state shall be a pointer to a rnd_buf_info structure.
+ *
+ * The number of bytes released from the buffer on each call to
+ * the random function is specified by per_call. (Can be between
+ * 1 and 4)
+ *
+ * After the buffer is empty it will return rand();
+ */
+int runIt_rndBufferRand(void *rng_state, unsigned char *output, size_t len)
+{
+    rnd_buf_info *info = (rnd_buf_info *) rng_state;
+    size_t use_len;
+
+    if (rng_state == NULL)
+        return (runIt_rndStdRand( NULL, output, len));
+
+    use_len = len;
+    if (len > info->length)
+        use_len = info->length;
+
+    if (use_len)
+    {
+        memcpy(output, info->buf, use_len);
+        info->buf += use_len;
+        info->length -= use_len;
+    }
+
+    if (len - use_len > 0)
+        return (runIt_rndStdRand( NULL, output + use_len, len - use_len));
+
+    return (0);
+}
+
+int runIt_free(RunItPtr *ptrElement)
+{
+    int rc = 0;
+    RUNIT_ASSERT(ptrElement != NULL);
+
+    mbedtls_free(ptrElement->buf);
+
+bail:
+    return rc;
+}
+
+int runIt_malloc(RunItPtr *ptrElement, size_t length)
+{
+    int rc = 0;
+    RUNIT_ASSERT(ptrElement != NULL);
+
+    memset(ptrElement, 0, sizeof(*ptrElement));
+
+    ptrElement->buf = mbedtls_calloc(1, length + RUNIT_ALIGN32_SLACK + sizeof(uint32_t));
+    runIt_buffAlign32(ptrElement->buf, &(ptrElement->ba), length, "temp");
+    ptrElement->length = length;
+
+bail:
+    return rc;
+}
+
+/**
+ * @brief                   Function needed by some of CC API.
+ *                          Converts between CC API signature to internal flash read function
+ *                          This specific function implementation reads the flash content in newly allocated memory.
+ *
+ * @param flashAddress      [input]
+ * @param memDst            [output]
+ * @param sizeToRead        [input]
+ * @param context           [input] not used
+ *
+ * @return                  CC_OK on success
+ */
+uint32_t runIt_flashReadWrap(void* flashAddress, /*! Flash address to read from */
+                             uint8_t *memDst, /*! memory destination to read the data to */
+                             uint32_t sizeToRead, /*! size to read from Flash (in bytes) */
+                             void* context)
+{
+    CC_UNUSED_PARAM(context);
+
+    if (runIt_flashRead((uint32_t)flashAddress, memDst, sizeToRead) != RUNIT_ERROR__OK)
+        return 1;
+
+    return 0;
+}
+
+
+int runIt_buildRandomBuffer(uint8_t *pBuf, size_t bufSize)
+{
+    uint32_t chunkSize = 0;
+    uint32_t doneSize = 0;
+
+    while (doneSize < bufSize)
+    {
+        chunkSize = (bufSize - doneSize > MBEDTLS_CTR_DRBG_MAX_REQUEST) ? MBEDTLS_CTR_DRBG_MAX_REQUEST : (bufSize - doneSize);
+        if (gpRndContext->rndGenerateVectFunc(gpRndContext->rndState, pBuf + doneSize, chunkSize) == 0)
+        {
+            doneSize += chunkSize;
+        }
+        else
+        {
+            return RUNIT_ERROR__FAIL;
+        }
+    }
+
+    return RUNIT_ERROR__OK;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_helper.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_helper.h
new file mode 100644
index 0000000..74b54e3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_helper.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _RUN_INTEGRATION_HELPER_H_
+#define _RUN_INTEGRATION_HELPER_H_
+
+#include MBEDTLS_CONFIG_FILE
+
+#include <inttypes.h>
+
+/* cc lib */
+#include "cc_rnd_common.h"
+#include "cc_pal_types.h"
+#include "cc_pal_perf.h"
+
+#include "mbedtls/platform.h"
+#include "mbedtls/ctr_drbg.h"
+/* pal */
+#include "test_pal_mem.h"
+#include "test_pal_mem_s.h"
+
+#include MBEDTLS_CONFIG_FILE
+#include "run_integration_profiler.h"
+
+#define RUNIT_ALIGN32_SLACK                     (sizeof(uint32_t) - 1)
+
+#define RUNIT_DEBUG_ALLOC(_pStruct)              do {} while(0); // RUNIT_PRINT_DBG("%s[%p]\n", #_pStruct, _pStruct)
+
+/************************************************************
+ *
+ * Alloc macros
+ *
+ ************************************************************/
+#define FREE_IF_NOT_NULL(_buff)    \
+                if (_buff.buf != NULL) {     \
+                    mbedtls_free(_buff.buf);    \
+                }
+
+#define ALLOC_VERIFY(_buff, _size) \
+                do {                                                                                    \
+                    if (_buff == NULL)                                                                  \
+                    {                                                                                   \
+                        RUNIT_PRINT_ERROR("Failed to allocate %u bytes for %s\n", (unsigned int)_size, #_buff);       \
+                        rc = RUNIT_ERROR__FAIL;                                                         \
+                        goto bail;                                                                      \
+                    }                                                                                   \
+                } while(0)
+
+/**
+ * Allocate 8 bit aligned buf using mbedtls
+ * the buf will be unaligned on purpose
+ */
+#define MALLOC(_buff, _pStruct, _size) \
+                do { \
+                    runIt_malloc(&_buff, _size); \
+                    ALLOC_VERIFY(_buff.buf, _size); \
+                } while(0)
+
+#define ALLOC(_buff, _pStruct, _size) \
+                do { \
+                    MALLOC(_buff, _pStruct, _size); \
+                    _pStruct = (void*)((void*)GET_UNALIGNED_PTR(_buff)); \
+                    RUNIT_DEBUG_ALLOC(_pStruct); \
+                } while(0)
+
+/** Allocate 32 bit aligned buf using mbedtls */
+#define ALLOC_STRUCT(_type, _buff, _pStruct) \
+                do { \
+                    MALLOC(_buff, _pStruct, sizeof(_type)); \
+                    _pStruct = (_type*)((void*)GET_PTR(_buff)); \
+                    RUNIT_DEBUG_ALLOC(_pStruct); \
+                } while(0)
+
+/**
+ * Allocat 8 bit aligned buf using mbedtls and copy contents from other buf
+ * the buf will be unaligned on purpose
+ */
+#define ALLOC_AND_COPY(_buff, _pStruct, _src_buf, _size) \
+                do { \
+                    ALLOC(_buff, _pStruct, _size); \
+                    RUNIT_DEBUG_ALLOC(_pStruct); \
+                    memcpy((uint8_t*)_pStruct, (uint8_t*)_src_buf, _size); \
+                    RUNIT_DEBUG_ALLOC(_pStruct); \
+                } while(0)
+
+/** Allocate 32 bit aligned buf using mbedtls and copy contents from other buf */
+#define ALLOC32_AND_COPY(_buff, _pStruct, _src_buf, _size) \
+                do { \
+                    ALLOC(_buff, _pStruct, _size); \
+                    _pStruct = (void*)((void*)GET_PTR(_buff)); \
+                    memcpy((uint8_t*)_pStruct, (uint8_t*)_src_buf, _size); \
+                    RUNIT_DEBUG_ALLOC(_pStruct); \
+                } while(0)
+
+/** Allocate 32 bit aligned buf using mbedtls */
+#define ALLOC32(_buff, _pStruct, _size) \
+                do { \
+                    ALLOC(_buff, _pStruct, _size); \
+                    _pStruct = (void*)((void*)GET_PTR(_buff)); \
+                    RUNIT_DEBUG_ALLOC(_pStruct); \
+                } while(0)
+
+#ifdef ARCH_V8M
+#define RUNIT_TEST_PAL_ALLOC    Test_PalDMAContigBufferAlloc_s
+#define RUNIT_TEST_PAL_FREE     Test_PalDMAContigBufferFree_s
+#else
+#define RUNIT_TEST_PAL_ALLOC    Test_PalDMAContigBufferAlloc
+#define RUNIT_TEST_PAL_FREE     Test_PalDMAContigBufferFree
+#endif
+
+/** Allocate 32 bit aligned buf using pal */
+#define ALLOC_BUFF_ALIGN32(_bufWithSlack, _alignedBuff, _wantedBuffSize) \
+                do {                                                                                    \
+                    _bufWithSlack = (uint8_t*)RUNIT_TEST_PAL_ALLOC(_wantedBuffSize + RUNIT_ALIGN32_SLACK);\
+                    ALLOC_VERIFY(_bufWithSlack, _wantedBuffSize + RUNIT_ALIGN32_SLACK);                 \
+                    runIt_buffAlign32(_bufWithSlack, &_alignedBuff, _wantedBuffSize, #_bufWithSlack);                                    \
+                }while(0)
+
+/**
+ *
+ * Assert Macros
+ *
+ */
+#define RUNIT_ASSERT_WITH_RESULT(_c, _exp)                                            \
+                do {                                                                  \
+                    int _ret = 0;                                                     \
+                    runItPerfType_t _type = PERF_TYPE_TEST_NOT_SET;                   \
+                    runItPerfData_t _data = 0;                                        \
+                    _type = runIt_perfTypeFromStr(#_c, "");                           \
+                    RUNIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _data = runIt_perfOpenNewEntry(_type);                            \
+                    if( ( _ret = (int)_c) != _exp )                                   \
+                    {                                                                 \
+                        RUNIT_PRINT_ERROR( "failed with rc 0x%08x\n", _ret );         \
+                        rc = RUNIT_ERROR__FAIL;                                       \
+                        runIt_perfCloseEntry(_data, _type);                           \
+                        goto bail;                                                    \
+                    }                                                                 \
+                    runIt_perfCloseEntry(_data, _type);                               \
+                } while(0)
+
+#define RUNIT_ASSERT(_c)                                                              \
+                do {                                                                  \
+                    if( !(_c))                                                        \
+                    {                                                                 \
+                        RUNIT_PRINT_ERROR( "failed\n" );                              \
+                        rc = RUNIT_ERROR__FAIL;                                       \
+                        goto bail;                                                    \
+                    }                                                                 \
+                }                                                                     \
+                while(0)
+
+#define RUNIT_API(_c)                                                                 \
+                do {                                                                  \
+                    runItPerfType_t _type = PERF_TYPE_TEST_NOT_SET;                   \
+                    runItPerfData_t _data = 0;                                        \
+                    _type = runIt_perfTypeFromStr(#_c, "");                           \
+                    RUNIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _data = runIt_perfOpenNewEntry(_type);                            \
+                    _c;                                                               \
+                    runIt_perfCloseEntry(_data, _type);                               \
+                } while(0)
+
+#define RUNIT_API_ASSIGNMENT(_res, _c)                                                \
+                do {                                                                  \
+                    runItPerfType_t _type = PERF_TYPE_TEST_NOT_SET;                   \
+                    runItPerfData_t _data = 0;                                        \
+                    _type = runIt_perfTypeFromStr(#_c, "");                           \
+                    RUNIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _data = runIt_perfOpenNewEntry(_type);                            \
+                    _res = _c;                                                        \
+                    runIt_perfCloseEntry(_data, _type);                               \
+                } while(0)
+
+#define RUNIT_ASSERT_API(_c)                                                          \
+                do {                                                                  \
+                    runItPerfType_t _type = PERF_TYPE_TEST_NOT_SET;                   \
+                    runItPerfData_t _data = 0;                                        \
+                    _type = runIt_perfTypeFromStr(#_c, "");                           \
+                    RUNIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _data = runIt_perfOpenNewEntry(_type);                            \
+                    RUNIT_ASSERT(_c);                                                 \
+                    runIt_perfCloseEntry(_data, _type);                               \
+                } while(0)
+
+#define RUNIT_ASSERT_W_PARAM(_s, _c)                                                  \
+                do {                                                                  \
+                    runItPerfType_t _type = PERF_TYPE_TEST_NOT_SET;                   \
+                    runItPerfData_t _data = 0;                                        \
+                    _type = runIt_perfTypeFromStr(#_c, _s);                           \
+                    RUNIT_PRINT_DBG("running %-30.30s\n", #_c);                       \
+                    _data = runIt_perfOpenNewEntry(_type);                            \
+                    RUNIT_ASSERT(_c);                                                 \
+                    runIt_perfCloseEntry(_data, _type);                               \
+                } while(0)
+
+#define GET_PTR(_c) (_c.ba)
+#define GET_UNALIGNED_PTR(_c) ((uint8_t*)(_c.ba) + 1)
+
+#define RUNIT_PERF_REG_API_W_PARAM(_c, _s, _is_hw)                                    \
+    runIt_perfEntryInit(#_c, _s, _is_hw)
+
+#define RUNIT_PERF_REG_API(_c, _is_hw)                                                \
+    runIt_perfEntryInit(#_c, "", _is_hw)
+/************************************************************
+ *
+ * type decelerations
+ *
+ ************************************************************/
+typedef struct rnd_buf_info
+{
+    unsigned char *buf;
+    size_t length;
+} rnd_buf_info;
+
+typedef struct RunItPtr
+{
+    uint8_t*    buf;
+    uint32_t*   ba;
+    size_t      length;
+} RunItPtr;
+
+/************************************************************
+ *
+ * externs
+ *
+ *******************    *****************************************/
+extern CCRndContext_t* gpRndContext;
+extern mbedtls_ctr_drbg_context* gpRndState;
+extern uint32_t gRunItStackSize;
+
+/************************************************************
+ *
+ * function prototypes
+ *
+ ************************************************************/
+void runIt_buffAlign32(uint8_t* pBuff, uint32_t **ppBuffAligned, uint32_t wantedBuffSize, const char * name);
+int runIt_unhexify(unsigned char *obuf, const char *ibuf);
+void runIt_hexify(unsigned char *obuf, const unsigned char *ibuf, int len);
+int runIt_rndBufferRand(void *rng_state, unsigned char *output, size_t len);
+int runIt_rand(void *rng_state, unsigned char *output, size_t len);
+int runIt_free(RunItPtr *ptrElement);
+int runIt_malloc(RunItPtr *ptrElement, size_t length);
+uint32_t runIt_flashReadWrap(void* flashAddress, uint8_t *memDst, uint32_t sizeToRead, void* context);
+int runIt_buildRandomBuffer(uint8_t *pBuf, size_t bufSize);
+#endif //_RUN_INTEGRATION_HELPER_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_otp.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_otp.c
new file mode 100644
index 0000000..27c87e9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_otp.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "stdint.h"
+#include "stdio.h"
+#include <string.h>
+
+#include "run_integration_pal_otp.h"
+#include "run_integration_pal_log.h"
+#include "run_integration_pal_reg.h"
+
+#include "board_configs.h"
+#include "test_pal_time.h"
+#include "test_proj_defs.h"
+
+#include "dx_env.h"
+#include "dx_host.h"
+#include "dx_nvm.h"
+#include "dx_crys_kernel.h"
+#include "dx_reg_base_host.h"
+
+#include "cc_otp_defs.h"
+#include "cc_regs.h"
+#include "run_integration_otp.h"
+
+#ifdef RUNIT_PIE_ENABLED
+/* include sbrom data file to determine whether we are running system flows */
+#include "bsv_integration_data_def.h"
+#endif /* RUNIT_PIE_ENABLED */
+
+#ifndef RUNIT_SECURE_BOOT_SKIP_BURN_OTP
+#define RUNIT_SECURE_BOOT_SKIP_BURN_OTP 0
+#endif
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+/* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+#define RUNIT_WAIT_NVM_IDLE(regVal) \
+                do {                                            \
+                    uint32_t regVal;                                \
+                    do {                                        \
+                        regVal = RUNIT_READ_REG(CC_REG_OFFSET(HOST_RGF, NVM_IS_IDLE));            \
+                        regVal = CC_REG_FLD_GET(0, NVM_IS_IDLE, VALUE, regVal);         \
+                    }while( !regVal );                              \
+                }while(0)
+
+
+#define RUNIT_TEST_CALC_BUFF_ZEROS(wordBuf, buffWordSize, zeros) \
+                do {\
+                    int i = 0;\
+                    int j = 0;\
+                    int mask = 0;\
+                    zeros = 0;\
+                    for (i = 0; i< buffWordSize; i++) {\
+                        for (j = 0; j<32; j++) {\
+                            mask = 0x1;\
+                            if (!(*(wordBuf+i) & (mask << j))) {\
+                                zeros++;\
+                            }\
+                        }\
+                    }\
+                }
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+
+
+RunItError_t runIt_getLcs(unsigned int *lcs)
+{
+    unsigned int regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    RUNIT_WAIT_NVM_IDLE(regVal);
+
+    /* Read the LCS register */
+    regVal = RUNIT_READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    *lcs = regVal;
+
+    return RUNIT_ERROR__OK;
+}
+
+RunItError_t runIt_checkLcs(unsigned int lcs)
+{
+    unsigned int regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    RUNIT_WAIT_NVM_IDLE(regVal);
+
+    /* Read the LCS register */
+    regVal = RUNIT_READ_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    /* Verify lcs */
+    if(regVal != lcs)
+    {
+        RUNIT_PRINT_ERROR("actual LCS %d != expected LCS %d\n", regVal, lcs);
+        return RUNIT_ERROR__FAIL;
+    }
+
+    return RUNIT_ERROR__OK;
+}
+
+RunItError_t runIt_burnOtp(unsigned int *otpBuf, unsigned int nextLcs)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if !RUNIT_SECURE_BOOT_SKIP_BURN_OTP
+    unsigned int i = 0;
+
+    /*  Perform SW reset to reach CM LCS */
+    Test_ProjPerformPowerOnReset();
+
+    RUNIT_PRINT_DBG("Restarted\n");
+    /* Copy new OTP buffer */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++)
+    {
+        RUNIT_WRITE_OTP(i, otpBuf[i]);
+        RUNIT_PRINT_DBG("0x%02x: 0x%08X\n", i, otpBuf[i]);
+
+        Test_PalDelay(10);
+    }
+
+    /*  Perform SW reset after writing to OTP new values */
+    Test_ProjPerformPowerOnReset();
+    RUNIT_PRINT_DBG("Restarted\n");
+
+    /* verify LCS */
+    rc = runIt_checkLcs(nextLcs);
+    if (rc == RUNIT_ERROR__OK)
+    {
+        RUNIT_PRINT_DBG("OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
+    }
+    else
+    {
+        RUNIT_PRINT_ERROR("Error: Failed to burn OTP!!\n");
+    }
+#endif /* !RUNIT_SECURE_BOOT_SKIP_BURN_OTP */
+    return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_otp.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_otp.h
new file mode 100644
index 0000000..08a6d53
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_otp.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _BSV_INTEGRATION_OTP_H_
+#define _BSV_INTEGRATION_OTP_H_
+
+#include <stdint.h>
+#include "run_integration_test.h"
+#include "test_proj_otp.h"
+
+#define RUNIT_ENV_OTP_START_OFFSET           0x2000UL
+#define RUNIT_TEST_OTP_SIZE_IN_WORDS         0x2C
+#define RUNIT_MAX_OTP_SIZE_IN_WORDS          0x7FF
+
+/**
+ * @brief               Retrieves the current life cycles based on the OTP values.
+ *
+ * @param lcs           [output] the returned LCS.
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_getLcs(unsigned int *lcs);
+
+/**
+ * @brief               Verifies that the current life cycle is lcs
+ *
+ * @param lcs           [input] the life cycle to expect
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_checkLcs(unsigned int lcs);
+
+/**
+ * @brief               Sets the appropriate fields on the OTP buffer to correspond with a specific Kceicv
+ *
+ * @param otp           [output] The OTP image to alter
+ * @param kceicvBuff    [input] the Kceicv to use
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_setKceicvInOtpBuff(unsigned int *otp, unsigned int *kceicvBuff);
+
+/**
+ * @brief               Sets the appropriate fields on the OTP buffer to correspond with a specific Kce
+ *
+ * @param otp           [output] The OTP image to alter
+ * @param kceBuff       [input] the Kce to use
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_setKceInOtpBuff(unsigned int *otp, unsigned int *kceBuff);
+
+/**
+ * @brief               Assign a new Kicv key into opt image. Also adjusts all the needed validation fields.
+ *
+ * @param otp           [ouput] The image to burn to NVM
+ * @param kpicvBuff     [input] New Kicv to use
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_setKpicvInOtpBuff(unsigned int *otp, unsigned int *kpicvBuff);
+
+/**
+ * @brief               Assign a new Kcp key into opt image. Also adjusts all the needed validation fields.
+ *
+ * @param otp           [ouput] The image to burn to NVM
+ * @param kpicvBuff     [input] New Kcp to use
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_setKpcInOtpBuff(unsigned int *otp, unsigned int *kcpBuff);
+
+/**
+ # @brief               Sets the appropriate fields on the OTP buffer to correspond with a specific Hbk
+
+* @param otp            [output] The OTP image to alter
+ * @param hbkBuff       [input] The Hbk to use. 32 bytes of key.
+ *                      in case Hbk0 4 lower words will be used
+ *                      in case Hbk1 4 upper words will be used
+ *                      in case full Hbk all 8 words will be used
+ * @param isFullHbk     [input] Defines in which manner to write the hbkBuff to otp
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_setHbkOtpBuff(uint32_t *otp, uint32_t *hbkBuff, uint8_t isFullHbk);
+
+/**
+ # @brief               Sets the appropriate fields on the OTP buffer to correspond with a specific SW version
+
+* @param otp            [output] The OTP image to alter
+ * @param isFullHbk     [input] Defines in which manner to write the hbkBuff to otp
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_setSwVerInOtpBuff(uint32_t *otp, uint8_t isFullHbk);
+
+/**
+ * @brief               read OTP image
+ *
+ * @param otpBuf        [output] The image read from
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_printOtp(uint32_t otpBuf[TEST_OTP_SIZE_IN_WORDS]);
+
+/**
+ * @brief               Burn the byte array in otpBuf to otp.
+ *                      nextLcs is provided to perform sanity check after burn and powerOnReset.
+ *
+ * @param otpBuf        [input] The image to burn to NVM
+ * @param nextLcs       [input] The expected life cycle after boot
+ *
+ * @return              RUNIT_ERROR__OK on success. RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_burnOtp(unsigned int *otpBuf, unsigned int nextLcs);
+
+
+#endif //_BSV_INTEGRATION_OTP_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_profiler.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_profiler.c
new file mode 100644
index 0000000..e3b3bb3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_profiler.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/************* Include Files ****************/
+
+/* local */
+#include "run_integration_test.h"
+#include "run_integration_profiler.h"
+
+char* runIt_perfTypeStr(runItPerfType_t type, char* pStr, uint32_t buffLen)
+{
+    (void) type;
+    (void) pStr;
+    (void) buffLen;
+    return NULL;
+}
+
+runItPerfType_t runIt_perfTypeFromStr(const char* typeStr, const char* paramStr)
+{
+    (void) typeStr;
+    (void) paramStr;
+    return PERF_TYPE_TEST_NOT_SET;
+}
+/* END - DO NOT CHANGE */
+
+/**
+ * @brief   initialise performance test mechanism
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void runIt_perfInit(void)
+{
+}
+
+/**
+ * @brief   terminates resources used for performance tests
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void runIt_perfFin(void)
+{
+    // nothing to be done
+}
+
+/**
+ * register api to DB
+ *
+ * @param func          address of function
+ * @param name          name of function
+ * @param param         param ti distinguish between flows
+ */
+void runIt_perfEntryInit(const char* name, const char* param, uint8_t isHw)
+{
+    (void) name;
+    (void) param;
+    (void) isHw;
+}
+
+/**
+ * @brief   opens new entry in perf buffer to record new entry
+ *
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+runItPerfData_t runIt_perfOpenNewEntry(runItPerfType_t entryType)
+{
+    (void) entryType;
+
+    return PERF_TYPE_TEST_NOT_SET;
+}
+
+/**
+ * @brief   closes entry in perf buffer previously opened by runIt_perfOpenNewEntry
+ *
+ * @param[in] idx -  index of the entry to be closed, the return value of runIt_perfOpenNewEntry
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return Returns a non-zero value in case of failure
+ */
+void runIt_perfCloseEntry(runItPerfData_t idx, runItPerfType_t entryType)
+{
+    (void) idx;
+    (void) entryType;
+}
+
+/**
+ * @brief   dumps the performance buffer
+ *
+ * @param[in] None
+ *
+ * @return None
+ */
+void runIt_perfDump(void)
+{
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_profiler.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_profiler.h
new file mode 100644
index 0000000..2ec5b3b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_profiler.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _RUN_INTEGRATION_PROFILER_H_
+#define _RUN_INTEGRATION_PROFILER_H_
+
+#include "stdio.h"
+#include "string.h"
+
+/* cc lib */
+#include "cc_pal_types.h"
+#include "cc_pal_perf.h"
+
+/* pal */
+#include "test_pal_mem.h"
+#include "run_integration_pal_log.h"
+
+#define PARAM_LEN                   30
+
+typedef uint64_t runItPerfData_t;
+
+typedef enum runItPerfType_t
+{
+    PERF_TYPE_TEST_NOT_SET,
+
+    TEST_MAX = 256,
+
+    RESERVE32 = 0x7FFFFFFF
+} runItPerfType_t;
+
+/**
+ * @brief   initialise performance test mechanism
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void runIt_perfInit(void);
+
+/**
+ * register api to DB
+ *
+ * @param func          address of function
+ * @param name          name of function
+ * @param param         param ti distinguish between flows
+ */
+void runIt_perfEntryInit(const char* name, const char* param, uint8_t isHw);
+
+/**
+ * @brief   opens new entry in perf buffer to record new entry
+ *
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return A non-zero value in case of failure.
+ */
+runItPerfData_t runIt_perfOpenNewEntry(runItPerfType_t entryType);
+
+
+/**
+ * @brief   closes entry in perf buffer previously opened by runIt_perfOpenNewEntry
+ *
+ * @param[in] idx -  index of the entry to be closed, the return value of runIt_perfOpenNewEntry
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return A non-zero value in case of failure.
+ */
+void runIt_perfCloseEntry(runItPerfData_t idx, runItPerfType_t entryType);
+
+
+/**
+ * @brief   dumps the performance buffer
+ *
+ * @param[in] None
+ *
+ * @return None
+ */
+void runIt_perfDump(void);
+
+
+/**
+ * @brief   terminates resources used for performance tests
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void runIt_perfFin(void);
+
+/**
+ *
+ * @param typeStr
+ * @return
+ */
+runItPerfType_t runIt_perfTypeFromStr(const char* typeStr, const char* paramStr);
+
+/**
+ *
+ * @param func
+ * @param paramStr
+ * @return
+ */
+runItPerfType_t runIt_perfTypeFromFunc(void* func, const char* paramStr);
+
+/**
+ *
+ * @param type
+ * @param pStr
+ * @param buffLen
+ * @return
+ */
+char* runIt_perfTypeStr(runItPerfType_t type, char* pStr, uint32_t buffLen);
+
+#endif //_RUN_INTEGRATION_PROFILER_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.c
new file mode 100644
index 0000000..bdce849
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.c
@@ -0,0 +1,820 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* system includes */
+#include <stdlib.h>
+
+
+/* cerberus pal */
+#include "cc_pal_types.h"
+#include "cc_pal_types_plat.h"
+#include "cc_pal_mem.h"
+#include "cc_pal_perf.h"
+#include "cc_regs.h"
+#include "cc_otp_defs.h"
+#include "cc_lib.h"
+#include "cc_rnd_common.h"
+#include "mbedtls_cc_mng.h"
+
+/* tests pal and hal */
+#include "board_configs.h"
+#include "test_pal_mem.h"
+#include "test_pal_mem_s.h"
+#include "test_pal_thread.h"
+#include "test_pal_log.h"
+#include "test_proj_otp.h"
+
+/* mbedtls */
+#include "mbedtls/memory_buffer_alloc.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+
+/* internal files */
+#include "run_integration_test.h"
+#include "run_integration_test_api.h"
+#include "run_integration_helper.h"
+#include "run_integration_pal_log.h"
+#include "run_integration_pal_otp.h"
+#include "run_integration_pal_reg.h"
+#include "run_integration_profiler.h"
+#include "run_integration_flash.h"
+#include "run_integration_otp.h"
+
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define RUNIT_FLASH_SIZE                        0x10000
+#define RUNIT_TEST_NAME_LENGTH                  50
+#define RUNIT_PTHREAD_STACK_MIN                 16384
+#define RUNIT_MBEDTLS_HEAP_MIN                  1024*512
+
+#ifndef RUNIT_TEST_ITER_MAX
+#define RUNIT_TEST_ITER_MAX 1
+#endif
+
+/************************************************************
+ *
+ * macros
+ *
+ ************************************************************/
+typedef struct ImpCong_t
+{
+    uint8_t md2_process;
+    uint8_t md4_process;
+    uint8_t md5_process;
+    uint8_t ripemd160_process;
+    uint8_t sha1_process;
+    uint8_t sha256_process;
+    uint8_t sha512_process;
+    uint8_t des_setkey;
+    uint8_t des_crypt;
+    uint8_t des3_crypt;
+    uint8_t aes_setkey;
+    uint8_t aes_setkey_dec;
+    uint8_t aes_encrypt;
+    uint8_t aes_decrypt;
+    uint8_t aes;
+    uint8_t ccm;
+    uint8_t gcm;
+    uint8_t sha1;
+    uint8_t sha256;
+    uint8_t sha512;
+    uint8_t rsa;
+    uint8_t dhm;
+    uint8_t ecc;
+    uint8_t ecp;
+    uint8_t entropy_hardware;
+    uint8_t pk_rsa_alt;
+    uint8_t cmac;
+    uint8_t mbedtls_ecdh_gen_public_alt;
+    uint8_t mbedtls_ecdh_compute_shared_alt;
+    uint8_t mbedtls_ecdsa_verify_alt;
+    uint8_t mbedtls_ecdsa_sign_alt;
+    uint8_t mbedtls_ecdsa_genkey_alt;
+} ImpCong_t;
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static void runIt_finish(void);
+static RunItError_t runIt_init(void);
+static void* runIt_executer(void *params);
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+/* pass result between executer and main thread */
+RunItError_t g_runIt_executerRc = RUNIT_ERROR__FAIL;
+
+/* ptr to the heap managed by the mbedtls library. to be freed at a later point */
+uint8_t* gRunIt_mbedtlsHeap_ptr = NULL;
+
+/* RndContext and RndState to be used by the tests */
+CCRndContext_t* gpRndContext = NULL;
+mbedtls_ctr_drbg_context* gpRndState = NULL;
+
+/* RunItPtr to be freed at a later point */
+RunItPtr gRunIt_rndContext_ptr;
+RunItPtr gRunIt_rndWorkBuff_ptr;
+RunItPtr gRunIt_rndState_ptr;
+RunItPtr gRunIt_entropy_ptr;
+
+/* for debugging */
+uint32_t gRunItStackSize = 0;
+uint8_t gRunItPrintEnable = 1;
+ImpCong_t gCompConf = { 0 };
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static void runIt_finish(void)
+{
+    runIt_perfFin();
+
+    CC_LibFini((CCRndContext_t *)GET_PTR(gRunIt_rndContext_ptr));
+
+    FREE_IF_NOT_NULL(gRunIt_rndContext_ptr);
+    FREE_IF_NOT_NULL(gRunIt_rndWorkBuff_ptr);
+    FREE_IF_NOT_NULL(gRunIt_rndState_ptr);
+    FREE_IF_NOT_NULL(gRunIt_entropy_ptr);
+
+    RUNIT_TEST_PAL_FREE(gRunIt_mbedtlsHeap_ptr);
+}
+
+static RunItError_t runIt_init(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    uint32_t* mbedtlsHeapAligned = NULL;
+
+    RunItPtr rndContext;
+    RunItPtr rndWorkBuff;
+    RunItPtr rndState;
+    RunItPtr mbedtlsEntropy;
+
+    CCRndContext_t* pRndContex = NULL;
+    CCRndWorkBuff_t* pRndWorkBuff = NULL;
+    mbedtls_ctr_drbg_context* pRndState = NULL;
+    mbedtls_entropy_context* pMbedtlsEntropy = NULL;
+
+    /* initilaise mbedtls heap manager */
+    ALLOC_BUFF_ALIGN32(gRunIt_mbedtlsHeap_ptr, mbedtlsHeapAligned, RUNIT_MBEDTLS_HEAP_MIN);
+    mbedtls_memory_buffer_alloc_init((uint8_t*)mbedtlsHeapAligned, RUNIT_MBEDTLS_HEAP_MIN);
+
+    /* use global ptr to be able to free them on exit */
+    ALLOC_STRUCT(CCRndContext_t, rndContext, pRndContex);
+    ALLOC_STRUCT(CCRndWorkBuff_t, rndWorkBuff, pRndWorkBuff);
+    ALLOC_STRUCT(mbedtls_ctr_drbg_context, rndState, pRndState);
+    ALLOC_STRUCT(mbedtls_entropy_context, mbedtlsEntropy, pMbedtlsEntropy);
+
+    /* init Rnd context's inner member */
+    pRndContex->rndState = pRndState;
+    pRndContex->entropyCtx = pMbedtlsEntropy;
+
+    /* save pointers staticaly to free them at a  later point */
+    gRunIt_rndContext_ptr = rndContext;
+    gRunIt_rndWorkBuff_ptr = rndWorkBuff;
+    gRunIt_rndState_ptr = rndState;
+    gRunIt_entropy_ptr = mbedtlsEntropy;
+
+    /* set global vars */
+    gpRndContext = pRndContex;
+    gpRndState = pRndState;
+
+
+    /* initialise CC library */
+    RUNIT_ASSERT(CC_LibInit(pRndContex, pRndWorkBuff) == CC_LIB_RET_OK);
+
+    return RUNIT_ERROR__OK;
+
+bail:
+    runIt_finish();
+
+    return rc;
+
+}
+
+static void runIt_printMbedtlsAltConfig(void)
+{
+    static const char* SOFTWARE = "software";
+    static const char* HARDWARE = "hardware";
+    static const char* MBEDTLS_CONFIG_FORMAT = "%-40.40s %-10.10s\n";
+    static const char* DASH = "----------------------------------------------------------------------------------";
+
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "define", "state");
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, DASH, DASH);
+
+    (void)HARDWARE;
+    (void)SOFTWARE;
+
+#if defined(MBEDTLS_MD2_PROCESS_ALT)
+    gCompConf.md2_process = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_MD2_PROCESS_ALT", HARDWARE);
+#else
+    gCompConf.md2_process = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_MD2_PROCESS_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_MD4_PROCESS_ALT)
+    gCompConf.md4_process = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_MD4_PROCESS_ALT", HARDWARE);
+#else
+    gCompConf.md4_process = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_MD4_PROCESS_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_MD5_PROCESS_ALT)
+    gCompConf.md5_process = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_MD5_PROCESS_ALT", HARDWARE);
+#else
+    gCompConf.md5_process = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_MD5_PROCESS_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_RIPEMD160_PROCESS_ALT)
+    gCompConf.ripemd160_process = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_RIPEMD160_PROCESS_ALT", HARDWARE);
+#else
+    gCompConf.ripemd160_process = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_RIPEMD160_PROCESS_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_SHA1_PROCESS_ALT)
+    gCompConf.sha1_process = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA1_PROCESS_ALT", HARDWARE);
+#else
+    gCompConf.sha1_process = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA1_PROCESS_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_SHA256_PROCESS_ALT)
+    gCompConf.sha256_process = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA256_PROCESS_ALT", HARDWARE);
+#else
+    gCompConf.sha256_process = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA256_PROCESS_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_SHA512_PROCESS_ALT)
+    gCompConf.sha512_process = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA512_PROCESS_ALT", HARDWARE);
+#else
+    gCompConf.sha512_process = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA512_PROCESS_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_DES_SETKEY_ALT)
+    gCompConf.des_setkey = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DES_SETKEY_ALT", HARDWARE);
+#else
+    gCompConf.des_setkey = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DES_SETKEY_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_DES_CRYPT_ECB_ALT)
+    gCompConf.des_crypt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DES_CRYPT_ECB_ALT", HARDWARE);
+#else
+    gCompConf.des_crypt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DES_CRYPT_ECB_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_DES3_CRYPT_ECB_ALT)
+    gCompConf.des3_crypt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DES3_CRYPT_ECB_ALT", HARDWARE);
+#else
+    gCompConf.des3_crypt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DES3_CRYPT_ECB_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_AES_SETKEY_ENC_ALT)
+    gCompConf.des_setkey = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_SETKEY_ENC_ALT", HARDWARE);
+#else
+    gCompConf.des_setkey = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_SETKEY_ENC_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_AES_SETKEY_DEC_ALT)
+    gCompConf.aes_setkey = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_SETKEY_DEC_ALT", HARDWARE);
+#else
+    gCompConf.aes_setkey = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_SETKEY_DEC_ALT", SOFTWARE);
+#endif
+
+
+#if defined(MBEDTLS_AES_ENCRYPT_ALT)
+    gCompConf.aes_encrypt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_ENCRYPT_ALT", HARDWARE);
+#else
+    gCompConf.aes_encrypt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_ENCRYPT_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_AES_DECRYPT_ALT)
+    gCompConf.aes_decrypt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_DECRYPT_ALT", HARDWARE);
+#else
+    gCompConf.aes_decrypt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_DECRYPT_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_AES_ALT)
+    gCompConf.aes = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_ALT", HARDWARE);
+#else
+    gCompConf.aes = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_AES_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_CCM_ALT)
+    gCompConf.ccm = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_CCM_ALT", HARDWARE);
+#else
+    gCompConf.ccm = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_CCM_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_GCM_ALT)
+    gCompConf.gcm = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_GCM_ALT", HARDWARE);
+#else
+    gCompConf.gcm = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_GCM_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_SHA1_ALT)
+    gCompConf.sha1 = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA1_ALT", HARDWARE);
+#else
+    gCompConf.sha1 = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA1_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_SHA256_ALT)
+    gCompConf.sha256 = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA256_ALT", HARDWARE);
+#else
+    gCompConf.sha256 = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA256_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_SHA512_ALT)
+    gCompConf.sha512 = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA512_ALT", HARDWARE);
+#else
+    gCompConf.sha512 = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_SHA512_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_RSA_ALT)
+    gCompConf.rsa = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_RSA_ALT", HARDWARE);
+#else
+    gCompConf.rsa = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_RSA_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_DHM_ALT)
+    gCompConf.dhm = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DHM_ALT", HARDWARE);
+#else
+    gCompConf.dhm = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_DHM_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ECC_ALT)
+    gCompConf.ecc = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECC_ALT", HARDWARE);
+#else
+    gCompConf.ecc = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECC_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ECP_ALT)
+    gCompConf.ecp = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECP_ALT", HARDWARE);
+#else
+    gCompConf.ecp = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECP_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT)
+    gCompConf.entropy_hardware = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ENTROPY_HARDWARE_ALT", HARDWARE);
+#else
+    gCompConf.entropy_hardware = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ENTROPY_HARDWARE_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT)
+    gCompConf.pk_rsa_alt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_PK_RSA_ALT_SUPPORT", HARDWARE);
+#else
+    gCompConf.pk_rsa_alt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_PK_RSA_ALT_SUPPORT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_CMAC_ALT)
+    gCompConf.cmac = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_CMAC_ALT", HARDWARE);
+#else
+    gCompConf.cmac = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_CMAC_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT)
+    gCompConf.mbedtls_ecdh_gen_public_alt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDH_GEN_PUBLIC_ALT", HARDWARE);
+#else
+    gCompConf.mbedtls_ecdh_gen_public_alt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDH_GEN_PUBLIC_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
+    gCompConf.mbedtls_ecdh_compute_shared_alt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDH_COMPUTE_SHARED_ALT", HARDWARE);
+#else
+    gCompConf.mbedtls_ecdh_compute_shared_alt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDH_COMPUTE_SHARED_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ECDSA_VERIFY_ALT)
+    gCompConf.mbedtls_ecdsa_verify_alt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDSA_VERIFY_ALT", HARDWARE);
+#else
+    gCompConf.mbedtls_ecdsa_verify_alt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDSA_VERIFY_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ECDSA_SIGN_ALT)
+    gCompConf.mbedtls_ecdsa_sign_alt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDSA_SIGN_ALT", HARDWARE);
+#else
+    gCompConf.mbedtls_ecdsa_sign_alt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDSA_SIGN_ALT", SOFTWARE);
+#endif
+
+#if defined(MBEDTLS_ECDSA_GENKEY_ALT)
+    gCompConf.mbedtls_ecdsa_genkey_alt = 1;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDSA_GENKEY_ALT", HARDWARE);
+#else
+    gCompConf.mbedtls_ecdsa_genkey_alt = 0;
+    RUNIT_PRINT(MBEDTLS_CONFIG_FORMAT, "MBEDTLS_ECDSA_GENKEY_ALT", SOFTWARE);
+#endif
+
+}
+
+static void runIt_regApi(void)
+{
+    RUNIT_PERF_REG_API(mbedtls_aes_crypt_cbc                              , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_crypt_cfb128                           , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_crypt_cfb8                             , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_crypt_ctr                              , gCompConf.aes);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_aes_crypt_ctr, "16B"               , gCompConf.aes);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_aes_crypt_ctr, "128B"              , gCompConf.aes);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_aes_crypt_ctr, "1024B"             , gCompConf.aes);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_aes_crypt_ctr, "8192B"             , gCompConf.aes);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_aes_crypt_ctr, "65535B"            , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_crypt_ecb                              , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_crypt_ofb                              , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_ext_dma_init                           , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_ext_dma_set_key                        , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_ext_dma_set_iv                         , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_ext_dma_finish                         , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_free                                   , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_init                                   , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_key_wrap                               , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_key_unwrap                             , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_setkey_dec                             , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_aes_setkey_enc                             , gCompConf.aes);
+    RUNIT_PERF_REG_API(mbedtls_ccm_init                                   , gCompConf.ccm);
+    RUNIT_PERF_REG_API(mbedtls_ccm_setkey                                 , gCompConf.ccm);
+    RUNIT_PERF_REG_API(mbedtls_ccm_encrypt_and_tag                        , gCompConf.ccm);
+    RUNIT_PERF_REG_API(mbedtls_ccm_auth_decrypt                           , gCompConf.ccm);
+    RUNIT_PERF_REG_API(mbedtls_ccm_free                                   , gCompConf.ccm);
+    RUNIT_PERF_REG_API(mbedtls_ccm_star_nonce_generate                    , 1);
+    RUNIT_PERF_REG_API(mbedtls_ccm_star_encrypt_and_tag                   , 1);
+    RUNIT_PERF_REG_API(mbedtls_ccm_star_auth_decrypt                      , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chacha, "encrypt"                  , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chacha, "decrypt"                  , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha_init                                , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha_finish                              , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha_free                                , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chacha_poly, "encrypt"             , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chacha_poly, "decrypt"             , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chacha20_crypt, "encrypt"          , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha20_init                              , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha20_free                              , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha20_setkey                            , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha20_starts                            , 1);
+    RUNIT_PERF_REG_API(mbedtls_chacha20_update                            , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chachapoly_auth_decrypt, "decrypt" , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chachapoly_encrypt_and_tag, "encrypt" , 1);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_chachapoly_encrypt_and_tag, "decrypt" , 1);
+    RUNIT_PERF_REG_API(mbedtls_chachapoly_init                            , 1);
+    RUNIT_PERF_REG_API(mbedtls_chachapoly_free                            , 1);
+    RUNIT_PERF_REG_API(mbedtls_chachapoly_setkey                          , 1);
+    RUNIT_PERF_REG_API(mbedtls_cipher_cmac_finish                         , gCompConf.cmac);
+    RUNIT_PERF_REG_API(mbedtls_cipher_cmac_starts                         , gCompConf.cmac);
+    RUNIT_PERF_REG_API(mbedtls_cipher_cmac_update                         , gCompConf.cmac);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_cipher_cmac_update, "16B"          , gCompConf.cmac);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_cipher_cmac_update, "128B"         , gCompConf.cmac);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_cipher_cmac_update, "1024B"        , gCompConf.cmac);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_cipher_cmac_update, "8192B"        , gCompConf.cmac);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_cipher_cmac_update, "65535B"       , gCompConf.cmac);
+    RUNIT_PERF_REG_API(mbedtls_cipher_cmac_reset                          , gCompConf.cmac);
+    RUNIT_PERF_REG_API(mbedtls_cipher_cmac                                , gCompConf.cmac);
+    RUNIT_PERF_REG_API(mbedtls_cipher_free                                , 0);
+    RUNIT_PERF_REG_API(mbedtls_cipher_info_from_type                      , 0);
+    RUNIT_PERF_REG_API(mbedtls_cipher_init                                , 0);
+    RUNIT_PERF_REG_API(mbedtls_cipher_setup                               , 0);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_free                              , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_init                              , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_random                            , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_random_with_add                   , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_reseed                            , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_seed                              , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_seed_entropy_len                  , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_set_entropy_len                   , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_set_prediction_resistance         , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_set_reseed_interval               , 1);
+    RUNIT_PERF_REG_API(mbedtls_ctr_drbg_update                            , 1);
+    RUNIT_PERF_REG_API(mbedtls_dhm_calc_secret                            , gCompConf.dhm);
+    RUNIT_PERF_REG_API(mbedtls_dhm_free                                   , gCompConf.dhm);
+    RUNIT_PERF_REG_API(mbedtls_dhm_init                                   , gCompConf.dhm);
+    RUNIT_PERF_REG_API(mbedtls_dhm_make_params                            , gCompConf.dhm);
+    RUNIT_PERF_REG_API(mbedtls_dhm_make_public                            , gCompConf.dhm);
+    RUNIT_PERF_REG_API(mbedtls_dhm_read_params                            , gCompConf.dhm);
+    RUNIT_PERF_REG_API(mbedtls_dhm_read_public                            , gCompConf.dhm);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_calc_secret                           , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_compute_shared                        , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_free                                  , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_gen_public                            , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_init                                  , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_make_params                           , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_make_public                           , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_read_params                           , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_read_public                           , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_read_params_edwards                   , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdh_make_params_edwards                   , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_free                                 , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_genkey                               , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_genkey_edwards                       , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_init                                 , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_read_signature                       , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_sign                                 , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_sign_det                             , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_sign_edwards                         , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_verify                               , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_verify_edwards                       , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecdsa_write_signature                      , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecies_kem_encrypt                          , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecies_kem_encrypt_full                     , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_ecies_kem_decrypt                          , gCompConf.ecc);
+    RUNIT_PERF_REG_API(mbedtls_entropy_init                               , 0);
+    RUNIT_PERF_REG_API(mbedtls_gcm_auth_decrypt                           , gCompConf.gcm);
+    RUNIT_PERF_REG_API(mbedtls_gcm_crypt_and_tag                          , gCompConf.gcm);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_gcm_crypt_and_tag, "encrypt"       , gCompConf.gcm);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_gcm_crypt_and_tag, "decrypt"       , gCompConf.gcm);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_gcm_crypt_and_tag, "16B"           , gCompConf.gcm);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_gcm_crypt_and_tag, "128B"          , gCompConf.gcm);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_gcm_crypt_and_tag, "1024B"         , gCompConf.gcm);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_gcm_crypt_and_tag, "8192B"         , gCompConf.gcm);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_gcm_crypt_and_tag, "65534B"        , gCompConf.gcm);
+    RUNIT_PERF_REG_API(mbedtls_gcm_free                                   , gCompConf.gcm);
+    RUNIT_PERF_REG_API(mbedtls_gcm_init                                   , gCompConf.gcm);
+    RUNIT_PERF_REG_API(mbedtls_gcm_setkey                                 , gCompConf.gcm);
+    RUNIT_PERF_REG_API(mbedtls_hkdf                                       , 1);
+    RUNIT_PERF_REG_API(mbedtls_hkdf_key_derivation                        , 1);
+    RUNIT_PERF_REG_API(mbedtls_md                                         , 0);
+    RUNIT_PERF_REG_API(mbedtls_md_hmac                                    , 0);
+    RUNIT_PERF_REG_API(mbedtls_md_hmac_finish                             , 0);
+    RUNIT_PERF_REG_API(mbedtls_md_hmac_starts                             , 0);
+    RUNIT_PERF_REG_API(mbedtls_md_hmac_update                             , 0);
+    RUNIT_PERF_REG_API(mbedtls_md_info_from_string                        , 0);
+    RUNIT_PERF_REG_API(mbedtls_md_init                                    , 0);
+    RUNIT_PERF_REG_API(mbedtls_md_setup                                   , 0);
+    RUNIT_PERF_REG_API(mbedtls_poly                                       , 1);
+    RUNIT_PERF_REG_API(mbedtls_poly1305_mac                               , 1);
+    RUNIT_PERF_REG_API(mbedtls_rsa_check_privkey                          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_check_privkey, "2048"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_check_privkey, "3072"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_check_privkey, "4096"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_check_pubkey                           , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_check_pubkey, "2048"           , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_check_pubkey, "3072"           , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_check_pubkey, "4096"           , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_check_pub_priv                         , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_complete                               , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_copy                                   , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_copy, "2048"                   , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_copy, "3072"                   , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_copy, "4096"                   , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_free                                   , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_gen_key                                , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_init                                   , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_decrypt, "2048"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_decrypt, "3072"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_decrypt, "4096"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_encrypt, "2048"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_encrypt, "3072"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_encrypt, "4096"          , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_sign, "2048"             , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_sign, "3072"             , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_sign, "4096"             , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_verify, "2048"           , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_verify, "3072"           , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_pkcs1_verify, "4096"           , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_private                                , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_private, "2048"                , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_private, "3072"                , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_private, "4096"                , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_rsa_public                                 , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_public, "2048"                 , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_public, "3072"                 , gCompConf.rsa);
+    RUNIT_PERF_REG_API_W_PARAM(mbedtls_rsa_public, "4096"                 , gCompConf.rsa);
+    RUNIT_PERF_REG_API(mbedtls_sb_cert_chain_cerification_init            , 1);
+    RUNIT_PERF_REG_API(mbedtls_sb_cert_verify_single                      , 1);
+    RUNIT_PERF_REG_API(mbedtls_sb_sw_image_store_address_change           , 1);
+    RUNIT_PERF_REG_API(mbedtls_sha1                                       , gCompConf.sha1);
+    RUNIT_PERF_REG_API(mbedtls_sha1_clone                                 , gCompConf.sha1);
+    RUNIT_PERF_REG_API(mbedtls_sha1_finish_ret                            , gCompConf.sha1);
+    RUNIT_PERF_REG_API(mbedtls_sha1_free                                  , gCompConf.sha1);
+    RUNIT_PERF_REG_API(mbedtls_sha1_init                                  , gCompConf.sha1);
+    RUNIT_PERF_REG_API(mbedtls_sha1_starts_ret                            , gCompConf.sha1);
+    RUNIT_PERF_REG_API(mbedtls_sha1_update_ret                            , gCompConf.sha1);
+    RUNIT_PERF_REG_API(mbedtls_sha256                                     , gCompConf.sha256);
+    RUNIT_PERF_REG_API(mbedtls_sha256_clone                               , gCompConf.sha256);
+    RUNIT_PERF_REG_API(mbedtls_sha256_finish_ret                          , gCompConf.sha256);
+    RUNIT_PERF_REG_API(mbedtls_sha256_free                                , gCompConf.sha256);
+    RUNIT_PERF_REG_API(mbedtls_sha256_init                                , gCompConf.sha256);
+    RUNIT_PERF_REG_API(mbedtls_sha256_starts_ret                          , gCompConf.sha256);
+    RUNIT_PERF_REG_API(mbedtls_sha256_update_ret                          , gCompConf.sha256);
+    RUNIT_PERF_REG_API(mbedtls_sha512                                     , gCompConf.sha512);
+    RUNIT_PERF_REG_API(mbedtls_sha512_clone                               , gCompConf.sha512);
+    RUNIT_PERF_REG_API(mbedtls_sha512_finish                              , gCompConf.sha512);
+    RUNIT_PERF_REG_API(mbedtls_sha512_free                                , gCompConf.sha512);
+    RUNIT_PERF_REG_API(mbedtls_sha512_init                                , gCompConf.sha512);
+    RUNIT_PERF_REG_API(mbedtls_sha512_starts                              , gCompConf.sha512);
+    RUNIT_PERF_REG_API(mbedtls_sha512_update                              , gCompConf.sha512);
+    RUNIT_PERF_REG_API(mbedtls_srp_init                                   , 1);
+    RUNIT_PERF_REG_API(mbedtls_srp_pwd_ver_create                         , 1);
+    RUNIT_PERF_REG_API(mbedtls_srp_host_pub_key_create                    , 1);
+    RUNIT_PERF_REG_API(mbedtls_srp_user_proof_calc                        , 1);
+    RUNIT_PERF_REG_API(mbedtls_srp_user_pub_key_create                    , 1);
+    RUNIT_PERF_REG_API(mbedtls_srp_host_proof_verify_and_calc             , 1);
+    RUNIT_PERF_REG_API(mbedtls_srp_user_proof_verify                      , 1);
+    RUNIT_PERF_REG_API(mbedtls_util_asset_pkg_unpack                      , 1);
+    RUNIT_PERF_REG_API(mbedtls_util_key_derivation_cmac                   , 1);
+    RUNIT_PERF_REG_API(mbedtls_util_key_derivation_hmac                   , 1);
+}
+/**
+ * @brief               Executor function. Called from a side thread to perform the sequence of tests.
+ * @note                This is a workaround the issue that CC API requires DMA-able stack.
+ *                      When using Test_PalThreadCreate we are able to ensure that the stack is DMA-able.
+ * @param params        Not used
+ */
+static void* runIt_executer(void *params)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    const char* TEST_NAME = "All Tests";
+    uint32_t testIter = 0;
+
+    CC_UNUSED_PARAM(params);
+
+    RUNIT_PRINT("cc312 runtime integration test\n");
+    RUNIT_PRINT("---------------------------------------------------------------\n");
+
+    /* Initialise runtime integration perf engine */
+    runIt_perfInit();
+
+    runIt_printMbedtlsAltConfig();
+
+    RUNIT_PRINT_HEADER();
+
+    gRunItPrintEnable = 1;
+
+    runIt_regApi();
+
+    for (testIter = 1; testIter <= RUNIT_TEST_ITER_MAX; ++testIter)
+    {
+
+        RUNIT_TEST_START(TEST_NAME);
+
+        /* Init libraries */
+        RUNIT_ASSERT(runIt_init() == RUNIT_ERROR__OK);
+
+#if !defined(RUNIT_PIE_ENABLED)
+        rc += runIt_aesTest();
+        rc += runIt_srpTest();
+        rc += runIt_shaTest();
+        rc += runIt_ccmTest();
+        rc += runIt_gcmTest();
+        rc += runIt_rsaTest();
+        rc += runIt_ecdsaTest();
+        rc += runIt_ecdhTest();
+        rc += runIt_eciesTest();
+        rc += runIt_ctrDrbgTest();
+        rc += runIt_ChachaTest();
+        rc += runIt_macTest();
+        rc += runIt_dhmTest();
+        rc += runIt_extDmaTest();
+#endif /* RUNIT_PIE_ENABLED */
+
+        rc += runIt_keyDerivationTest();
+        rc += runIt_assetProvTest();
+        rc += runIt_secureBootTest();
+
+        g_runIt_executerRc = rc;
+
+        RUNIT_TEST_RESULT(TEST_NAME);
+
+        /* continue to next test only if all passed */
+        RUNIT_ASSERT(rc == RUNIT_ERROR__OK);
+
+        /* disable printing of next tests */
+        gRunItPrintEnable = 0;
+
+        /* indicate progress */
+        RUNIT_PRINT("Test %u/%u completed\n", (unsigned int)testIter, RUNIT_TEST_ITER_MAX);
+
+        runIt_finish();
+    }
+
+bail:
+    runIt_perfDump();
+    CC_PAL_PERF_DUMP();
+
+    return NULL;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_all(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    ThreadHandle threadHandle = NULL;
+    const char* TASK_NAME = "runIt_executer";
+    uint32_t priotity = Test_PalGetDefaultPriority();
+
+    /* init platform and map memory */
+    RUNIT_ASSERT(Test_ProjInit() == 0);
+
+    RUNIT_PRINT("FPGA version: 0x%08"PRIx32"\n", TEST_READ_TEE_ENV_REG(DX_ENV_VERSION_REG_OFFSET));
+
+    gRunItStackSize = RUNIT_PTHREAD_STACK_MIN;
+
+    /* Create a task that will allocate a DMA -able stack */
+    threadHandle = Test_PalThreadCreate(RUNIT_PTHREAD_STACK_MIN,
+                                        runIt_executer,
+                                        priotity,
+                                        NULL,
+                                        (char*) TASK_NAME,
+                                        sizeof(TASK_NAME),
+                                        true);
+
+    /* Verify task was created successfully */
+    RUNIT_ASSERT(threadHandle != NULL);
+
+    /* Wait for task to complete */
+    Test_PalThreadJoin(threadHandle, NULL);
+
+    /* Finalize task's resources */
+    Test_PalThreadDestroy(threadHandle);
+
+    /* Read result code */
+    rc = g_runIt_executerRc;
+
+bail:
+    /* Free platform */
+    Test_ProjFree();
+
+    return rc;
+}
+
+#if defined(DX_PLAT_ZYNQ7000)
+int main(int argc, char** argv)
+{
+    ((void)argc);
+    ((void)argv);
+
+    runIt_all();
+
+    return 0;
+}
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.h
new file mode 100644
index 0000000..c79548d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _RUN_INTEGRATION_TEST_H_
+#define _RUN_INTEGRATION_TEST_H_
+
+/************************************************************
+ *
+ * type decelerations
+ *
+ ************************************************************/
+/**
+ * Error Codes
+ */
+typedef enum RunItError_t
+{
+    RUNIT_ERROR__OK = 0,
+    RUNIT_ERROR__FAIL = 0x0000FFFF,
+}RunItError_t;
+
+/************************************************************
+ *
+ * externs
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * function prototypes
+ *
+ ************************************************************/
+
+/**
+ * @brief               Call to perform all tests
+ *                      Performs:
+ *
+ * @return              RUNIT_ERROR__OK on success, RUNIT_ERROR__FAIL otherwise
+ */
+RunItError_t runIt_all(void);
+
+#endif //_RUN_INTEGRATION_TEST_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.mk b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.mk
new file mode 100644
index 0000000..5157ddf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test.mk
@@ -0,0 +1,141 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+include ../proj_integration_tests.cfg
+include $(HOST_PROJ_ROOT)/Makefile.test_suite
+include $(HOST_PROJ_ROOT)/../proj.ext.cfg
+
+MBEDTLS_ROOT = $(HOST_SRCDIR)/../../mbedtls
+
+ifneq ($(TEE_OS),linux)
+TARGET_LIBS = run_integration_test
+else
+TARGET_EXES = run_integration_test
+LIBDIRS += $(MBEDTLS_ROOT)/library
+DEPLIBS = mbedcrypto
+DEPLIBS += cc_312 pal_$(TEE_OS)
+DEPLIBS += $(TEST_AL_LITE_LIBS)
+endif
+
+# Unit test dependencies
+SOURCES_run_integration_test = run_integration_test.c
+SOURCES_run_integration_test += run_integration_helper.c
+SOURCES_run_integration_test += run_integration_flash.c
+SOURCES_run_integration_test += run_integration_otp.c
+SOURCES_run_integration_test += run_integration_aes.c
+SOURCES_run_integration_test += run_integration_asset_prov.c
+SOURCES_run_integration_test += run_integration_sha.c
+SOURCES_run_integration_test += run_integration_ccm.c
+SOURCES_run_integration_test += run_integration_gcm.c
+SOURCES_run_integration_test += run_integration_ecdsa.c
+SOURCES_run_integration_test += run_integration_ecies.c
+SOURCES_run_integration_test += run_integration_ecdh.c
+SOURCES_run_integration_test += run_integration_rsa.c
+SOURCES_run_integration_test += run_integration_drbg.c
+SOURCES_run_integration_test += run_integration_key_derivation.c
+SOURCES_run_integration_test += run_integration_chacha.c
+SOURCES_run_integration_test += run_integration_srp.c
+SOURCES_run_integration_test += run_integration_mac.c
+SOURCES_run_integration_test += run_integration_dhm.c
+SOURCES_run_integration_test += run_integration_ext_dma.c
+SOURCES_run_integration_test += run_integration_test_arm.c
+SOURCES_run_integration_test += run_integration_secure_boot.c
+SOURCES_run_integration_test += $(PROJ_SOURCES)
+
+ifeq ($(TEE_OS),freertos)
+ifeq ($(ARM_INTERNAL),1)
+SOURCES_run_integration_test += run_integration_profiler_arm.c
+else
+SOURCES_run_integration_test += run_integration_profiler.c
+endif
+else # linux
+SOURCES_run_integration_test += run_integration_profiler.c
+endif
+
+TEST_INCLUDES += $(CURDIR)/run_integration_test.h
+
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal/$(TEE_OS)
+INCDIRS_EXTRA += $(SHARED_INCDIR)/pal/$(TEE_OS)/include
+
+INCDIRS_EXTRA += $(HOST_PROJ_ROOT)/include
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal
+INCDIRS_EXTRA += $(HOST_SRCDIR)/hal/$(TEST_PRODUCT)
+
+INCDIRS_EXTRA += $(CURDIR)/tests
+INCDIRS_EXTRA += $(CURDIR)/pal/include
+INCDIRS_EXTRA += $(CURDIR)/pal/$(TEE_OS)
+
+INCDIRS_EXTRA += $(PROJ_INCLUDE)
+INCDIRS_EXTRA += $(TEST_AL_INCLUDE)
+
+INCDIRS_EXTRA += $(CODESAFE_SRCDIR)/crypto_api/common #due to usage of inverse functions in test
+INCDIRS_EXTRA += $(SHARED_DIR)/hw/include
+INCDIRS_EXTRA += $(HOST_PROJ_ROOT)/../mbedtls/include
+
+
+ifeq ($(TEE_OS), freertos)
+include  $(HOST_SRCDIR)/../Makefile.freertos
+endif
+
+ifeq ($(LIB_PERF),1)
+CFLAGS += -DLIB_PERF
+endif
+
+ifeq ($(PIE),1)
+CFLAGS += -DRUNIT_PIE_ENABLED
+endif
+
+ifeq ($(ARM_CPU),cortex-m33)
+# needed to identify in code which FPGA we are working with.
+# although the cortex should not matter the memory layout should.
+# for example the unmanaged memory address is different -> the certificates are different
+CFLAGS += -DCORTEX_M33_FPGA
+endif
+
+ifeq ($(TEST_DEBUG),1)
+CFLAGS_EXTRA += -DTEST_DEBUG=1# use to toggle debug
+endif
+
+ifeq ($(CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES),)
+CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES = 8192
+endif
+
+ifeq ($(CC_CONFIG_SB_X509_CERT_SUPPORTED),1)
+CFLAGS_EXTRA += -DCC_SB_X509_CERT_SUPPORTED
+endif
+
+ifeq ($(CC_CONFIG_CC_CHACHA_POLY_SUPPORT),1)
+CFLAGS_EXTRA += -DCC_CONFIG_CC_CHACHA_POLY_SUPPORT
+endif
+
+ifeq ($(CC_CONFIG_SUPPORT_SRP),1)
+CFLAGS_EXTRA += -DCC_CONFIG_SUPPORT_SRP
+endif
+
+
+ifneq ($(RUNIT_TEST_ITER_MAX),)
+ifeq ($(TEE_OS),freertos)
+ifeq ($(ARM_INTERNAL),1)
+CFLAGS_EXTRA+=-DRUNIT_TEST_ITER_MAX=$(RUNIT_TEST_ITER_MAX)
+endif
+endif
+endif
+
+ifeq ($(CC_CONFIG_SUPPORT_EXT_DMA),1)
+CFLAGS_EXTRA += -DCC_CONFIG_SUPPORT_EXT_DMA=1
+endif
+
+CFLAGS_EXTRA += -DCC_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES=$(CC_CONFIG_SB_DOUBLE_BUFFER_MAX_SIZE_IN_BYTES)
+CFLAGS_EXTRA += -DCC_TEE
+
+VPATH += $(CURDIR)/pal/$(TEE_OS)
+VPATH += $(CURDIR)/tests
+VPATH += $(CURDIR)/hal/$(TEST_PRODUCT)
+VPATH += $(PROJ_VPATH)
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test_arm.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test_arm.c
new file mode 100644
index 0000000..5e46d3d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/run_integration_test_arm.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "stdlib.h"
+#include "stdint.h"
+#include <string.h>
+
+#include "cc_pal_types.h"
+#include "test_pal_cli.h"
+#include "dx_reg_base_host.h"
+
+#include "run_integration_test.h"
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static int runIt_cliCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+/**
+ * @brief A wrapper function for the "all" command
+ */
+static int runIt_cliCommand(char *pcWriteBuffer, size_t xWriteBufferLen, const char *pcCommandString)
+{
+    CC_UNUSED_PARAM(pcWriteBuffer);
+    CC_UNUSED_PARAM(xWriteBufferLen);
+    CC_UNUSED_PARAM(pcCommandString);
+
+    runIt_all();
+
+    return 0;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+/**
+ * This function will be called by freertos before the scheduler starts running.
+ * it's main responsibility is to register the test to the cli interface.
+ *
+ * @return    0 on success
+ */
+int librun_integration_test_initLib(void)
+{
+    int rc = 0;
+
+    static struct Test_PalCliCommand cmdAll =
+    {
+        "integ-all",
+        "\r\ninteg-all: \r\n Run all integration tests\r\n",
+        runIt_cliCommand,
+        0
+    };
+
+    static struct Test_PalCliCommand cmdAlias =
+    {
+        "a",
+        "\r\na: \r\n Run all integration tests\r\n",
+        runIt_cliCommand,
+        0
+    };
+
+    rc += Test_PalCLIRegisterCommand(&cmdAll);
+    rc += Test_PalCLIRegisterCommand(&cmdAlias);
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/stackinfo b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/stackinfo
new file mode 100644
index 0000000..b15afb0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/stackinfo
@@ -0,0 +1,1506 @@
+function                                           code size       stack depth    
+-------------------------------------------------- --------------- ---------------
+mbedtls_mpi_write_file                                         144            2520
+mbedtls_mpi_read_file                                          138            2512
+mbedtls_mpi_exp_mod                                           1110            1648
+mbedtls_sha1_self_test                                         200            1312
+mbedtls_memory_buffer_alloc_self_test                          604            1064
+mbedtls_md_file                                                154            1064
+mbedtls_entropy_update_seed_file                               120            1048
+mbedtls_mpi_fill_random                                         52            1040
+LLF_HASH_SHA512_SingleBlockUpdate                             1586             848
+mbedtls_sha512_process                                        2758             816
+mbedtls_entropy_self_test                                      192             784
+block_cipher_df                                                344             656
+HkdfExtract                                                    156             632
+CC_RsaSchemesDecrypt                                           430             592
+CC_SrpUserProofCalc                                            200             560
+HkdfExpand                                                     238             512
+CC_SrpHostProofVerifyAndCalc                                   238             496
+SRP_UserProofCalc2                                             338             472
+FinishSwHash512                                                222             416
+mbedtls_hmac_drbg_reseed                                        98             408
+mbedtls_ctr_drbg_reseed                                        114             408
+CC_Hmac                                                         62             400
+SRP_UserCredDigCalc                                            138             336
+SRP_uScrambleCalc                                              186             336
+SRP_HostProofCalc                                              154             336
+SRP_xBuffCalc                                                  106             328
+SRP_kMultiplierCalc                                            192             328
+runIt_perfDump                                                 536             320
+mbedtls_sha512_self_test                                       248             320
+mbedtls_sha256_self_test                                       252             312
+mbedtls_hardware_poll                                          134             312
+mbedtls_ecdsa_sign_det                                         250             312
+runIt_aesOfbTest                                               426             280
+runIt_aesCtrTest                                               894             280
+mbedtls_hmac_drbg_write_seed_file                               78             280
+mbedtls_hmac_drbg_update_seed_file                             122             280
+mbedtls_ecp_self_test                                          700             280
+mbedtls_ctr_drbg_write_seed_file                                78             280
+mbedtls_ctr_drbg_update_seed_file                              124             280
+CC_UtilKeyDerivation                                           396             280
+runIt_srpTest                                                 2070             264
+RndDf                                                          328             264
+mbedtls_sha256                                                  54             264
+CC_Hash                                                         58             264
+runIt_aesCbcTest                                               458             256
+mbedtls_sha1                                                    50             256
+runIt_aesCfb128Test                                            464             248
+CC_ChachaPoly                                                  286             248
+runIt_ecdhPrimRandom                                          1788             240
+mbedtls_sha512                                                  54             240
+runIt_dhmTest                                                 1950             232
+runIt_aesEcbTest                                               740             232
+runIt_aesCfb8Test                                              568             232
+runIt_ccmTest                                                  554             224
+CC_HmacInit                                                    246             224
+runIt_Poly                                                     492             216
+runIt_ecdsaPrimVectorsTest                                    1526             216
+ecdsa_wrst_verify                                              228             216
+runIt_hmacTest                                                 626             208
+mbedtls_hmac_drbg_self_test                                    258             208
+ecdsa_edw_verify                                               198             208
+runIt_cmacKeyDerivTest                                         286             200
+prvParseDNSReply                                               664             200
+mbedtls_ecp_check_pub_priv                                     176             200
+AesWrap                                                        250             200
+runIt_gcmTest                                                 1574             192
+runIt_ecdsaDetVectorsTest                                     1126             192
+runIt_ChachaEncrypt                                            594             192
+mbedtls_rsa_check_privkey                                      532             192
+ecp_mont_gen_keypair_base                                      300             192
+runIt_sha512Test                                               598             184
+mbedtls_ctr_drbg_self_test                                     250             184
+AesUnWrap                                                      248             184
+ecp_mont_mul                                                   160             176
+runIt_sha384Test                                               900             168
+runIt_perfTypeFromStr                                         4610             168
+runIt_ecdsaWriteReadRandomTest                                 512             168
+runIt_ecdsaPrimRandomTest                                      640             168
+runIt_ChachaDecrypt                                            248             168
+entropy_gather_internal                                        110             168
+ecdsa_wrst_sign                                                248             168
+ecdsa_signature_to_asn1                                         98             168
+CC_RndGenerateVector                                           632             168
+runIt_rsaPublic                                                866             160
+runIt_rsaPrivate                                              1620             160
+runIt_rsaPkcsV21Test                                          1214             160
+runIt_sha256Test                                               588             152
+runIt_hmacKeyDerivTest                                         450             152
+runIt_ctrDrbgEntropyUsageTest                                 1616             152
+RndUpdate                                                      120             152
+ProcessSwHash512                                               114             152
+mbedtls_hashUpdate                                             168             152
+runIt_sha224Test                                              1186             144
+runIt_ecdhExchange                                             770             144
+runIt_ChachaPolyEncrypt                                        860             144
+runIt_ChachaPolyDecrypt                                        502             144
+mbedtls_base64_self_test                                       116             144
+runIt_sha1Test                                                 536             136
+runIt_init                                                     402             136
+runIt_buildPrivateKey                                          250             136
+runIt_aesKeyWrapTest                                           518             136
+mbedtls_sha_finish_internal                                     64             136
+mbedtls_dhm_self_test                                           66             136
+CC_LibInit                                                     368             136
+runIt_ctrDrbgVectorTest                                        660             128
+mbedtls_mpi_inv_mod                                            616             128
+ecdsa_edw_sign                                                 190             128
+UtilCmacDeriveKey                                              198             120
+mbedtls_mpi_div_mpi                                            790             120
+ecp_add_mixed                                                  946             120
+runIt_rsaCheckPubpriv                                          902             112
+RsaPssVerify21                                                 416             112
+mpi_miller_rabin                                               492             112
+mbedtls_mpi_self_test                                          548             112
+ecp_mod_koblitz                                                326             112
+CC_HkdfKeyDerivFunc                                             96             112
+runIt_hkdfKeyDerivTest                                         682             104
+RsaOaepMGF1                                                    138             104
+prvTCPReturnPacket                                             690             104
+runIt_rsaCheckPubkey                                           504              96
+runIt_rsaCheckPrivkey                                          474              96
+RndInstantiateOrReseed                                         356              96
+mbedtls_rsa_gen_key                                            376              96
+mbedtls_hmac_drbg_update                                       148              96
+mbedtls_entropy_func                                           184              96
+mbedtls_ctr_drbg_random_with_add                               200              96
+mbedtls_ccm_auth_decrypt                                        76              96
+ecp_mod_p521                                                   110              96
+ecp_mod_p384                                                  1380              96
+CC_SrpUserProofVerify                                          100              96
+CC_Chacha                                                       76              96
+runIt_shaTest                                                  250              88
+runIt_rsaTest                                                  260              88
+runIt_keyDerivationTest                                        218              88
+runIt_ecdsaTest                                                496              88
+runIt_ecdhTest                                                 728              88
+runIt_ctrDrbgTest                                              208              88
+runIt_ChachaTest                                               226              88
+runIt_aesTest                                                  272              88
+prvHandleEstablished                                           418              88
+PkaSum2ScalarMullt                                             704              88
+PkaEcEdwAddTwoScalarMult                                       946              88
+mbedtls_rsa_rsassa_pss_sign                                    238              88
+mbedtls_rsa_rsassa_pkcs1_v15_sign                              220              88
+mbedtls_rsa_rsaes_oaep_encrypt                                 306              88
+mbedtls_mng_getHWVersion                                       174              88
+mbedtls_md_hmac_starts                                         160              88
+mbedtls_md_hmac_finish                                          88              88
+LLF_RND_GetTrngSource                                          326              88
+entropy_update                                                  66              88
+CC_SrpPwdVerCreate                                             124              88
+CC_HmacFinish                                                  160              88
+CC_AesKeyUnWrap                                                190              88
+SRP_UserNameDigCalc                                             66              80
+SRP_SharedSecretCalc                                            80              80
+ScalarMultAff                                                  272              80
+runIt_executer                                                 334              80
+RsaPssOaepEncode                                               416              80
+RsaExecPrivKeyExpCrt                                           712              80
+prvStoreRxData                                                 216              80
+prvGetHostByName                                               286              80
+PolyMacCalc                                                    396              80
+PkaEcEdwSpecialScalarMultBase                                  408              80
+PkaEcEdwScalarMultBase                                         738              80
+mbedtls_rsa_rsassa_pkcs1_v15_verify                            190              80
+mbedtls_rsa_rsaes_pkcs1_v15_encrypt                            246              80
+mbedtls_entropy_write_seed_file                                 74              80
+mbedtls_ecdh_compute_shared                                     92              80
+GLCD_ClearLn                                                    94              80
+gcm_crypt_and_tag                                              322              80
+FreeRTOS_recvfrom                                              248              80
+ecp_mod_p256                                                  1074              80
+ecp_double_jac                                                1070              80
+EcEdwSign                                                      730              80
+EcdsaSignFinishInt                                             344              80
+ctr_drbg_update_internal                                       130              80
+CC_AesKeyWrap                                                  126              80
+xTaskCreate                                                    100              72
+SrpUserSessionKeyCalc                                          616              72
+SrpHostPublicKeyCalc                                           450              72
+runIt_malloc                                                    92              72
+runIt_ChachaPoly                                               270              72
+runIt_ChachaAes                                                122              72
+runIt_all                                                      112              72
+RsaGenRndNonZeroVect                                           154              72
+prvProcessDHCPReplies                                          422              72
+mbedtls_rsa_rsaes_oaep_decrypt                                 312              72
+EcWrstDsaSign                                                  214              72
+ecp_wrst_gen_keypair_base                                      378              72
+ecp_mod_p224                                                   576              72
+EcMontPkaScalarMultWithLadderExe                               904              72
+EcEdwSignVerify                                                456              72
+EcEdwAddTwoScalarMult                                          296              72
+ccm_init                                                       262              72
+CalcSignature                                                  520              72
+xEventGroupWaitBits                                            286              64
+SrpHostSessionKeyCalc                                          626              64
+runIt_free                                                      60              64
+prvTCPPrepareSend                                              546              64
+_printf_char_common                                             32              64
+PkiLongNumMul                                                  166              64
+PkiLongNumDiv                                                  194              64
+PkiExecModExpBe                                                154              64
+PkiCalcNp                                                      114              64
+mbedtls_rsa_rsassa_pss_verify_ext                              338              64
+mbedtls_rsa_rsaes_pkcs1_v15_decrypt                            234              64
+mbedtls_pem_write_buffer                                       246              64
+mbedtls_ecp_muladd                                             108              64
+mbedtls_ecdsa_write_signature                                  104              64
+mbedtls_ecdsa_read_signature                                   160              64
+mbedtls_dhm_parse_dhm                                          208              64
+mbedtls_ctr_drbg_seed_entropy_len                               84              64
+FreeRTOS_recv                                                  344              64
+ecp_mod_p255                                                   138              64
+ecMontKeyPairBase                                              188              64
+EcEdwSeedKeyPair                                               202              64
+EcdsaVerifyFinish                                              264              64
+CC_RsaSchemesEncrypt                                           362              64
+CC_RndGenerateVectorInRange                                    452              64
+CC_EcpkiKeyPairGenerateBase                                    232              64
+CC_EcMontScalarmult                                            250              64
+build_cc_priv_crt_key                                          500              64
+xTaskCreateStatic                                              118              56
+xQueueGenericSend                                              384              56
+xQueueGenericReceive                                           420              56
+SrpUserPublicKeyCalc                                           352              56
+SrpPwdVerifierCalc                                             246              56
+RsaPssSign21                                                   354              56
+RsaPssOaepDecode                                               384              56
+prvTCPWindowTxCheckAck                                         274              56
+prvHandleSynReceived                                           288              56
+prvCheckOptions                                                314              56
+PkaScalarMultAff                                               346              56
+PkaEcWrstScalarMult                                             92              56
+PkaCalcNpIntoPkaReg                                            606              56
+mpi_montmul                                                    190              56
+mbedtls_rsa_public                                             190              56
+mbedtls_mpi_mul_mpi                                            196              56
+mbedtls_mpi_gcd                                                256              56
+mbedtls_gcm_crypt_and_tag                                       32              56
+mbedtls_ecp_group_load                                         436              56
+mbedtls_ecdsa_sign                                             118              56
+mbedtls_ctr_drbg_update                                         38              56
+mbedtls_ccm_encrypt_and_tag                                     40              56
+mbedtls_aes_crypt_cfb8                                         136              56
+lTCPWindowRxCheck                                              370              56
+LLF_RND_EntropyEstimateFull                                    114              56
+GLCD_DrawChar                                                  150              56
+FreeRTOS_sendto                                                252              56
+FreeRTOS_send                                                  262              56
+FreeRTOS_accept                                                278              56
+EcWrstDsaVerify                                                308              56
+ecp_wrst_mul                                                   208              56
+CC_SrpInit                                                     228              56
+CC_RsaVerifyInit                                               420              56
+CC_RsaSignInit                                                 402              56
+CC_RsaSignFinish                                               234              56
+CC_EcpkiBuildEcDomain                                          480              56
+CC_EcMontSeedKeyPair                                           182              56
+CC_EcMontScalarmultBase                                        198              56
+xTimerGenericCommand                                           116              48
+xProcessReceivedTCPPacket                                      402              48
+xEventGroupSetBits                                             182              48
+vApplicationIPNetworkEventHook                                 190              48
+UtilCmacBuildDataForDerivation                                 192              48
+Test_PalThreadCreate                                           118              48
+RsaExecPubKeyExp                                               180              48
+RsaExecPrivKeyExpNonCrt                                        178              48
+RndStartupTest                                                  78              48
+prvTCPHandleState                                              406              48
+prvSendData                                                    258              48
+prvProcessReceivedCommands                                     254              48
+prvProcessIPPacket                                             228              48
+prvCreatePartDHCPMessage                                       248              48
+PkiExecModExpLeW                                               170              48
+PkaExecFullModInv                                              674              48
+PkaCopyByteBuffIntoPkaReg                                      214              48
+PkaBuildNaf                                                    264              48
+mbedtls_rsa_rsassa_pss_verify                                   46              48
+mbedtls_rsa_pkcs1_decrypt                                       62              48
+mbedtls_pem_read_buffer                                        246              48
+mbedtls_mpi_write_string                                       262              48
+mbedtls_mpi_read_string                                        274              48
+mbedtls_mpi_gen_prime                                          316              48
+mbedtls_gcm_auth_decrypt                                        48              48
+mbedtls_entropy_source_self_test                               128              48
+mbedtls_ecp_point_write_binary                                 186              48
+mbedtls_dhm_make_params                                        260              48
+mbedtls_dhm_calc_secret                                        218              48
+_ll_udiv                                                       238              48
+LLF_RND_EntropyEstimate                                        236              48
+FreeRTOS_connect                                               126              48
+EcWrstGenKeyPairBase                                           172              48
+EcWrstDhDeriveSharedSecret                                     132              48
+ecp_normalize_jac                                              214              48
+ecp_check_pubkey_sw                                            354              48
+ccm_auth_crypt                                                 178              48
+build_cc_pubkey                                                246              48
+__aeabi_uldivmod                                                 0              48
+xTimerPendFunctionCallFromISR                                   48              40
+xTimerPendFunctionCall                                          64              40
+xTimerCreateStatic                                              88              40
+xTimerCreate                                                    54              40
+xTCPWindowRxConfirm                                            100              40
+xTaskGenericNotifyFromISR                                      272              40
+xQueueReceiveFromISR                                           178              40
+xQueueGenericSendFromISR                                       212              40
+xEventGroupSync                                                222              40
+vSocketBind                                                    180              40
+vPortDefineHeapRegions                                         254              40
+uxStreamBufferGet                                              174              40
+uxStreamBufferAdd                                              248              40
+usGenerateProtocolChecksum                                     216              40
+RsaEmsaPkcs1v15Encode                                          124              40
+prvTCPPrepareConnect                                           312              40
+prvTCPHandleFin                                                236              40
+prvInitialiseNewTask                                           192              40
+ProcessChacha                                                  340              40
+ProcessBypass                                                  172              40
+ProcessAesGcm                                                  248              40
+__printf                                                       388              40
+PkaEcEdwAddExtPrcExt                                           476              40
+PkaEcEdwAddExtExtExt                                           506              40
+PkaEcdsaVerify                                                 580              40
+PkaDivLongNum                                                  268              40
+PkaCopyBeByteBuffIntoPkaReg                                    170              40
+mbedtls_sha512_finish                                          774              40
+mbedtls_rsa_private                                            162              40
+mbedtls_rsa_pkcs1_verify                                        56              40
+mbedtls_rsa_pkcs1_sign                                          60              40
+mbedtls_rsa_pkcs1_encrypt                                       56              40
+mbedtls_md_hmac                                                 82              40
+mbedtls_hmac_drbg_random_with_add                              184              40
+mbedtls_ecp_gen_keypair_base                                    98              40
+mbedtls_ecdsa_verify                                            96              40
+mbedtls_ecdh_make_params                                       108              40
+mbedtls_ecdh_calc_secret                                        96              40
+mbedtls_dhm_make_public                                        168              40
+mbedtls_asn1_store_named_data                                  160              40
+mbedtls_aes_crypt_cfb128                                       166              40
+main                                                           124              40
+lTCPWindowTxAdd                                                264              40
+GLCD_ChangeBitMap                                              124              40
+gcm_init                                                       178              40
+FreeRTOS_socket                                                196              40
+FreeRTOS_setsockopt                                            584              40
+FreeRTOS_IPInit                                                352              40
+FreeRTOS_bind                                                  138              40
+EcWrstFullCheckPublKey                                         108              40
+ecp_group_load                                                 128              40
+EcEdwSpecialScalarMultBase                                     396              40
+dhm_update_blinding                                            238              40
+dhm_check_range                                                 84              40
+CC_RsaVerifyFinish                                             216              40
+CC_RsaSign                                                      78              40
+CC_RsaPrimEncrypt                                              218              40
+CC_RsaPrimDecrypt                                              218              40
+CC_RndEnterKatMode                                             198              40
+ccm_finish                                                     150              40
+ccm_ass_data                                                   160              40
+CC_EcpkiPublKeyBuildAndCheck                                   360              40
+CC_EcEdwSign                                                    94              40
+CC_EcEdwSeedKeyPair                                            108              40
+CC_EcEdwKeyPair                                                148              40
+CC_EcdsaSign                                                    70              40
+__2snprintf                                                     50              40
+usGenerateChecksum                                             332              36
+PkaDoubleMdf2Mdf                                               498              36
+PkaAddJcbAfn2Mdf                                               650              36
+mbedtls_base64_encode                                          272              36
+xTimerCreateTimerTask                                          162              32
+xTCPWindowTxHasData                                            140              32
+xTCPWindowNew                                                  156              32
+xTCPTimerCheck                                                 130              32
+xTaskGenericNotify                                             216              32
+xQueuePeekFromISR                                              140              32
+xQueueGiveFromISR                                              188              32
+xQueueGenericCreateStatic                                      162              32
+xQueueGenericCreate                                             82              32
+xQueueCreateMutexStatic                                         42              32
+_writebuf                                                       84              32
+vTCPWindowCreate                                                96              32
+vTaskStartScheduler                                            232              32
+vTaskPrioritySet                                               294              32
+vTaskList                                                      204              32
+vTaskGetRunTimeStats                                           182              32
+vTaskDelayUntil                                                164              32
+vProcessGeneratedUDPPacket                                     226              32
+vARPRefreshCacheEntry                                          330              32
+ulTCPWindowTxGet                                               354              32
+SMSC9220_RecvPacket                                            116              32
+SMSC9220_PHY_RegWrite                                          144              32
+SMSC9220_PHY_RegRead                                           136              32
+SMSC9220_MAC_RegWrite                                          120              32
+SMSC9220_MAC_RegRead                                           128              32
+prvThreeParameterEchoCommand                                   144              32
+prvTCPWindowFastRetransmit                                     128              32
+prvTCPSendRepeated                                              66              32
+prvTCPBufferResize                                             140              32
+prvTCPAddTxData                                                 90              32
+prvSwitchTimerLists                                            138              32
+prvSetOptions                                                  138              32
+prvSendDHCPRequest                                              80              32
+prvSendDHCPDiscover                                             64              32
+prvParameterEchoCommand                                        130              32
+prvListTasksWithinSingleList                                   106              32
+prvInitialiseNewTimer                                           66              32
+prvGetRegistersFromStack                                        38              32
+prvCreateDNSMessage                                            118              32
+ProcessHash                                                    302              32
+ProcessAesCcm                                                  214              32
+ProcessAes                                                     250              32
+_printf_int_common                                             178              32
+PolyAccCalc                                                    366              32
+PkaDoubleMdf2Jcb                                               440              32
+PkaCopyBe8DataIntoPkaReg                                        84              32
+mpi_montred                                                     34              32
+mbedtls_mpi_sub_abs                                            110              32
+mbedtls_mpi_read_binary                                        110              32
+mbedtls_mng_getPendingRMAStatus                                116              32
+mbedtls_hmac_drbg_seed                                         114              32
+mbedtls_ecp_mul_shortcuts                                      108              32
+mbedtls_ecdsa_write_signature_det                               34              32
+mbedtls_ecdh_make_public                                        70              32
+mbedtls_base64_decode                                          300              32
+mbedtls_asn1_get_sequence_of                                   124              32
+mbedtls_aes_crypt_ofb                                           36              32
+mbedtls_aes_crypt_ctr                                           38              32
+mbedtls_aes_crypt_cbc                                          114              32
+lTCPAddRxdata                                                  136              32
+LoadAesKey                                                     304              32
+_ll_ufrom_d                                                    120              32
+LLF_RND_StartTrngHW                                            200              32
+initAesGcm                                                     338              32
+GLCD_SetWindow                                                 104              32
+GLCD_BoxSize                                                    74              32
+GLCD_Box                                                        66              32
+GLCD_BitmapSize                                                 76              32
+GLCD_Bitmap                                                     70              32
+GLCD_Bargraph                                                   98              32
+FreeRTOS_get_tx_head                                            70              32
+FreeRTOS_CLIProcessCommand                                     200              32
+fread                                                           58              32
+_fclose_internal                                                76              32
+fclose                                                           0              32
+EcWrstInitPubKey                                               352              32
+ecp_mod_p192                                                   156              32
+EcMontScalarmult                                                92              32
+EcMontPkaScalMultWithLadder                                    100              32
+EcEdwScalarMultBase                                            366              32
+ecc_conv_mpi_to_scalar                                          96              32
+_ddiv                                                          552              32
+CC_RsaVerify                                                    58              32
+CC_RndAddAdditionalInput                                       118              32
+CC_EcpkiPubKeyExport                                           258              32
+CC_EcpkiPrivKeyBuild                                           186              32
+CC_EcpkiKeyPairGenerate                                         36              32
+CC_EcMontKeyPairBase                                            30              32
+CC_EcMontKeyPair                                                18              32
+CC_EcEdwVerify                                                  70              32
+aes_crypt_ctr_ofb                                               86              32
+__aeabi_ddiv                                                     0              32
+__aeabi_d2ulz                                                    0              32
+__2sprintf                                                      38              32
+SMSC9220_XmitPacket                                             84              28
+pxTCPSocketLookup                                               88              28
+prvCheckRxData                                                 120              28
+LLF_RND_HistogramUpdate                                        830              28
+CC_CommonCmpMsbUnsignedCounters                                118              28
+xTaskResumeFromISR                                             144              24
+xTaskNotifyWait                                                150              24
+xTaskIncrementTick                                             352              24
+xTaskCheckForTimeOut                                           112              24
+xSendEventToIPTask                                              24              24
+xSendEventStructToIPTask                                       100              24
+xQueueCreateMutex                                               34              24
+xQueueCreateCountingSemaphoreStatic                             76              24
+xProcessReceivedUDPPacket                                      186              24
+xEventGroupSetBitsFromISR                                       32              24
+xEventGroupClearBits                                            68              24
+vUARTCommandConsoleStart                                       154              24
+vTCPWindowDestroy                                               64              24
+vTCPStateChange                                                242              24
+vTaskNotifyGiveFromISR                                         190              24
+vTaskGetInfo                                                   114              24
+vReturnEthernetFrame                                            62              24
+vQueueWaitForMessageRestricted                                  74              24
+uxTaskPriorityGetFromISR                                        62              24
+uxTaskGetSystemState                                           154              24
+ulTCPWindowTxSack                                               68              24
+ulTCPWindowTxAck                                                42              24
+TSC_I2C_read                                                   278              24
+Test_HalPerformWarmReset                                        58              24
+Test_HalPerformPowerOnReset                                    126              24
+Test_HalPerformColdReset                                       106              24
+_sys_write                                                      60              24
+_sys_read                                                       60              24
+strcasecmp                                                      42              24
+sqrt                                                            76              24
+SMSC9220_GetMacAddress                                         100              24
+smsc9220_CheckMacAddress                                       104              24
+runIt_rndBufferRand                                             70              24
+RndGenerateWordsArrayInRange                                    86              24
+register_test                                                  118              24
+realloc                                                          0              24
+pxGetNetworkBufferWithDescriptor                               142              24
+pvPortRealloc                                                   72              24
+pvPortMalloc                                                   202              24
+prvTCPWindowTxHasSpace                                          98              24
+prvTCPSocketCopy                                               132              24
+prvTCPSendPacket                                               138              24
+prvTCPCreateWindow                                              58              24
+prvTCPCreateStream                                             126              24
+prvTaskStatsCommand                                             50              24
+prvSetupHardware                                               252              24
+prvSetSynAckOptions                                             90              24
+prvRunTimeStatsCommand                                          50              24
+prvReplyDNSMessage                                             156              24
+prvProcessTimerOrBlockTask                                     102              24
+prvProcessExpiredTimer                                          82              24
+prvProcessDNSCache                                             188              24
+prvIPTask                                                      258              24
+prvInsertTimerInActiveList                                      80              24
+prvInitialiseNewQueue                                           42              24
+prvHelpCommand                                                  66              24
+prvHandleListen                                                272              24
+prvGetPrivatePortNumber                                         98              24
+prvDetermineSocketSize                                         150              24
+prvCreateDNSSocket                                             102              24
+prvCreateDHCPSocket                                            120              24
+prvCopyDataToQueue                                             124              24
+prvCheckNetworkTimers                                          132              24
+prvAllowIPPacket                                               100              24
+prvAddCurrentTaskToDelayedList                                 100              24
+_printf_int_dec                                                104              24
+PkiIsModSquareRootExists                                      1218              24
+PkaGetBitFromPkaReg                                            166              24
+PkaEcEdwDoublExtExt                                            380              24
+PkaCopyPkaRegIntoBeByteBuff                                     72              24
+PkaCopyDataIntoPkaReg                                          156              24
+PkaClearBlockOfRegs                                            248              24
+mpi_write_hlp                                                  100              24
+mpi_check_small_factors                                         74              24
+mbedtls_sha512_update                                          134              24
+mbedtls_mpi_write_binary                                        68              24
+mbedtls_mpi_sub_mpi                                             78              24
+mbedtls_mpi_sub_int                                             46              24
+mbedtls_mpi_shift_r                                            126              24
+mbedtls_mpi_shift_l                                            154              24
+mbedtls_mpi_set_bit                                             84              24
+mbedtls_mpi_safe_cond_swap                                     136              24
+mbedtls_mpi_safe_cond_assign                                   106              24
+mbedtls_mpi_mul_int                                             22              24
+mbedtls_mpi_is_prime                                            84              24
+mbedtls_mpi_grow                                                84              24
+mbedtls_mpi_div_int                                             44              24
+mbedtls_mpi_copy                                                84              24
+mbedtls_mpi_add_mpi                                             76              24
+mbedtls_mpi_add_int                                             44              24
+mbedtls_mpi_add_abs                                            188              24
+mbedtls_mng_setDebugKey                                         74              24
+mbedtls_mng_setCCSecMode                                       180              24
+mbedtls_mng_setCCPrivMode                                      174              24
+mbedtls_mng_lockOemKey                                         158              24
+mbedtls_md_setup                                                66              24
+mbedtls_hmac_drbg_seed_buf                                      74              24
+mbedtls_entropy_source_self_test_gather                         52              24
+mbedtls_ecp_tls_write_point                                     56              24
+mbedtls_ecp_point_read_binary                                  118              24
+mbedtls_ecp_mul                                                112              24
+mbedtls_ecp_gen_key                                             46              24
+mbedtls_ecp_check_pubkey                                        86              24
+mbedtls_ecp_check_privkey                                      118              24
+mbedtls_ecdsa_genkey                                            48              24
+mbedtls_ecdh_read_public                                        44              24
+mbedtls_ecdh_get_params                                         76              24
+mbedtls_ctr_drbg_seed                                           16              24
+mbedtls_asn1_write_mpi                                         122              24
+mbedtls_asn1_write_bitstring                                   104              24
+mbedtls_asn1_write_algorithm_identifier                         78              24
+mbedtls_asn1_get_alg                                           138              24
+malloc                                                           0              24
+load_file                                                      156              24
+LLF_RND_RndCprngt                                               98              24
+LLF_RND_DescBypass                                              68              24
+initLibraries                                                  128              24
+InitAesCcm                                                     168              24
+InitAes                                                        190              24
+hashUpdate                                                     152              24
+GLCD_SetWindowSize                                              88              24
+GLCD_DisplayString                                              40              24
+GLCD_DisplayChar                                                84              24
+GetChars                                                        74              24
+fwrite                                                          50              24
+_fseek                                                         242              24
+fseek                                                            0              24
+freopen                                                        158              24
+FreeRTOS_shutdown                                               70              24
+FreeRTOS_listen                                                148              24
+FreeRTOS_inet_addr                                             142              24
+FreeRTOS_GetUDPPayloadBuffer                                    44              24
+FreeRTOS_gethostbyname                                          58              24
+FreeRTOS_closesocket                                            48              24
+fopen                                                           74              24
+finalizeCmac                                                   212              24
+fgets                                                           74              24
+eTaskGetState                                                  100              24
+EcdsaVerifyUpdate                                              128              24
+EcdsaVerifyInit                                                150              24
+EcdsaSignUpdate                                                124              24
+EcdsaSignInit                                                  150              24
+ecc_conv_scalar_to_mpi                                          88              24
+eARPGetCacheEntry                                              130              24
+_dsqrt                                                         456              24
+ChachaBlock                                                    130              24
+CC_SrpUserPubKeyCreate                                          92              24
+CC_SrpHostPubKeyCreate                                         102              24
+CC_EcdsaVerify                                                  50              24
+CC_CommonConvertMsbLsbBytesToLswMswWords                       130              24
+CC_CommonConvertLswMswWordsToMsbLsbBytes                       108              24
+CC_ChachaInit                                                  106              24
+CC_AesFinish                                                   188              24
+buffer_alloc_calloc                                            214              24
+ap_check_peripheral_interrupt                                  150              24
+AesKeyWrapInputCheck                                           146              24
+__2printf                                                       20              24
+prvReadNameField                                                80              20
+PkiCalcJacobiSymbol                                            354              20
+PkaJcb2Afn                                                     158              20
+PkaInitPka                                                     174              20
+PkaGetRegEffectiveSizeInBits                                   112              20
+PkaGetNextMsBit                                                 86              20
+PkaGet2MsBits                                                   72              20
+PkaEcEdwPointToAfn                                              76              20
+PkaEcEdwDecompress                                             440              20
+PkaEcEdwConvertAfn2Prc                                         140              20
+PkaAddAff                                                      306              20
+Mult32x32                                                       58              20
+mpi_sub_hlp                                                     76              20
+mbedtls_mpi_swap                                                20              20
+mbedtls_mpi_mod_int                                            110              20
+mbedtls_mpi_cmp_int                                             46              20
+mbedtls_asn1_write_len                                         204              20
+mbedtls_asn1_get_len                                           158              20
+CC_CommonSubtractUintArrays                                     50              20
+CC_CommonSubtractMSBUint8Arrays                                 58              20
+CC_CommonShiftRightVector                                       52              20
+CC_CommonShiftLeftBigEndVector                                  52              20
+CC_CommonCmpLsWordsUnsignedCounters                            132              20
+CC_CommonCmpLsbUnsignedCounters                                128              20
+CC_CommonAdd2vectors                                            64              20
+xTimerIsTimerActive                                             44              16
+xTimerGetPeriod                                                 22              16
+xTimerGetExpiryTime                                             24              16
+xTCPWindowRxFind                                                38              16
+xTCPWindowRxEmpty                                               46              16
+xTCPWindowGetHead                                               34              16
+xTCPSocketCheck                                                146              16
+xTCPCheckNewClient                                              76              16
+xTaskResumeAll                                                 210              16
+xTaskRemoveFromEventList                                       114              16
+xTaskPriorityDisinherit                                        128              16
+xTaskNotifyStateClear                                           48              16
+xTaskGetTickCountFromISR                                        16              16
+xQueueIsQueueFullFromISR                                        34              16
+xQueueIsQueueEmptyFromISR                                       30              16
+xQueueGenericReset                                             134              16
+xQueueCreateCountingSemaphore                                   68              16
+xPortStartScheduler                                            136              16
+xPortHasUDPSocket                                               30              16
+xNetworkInterfaceOutput                                         70              16
+xNetworkInterfaceInitialise                                     38              16
+xNetworkBuffersInitialise                                      140              16
+xEventGroupGetBitsFromISR                                       44              16
+xEventGroupCreateStatic                                         36              16
+xEventGroupClearBitsFromISR                                     26              16
+xDeferredInterruptHandlerTask                                  142              16
+xApplicationDNSQueryHook                                        28              16
+xApplicationDHCPHook                                            16              16
+wr_reg                                                          20              16
+WriteBuf                                                        22              16
+vTimerSetTimerID                                                32              16
+vTaskSuspend                                                   150              16
+vTaskResume                                                    114              16
+vTaskRemoveFromUnorderedEventList                              116              16
+vTaskPriorityInherit                                           128              16
+vTaskPlaceOnUnorderedEventList                                  76              16
+vTaskPlaceOnEventListRestricted                                 48              16
+vTaskPlaceOnEventList                                           40              16
+vTaskDelete                                                    156              16
+vTaskDelay                                                      70              16
+vSocketClose                                                   136              16
+vReleaseNetworkBufferAndDescriptor                              94              16
+vQueueDelete                                                    38              16
+vPortValidateInterruptPriority                                  84              16
+vPortFree                                                      116              16
+vNetworkSocketsInit                                             76              16
+vNetworkBufferReleaseFromISR                                    62              16
+vEventGroupSetBitsCallback                                      16              16
+vEventGroupDelete                                               84              16
+vEventGroupClearBitsCallback                                    16              16
+verify_chain                                                    54              16
+vDHCPProcess                                                   556              16
+vARPGenerateRequestPacket                                       62              16
+vARPAgeCache                                                   174              16
+uxTaskPriorityGet                                               30              16
+uxTaskGetStackHighWaterMark                                     30              16
+uxStreamBufferMidSpace                                          20              16
+uxStreamBufferGetSpace                                          20              16
+uxStreamBufferGetSize                                           32              16
+uxStreamBufferFrontSpace                                        20              16
+uxStreamBufferFrontSpace                                        20              16
+uxQueueSpacesAvailable                                          36              16
+uxQueueMessagesWaitingFromISR                                   22              16
+uxQueueMessagesWaiting                                          30              16
+ulTaskNotifyTake                                               108              16
+ulMainGetRunTimeCounterValue                                    96              16
+ulDNSHandlePacket                                               24              16
+TSC_I2C_write                                                  112              16
+TSC_I2C_send_byte                                               96              16
+TSC_I2C_receive_byte                                            86              16
+Test_HalPlatformInit                                            54              16
+Test_HalBoardInit                                              166              16
+_terminateio                                                    56              16
+_sys_open                                                       60              16
+strncmp                                                        150              16
+SMSC9220_ResetPhy                                               64              16
+SMSC9220_PrintPhyRegisters                                     190              16
+SMSC9220_PrintMacRegisters                                      44              16
+SMSC9220_PerfectFilteringMode                                  122              16
+SMSC9220_Initialise                                           1010              16
+SMSC9220_CheckPhy                                               72              16
+SMSC9220_CheckId                                                88              16
+setvbuf                                                         70              16
+setHwKeyToShadowReg                                            146              16
+runIt_unhexify                                                 112              16
+runIt_rndStdRand                                                26              16
+runIt_perfOpenNewEntry                                          24              16
+runIt_perfInit                                                  44              16
+runIt_perfCloseEntry                                            78              16
+runIt_ctrDrbgSelfTestEntropy                                    28              16
+RsaInitPrivKeyDb                                                90              16
+ReadBuf                                                         22              16
+pxUDPSocketLookup                                               44              16
+pxNetworkBufferGetFromISR                                       84              16
+pxListFindListItemWithValue                                     48              16
+pxDuplicateNetworkBufferWithDescriptor                          44              16
+pvTimerGetTimerID                                               32              16
+pvPortCalloc                                                    38              16
+prvWriteNameToBuffer                                            42              16
+prvUnlockQueue                                                 126              16
+prvTCPStatusAgeCheck                                           104              16
+prvTCPSetSocketCount                                            56              16
+prvTCPSendReset                                                 36              16
+prvTCPSendCheck                                                 94              16
+prvTCPNextTimeout                                              176              16
+prvTCPConnectStart                                             170              16
+prvTaskIsTaskSuspended                                          70              16
+prvSocketSetMSS                                                 78              16
+prvSendBuffer                                                   34              16
+prvSampleTimeNow                                                40              16
+prvProcessICMPPacket                                            36              16
+prvProcessEthernetPacket                                       114              16
+prvIsQueueFull                                                  30              16
+prvIsQueueEmpty                                                 26              16
+prvIPTimerStart                                                 48              16
+prvIPTimerReload                                                18              16
+prvIPTimerCheck                                                 54              16
+prvCreateSectors                                               116              16
+prvCopyDataFromQueue                                            42              16
+prvCheckTasksWaitingTermination                                 86              16
+_printf_str                                                     82              16
+_printf_pre_padding                                             44              16
+_printf_post_padding                                            34              16
+_printf_longlong_hex                                             0              16
+_printf_int_hex                                                 84              16
+_printf_char_file                                               32              16
+PkiAreBuffersEqual                                              30              16
+PkaModDivideBy2                                                140              16
+PkaIsRegModEqual                                               102              16
+PkaInitAndMutexLock                                             64              16
+PkaCopyDataFromPkaRegToBe8Buff                                  40              16
+PkaCopyDataFromPkaReg                                           90              16
+pcTimerGetName                                                  22              16
+pcTaskGetName                                                   34              16
+mpi_mul_hlp                                                    904              16
+mbedtls_sha_starts_internal                                     34              16
+mbedtls_sha256_finish                                           44              16
+mbedtls_sha1_finish                                             32              16
+mbedtls_rsa_init                                                20              16
+mbedtls_rsa_copy                                               244              16
+mbedtls_rsa_check_pub_priv                                      56              16
+mbedtls_rsa_check_pubkey                                        88              16
+mbedtls_pem_free                                                34              16
+mbedtls_mpi_shrink                                              94              16
+mbedtls_mpi_mod_mpi                                             98              16
+mbedtls_mpi_lset                                                56              16
+mbedtls_mpi_lsb                                                 46              16
+mbedtls_mpi_cmp_mpi                                            136              16
+mbedtls_mpi_cmp_abs                                             96              16
+mbedtls_mng_setApbcConfig                                      252              16
+mbedtls_memory_buffer_alloc_init                                76              16
+mbedtls_md_hmac_reset                                           42              16
+mbedtls_md                                                      26              16
+mbedtls_entropy_init                                            38              16
+mbedtls_entropy_add_source                                      48              16
+mbedtls_ecp_tls_write_group                                     56              16
+mbedtls_ecp_tls_read_point                                      76              16
+mbedtls_ecp_tls_read_group                                      74              16
+mbedtls_ecp_point_read_string                                   60              16
+mbedtls_ecp_point_cmp                                           60              16
+mbedtls_ecp_group_free                                         102              16
+mbedtls_ecp_gen_keypair                                         30              16
+mbedtls_ecp_curve_info_from_name                                38              16
+mbedtls_ecp_copy                                                54              16
+mbedtls_ecdsa_from_keypair                                      66              16
+mbedtls_ecdh_read_params                                        54              16
+mbedtls_ecdh_gen_public                                         12              16
+mbedtls_dhm_read_params                                         76              16
+mbedtls_dhm_parse_dhmfile                                       52              16
+mbedtls_asn1_write_raw_buffer                                   42              16
+mbedtls_asn1_write_printable_string                             50              16
+mbedtls_asn1_write_oid                                          50              16
+mbedtls_asn1_write_octet_string                                 50              16
+mbedtls_asn1_write_null                                         36              16
+mbedtls_asn1_write_int                                          92              16
+mbedtls_asn1_write_ia5_string                                   50              16
+mbedtls_asn1_write_bool                                         68              16
+mbedtls_asn1_get_mpi                                            38              16
+mbedtls_asn1_get_int                                            76              16
+mbedtls_asn1_get_bool                                           50              16
+mbedtls_asn1_get_bitstring                                      78              16
+mbedtls_asn1_get_alg_null                                       40              16
+mbedtls_asn1_free_named_data_list                               32              16
+mbedtls_asn1_free_named_data                                    34              16
+mbedtls_asn1_find_named_data                                    38              16
+mbedtls_aes_crypt_ecb                                           64              16
+LLF_RND_WaitRngInterrupt                                        62              16
+LLF_RND_TRNG_ReadEhrData                                        84              16
+LLF_RND_GetPreferableRosc                                       46              16
+inc32AesGcmJ0                                                   38              16
+hmac_drbg_self_test_entropy                                     28              16
+GLCD_WrReg                                                      16              16
+GLCD_PutPixelColor                                              94              16
+GLCD_PutPixel                                                  108              16
+GLCD_Clear                                                      42              16
+GetParamsFromHKDFHashMode                                       74              16
+gcm_process_j0                                                 104              16
+FreeRTOS_tx_space                                               40              16
+FreeRTOS_tx_size                                                40              16
+FreeRTOS_rx_size                                                40              16
+FreeRTOS_ReleaseUDPPayloadBuffer                                18              16
+FreeRTOS_OutputARPRequest                                       34              16
+FreeRTOS_netstat                                                24              16
+FreeRTOS_maywrite                                               74              16
+FreeRTOS_dnslookup                                              22              16
+FreeRTOS_CLIRegisterCommand                                     66              16
+free                                                             0              16
+fputc                                                           14              16
+__fpl_dnaninf                                                  156              16
+fix_negative                                                    42              16
+fgetc                                                           16              16
+_fflush                                                         70              16
+fflush                                                          42              16
+entropy_dummy_source                                            22              16
+EcWrstGenKeyPair                                                30              16
+EcWrstDsaTruncateMsg                                            88              16
+ecp_use_curve25519                                             116              16
+ecp_mod_p256k1                                                  22              16
+ecp_mod_p224k1                                                  22              16
+ecp_mod_p192k1                                                  22              16
+ecp_modp                                                       132              16
+eConsiderFrameForProcessing                                     82              16
+eARPProcessPacket                                              156              16
+_do_fflush                                                      54              16
+dhm_read_bignum                                                 56              16
+__default_signal_display                                        50              16
+ctr_drbg_self_test_entropy                                      28              16
+Common_EnableIrq                                                66              16
+CC_RsaVerifyUpdate                                             114              16
+CC_RsaSignUpdate                                               114              16
+CC_RndReseeding                                                 84              16
+CC_RndInstantiation                                             84              16
+CC_Poly                                                         44              16
+CC_PalPowerSaveModeSelect                                       40              16
+CC_LibFini                                                      36              16
+CC_HashInit                                                    108              16
+CC_HashFinish                                                   92              16
+CC_AesSetKey                                                    86              16
+CC_AesInit                                                     162              16
+CC_AesBlock                                                     68              16
+calloc                                                           0              16
+buffer_alloc_free                                              216              16
+apTSC_INIT                                                     220              16
+add64                                                           62              16
+vTCPWindowInit                                                  84              12
+vListInsertFifo                                                 20              12
+uxPortGetSize                                                   46              12
+strstr                                                          36              12
+strcpy                                                          72              12
+prvValidSocket                                                  48              12
+prvProcessICMPEchoRequest                                       88              12
+prvCacheLookup                                                  74              12
+PkiGetNextTwoMsBits                                             36              12
+PkiConditionalSecureSwapUint32                                  24              12
+PkaClearPkaRegWords                                            102              12
+Mult48x16                                                       36              12
+mbedtls_mng_otpWordRead                                         48              12
+mbedtls_entropy_source_self_test_check_bits                    116              12
+mbedtls_asn1_get_bitstring_null                                 44              12
+FreeRTOS_SetAddressConfiguration                                36              12
+FreeRTOS_GetRemoteAddress                                       74              12
+FreeRTOS_CLIGetParameter                                        92              12
+convert_mbedtls_md_type_to_cc_rsa_hash_opmode                   76              12
+CC_HalWaitInterrupt                                             46              12
+CC_CommonReverseMemcpy                                          82              12
+CC_CommonInPlaceConvertBytesWordsAndArrayEndiannes              72              12
+CC_CommonIncLsbUnsignedCounter                                  38              12
+CC_CommonDivideVectorBy2                                        48              12
+xTimerGetTimerDaemonTaskHandle                                  32               8
+xTaskGetIdleTaskHandle                                          32               8
+xIsCallingFromIPTask                                            24               8
+xEventGroupCreate                                               30               8
+wr_dat_start                                                    22               8
+wr_dat_only                                                     18               8
+wr_dat                                                          48               8
+wr_cmd                                                          48               8
+vTCPWindowFree                                                  48               8
+vTCPTimerSet                                                    12               8
+vTaskSwitchContext                                             192               8
+vTaskSetTimeOutState                                           100               8
+vTaskSetThreadLocalStoragePointer                               28               8
+vTaskEndScheduler                                               32               8
+vSocketWakeUpUser                                               26               8
+vRegisterCLICommands                                            28               8
+vPortExitCritical                                               46               8
+vPortEnterCritical                                              68               8
+vPortEndScheduler                                               32               8
+vNetworkInterfaceAllocateRAMToBuffers                           46               8
+vListInsert                                                     52               8
+vIPReloadDHCPTimer                                              14               8
+vIPNetworkUpCalls                                               20               8
+vAssertCalled                                                   46               8
+vARPSendGratuitous                                              16               8
+vApplicationIdleHook                                            12               8
+uxStreamBufferSpace                                             24               8
+uxStreamBufferSpace                                             24               8
+uxStreamBufferDistance                                          22               8
+__user_setup_stackheap                                          74               8
+ulTimerGetAge                                                   14               8
+UartGetc                                                        42               8
+_ttywrch                                                        12               8
+TSC_I2C_send_ack                                                70               8
+TSC_I2C_receive_ack                                             92               8
+TSC_I2C_clear                                                   68               8
+tolower                                                         26               8
+Test_PalThreadStackHighestWatermark                             10               8
+Test_PalThreadJoin                                              16               8
+Test_PalThreadFunc                                              34               8
+Test_PalThreadDestroy                                           10               8
+Test_PalCLIRegisterCommand                                      16               8
+Test_HalBoardFree                                               74               8
+SysTick_Handler                                                 48               8
+sub32                                                           30               8
+strncpy                                                         86               8
+strncat                                                         36               8
+strlen                                                          62               8
+StoreIVState                                                    92               8
+srpHashFinish                                                   22               8
+srand                                                           42               8
+SMSC9220_WaitForEEPROM                                          42               8
+SMSC9220_SoftReset                                              56               8
+SMSC9220_EstablishLink                                          82               8
+SMSC9220_EnableMacXmit                                          48               8
+SMSC9220_EnableMacRecv                                         682               8
+SMSC9220_ClearRxFifo                                            40               8
+SMSC9220_AdvertiseCap                                           64               8
+Sleepms                                                         74               8
+sha384_ctx_free                                                 20               8
+sha384_ctx_alloc                                                24               8
+sha224_ctx_free                                                 20               8
+sha224_ctx_alloc                                                24               8
+sha1_ctx_free                                                   20               8
+sha1_ctx_alloc                                                  24               8
+__set_errno                                                     12               8
+runIt_perfTypeStr                                             5212               8
+runIt_hexify                                                    50               8
+runIt_getMicroSec                                               18               8
+runIt_finish                                                    72               8
+runIt_cliCommand                                                10               8
+__rt_SIGRTRED_inner                                             14               8
+__rt_SIGRTRED                                                   14               8
+__rt_SIGABRT_inner                                              14               8
+__rt_SIGABRT                                                    14               8
+__rt_memmove_w                                                 122               8
+__rt_memcpy_w                                                  100               8
+__rt_ctype_table                                                16               8
+RndAddValToIv                                                   38               8
+__read_errno                                                    10               8
+pvTaskGetThreadLocalStoragePointer                              36               8
+prvWinScaleFactor                                               36               8
+prvUARTCommandConsoleTask                                      302               8
+prvTimerTask                                                    26               8
+prvTestWaitCondition                                            30               8
+prvTCPTouchSocket                                               40               8
+prvProcessNetworkDownEvent                                      50               8
+prvIsFreeBuffer                                                 36               8
+prvInsertBlockIntoFreeList                                      96               8
+prvInitialiseTaskLists                                          70               8
+prvInitialiseMutex                                              28               8
+prvInitialiseDHCP                                              118               8
+prvHandleEthernetPacket                                         12               8
+prvDeleteTCB                                                    68               8
+prvCheckForValidListAndQueue                                    78               8
+prvAddNewTaskToReadyList                                       154               8
+_printf_cs_common                                               20               8
+PkiIsUint8ArrayEqualTo0                                         26               8
+PkiClearAllPka                                                  28               8
+PkaSetLenIds                                                    54               8
+PkaFinishAndMutexUnlock                                         48               8
+memcmp                                                          88               8
+mbedtls_rsa_free                                               110               8
+mbedtls_mpi_free                                                36               8
+mbedtls_mpi_bitlen                                              62               8
+mbedtls_mng_suspend                                            134               8
+mbedtls_mng_resume                                              70               8
+mbedtls_mng_apbcAccess                                          32               8
+mbedtls_md_update                                               22               8
+mbedtls_md_starts                                               22               8
+mbedtls_md_process                                              22               8
+mbedtls_md_info_from_string                                     94               8
+mbedtls_md_hmac_update                                          26               8
+mbedtls_md_free                                                 58               8
+mbedtls_md_finish                                               22               8
+mbedtls_md_clone                                                34               8
+mbedtls_hmac_drbg_random                                        12               8
+mbedtls_hmac_drbg_free                                          26               8
+mbedtls_gcm_setkey                                              60               8
+mbedtls_gcm_init                                                20               8
+mbedtls_ecp_set_zero                                            48               8
+mbedtls_ecp_point_init                                          32               8
+mbedtls_ecp_point_free                                          32               8
+mbedtls_ecp_keypair_init                                        30               8
+mbedtls_ecp_keypair_free                                        30               8
+mbedtls_ecp_is_zero                                             26               8
+mbedtls_ecp_grp_id_list                                         40               8
+mbedtls_ecdh_free                                               72               8
+mbedtls_dhm_read_public                                         32               8
+mbedtls_dhm_free                                                92               8
+mbedtls_ctr_drbg_random                                         12               8
+mbedtls_ctr_drbg_free                                           28               8
+mbedtls_ccm_setkey                                              60               8
+mbedtls_ccm_init                                                20               8
+mbedtls_ccm_free                                                20               8
+mbedtls_asn1_get_tag                                            38               8
+mbedtls_aes_init                                                22               8
+_ll_uto_d                                                      138               8
+librun_integration_test_initLib                                 22               8
+InitSwHash512                                                   42               8
+_initio                                                        210               8
+InitHash                                                        56               8
+HASH_COMMON_IncMsbUnsignedCounter                               90               8
+HASH_COMMON_IncLsbUnsignedCounter                               48               8
+GLCD_Write                                                      12               8
+GLCD_WrCmd                                                      12               8
+GLCD_WindowMax                                                  18               8
+GLCD_Start                                                      14               8
+GLCD_Initialize                                                616               8
+GLCD_End                                                         8               8
+GLCD_Boarder                                                    54               8
+_get_lc_ctype                                                   44               8
+_ftell_internal                                                 66               8
+ftell                                                            0               8
+FreeRTOS_NetworkDownFromISR                                    104               8
+FreeRTOS_NetworkDown                                            32               8
+FreeRTOS_GetLocalAddress                                        30               8
+FreeRTOS_GetAddressConfiguration                                36               8
+FreeRTOS_ClearARP                                               12               8
+FinalizeAes                                                     66               8
+exit                                                            18               8
+ETHERNET_Handler                                                70               8
+error_mapping_cc_to_mbedtls_rsa                                344               8
+_deferredlazyseek                                               60               8
+Common_Sleep                                                    74               8
+Common_DisableIrq                                               28               8
+CC_SrpClear                                                     22               8
+CC_RndUnInstantiation                                           30               8
+CC_PalTerminate                                                 50               8
+CC_PalMutexUnlock                                               24               8
+CC_PalMutexLock                                                 26               8
+CC_PalMutexDestroy                                              12               8
+CC_PalMutexCreate                                               22               8
+CC_PalInit                                                      70               8
+CC_HmacUpdate                                                   50               8
+CC_HmacFree                                                     22               8
+CC_HashUpdate                                                   52               8
+CC_HashFree                                                     20               8
+CC_HalTerminate                                                 20               8
+CC_HalInit                                                      28               8
+CC_CommonIncMsbUnsignedCounter                                  90               8
+CC_CommonDecrLsbUnsignedCounter                                 30               8
+CC_CommonConvertLsbMsbBytesToLswMswWords                        30               8
+CC_ChachaFree                                                   18               8
+CC_ChachaBlock                                                  18               8
+CC_AesSetIv                                                     50               8
+CC_AesGetIv                                                     60               8
+CC_AesFree                                                      20               8
+carry64                                                         38               8
+aes_setkey                                                      60               8
+__aeabi_ul2d                                                     0               8
+__aeabi_memmove8                                                 0               8
+__aeabi_memmove4                                                 0               8
+__aeabi_memcpy8                                                  0               8
+__aeabi_memcpy4                                                  0               8
+AddInt8ValueToUin8Vector                                        26               8
+add32                                                           28               8
+abort                                                           22               8
+__rt_memclr_w                                                   78               4
+prvShowWarnings                                                 50               4
+mbedtls_mpi_size                                                12               4
+__aeabi_memclr8                                                  0               4
+__aeabi_memclr4                                                  0               4
+xTCPWindowTxDone                                                16               0
+xTCPWindowPeekHead                                              24               0
+xTaskGetTickCount                                                6               0
+xTaskGetSchedulerState                                          24               0
+xTaskGetCurrentTaskHandle                                        6               0
+xSequenceLessThan                                               12               0
+xSequenceGreaterThanOrEqual                                     10               0
+xSequenceGreaterThan                                            12               0
+xPortGetMinimumEverFreeHeapSize                                  6               0
+xPortGetFreeHeapSize                                             6               0
+xIsDHCPSocket                                                   18               0
+xIPIsNetworkTaskReady                                            6               0
+wr_dat_stop                                                     14               0
+vTaskSuspendAll                                                 12               0
+vTaskSetTaskNumber                                               8               0
+vTaskMissedYield                                                 8               0
+vStreamBufferClear                                              12               0
+vQueueUnregisterQueue                                           44               0
+vQueueSetQueueNumber                                             4               0
+vQueueAddToRegistry                                             38               0
+vPortSetupTimerInterrupt                                        16               0
+vPortGetIPSR                                                     6               0
+vMainConfigureTimerForRunTimeStats                              10               0
+vListInsertGeneric                                              22               0
+vListInsertEnd                                                  24               0
+vListInitialiseItem                                              6               0
+vListInitialise                                                 26               0
+vIPSetDHCPTimerEnableState                                      32               0
+verify_header                                                   50               0
+vApplicationTickHook                                            12               0
+vApplicationStackOverflowHook                                    4               0
+vApplicationMallocFailedHook                                     4               0
+vApplicationGetTimerTaskMemory                                  14               0
+vApplicationGetIdleTaskMemory                                   14               0
+validate_mbedtls_rsa_context_public_key                         46               0
+validate_mbedtls_rsa_context_private_key                        86               0
+uxTaskResetEventItemValue                                       24               0
+uxTaskGetTaskNumber                                             14               0
+uxTaskGetNumberOfTasks                                           6               0
+uxQueueGetQueueNumber                                            6               0
+uxListRemove                                                    40               0
+uxGetNumberOfFreeNetworkBuffers                                  6               0
+uxGetMinimumFreeNetworkBuffers                                   6               0
+uxEventGroupGetNumber                                           14               0
+__use_two_region_memory                                          2               0
+__user_perthread_libspace                                        0               0
+__user_perproc_libspace                                          0               0
+__user_libspace                                                  8               0
+__user_initial_stackheap                                        10               0
+usChar2u16                                                      12               0
+UsageFault_Handler                                               2               0
+UpdateHashFinish                                                80               0
+ulChar2u32                                                      24               0
+ucQueueGetQueueType                                              8               0
+UARTTX2_Handler                                                  0               0
+UARTTX1_Handler                                                  0               0
+UARTTX0_Handler                                                  0               0
+UartStdOutInit                                                  24               0
+UARTRX2_Handler                                                  0               0
+UARTRX1_Handler                                                  0               0
+UARTRX0_Handler                                                  0               0
+UartPutc                                                        58               0
+UARTOVF_Handler                                                  0               0
+UartEndSimulation                                               10               0
+TIMER1_Handler                                                   0               0
+TIMER0_Handler                                                   0               0
+time                                                            12               0
+Test_PalUnmapAddr                                                2               0
+Test_PalSetDMABaseAddr                                           2               0
+Test_PalRealloc                                                  4               0
+Test_PalMemInit                                                  4               0
+Test_PalMemFin                                                   4               0
+Test_PalMapAddr                                                  2               0
+Test_PalMalloc                                                   4               0
+Test_PalGetDMABaseAddr                                           4               0
+Test_PalFree                                                     4               0
+Test_PalDMAContigBufferFree                                      4               0
+Test_PalDMAContigBufferAlloc                                     2               0
+Test_PalDelay                                                   12               0
+Test_PalCLIGetParameter                                          4               0
+Test_HalPlatformFree                                             2               0
+_sys_tmpnam                                                      6               0
+SystemInit                                                       8               0
+SystemCoreClockUpdate                                            8               0
+system                                                           6               0
+_sys_seek                                                       20               0
+_sys_istty                                                      16               0
+_sys_flen                                                       18               0
+_sys_exit                                                        4               0
+_sys_ensure                                                     20               0
+_sys_command_string                                              2               0
+_sys_close                                                      18               0
+SVC_Handler                                                     32               0
+strcmp                                                         128               0
+StoreChachaState                                                80               0
+storeAesGcmGhashIV                                              46               0
+storeAesGcmCntr                                                 30               0
+StoreAesCcmIvState                                              64               0
+StoreAesCcmCtrState                                             30               0
+_sputc                                                          10               0
+spi_tran                                                        28               0
+SPI_Handler                                                      0               0
+_snputc                                                         16               0
+SMSC9220_SetTxFifo                                              22               0
+SMSC9220_SetSoftInt                                             18               0
+SMSC9220_RxStatusFifoLevelIrq                                   12               0
+SMSC9220_RecvSize                                               26               0
+SMSC9220_ReadID                                                  8               0
+SMSC9220_IsTxFifoAvailable                                      12               0
+SMSC9220_InitIrqs                                               26               0
+SMSC9220_EnableXmit                                             10               0
+SMSC9220_EnableRxDataIrq                                        38               0
+SMSC9220_ClearTxFifo                                            34               0
+SMSC9220_ClearSoftInt                                           18               0
+SMSC9220_ClearRxStatusFifoLevelIrq                              18               0
+SMSC9220_ClearAllIrqs                                           12               0
+SMSC9220_CheckReady                                             18               0
+Sleepus                                                         58               0
+__sig_exit                                                      10               0
+sha512_wrap                                                      6               0
+sha512_starts_wrap                                               6               0
+sha384_wrap                                                      6               0
+sha384_update_wrap                                               4               0
+sha384_starts_wrap                                               6               0
+sha384_process_wrap                                              4               0
+sha384_finish_wrap                                               4               0
+sha384_clone_wrap                                                4               0
+sha256_wrap                                                      6               0
+sha256_starts_wrap                                               6               0
+sha224_wrap                                                      6               0
+sha224_update_wrap                                               4               0
+sha224_starts_wrap                                               6               0
+sha224_process_wrap                                              4               0
+sha224_finish_wrap                                               4               0
+sha224_clone_wrap                                                4               0
+sha1_update_wrap                                                 4               0
+sha1_starts_wrap                                                 4               0
+sha1_process_wrap                                                4               0
+sha1_finish_wrap                                                 4               0
+sha1_clone_wrap                                                  4               0
+_seterr                                                         20               0
+runIt_perfFin                                                    2               0
+runIt_getCycles                                                 10               0
+runIt_buffAlign32                                               12               0
+__rt_memmove                                                   132               0
+__rt_memcpy                                                    138               0
+__rt_memclr                                                     68               0
+__rt_locale                                                      8               0
+__rt_heap_expand$2region                                         2               0
+__rt_heap_escrow$2region                                         2               0
+__rt_errno_addr$intlibspace                                      0               0
+RsaInitPubKeyDb                                                 20               0
+RsaExecPrivKeyExp                                               12               0
+RNG_PLAT_SetUserRngParameters                                   50               0
+Reset_Handler                                                    8               0
+_rand_init                                                       4               0
+rand                                                            48               0
+pxUDPPayloadBuffer_to_NetworkBuffer                             26               0
+pxResizeNetworkBufferWithDescriptor                              2               0
+pxPortInitialiseStack                                           30               0
+pxPacketBuffer_to_NetworkBuffer                                 26               0
+pvTaskIncrementMutexHeldCount                                  106               0
+prvTCPSocketIsActive                                            42               0
+prvTaskExitError                                                46               0
+prvTaskCheckFreeStackSpace                                      22               0
+prvSkipNameField                                                32               0
+prvResetNextTaskUnblockTime                                     42               0
+prvIdleTask                                                     12               0
+prvGetNumberOfParameters                                        46               0
+prvGetNextExpireTime                                            36               0
+prvCalculateSleepTime                                           62               0
+_printf_string                                                   8               0
+_printf_input_char                                              10               0
+_printf_char                                                    16               0
+PORT1_COMB_Handler                                               0               0
+PORT0_COMB_Handler                                               0               0
+PORT0_9_Handler                                                  0               0
+PORT0_8_Handler                                                  0               0
+PORT0_7_Handler                                                  0               0
+PORT0_6_Handler                                                  0               0
+PORT0_5_Handler                                                  0               0
+PORT0_4_Handler                                                  0               0
+PORT0_3_Handler                                                  0               0
+PORT0_2_Handler                                                  0               0
+PORT0_1_Handler                                                  0               0
+PORT0_15_Handler                                                 0               0
+PORT0_14_Handler                                                 0               0
+PORT0_13_Handler                                                 0               0
+PORT0_12_Handler                                                 0               0
+PORT0_11_Handler                                                 0               0
+PORT0_10_Handler                                                 0               0
+PORT0_0_Handler                                                  0               0
+PkaSetRegsSizesTab                                              46               0
+PkaFinishPka                                                    44               0
+PendSV_Handler                                                  72               0
+pcQueueGetName                                                  38               0
+pcApplicationHostnameHook                                        4               0
+NVIC_GetPendingIRQ                                              30               0
+NMI_Handler                                                      2               0
+mpi_get_digit                                                   54               0
+message_size_to_hash_mode                                       38               0
+MemManage_Handler                                                2               0
+mbedtls_zeroize_internal                                        18               0
+mbedtls_zeroize                                                 14               0
+mbedtls_zeroize                                                 14               0
+mbedtls_zeroize                                                 14               0
+mbedtls_zeroize                                                 14               0
+mbedtls_sha_update_internal                                     16               0
+mbedtls_sha_process_internal                                    14               0
+mbedtls_sha512_starts                                          144               0
+mbedtls_sha512_init                                              6               0
+mbedtls_sha512_free                                             20               0
+mbedtls_sha512_clone                                             6               0
+mbedtls_sha256_update                                            4               0
+mbedtls_sha256_starts                                           12               0
+mbedtls_sha256_process                                           4               0
+mbedtls_sha256_init                                             12               0
+mbedtls_sha256_free                                             12               0
+mbedtls_sha256_clone                                            16               0
+mbedtls_sha1_update                                              4               0
+mbedtls_sha1_starts                                              6               0
+mbedtls_sha1_process                                             4               0
+mbedtls_sha1_init                                               12               0
+mbedtls_sha1_free                                               12               0
+mbedtls_sha1_clone                                              16               0
+mbedtls_rsa_set_padding                                          6               0
+mbedtls_platform_set_calloc_free                                10               0
+mbedtls_pem_init                                                10               0
+mbedtls_mpi_zeroize                                             12               0
+mbedtls_mpi_init                                                16               0
+mbedtls_mpi_get_bit                                             32               0
+mbedtls_mng_lcsGet                                              38               0
+mbedtls_mng_getGenConfig                                         6               0
+mbedtls_memory_buffer_set_verify                                 6               0
+mbedtls_memory_buffer_alloc_verify                               2               0
+mbedtls_memory_buffer_alloc_free                                18               0
+mbedtls_md_list                                                  4               0
+mbedtls_md_init_ctx                                              4               0
+mbedtls_md_init                                                 10               0
+mbedtls_md_info_from_type                                       40               0
+mbedtls_md_get_type                                             96               0
+mbedtls_md_get_size                                              8               0
+mbedtls_md_get_name                                              8               0
+mbedtls_hmac_drbg_set_reseed_interval                            4               0
+mbedtls_hmac_drbg_set_prediction_resistance                      4               0
+mbedtls_hmac_drbg_set_entropy_len                                4               0
+mbedtls_hmac_drbg_init                                           6               0
+mbedtls_gcm_update                                               6               0
+mbedtls_gcm_starts                                               6               0
+mbedtls_gcm_free                                                 8               0
+mbedtls_gcm_finish                                               6               0
+mbedtls_entropy_update_manual                                    8               0
+mbedtls_entropy_gather                                           2               0
+mbedtls_entropy_free                                            18               0
+mbedtls_ecp_group_init                                          12               0
+mbedtls_ecp_group_copy                                          22               0
+mbedtls_ecp_curve_list                                           4               0
+mbedtls_ecp_curve_info_from_tls_id                              24               0
+mbedtls_ecp_curve_info_from_grp_id                              22               0
+mbedtls_ecdsa_init                                               4               0
+mbedtls_ecdsa_free                                               4               0
+mbedtls_ecdh_init                                               14               0
+mbedtls_dhm_init                                                 6               0
+mbedtls_ctr_drbg_set_reseed_interval                             4               0
+mbedtls_ctr_drbg_set_prediction_resistance                       4               0
+mbedtls_ctr_drbg_set_entropy_len                                 4               0
+mbedtls_ctr_drbg_init                                            6               0
+mbedtls_asn1_write_tag                                          24               0
+mbedtls_aes_setkey_enc                                           4               0
+mbedtls_aes_setkey_dec                                           4               0
+mbedtls_aes_free                                                12               0
+__main                                                           8               0
+lTCPIncrementTxPosition                                         10               0
+LoadIVState                                                     88               0
+LoadChachaState                                                 70               0
+loadAesGcmKey                                                   70               0
+loadAesGcmGhashSubkey                                           30               0
+loadAesGcmGhashIV                                               30               0
+loadAesGcmCntr                                                  30               0
+LoadAesCcmIvState                                               60               0
+LoadAesCcmdKey                                                 114               0
+LoadAesCcmCtrState                                              30               0
+LLF_RND_TurnOffTrng                                             32               0
+LLF_RND_TRNG_EnableRngSourceAndWatchdog                         26               0
+LLF_RND_RunTrngStartupTest                                       4               0
+LLF_RND_GetRoscSampleCnt                                        42               0
+LLF_RND_GetFastestRosc                                          26               0
+LLF_RND_GetCountRoscs                                           22               0
+isSrpVerValid                                                   22               0
+isSrpModulusSizeValid                                           32               0
+_is_digit                                                       14               0
+I2S_Handler                                                      0               0
+i2c_delay                                                       54               0
+HardFault_Handler                                               20               0
+GLCD_SetTextColor                                                6               0
+GLCD_SetBackColor                                                6               0
+GLCD_ScrollVertical                                              2               0
+getHashDigestSize                                               42               0
+getc                                                             4               0
+FreeRTOS_SetNetmask                                              6               0
+FreeRTOS_SetIPAddress                                            6               0
+FreeRTOS_SetGatewayAddress                                       6               0
+FreeRTOS_round_up                                               14               0
+FreeRTOS_mss                                                    22               0
+FreeRTOS_min_uint32                                             14               0
+FreeRTOS_min_uint32                                             14               0
+FreeRTOS_min_int32                                              14               0
+FreeRTOS_max_uint32                                             14               0
+FreeRTOS_issocketconnected                                      40               0
+FreeRTOS_IsNetworkUp                                             6               0
+FreeRTOS_get_rx_buf                                              8               0
+FreeRTOS_GetNetmask                                              6               0
+FreeRTOS_GetMACAddress                                           4               0
+FreeRTOS_GetIPAddress                                            6               0
+FreeRTOS_GetGatewayAddress                                       6               0
+FreeRTOS_GetDNSServerAddress                                     6               0
+FreeRTOS_connstatus                                             24               0
+FreeRTOS_CLIGetOutputBuffer                                      4               0
+__fpl_dretinf                                                   12               0
+FinishHash                                                      34               0
+ferror                                                           8               0
+error_mapping_cc_to_mbedtls_ecc                                312               0
+__errno$intlibspace                                              0               0
+ecp_mpi_load                                                    12               0
+ecp_grp_id_to_domain_id                                         68               0
+ecp_get_type                                                    20               0
+ecp_get_type                                                    20               0
+ecp_get_type                                                    20               0
+EcMontGetCurve25519Domain                                        4               0
+EcEdwGetDomain25519                                              4               0
+DUALTIMER_HANDLER                                                0               0
+Driver2CCHashErr                                                44               0
+Driver2CCAesErr                                                 72               0
+DMA_Handler                                                      0               0
+_dfltu                                                          38               0
+delay                                                           14               0
+DebugMon_Handler                                                 2               0
+__cyg_profile_func_exit                                          2               0
+__cyg_profile_func_enter                                         2               0
+CRTS_RSA_VER15_UTIL_foo                                          2               0
+Common_Sleepus                                                  58               0
+check_pointer                                                   14               0
+check_all_free                                                  26               0
+CC_RSA_PSS21_UTIL_foo                                            2               0
+CC_RndSetGenerateVectorFunc                                     22               0
+CC_RndDisableKatMode                                            18               0
+CC_PalPowerSaveModeStatus                                        6               0
+CC_PalPowerSaveModeInit                                          8               0
+CC_PalMemUnMap                                                   4               0
+CC_PalMemMap                                                     6               0
+CC_PalIsDmaBufferContiguous                                      4               0
+CC_PalDmaTerminate                                               2               0
+CC_PalDmaInit                                                    4               0
+CC_PalDmaContigBufferFree                                        4               0
+CC_PalDmaContigBufferAllocate                                    4               0
+CC_PalDmaBufferUnmap                                             4               0
+CC_PalDmaBufferMap                                               4               0
+CC_HalMaskInterrupt                                             10               0
+CC_HalClearInterruptBit                                         10               0
+CC_EcpkiGetSecp521r1DomainP                                      4               0
+CC_EcpkiGetSecp384r1DomainP                                      4               0
+CC_EcpkiGetSecp256r1DomainP                                      4               0
+CC_EcpkiGetSecp256k1DomainP                                      4               0
+CC_EcpkiGetSecp224r1DomainP                                      4               0
+CC_EcpkiGetSecp224k1DomainP                                      4               0
+CC_EcpkiGetSecp192r1DomainP                                      4               0
+CC_EcpkiGetSecp192k1DomainP                                      4               0
+CC_EcpkiGetEcDomain                                             20               0
+CC_CommonGetWordsCounterEffectiveSizeInBits                     52               0
+CC_CommonGetBytesCounterEffectiveSizeInBits                     50               0
+CC_CommonConvertLswMswWordsToLsbMsbBytes                        12               0
+CC_ChachaFinish                                                  8               0
+BusFault_Handler                                                 2               0
+bMayConnect                                                     36               0
+bIsValidNetworkDescriptor                                       42               0
+__asm___6_port_c_39a90d8d__prvStartFirstTask                    28               0
+__aeabi_ui2d                                                     0               0
+__aeabi_memset                                                  16               0
+__aeabi_memmove                                                  0               0
+__aeabi_memcpy                                                   0               0
+__aeabi_memclr                                                   0               0
+__aeabi_errno_addr                                               8               0
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_aes.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_aes.c
new file mode 100644
index 0000000..a86e76e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_aes.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/aes.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/gcm.h"
+
+/* CC */
+#include "mbedtls_cc_aes_key_wrap.h"
+
+
+/* pal */
+#include "test_pal_mem.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+#if defined(MBEDTLS_AES_C)
+
+#define AES_IV_SIZE     16
+#define AES_BLOCK_SIZE  16
+
+/************************************************************
+ *
+ * static functions prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_aesOfbTest(void);
+static RunItError_t runIt_aesCtrTestProfiling(size_t data_len);
+static RunItError_t runIt_aesCtrTest(void);
+static RunItError_t runIt_aesCbcTest(void);
+static RunItError_t runIt_aesEcbTest(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+
+static RunItError_t runIt_aesOfbTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_CIPHER_MODE_OFB) && defined(MBEDTLS_AES_ALT)
+    const uint32_t KEY_SIZE = 256;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_OFB.pdf */
+    static const uint8_t IV[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
+    static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
+    static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
+    static const uint8_t CYPHER[] = { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60 };
+
+    uint8_t key[KEY_SIZE / 8];
+    uint8_t iv[AES_IV_SIZE];
+    uint8_t buf[AES_BLOCK_SIZE];
+    mbedtls_aes_context ctx;
+
+    const char* TEST_NAME = "AES-OFB-256";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    /* Initialize aes engine */
+    RUNIT_API(mbedtls_aes_init(&ctx));
+
+    memcpy(key, KEY, sizeof(key));
+
+    /*
+     * encrypt
+     */
+    memcpy(buf, PLAIN, sizeof(buf));
+    memcpy(iv, IV, sizeof(iv));
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_ofb(&ctx, sizeof(buf), 0, iv, buf, buf) == 0);
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
+
+    /*
+     * decrypt
+     */
+    memcpy(buf, CYPHER, sizeof(buf));
+    memcpy(iv, IV, sizeof(iv));
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_dec");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_ofb(&ctx, sizeof(buf), 0, iv, buf, buf) == 0);
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
+
+bail:
+    RUNIT_API(mbedtls_aes_free(&ctx));
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] IV[%uB] PLAIN[%uB]", sizeof(key) * 8, sizeof(iv), sizeof(buf));
+#endif /* MBEDTLS_CIPHER_MODE_OFB && MBEDTLS_AES_ALT */
+    return rc;
+
+}
+
+static RunItError_t runIt_aesCtrTestProfiling(size_t data_len)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    const uint32_t KEY_SIZE = 128;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CTR.pdf */
+    static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81 };
+    static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
+    static const uint8_t NONCE[] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
+
+    size_t offset;
+    uint8_t key[KEY_SIZE / 8];
+    uint8_t *buf = NULL;
+    unsigned char nonce_counter[16];
+    unsigned char stream_block[16];
+    mbedtls_aes_context ctx;
+    char testParam[PARAM_LEN] = { 0 };
+
+    RunItPtr bufPtr;
+
+    const char* TEST_NAME = "AES-CTR-128";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    snprintf(testParam, PARAM_LEN - 1, "%uB", data_len);
+
+    ALLOC32(bufPtr, buf, data_len);
+
+    /* Initialize aes engine */
+    RUNIT_API(mbedtls_aes_init(&ctx));
+
+    memcpy(key, KEY, sizeof(key));
+
+    /*
+     * encrypt
+     */
+    memcpy(buf, PLAIN, sizeof(PLAIN));
+    memcpy(nonce_counter, NONCE, sizeof(nonce_counter));
+    offset = 0;
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_W_PARAM(testParam, mbedtls_aes_crypt_ctr(&ctx, data_len, &offset, nonce_counter, stream_block, buf, buf) == 0);
+
+bail:
+    RUNIT_API(mbedtls_aes_free(&ctx));
+
+    FREE_IF_NOT_NULL(bufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", (unsigned int)KEY_SIZE, (unsigned int)data_len);
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+    return rc;
+}
+
+static RunItError_t runIt_aesCtrTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_CIPHER_MODE_CTR)
+    const uint32_t KEY_SIZE = 256;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CTR.pdf */
+    static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
+    static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
+    static const uint8_t CYPHER[] = { 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28 };
+    static const uint8_t NONCE[] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
+
+    size_t offset;
+    uint8_t key[KEY_SIZE / 8];
+    uint8_t buf[AES_BLOCK_SIZE];
+    unsigned char nonce_counter[16];
+    unsigned char stream_block[16];
+    mbedtls_aes_context ctx;
+
+    const char* TEST_NAME = "AES-CTR-256";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    /* Initialize aes engine */
+    RUNIT_API(mbedtls_aes_init(&ctx));
+
+    memcpy(key, KEY, sizeof(key));
+
+    /*
+     * encrypt
+     */
+    memcpy(buf, PLAIN, sizeof(buf));
+    memcpy(nonce_counter, NONCE, sizeof(nonce_counter));
+    offset = 0;
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_ctr(&ctx, sizeof(buf), &offset, nonce_counter, stream_block, buf, buf) == 0);
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
+
+    /*
+     * decrypt
+     */
+    memcpy(buf, CYPHER, sizeof(buf));
+    memcpy(nonce_counter, NONCE, sizeof(nonce_counter));
+    offset = 0;
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_dec");
+
+    /* set key into context, also in aes ctr decrypt, nonce should be encrypted */
+    /* aes ctr is fully symmetric so we use the encrypt operation to decrypt */
+    /* by using mbedtls_aes_setkey_enc we select an encryption operation */
+
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_ctr(&ctx, sizeof(buf), &offset, nonce_counter, stream_block, buf, buf) == 0);
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
+
+bail:
+    RUNIT_API(mbedtls_aes_free(&ctx));
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", (unsigned int)KEY_SIZE, sizeof(buf));
+#endif /* MBEDTLS_CIPHER_MODE_CTR */
+    return rc;
+}
+
+static RunItError_t runIt_aesCbcTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_CIPHER_MODE_CBC)
+
+    const uint32_t KEY_SIZE = 256;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CBC.pdf */
+    static const uint8_t IV[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
+    static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
+    static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
+    static const uint8_t CYPHER[] = { 0xF5, 0x8C, 0x4C, 0x04, 0xD6, 0xE5, 0xF1, 0xBA, 0x77, 0x9E, 0xAB, 0xFB, 0x5F, 0x7B, 0xFB, 0xD6 };
+
+    uint8_t key[KEY_SIZE / 8];
+    uint8_t buf[AES_BLOCK_SIZE];
+    uint8_t iv[AES_IV_SIZE];
+    mbedtls_aes_context ctx;
+
+    const char* TEST_NAME = "AES-CBC-256";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    /* Initialize aes engine */
+    RUNIT_API(mbedtls_aes_init(&ctx));
+
+    memcpy(key, KEY, sizeof(key));
+
+    /*
+     * encrypt
+     */
+    memcpy(iv, IV, sizeof(iv));
+    memcpy(buf, PLAIN, sizeof(buf));
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_enc");
+    RUNIT_PRINT_BUF(iv, AES_IV_SIZE, "iv_enc");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_ENCRYPT, sizeof(buf), iv, buf, buf) == 0);
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
+
+    /*
+     * decrypt
+     */
+    memcpy(iv, IV, sizeof(iv));
+    memcpy(buf, CYPHER, sizeof(buf));
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init_dec");
+    RUNIT_PRINT_BUF(iv, AES_IV_SIZE, "iv_dec");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_cbc(&ctx, MBEDTLS_AES_DECRYPT, sizeof(buf), iv, buf, buf) == 0);
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
+
+bail:
+    RUNIT_API(mbedtls_aes_free(&ctx));
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", sizeof(key) * 8, sizeof(buf));
+#endif /* MBEDTLS_CIPHER_MODE_CBC */
+    return rc;
+}
+
+static RunItError_t runIt_aesEcbTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    const uint32_t KEY_SIZE = 256;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CBC.pdf */
+    static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
+    static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
+    static const uint8_t CYPHER[] = { 0xF3, 0xEE, 0xD1, 0xBD, 0xB5, 0xD2, 0xA0, 0x3C, 0x06, 0x4B, 0x5A, 0x7E, 0x3D, 0xB1, 0x81, 0xF8 };
+
+    uint8_t key[KEY_SIZE / 8];
+    uint8_t buf[AES_BLOCK_SIZE];
+    mbedtls_aes_context ctx;
+
+    const char* TEST_NAME = "AES-ECB-256";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    /* Initialize aes engine */
+    RUNIT_API(mbedtls_aes_init(&ctx));
+
+    memcpy(key, KEY, sizeof(key));
+
+    /*
+     * encrypt
+     */
+    memcpy(buf, PLAIN, sizeof(buf));
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "init");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_enc(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_ENCRYPT, buf, buf) == 0);
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, CYPHER, AES_BLOCK_SIZE) == 0);
+
+    /*
+     * decrypt
+     */
+    memcpy(buf, CYPHER, sizeof(buf));
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "encrypted");
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_aes_setkey_dec(&ctx, key, KEY_SIZE) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, buf, buf) == 0);
+
+    RUNIT_PRINT_BUF(buf, AES_BLOCK_SIZE, "decrypted");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, PLAIN, AES_BLOCK_SIZE) == 0);
+
+bail:
+    RUNIT_API(mbedtls_aes_free(&ctx));
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", sizeof(key) * 8, sizeof(buf));
+    return rc;
+
+}
+
+
+
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_aesTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "AES";
+    RUNIT_TEST_START(TEST_NAME);
+
+
+    RUNIT_ASSERT(runIt_aesEcbTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_aesCbcTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_aesCtrTest() == RUNIT_ERROR__OK);
+
+    RUNIT_ASSERT(runIt_aesOfbTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_aesCtrTestProfiling(16) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_aesCtrTestProfiling(128) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_aesCtrTestProfiling(1024) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_aesCtrTestProfiling(8192) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_aesCtrTestProfiling(65535) == RUNIT_ERROR__OK);
+
+bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+
+#endif /* MBEDTLS_AES_C */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_asset_prov.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_asset_prov.c
new file mode 100644
index 0000000..e0efdb4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_asset_prov.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/cipher.h"
+#include "mbedtls/timing.h"
+
+/* CC pal */
+#include "mbedtls_cc_util_asset_prov.h"
+#include "mbedtls_cc_mng.h"
+#include "cc_pal_types.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+#include "run_integration_otp.h"
+
+#ifdef RUNIT_PIE_ENABLED
+/* include sbrom data file to determine whether we are running system flows */
+#include "bsv_integration_data_def.h"
+#endif /* RUNIT_PIE_ENABLED */
+
+#ifndef RUNIT_ASSET_PROV_SYS_FLOW_ENABLE
+#define RUNIT_ASSET_PROV_SYS_FLOW_ENABLE 0
+#endif
+
+#ifndef RUNIT_ASSET_PROV_SKIP_TEST
+#define RUNIT_ASSET_PROV_SKIP_TEST 0
+#endif
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_assetProv(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+#if ! RUNIT_ASSET_PROV_SYS_FLOW_ENABLE
+static RunItError_t runIt_assetProv(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static const uint32_t ASSET_ID = 0x19952006;
+
+    static uint32_t OTP_SECURE_2_HBK128_VALUES[] = {
+
+        /*  [0x00-0x07]: 256bit Device root key (HUK) */
+        0x01020408, 0x01010101, 0x01020408, 0x02020202, 0x01020408, 0x04040404, 0x01020408, 0x08080808,
+        /*  [0x08-0x0B]: 128bit ICV Provosioning secret (Kpicv) */
+        0xEEEEAAAA, 0x11115555, 0x11115555, 0xEEEEAAAA,
+        /*  [0x0C-0x0F]: 128bit ICV Provosioning secret (Kceicv) */
+        0x00000000, 0x00000000, 0x00000000, 0x00000000,
+        /*  [0x10]: manufacturer programmed flag */
+        0x3C0040E0,
+        /*  [0x11-0x14]:  HBK0 */
+        0x21F7B953, 0xFE56A24D, 0x4E3EC4EF, 0xC21F3C40,
+        /*  [0x15-0x18]: HBK1 */
+        0x2FF17BDA, 0xE93EB506, 0x9AA54F0B, 0x4ADE752B,
+        /*  [0x19-0x1C]: 128bit OEM provisioning secret (Kcp) */
+        0x0000AAAA,  0x11115555, 0x11115555, 0x0000AAAA,
+        /*  [0x1D-0x20]: 128bit OEM code encryption secret (Kce) */
+        0x00000000, 0x00000000, 0x00000000, 0x00000000,
+        /*  [0x21]: OEM programmed flag */
+        0x00005838,
+        /*  [0x22-0x23]: Hbk0 trusted FW min version */
+        0x00000001, 0x00000000,
+        /*  [0x24-0x26]: Hbk1 trusted FW min version */
+        0x00000003, 0x00000000, 0x00000000,
+        /*  [0x27]: general purpose configuration flag */
+        0x00000000,
+        /*  [0x28-0x2B] - 128b DCU lock mask */
+        0x55551111, 0xAAAAEEEE, 0x55551111, 0xAAAAEEEE,
+
+    };
+
+    static const uint8_t ASSET_PKG[] = {
+        0x74, 0x65, 0x73, 0x41, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0xb8, 0x4b, 0xce, 0x45, 0x9d, 0x6b, 0x4d, 0xc2, 0xa2, 0x7d, 0xb3, 0x92,
+        0x47, 0x1a, 0x40, 0xc5, 0x43, 0x17, 0xad, 0x30, 0xeb, 0xa2, 0x76, 0xa3, 0xb8, 0x50, 0xc3, 0x6e,
+        0xbc, 0x1f, 0x8a, 0x87, 0xf7, 0x66, 0x91, 0x77, 0x8c, 0x18, 0xae, 0x25, 0x5e, 0x86, 0x6e, 0x38,
+        0x96, 0xdc, 0x85, 0x1b, 0xc1, 0x65, 0xd0, 0x14, 0x1b, 0x64, 0xf9, 0xb5, 0xa9, 0x1a, 0xbf, 0x22,
+        0x50, 0xab, 0xd9, 0xba, 0x4e, 0xad, 0x5e, 0x2f, 0x8b, 0xcb, 0x1c, 0x77, 0xde, 0xcf, 0xf1, 0x95,
+        0xc1, 0x21, 0x90, 0xf4, 0x90, 0x12, 0x0f, 0xeb, 0x05, 0x70, 0xea, 0x5b, 0x64, 0xf9, 0x9b, 0xb3,
+        0x98, 0x08, 0x3b, 0xb5, 0xf3, 0x09, 0x06, 0x12, 0x5e, 0x41, 0x31, 0x37, 0x9a, 0xcc, 0x59, 0x21,
+        0x2f, 0x24, 0x6b, 0x37, 0x0a, 0x0d, 0x68, 0x92, 0x6c, 0x6d, 0xfc, 0xdc, 0xe5, 0x72, 0xfc, 0x79,
+        0xf3, 0x98, 0x7c, 0x7f, 0x6f, 0x4d, 0xbc, 0xe8, 0x31, 0xe8, 0x03, 0x26, 0x3e, 0x51, 0x97, 0x80,
+        0x15, 0xb0, 0xad, 0x52, 0x00, 0x1d, 0x0f, 0x89, 0x9b, 0xa7, 0x7a, 0xa2, 0xa8, 0x39, 0x4c, 0x39,
+        0x76, 0xdc, 0x13, 0x79, 0x85, 0x92, 0x5c, 0xc2, 0x07, 0xce, 0xeb, 0x79, 0xbe, 0x91, 0xf8, 0x6f,
+        0xcc, 0xee, 0x61, 0x6e, 0xcc, 0xbe, 0xa0, 0x18, 0xc9, 0x58, 0x5d, 0x49, 0xf0, 0x6a, 0x18, 0x82,
+        0xf9, 0x03, 0x9f, 0x8b, 0x44, 0x74, 0xd4, 0x99, 0xb6, 0x27, 0xa9, 0x9b, 0x3a, 0x9c, 0x86, 0x21,
+        0x51, 0x55, 0xbf, 0xbe, 0x17, 0xe0, 0x91, 0x61, 0xcd, 0x28, 0x2e, 0x2c, 0x2a, 0xb7, 0xb8, 0xc4,
+        0x1e, 0x3f, 0x41, 0x42, 0x2e, 0x61, 0xda, 0x4b, 0x2f, 0x02, 0x32, 0x88, 0x57, 0xfe, 0x48, 0x82,
+        0x18, 0x62, 0x39, 0xfa, 0x56, 0xc4, 0x17, 0x72, 0x24, 0xee, 0xfe, 0xe2, 0x8a, 0x29, 0x67, 0x1a,
+        0xd7, 0x51, 0xb0, 0xc3, 0xc1, 0xa4, 0xc9, 0x07, 0xd9, 0xb5, 0x28, 0x90, 0xf0, 0xd2, 0x7a, 0x4f,
+        0x47, 0x5b, 0x08, 0x0e, 0x79, 0x5a, 0xbf, 0xf0, 0x7d, 0x6a, 0x03, 0x08, 0xd4, 0x81, 0x61, 0xae,
+    };
+
+
+    static const uint8_t EXP_ASSET_BIN[] = {
+        0x10, 0x00, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
+    };
+
+
+    uint32_t *pPkg = NULL;
+    uint32_t *pBuf = NULL;
+
+    RunItPtr pkgPtr;
+    RunItPtr bufPtr;
+
+    size_t assetLen = CC_ASSET_PROV_MAX_ASSET_PKG_SIZE;
+
+    const char* TEST_NAME = "Asset Provisioning";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC32_AND_COPY(pkgPtr, pPkg, ASSET_PKG, sizeof(ASSET_PKG));
+    ALLOC32(bufPtr, pBuf, CC_ASSET_PROV_MAX_ASSET_PKG_SIZE);
+
+    RUNIT_ASSERT(runIt_burnOtp((unsigned int *)OTP_SECURE_2_HBK128_VALUES, CC_MNG_LCS_SEC_ENABLED) == RUNIT_ERROR__OK);
+
+    RUNIT_ASSERT_API(mbedtls_util_asset_pkg_unpack(ASSET_PROV_KEY_TYPE_KCP,
+                                                   ASSET_ID,
+                                                   pPkg,
+                                                   sizeof(ASSET_PKG),
+                                                   pBuf,
+                                                   &assetLen) == CC_OK);
+
+    RUNIT_ASSERT(memcmp(pBuf, EXP_ASSET_BIN, assetLen) == 0);
+
+bail:
+    FREE_IF_NOT_NULL(pkgPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ASSET[%"PRIu32"B]", (uint32_t)256);
+    return rc;
+}
+#else
+static RunItError_t runIt_assetProv(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if ! RUNIT_ASSET_PROV_SKIP_TEST
+    uint32_t lcs = 0xffffffff;
+
+    static const uint32_t ASSET_ID = RUNIT_ASSET_PROV_ASSET_ID;
+
+    static const uint8_t ASSET_PKG[] = { RUNIT_ASSET_PROV_PKG };
+
+    static const uint8_t EXP_ASSET_BIN[] = { RUNIT_ASSET_PROV_PKG_BIN };
+
+    uint32_t *pPkg = NULL;
+    uint32_t *pBuf = NULL;
+
+    RunItPtr pkgPtr;
+    RunItPtr bufPtr;
+
+    size_t assetLen;
+
+    const char* TEST_NAME = "Asset Provisioning";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC32_AND_COPY(pkgPtr, pPkg, ASSET_PKG, sizeof(ASSET_PKG));
+    ALLOC32(bufPtr, pBuf, CC_ASSET_PROV_MAX_ASSET_PKG_SIZE);
+
+    RUNIT_ASSERT(runIt_getLcs(&lcs) == RUNIT_ERROR__OK);
+    RUNIT_PRINT_DBG("lcs[%"PRIu32"]\n", (uint32_t)lcs);
+
+    RUNIT_ASSERT_API(mbedtls_util_asset_pkg_unpack(ASSET_PROV_KEY_TYPE_KPICV,
+                                                   ASSET_ID,
+                                                   pPkg,
+                                                   sizeof(ASSET_PKG),
+                                                   pBuf,
+                                                   &assetLen) == CC_OK);
+
+    RUNIT_ASSERT(memcmp(pBuf, EXP_ASSET_BIN, assetLen) == 0);
+
+bail:
+    FREE_IF_NOT_NULL(pkgPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "LCS[%"PRIu32"] ASSET[%"PRIu32"B]", (uint32_t)lcs, (uint32_t)256);
+#endif /* RUNIT_ASSET_PROV_SKIP_TEST */
+    return rc;
+}
+
+#endif /* RUNIT_ASSET_PROV_SYS_FLOW_ENABLE */
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_assetProvTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+
+#if !RUNIT_ASSET_PROV_SKIP_TEST
+    const char* TEST_NAME = "AssetProv";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_assetProv() == RUNIT_ERROR__OK);
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+#endif /* !RUNIT_ASSET_PROV_SKIP_TEST */
+
+    (void)runIt_assetProv;
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ccm.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ccm.c
new file mode 100644
index 0000000..84c6e92
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ccm.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/ccm.h"
+#include "mbedtls_cc_ccm_star.h"
+#include "mbedtls_ccm_common.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/ctr_drbg.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+#define AESCCM_DEFAULT_NONCE_SIZE 16
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_ccm(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_ccmStarEncOnly(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CCM.pdf */
+    static const uint8_t KEY[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
+    const uint8_t AD[20] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 };
+    const uint8_t MSG[24] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
+    const uint8_t RES[] = {0x5a, 0x21, 0xaf, 0x13, 0x2a, 0xf4, 0x02, 0x43, 0x31, 0xba, 0x7c, 0x4d, 0x7c, 0x3d, 0xcc, 0x0e, 0x19, 0x3e, 0x4d, 0x46, 0xa5, 0xc9, 0xa6, 0x82, };
+
+    static const size_t TAG_LEN = 0;
+
+    uint32_t FrameCounter = 5;
+    unsigned char nonceBuff[MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES];
+    uint8_t srcAddr[16] = { 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e };
+
+    uint8_t buf[32];
+    mbedtls_ccm_context *pCtx = NULL;
+    RunItPtr ctxPtr;
+
+    const char* TEST_NAME = "CCM STAR - ENC ONLY";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ccm_context, ctxPtr, pCtx);
+
+    /* generate random buffer */
+    RUNIT_ASSERT_API(mbedtls_ccm_star_nonce_generate((uint8_t*)srcAddr, FrameCounter, TAG_LEN, nonceBuff) == 0);
+
+    /* Initialize ccm engine */
+    RUNIT_API(mbedtls_ccm_init(pCtx));
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, KEY, 8 * sizeof(KEY)) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_ccm_star_encrypt_and_tag(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), MSG, buf, buf + sizeof(MSG), TAG_LEN) == 0);
+
+    RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "signed");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, RES, sizeof(MSG) + TAG_LEN) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_ccm_star_auth_decrypt(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), RES, buf, RES + sizeof(MSG), TAG_LEN) == 0);
+
+    RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "verified");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, MSG, sizeof(MSG)) == 0);
+
+bail:
+    RUNIT_API(mbedtls_ccm_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] AAD[%"PRIu32"B] MSG[%"PRIu32"B] TAG[%"PRIu32"B]",
+                                   (uint32_t)8 * sizeof(KEY), (uint32_t)sizeof(AD), (uint32_t)sizeof(MSG), (uint32_t)TAG_LEN);
+    return rc;
+}
+
+static RunItError_t runIt_ccmStar(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CCM.pdf */
+    static const uint8_t KEY[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
+    const uint8_t AD[20] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 };
+    const uint8_t MSG[24] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
+    const uint8_t RES[] = {0x07, 0x11, 0x7e, 0x35, 0x39, 0xb2, 0xed, 0x4c, 0x84, 0x91, 0x66, 0x07, 0x0b, 0x33, 0xe6, 0x39, 0x0c, 0xf8, 0xda, 0xcc, 0x37, 0x44, 0x00, 0x9d, 0xb1, 0xac, 0x43, 0x81, 0x81, 0x8e, 0x17, 0x6d, 0x54, 0x63, 0x78, 0x4b, 0xd7, 0xd0, 0xc5, 0x46, };
+
+    static const size_t TAG_LEN = 16;
+
+    uint32_t FrameCounter = 5;
+    unsigned char nonceBuff[MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES];
+    uint8_t srcAddr[16] = { 0x39, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e };
+
+    uint8_t buf[40];
+    mbedtls_ccm_context *pCtx = NULL;
+    RunItPtr ctxPtr;
+
+    const char* TEST_NAME = "CCM STAR";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ccm_context, ctxPtr, pCtx);
+
+    /* generate random buffer */
+    RUNIT_ASSERT_API(mbedtls_ccm_star_nonce_generate((uint8_t*)srcAddr, FrameCounter, TAG_LEN, nonceBuff) == 0);
+
+    /* Initialize ccm engine */
+    RUNIT_API(mbedtls_ccm_init(pCtx));
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, KEY, 8 * sizeof(KEY)) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_ccm_star_encrypt_and_tag(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), MSG, buf, buf + sizeof(MSG), TAG_LEN) == 0);
+
+    RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "signed");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, RES, sizeof(MSG) + TAG_LEN) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_ccm_star_auth_decrypt(pCtx, sizeof(MSG), nonceBuff, MBEDTLS_AESCCM_STAR_NONCE_SIZE_BYTES, AD, sizeof(AD), RES, buf, RES + sizeof(MSG), TAG_LEN) == 0);
+
+    RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "verified");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, MSG, sizeof(MSG)) == 0);
+
+bail:
+    RUNIT_API(mbedtls_ccm_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] AAD[%"PRIu32"B] MSG[%"PRIu32"B] TAG[%"PRIu32"B]",
+                                   (uint32_t)8 * sizeof(KEY), (uint32_t)sizeof(AD), (uint32_t)sizeof(MSG), (uint32_t)TAG_LEN);
+    return rc;
+}
+
+static RunItError_t runIt_ccm(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_CCM_C)
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CCM.pdf */
+    static const uint8_t KEY[16] = { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f };
+    static const uint8_t IV[12] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b };
+    const uint8_t AD[20] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 };
+    const uint8_t MSG[24] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
+    const uint8_t RES[32] = { 0xE3, 0xB2, 0x01, 0xA9, 0xF5, 0xB7, 0x1A, 0x7A, 0x9B, 0x1C, 0xEA, 0xEC, 0xCD, 0x97, 0xE7, 0x0B, 0x61, 0x76, 0xAA, 0xD9, 0xA4, 0x42, 0x8A, 0xA5, 0x48, 0x43, 0x92, 0xFB, 0xC1, 0xB0, 0x99, 0x51 };
+    static const size_t TAG_LEN = 8;
+
+    uint8_t buf[32];
+    RunItPtr ctxPtr;
+    mbedtls_ccm_context *pCtx = NULL;
+
+    const char* TEST_NAME = "CCM";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ccm_context, ctxPtr, pCtx);
+
+    /* Initialize ccm engine */
+    RUNIT_API(mbedtls_ccm_init(pCtx));
+
+    /* set key into context */
+    RUNIT_ASSERT_API(mbedtls_ccm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, KEY, 8 * sizeof(KEY)) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_ccm_encrypt_and_tag(pCtx, sizeof(MSG), IV, sizeof(IV), AD, sizeof(AD), MSG, buf, buf + sizeof(MSG), TAG_LEN) == 0);
+
+    RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "signed");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, RES, sizeof(MSG) + TAG_LEN) == 0);
+
+    /* perform cryptographic operation */
+    RUNIT_ASSERT_API(mbedtls_ccm_auth_decrypt(pCtx, sizeof(MSG), IV, sizeof(IV), AD, sizeof(AD), RES, buf, RES + sizeof(MSG), TAG_LEN) == 0);
+
+    RUNIT_PRINT_BUF(buf, sizeof(MSG) + TAG_LEN, "verified");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(buf, MSG, sizeof(MSG)) == 0);
+
+bail:
+    RUNIT_API(mbedtls_ccm_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] AAD[%"PRIu32"B] MSG[%"PRIu32"B]",
+                                   (uint32_t)8 * sizeof(KEY), (uint32_t)sizeof(AD), (uint32_t)sizeof(MSG));
+#endif /* MBEDTLS_CCM_C */
+    return rc;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_ccmTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "CCM";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_ccm() == RUNIT_ERROR__OK);
+#ifdef MBEDTLS_CCM_ALT
+    RUNIT_ASSERT(runIt_ccmStar() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ccmStarEncOnly() == RUNIT_ERROR__OK);
+#else
+    (void)runIt_ccmStar;
+    (void)runIt_ccmStarEncOnly;
+#endif
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_chacha.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_chacha.c
new file mode 100644
index 0000000..ca97fdc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_chacha.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/timing.h"
+
+/* CC pal */
+#if defined(CC_CONFIG_CC_CHACHA_POLY_SUPPORT)
+#include "mbedtls/chacha20.h"
+#include "mbedtls/poly1305.h"
+#include "mbedtls/chachapoly.h"
+#endif
+#include "cc_pal_types.h"
+#include "cc_common.h"
+
+/* pal */
+#include "test_pal_mem.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+/************************************************************
+ *
+ * static functions prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_Chacha(void);
+static RunItError_t runIt_ChachaPolyEncrypt(void);
+static RunItError_t runIt_ChachaPolyDecrypt(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_Chacha(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(CC_CONFIG_CC_CHACHA_POLY_SUPPORT)
+    static mbedtls_chacha_nonce pIVCounter = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x00 };
+    static mbedtls_chacha_key pKey = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };
+    static uint32_t initialCounter = 1;
+    static uint8_t pExpectedDataOut[] = { 0x6e, 0x2e, 0x35, 0x9a, 0x25, 0x68, 0xf9, 0x80, 0x41, 0xba, 0x07, 0x28, 0xdd, 0x0d, 0x69, 0x81, 0xe9, 0x7e, 0x7a, 0xec, 0x1d, 0x43, 0x60, 0xc2, 0x0a, 0x27, 0xaf, 0xcc, 0xfd, 0x9f, 0xae, 0x0b, 0xf9, 0x1b, 0x65, 0xc5, 0x52, 0x47, 0x33, 0xab, 0x8f, 0x59, 0x3d, 0xab, 0xcd, 0x62, 0xb3, 0x57, 0x16, 0x39, 0xd6, 0x24, 0xe6, 0x51, 0x52, 0xab, 0x8f, 0x53, 0x0c, 0x35, 0x9f, 0x08, 0x61, 0xd8, 0x07, 0xca, 0x0d, 0xbf, 0x50, 0x0d, 0x6a, 0x61, 0x56, 0xa3, 0x8e, 0x08, 0x8a, 0x22, 0xb6, 0x5e, 0x52, 0xbc, 0x51, 0x4d, 0x16, 0xcc, 0xf8, 0x06, 0x81, 0x8c, 0xe9, 0x1a, 0xb7, 0x79, 0x37, 0x36, 0x5a, 0xf9, 0x0b, 0xbf, 0x74, 0xa3, 0x5b, 0xe6, 0xb4, 0x0b, 0x8e, 0xed, 0xf2, 0x78, 0x5e, 0x42, 0x87, 0x4d };
+    uint8_t pDataIn[] = { 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e };
+    uint32_t j=0;
+    static const uint32_t DATA_OUT_SIZE = 114;
+    uint8_t *pDataOut = NULL;
+    mbedtls_chacha20_context ctx;
+    RunItPtr dataOutPtr;
+    uint32_t blockSize = MBEDTLS_CHACHA_BLOCK_SIZE_BYTES;
+    uint32_t dataLen = sizeof(pDataIn);
+    const char* TEST_NAME = "ChaCha";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(dataOutPtr, pDataOut, DATA_OUT_SIZE);
+
+    /*
+     * integrated test
+     */
+    memset(pDataOut, 0, DATA_OUT_SIZE);
+    RUNIT_ASSERT_W_PARAM("encrypt", mbedtls_chacha20_crypt( pKey,
+                                                            pIVCounter,
+                                                            initialCounter,
+                                                            sizeof(pDataIn),
+                                                            pDataIn,
+                                                            pDataOut ) == CC_OK);
+
+    RUNIT_ASSERT(memcmp(pDataOut, pExpectedDataOut, sizeof(pDataIn)) == 0);
+
+    /*
+     * non integrated test
+     */
+    memset(pDataOut, 0, DATA_OUT_SIZE);
+
+    /* Initialise chacha */
+    RUNIT_API(mbedtls_chacha20_init(&ctx));
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_chacha20_setkey( &ctx, pKey ), CC_OK);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_chacha20_starts( &ctx, pIVCounter, initialCounter ), CC_OK);
+    /* Iterate over all  blocks */
+    for (j = 0; j < (blockSize * (dataLen / blockSize)); j += blockSize)
+    {
+        RUNIT_ASSERT_WITH_RESULT(mbedtls_chacha20_update( &ctx, blockSize , pDataIn + j, pDataOut + j ), CC_OK);
+    }
+
+    /* process remainder of last block */
+    blockSize = dataLen % blockSize;
+    if (blockSize)
+    {
+        RUNIT_ASSERT_WITH_RESULT(mbedtls_chacha20_update(&ctx, blockSize ,pDataIn + j, pDataOut + j), CC_OK);
+    }
+
+    /* free context */
+    RUNIT_API(mbedtls_chacha20_free(&ctx));
+
+    RUNIT_ASSERT(memcmp(pDataOut, pExpectedDataOut, sizeof(pDataIn)) == 0);
+
+
+bail:
+
+    FREE_IF_NOT_NULL(dataOutPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] DATA_IN[%uB]", sizeof(pKey) * 8, sizeof(pDataIn));
+#endif
+    return rc;
+}
+
+static RunItError_t runIt_ChachaPolyEncrypt(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(CC_CONFIG_CC_CHACHA_POLY_SUPPORT)
+    static const uint8_t DATA_IN[] = { 0x4c, 0x61, 0x64, 0x69, 0x65, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x47, 0x65, 0x6e, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x39, 0x39, 0x3a, 0x20, 0x49, 0x66, 0x20, 0x49, 0x20, 0x63, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x79, 0x6f, 0x75, 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x74, 0x69, 0x70, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x75, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x75, 0x6e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x77, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x62, 0x65, 0x20, 0x69, 0x74, 0x2e };
+    static const uint8_t ADD_DATA[] = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 };
+
+    static mbedtls_chacha_key pKey = { 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f };    //pKey
+    static mbedtls_chacha_nonce pNonce = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 };
+    static const uint8_t pExpectedDataOut[] = { 0xd3, 0x1a, 0x8d, 0x34, 0x64, 0x8e, 0x60, 0xdb, 0x7b, 0x86, 0xaf, 0xbc, 0x53, 0xef, 0x7e, 0xc2, 0xa4, 0xad, 0xed, 0x51, 0x29, 0x6e, 0x08, 0xfe, 0xa9, 0xe2, 0xb5, 0xa7, 0x36, 0xee, 0x62, 0xd6, 0x3d, 0xbe, 0xa4, 0x5e, 0x8c, 0xa9, 0x67, 0x12, 0x82, 0xfa, 0xfb, 0x69, 0xda, 0x92, 0x72, 0x8b, 0x1a, 0x71, 0xde, 0x0a, 0x9e, 0x06, 0x0b, 0x29, 0x05, 0xd6, 0xa5, 0xb6, 0x7e, 0xcd, 0x3b, 0x36, 0x92, 0xdd, 0xbd, 0x7f, 0x2d, 0x77, 0x8b, 0x8c, 0x98, 0x03, 0xae, 0xe3, 0x28, 0x09, 0x1b, 0x58, 0xfa, 0xb3, 0x24, 0xe4, 0xfa, 0xd6, 0x75, 0x94, 0x55, 0x85, 0x80, 0x8b, 0x48, 0x31, 0xd7, 0xbc, 0x3f, 0xf4, 0xde, 0xf0, 0x8e, 0x4b, 0x7a, 0x9d, 0xe5, 0x76, 0xd2, 0x65, 0x86, 0xce, 0xc6, 0x4b, 0x61, 0x16 };
+    static const uint8_t pExpectedMac[] = { 0x1a, 0xe1, 0x0b, 0x59, 0x4f, 0x09, 0xe2, 0x6a, 0x7e, 0x90, 0x2e, 0xcb, 0xd0, 0x60, 0x06, 0x91 };
+
+    uint8_t *pCcDataOutBuff = NULL;
+    uint8_t *pMacBuffRaw = NULL;
+    uint8_t *pDataInRaw = NULL;
+    uint8_t *pAddDataRaw = NULL;
+
+    RunItPtr ccDataOutBuffPtr;
+    RunItPtr macBuffRawPtr;
+    RunItPtr dataInRawPtr;
+    RunItPtr addDataRawPtr;
+
+    mbedtls_chachapoly_context ctx;
+
+    const char* TEST_NAME = "ChaCha-POLY-Encrypt";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(ccDataOutBuffPtr, pCcDataOutBuff, sizeof(pExpectedDataOut));
+    ALLOC(macBuffRawPtr, pMacBuffRaw, MBEDTLS_POLY_MAC_SIZE_BYTES);
+    ALLOC_AND_COPY(dataInRawPtr, pDataInRaw, DATA_IN, sizeof(DATA_IN));
+    ALLOC_AND_COPY(addDataRawPtr, pAddDataRaw, ADD_DATA, sizeof(ADD_DATA));
+
+    RUNIT_API(mbedtls_chachapoly_init(&ctx));
+
+    RUNIT_ASSERT_WITH_RESULT( mbedtls_chachapoly_setkey( &ctx, pKey ), CC_OK);
+
+    RUNIT_ASSERT_W_PARAM("encrypt", mbedtls_chachapoly_encrypt_and_tag( &ctx,
+                                                                        sizeof(DATA_IN),
+                                                                        pNonce,
+                                                                        pAddDataRaw,
+                                                                        sizeof(ADD_DATA),
+                                                                        pDataInRaw,
+                                                                        pCcDataOutBuff,
+                                                                        pMacBuffRaw ) == CC_OK);
+
+
+    RUNIT_PRINT_BUF(pCcDataOutBuff, sizeof(pExpectedDataOut), "ccDataOutBuff");
+    RUNIT_PRINT_BUF(pExpectedDataOut, sizeof(pExpectedDataOut), "pExpectedDataOut");
+
+    RUNIT_ASSERT(memcmp(pCcDataOutBuff, pExpectedDataOut, sizeof(pExpectedDataOut)) == 0);
+    RUNIT_ASSERT(memcmp(pMacBuffRaw, pExpectedMac, sizeof(pExpectedMac)) == 0);
+
+bail:
+    FREE_IF_NOT_NULL(ccDataOutBuffPtr);
+    FREE_IF_NOT_NULL(dataInRawPtr);
+    FREE_IF_NOT_NULL(macBuffRawPtr);
+    FREE_IF_NOT_NULL(addDataRawPtr);
+
+    RUNIT_API(mbedtls_chachapoly_free(&ctx));
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] DATA_IN[%uB] AAD[%uB]", sizeof(pKey) * 8, sizeof(DATA_IN), sizeof(ADD_DATA));
+#endif
+    return rc;
+}
+
+static RunItError_t runIt_ChachaPolyDecrypt(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(CC_CONFIG_CC_CHACHA_POLY_SUPPORT)
+    static const uint8_t DATA_IN[] = {0x64,0xa0,0x86,0x15,0x75,0x86,0x1a,0xf4,0x60,0xf0,0x62,0xc7,0x9b,0xe6,0x43,0xbd,0x5e,0x80,0x5c,0xfd,0x34,0x5c,0xf3,0x89,0xf1,0x08,0x67,0x0a,0xc7,0x6c,0x8c,0xb2,0x4c,0x6c,0xfc,0x18,0x75,0x5d,0x43,0xee,0xa0,0x9e,0xe9,0x4e,0x38,0x2d,0x26,0xb0,0xbd,0xb7,0xb7,0x3c,0x32,0x1b,0x01,0x00,0xd4,0xf0,0x3b,0x7f,0x35,0x58,0x94,0xcf,0x33,0x2f,0x83,0x0e,0x71,0x0b,0x97,0xce,0x98,0xc8,0xa8,0x4a,0xbd,0x0b,0x94,0x81,0x14,0xad,0x17,0x6e,0x00,0x8d,0x33,0xbd,0x60,0xf9,0x82,0xb1,0xff,0x37,0xc8,0x55,0x97,0x97,0xa0,0x6e,0xf4,0xf0,0xef,0x61,0xc1,0x86,0x32,0x4e,0x2b,0x35,0x06,0x38,0x36,0x06,0x90,0x7b,0x6a,0x7c,0x02,0xb0,0xf9,0xf6,0x15,0x7b,0x53,0xc8,0x67,0xe4,0xb9,0x16,0x6c,0x76,0x7b,0x80,0x4d,0x46,0xa5,0x9b,0x52,0x16,0xcd,0xe7,0xa4,0xe9,0x90,0x40,0xc5,0xa4,0x04,0x33,0x22,0x5e,0xe2,0x82,0xa1,0xb0,0xa0,0x6c,0x52,0x3e,0xaf,0x45,0x34,0xd7,0xf8,0x3f,0xa1,0x15,0x5b,0x00,0x47,0x71,0x8c,0xbc,0x54,0x6a,0x0d,0x07,0x2b,0x04,0xb3,0x56,0x4e,0xea,0x1b,0x42,0x22,0x73,0xf5,0x48,0x27,0x1a,0x0b,0xb2,0x31,0x60,0x53,0xfa,0x76,0x99,0x19,0x55,0xeb,0xd6,0x31,0x59,0x43,0x4e,0xce,0xbb,0x4e,0x46,0x6d,0xae,0x5a,0x10,0x73,0xa6,0x72,0x76,0x27,0x09,0x7a,0x10,0x49,0xe6,0x17,0xd9,0x1d,0x36,0x10,0x94,0xfa,0x68,0xf0,0xff,0x77,0x98,0x71,0x30,0x30,0x5b,0xea,0xba,0x2e,0xda,0x04,0xdf,0x99,0x7b,0x71,0x4d,0x6c,0x6f,0x2c,0x29,0xa6,0xad,0x5c,0xb4,0x02,0x2b,0x02,0x70,0x9b};
+    static const uint8_t ADD_DATA[] = {0xf3,0x33,0x88,0x86,0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0x91};
+
+    static mbedtls_chacha_key pKey = {0x1c,0x92,0x40,0xa5,0xeb,0x55,0xd3,0x8a,0xf3,0x33,0x88,0x86,0x04,0xf6,0xb5,0xf0,0x47,0x39,0x17,0xc1,0x40,0x2b,0x80,0x09,0x9d,0xca,0x5c,0xbc,0x20,0x70,0x75,0xc0};
+    static mbedtls_chacha_nonce pNonce = {0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
+    static const uint8_t pExpectedDataOut[] = {0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x64, 0x72, 0x61, 0x66, 0x74, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x69, 0x78, 0x20, 0x6d, 0x6f, 0x6e, 0x74, 0x68, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x2c, 0x20, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x62, 0x73, 0x6f, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x74, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x2e, 0x20, 0x49, 0x74, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x70, 0x72, 0x69, 0x61, 0x74, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x75, 0x73, 0x65, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x2d, 0x44, 0x72, 0x61, 0x66, 0x74, 0x73, 0x20, 0x61, 0x73, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x6d, 0x61, 0x74, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x20, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20, 0x63, 0x69, 0x74, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6d, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, 0x20, 0x61, 0x73, 0x20, 0x2f, 0xe2, 0x80, 0x9c, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x2e, 0x2f, 0xe2, 0x80, 0x9d};
+    static const uint8_t pExpectedMac[] = {0xee,0xad,0x9d,0x67,0x89,0x0c,0xbb,0x22,0x39,0x23,0x36,0xfe,0xa1,0x85,0x1f,0x38};
+
+    uint8_t *pDataInRaw = NULL;
+    uint8_t *pAddDataRaw = NULL;
+    uint8_t *pCcDataOutBuff = NULL;
+    uint8_t *pMacBuffRaw = NULL;
+
+    RunItPtr ccDataOutBuffPtr;
+    RunItPtr macBuffRawPtr;
+    RunItPtr dataInRawPtr;
+    RunItPtr addDataRawPtr;
+
+    mbedtls_chachapoly_context ctx;
+
+    const char* TEST_NAME = "ChaCha-POLY-Decrypt";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(ccDataOutBuffPtr, pCcDataOutBuff, sizeof(pExpectedDataOut));
+    ALLOC(macBuffRawPtr, pMacBuffRaw, MBEDTLS_POLY_MAC_SIZE_BYTES);
+    ALLOC_AND_COPY(dataInRawPtr, pDataInRaw, DATA_IN, sizeof(DATA_IN));
+    ALLOC_AND_COPY(addDataRawPtr, pAddDataRaw, ADD_DATA, sizeof(ADD_DATA));
+
+    memcpy(pMacBuffRaw, pExpectedMac, MBEDTLS_POLY_MAC_SIZE_BYTES);
+
+    RUNIT_API(mbedtls_chachapoly_init(&ctx));
+
+    RUNIT_ASSERT_WITH_RESULT( mbedtls_chachapoly_setkey( &ctx, pKey ), CC_OK);
+
+    RUNIT_ASSERT_W_PARAM("decrypt", mbedtls_chachapoly_auth_decrypt( &ctx,
+                                                                     sizeof(DATA_IN),
+                                                                     pNonce,
+                                                                     pAddDataRaw,
+                                                                     sizeof(ADD_DATA),
+                                                                     pMacBuffRaw,
+                                                                     pDataInRaw,
+                                                                     pCcDataOutBuff) == CC_OK);
+
+    RUNIT_PRINT_BUF(pCcDataOutBuff, sizeof(pExpectedDataOut), "ccDataOutBuff");
+    RUNIT_PRINT_BUF(pExpectedDataOut, sizeof(pExpectedDataOut), "pExpectedDataOut");
+
+    RUNIT_ASSERT(memcmp(pCcDataOutBuff, pExpectedDataOut, sizeof(pExpectedDataOut)) == 0);
+
+bail:
+
+    FREE_IF_NOT_NULL(ccDataOutBuffPtr);
+    FREE_IF_NOT_NULL(dataInRawPtr);
+    FREE_IF_NOT_NULL(macBuffRawPtr);
+    FREE_IF_NOT_NULL(addDataRawPtr);
+
+    RUNIT_API(mbedtls_chachapoly_free(&ctx));
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] DATA_IN[%uB] AAD[%uB]", sizeof(pKey) * 8, sizeof(DATA_IN), sizeof(ADD_DATA));
+#endif
+    return rc;
+}
+
+static RunItError_t runIt_Poly(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(CC_CONFIG_CC_CHACHA_POLY_SUPPORT)
+    /* The following test vectors were taken from: https://tools.ietf.org/html/rfc7539 */
+    /* section 2.5.2 */
+    uint8_t KEY[] = {0X85, 0Xd6, 0Xbe, 0X78, 0X57, 0X55, 0X6d, 0X33, 0X7f, 0X44, 0X52, 0Xfe, 0X42, 0Xd5, 0X06, 0Xa8, 0X01, 0X03, 0X80, 0X8a, 0Xfb, 0X0d, 0Xb2, 0Xfd, 0X4a, 0Xbf, 0Xf6, 0Xaf, 0X41, 0X49, 0Xf5, 0X1b};
+    uint8_t DATA_IN[] = {0x43, 0x72, 0X79, 0X70, 0X74, 0X6f, 0X67, 0X72, 0X61, 0X70, 0X68, 0X69, 0X63, 0X20, 0X46, 0X6f, 0x72, 0x75, 0X6d, 0X20, 0X52, 0X65, 0X73, 0X65, 0X61, 0X72, 0X63, 0X68, 0X20, 0X47, 0X72, 0X6f, 0x75, 0x70};
+    uint8_t EXPECTED_MAC[] = {0xa8, 0x06, 0x1d, 0xc1, 0x30, 0x51, 0x36, 0xc6, 0xc2, 0x2b, 0x8b, 0xaf, 0x0c, 0x01, 0x27, 0xa9};
+
+    uint8_t *pDataIn = NULL;
+    uint8_t *pKey = NULL;
+    uint8_t *pMacBuff = NULL;
+
+    RunItPtr dataInPtr;
+    RunItPtr keyPtr;
+    RunItPtr macBuffPtr;
+
+    const char* TEST_NAME = "POLY";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(dataInPtr, pDataIn, sizeof(DATA_IN));
+    ALLOC(keyPtr, pKey, sizeof(KEY));
+    ALLOC(macBuffPtr, pMacBuff, MBEDTLS_POLY_MAC_SIZE_BYTES);
+
+    memcpy(pDataIn, DATA_IN, sizeof(DATA_IN));
+    memcpy(pKey, KEY, sizeof(mbedtls_poly_key));
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_poly1305_mac(pKey,
+                                          (uint8_t*)pDataIn,
+                                          sizeof(DATA_IN),
+                                          pMacBuff), CC_OK);
+
+    RUNIT_ASSERT(memcmp(pMacBuff, EXPECTED_MAC, sizeof(EXPECTED_MAC)) == 0);
+
+bail:
+    FREE_IF_NOT_NULL(dataInPtr);
+    FREE_IF_NOT_NULL(keyPtr);
+    FREE_IF_NOT_NULL(macBuffPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%ub] PLAIN[%uB]", sizeof(mbedtls_poly_key) * 8, sizeof(DATA_IN));
+#endif
+    return rc;
+}
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_ChachaTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(CC_CONFIG_CC_CHACHA_POLY_SUPPORT)
+    const char* TEST_NAME = "ChaCha";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_Poly() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_Chacha() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ChachaPolyEncrypt() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ChachaPolyDecrypt() == RUNIT_ERROR__OK);
+
+bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+
+#else
+    (void) runIt_Poly;
+    (void) runIt_Chacha;
+    (void) runIt_ChachaPolyEncrypt;
+    (void) runIt_ChachaPolyDecrypt;
+#endif
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_dhm.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_dhm.c
new file mode 100644
index 0000000..5fa745d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_dhm.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/dhm.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/ctr_drbg.h"
+
+/* CC pal */
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_dhm(void);
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_dhm(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_DHM_C)
+
+    static const int radix_P = 10;
+    static const char *input_P = "93450983094850938450983409623982317398171298719873918739182739712938719287391879381271";
+    static const int radix_G = 10;
+    static const char *input_G = "9345098309485093845098340962223981329819812792137312973297123912791271";
+
+    static const int BUF_SIZE = 1000;
+
+    mbedtls_dhm_context *pCtxSrv = NULL;
+    mbedtls_dhm_context *pCtxCli = NULL;
+    unsigned char *pSke = NULL;
+    unsigned char *pPubCli = NULL;
+    unsigned char *pSecSrv = NULL;
+    unsigned char *pSecCli = NULL;
+
+    RunItPtr ctxSrvPtr;
+    RunItPtr ctxCliPtr;
+    RunItPtr skePrt;
+    RunItPtr pubCliPrt;
+    RunItPtr secSrvPrt;
+    RunItPtr secCliPrt;
+
+    unsigned char *p = NULL;
+    size_t ske_len = 0;
+    size_t pub_cli_len = 0;
+    size_t sec_srv_len;
+    size_t sec_cli_len;
+    int x_size, i;
+
+    const char* TEST_NAME = "DH";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_dhm_context, ctxSrvPtr, pCtxSrv);
+    ALLOC_STRUCT(mbedtls_dhm_context, ctxCliPtr, pCtxCli);
+    ALLOC(skePrt, pSke, BUF_SIZE);
+    ALLOC(pubCliPrt, pPubCli, BUF_SIZE);
+    ALLOC(secSrvPrt, pSecSrv, BUF_SIZE);
+    ALLOC(secCliPrt, pSecCli, BUF_SIZE);
+
+
+    RUNIT_API(mbedtls_dhm_init(pCtxSrv));
+    RUNIT_API(mbedtls_dhm_init(pCtxCli));
+    memset(pSke, 0x00, BUF_SIZE);
+    memset(pPubCli, 0x00, BUF_SIZE);
+    memset(pSecSrv, 0x00, BUF_SIZE);
+    memset(pSecCli, 0x00, BUF_SIZE);
+
+    /*
+     * Set params
+     */
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&pCtxSrv->P, radix_P, input_P) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&pCtxSrv->G, radix_G, input_G) == 0);
+    x_size = mbedtls_mpi_size(&pCtxSrv->P);
+    pub_cli_len = x_size;
+
+    /*
+     * First key exchange
+     */
+    p = pSke;
+
+    RUNIT_ASSERT_API(mbedtls_dhm_make_params(pCtxSrv, x_size, pSke, &ske_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    pSke[ske_len++] = 0;
+    pSke[ske_len++] = 0;
+
+    RUNIT_ASSERT_API(mbedtls_dhm_read_params(pCtxCli, &p, pSke + ske_len) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_dhm_make_public(pCtxCli, x_size, pPubCli, pub_cli_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_dhm_read_public(pCtxSrv, pPubCli, pub_cli_len) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxSrv, pSecSrv, BUF_SIZE, &sec_srv_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxCli, pSecCli, BUF_SIZE, &sec_cli_len, NULL, NULL ) == 0);
+
+    RUNIT_ASSERT(sec_srv_len == sec_cli_len);
+    RUNIT_ASSERT(sec_srv_len != 0);
+    RUNIT_ASSERT(memcmp(pSecSrv, pSecCli, sec_srv_len) == 0);
+
+    /* Re-do calc_secret on server a few times to test update of blinding values */
+    for (i = 0; i < 3; i++)
+    {
+        sec_srv_len = 1000;
+        RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxSrv, pSecSrv, BUF_SIZE, &sec_srv_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
+
+        RUNIT_ASSERT(sec_srv_len == sec_cli_len);
+        RUNIT_ASSERT(sec_srv_len != 0);
+        RUNIT_ASSERT(memcmp(pSecSrv, pSecCli, sec_srv_len) == 0);
+    }
+
+    /*
+     * Second key exchange to test change of blinding values on server
+     */
+    p = pSke;
+
+    RUNIT_ASSERT_API(mbedtls_dhm_make_params(pCtxSrv, x_size, pSke, &ske_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    pSke[ske_len++] = 0;
+    pSke[ske_len++] = 0;
+    RUNIT_ASSERT_API(mbedtls_dhm_read_params(pCtxCli, &p, pSke + ske_len) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_dhm_make_public(pCtxCli, x_size, pPubCli, pub_cli_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_dhm_read_public(pCtxSrv, pPubCli, pub_cli_len) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxSrv, pSecSrv, BUF_SIZE, &sec_srv_len, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_dhm_calc_secret(pCtxCli, pSecCli, BUF_SIZE, &sec_cli_len, NULL, NULL ) == 0);
+
+    RUNIT_ASSERT(sec_srv_len == sec_cli_len);
+    RUNIT_ASSERT(sec_srv_len != 0);
+    RUNIT_ASSERT(memcmp(pSecSrv, pSecCli, sec_srv_len) == 0);
+
+bail:
+    RUNIT_API(mbedtls_dhm_free(pCtxSrv));
+    RUNIT_API(mbedtls_dhm_free(pCtxCli));
+
+    FREE_IF_NOT_NULL(ctxSrvPtr);
+    FREE_IF_NOT_NULL(ctxCliPtr);
+    FREE_IF_NOT_NULL(skePrt);
+    FREE_IF_NOT_NULL(pubCliPrt);
+    FREE_IF_NOT_NULL(secSrvPrt);
+    FREE_IF_NOT_NULL(secCliPrt);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "G[%"PRIu32"b]", (uint32_t)strlen(input_G) * 8);
+#endif /* MBEDTLS_DHM_C */
+    return rc;
+}
+
+RunItError_t runIt_dhmTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    const char* TEST_NAME = "DH";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_dhm() == RUNIT_ERROR__OK);
+
+bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_drbg.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_drbg.c
new file mode 100644
index 0000000..941de06
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_drbg.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/timing.h"
+#include "mbedtls/ctr_drbg.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+#if defined(MBEDTLS_CTR_DRBG_C)
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_ctrDrbgEntropyUsageTest(void);
+static RunItError_t runIt_ctrDrbgVectorTest(void);
+static int runIt_ctrDrbgSelfTestEntropy(void *data, unsigned char *buf, size_t len);
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+static size_t test_offset;
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static int runIt_ctrDrbgSelfTestEntropy(void *data, unsigned char *buf, size_t len)
+{
+    const unsigned char *p = data;
+    memcpy(buf, p + test_offset, len);
+    test_offset += len;
+    return (0);
+}
+
+static RunItError_t runIt_ctrDrbgEntropyUsageTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    unsigned char out[16];
+    unsigned char add[16];
+
+    unsigned char *pEntropy = NULL;
+    mbedtls_ctr_drbg_context *pCtx = NULL;
+
+    RunItPtr entropyPtr;
+    RunItPtr ctxPtr;
+
+    size_t i, reps = 10;
+    size_t last_idx;
+
+    const char* TEST_NAME = "CTR-DRBG Entropy Usage";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(entropyPtr, pEntropy, 1024);
+    ALLOC_STRUCT(mbedtls_ctr_drbg_context, ctxPtr, pCtx);
+
+    RUNIT_API(mbedtls_ctr_drbg_init(pCtx));
+    test_offset = 0;
+    memset(pEntropy, 0, 1024);
+    memset(out, 0, sizeof(out));
+    memset(add, 0, sizeof(add));
+
+    /* Init must use entropy */
+    last_idx = test_offset;
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_seed(pCtx, runIt_ctrDrbgSelfTestEntropy, pEntropy, NULL, 0) == 0);
+    RUNIT_ASSERT(last_idx < test_offset);
+
+    /* By default, PR is off and reseed_interval is large,
+     * so the next few calls should not use entropy */
+    last_idx = test_offset;
+    for (i = 0; i < reps; i++)
+    {
+        RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, out, sizeof(out) - 4) == 0);
+        RUNIT_ASSERT_API(mbedtls_ctr_drbg_random_with_add(pCtx, out, sizeof(out) - 4, add, sizeof(add)) == 0);
+    }
+    RUNIT_ASSERT(last_idx == test_offset);
+
+    /* While at it, make sure we didn't write past the requested length */
+    RUNIT_ASSERT(out[sizeof(out) - 4] == 0);
+    RUNIT_ASSERT(out[sizeof(out) - 3] == 0);
+    RUNIT_ASSERT(out[sizeof(out) - 2] == 0);
+    RUNIT_ASSERT(out[sizeof(out) - 1] == 0);
+
+    /* Set reseed_interval to the number of calls done,
+     * so the next call should reseed */
+    RUNIT_API(mbedtls_ctr_drbg_set_reseed_interval(pCtx, 2 * reps));
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, out, sizeof(out)) == 0);
+    RUNIT_ASSERT(last_idx < test_offset);
+
+    /* The new few calls should not reseed */
+    last_idx = test_offset;
+    for (i = 0; i < reps / 2; i++)
+    {
+        RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, out, sizeof(out)) == 0);
+        RUNIT_ASSERT_API(mbedtls_ctr_drbg_random_with_add(pCtx, out, sizeof(out), add, sizeof(add)) == 0);
+    }
+    RUNIT_ASSERT(last_idx == test_offset);
+
+    /* Call update with too much data (sizeof entropy > MAX(_SEED)_INPUT)
+     * (just make sure it doesn't cause memory corruption) */
+    RUNIT_API(mbedtls_ctr_drbg_update(pCtx, pEntropy, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT));
+
+    /* Now enable PR, so the next few calls should all reseed */
+    RUNIT_API(mbedtls_ctr_drbg_set_prediction_resistance(pCtx, MBEDTLS_CTR_DRBG_PR_ON));
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, out, sizeof(out)) == 0);
+    RUNIT_ASSERT(last_idx < test_offset);
+
+    /* Finally, check setting entropy_len */
+    RUNIT_API(mbedtls_ctr_drbg_set_entropy_len(pCtx, 42));
+    last_idx = test_offset;
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, out, sizeof(out)) == 0);
+    RUNIT_ASSERT(test_offset - last_idx == 42);
+
+    RUNIT_API(mbedtls_ctr_drbg_set_entropy_len(pCtx, 13));
+    last_idx = test_offset;
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, out, sizeof(out)) == 0);
+    RUNIT_ASSERT(test_offset - last_idx == 13);
+
+bail:
+    RUNIT_API(mbedtls_ctr_drbg_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(entropyPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+
+static RunItError_t runIt_ctrDrbgVectorTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static const unsigned char nonce_pers_pr[16] = { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c };
+    static const unsigned char nonce_pers_nopr[16] = { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f };
+    static const unsigned char entropy_source_pr[96] = { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 };
+    static const unsigned char entropy_source_nopr[64] = { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e };
+    static const unsigned char result_nopr[16] = { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f };
+    static const unsigned char result_pr[16] = { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 };
+
+    mbedtls_ctr_drbg_context *pCtx = NULL;
+    RunItPtr ctxPtr;
+
+    unsigned char buf[16];
+
+    const char* TEST_NAME = "CTR-DRBG Vectors";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ctr_drbg_context, ctxPtr, pCtx);
+
+    RUNIT_API(mbedtls_ctr_drbg_init(pCtx));
+
+    /*
+     * Based on a NIST CTR_DRBG test vector (PR = True)
+     */
+    test_offset = 0;
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_seed_entropy_len(pCtx, runIt_ctrDrbgSelfTestEntropy, (void * ) entropy_source_pr, nonce_pers_pr, 16, 32) == 0);
+    RUNIT_API(mbedtls_ctr_drbg_set_prediction_resistance(pCtx, MBEDTLS_CTR_DRBG_PR_ON));
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE) == 0);
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE) == 0);
+    RUNIT_ASSERT(memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE) == 0);
+
+    RUNIT_API(mbedtls_ctr_drbg_free(pCtx));
+
+    /*
+     * Based on a NIST CTR_DRBG test vector (PR = FALSE)
+     */
+    RUNIT_API(mbedtls_ctr_drbg_init(pCtx));
+
+    test_offset = 0;
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_seed_entropy_len(pCtx, runIt_ctrDrbgSelfTestEntropy, (void * ) entropy_source_nopr, nonce_pers_nopr, 16, 32) == 0);
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, buf, 16) == 0);
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_reseed(pCtx, NULL, 0 ) == 0);
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtx, buf, 16) == 0);
+    RUNIT_ASSERT(memcmp(buf, result_nopr, 16) == 0);
+
+bail:
+    RUNIT_API(mbedtls_ctr_drbg_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_ctrDrbgTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    const char* TEST_NAME = "CTR-DRBG";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_ctrDrbgEntropyUsageTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ctrDrbgVectorTest() == RUNIT_ERROR__OK);
+
+bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+
+}
+#endif /* MBEDTLS_CTR_DRBG_C */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecdh.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecdh.c
new file mode 100644
index 0000000..42ff54a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecdh.c
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/ecdh.h"
+#include "mbedtls/ctr_drbg.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+#include "mbedtls_cc_ecdh_edwards.h"
+
+#if defined MBEDTLS_ECDH_C
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_ecdhPrimRandom(void);
+static RunItError_t runIt_ecdhExchange(void);
+#if defined (MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+static RunItError_t runIt_ecdhExange25519(void);
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_ecdhPrimRandom(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static const char *dA_str = "C88F01F510D9AC3F70A292DAA2316DE544E9AAB8AFE84049C62A9C57862D1433";
+    static const char *xA_str = "DAD0B65394221CF9B051E1FECA5787D098DFE637FC90B9EF945D0C3772581180";
+    static const char *yA_str = "5271A0461CDB8252D61F1C456FA3E59AB1F45B33ACCF5F58389E0577B8990BB3";
+    static const char *dB_str = "C6EF9C5D78AE012A011164ACB397CE2088685D8F06BF9BE0B283AB46476BEE53";
+    static const char *xB_str = "D12DFB5289C8D4F81208B70270398C342296970A0BCCB74C736FC7554494BF63";
+    static const char *yB_str = "56FBF3CA366CC23E8157854C13C58D6AAC23F046ADA30F8353E74F33039872AB";
+    static const char *z_str = "D6840F6B42F6EDAFD13116E0E12565202FEF8E9ECE7DCE03812464D04B9442DE";
+
+    mbedtls_ecp_group *pGrp = NULL;
+    mbedtls_ecp_point *pQA = NULL;
+    mbedtls_ecp_point *pQB = NULL;
+    unsigned char *pRndBufA = NULL;
+    unsigned char *pRndBufB = NULL;
+    mbedtls_mpi dA;
+    mbedtls_mpi dB;
+    mbedtls_mpi zA;
+    mbedtls_mpi zB;
+    mbedtls_mpi check;
+
+    RunItPtr grpPtr;
+    RunItPtr qAPtr;
+    RunItPtr qBPtr;
+    RunItPtr rndBufAPtr;
+    RunItPtr rndBufBPtr;
+
+    rnd_buf_info rnd_info_A;
+    rnd_buf_info rnd_info_B;
+
+    const char* TEST_NAME = "ECDH Vectors";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
+    ALLOC_STRUCT(mbedtls_ecp_point, qAPtr, pQA);
+    ALLOC_STRUCT(mbedtls_ecp_point, qBPtr, pQB);
+    ALLOC(rndBufAPtr, pRndBufA, MBEDTLS_ECP_MAX_BYTES);
+    ALLOC(rndBufBPtr, pRndBufB, MBEDTLS_ECP_MAX_BYTES);
+
+    mbedtls_ecp_group_init(pGrp);
+    mbedtls_ecp_point_init(pQA);
+    mbedtls_ecp_point_init(pQB);
+    mbedtls_mpi_init(&dA);
+    mbedtls_mpi_init(&dB);
+    mbedtls_mpi_init(&zA);
+    mbedtls_mpi_init(&zB);
+    mbedtls_mpi_init(&check);
+
+    RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, MBEDTLS_ECP_DP_SECP256R1) == 0);
+
+    rnd_info_A.buf = pRndBufA;
+    rnd_info_A.length = runIt_unhexify(pRndBufA, dA_str);
+
+    /* Fix rnd_buf_A by shifting it left if necessary */
+    if (pGrp->nbits % 8 != 0)
+    {
+        unsigned char shift = 8 - (pGrp->nbits % 8);
+        size_t i;
+
+        for (i = 0; i < rnd_info_A.length - 1; i++)
+            pRndBufA[i] = pRndBufA[i] << shift | pRndBufA[i + 1] >> (8 - shift);
+
+        pRndBufA[rnd_info_A.length - 1] <<= shift;
+    }
+
+    rnd_info_B.buf = pRndBufB;
+    rnd_info_B.length = runIt_unhexify(pRndBufB, dB_str);
+
+    /* Fix rnd_buf_B by shifting it left if necessary */
+    if (pGrp->nbits % 8 != 0)
+    {
+        unsigned char shift = 8 - (pGrp->nbits % 8);
+        size_t i;
+
+        for (i = 0; i < rnd_info_B.length - 1; i++)
+            pRndBufB[i] = pRndBufB[i] << shift | pRndBufB[i + 1] >> (8 - shift);
+
+        pRndBufB[rnd_info_B.length - 1] <<= shift;
+    }
+
+    RUNIT_ASSERT_API(mbedtls_ecdh_gen_public(pGrp, &dA, pQA, runIt_rndBufferRand, &rnd_info_A) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_is_zero(pQA) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, xA_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQA->X, &check) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, yA_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQA->Y, &check) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_ecdh_gen_public(pGrp, &dB, pQB, runIt_rndBufferRand, &rnd_info_B) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_is_zero(pQB) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, xB_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQB->X, &check) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, yB_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pQB->Y, &check) == 0);
+
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&check, 16, z_str) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_compute_shared( pGrp, &zA, pQB, &dA, NULL, NULL ) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&zA, &check) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_compute_shared( pGrp, &zB, pQA, &dB, NULL, NULL ) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&zB, &check) == 0);
+
+bail:
+
+    mbedtls_ecp_group_free(pGrp);
+    mbedtls_ecp_point_free(pQA);
+    mbedtls_ecp_point_free(pQB);
+
+    mbedtls_mpi_free(&dA);
+    mbedtls_mpi_free(&dB);
+    mbedtls_mpi_free(&zA);
+    mbedtls_mpi_free(&zB);
+    mbedtls_mpi_free(&check);
+
+    FREE_IF_NOT_NULL(grpPtr);
+    FREE_IF_NOT_NULL(qAPtr);
+    FREE_IF_NOT_NULL(qBPtr);
+    FREE_IF_NOT_NULL(rndBufAPtr);
+    FREE_IF_NOT_NULL(rndBufBPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+
+    return rc;
+}
+
+static RunItError_t runIt_ecdhExchange(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    static const uint32_t BUF_SIZE = 1000;
+
+    mbedtls_ecdh_context *pSrv = NULL;
+    mbedtls_ecdh_context *pCli = NULL;
+    unsigned char *pBuf = NULL;
+
+    RunItPtr srvPtr = {0};
+    RunItPtr cliPtr = {0};
+    RunItPtr bufPtr = {0};
+
+    const unsigned char *vbuf;
+    size_t len;
+
+    const char* TEST_NAME = "ECDH Exchange";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ecdh_context, srvPtr, pSrv);
+    ALLOC_STRUCT(mbedtls_ecdh_context, cliPtr, pCli);
+    ALLOC(bufPtr, pBuf, BUF_SIZE);
+
+    RUNIT_API(mbedtls_ecdh_init(pSrv));
+    RUNIT_API(mbedtls_ecdh_init(pCli));
+
+    RUNIT_ASSERT(mbedtls_ecp_group_load(&pSrv->grp, MBEDTLS_ECP_DP_SECP256R1) == 0);
+
+    memset(pBuf, 0x00, BUF_SIZE);
+    vbuf = pBuf;
+    RUNIT_ASSERT_API(mbedtls_ecdh_make_params(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_read_params(pCli, &vbuf, pBuf + len) == 0);
+
+    memset(pBuf, 0x00, BUF_SIZE);
+    RUNIT_ASSERT_API(mbedtls_ecdh_make_public(pCli, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_read_public(pSrv, pBuf, len) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pCli, &len, pBuf, BUF_SIZE, NULL, NULL) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pSrv->z, &pCli->z) == 0);
+
+bail:
+    RUNIT_API(mbedtls_ecdh_free(pSrv));
+    RUNIT_API(mbedtls_ecdh_free(pCli));
+
+    FREE_IF_NOT_NULL(srvPtr);
+    FREE_IF_NOT_NULL(cliPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+
+#if defined (MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+static RunItError_t runIt_ecdhExange25519(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    static const uint32_t BUF_SIZE = 1000;
+
+    mbedtls_ecdh_context *pSrv = NULL;
+    mbedtls_ecdh_context *pCli = NULL;
+    unsigned char *pBuf = NULL;
+
+    RunItPtr srvPtr = {0};
+    RunItPtr cliPtr = {0};
+    RunItPtr bufPtr = {0};
+
+    const unsigned char *vbuf;
+    size_t len;
+
+    const char* TEST_NAME = "ECDH 25519 Exchange";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ecdh_context, srvPtr, pSrv);
+    ALLOC_STRUCT(mbedtls_ecdh_context, cliPtr, pCli);
+    ALLOC(bufPtr, pBuf, BUF_SIZE);
+
+    RUNIT_API(mbedtls_ecdh_init(pSrv));
+    RUNIT_API(mbedtls_ecdh_init(pCli));
+
+    RUNIT_ASSERT(mbedtls_ecp_group_load(&pSrv->grp, MBEDTLS_ECP_DP_CURVE25519) == 0);
+
+    memset(pBuf, 0x00, BUF_SIZE);
+    vbuf = pBuf;
+
+    RUNIT_ASSERT_API(mbedtls_ecdh_make_params_edwards(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_read_params_edwards(pCli, &vbuf, pBuf + len) == 0);
+
+    memset(pBuf, 0x00, BUF_SIZE);
+    RUNIT_ASSERT_API(mbedtls_ecdh_make_public(pCli, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_read_public(pSrv, pBuf, len) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pSrv, &len, pBuf, BUF_SIZE, mbedtls_ctr_drbg_random, gpRndState) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdh_calc_secret(pCli, &len, pBuf, BUF_SIZE, NULL, NULL) == 0);
+
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pSrv->z, &pCli->z) == 0);
+
+bail:
+    RUNIT_API(mbedtls_ecdh_free(pSrv));
+    RUNIT_API(mbedtls_ecdh_free(pCli));
+
+    FREE_IF_NOT_NULL(srvPtr);
+    FREE_IF_NOT_NULL(cliPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+    return rc;
+
+}
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_ecdhTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "ECDH";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_ecdhPrimRandom() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ecdhExchange() == RUNIT_ERROR__OK);
+#if defined (MBEDTLS_ECP_DP_CURVE25519_ENABLED)
+    RUNIT_ASSERT(runIt_ecdhExange25519() == RUNIT_ERROR__OK);
+#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
+    bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+#endif /* MBEDTLS_ECDH_C */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecdsa.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecdsa.c
new file mode 100644
index 0000000..182efe1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecdsa.c
@@ -0,0 +1,440 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/ecdsa.h"
+#include "mbedtls/ecp.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/ctr_drbg.h"
+#include "mbedtls_cc_ecdsa_edwards.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+#if defined MBEDTLS_ECDSA_C
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define DIGEST_SIZE         64
+#define ECP_GROUP_ID        MBEDTLS_ECP_DP_SECP256R1
+#define ECP_GROUP_ID_STR    "DP_SECP256R1"
+#define MD_TYPE_ID          MBEDTLS_MD_SHA256
+#define MD_TYPE_ID_STR      "SHA256"
+
+#define RUNIT_ECDSA_TEST_R521 0
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_ecdsaPrimRandomTest(void);
+static RunItError_t runIt_ecdsaPrimVectorsTest(void);
+static RunItError_t runIt_ecdsaDetVectorsTest(void);
+static RunItError_t runIt_ecdsaWriteReadRandomTest(void);
+static RunItError_t runIt_ecdsaPrimRandomEdwTest(void);
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_ecdsaPrimRandomTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    mbedtls_ecp_group_id id = RUNIT_ECDSA_TEST_R521 ? MBEDTLS_ECP_DP_SECP521R1 : MBEDTLS_ECP_DP_SECP256R1;
+    mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
+    mbedtls_ecp_group *pGrp = NULL;
+    mbedtls_ecp_point *pQ = NULL;
+    mbedtls_mpi d, r, s;
+    unsigned char *pBuf = NULL;
+
+    RunItPtr grpPtr;
+    RunItPtr qPtr;
+    RunItPtr bufPtr;
+
+    const char* TEST_NAME = "ECDSA Primary Random";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(bufPtr, pBuf, DIGEST_SIZE);
+    ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
+    ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
+
+    mbedtls_ecp_group_init(pGrp);
+    mbedtls_ecp_point_init(pQ);
+    mbedtls_mpi_init(&d);
+    mbedtls_mpi_init(&r);
+    mbedtls_mpi_init(&s);
+    memset(pBuf, 0, DIGEST_SIZE);
+
+    RUNIT_ASSERT(mbedtls_ctr_drbg_random(pCtrDrbg, pBuf, DIGEST_SIZE) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, id) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_gen_keypair(pGrp, &d, pQ, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdsa_sign(pGrp, &r, &s, &d, pBuf, DIGEST_SIZE, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdsa_verify(pGrp, pBuf, DIGEST_SIZE, pQ, &r, &s) == 0);
+
+bail:
+    mbedtls_ecp_group_free(pGrp);
+    mbedtls_ecp_point_free(pQ);
+
+    mbedtls_mpi_free(&d);
+    mbedtls_mpi_free(&r);
+    mbedtls_mpi_free(&s);
+
+    FREE_IF_NOT_NULL(grpPtr);
+    FREE_IF_NOT_NULL(qPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s]", mbedtls_ecp_curve_info_from_grp_id(id)->name);
+#endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) */
+    return rc;
+}
+
+static RunItError_t runIt_ecdsaPrimRandomEdwTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    size_t data_len = 200;
+
+    mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
+    mbedtls_ecdsa_context *pCtx = NULL;
+
+    unsigned char *pDataIn = NULL;
+
+    RunItPtr ctxPtr;
+    RunItPtr dataPtr;
+
+    mbedtls_mpi r, s;
+    const char* TEST_NAME = "ECDSA Random Edwards";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    mbedtls_mpi_init( &r );
+    mbedtls_mpi_init( &s );
+
+
+    ALLOC_STRUCT(mbedtls_ecdsa_context, ctxPtr, pCtx);
+    ALLOC(dataPtr, pDataIn, data_len);
+
+    RUNIT_API(mbedtls_ecdsa_init(pCtx));
+
+    /* prepare material for signature */
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_ctr_drbg_random(pCtrDrbg, pDataIn, data_len), 0);
+
+    /* generate signing key */
+    RUNIT_ASSERT_WITH_RESULT( mbedtls_ecdsa_genkey_edwards(pCtx, MBEDTLS_ECP_DP_CURVE25519, mbedtls_ctr_drbg_random, pCtrDrbg), 0);
+    RUNIT_ASSERT_WITH_RESULT( mbedtls_ecdsa_sign_edwards( &pCtx->grp, &r, &s, &pCtx->d, pDataIn, data_len), 0 );
+    RUNIT_ASSERT_WITH_RESULT( mbedtls_ecdsa_verify_edwards(&pCtx->grp, pDataIn, data_len, &pCtx->Q, &r, &s), 0 );
+
+bail:
+    RUNIT_API(mbedtls_ecdsa_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(dataPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[DP_CURVE25519] MD[%s]", MD_TYPE_ID_STR);
+    return rc;
+}
+
+static RunItError_t runIt_ecdsaPrimVectorsTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
+    static const char *d_str = "DC51D3866A15BACDE33D96F992FCA99DA7E6EF0934E7097559C27F1614C88A7F";
+    static const char *xQ_str = "2442A5CC0ECD015FA3CA31DC8E2BBC70BF42D60CBCA20085E0822CB04235E970";
+    static const char *yQ_str = "6FC98BD7E50211A4A27102FA3549DF79EBCB4BF246B80945CDDFE7D509BBFD7D";
+    static const char *k_str = "9E56F509196784D963D1C0A401510EE7ADA3DCC5DEE04B154BF61AF1D5A6DECE";
+    static const char *hash_str = "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD";
+    static const char *r_str = "CB28E0999B9C7715FD0A80D8E47A77079716CBBF917DD72E97566EA1C066957C";
+    static const char *s_str = "86FA3BB4E26CAD5BF90B7F81899256CE7594BB1EA0C89212748BFF3B3D5B0315";
+
+    mbedtls_ecp_group *pGrp = NULL;
+    mbedtls_ecp_point *pQ = NULL;
+    mbedtls_mpi d;
+    mbedtls_mpi r;
+    mbedtls_mpi s;
+    mbedtls_mpi rCheck;
+    mbedtls_mpi sCheck;
+    unsigned char *pHash = NULL;
+    unsigned char *pRndBuf = NULL;
+
+    RunItPtr grpPtr;
+    RunItPtr qPtr;
+    RunItPtr hashPtr;
+    RunItPtr rndBufPtr;
+
+    size_t hlen;
+    rnd_buf_info rnd_info;
+
+    const char* TEST_NAME = "ECDSA Primary Vector";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
+    ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
+    ALLOC(hashPtr, pHash, 66);
+    ALLOC(rndBufPtr, pRndBuf, 66);
+
+    mbedtls_ecp_group_init(pGrp);
+    mbedtls_ecp_point_init(pQ);
+    mbedtls_mpi_init(&d);
+    mbedtls_mpi_init(&r);
+    mbedtls_mpi_init(&s);
+    mbedtls_mpi_init(&rCheck);
+    mbedtls_mpi_init(&sCheck);
+    memset(pHash, 0, 66);
+    memset(pRndBuf, 0, 66);
+
+    RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, ECP_GROUP_ID) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_point_read_string(pQ, 16, xQ_str, yQ_str) == 0);
+
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&d, 16, d_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&rCheck, 16, r_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&sCheck, 16, s_str) == 0);
+
+    hlen = runIt_unhexify(pHash, hash_str);
+
+    rnd_info.buf = pRndBuf;
+    rnd_info.length = runIt_unhexify(pRndBuf, k_str);
+
+    /* Fix pRndBuf by shifting it left if necessary */
+    if (pGrp->nbits % 8 != 0)
+    {
+        unsigned char shift = 8 - (pGrp->nbits % 8);
+        size_t i;
+
+        for (i = 0; i < rnd_info.length - 1; i++)
+            pRndBuf[i] = pRndBuf[i] << shift | pRndBuf[i + 1] >> (8 - shift);
+
+        pRndBuf[rnd_info.length - 1] <<= shift;
+    }
+
+    RUNIT_ASSERT_API(mbedtls_ecdsa_sign(pGrp, &r, &s, &d, pHash, hlen, runIt_rndBufferRand, &rnd_info) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&r, &rCheck) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&s, &sCheck) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdsa_verify(pGrp, pHash, hlen, pQ, &rCheck, &sCheck) == 0);
+
+bail:
+    mbedtls_ecp_group_free(pGrp);
+    mbedtls_ecp_point_free(pQ);
+
+    mbedtls_mpi_free(&d);
+    mbedtls_mpi_free(&r);
+    mbedtls_mpi_free(&s);
+    mbedtls_mpi_free(&rCheck);
+    mbedtls_mpi_free(&sCheck);
+
+    FREE_IF_NOT_NULL(grpPtr);
+    FREE_IF_NOT_NULL(qPtr);
+    FREE_IF_NOT_NULL(hashPtr);
+    FREE_IF_NOT_NULL(rndBufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s]", ECP_GROUP_ID_STR);
+#endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) */
+    return rc;
+}
+
+static RunItError_t runIt_ecdsaDetVectorsTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C)
+
+#if RUNIT_ECDSA_TEST_R521
+    mbedtls_ecp_group_id id = MBEDTLS_ECP_DP_SECP521R1;
+    static const char *d_str = "0100085F47B8E1B8B11B7EB33028C0B2888E304BFC98501955B45BBA1478DC184EEEDF09B86A5F7C21994406072787205E69A63709FE35AA93BA333514B24F961722";
+    static const mbedtls_md_type_t md_alg = MBEDTLS_MD_SHA512;
+    static const char *msg = "Example of ECDSA with P-521";
+    static const char *r_str = "26B55806BC7F28FF38323A46DB837CCA018FE58B766577498AAC828A76E272D61657E3C386F2FA940CDEC5961F9A81800F1385D2AF365C88B4E341824C5203D0CD";
+    static const char *s_str = "01399C2DBA893C4296C9EB06C29E2B87114EE1A8AF7EFF2312737C147AAC69BF77EB4BE520406EADAB45AE2621970B175B0213526B939FCE6B780523C20693B33601";
+#else
+    mbedtls_ecp_group_id id = ECP_GROUP_ID;
+    static const char *d_str = "C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721";
+    static const mbedtls_md_type_t md_alg = MD_TYPE_ID;
+    static const char *msg = "sample";
+    static const char *r_str = "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716";
+    static const char *s_str = "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8";
+#endif
+
+    size_t hlen;
+    const mbedtls_md_info_t *md_info;
+
+    unsigned char *pHash = NULL;
+    mbedtls_ecp_group *pGrp = NULL;
+    mbedtls_mpi *pD = NULL;
+    mbedtls_mpi *pR = NULL;
+    mbedtls_mpi *pS = NULL;
+    mbedtls_mpi *pRCheck = NULL;
+    mbedtls_mpi *pSCheck = NULL;
+
+    RunItPtr hashPtr;
+    RunItPtr grpPtr;
+    RunItPtr dPtr;
+    RunItPtr rPtr;
+    RunItPtr sPtr;
+    RunItPtr rCheckPtr;
+    RunItPtr sCheckPtr;
+
+    const char* TEST_NAME = "ECDSA Det Primary Vector";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    md_info = mbedtls_md_info_from_type(md_alg);
+    RUNIT_ASSERT(md_info != NULL);
+
+    ALLOC(hashPtr, pHash, MBEDTLS_MD_MAX_SIZE);
+    ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
+    ALLOC_STRUCT(mbedtls_mpi, dPtr, pD);
+    ALLOC_STRUCT(mbedtls_mpi, rPtr, pR);
+    ALLOC_STRUCT(mbedtls_mpi, sPtr, pS);
+    ALLOC_STRUCT(mbedtls_mpi, rCheckPtr, pRCheck);
+    ALLOC_STRUCT(mbedtls_mpi, sCheckPtr, pSCheck);
+
+    memset(pHash, 0, MBEDTLS_MD_MAX_SIZE);
+    mbedtls_ecp_group_init(pGrp);
+    mbedtls_mpi_init(pD);
+    mbedtls_mpi_init(pR);
+    mbedtls_mpi_init(pS);
+    mbedtls_mpi_init(pRCheck);
+    mbedtls_mpi_init(pSCheck);
+
+    RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, id) == 0);
+
+    RUNIT_ASSERT(mbedtls_mpi_read_string(pD, 16, d_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(pRCheck, 16, r_str) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(pSCheck, 16, s_str) == 0);
+
+    hlen = mbedtls_md_get_size(md_info);
+
+    RUNIT_ASSERT_API(mbedtls_md(md_info, (const unsigned char *) msg, strlen(msg), pHash) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdsa_sign_det(pGrp, pR, pS, pD, pHash, hlen, md_alg) == 0);
+
+#if 0
+    {
+        char buff[300] = {0};
+        uint32_t len = 0;
+        RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pR, 16, buff, 299, &len), 0);
+        RUNIT_PRINT_DBG("pR[%s]\n", buff);
+        RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pRCheck, 16, buff, 299, &len), 0);
+        RUNIT_PRINT_DBG("pRCheck[%s]\n", buff);
+
+        RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pS, 16, buff, 299, &len), 0);
+        RUNIT_PRINT_DBG("pS[%s]\n", buff);
+        RUNIT_ASSERT_WITH_RESULT(mbedtls_mpi_write_string(pSCheck, 16, buff, 299, &len), 0);
+        RUNIT_PRINT_DBG("pSCheck[%s]\n", buff);
+    }
+#endif /* 0 */
+
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(pR, pRCheck) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(pS, pSCheck) == 0);
+
+bail:
+    mbedtls_ecp_group_free(pGrp);
+
+    mbedtls_mpi_free(pD);
+    mbedtls_mpi_free(pR);
+    mbedtls_mpi_free(pS);
+    mbedtls_mpi_free(pRCheck);
+    mbedtls_mpi_free(pSCheck);
+
+    FREE_IF_NOT_NULL(hashPtr);
+    FREE_IF_NOT_NULL(grpPtr);
+    FREE_IF_NOT_NULL(dPtr);
+    FREE_IF_NOT_NULL(rPtr);
+    FREE_IF_NOT_NULL(sPtr);
+    FREE_IF_NOT_NULL(rCheckPtr);
+    FREE_IF_NOT_NULL(sCheckPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] MD[%s]", (mbedtls_ecp_curve_info_from_grp_id(id)->name), mbedtls_md_get_name(md_info));
+#endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C) */
+    return rc;
+}
+
+static RunItError_t runIt_ecdsaWriteReadRandomTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C)
+    unsigned char hash[32];
+    size_t sig_len;
+
+    mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
+    mbedtls_ecdsa_context *pCtx = NULL;
+    unsigned char *pSig = NULL;
+
+    RunItPtr ctxPtr;
+    RunItPtr sigPtr;
+
+    const char* TEST_NAME = "ECDSA Write Read Random";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ecdsa_context, ctxPtr, pCtx);
+    ALLOC(sigPtr, pSig, 200);
+
+    RUNIT_API(mbedtls_ecdsa_init(pCtx));
+    memset(hash, 0, sizeof(hash));
+    memset(pSig, 0, 200);
+
+    /* prepare material for signature */
+    RUNIT_ASSERT_API(mbedtls_ctr_drbg_random(pCtrDrbg, hash, sizeof(hash)) == 0);
+
+    /* generate signing key */
+    RUNIT_ASSERT_API(mbedtls_ecdsa_genkey(pCtx, ECP_GROUP_ID, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdsa_write_signature(pCtx, MD_TYPE_ID, hash, sizeof(hash), pSig, &sig_len, mbedtls_ctr_drbg_random, pCtrDrbg) == 0);
+    RUNIT_ASSERT_API(mbedtls_ecdsa_read_signature(pCtx, hash, sizeof(hash), pSig, sig_len) == 0);
+
+bail:
+    RUNIT_API(mbedtls_ecdsa_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(sigPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] MD[%s]", ECP_GROUP_ID_STR, MD_TYPE_ID_STR);
+#endif /* defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) && defined(MBEDTLS_SHA256_C) */
+    return rc;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_ecdsaTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "ECDSA";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_ecdsaPrimRandomTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ecdsaPrimVectorsTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ecdsaDetVectorsTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ecdsaWriteReadRandomTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_ecdsaPrimRandomEdwTest() == RUNIT_ERROR__OK);
+
+bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+#endif /* MBEDTLS_ECDSA_C */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecies.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecies.c
new file mode 100644
index 0000000..9a616ab
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ecies.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* cc lib */
+#include "mbedtls_cc_ecies.h"
+
+/* mbedtls lib */
+#include "mbedtls/timing.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/ctr_drbg.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define RUNIT_PRINT_RANDOM_KEYS 0
+
+#define DIGEST_SIZE         64
+#define ECP_GROUP_ID        MBEDTLS_ECP_DP_SECP256R1
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static int runIt_isEciesGrpSupported(mbedtls_ecp_group_id grpId);
+static RunItError_t runIt_eciesRandom(void);
+static RunItError_t runIt_eciesVector(void);
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_eciesRandom(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    mbedtls_ecp_group *pGrp = NULL;
+    mbedtls_ecp_point *pQ = NULL;
+    mbedtls_mpi d;
+
+    const char * testName = NULL;
+    uint8_t* pSenderSecret = NULL;
+    uint8_t* pRecieverSecret = NULL;
+    static const size_t SECRET_KEY_LEN_BYTES = 200;
+    uint8_t* pCipher = NULL;
+    size_t cipherDataSize = MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES;
+    uint32_t *pBuf = NULL;
+
+    RunItPtr grpPtr;
+    RunItPtr senderSecretPtr;
+    RunItPtr recieverSecretPtr;
+    RunItPtr ciphertPtr;
+    RunItPtr qPtr;
+    RunItPtr bufPtr;
+
+    const char* TEST_NAME = "ECIES Random";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    if (runIt_isEciesGrpSupported(ECP_GROUP_ID) == 0)
+    {
+        testName = "UNKNOWN";
+        goto skip;
+    }
+
+    ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
+    ALLOC(senderSecretPtr, pSenderSecret, SECRET_KEY_LEN_BYTES);
+    ALLOC(recieverSecretPtr, pRecieverSecret, SECRET_KEY_LEN_BYTES);
+    ALLOC(ciphertPtr, pCipher, MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES);
+    ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
+    ALLOC32(bufPtr, pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
+
+    mbedtls_ecp_group_init(pGrp);
+    mbedtls_ecp_point_init(pQ);
+    mbedtls_mpi_init(&d);
+    memset(pBuf, 0, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
+    memset((uint8_t*)pSenderSecret, 0, SECRET_KEY_LEN_BYTES);
+    memset((uint8_t*)pRecieverSecret, 0, SECRET_KEY_LEN_BYTES);
+
+    RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, ECP_GROUP_ID) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_gen_keypair(pGrp, &d, pQ, gpRndContext->rndGenerateVectFunc, gpRndState) == 0);
+
+    testName = mbedtls_ecp_curve_info_from_grp_id(ECP_GROUP_ID)->name;
+
+#if RUNIT_PRINT_RANDOM_KEYS
+    {
+        size_t olen = 0;
+        RUNIT_ASSERT_API(mbedtls_ecp_point_write_binary(pGrp, pQ, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES) == 0);
+        RUNIT_PRINT_BUF(pBuf, olen, "public binary");
+
+        RUNIT_ASSERT_API(mbedtls_mpi_write_binary(&d, pBuf, mbedtls_mpi_size(&d)) == 0);
+        RUNIT_PRINT_BUF(pBuf, mbedtls_mpi_size(&d), "private binary");
+    }
+#endif
+
+    RUNIT_ASSERT_API(mbedtls_ecies_kem_encrypt(pGrp,
+                                               pQ,
+                                               CC_KDF_ISO18033_KDF1_DerivMode,
+                                               CC_HKDF_HASH_SHA256_mode,
+                                               1,
+                                               pSenderSecret,
+                                               SECRET_KEY_LEN_BYTES,
+                                               pCipher,
+                                               &cipherDataSize,
+                                               pBuf,
+                                               MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES,
+                                               gpRndContext->rndGenerateVectFunc,
+                                               gpRndContext->rndState) == 0);
+
+    RUNIT_PRINT_BUF(pCipher, cipherDataSize, "pCipher");
+
+    RUNIT_ASSERT_API(mbedtls_ecies_kem_decrypt(pGrp,
+                                               &d,
+                                               CC_KDF_ISO18033_KDF1_DerivMode,
+                                               CC_HKDF_HASH_SHA256_mode,
+                                               1,
+                                               pCipher,
+                                               cipherDataSize,
+                                               pRecieverSecret,
+                                               SECRET_KEY_LEN_BYTES,
+                                               pBuf,
+                                               MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES) == 0);
+
+    RUNIT_PRINT_BUF(pSenderSecret, SECRET_KEY_LEN_BYTES, "pSenderSecret");
+    RUNIT_PRINT_BUF(pRecieverSecret, SECRET_KEY_LEN_BYTES, "pRecieverSecret");
+
+    RUNIT_ASSERT(memcmp(pSenderSecret, pRecieverSecret, SECRET_KEY_LEN_BYTES) == 0);
+
+bail:
+    mbedtls_ecp_group_free(pGrp);
+    mbedtls_ecp_point_free(pQ);
+    mbedtls_mpi_free(&d);
+
+    FREE_IF_NOT_NULL(grpPtr);
+    FREE_IF_NOT_NULL(senderSecretPtr);
+    FREE_IF_NOT_NULL(recieverSecretPtr);
+    FREE_IF_NOT_NULL(ciphertPtr);
+    FREE_IF_NOT_NULL(qPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+
+skip:
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] DERIVE[ISO18033_KDF1] MD[SHA256]", testName);
+    return rc;
+}
+
+static int runIt_isEciesGrpSupported(mbedtls_ecp_group_id grpId)
+{
+    const mbedtls_ecp_group_id * pGrpIdList = mbedtls_ecp_grp_id_list();
+
+    while (*pGrpIdList != MBEDTLS_ECP_DP_NONE)
+    {
+        RUNIT_PRINT_DBG("test %"PRIu32" pGrpIdList %"PRIu32"\n", (uint32_t)grpId, (uint32_t)*pGrpIdList);
+        if (grpId == *pGrpIdList)
+            return 1;
+
+        pGrpIdList++;
+    }
+
+    return 0;
+}
+
+static RunItError_t runIt_eciesVector(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static const char* INPUT_D = "895a6ff53cd45011b125cd22c3f578bd77f916402f01d96488e12ddfa7fc61ec";
+    static const char* INPUT_X = "efbbaee7568701f463187d7bf88d1dbf26dd597602f860512a0dea5842fd6cfa";
+    static const char* INPUT_Y = "c1276720f57d2cc777b51dea53c086fe1cf315dc899c948f169f2206da4f6b3b";
+
+    static const char* INPUT_EPH_D = "2b74dd5215d265d8b2df0488d2a01586830a832f731ce5e1a3db9aa8f99f8cd5";
+    static const char* INPUT_EPH_X = "4b27901968c47b81f88116723ddd6a02be1d3bb6a820b69ee0198bc35606cabc";
+    static const char* INPUT_EPH_Y = "99e388fc709819ac66c5aafab3d250e1fbb247594ddb4b5b33bce91b91fa14f9";
+
+    mbedtls_ecp_group *pGrp = NULL;
+    mbedtls_ecp_point *pQ = NULL;
+    mbedtls_mpi d;
+    mbedtls_ecp_point *pQEph = NULL;
+    mbedtls_mpi dEph;
+    uint32_t *pBuf = NULL;
+
+    uint8_t* pSenderSecret = NULL;
+    uint8_t* pRecieverSecret = NULL;
+    static const size_t SECRET_KEY_LEN_BYTES = 128;
+    uint8_t* pCipher = NULL;
+    size_t cipherDataSize = MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES;
+    size_t olen = 0;
+
+    RunItPtr grpPtr;
+    RunItPtr senderSecretPtr;
+    RunItPtr recieverSecretPtr;
+    RunItPtr ciphertPtr;
+    RunItPtr qPtr;
+    RunItPtr qEphPtr;
+    RunItPtr bufPtr;
+
+    const char* TEST_NAME = "ECIES Vector";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_ecp_group, grpPtr, pGrp);
+    ALLOC(senderSecretPtr, pSenderSecret, SECRET_KEY_LEN_BYTES);
+    ALLOC(recieverSecretPtr, pRecieverSecret, SECRET_KEY_LEN_BYTES);
+    ALLOC(ciphertPtr, pCipher, MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES);
+    ALLOC_STRUCT(mbedtls_ecp_point, qPtr, pQ);
+    ALLOC_STRUCT(mbedtls_ecp_point, qEphPtr, pQEph);
+    ALLOC32(bufPtr, pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
+
+    mbedtls_ecp_group_init(pGrp);
+    mbedtls_ecp_point_init(pQ);
+    mbedtls_mpi_init(&d);
+    mbedtls_ecp_point_init(pQEph);
+    mbedtls_mpi_init(&dEph);
+
+    memset(pBuf, 0, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES);
+    memset((uint8_t*)pSenderSecret, 0, SECRET_KEY_LEN_BYTES);
+    memset((uint8_t*)pRecieverSecret, 0, SECRET_KEY_LEN_BYTES);
+
+    RUNIT_ASSERT(mbedtls_ecp_group_load(pGrp, ECP_GROUP_ID) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&d, 16, INPUT_D) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_point_read_string(pQ, 16, INPUT_X, INPUT_Y) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&dEph, 16, INPUT_EPH_D) == 0);
+    RUNIT_ASSERT(mbedtls_ecp_point_read_string(pQEph, 16, INPUT_EPH_X, INPUT_EPH_Y) == 0);
+
+    RUNIT_ASSERT(mbedtls_ecp_point_write_binary(pGrp, pQ, MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, (uint8_t*)pBuf, MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES) == 0);
+    RUNIT_PRINT_BUF(pBuf, olen, "public binary");
+
+    RUNIT_ASSERT(mbedtls_mpi_write_binary(&dEph, (uint8_t*)pBuf, mbedtls_mpi_size(&dEph)) == 0);
+    RUNIT_PRINT_BUF(pBuf, mbedtls_mpi_size(&dEph), "private binary");
+
+    RUNIT_ASSERT_API(mbedtls_ecies_kem_encrypt_full(pGrp,
+                                                    pQ,
+                                                    CC_KDF_ISO18033_KDF1_DerivMode,
+                                                    CC_HKDF_HASH_SHA256_mode,
+                                                    1,
+                                                    pQEph,
+                                                    &dEph,
+                                                    pSenderSecret,
+                                                    SECRET_KEY_LEN_BYTES,
+                                                    pCipher,
+                                                    &cipherDataSize,
+                                                    pBuf,
+                                                    MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES,
+                                                    gpRndContext->rndGenerateVectFunc,
+                                                    gpRndContext->rndState) == 0);
+
+    RUNIT_PRINT_BUF(pCipher, cipherDataSize, "pCipher");
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_ecies_kem_decrypt(pGrp,
+                                                       &d,
+                                                       CC_KDF_ISO18033_KDF1_DerivMode,
+                                                       CC_HKDF_HASH_SHA256_mode,
+                                                       1,
+                                                       pCipher,
+                                                       cipherDataSize,
+                                                       pRecieverSecret,
+                                                       SECRET_KEY_LEN_BYTES,
+                                                       pBuf,
+                                                       MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES), 0);
+
+    RUNIT_PRINT_BUF(pSenderSecret, SECRET_KEY_LEN_BYTES, "pSenderSecret");
+    RUNIT_PRINT_BUF(pRecieverSecret, SECRET_KEY_LEN_BYTES, "pRecieverSecret");
+
+    RUNIT_ASSERT(memcmp(pRecieverSecret, pSenderSecret, SECRET_KEY_LEN_BYTES) == 0);
+
+bail:
+    mbedtls_ecp_group_free(pGrp);
+    mbedtls_ecp_point_free(pQ);
+    mbedtls_ecp_point_free(pQEph);
+    mbedtls_mpi_free(&d);
+    mbedtls_mpi_free(&dEph);
+
+    FREE_IF_NOT_NULL(grpPtr);
+    FREE_IF_NOT_NULL(senderSecretPtr);
+    FREE_IF_NOT_NULL(recieverSecretPtr);
+    FREE_IF_NOT_NULL(ciphertPtr);
+    FREE_IF_NOT_NULL(qPtr);
+    FREE_IF_NOT_NULL(qEphPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "ID[%s] DERIVE[ISO18033_KDF1] MD[SHA256]", mbedtls_ecp_curve_info_from_grp_id(ECP_GROUP_ID)->name);
+    return rc;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_eciesTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "ECIES";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_eciesRandom() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_eciesVector() == RUNIT_ERROR__OK);
+
+bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ext_dma.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ext_dma.c
new file mode 100644
index 0000000..5788e6a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_ext_dma.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* cc lib */
+#include "cc_aes_defs.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "cc_hal_plat.h"
+#if defined(CC_CONFIG_SUPPORT_EXT_DMA)
+#include "mbedtls_aes_ext_dma.h"
+#endif
+
+/* mbedtls lib */
+#include "mbedtls/cipher.h"
+#include "mbedtls/timing.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_extDma(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_extDma(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(CC_CONFIG_SUPPORT_EXT_DMA)
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_CTR.pdf */
+    static const uint8_t KEY[] = { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 };
+    static const uint8_t PLAIN[] = { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A };
+    static const uint8_t CYPHER[] = { 0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5, 0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28 };
+    static const uint8_t NONCE[] = { 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };
+
+    uint32_t dataLen = sizeof(PLAIN);
+    size_t keySize = sizeof(KEY);
+    uint8_t *dataInBuff = NULL;
+    uint32_t *dataInWords = NULL;
+    uint32_t *outputBuffer = NULL;
+    uint32_t k = 0, i =0;
+    uint32_t sizeInWords = 0;
+    uint32_t wordsToRW = 0;
+    CCAesIv_t ivBuff = {0};
+    uint8_t keyBuff[CC_AES_KEY_MAX_SIZE_IN_BYTES] = {0};
+
+    RunItPtr dataInBuffPtr;
+    RunItPtr outputBufferPtr;
+    RunItPtr dataInWordsPtr;
+
+    const char* TEST_NAME = "External DMA";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    sizeInWords = (dataLen + 3) / sizeof(uint32_t);
+    /*
+     * you DO NOT have to allocate the buffers in a DMAble address space.
+     */
+    ALLOC_AND_COPY(dataInBuffPtr, dataInBuff, PLAIN, dataLen);
+    ALLOC32(outputBufferPtr, outputBuffer, dataLen);
+    ALLOC32(dataInWordsPtr, dataInWords, sizeInWords * sizeof(uint32_t));
+
+    memcpy(ivBuff, NONCE, sizeof(ivBuff));
+    memcpy(keyBuff, KEY, sizeof(keyBuff));
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_aes_ext_dma_init(keySize * 8, CC_AES_ENCRYPT, CC_AES_MODE_CTR), CC_OK);
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_aes_ext_dma_set_key(CC_AES_MODE_CTR, keyBuff, keySize * 8), CC_OK);
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_aes_ext_dma_set_iv(CC_AES_MODE_CTR, ivBuff, 16), CC_OK);
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_aes_ext_dma_set_data_size(dataLen, CC_AES_MODE_CTR), CC_OK);
+
+    memset(dataInWords, 0, sizeInWords * sizeof(uint32_t));
+    memcpy(dataInWords, dataInBuff, dataLen);
+
+    // DATA DIN and DATA DOUT are written and read in 4 Words chunks.
+    while (k < sizeInWords)
+    {
+        if (sizeInWords - k > 4)
+        {
+            wordsToRW = 4;
+        }
+        else
+        {
+            wordsToRW = (sizeInWords - k);
+        }
+
+        for (i = 0; i < wordsToRW; i++)
+        {
+            CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF, DIN_BUFFER), dataInWords[i + k]);
+        }
+
+        for (i = 0; i < wordsToRW; i++)
+        {
+            outputBuffer[i + k] = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, DOUT_BUFFER));
+        }
+
+        k += 4;
+    }
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_aes_ext_dma_finish(CC_AES_MODE_CTR, ivBuff, 16), CC_OK);
+
+    RUNIT_PRINT_BUF(outputBuffer, sizeInWords * sizeof(uint32_t), "outputBuffer");
+    RUNIT_ASSERT(memcmp(outputBuffer, CYPHER, sizeInWords * sizeof(uint32_t)) == 0);
+
+bail:
+
+    FREE_IF_NOT_NULL(dataInBuffPtr);
+    FREE_IF_NOT_NULL(outputBufferPtr);
+    FREE_IF_NOT_NULL(dataInWordsPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] PLAIN[%"PRIu32"B]",
+                                   (uint32_t)keySize, (uint32_t)dataLen);
+#endif /* CC_CONFIG_SUPPORT_EXT_DMA */
+    return rc;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_extDmaTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "External DMA";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_extDma() == RUNIT_ERROR__OK);
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_gcm.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_gcm.c
new file mode 100644
index 0000000..a817b6b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_gcm.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/gcm.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/timing.h"
+
+/* pal */
+#include "test_pal_mem.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_gcmProfiling(size_t data_len);
+static RunItError_t runIt_gcm(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+
+static RunItError_t runIt_gcmProfiling(size_t data_len)
+{
+
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_GCM_C)
+    static const uint8_t key[] = {0xFE,0xFF,0xE9,0x92,0x86,0x65,0x73,0x1C,0x6D,0x6A,0x8F,0x94,0x67,0x30,0x83,0x08};
+    static const uint8_t iv[] = {0xCA,0xFE,0xBA,0xBE,0xFA,0xCE,0xDB,0xAD,0xDE,0xCA,0xF8,0x88};
+    static const size_t iv_len = sizeof(iv);
+    static const uint8_t additional[] = {0x3A,0xD7,0x7B,0xB4,0x0D,0x7A,0x36,0x60,0xA8,0x9E,0xCA,0xF3,0x24,0x66,0xEF,0x97};
+    static const size_t add_len = sizeof(additional);
+    static const size_t tag_len = 16;
+    static const int key_len = sizeof(key) * 8;
+
+    RunItPtr ctxPtr;
+    mbedtls_gcm_context *pCtx = NULL;
+
+    RunItPtr cipherPtr, plainBufPtr, tagBufPtr, ivBufPtr, addBufPtr;
+    uint8_t *pCipher = NULL, *pPlainBuf = NULL, *pTagBuf = NULL, *pIvBuf = NULL, *pAddBuf = NULL;
+    char testParam[PARAM_LEN] = { 0 };
+
+    const char* TEST_NAME = "AES-GCM Profiling";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    snprintf(testParam, PARAM_LEN - 1, "%"PRIu32"B", (uint32_t)data_len);
+
+    ALLOC_STRUCT(mbedtls_gcm_context, ctxPtr, pCtx);
+    ALLOC(cipherPtr, pCipher, data_len);
+    ALLOC(plainBufPtr, pPlainBuf, data_len);
+    ALLOC(tagBufPtr, pTagBuf, tag_len);
+    ALLOC_AND_COPY(ivBufPtr, pIvBuf, iv, iv_len);
+    ALLOC_AND_COPY(addBufPtr, pAddBuf, additional, add_len);
+
+
+
+    /***************************************************************
+     *                     ENCRYPTION                              *
+     ***************************************************************/
+
+    RUNIT_ASSERT(runIt_buildRandomBuffer(pPlainBuf, data_len) == 0);
+
+    RUNIT_API(mbedtls_gcm_init(pCtx));
+
+    RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_gcm_crypt_and_tag(pCtx,
+                                                       MBEDTLS_GCM_ENCRYPT,
+                                                       data_len,
+                                                       pIvBuf,
+                                                       iv_len,
+                                                       pAddBuf,
+                                                       add_len,
+                                                       pPlainBuf,
+                                                       pCipher,
+                                                       tag_len,
+                                                       pTagBuf), 0);
+
+bail:
+    RUNIT_API(mbedtls_gcm_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(cipherPtr);
+    FREE_IF_NOT_NULL(plainBufPtr);
+    FREE_IF_NOT_NULL(tagBufPtr);
+    FREE_IF_NOT_NULL(ivBufPtr);
+    FREE_IF_NOT_NULL(addBufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] AAD[%"PRIu32"B]",
+                                   (uint32_t)key_len, (uint32_t)data_len, (uint32_t)add_len);
+#endif /* defined(MBEDTLS_GCM_C) */
+    return rc;
+
+
+}
+
+static RunItError_t runIt_gcm(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_GCM_C)
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/AES_GCM.pdf */
+    static const uint8_t key[] = {0xFE,0xFF,0xE9,0x92,0x86,0x65,0x73,0x1C,0x6D,0x6A,0x8F,0x94,0x67,0x30,0x83,0x08};
+    static const uint8_t iv[] = {0xCA,0xFE,0xBA,0xBE,0xFA,0xCE,0xDB,0xAD,0xDE,0xCA,0xF8,0x88};
+    static const size_t iv_len = sizeof(iv);
+    static const uint8_t additional[] = {0x3A,0xD7,0x7B,0xB4,0x0D,0x7A,0x36,0x60,0xA8,0x9E,0xCA,0xF3,0x24,0x66,0xEF,0x97,0xF5,0xD3,0xD5,0x85,0x03,0xB9,0x69,0x9D,0xE7,0x85,0x89,0x5A,0x96,0xFD,0xBA,0xAF,0x43,0xB1,0xCD,0x7F,0x59,0x8E,0xCE,0x23,0x88,0x1B,0x00,0xE3,0xED,0x03,0x06,0x88,0x7B,0x0C,0x78,0x5E,0x27,0xE8,0xAD,0x3F,0x82,0x23,0x20,0x71,0x04,0x72,0x5D,0xD4};
+    static const size_t add_len = sizeof(additional);
+    static const uint8_t pt[] = {0xD9,0x31,0x32,0x25,0xF8,0x84,0x06,0xE5,0xA5,0x59,0x09,0xC5,0xAF,0xF5,0x26,0x9A,0x86,0xA7,0xA9,0x53,0x15,0x34,0xF7,0xDA,0x2E,0x4C,0x30,0x3D,0x8A,0x31,0x8A,0x72,0x1C,0x3C,0x0C,0x95,0x95,0x68,0x09,0x53,0x2F,0xCF,0x0E,0x24,0x49,0xA6,0xB5,0x25,0xB1,0x6A,0xED,0xF5,0xAA,0x0D,0xE6,0x57,0xBA,0x63,0x7B,0x39,0x1A,0xAF,0xD2,0x55};
+    static const size_t pt_len = sizeof(pt);
+    static const uint8_t ct[] = {0x42,0x83,0x1E,0xC2,0x21,0x77,0x74,0x24,0x4B,0x72,0x21,0xB7,0x84,0xD0,0xD4,0x9C,0xE3,0xAA,0x21,0x2F,0x2C,0x02,0xA4,0xE0,0x35,0xC1,0x7E,0x23,0x29,0xAC,0xA1,0x2E,0x21,0xD5,0x14,0xB2,0x54,0x66,0x93,0x1C,0x7D,0x8F,0x6A,0x5A,0xAC,0x84,0xAA,0x05,0x1B,0xA3,0x0B,0x39,0x6A,0x0A,0xAC,0x97,0x3D,0x58,0xE0,0x91,0x47,0x3F,0x59,0x85};
+    static const size_t ct_len = sizeof(ct);
+    static const uint8_t tag[] = {0x64,0xC0,0x23,0x29,0x04,0xAF,0x39,0x8A,0x5B,0x67,0xC1,0x0B,0x53,0xA5,0x02,0x4D};
+    static const size_t tag_len = sizeof(tag);
+    static const int key_len = sizeof(key) * 8;
+
+    RunItPtr ctxPtr;
+    mbedtls_gcm_context *pCtx = NULL;
+
+    RunItPtr bufPtr, cipherPtr, plainBufPtr, tagBufPtr, ivBufPtr, addBufPtr;
+    uint8_t *pBuf = NULL, *pCipher = NULL, *pPlainBuf = NULL, *pTagBuf = NULL, *pIvBuf = NULL, *pAddBuf = NULL;
+
+    const char* TEST_NAME = "AES-GCM";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_gcm_context, ctxPtr, pCtx);
+    ALLOC(bufPtr, pBuf, ct_len);
+    ALLOC_AND_COPY(cipherPtr, pCipher, ct, ct_len);
+    ALLOC_AND_COPY(plainBufPtr, pPlainBuf, pt, pt_len);
+    ALLOC(tagBufPtr, pTagBuf, tag_len);
+    ALLOC_AND_COPY(ivBufPtr, pIvBuf, iv, iv_len);
+    ALLOC_AND_COPY(addBufPtr, pAddBuf, additional, add_len);
+
+    memset(pBuf, 0, sizeof(ct));
+
+    /***************************************************************
+     *                     ENCRYPTION                              *
+     ***************************************************************/
+    RUNIT_API(mbedtls_gcm_init(pCtx));
+
+    RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
+
+    RUNIT_ASSERT_W_PARAM("encrypt", mbedtls_gcm_crypt_and_tag(pCtx,
+                                                              MBEDTLS_GCM_ENCRYPT,
+                                                              pt_len,
+                                                              pIvBuf,
+                                                              iv_len,
+                                                              pAddBuf,
+                                                              add_len,
+                                                              pPlainBuf,
+                                                              pBuf,
+                                                              sizeof(tag),
+                                                              pTagBuf) == 0);
+
+    RUNIT_PRINT_BUF(pBuf, ct_len, "pBuf");
+    RUNIT_PRINT_BUF(ct, ct_len, "ct");
+
+    RUNIT_PRINT_BUF(pTagBuf, tag_len, "pTagBuf");
+    RUNIT_PRINT_BUF(tag, tag_len, "tag");
+
+    RUNIT_ASSERT(memcmp(pBuf, ct, pt_len) == 0);
+    RUNIT_ASSERT(memcmp(pTagBuf, tag, tag_len) == 0);
+
+    RUNIT_API(mbedtls_gcm_free(pCtx));
+
+    /***************************************************************
+     *                     DECRYPTION                              *
+     ***************************************************************/
+    memset(pBuf, 0, sizeof(ct));
+    memcpy(pTagBuf, tag, tag_len);
+
+    RUNIT_API(mbedtls_gcm_init(pCtx));
+
+    RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
+
+    RUNIT_ASSERT_W_PARAM("decrypt", mbedtls_gcm_crypt_and_tag(pCtx,
+                                                              MBEDTLS_GCM_DECRYPT,
+                                                              pt_len,
+                                                              pIvBuf,
+                                                              iv_len,
+                                                              pAddBuf,
+                                                              add_len,
+                                                              pCipher,
+                                                              pBuf,
+                                                              tag_len,
+                                                              pTagBuf) == 0);
+
+
+    RUNIT_ASSERT(memcmp(pBuf, pt, pt_len) == 0);
+
+    RUNIT_API(mbedtls_gcm_free(pCtx));
+
+    /***************************************************************
+     *            ALTERNATIVE DECRYPTION API                       *
+     ***************************************************************/
+    memset(pBuf, 0, sizeof(ct));
+    memcpy(pTagBuf, tag, tag_len);
+
+    RUNIT_API(mbedtls_gcm_init(pCtx));
+
+    RUNIT_API(mbedtls_gcm_setkey(pCtx, MBEDTLS_CIPHER_ID_AES, key, key_len));
+
+    RUNIT_ASSERT_API(mbedtls_gcm_auth_decrypt(pCtx,
+                                              pt_len,
+                                              pIvBuf,
+                                              iv_len,
+                                              pAddBuf,
+                                              add_len,
+                                              pTagBuf,
+                                              tag_len,
+                                              pCipher,
+                                              pBuf) == 0);
+
+    RUNIT_ASSERT(memcmp(pBuf, pt, pt_len) == 0);
+
+bail:
+    RUNIT_API(mbedtls_gcm_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(bufPtr);
+    FREE_IF_NOT_NULL(cipherPtr);
+    FREE_IF_NOT_NULL(plainBufPtr);
+    FREE_IF_NOT_NULL(tagBufPtr);
+    FREE_IF_NOT_NULL(ivBufPtr);
+    FREE_IF_NOT_NULL(addBufPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] AAD[%"PRIu32"B]",
+                                   (uint32_t)key_len, (uint32_t)pt_len, (uint32_t)add_len);
+#endif /* defined(MBEDTLS_GCM_C) */
+    return rc;
+
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_gcmTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "GCM";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_gcm() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_gcmProfiling(16) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_gcmProfiling(128) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_gcmProfiling(1024) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_gcmProfiling(8192) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_gcmProfiling(65535) == RUNIT_ERROR__OK);
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_key_derivation.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_key_derivation.c
new file mode 100644
index 0000000..23da37a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_key_derivation.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/hkdf.h"
+#include "mbedtls/md.h"
+#include "mbedtls/timing.h"
+
+/* CC */
+#include "cc_aes_defs.h"
+#include "cc_pal_types.h"
+#include "mbedtls_cc_util_defs.h"
+#include "cc_util_error.h"
+#include "mbedtls_cc_util_key_derivation.h"
+#include "cc_hash_defs.h"
+
+/* pal */
+#include "test_pal_mem.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+#include "run_integration_otp.h"
+
+#ifdef RUNIT_PIE_ENABLED
+/* include sbrom data file to determine whether we are running system flows */
+#include "bsv_integration_data_def.h"
+#endif /* RUNIT_PIE_ENABLED */
+
+#ifndef RUNIT_KDF_SKIP_COMPARE
+#define RUNIT_KDF_SKIP_COMPARE 1
+#endif
+
+#ifndef RUNIT_KDF_ROOT_KEY_SKIP_TEST
+#define RUNIT_KDF_ROOT_KEY_SKIP_TEST 1
+#endif
+
+/************************************************************
+ *
+ * static functions prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_hmacKeyDerivTest(void);
+static RunItError_t runIt_cmacKeyDerivTest(void);
+static RunItError_t runIt_cmacRootKeyDerivTest(void);
+static RunItError_t runIt_hkdfKeyDerivTest(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_hmacKeyDerivTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static const uint8_t userKeyDataOut[] = { 0xba, 0x58, 0xa5, 0xc5, 0x88, 0x59, 0x88, 0x37, 0x72, 0xb6, 0x93, 0x68, 0xee, 0x53, 0xf4, 0x7c  };
+    static const uint8_t label[] = { 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xEF, 0x3E, 0x3E, 0xE8, 0xEF };
+    static const uint8_t context[] = { 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3D, 0xFB, 0xAF, 0x7F };
+    static const uint8_t userKey[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
+
+    uint8_t* pLabel = NULL;
+    uint8_t* pContext = NULL;
+    uint8_t* pUserKey = NULL;
+    uint8_t* pDataOut = NULL;
+
+    RunItPtr labelPtr;
+    RunItPtr contextPtr;
+    RunItPtr userKeyPtr;
+    RunItPtr dataOutPtr;
+
+    mbedtls_util_keydata keyData = {0};
+    uint32_t dataOutLength = sizeof(userKeyDataOut);
+
+    const char* TEST_NAME = "HMAC Key Derivation";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_AND_COPY(labelPtr, pLabel, label, sizeof(label));
+    ALLOC_AND_COPY(contextPtr, pContext, context, sizeof(context));
+    ALLOC_AND_COPY(userKeyPtr, pUserKey, userKey, sizeof(userKey));
+    ALLOC(dataOutPtr, pDataOut, dataOutLength);
+
+    keyData.pKey = pUserKey;
+    keyData.keySize = sizeof(userKey);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_hmac(CC_UTIL_USER_KEY,
+                                                              (void*)&keyData,
+                                                              CC_HASH_SHA256_mode,
+                                                              (uint8_t *)pLabel,
+                                                              sizeof(label),
+                                                              (uint8_t *)pContext,
+                                                              sizeof(context),
+                                                              (uint8_t *)pDataOut,
+                                                              dataOutLength),
+                             CC_UTIL_OK);
+
+    RUNIT_PRINT_BUF(keyData.pKey, keyData.keySize, "keyData.pKey");
+    RUNIT_PRINT_BUF(label, sizeof(label), "label");
+    RUNIT_PRINT_BUF(context, sizeof(context), "context");
+    RUNIT_PRINT_BUF(pDataOut, dataOutLength, "dataOutBuff");
+
+    RUNIT_ASSERT(memcmp(pDataOut, userKeyDataOut, dataOutLength) == 0);
+
+bail:
+
+    FREE_IF_NOT_NULL(labelPtr);
+    FREE_IF_NOT_NULL(contextPtr);
+    FREE_IF_NOT_NULL(userKeyPtr);
+    FREE_IF_NOT_NULL(dataOutPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "MODE[SHA256] KEY[%ub] CONTEXT[%uB] LABEL[%uB]", keyData.keySize * 8, sizeof(context), sizeof(label));
+    return rc;
+}
+
+static RunItError_t runIt_cmacKeyDerivTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static uint8_t context[] = { 0x54,0x45,0x53,0x54 };
+    static uint8_t label[] = { 0x55,0x53,0x45,0x52,0xF2,0x4B,0x45,0x59 };
+    static const uint8_t userKey[] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
+    static const uint8_t userKeyDataOut[] = { 0x2B, 0x05, 0xE1, 0xF8, 0xF0, 0x58, 0x78, 0xAC, 0x41, 0xB0, 0xB5, 0x5D, 0xB0, 0x42, 0x9E, 0x5C };
+
+    uint8_t* pLabel = NULL;
+    uint8_t* pContext = NULL;
+    uint8_t* pUserKey = NULL;
+    uint8_t* pDataOut = NULL;
+
+    RunItPtr labelPtr;
+    RunItPtr contextPtr;
+    RunItPtr userKeyPtr;
+    RunItPtr dataOutPtr;
+
+    mbedtls_util_keydata keyData={0};
+    uint32_t dataOutLength = sizeof(userKeyDataOut);
+
+    const char* TEST_NAME = "CMAC Key Derivation";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_AND_COPY(labelPtr, pLabel, label, sizeof(label));
+    ALLOC_AND_COPY(contextPtr, pContext, context, sizeof(context));
+    ALLOC_AND_COPY(userKeyPtr, pUserKey, userKey, sizeof(userKey));
+    ALLOC(dataOutPtr, pDataOut, dataOutLength);
+
+    keyData.pKey = (uint8_t*)pUserKey;
+    keyData.keySize = sizeof(userKey);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_cmac(CC_UTIL_USER_KEY,
+                                                              (void*)&keyData,
+                                                              (uint8_t *)pLabel,
+                                                              sizeof(label),
+                                                              (uint8_t *)pContext,
+                                                              sizeof(context),
+                                                              (uint8_t *)pDataOut,
+                                                              dataOutLength),
+                             CC_UTIL_OK);
+
+    RUNIT_PRINT_BUF(pDataOut, dataOutLength, "pDataOut");
+
+    RUNIT_ASSERT(memcmp(pDataOut, userKeyDataOut, dataOutLength) == 0);
+
+bail:
+
+    FREE_IF_NOT_NULL(labelPtr);
+    FREE_IF_NOT_NULL(contextPtr);
+    FREE_IF_NOT_NULL(userKeyPtr);
+    FREE_IF_NOT_NULL(dataOutPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] CONTEXT[%"PRIu32"B] LABEL[%"PRIu32"B]",
+                                   (uint32_t)keyData.keySize * 8, (uint32_t)sizeof(context), (uint32_t)sizeof(label));
+    return rc;
+}
+
+static RunItError_t runIt_cmacRootKeyDerivTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if !RUNIT_KDF_ROOT_KEY_SKIP_TEST
+    static uint8_t context[] = { 0x54,0x45,0x53,0x54 };
+    static uint8_t label[] = { 0x55,0x53,0x45,0x52,0xF2,0x4B,0x45,0x59 };
+    static const uint8_t userKey[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+    static const uint8_t userKeyDataOut[] = { RUNIT_KDF_RESULT };
+
+    uint8_t* pLabel = NULL;
+    uint8_t* pContext = NULL;
+    uint8_t* pUserKey = NULL;
+    uint8_t* pDataOut = NULL;
+    uint8_t* pDataOutRef = NULL;
+
+    RunItPtr labelPtr;
+    RunItPtr contextPtr;
+    RunItPtr userKeyPtr;
+    RunItPtr dataOutPtr;
+    RunItPtr dataOutRefPtr;
+
+    mbedtls_util_keydata keyData;
+    uint32_t dataOutLength = sizeof(userKeyDataOut);
+
+    const char* TEST_NAME = "CMAC Root Key Derivation";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    (void)userKeyDataOut;
+
+    ALLOC_AND_COPY(labelPtr, pLabel, label, sizeof(label));
+    ALLOC_AND_COPY(contextPtr, pContext, context, sizeof(context));
+    ALLOC_AND_COPY(userKeyPtr, pUserKey, userKey, sizeof(userKey));
+    ALLOC(dataOutPtr, pDataOut, dataOutLength);
+    ALLOC(dataOutRefPtr, pDataOutRef, dataOutLength);
+
+    keyData.pKey = (uint8_t*)pUserKey;
+    keyData.keySize = sizeof(userKey);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_cmac(CC_UTIL_USER_KEY,
+                                                              (void*)&keyData,
+                                                              (uint8_t *)pLabel,
+                                                              sizeof(label),
+                                                              (uint8_t *)pContext,
+                                                              sizeof(context),
+                                                              (uint8_t *)pDataOutRef,
+                                                              dataOutLength),
+                             CC_UTIL_OK);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_util_key_derivation_cmac(CC_UTIL_ROOT_KEY,
+                                                              (void*)&keyData,
+                                                              (uint8_t *)pLabel,
+                                                              sizeof(label),
+                                                              (uint8_t *)pContext,
+                                                              sizeof(context),
+                                                              (uint8_t *)pDataOut,
+                                                              dataOutLength),
+                             CC_UTIL_OK);
+
+    RUNIT_PRINT_BUF(pDataOutRef, dataOutLength, "pDataOutRef");
+    RUNIT_PRINT_BUF(pDataOut, dataOutLength, "pDataOut");
+
+
+#if RUNIT_KDF_COMPARE_EXPECTED_RESULT
+    RUNIT_ASSERT(memcmp(pDataOut, pDataOutRef, dataOutLength) != 0);
+#else
+    RUNIT_ASSERT(memcmp(pDataOut, pDataOutRef, dataOutLength) == 0);
+#endif
+
+    if (sizeof(userKeyDataOut) != 1)
+        RUNIT_ASSERT(memcmp(pDataOut, userKeyDataOut, dataOutLength) == 0);
+
+bail:
+
+    FREE_IF_NOT_NULL(labelPtr);
+    FREE_IF_NOT_NULL(contextPtr);
+    FREE_IF_NOT_NULL(userKeyPtr);
+    FREE_IF_NOT_NULL(dataOutPtr);
+    FREE_IF_NOT_NULL(dataOutRefPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] CONTEXT[%"PRIu32"B] LABEL[%"PRIu32"B]",
+                                   (uint32_t)keyData.keySize * 8, (uint32_t)sizeof(context), (uint32_t)sizeof(label));
+
+#endif /* !RUNIT_KDF_ROOT_KEY_SKIP_TEST */
+    return rc;
+}
+
+static RunItError_t runIt_hkdfKeyDerivTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static uint8_t hkdf_IKM[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
+    static const uint32_t hkdf_IKMSize = 22;
+    static uint8_t hkdf_Salt[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c };
+    static const uint32_t hkdf_SaltSize = 13;
+    static uint8_t hkdf_Info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 };
+    static const uint32_t hkdf_InfoSize = 10;
+    static const uint8_t hkdf_ExpectOKM[] = { 0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf, 0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65 };
+    static const uint32_t hkdf_LSize = 42;
+    const mbedtls_md_info_t *md = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
+    uint8_t* pOKMDataBuff = NULL;
+
+    RunItPtr okmDataBuff;
+
+    const char* TEST_NAME = "HKDF Key Derivation";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(okmDataBuff, pOKMDataBuff, 4096);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_hkdf(md,
+                                         hkdf_Salt,
+                                         (size_t)hkdf_SaltSize,
+                                         hkdf_IKM,
+                                         hkdf_IKMSize,
+                                         hkdf_Info,
+                                         hkdf_InfoSize,
+                                         pOKMDataBuff,
+                                         hkdf_LSize),
+                             CC_OK);
+
+    /* compare the result and print result*/
+    RUNIT_ASSERT(memcmp(pOKMDataBuff, hkdf_ExpectOKM, hkdf_LSize) == 0);
+
+bail:
+    FREE_IF_NOT_NULL(okmDataBuff);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "MODE[SHA256] IKM[%uB] SALT[%uB] INFO[%uB] OKM[%uB]",
+                                   (unsigned int)hkdf_IKMSize, (unsigned int)hkdf_SaltSize,
+                                   (unsigned int)hkdf_InfoSize, (unsigned int)hkdf_LSize);
+    return rc;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_keyDerivationTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "Key Derivation";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_hmacKeyDerivTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmacKeyDerivTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmacRootKeyDerivTest() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_hkdfKeyDerivTest() == RUNIT_ERROR__OK);
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_mac.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_mac.c
new file mode 100644
index 0000000..a861604
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_mac.c
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/md.h"
+#include "cc_general_defs.h"
+#include "mbedtls/cmac.h"
+/* pal */
+#include "test_pal_mem.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_hmac(void);
+static RunItError_t runIt_cmac(void);
+static RunItError_t runIt_cmacProfiling(size_t data_len);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_hmac(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static uint8_t hmacTest_Key[] = { 0x15, 0xb2, 0x9a, 0xd8, 0xae, 0x2a, 0xad, 0x73, 0xa7, 0x26, 0x43, 0x50, 0x70, 0xe8, 0xe9, 0xda, 0x9b, 0x47, 0x69, 0xc3, 0xe3, 0xa4, 0xee, 0x99, 0x6e, 0x20, 0x6a, 0x9b, 0x4f, 0x0c, 0x35, 0xca, 0x4f, 0xa2, 0xf7, 0x43, 0xed, 0xf2, 0xc7, 0xcb, 0xa3, 0x1e, 0x94, 0xac, 0x6b, 0xca, 0xc4, 0xc0, 0x82, 0xcf, 0x1c, 0xcb, 0x6c, 0x2f, 0xe0, 0x0d, 0x38, 0x4e, 0x3b, 0x18, 0x05, 0x5f, 0xe0, 0xe0 };
+    static const uint16_t hmacTest_KeySize = sizeof(hmacTest_Key);
+    static uint8_t hmacTest_InputData[] = { 0x99, 0xfd, 0x18, 0xa3, 0x5d, 0x50, 0x81, 0x84, 0xa6, 0xf3, 0x61, 0xc6, 0x7c, 0xd9, 0xb1, 0x0b, 0x4c, 0xd1, 0xd8, 0xb2, 0x46, 0x57, 0x2a, 0x4d, 0x03, 0xb0, 0xae, 0x55, 0x6b, 0x36, 0x24, 0x1d, 0xd6, 0xf0, 0x46, 0x05, 0x71, 0x65, 0x4f, 0xf0, 0xe4, 0xb2, 0xba, 0xf8, 0x31, 0xdb, 0x4c, 0x60, 0xdf, 0x5f, 0x54, 0xc9, 0x59, 0x0f, 0x32, 0xa9, 0x91, 0x1f, 0x16, 0xfa, 0xe8, 0x7e, 0x0a, 0x2f, 0x52 };
+    static const uint32_t hmacTest_InputDataSize = sizeof(hmacTest_InputData);
+    static CCHashResultBuf_t hmacTest_ExpOutData = { 0xE0903CC8, 0x24C89469, 0x71B12528, 0x6DEFD88C, 0xF662C7FC, 0x971C4DD1, 0x5755CB85, 0x8E72FD6F };
+    static const uint32_t hmacTest_ExpOutDataSize = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES * sizeof(uint8_t);
+
+    uint8_t *pDataInBuff = NULL;
+    uint8_t *pKey = NULL;
+
+    RunItPtr dataInBuffPtr;
+    RunItPtr keyPtr;
+
+    const mbedtls_md_info_t *md_info = NULL;
+    mbedtls_md_context_t ctx;
+    unsigned char hmacOutBuff[64] = { 0 };
+
+    const char* TEST_NAME = "HMAC";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_AND_COPY(dataInBuffPtr, pDataInBuff, hmacTest_InputData, hmacTest_InputDataSize);
+    ALLOC_AND_COPY(keyPtr, pKey, hmacTest_Key, hmacTest_KeySize);
+
+    /***************************************************************************************
+     *
+     *                  Integrated operation
+     *
+     ***************************************************************************************/
+    RUNIT_API_ASSIGNMENT(md_info, mbedtls_md_info_from_string(HashAlgMode2mbedtlsString[CC_HASH_SHA256_mode]));
+    RUNIT_ASSERT(md_info != NULL);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac( md_info,
+                                              pKey,
+                                              hmacTest_KeySize,
+                                              pDataInBuff,
+                                              hmacTest_InputDataSize,
+                                              hmacOutBuff ), CC_OK);
+
+    RUNIT_ASSERT(memcmp(hmacOutBuff, hmacTest_ExpOutData, hmacTest_ExpOutDataSize) == 0);
+
+
+    /***************************************************************************************
+     *
+     *                  Non integrated operation
+     *
+     ***************************************************************************************/
+    memset(hmacOutBuff, 0, 64);
+
+    RUNIT_API(mbedtls_md_init(&ctx));
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_md_setup(&ctx, md_info, 1), CC_OK); // 1 = HMAC
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac_starts(&ctx, pKey, hmacTest_KeySize), CC_OK);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac_update(&ctx, pDataInBuff, hmacTest_InputDataSize), CC_OK);
+
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_md_hmac_finish(&ctx, hmacOutBuff), CC_OK);
+
+    RUNIT_ASSERT(memcmp(hmacOutBuff, hmacTest_ExpOutData, hmacTest_ExpOutDataSize) == 0);
+    /***************************************************************************************/
+
+bail:
+
+    FREE_IF_NOT_NULL(dataInBuffPtr);
+    FREE_IF_NOT_NULL(keyPtr);
+
+    mbedtls_md_free(&ctx);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "MODE[SHA256] KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] ",
+                                   (uint32_t)hmacTest_KeySize * 8, (uint32_t)hmacTest_InputDataSize);
+    return rc;
+}
+
+/**
+ * This test is meant to measure the execution times of the API.
+ * This test doesn't compare the results with expected result.
+ * I uses the return value to verify everything went well.
+ *
+ * @param block1_len
+ * @return
+ */
+static RunItError_t runIt_cmacProfiling(size_t data_len)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    mbedtls_cipher_type_t cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
+    const char *key_string = "2b7e151628aed2a6abf7158809cf4f3c";
+    int keybits = 128;
+
+    unsigned char *key = NULL;
+    unsigned char *data = NULL;
+    const mbedtls_cipher_info_t *cipher_info = NULL;
+    mbedtls_cipher_context_t *ctx = NULL;
+    unsigned char *output = NULL;
+    char testParam[PARAM_LEN] = { 0 };
+
+    RunItPtr ketPtr;
+    RunItPtr dataPtr;
+    RunItPtr ctxPtr;
+    RunItPtr outputPtr;
+
+    const char* TEST_NAME = "CMAC-Profile";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(ketPtr, key, keybits / 8);
+    ALLOC(dataPtr, data, data_len);
+    ALLOC_STRUCT(mbedtls_cipher_context_t, ctxPtr, ctx);
+    ALLOC(outputPtr, output, MBEDTLS_CIPHER_BLKSIZE_MAX);
+
+    snprintf(testParam, PARAM_LEN - 1, "%"PRIu32"B", (uint32_t)data_len);
+
+    /* Convert the test parameters to binary data */
+    runIt_unhexify( key, key_string );
+
+    /* this is temporary patch */
+    RUNIT_API(mbedtls_cipher_init( ctx ));
+
+    /* Set up */
+    RUNIT_API_ASSIGNMENT(cipher_info, mbedtls_cipher_info_from_type(cipher_type));
+    RUNIT_ASSERT(cipher_info != NULL);
+
+    RUNIT_ASSERT_API(mbedtls_cipher_setup(ctx, cipher_info) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac_starts(ctx, (const unsigned char* )key, keybits) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac_reset(ctx) == 0);
+
+    /* Multiple partial and complete blocks. A negative length means skip the
+     * update operation */
+    RUNIT_ASSERT_W_PARAM(testParam, mbedtls_cipher_cmac_update(ctx, (unsigned char* )data, data_len) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac_finish(ctx, output) == 0);
+
+bail:
+
+    RUNIT_API(mbedtls_cipher_free( ctx ));
+
+    FREE_IF_NOT_NULL(ketPtr);
+    FREE_IF_NOT_NULL(dataPtr);
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(outputPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "TYPE[AES_128_ECB] KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] ",
+                                   (uint32_t)keybits, (uint32_t)data_len);
+    return rc;
+}
+
+static RunItError_t runIt_cmac(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    mbedtls_cipher_type_t cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
+    const char *key_string = "2b7e151628aed2a6abf7158809cf4f3c";
+    int keybits = 128;
+    int block_size = 16;
+    const char *block1_string = "6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710";
+    int block1_len = 64;
+    const char *expected_result_string = "51f0bebf7e3b9d92fc49741779363cfe";
+
+    unsigned char *key = NULL;
+    unsigned char *block1 = NULL;
+    unsigned char *expected_result = NULL;
+    const mbedtls_cipher_info_t *cipher_info = NULL;
+    mbedtls_cipher_context_t *ctx = NULL;
+    unsigned char *output = NULL;
+
+    RunItPtr ketPtr;
+    RunItPtr block1Ptr;
+    RunItPtr expectedResultPtr;
+    RunItPtr ctxPtr;
+    RunItPtr outputPtr;
+
+    const char* TEST_NAME = "CMAC";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(ketPtr, key, keybits / 8);
+    ALLOC(block1Ptr, block1, block1_len);
+    ALLOC(expectedResultPtr, expected_result, block_size);
+    ALLOC_STRUCT(mbedtls_cipher_context_t, ctxPtr, ctx);
+    ALLOC(outputPtr, output, MBEDTLS_CIPHER_BLKSIZE_MAX);
+
+    /* Convert the test parameters to binary data */
+    runIt_unhexify( key, key_string );
+    runIt_unhexify( block1, block1_string );
+    runIt_unhexify( expected_result, expected_result_string );
+
+    RUNIT_API(mbedtls_cipher_init( ctx ));
+
+    /* Set up */
+    RUNIT_API_ASSIGNMENT(cipher_info, mbedtls_cipher_info_from_type(cipher_type));
+    RUNIT_ASSERT(cipher_info != NULL);
+
+    /*
+     * Non Integrated
+     */
+    RUNIT_ASSERT_API(mbedtls_cipher_setup(ctx, cipher_info) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac_starts(ctx, (const unsigned char* )key, keybits) == 0);
+
+    /* this is temporary patch */
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac_reset(ctx) == 0);
+
+    /* Multiple partial and complete blocks. A negative length means skip the
+     * update operation */
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac_update(ctx, (unsigned char* )block1, block1_len) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac_finish(ctx, output) == 0);
+
+    RUNIT_PRINT_BUF(output, MBEDTLS_CIPHER_BLKSIZE_MAX, "output");
+    RUNIT_PRINT_BUF(expected_result, MBEDTLS_CIPHER_BLKSIZE_MAX, "expected_result");
+
+    RUNIT_ASSERT(memcmp(output, expected_result, block_size) == 0);
+
+    /*
+     * Integrated
+     */
+    memset(output, 0, MBEDTLS_CIPHER_BLKSIZE_MAX);
+
+    RUNIT_ASSERT_API(mbedtls_cipher_cmac(cipher_info,
+                        key, keybits,
+                        block1, block1_len,
+                        output) == 0);
+
+    RUNIT_ASSERT(memcmp(output, expected_result, block_size) == 0);
+
+bail:
+
+    RUNIT_API(mbedtls_cipher_free( ctx ));
+
+    FREE_IF_NOT_NULL(ketPtr);
+    FREE_IF_NOT_NULL(block1Ptr);
+    FREE_IF_NOT_NULL(expectedResultPtr);
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(outputPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "TYPE[AES_128_ECB] KEY[%"PRIu32"b] PLAIN[%"PRIu32"B] ",
+                                   (uint32_t)keybits, (uint32_t)block1_len);
+    return rc;
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_macTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "HMAC";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_hmac() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmac() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmacProfiling(16) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmacProfiling(128) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmacProfiling(1024) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmacProfiling(8192) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_cmacProfiling(65535) == RUNIT_ERROR__OK);
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_rsa.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_rsa.c
new file mode 100644
index 0000000..0853e08
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_rsa.c
@@ -0,0 +1,717 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/rsa.h"
+#include "mbedtls/timing.h"
+#include "mbedtls/bignum.h"
+#include "mbedtls/sha1.h"
+#include "mbedtls/entropy.h"
+#include "mbedtls/ctr_drbg.h"
+
+/* cc api */
+#include "cc_rnd_common.h"
+
+/* CC pal */
+#include "cc_pal_types.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+#if defined(MBEDTLS_RSA_C)
+
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define RUNIT_RSA_4096 0
+
+/************************************************************
+ *
+ * typedefs
+ *
+ ************************************************************/
+typedef struct RunItRsaData_t
+{
+    int mod;
+    const char *name;
+    const char *input_P;
+    const char *input_Q;
+    const char *input_N;
+    const char *input_E;
+    const char *input_D;
+    const char *private_result_hex_str;
+    const char *public_result_hex_str;
+} RunItRsaData_t;
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static const RunItRsaData_t data[] =
+{
+    {
+        2048,
+        "2048",
+        "e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17",
+        "c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89",
+        "b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f",
+        "3",
+        "77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB",
+        "48ce62658d82be10737bd5d3579aed15bc82617e6758ba862eeb12d049d7bacaf2f62fce8bf6e980763d1951f7f0eae3a493df9890d249314b39d00d6ef791de0daebf2c50f46e54aeb63a89113defe85de6dbe77642aae9f2eceb420f3a47a56355396e728917f17876bb829fabcaeef8bf7ef6de2ff9e84e6108ea2e52bbb62b7b288efa0a3835175b8b08fac56f7396eceb1c692d419ecb79d80aef5bc08a75d89de9f2b2d411d881c0e3ffad24c311a19029d210d3d3534f1b626f982ea322b4d1cfba476860ef20d4f672f38c371084b5301b429b747ea051a619e4430e0dac33c12f9ee41ca4d81a4f6da3e495aa8524574bdc60d290dd1f7a62e90a67",
+        "1f5e927c13ff231090b0f18c8c3526428ed0f4a7561457ee5afe4d22d5d9220c34ef5b9a34d0c07f7248a1f3d57f95d10f7936b3063e40660b3a7ca3e73608b013f85a6e778ac7c60d576e9d9c0c5a79ad84ceea74e4722eb3553bdb0c2d7783dac050520cb27ca73478b509873cb0dcbd1d51dd8fccb96c29ad314f36d67cc57835d92d94defa0399feb095fd41b9f0b2be10f6041079ed4290040449f8a79aba50b0a1f8cf83c9fb8772b0686ec1b29cb1814bb06f9c024857db54d395a8da9a2c6f9f53b94bec612a0cb306a3eaa9fc80992e85d9d232e37a50cabe48c9343f039601ff7d95d60025e582aec475d031888310e8ec3833b394a5cf0599101e"
+    },
+    {
+        3072,
+        "3072",
+        "f5b86d4a3aa83ad24b334c7457e6b1ded044093e69fa19ebef2e24df9aca6c55d2a6cb84683667ff9cfd8f4537234c9ba4e5de9ca6833f4fa08a0a0d5516e2606095528c48dfae424f3df0009a749b0ad67cf879a523c3a0fc5c46428be1a7f368165959fbe3b33c122c8d2681260cfb8bc4814404778662ded71c08beec6ada120141efde7fbb92a1ca2e0cffae7ec5cb43a6db42218af06ae14e0eba5b9289aef170837f2bbeb144cedd5cfb27e46d8f2784baeb1c772273e70752db31363b",
+        "c10d3ca1b2711eb97f0a567f476cad607fcbf552cd449f7f0919287ce77ab0c2371034df58133416dc4ef21d490a82d0dbf0897b363bb01e3a7f5d223020e5d9368baa685cb17f395625bab672722abafc20985e95f952282868894085bdfcde13a63f71db21cfbb20d13168c80939602add3a56f653ecb97fcfad4955959da35d8e3621f89639953d4c569c146c00c3e452523d931fe75424b39c4a1bcd6c572d7d334f30b7fc7fa736ab1579381eeafc2c46ca8cc3330fe55a3514193b85a7",
+        "b94cbef4f0dec0355c88bb3e6ab31dfb8c9c1176fa16d95519c6f8a663b8116235435c02a5a9b76591c380cae0ea7f9e381052a7d34dddc4f234f45db969d7900fce21d5bbc6bb300289ce595ffd1b0d85d749a717a326fee838f0eab063f1db8b7a21e187f41a9e826ea67c2f870c568c563b086c1c17c9221b7e59b268a989023d39508efa07e40d99aa003378307c535156ad5235265b89bae1c6182b8beceb0504855fdfa0c80e967f49484d21a2656d848a4f88224cdb5589cbb871a7f165914e37c34e1a9957cee1366b1ff8ec7900ec559c0cf4fffc5b3f473b509aa3a9084858adaa848262fd8158ce8bedd5a0a9f09631f993cf7b25178186d67e85ac7c42d1b206ef02d8f8ec75575253e4fff2caf74740d929316d3a6982c38eeb4c815188fd822697462aa327daaf0b021f3b86c3c8d4d927e13737991ea4623efc95c04f90ddf5bb5554a16fc64d540beb64599ad4a8d4e7ae58ac452eeaec5697f61d5951bbf82f7c1e9a8a7f1a7af23e3c3ef4c81ea0c591d4992cd0e0077d",
+        "10001",
+        "2DC97AFE076EE34BCC3BB518ED40A94DF926AF6218D60089F8BEA3BE69B1980A0E63409F1ED45B0EEBFFC5195C8E554E8147F744A4FFFEA6A5BAD40F3CBB9C9A6A6D630AEF456207B0F8E0565153B79595D6E6CA351B098DBF5022A7BB4257070AE5F8ED43ACDBCF0327D857A35ED97BA15DC564856243B65D8931A574624C52208D8456159E4EC8D95B7918679F714BA742D80A27E01E444C3A3383C18131282FC2A3A5595566E3484783D855D749525981C05874E28CA7352363D34516408B074426AADE995682C4D278F2046DE0235B947D0C246499706EFB86B19B5BED7FCCB446F58C9A7F93FAC0D3DEC6EA96D51F1A24062385440D2384F402AF87CA3FEE9F091A5FF3D1085984AE24193B8E78C1B8E78DB87035DCCC03E9B65B8AA6540EB42D79FFC298A3FB59027B78A87BAD2AF7A5ADC58BA8FD7B1BB944308AE066E5340231CE704F4420D9A43EACD5C6910FBA253ABA238FCA02D6185B106B8B03A67D09586D318390DB8676641E72890F1F9834BDF2B43C3590AB4927531BE239",
+        "9f351ced000825b86f53020dce5712f0865b023ffc981b26c5c308ca64aaabbf50b66198cc95e6411a602d62af45daec586184308c99cf05af66451ffb76c025d5305539cf2b600d42cac6b1669955b2436738d87c8b78e6d57c3217752fff86c269a14645b62e110f5f04f4675ca06d2575276da5a6d884052a19decd4a002300a201184cb256c02e895a32c5b0e59c9c0ecf7af9aa64aeaa48f83f9b729ff2ab3f21846c42ec9748fa18e49d297c59f7acc0deb3718b4c820a6cbb090b946f4d32f7ed47ec0f2e8b883c718a651ab3916173af7b0a8ae718617c9b6cb4ac4e9c47dbebc71f7737551d23d6a69eca1aeb9d54214e65fa992f4871d99674dc95ab374c42414dea78284e3c9ff5e9384c873a5f4f9440a6eb8423f80aeeed9a96c57f2db523f16f8a2b82c092d92bf0fb2140d26e2c4f18f91bcf2d1fd8db593d53ae67f5b8efad2a0543cf5aca71b738ca100d2ff52ee5483e4e423b5b1064d58375635ffad4d195cdbe7755c246304dcbe897fba1e318b7b12b28866de496e4",
+        "a18ea22a5c6b4d09b5ec2a3fbce5e63a871a831375e8a26c8befdb98bde625d66c44e4938127d1bfdd624000eca308e218d518d2b26df415ab44252d81d6f92602a7e00437e55399e8f434b055c35321b33df6e6bf15bcbea456f5cda48f3de9f429f7254140fc006ade528ae302c077f69f783dfa1269905d3808976322386d6479e0d6811bf629e33f21e9e54aae85fbf521360bae30c00c6eadd2b1771809e0ecc693d6f9ce94b826b7e71fa59a005e7824d085ab0e21831c1676afaa83150cc52a315b422ad28f5bb9a4efeb0d18c48d0ae5ca76b3ad75e51138005db530c2b253089f3d8e7e7c5c39cc59746db8c284e9cebb672a47e3802873912c44d6e307b449bac83e17f97a5be9c0b4d9830a734a4f7b88995c6e674fdff93e7d6bf7fd79d6c5ddbe28a787520e6d8027c0c771c2dcd487444091da5478758db52ea66ef35c11e944601fea643732a55578a1367426d4268c728355a2c5000aad23e341669e08abf7516cd67a7fe48127a9c823ac6c1a75f722cbca51a45c0d8516"
+    },
+    {
+        4096,
+        "4096",
+        "d8d78135a5456957e4970b3b6bea0350ba05ec296734a211c4aa7177ecb7f78e58f40213d68c2184ed11688bdc0e3acc3f97b3fec287ca9d79714d39014c5e5d5cbdd540d88cfa72b4a06b404e083b6c08c554fa91dff7c690e72999da594ab2ed373e92f0353e398adfa2de2d6ab72f3dd82d7bdcdff698ba2e2ba6800ba6cdab2124a3b06b3699eec1a0c636bfdc4ae42c598738b0cc394a5c17c2ced0ee0b0cf9ca82e38a46f8448003523305254b1fecbba2efd94811cf2de6d0b9ff9d0bf8f2b468ad92f01384e746b3d41ddd9842629e9e344405573c026d1325652bac954679e6216aea8b52c7e19018d23317b8242cc3acbb31efe408b3ef437f1b87",
+        "c78c3d0da2b1cbaeb8ebafaa7cd75910daf0bd408ef0875ae5221b3227707f8d02a596b71d136cbfb457c208f17352d2d18bd2bbfe8107684f3f2fea3076926a10661406a942268beea32376c845212a3a8530b70f993f6526859093156ca098f2319998d4c17ca4cbad245123728c08d12315b50f8694cbd74ee9b49ab642fb87232d8bc95145be4e136ee9ce4b5955964ab9e8257a4cc19f394bd58229023052c0d73763892ea0c6f29bfff9b341ec3cc17890388d7e5b182356607ac2bb358f058ee5b64663397df9ce3fe9eeb21dfaea85b8a59fbf42e2f524ddbab34a146c40327c3a12bbff65e79465ae67eae4aa6145be50c561796d35b36b27916827",
+        "a9064f024359a83f08a1cceda81473e2176735f4a9a0b2a2403f3e188b73998792a54d182ceb220b8715261a6f4c051548937d528f20203d56ffa85ca09f419f5d89447f0f595a73976e74c2fad651f3b6e93c563fa73da173809b0d9af2ef76702b0ebe516c30455750232982cf23f40fde64a4954142b75460fa0a24c18f88fbfc0f48a1eb75f1a7264c2b50222f89c8636f589250316137369f9b515030582635bdf9aabd28e0ff012810eab9f8fd59c479cdf5a2a555272f3185c052679e2bdbbe69c0b6fad3aa54399622a27a5cd347fee5bd0d820be2bfbf155df589826f039707e322807ade03fe8e7f6cb0d859a8f888547b2aac91535a2861ee25ab3268d2fcf49f8c4fdbdccc4182e68f712ae6e358fb0ed4d1d6020a1a72714b07d8c1f3c0635a3d6ea0096bc5bec63c4c8aa3573c5611a36e52a8c3bfded68f6bbc6d137e74a62fc7f73c13f53aa4a0c1348ca70aefea0309c4f692ac8074d0a77f6bebf79c9521747fe36650670b25432cf1008ecc59d51336e771955fd16390fb9b0326f45f95acb2f7e583c66bac472bb999c6e3589f00d656bd4cb266fb1c59d6aa673e1ab94fc30ce93cbf517af3bf6efa908a9cd8becf8add8d2bd7a10b892150985b5d7b4f9657efc225edf2828a0784bfd4cc91df815293c2aecf4fb99a71604ce31a054f0cf57ce25220da793a2c6005268a4f91e88d1b7c14030991",
+        "10001",
+        "929041da788439fbce845eaa856096cba9f77935da10da550ed8c803888888cca2406c05568ddd4b99aaa10bb30e7c29e470dfeec2e4dc8fd3ec84152dc26aa8c1f6d14a4c08f301e0818b05b7743843d88b8e224bb7bd1d4e8669ecf63b49a1adc9e852e74fa4dbbbc665770d52889e8d540e7918632a72c5dc0174e242653027307e20412767724fba49ba15164f9a6e04aafc6682db0ead4dd4405dd5e6d5c8ec38fb512e0d506c4e986b72de2825a7bd52d160f9d3db6ecae16a55461f4b6c44736c480b629c3fca20d52adb30b7650dbcdd817d4113055fb755d3cfa19954a20c486e8ff0509a4b646433e20fc6ca98564a00d77c3d7f1683cb187fe47091898e5b227826980055215008edd0c4e70313794b0d43edcad3e71d94e419bfab175f280be61915951168f6037fc6e7edbf03121a2537502ab2faa7c8fc86477be8b98e442c6f49ec6247478743947c980efbd3f0cca63aba0a998ca3ecc43d1b17100765c498b804c873dbc0dbb0726b5c37043bb93e5f0e5897f87f01d85b811e86fd517e33eca533b7ae92b40eaea46e47078517e06b2acccdf837b2d2081b584bbd8fc6e0d483886a27d94e9b6a73472dbab3faa710170a411efdb59b146ec5261cc95ff341a8951b4e778d5c9a42be29f35dfe98605dd50452e5a87081bc37682329cc51f07412f4d60febdbed7521ee3a194fb3b48edf541b0be0a071",
+        "77481e96cd01f851426af3e2c2a12cbbf708c7b033a7d2d77e388578023fb1dd9b7b459b95c7b38888d2df4a850ff8cafbf9294c1ba8904e92e8a6e28d63421fa6aa620fd1024119713a26e921f4281ad22e078dd0485c5dc3d047f4ae506b15d922e33e5b6bdb716f0f9d4340435008bacbaa690e536e2d80e7ff87b4f5aa608444f244e03c081b7dd791ad28c34cc381c4f37efb3b2ec46f1107af8c92d50b9cbf524ad2f1e440fafad1b2265942181dfb4c4d8ba710342c50a2818a98135cfdbe2f5d6f2f16d11480d6a80b459ae52a869ba26d06f8e1678e2aa85978b6c8618ebcb820489f9f92021c9d47981450345903657ee1b43bdd8132f4ed29fd2cbcab6a9f2dd9834be44e306c187a8de45d6ce54cfd5d0eb8568d7967f1604d89fdf98e335d2574b65affe0360365603589cb5f5eb15ca75439ee2178d2ac1c08e8f064ba189cd5f394ad0130ed97f2a9a627d1dcb2965f997428cc05f6be2d803629c4d04bbca10c837d7eef216fd0c27441b7942edb42d061e6596e563b2c5bee1649200f057092ecd5a70139812019d5ed6e8bdd2dbdd706e3acece2964f76120b6eb7746e85bd87d67902adf40afdf18da3274a89f444a10d017a40bfb24eaf43ca2eb5a39f807cb4e4f63a91a10ec654ae6152b3192ac7f6fabb1654809076df5f8bd236f5f41c3f214ec3bac1befdafcb55aab2d0026dbe3a6100c29f5e",
+        "3a7d38eb3ff20c0823bc559c142d248e420f88b077cab28ad642be2210b928b23a54d82a2f74b8e8c19168f1749be2841e493aece4753571389997a5d443040e1e4c34f655ed0872596f66679267651641ecf636ce79057c968d5310654ec768940cc0023edb5c10adf4f067c9d7efc87009c6e9e8c3f85708c5a1efc3e1562cd494d7922996ee8d1a83551e35df3062deebe796d246aef5bb52e3b9c19fa692cbeaa4605b6608b483228bff9670738fddd9a9ca67887283ae9a7926de6b695d016c713f9bd01a0b119a04280385a8f175d17738b8cbfc51cc46bc4760bc38dcfa073f0a1e7ab25a5f59af809fc0c89a6f2e4da90d3fb73a4a133d795cfa2e5440f3054d7640b3dd3f9d65168cd5ef3849f4fe53c26d220ec7619f2e35c144f4d53297e5e2af8b0a8dfd0d15d77f2e6067e100d90c3b0afdab37b6747b0c8f56dcc05b6706f4ed8ceb76286d05a6f7878b26269693ddf02f980e95f7f80a8780c1b676a562dab69f85cf83839ca09da9e83da19879e3ad9dcbb15846b071b259dfc8c88e317e46d62f0f1b45d36240c2dc970a0be128562ee9127fed1961530ba46168fd6019eefe8ec0c3f288af0a7a218b0db621d61f02d2540fb51f0840a9fda5a6407669cda41586cb105f2e2649068b14d997101212779295a03657f4ff14dae0eac339f1fcd5633e96708b1bff0c24619fa398fd8973792ad969f3e67f"
+    },
+    {
+        0,
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+    }
+
+};
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_rsaPublic(void);
+static RunItError_t runIt_rsaPublicGeneral(const RunItRsaData_t *pData);
+static RunItError_t runIt_rsaPrivate(void);
+static RunItError_t runIt_rsaPrivateGeneral(const RunItRsaData_t *pData);
+static RunItError_t runIt_rsaCheckPubpriv(void);
+static RunItError_t runIt_rsaCheckPrivkey(void);
+static RunItError_t runIt_rsaGenKey(void);
+static RunItError_t runIt_rsaPkcsV21Test(void);
+static RunItError_t runIt_rsaPkcsV21TestGeneral(const RunItRsaData_t *pData);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+RunItError_t runIt_buildPrivateKey(mbedtls_rsa_context* ctx)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    mbedtls_mpi p1, q1, h, g;
+
+    mbedtls_mpi_init(&p1);
+    mbedtls_mpi_init(&q1);
+    mbedtls_mpi_init(&h);
+    mbedtls_mpi_init(&g);
+
+    RUNIT_ASSERT(mbedtls_mpi_sub_int(&p1, &ctx->P, 1) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_sub_int(&q1, &ctx->Q, 1) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_mul_mpi(&h, &p1, &q1) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_gcd(&g, &ctx->E, &h) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_inv_mod(&ctx->D, &ctx->E, &h) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_mod_mpi(&ctx->DP, &ctx->D, &p1) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_mod_mpi(&ctx->DQ, &ctx->D, &q1) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_inv_mod(&ctx->QP, &ctx->Q, &ctx->P) == 0);
+
+bail:
+    mbedtls_mpi_free(&p1);
+    mbedtls_mpi_free(&q1);
+    mbedtls_mpi_free(&h);
+    mbedtls_mpi_free(&g);
+
+    return rc;
+}
+
+static RunItError_t runIt_rsaPublic(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    const RunItRsaData_t *iter = data;
+    while (iter->mod != 0)
+    {
+        RUNIT_ASSERT(runIt_rsaPublicGeneral(iter) == RUNIT_ERROR__OK);
+        iter++;
+    }
+
+bail:
+    return rc;
+}
+
+
+static RunItError_t runIt_rsaPublicGeneral(const RunItRsaData_t *pData)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    static const uint32_t BUF_SIZE = 2048;
+
+    static const char *MESSAGE_HEX_STRING = "59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870";
+    int mod = pData->mod;
+    const char *name = pData->name;
+    const char *input_N = pData->input_N;
+    const char *input_E = pData->input_E;
+    const char *result_hex_str = pData->public_result_hex_str;
+
+    uint8_t *pMessageStr = NULL;
+    uint8_t *pOutput = NULL;
+    uint8_t *pOutputStr = NULL;
+    mbedtls_rsa_context *pCtx = NULL;
+    mbedtls_rsa_context *pCtx2 = NULL;
+
+    RunItPtr messageStrPtr;
+    RunItPtr outputPtr;
+    RunItPtr outputStrPtr;
+    RunItPtr ctxPtr;
+    RunItPtr ctx2Ptr;
+
+    mbedtls_mpi n;
+    mbedtls_mpi e;
+
+    const char* TEST_NAME = "RSA Public";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(messageStrPtr, pMessageStr, BUF_SIZE);
+    ALLOC(outputPtr, pOutput, BUF_SIZE);
+    ALLOC(outputStrPtr, pOutputStr, BUF_SIZE);
+    ALLOC_STRUCT(mbedtls_rsa_context, ctxPtr, pCtx);
+    ALLOC_STRUCT(mbedtls_rsa_context, ctx2Ptr, pCtx2);
+
+    RUNIT_API(mbedtls_rsa_init(pCtx, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+    RUNIT_API(mbedtls_rsa_init(pCtx2, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+
+    memset(pMessageStr, 0, BUF_SIZE);
+    memset(pOutput, 0, BUF_SIZE);
+    memset(pOutputStr, 0, BUF_SIZE);
+
+    mbedtls_mpi_init(&n);
+    mbedtls_mpi_init(&e);
+
+    pCtx->len = mod / 8;
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&n, 16, input_N) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&e, 16, input_E) == 0);
+
+    RUNIT_ASSERT(mbedtls_rsa_import(pCtx, &n, NULL, NULL, NULL, &e) == 0);
+
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_check_pubkey(pCtx) == 0);
+
+    runIt_unhexify(pMessageStr, MESSAGE_HEX_STRING);
+
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_public(pCtx, pMessageStr, pOutput) == 0);
+
+    runIt_hexify(pOutputStr, pOutput, pCtx->len);
+
+    RUNIT_ASSERT(strcasecmp((char *) pOutputStr, result_hex_str) == 0);
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_copy(pCtx2, pCtx) == 0);
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_check_pubkey(pCtx2) == 0);
+
+    memset(pOutput, 0x00, BUF_SIZE);
+    memset(pOutputStr, 0x00, BUF_SIZE);
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_public(pCtx2, pMessageStr, pOutput) == 0);
+
+    runIt_hexify(pOutputStr, pOutput, pCtx2->len);
+
+    RUNIT_ASSERT(strcasecmp((char *) pOutputStr, result_hex_str) == 0);
+bail:
+    RUNIT_API(mbedtls_rsa_free(pCtx));
+    RUNIT_API(mbedtls_rsa_free(pCtx2));
+
+    FREE_IF_NOT_NULL(messageStrPtr);
+    FREE_IF_NOT_NULL(outputPtr);
+    FREE_IF_NOT_NULL(outputStrPtr);
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(ctx2Ptr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] INPUT[%"PRIu32"B]",
+                                   (uint32_t)mod, (uint32_t)strlen(MESSAGE_HEX_STRING));
+    return rc;
+}
+
+static RunItError_t runIt_rsaPrivate(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    const RunItRsaData_t *iter = data;
+    while (iter->mod != 0)
+    {
+        RUNIT_ASSERT(runIt_rsaPrivateGeneral(iter) == RUNIT_ERROR__OK);
+        iter++;
+    }
+
+bail:
+    return rc;
+}
+
+static RunItError_t runIt_rsaPrivateGeneral(const RunItRsaData_t *pData)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    static const uint32_t BUF_SIZE = 2048;
+
+    static const char *message_hex_string = "59779fd2a39e56640c4fc1e67b60aeffcecd78aed7ad2bdfa464e93d04198d48466b8da7445f25bfa19db2844edd5c8f539cf772cc132b483169d390db28a43bc4ee0f038f6568ffc87447746cb72fefac2d6d90ee3143a915ac4688028805905a68eb8f8a96674b093c495eddd8704461eaa2b345efbb2ad6930acd8023f870";
+    int mod = pData->mod;
+    const char *name = pData->name;
+    const char *input_P = pData->input_P;
+    const char *input_Q = pData->input_Q;
+    const char *input_N = pData->input_N;
+    const char *input_E = pData->input_E;
+    const char *result_hex_str = pData->private_result_hex_str;
+
+    uint8_t *pMessageStr = NULL;
+    uint8_t *pOutput = NULL;
+    uint8_t *pOutputStr = NULL;
+    mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
+    mbedtls_rsa_context *pCtx = NULL;
+    mbedtls_rsa_context *pCtx2 = NULL;
+
+    RunItPtr messageStrPtr;
+    RunItPtr outputPtr;
+    RunItPtr outputStrPtr;
+    RunItPtr ctxPtr;
+    RunItPtr ctx2Ptr;
+    int i;
+
+    mbedtls_mpi p;
+    mbedtls_mpi q;
+    mbedtls_mpi n;
+    mbedtls_mpi e;
+
+    const char* TEST_NAME = "RSA Private";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC(messageStrPtr, pMessageStr, BUF_SIZE);
+    ALLOC(outputPtr, pOutput, BUF_SIZE);
+    ALLOC(outputStrPtr, pOutputStr, BUF_SIZE);
+    ALLOC_STRUCT(mbedtls_rsa_context, ctxPtr, pCtx);
+    ALLOC_STRUCT(mbedtls_rsa_context, ctx2Ptr, pCtx2);
+
+    mbedtls_mpi_init(&p);
+    mbedtls_mpi_init(&q);
+    mbedtls_mpi_init(&n);
+    mbedtls_mpi_init(&e);
+
+    RUNIT_API(mbedtls_rsa_init(pCtx, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+    RUNIT_API(mbedtls_rsa_init(pCtx2, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+
+    memset(pMessageStr, 0x00, 1000);
+
+    pCtx->len = mod / 8;
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&p, 16, input_P) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&q, 16, input_Q) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&n, 16, input_N) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&e, 16, input_E) == 0);
+
+    RUNIT_ASSERT(mbedtls_rsa_import(pCtx, &n, &p, &q, NULL, &e) == 0);
+
+    RUNIT_ASSERT(runIt_buildPrivateKey(pCtx) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_check_privkey(pCtx) == 0);
+
+    runIt_unhexify(pMessageStr, message_hex_string);
+
+    /* repeat three times to test updating of blinding values */
+    for (i = 0; i < 3; i++)
+    {
+        memset(pOutput, 0x00, BUF_SIZE);
+        memset(pOutputStr, 0x00, BUF_SIZE);
+
+        RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_private(pCtx, mbedtls_ctr_drbg_random, pCtrDrbg, pMessageStr, pOutput) == 0);
+
+        RUNIT_PRINT_BUF(pOutput, pCtx->len, "pOutput");
+
+        runIt_hexify(pOutputStr, pOutput, pCtx->len);
+
+        RUNIT_ASSERT(strcasecmp((char *) pOutputStr, result_hex_str) == 0);
+    }
+
+    /* And now one more time with the copy */
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_copy(pCtx2, pCtx) == 0);
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_check_privkey(pCtx2) == 0);
+
+    memset(pOutput, 0x00, BUF_SIZE);
+    memset(pOutputStr, 0x00, BUF_SIZE);
+
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_private(pCtx2, mbedtls_ctr_drbg_random, pCtrDrbg, pMessageStr, pOutput) == 0);
+
+    runIt_hexify(pOutputStr, pOutput, pCtx2->len);
+
+    RUNIT_ASSERT(strcasecmp((char *) pOutputStr, result_hex_str) == 0);
+
+bail:
+    RUNIT_API(mbedtls_rsa_free(pCtx));
+    RUNIT_API(mbedtls_rsa_free(pCtx2));
+
+    FREE_IF_NOT_NULL(messageStrPtr);
+    FREE_IF_NOT_NULL(outputPtr);
+    FREE_IF_NOT_NULL(outputStrPtr);
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(ctx2Ptr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] INPUT[%"PRIu32"B]",
+                                   (uint32_t)mod, (uint32_t)strlen(message_hex_string));
+    return rc;
+}
+
+static RunItError_t runIt_rsaCheckPubpriv(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    static const int mod = 2048;
+    static const int radix_Npub = 16;
+    static const char *input_Npub = "b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f";
+    static const int radix_Epub = 16;
+    static const char *input_Epub = "3";
+    static const int radix_P = 16;
+    static const char *input_P = "e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17";
+    static const int radix_Q = 16;
+    static const char *input_Q = "c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89";
+    static const int radix_N = 16;
+    static const char *input_N = "b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f";
+    static const int radix_E = 16;
+    static const char *input_E = "3";
+    static const int radix_D = 16;
+    static const char *input_D = "77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB";
+
+    mbedtls_rsa_context *pPub = NULL;
+    mbedtls_rsa_context *pPrv = NULL;
+
+    RunItPtr pubPtr;
+    RunItPtr prvPtr;
+
+    mbedtls_mpi pub_n;
+    mbedtls_mpi pub_e;
+
+    mbedtls_mpi priv_p;
+    mbedtls_mpi priv_q;
+    mbedtls_mpi priv_n;
+    mbedtls_mpi priv_e;
+    mbedtls_mpi priv_d;
+
+    const char* TEST_NAME = "RSA Check Public Private";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_rsa_context, pubPtr, pPub);
+    ALLOC_STRUCT(mbedtls_rsa_context, prvPtr, pPrv);
+
+    RUNIT_API(mbedtls_rsa_init( pPub, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+    RUNIT_API(mbedtls_rsa_init( pPrv, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+
+    pPub->len = mod / 8;
+    pPrv->len = mod / 8;
+
+    mbedtls_mpi_init(&pub_n);
+    mbedtls_mpi_init(&pub_e);
+    mbedtls_mpi_init(&priv_p);
+    mbedtls_mpi_init(&priv_q);
+    mbedtls_mpi_init(&priv_n);
+    mbedtls_mpi_init(&priv_e);
+    mbedtls_mpi_init(&priv_d);
+
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&pub_n, radix_Npub, input_Npub) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&pub_e, radix_Epub, input_Epub) == 0);
+    RUNIT_ASSERT(mbedtls_rsa_import(pPub, &pub_n,  NULL, NULL, NULL, &pub_e) == 0);
+
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&priv_p, radix_P, input_P) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&priv_q, radix_Q, input_Q) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&priv_n, radix_N, input_N) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&priv_e, radix_E, input_E) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&priv_d, radix_D, input_D) == 0);
+    RUNIT_ASSERT(mbedtls_rsa_import(pPrv, &priv_n,  &priv_p, &priv_q, &priv_d, &priv_e) == 0);
+    RUNIT_ASSERT(mbedtls_rsa_complete(pPrv) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_rsa_check_pub_priv(pPub, pPrv) == 0);
+
+bail:
+    RUNIT_API(mbedtls_rsa_free(pPub));
+    RUNIT_API(mbedtls_rsa_free(pPrv));
+
+    FREE_IF_NOT_NULL(pubPtr);
+    FREE_IF_NOT_NULL(prvPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b]", (uint32_t)mod);
+    return (rc);
+}
+
+static RunItError_t runIt_rsaCheckPrivkey(void)
+{
+    static const int mod = 2048;
+    static const int radix_P = 16;
+    static const char *input_P = "e79a373182bfaa722eb035f772ad2a9464bd842de59432c18bbab3a7dfeae318c9b915ee487861ab665a40bd6cda560152578e8579016c929df99fea05b4d64efca1d543850bc8164b40d71ed7f3fa4105df0fb9b9ad2a18ce182c8a4f4f975bea9aa0b9a1438a27a28e97ac8330ef37383414d1bd64607d6979ac050424fd17";
+    static const int radix_Q = 16;
+    static const char *input_Q = "c6749cbb0db8c5a177672d4728a8b22392b2fc4d3b8361d5c0d5055a1b4e46d821f757c24eef2a51c561941b93b3ace7340074c058c9bb48e7e7414f42c41da4cccb5c2ba91deb30c586b7fb18af12a52995592ad139d3be429add6547e044becedaf31fa3b39421e24ee034fbf367d11f6b8f88ee483d163b431e1654ad3e89";
+    static const int radix_N = 16;
+    static const char *input_N = "b38ac65c8141f7f5c96e14470e851936a67bf94cc6821a39ac12c05f7c0b06d9e6ddba2224703b02e25f31452f9c4a8417b62675fdc6df46b94813bc7b9769a892c482b830bfe0ad42e46668ace68903617faf6681f4babf1cc8e4b0420d3c7f61dc45434c6b54e2c3ee0fc07908509d79c9826e673bf8363255adb0add2401039a7bcd1b4ecf0fbe6ec8369d2da486eec59559dd1d54c9b24190965eafbdab203b35255765261cd0909acf93c3b8b8428cbb448de4715d1b813d0c94829c229543d391ce0adab5351f97a3810c1f73d7b1458b97daed4209c50e16d064d2d5bfda8c23893d755222793146d0a78c3d64f35549141486c3b0961a7b4c1a2034f";
+    static const int radix_E = 16;
+    static const char *input_E = "3";
+    static const int radix_D = 16;
+    static const char *input_D = "77B1D99300D6A54E864962DA09AE10CF19A7FB888456BC2672B72AEA52B204914493D16C184AD201EC3F762E1FBD8702BA796EF953D9EA2F26300D285264F11B0C8301D0207FEB1E2C984445C899B0ACEBAA74EF014DD1D4BDDB43202C08D2FF9692D8D788478DEC829EB52AFB5AE068FBDBAC499A27FACECC391E75C936D55F07BB45EE184DAB45808E15722502F279F89B38C1CB292557E5063597F52C75D61001EDC33F4739353E33E56AD273B067C1A2760208529EA421774A5FFFCB3423B1E0051E7702A55D80CBF2141569F18F87BFF538A1DA8EDBB2693A539F68E0D62D77743F89EACF3B1723BDB25CE2F333FA63CACF0E67DF1A431893BB9B352FCB";
+
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    mbedtls_rsa_context *pCtx = NULL;
+
+    RunItPtr ctxPtr;
+
+    mbedtls_mpi p;
+    mbedtls_mpi q;
+    mbedtls_mpi n;
+    mbedtls_mpi e;
+    mbedtls_mpi d;
+
+    const char* TEST_NAME = "RSA Check Private";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_rsa_context, ctxPtr, pCtx);
+
+    RUNIT_API(mbedtls_rsa_init(pCtx, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+
+    mbedtls_mpi_init(&p);
+    mbedtls_mpi_init(&q);
+    mbedtls_mpi_init(&n);
+    mbedtls_mpi_init(&e);
+    mbedtls_mpi_init(&d);
+
+    pCtx->len = mod / 8;
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&p, radix_P, input_P) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&q, radix_Q, input_Q) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&n, radix_N, input_N) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&e, radix_E, input_E) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&d, radix_D, input_D) == 0);
+    RUNIT_ASSERT(mbedtls_rsa_import(pCtx, &n, &p, &q, &d, &e) == 0);
+    RUNIT_ASSERT(mbedtls_rsa_complete(pCtx) == 0);
+
+    RUNIT_ASSERT_API(mbedtls_rsa_check_privkey(pCtx) == 0);
+
+bail:
+    RUNIT_API(mbedtls_rsa_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b]", (uint32_t)mod);
+    return (rc);
+
+}
+
+static RunItError_t runIt_rsaGenKey(void)
+{
+    const int nrbits = 2048;
+    const int exponent = 3;
+
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    mbedtls_rsa_context *pCtx = NULL;
+
+    RunItPtr ctxPtr;
+
+    const char* TEST_NAME = "RSA Gen Key";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_rsa_context, ctxPtr, pCtx);
+
+    RUNIT_API(mbedtls_rsa_init(pCtx, MBEDTLS_RSA_PKCS_V15, MBEDTLS_MD_NONE));
+
+    RUNIT_ASSERT_API(mbedtls_rsa_gen_key(pCtx, gpRndContext->rndGenerateVectFunc, gpRndState, nrbits, exponent) == 0);
+    RUNIT_ASSERT_API(mbedtls_rsa_check_privkey(pCtx) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_cmp_mpi(&pCtx->P, &pCtx->Q) > 0);
+
+bail:
+    RUNIT_API(mbedtls_rsa_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+    return (rc);
+}
+
+
+static RunItError_t runIt_rsaPkcsV21Test(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    const RunItRsaData_t *iter = data;
+    while (iter->mod != 0)
+    {
+        RUNIT_ASSERT(runIt_rsaPkcsV21TestGeneral(iter) == RUNIT_ERROR__OK);
+        iter++;
+    }
+
+bail:
+    return rc;
+}
+
+static RunItError_t runIt_rsaPkcsV21TestGeneral(const RunItRsaData_t *pData)
+{
+    const uint32_t KEY_LEN = pData->mod;
+    const char * RSA_P = pData->input_P;
+    const char * RSA_Q = pData->input_Q;
+    const char * RSA_N = pData->input_N;
+    const char * RSA_E = pData->input_E;
+    const char * RSA_D = pData->input_D;
+    const char *name = pData->name;
+
+    static const uint32_t PT_LEN = 40;
+    static const char * RSA_PT = "385387514deccc7c740dd8cdf9daee49a1cbfd54";
+
+    const char* TEST_NAME = "OAEP: RSAES + RSASSA";
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+
+#if defined(MBEDTLS_PKCS1_V21)
+    mbedtls_ctr_drbg_context *pCtrDrbg = (mbedtls_ctr_drbg_context *)gpRndState;
+    mbedtls_rsa_context *pCtx = NULL;
+    unsigned char *pRsaPlaintext = NULL;
+    unsigned char *pRsaDecrypted = NULL;
+    unsigned char *pRsaCiphertext = NULL;
+
+    RunItPtr ctxPtr;
+    RunItPtr rsaPlaintextPtr;
+    RunItPtr rsaDecryptedPtr;
+    RunItPtr rsaCiphertextPtr;
+
+    size_t len;
+
+    mbedtls_mpi p;
+    mbedtls_mpi q;
+    mbedtls_mpi n;
+    mbedtls_mpi e;
+    mbedtls_mpi d;
+
+#if defined(MBEDTLS_SHA1_C)
+    unsigned char *pSha1Sum = NULL;
+
+    RunItPtr sha1SumPtr;
+#endif
+
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_rsa_context, ctxPtr, pCtx);
+    ALLOC(rsaPlaintextPtr, pRsaPlaintext, PT_LEN);
+    ALLOC(rsaDecryptedPtr, pRsaDecrypted, PT_LEN);
+    ALLOC(rsaCiphertextPtr, pRsaCiphertext, KEY_LEN / 8);
+#if defined(MBEDTLS_SHA1_C)
+    ALLOC(sha1SumPtr, pSha1Sum, 20);
+#endif
+
+    RUNIT_API(mbedtls_rsa_init(pCtx, MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA1));
+
+    mbedtls_mpi_init(&p);
+    mbedtls_mpi_init(&q);
+    mbedtls_mpi_init(&n);
+    mbedtls_mpi_init(&e);
+    mbedtls_mpi_init(&d);
+
+    pCtx->len = KEY_LEN / 8;
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&p, 16, RSA_P) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&q, 16, RSA_Q) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&n, 16, RSA_N) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&e, 16, RSA_E) == 0);
+    RUNIT_ASSERT(mbedtls_mpi_read_string(&d, 16, RSA_D) == 0);
+
+    RUNIT_ASSERT(mbedtls_rsa_import(pCtx, &n, &p, &q, &d, &e) == 0);
+    RUNIT_ASSERT(mbedtls_rsa_complete(pCtx) == 0);
+
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_check_pubkey(pCtx) == 0);
+
+    len = runIt_unhexify(pRsaPlaintext, RSA_PT);
+
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_pkcs1_encrypt(pCtx, mbedtls_ctr_drbg_random, pCtrDrbg, MBEDTLS_RSA_PUBLIC, len, pRsaPlaintext, pRsaCiphertext) == 0);
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_pkcs1_decrypt(pCtx, mbedtls_ctr_drbg_random, pCtrDrbg, MBEDTLS_RSA_PRIVATE, &len, pRsaCiphertext, pRsaDecrypted, PT_LEN) == 0);
+
+    RUNIT_PRINT_BUF(pRsaPlaintext, len, "rsa_plaintext");
+    RUNIT_PRINT_BUF(pRsaDecrypted, len, "rsa_decrypted");
+
+    RUNIT_ASSERT(memcmp(pRsaDecrypted, pRsaPlaintext, len) == 0);
+
+#if defined(MBEDTLS_SHA1_C)
+    RUNIT_API(mbedtls_sha1(pRsaPlaintext, PT_LEN, pSha1Sum));
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_pkcs1_sign(pCtx, mbedtls_ctr_drbg_random, pCtrDrbg, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0, pSha1Sum, pRsaCiphertext) == 0);
+    RUNIT_ASSERT_W_PARAM(name, mbedtls_rsa_pkcs1_verify(pCtx, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, pSha1Sum, pRsaCiphertext) == 0);
+#endif /* MBEDTLS_SHA1_C */
+
+#else /* MBEDTLS_PKCS1_V21 */
+    RUNIT_PRINT_DBG("Test not implemented\n");
+#endif /* MBEDTLS_PKCS1_V21 */
+
+bail:
+#if defined(MBEDTLS_PKCS1_V21)
+    RUNIT_API(mbedtls_rsa_free(pCtx));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(rsaPlaintextPtr);
+    FREE_IF_NOT_NULL(rsaDecryptedPtr);
+    FREE_IF_NOT_NULL(rsaCiphertextPtr);
+#if defined(MBEDTLS_SHA1_C)
+    FREE_IF_NOT_NULL(sha1SumPtr);
+#endif /* defined(MBEDTLS_SHA1_C) */
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "KEY[%"PRIu32"b] PLAIN[%"PRIu32"B]",
+                                   (uint32_t)KEY_LEN, (uint32_t)PT_LEN);
+#endif /* defined(MBEDTLS_PKCS1_V21) */
+    return (rc);
+}
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_rsaTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "RSA";
+    RUNIT_TEST_START(TEST_NAME);
+
+    /* to suppress compiler warning when commenting out some of the test below */
+    (void)runIt_rsaPublic;
+    (void)runIt_rsaPrivate;
+    (void)runIt_rsaCheckPubpriv;
+    (void)runIt_rsaCheckPrivkey;
+    (void)runIt_rsaPkcsV21Test;
+    (void)runIt_rsaGenKey;
+
+    RUNIT_ASSERT(runIt_rsaPublic() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_rsaPrivate() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_rsaCheckPubpriv() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_rsaCheckPrivkey() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_rsaPkcsV21Test() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_rsaGenKey() == RUNIT_ERROR__OK);
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return (rc);
+}
+
+#endif /* MBEDTLS_RSA_C */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_secure_boot.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_secure_boot.c
new file mode 100644
index 0000000..1e79f90
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_secure_boot.c
@@ -0,0 +1,659 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/ccm.h"
+#include "mbedtls/cipher.h"
+#include "mbedtls/timing.h"
+
+#include "mbedtls_cc_mng.h"
+#include "mbedtls_cc_sbrt.h"
+#include "secureboot_defs.h"
+#include "bootimagesverifier_def.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+#include "run_integration_flash.h"
+#include "run_integration_otp.h"
+
+#ifdef RUNIT_PIE_ENABLED
+/* include sbrom data file to determine whether we are running system flows */
+#include "bsv_integration_data_def.h"
+#endif /* RUNIT_PIE_ENABLED */
+
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define RUNIT_FLASH_SIZE            0x7000
+#define RUNIT_MAX_CHAIN_LENGTH      3
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x)    (uint32_t)(sizeof(x)/sizeof(x[0]))
+#endif
+
+#ifndef RUNIT_SECURE_BOOT_SKIP_TEST
+#define RUNIT_SECURE_BOOT_SKIP_TEST 0
+#endif
+
+#define RUNIT_SECURE_BOOT__KEY_PKG_1_FLASH_ADDRESS          0x00000000UL
+#define RUNIT_SECURE_BOOT__KEY_PKG_2_FLASH_ADDRESS          0x00001000UL
+#define RUNIT_SECURE_BOOT__CONTENT_PKG_1_FLASH_ADDRESS      0x00002000UL
+#define RUNIT_SECURE_BOOT__IMAGE_PKG_1_FLASH_ADDRESS        0x00003000UL
+#define RUNIT_SECURE_BOOT__IMAGE_PKG_2_FLASH_ADDRESS        0x00004000UL
+#define RUNIT_SECURE_BOOT__IMAGE_PKG_3_FLASH_ADDRESS        0x00005000UL
+#define RUNIT_SECURE_BOOT__IMAGE_PKG_3_NEW_FLASH_ADDRESS    0x00006000UL
+
+#if defined(CC_SB_X509_CERT_SUPPORTED)
+#define IS_X509 "yes"
+#else
+#define IS_X509 "no"
+#endif
+
+#if ! defined(RUNIT_PIE_ENABLED)
+#if defined(DX_PLAT_ZYNQ7000)
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__LOAD_ADDRESS /* threeChains,loadAndVerify,se,hbk1,encrypted */ 0x2FF00000
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__LOAD_ADDRESS /* threeChains,loadAndVerify,se,hbk1,encrypted */ 0x2FF01000
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__LOAD_ADDRESS /* threeChains,loadAndVerify,se,hbk1,encrypted */ 0x2FF02000
+#elif defined(DX_PLAT_MPS2_PLUS)
+#if defined(CORTEX_M33_FPGA)
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__LOAD_ADDRESS /* default */ 0x38200000
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__LOAD_ADDRESS /* default */ 0x38201000
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__LOAD_ADDRESS /* default */ 0x38202000
+#else
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__LOAD_ADDRESS /* default */ 0x21000000
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__LOAD_ADDRESS /* default */ 0x21001000
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__LOAD_ADDRESS /* default */ 0x21002000
+#endif /* defined(CORTEX_M33_FPGA) */
+#else
+#error not supported
+#endif
+
+#if defined(DX_PLAT_ZYNQ7000)
+#if defined(CC_SB_X509_CERT_SUPPORTED)
+/************************************/
+/*          ZYNQ X509               */
+/************************************/
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA /* extended_example/sb_key1_cert_test_10.bin */ 0x30, 0x82, 0x04, 0x6f, 0x30, 0x82, 0x02, 0xa7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x00, 0xc1, 0x43, 0xcd, 0x6d, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x30, 0x38, 0x34, 0x32, 0x31, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x34, 0x30, 0x33, 0x30, 0x33, 0x31, 0x35, 0x31, 0x30, 0x32, 0x37, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x4b, 0x65, 0x79, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6e, 0x30, 0x6c, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x2e, 0x06, 0x03, 0x64, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x24, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0x5e, 0x6a, 0x73, 0x83, 0x1b, 0xa5, 0x23, 0xae, 0x88, 0x1d, 0xb5, 0x09, 0xc2, 0x50, 0xec, 0xa1, 0x37, 0x35, 0xfd, 0xb3, 0x4b, 0x65, 0x95, 0x32, 0x88, 0xaa, 0x16, 0xc5, 0x28, 0x2c, 0x16, 0x26, 0xf5, 0xf0, 0xce, 0x4e, 0x8a, 0xd0, 0xf5, 0x00, 0x95, 0xa1, 0xeb, 0x60, 0xca, 0x82, 0x08, 0x09, 0x49, 0x7e, 0x52, 0x14, 0x4e, 0xb8, 0x4f, 0x88, 0x0f, 0x6e, 0xbe, 0xf9, 0xe7, 0xee, 0x36, 0x3a, 0x41, 0xe1, 0xb1, 0x53, 0x37, 0x26, 0xa7, 0x98, 0x89, 0x5b, 0x68, 0x1a, 0x78, 0xc9, 0x19, 0x39, 0x95, 0xf5, 0xad, 0xbe, 0xb3, 0x97, 0x51, 0x02, 0xcd, 0xce, 0x69, 0x7e, 0x36, 0x22, 0xfe, 0x49, 0x9a, 0x31, 0xcf, 0xe3, 0xea, 0xdb, 0x0e, 0x95, 0x7d, 0x03, 0x24, 0x15, 0xd0, 0xa3, 0x34, 0x83, 0xa2, 0x0c, 0xa6, 0x98, 0xc0, 0xef, 0x42, 0xe3, 0x47, 0x49, 0x77, 0x03, 0x47, 0xec, 0xa1, 0x5f, 0x91, 0x6f, 0xe0, 0x45, 0x56, 0x6c, 0xb1, 0xfa, 0x25, 0x76, 0x98, 0xf9, 0x8f, 0xbb, 0xa7, 0x84, 0x97, 0x73, 0x39, 0x89, 0x75, 0x2c, 0x85, 0x95, 0xd9, 0xc4, 0x6d, 0x54, 0x0b, 0x98, 0xdb, 0x8a, 0x58, 0x4a, 0xa9, 0x96, 0xb9, 0x60, 0x84, 0x39, 0x39, 0xcf, 0xd9, 0x5c, 0x58, 0xc6, 0x8e, 0xeb, 0x75, 0xb4, 0xfe, 0xb6, 0x6c, 0x33, 0xe5, 0x14, 0xed, 0x11, 0xe2, 0xe1, 0xcb, 0x14, 0x21, 0x59, 0xa8, 0x24, 0xf1, 0x71, 0x1f, 0x98, 0xb5, 0xdf, 0x88, 0x30, 0x35, 0x46, 0x50, 0xde, 0xb0, 0x91, 0xd2, 0x3d, 0x1d, 0x95, 0xf2, 0x6f, 0x5b, 0x04, 0x10, 0xa1, 0x92, 0x92, 0x9d, 0xb4, 0x52, 0xa2, 0x7b, 0xaa, 0x91, 0xc4, 0x9d, 0xb3, 0x75, 0x71, 0xb1, 0x34, 0x2e, 0x4d, 0x06, 0x5d, 0x1f, 0x0d, 0x3f, 0xf1, 0xf8, 0x8d, 0xf7, 0x37, 0x82, 0x43, 0xfa, 0xe8, 0x0a, 0xa3, 0x4e, 0xca, 0x94, 0x77, 0x6d, 0x9f, 0x8b, 0xe5, 0x0c, 0xb5, 0x19, 0x75, 0x7d, 0xac, 0x22, 0x89, 0x1b, 0x22, 0x73, 0xe5, 0xe0, 0xd3, 0x14, 0x92, 0x72, 0xd3, 0x1c, 0xda, 0xf5, 0xd7, 0x7a, 0xb5, 0xfc, 0xe7, 0x6f, 0x28, 0x59, 0x15, 0xd7, 0xab, 0xb2, 0xa4, 0xfb, 0xf8, 0x7e, 0x4d, 0x33, 0x5d, 0x86, 0xc9, 0xba, 0xd2, 0x84, 0x5c, 0x5b, 0x4e, 0xc2, 0x3f, 0xe8, 0xeb, 0x91, 0x21, 0x62, 0xf1, 0xa8, 0xb5, 0xbb, 0x7c, 0xae, 0x37, 0x8f, 0x80, 0xb9, 0x97, 0x28, 0x1a, 0x2d, 0x4d, 0x5c, 0x8e, 0x18, 0x80, 0x64, 0x4b, 0x1c, 0x75, 0x7b, 0x45, 0xd2, 0x13, 0x92, 0x66, 0x22, 0x59, 0x99, 0x6f, 0xc2, 0x5d, 0x62, 0x9f, 0xab, 0xd2, 0xa5, 0xce, 0x7f, 0xa1, 0xbc, 0x92, 0x69, 0x7b, 0x2d, 0x8a, 0xa6, 0x5c, 0x18, 0xc5, 0xcd, 0xdf, 0x95, 0x2d, 0xa3, 0x94, 0x28, 0x51, 0xc2, 0x1c, 0x04, 0x66, 0x3c, 0x52, 0x67, 0x46,
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA /* extended_example/sb_key2_cert_test_10.bin */ 0x30, 0x82, 0x04, 0x6f, 0x30, 0x82, 0x02, 0xa7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x00, 0xe3, 0x1c, 0x48, 0x45, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x30, 0x38, 0x34, 0x32, 0x31, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x34, 0x30, 0x33, 0x30, 0x33, 0x31, 0x35, 0x31, 0x30, 0x32, 0x37, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x4b, 0x65, 0x79, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6e, 0x30, 0x6c, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x2e, 0x06, 0x03, 0x64, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x24, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0x69, 0x05, 0x93, 0x68, 0x65, 0xc3, 0x00, 0x14, 0xc0, 0x00, 0x41, 0x07, 0xfd, 0x65, 0x61, 0x65, 0x76, 0x1c, 0x63, 0xb5, 0x2f, 0xe3, 0x2d, 0x66, 0x7a, 0x42, 0x02, 0x87, 0x58, 0x3a, 0xd5, 0x2a, 0xd3, 0x8b, 0x01, 0x16, 0xf8, 0x64, 0x71, 0xd6, 0x17, 0x21, 0x88, 0xd8, 0x1b, 0xee, 0xd7, 0xdf, 0x78, 0xc2, 0xfe, 0x9b, 0x93, 0xcd, 0x43, 0x6d, 0x50, 0xea, 0x66, 0xe7, 0x3e, 0x90, 0xf9, 0xb7, 0x3a, 0x68, 0x51, 0x5a, 0x7c, 0x21, 0xc8, 0x5a, 0x9d, 0xe1, 0x79, 0x5c, 0x29, 0xf2, 0x06, 0x24, 0x31, 0xaf, 0x81, 0x57, 0x79, 0xd0, 0xa0, 0x8c, 0xc9, 0xc2, 0x1b, 0x08, 0x63, 0xf2, 0xc7, 0xee, 0x06, 0x3e, 0x80, 0x7d, 0x86, 0x93, 0x53, 0x0c, 0xee, 0x7d, 0x65, 0x1a, 0x0f, 0x3f, 0x1c, 0x84, 0x2a, 0x1a, 0x34, 0x2b, 0x6a, 0xf0, 0x9a, 0xfb, 0xff, 0x91, 0x51, 0xa6, 0xba, 0xa8, 0x69, 0x80, 0xa7, 0xe9, 0xc6, 0x37, 0x8d, 0xa0, 0x4b, 0x2a, 0xd5, 0x43, 0x76, 0x4e, 0x0e, 0x19, 0x25, 0xa7, 0xa5, 0x58, 0x03, 0x32, 0x4b, 0x05, 0x04, 0xfc, 0xd8, 0xf8, 0x6c, 0x3f, 0xda, 0x6a, 0xa8, 0xc4, 0xd3, 0x55, 0x9f, 0x68, 0x27, 0x96, 0xb9, 0x96, 0x5a, 0xcb, 0xc7, 0x08, 0x40, 0x33, 0x24, 0x98, 0x3a, 0xac, 0xd4, 0x2e, 0xf6, 0xc5, 0xbb, 0x8a, 0x22, 0xdf, 0x69, 0xbc, 0x85, 0x16, 0x13, 0xcc, 0x8b, 0xa6, 0x6d, 0xf3, 0x8b, 0x12, 0xc1, 0x03, 0x06, 0x40, 0x66, 0xa0, 0x66, 0xcc, 0x14, 0x4b, 0xd7, 0xb7, 0x05, 0x73, 0x60, 0xdb, 0xc5, 0xb2, 0x42, 0xa5, 0x99, 0x79, 0x26, 0x04, 0x2c, 0x94, 0x15, 0xb9, 0x01, 0x9e, 0x0f, 0x98, 0x36, 0xc1, 0xe5, 0xe4, 0x5e, 0x1e, 0x62, 0xea, 0x6a, 0x49, 0x0d, 0x6f, 0x34, 0x88, 0x82, 0x39, 0x6e, 0x63, 0xed, 0x08, 0x9a, 0x47, 0x49, 0x07, 0x62, 0xed, 0x9b, 0x84, 0x23, 0x9c, 0xee, 0x3d, 0x82, 0xc2, 0x6a, 0x65, 0xc8, 0x91, 0x9d, 0x3e, 0x11, 0x0b, 0xa8, 0x57, 0x1d, 0xbf, 0x89, 0x01, 0x0f, 0x0d, 0x7d, 0x8e, 0xde, 0x10, 0x6b, 0x87, 0xbe, 0x61, 0x03, 0x0b, 0xff, 0x8f, 0xc5, 0x03, 0x0e, 0x59, 0x5b, 0xb1, 0x9f, 0x21, 0xc8, 0x76, 0x85, 0x45, 0xb4, 0xd9, 0x72, 0x81, 0x50, 0x02, 0x27, 0xe7, 0x26, 0x07, 0xb9, 0x05, 0x30, 0xe2, 0x8e, 0x66, 0x51, 0x80, 0x99, 0x24, 0x6f, 0x92, 0x45, 0xba, 0xd2, 0x4d, 0x2f, 0xb8, 0x61, 0x45, 0x6e, 0x9c, 0x09, 0x5c, 0x01, 0x13, 0x6d, 0xb1, 0x7b, 0xb5, 0x14, 0x0e, 0x73, 0xce, 0x4c, 0xe5, 0x12, 0xd7, 0x10, 0xdc, 0x27, 0xfb, 0xa5, 0x88, 0xa0, 0xd9, 0xf5, 0x86, 0x0b, 0x47, 0xc5, 0xac, 0x81, 0x9a, 0xff, 0xe8, 0xee, 0x69, 0xa0, 0xc4, 0xa4, 0x0d, 0xfb, 0x94, 0x36, 0x32, 0xd7, 0x52, 0xe0, 0x36,
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA /* extended_example/sb_content_cert_test_10.bin */ 0x30, 0x82, 0x04, 0xde, 0x30, 0x82, 0x03, 0x16, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x4a, 0x46, 0xac, 0xf4, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x30, 0x38, 0x34, 0x32, 0x31, 0x33, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x34, 0x30, 0x33, 0x30, 0x33, 0x31, 0x35, 0x31, 0x30, 0x32, 0x37, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x43, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xdd, 0x30, 0x81, 0xda, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x02, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x63, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x03, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x02, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x81, 0x9b, 0x06, 0x03, 0x64, 0x02, 0x04, 0x01, 0x01, 0xff, 0x04, 0x81, 0x90, 0x03, 0x00, 0x00, 0x00, 0xf5, 0x63, 0xad, 0x57, 0xcb, 0xc1, 0xef, 0xa3, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x00, 0xf0, 0x2f, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x10, 0xf0, 0x2f, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x20, 0xf0, 0x2f, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0xc4, 0x55, 0xb2, 0xdc, 0x4a, 0x70, 0x71, 0xe4, 0xfe, 0x1c, 0xab, 0xec, 0xe9, 0xf8, 0xab, 0xb3, 0xdb, 0x43, 0x53, 0x0f, 0xd9, 0x49, 0x92, 0x4b, 0xa7, 0xd3, 0xda, 0xdd, 0xfc, 0x55, 0x65, 0x65, 0x41, 0xb0, 0x24, 0x39, 0x2b, 0x20, 0x30, 0xde, 0x5e, 0xb1, 0xa4, 0x3d, 0xa7, 0x49, 0x85, 0x75, 0xe0, 0x44, 0xd4, 0xfa, 0xb2, 0x23, 0x30, 0x7d, 0xce, 0xce, 0xf6, 0x39, 0x2f, 0x3d, 0x26, 0xf9, 0x4f, 0x60, 0xf1, 0xea, 0x76, 0x1b, 0xc4, 0xdf, 0x90, 0x0c, 0xac, 0xed, 0x13, 0x5c, 0xce, 0x54, 0x1c, 0x76, 0x67, 0x6a, 0x94, 0x6a, 0x54, 0x84, 0xa3, 0xfe, 0x77, 0xce, 0xb3, 0xc9, 0x75, 0xce, 0xd2, 0xad, 0xa3, 0x47, 0x00, 0x10, 0xb2, 0xc6, 0x07, 0x80, 0x6d, 0xfa, 0xaa, 0x85, 0x9d, 0x35, 0x1d, 0xe4, 0x22, 0x61, 0x6b, 0xb7, 0xca, 0xd7, 0xca, 0x09, 0xaa, 0xfe, 0xb7, 0x82, 0x54, 0xb4, 0x00, 0xe0, 0x35, 0x91, 0x66, 0x00, 0x3b, 0xcb, 0x17, 0x16, 0x0d, 0x58, 0x12, 0x34, 0x28, 0xe4, 0xde, 0x1b, 0xb1, 0x6c, 0x24, 0x12, 0x4d, 0x6b, 0x78, 0xfc, 0xa5, 0xc9, 0xd5, 0xeb, 0x62, 0x1a, 0x73, 0x81, 0x7b, 0x41, 0x96, 0x58, 0x48, 0x05, 0x4d, 0xc0, 0xa0, 0x68, 0x59, 0x6c, 0x26, 0x09, 0xfb, 0x76, 0x15, 0x84, 0xfe, 0x8f, 0x26, 0x95, 0xf9, 0x42, 0xa7, 0xdc, 0x4a, 0x75, 0xf3, 0x57, 0xbd, 0xfc, 0x7c, 0x65, 0x40, 0x28, 0x44, 0xf5, 0x78, 0x51, 0x95, 0x20, 0xfb, 0xee, 0xf9, 0x74, 0x99, 0x95, 0x6a, 0xf9, 0x78, 0xb7, 0xd5, 0xe6, 0xee, 0xcf, 0x69, 0xf2, 0x53, 0xf8, 0xf3, 0xb3, 0x3c, 0x30, 0xd1, 0xbe, 0x04, 0x10, 0x6e, 0xcf, 0x44, 0xea, 0x31, 0x95, 0x30, 0x51, 0x9a, 0x78, 0x2e, 0x87, 0x32, 0x57, 0x03, 0x00, 0xf8, 0xf9, 0xd8, 0x3d, 0x3a, 0xbd, 0xc9, 0x65, 0x46, 0x7d, 0xa0, 0x58, 0x37, 0xa8, 0x77, 0xcb, 0x99, 0x3b, 0xc2, 0x54, 0x33, 0x3f, 0x29, 0x7b, 0x2a, 0xe6, 0x33, 0x04, 0x0d, 0x42, 0x3f, 0x10, 0x04, 0x6a, 0xb5, 0x57, 0x33, 0x05, 0x0d, 0xd9, 0xa4, 0x3e, 0xf6, 0x95, 0xfc, 0xc0, 0x97, 0x7f, 0x40, 0x3f, 0x10, 0x7f, 0x31, 0x60, 0xf7, 0x96, 0x52, 0x02, 0xce, 0x23, 0x82, 0xa5, 0xcd, 0xce, 0x1e, 0x8a, 0x94, 0x32, 0xc1, 0x1d, 0xc4, 0x86, 0x19, 0xd8, 0xee, 0x83, 0xab, 0x8d, 0x3a, 0x1a, 0x3d, 0x8c, 0xa3, 0x13, 0x5d, 0xe4, 0xe7, 0x43, 0xf4, 0xd4, 0x2d, 0x53, 0xef, 0x91, 0x7c, 0xf2, 0xe4, 0xbd, 0x43, 0x6b, 0xed, 0xa0, 0xe7, 0xbd, 0x04, 0xb5, 0x41, 0x17, 0x1d, 0xe4, 0x6f, 0x09, 0xc9, 0xf6, 0xb1, 0x1a, 0x97, 0x72, 0x48, 0x45, 0x54, 0x70, 0x5d, 0x21, 0xfa, 0x1b, 0x56, 0xff, 0x2c, 0x4b, 0xec, 0xaa, 0x45, 0xd3, 0x94, 0x49, 0x03, 0x86, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA /* extended_example/sb_image1_enc.bin */ 0x1f, 0xef, 0x8c, 0xa0, 0xb6, 0x85, 0xfb, 0x56, 0x36, 0xcf, 0x03, 0xf8, 0x84, 0xbd, 0x1f, 0x3b, 0x24, 0x9c, 0x56, 0xa9, 0xe5, 0x77, 0x07, 0x44, 0xfe, 0x9e, 0x83, 0x93, 0xbe, 0x35, 0xb6, 0x2b, 0x5e, 0x03, 0x1d, 0x53, 0xf5, 0x32, 0x52, 0xc1, 0x5c, 0x1a, 0xc7, 0x03, 0x30, 0x95, 0x1f, 0x32, 0x87, 0x79, 0x24, 0x5e, 0x96, 0x79, 0xbc, 0xa8, 0xda, 0x5f, 0x21, 0x85, 0xe7, 0xec, 0x21, 0x7b, 0x70, 0x24, 0x18, 0xc2, 0xb2, 0xcc, 0xfe, 0x71, 0x0f, 0x51, 0xb4, 0x9a, 0xf1, 0x39, 0x20, 0x1f, 0x6a, 0x0f, 0x33, 0xab, 0x7c, 0x13, 0x8a, 0x83, 0x5c, 0x77, 0x0b, 0xef, 0x1a, 0x58, 0x97, 0x88, 0x27, 0xcb, 0x54, 0x13, 0xd8, 0x6d, 0x66, 0x23, 0xfa, 0xe1, 0xa5, 0xc4, 0x69, 0x99, 0xa8, 0xdc,
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA /* extended_example/sb_image2_enc.bin */ 0x7b, 0xdd, 0x83, 0xdc, 0x2c, 0xb4, 0x51, 0x21, 0xa6, 0xfb, 0xd7, 0xe3, 0x8d, 0x14, 0xe8, 0xb7, 0xba, 0x4c, 0x45, 0x0a, 0x99, 0x18, 0x59, 0x2c, 0x1e, 0x97, 0x65, 0x09, 0xb6, 0x54, 0x8c, 0x77, 0x5b, 0x33, 0xc3, 0x0a, 0x73, 0x24, 0xe4, 0x7e, 0x2a, 0xfe, 0xd9, 0x50, 0x0b, 0x5e, 0x7c, 0xe3, 0x16, 0x72, 0xbb, 0xf1, 0x28, 0xe0, 0x06, 0x32, 0x9d, 0xa5, 0x56, 0x55, 0xd7, 0x01, 0x75, 0xe6, 0xa6, 0xc0, 0x03, 0x7b, 0xde, 0xda, 0xc5, 0xc3, 0xfb, 0x1e, 0x63, 0x10, 0x7b, 0x1c, 0x54, 0xd4, 0x86, 0x1a, 0xf7, 0x99, 0x0d, 0x8c, 0xf3, 0x9f, 0x39, 0xe1, 0x61, 0xba, 0x9e, 0x4f, 0x1b, 0x08, 0xe6, 0x86, 0x44, 0x93, 0x19, 0x50, 0xe1, 0x88, 0x32, 0xfe, 0xb4, 0x88, 0x2d, 0x84, 0x0a, 0xb1,
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA /* extended_example/sb_image3_enc.bin */ 0xc5, 0x6a, 0x57, 0x9c, 0x84, 0x98, 0x7e, 0xdb, 0x5a, 0x90, 0xf8, 0x34, 0xde, 0xd4, 0x03, 0x7a, 0x6a, 0xdb, 0x35, 0x2a, 0xf0, 0xa1, 0x14, 0xdd, 0xee, 0x40, 0x7c, 0x27, 0xdf, 0x96, 0xb5, 0x96, 0xf8, 0x9b, 0xaa, 0x90, 0x7a, 0x50, 0x60, 0x01, 0xf8, 0x93, 0xaf, 0x9c, 0xb1, 0x35, 0x33, 0xc1, 0xc3, 0x11, 0xdb, 0x5a, 0xe9, 0x57, 0x08, 0x86, 0x03, 0xc3, 0xe4, 0x5f, 0x37, 0xb3, 0x74, 0xf9, 0xa0, 0x65, 0x4b, 0x15, 0xae, 0x7e, 0x2c, 0xe2, 0x88, 0x47, 0x01, 0x5d, 0x70, 0x63, 0x44, 0x77, 0xe3, 0x5e, 0x74, 0x39, 0x22, 0x3a, 0xc8, 0xa9, 0x11, 0x8a, 0x43, 0xc0, 0xe9, 0xc3, 0x34, 0x63, 0xaf, 0x5d, 0x3d, 0x39, 0xe3, 0xbc, 0xc0, 0x77, 0xf8, 0x3f, 0xed, 0x27, 0x85, 0xd5, 0x43, 0xfb,
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA_LENGTH /* sb_key1_cert_test_10.bin */ 1139
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA_LENGTH /* sb_key2_cert_test_10.bin */ 1139
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH /* sb_content_cert_test_10.bin */ 1276
+#else
+/************************************/
+/*        ZYNQ NOT_X509             */
+/************************************/
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA /* extended_example/sb_key1_cert_test_10.bin */ 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x0b, 0xb1, 0xcd, 0x21, 0x43, 0xf5, 0x9a, 0x39, 0xb8, 0xd3, 0xe4, 0xdc, 0x7a, 0x82, 0xc6, 0xdc, 0x72, 0xd5, 0x6b, 0x13, 0xf3, 0x80, 0x1a, 0x00, 0x77, 0x17, 0xce, 0xc6, 0x98, 0x6b, 0x06, 0xc4, 0x4f, 0x74, 0xa2, 0xfa, 0x97, 0xe8, 0x14, 0x3d, 0x9e, 0xab, 0xa1, 0xaf, 0x5a, 0x3f, 0x38, 0x14, 0x5d, 0x10, 0x40, 0xc1, 0xdf, 0x58, 0xcd, 0xa6, 0xf5, 0xcf, 0x7b, 0xd9, 0x8d, 0xae, 0xd5, 0xe4, 0x13, 0x3e, 0x0b, 0x89, 0x21, 0x06, 0xc9, 0xd4, 0xe9, 0xf5, 0xe5, 0x74, 0x2d, 0x81, 0x45, 0x0d, 0x16, 0xe0, 0x7f, 0xf6, 0xd2, 0x63, 0xfc, 0xf9, 0x95, 0xf4, 0xf9, 0x18, 0x3f, 0x16, 0x1c, 0x69, 0xac, 0x45, 0x22, 0x40, 0x01, 0x88, 0xc3, 0xe3, 0x42, 0x01, 0x7c, 0x0a, 0xd1, 0xeb, 0x15, 0x22, 0x0d, 0xad, 0xd6, 0xc6, 0x03, 0xe6, 0x72, 0x26, 0xba, 0x30, 0xb4, 0x1e, 0xad, 0x93, 0xcf, 0x5e, 0x64, 0xd4, 0xf2, 0x03, 0x7c, 0x79, 0x98, 0x71, 0x60, 0xee, 0xd7, 0xa4, 0xe4, 0x77, 0xe3, 0x6b, 0xdb, 0x06, 0xcc, 0xd4, 0xe6, 0x1b, 0x08, 0x2a, 0xaa, 0xd6, 0x26, 0x21, 0x77, 0x1f, 0x22, 0xae, 0xa8, 0x7a, 0x92, 0xa4, 0x09, 0x54, 0xff, 0x5a, 0x53, 0xb5, 0x50, 0xd6, 0xf5, 0xd4, 0x50, 0xd4, 0x37, 0xd3, 0xcf, 0x1f, 0x8f, 0x93, 0xf7, 0x29, 0xfc, 0x83, 0xda, 0x3d, 0xa1, 0x0a, 0x59, 0xc8, 0x0d, 0xe2, 0xb7, 0x75, 0x9c, 0x18, 0x95, 0x4a, 0x3b, 0xa3, 0x33, 0x52, 0x99, 0x01, 0x31, 0x43, 0xd5, 0x95, 0x6f, 0x8f, 0xe6, 0x58, 0x0d, 0xfd, 0xdd, 0x05, 0xb8, 0x36, 0xea, 0xae, 0x2d, 0x21, 0xbc, 0x47, 0x51, 0x27, 0xe8, 0x96, 0x92, 0x7f, 0xec, 0x0a, 0x3a, 0x32, 0x62, 0x32, 0xfd, 0x92, 0xb4, 0x23, 0x43, 0x14, 0xd1, 0x2b, 0xe1, 0x37, 0xa0, 0x83, 0x02, 0xe4, 0xa8, 0x59, 0x97, 0x45, 0xc6, 0xd2, 0xd1, 0x73, 0x7e, 0x9e, 0x68, 0x33, 0xf3, 0xe0, 0x4d, 0xd0, 0x68, 0xf4, 0x16, 0x6e, 0x49, 0x60, 0xe7, 0xb2, 0xcf, 0x34, 0xce, 0x4b, 0xdf, 0x55, 0x02, 0xe1, 0xa5, 0xe9, 0x65, 0xfc, 0xc3, 0x9e, 0xb7, 0x98, 0x95, 0x5d, 0x1e, 0xf1, 0x18, 0x7b, 0xdb, 0x70, 0x0c, 0xd4, 0x9e, 0x93, 0xdb, 0x8f, 0x78, 0x28, 0xf6, 0xd6, 0xbd, 0x8e, 0x01, 0xd1, 0x58, 0xcd, 0xb5, 0xb5, 0x55, 0x49, 0x95, 0x12, 0x58, 0x61, 0x0b, 0x15, 0x40, 0xb6, 0xcf, 0x6e, 0x20, 0x88, 0xe9, 0x1f, 0x45, 0xf5, 0xed, 0x06, 0xa3, 0xa1, 0x4b, 0xd8, 0xc1, 0xca, 0x55, 0xed, 0x40, 0x2a, 0xb4, 0x74, 0x5a, 0x3b, 0xb4, 0x9d, 0xe2, 0xd8, 0xcf, 0x14, 0x13, 0xa3, 0xb4, 0xd2, 0x0f, 0x96, 0x04, 0x2a, 0xce, 0xf4, 0xe7, 0x72, 0x28, 0x63, 0x6d, 0x59, 0x24, 0x8a, 0x0f, 0x23, 0x54, 0x72, 0x12, 0x84, 0xf5, 0x5f,
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA /* extended_example/sb_key2_cert_test_10.bin */ 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0xa1, 0x5c, 0xd2, 0xb6, 0x0c, 0x8d, 0x36, 0xef, 0x1b, 0x68, 0x8e, 0x00, 0x82, 0x7e, 0x14, 0x0c, 0x13, 0x76, 0x3c, 0xa9, 0xc7, 0x02, 0x66, 0x72, 0x18, 0xb2, 0xfe, 0xd5, 0x05, 0x69, 0xe8, 0x2d, 0x37, 0x01, 0x83, 0x4d, 0x8d, 0x41, 0x66, 0x5d, 0x2b, 0xd6, 0x23, 0x1d, 0x9b, 0x12, 0x38, 0x62, 0xa1, 0x07, 0x5c, 0xa2, 0x1f, 0xb6, 0xce, 0x35, 0x9d, 0x6a, 0x6e, 0x8c, 0x1c, 0xa9, 0x5c, 0xa5, 0x3b, 0x86, 0x78, 0xac, 0xa8, 0x9f, 0x5b, 0x2e, 0x19, 0x52, 0x4d, 0xc5, 0xaa, 0x47, 0xe7, 0x90, 0xf4, 0xcf, 0x6b, 0x23, 0x3f, 0xc7, 0x05, 0xc1, 0xf9, 0x52, 0x9b, 0x60, 0x74, 0x07, 0x8a, 0xec, 0x73, 0x65, 0x51, 0x1f, 0x99, 0x2c, 0xa0, 0x1d, 0xb0, 0x29, 0x57, 0xf8, 0x9a, 0x8d, 0x80, 0x80, 0x7f, 0x6e, 0xc6, 0x44, 0x69, 0x61, 0x6b, 0x61, 0x10, 0xd5, 0xe8, 0xa0, 0x55, 0x36, 0x11, 0x5e, 0xad, 0x36, 0x8f, 0x92, 0x46, 0x73, 0x57, 0xdf, 0xdc, 0x47, 0xf5, 0xfd, 0xe9, 0x25, 0x2b, 0xec, 0x71, 0xf6, 0x66, 0x96, 0x67, 0xbd, 0xcf, 0x32, 0xd7, 0x46, 0x69, 0x05, 0xb2, 0xb0, 0xd3, 0xb3, 0xe7, 0xef, 0x58, 0x4a, 0x5e, 0xda, 0xe5, 0x0e, 0x61, 0xa3, 0x5a, 0x65, 0xce, 0xe0, 0x23, 0x0f, 0x86, 0x31, 0x2a, 0x97, 0xc3, 0xd5, 0x45, 0xb6, 0x4a, 0x5b, 0xc0, 0x17, 0x36, 0xb2, 0x11, 0xa8, 0x08, 0xcf, 0x26, 0xc8, 0x82, 0x08, 0x7c, 0xdc, 0xa2, 0x61, 0x57, 0x83, 0xa6, 0x35, 0xe7, 0x0a, 0xb2, 0x0c, 0x62, 0xa9, 0x0e, 0xcb, 0xfc, 0x46, 0x13, 0xf6, 0xae, 0x88, 0xc8, 0xc8, 0x8a, 0xb0, 0xee, 0xd4, 0xbc, 0xb3, 0xf8, 0x68, 0x62, 0x40, 0x2f, 0x6b, 0xd4, 0x45, 0x1f, 0xf7, 0x37, 0x95, 0xaf, 0x5b, 0xa9, 0x80, 0xf8, 0x8a, 0xe2, 0xf5, 0xd4, 0x5e, 0xeb, 0xf0, 0xe9, 0x5e, 0x19, 0x9d, 0x6c, 0xc4, 0x70, 0x71, 0x11, 0xb3, 0x63, 0x3d, 0x64, 0xf3, 0x8b, 0x5a, 0x8a, 0x2a, 0xa4, 0xb9, 0x2b, 0x32, 0xf0, 0xcf, 0x1c, 0xf3, 0x00, 0xf8, 0xa8, 0x25, 0x03, 0xf0, 0xa1, 0xed, 0x35, 0x99, 0xa4, 0xb7, 0x86, 0xd1, 0x3d, 0x88, 0xae, 0xa5, 0x0c, 0xd8, 0x3d, 0xf7, 0xae, 0x13, 0x2c, 0x25, 0xfc, 0x1d, 0xb9, 0x6e, 0x55, 0x70, 0x1c, 0x12, 0x46, 0x78, 0x8c, 0xdf, 0xbc, 0xc1, 0x14, 0xca, 0xc3, 0x04, 0xd6, 0x85, 0x60, 0x45, 0x10, 0x02, 0xf3, 0xd2, 0x7c, 0x5b, 0x7c, 0x28, 0x2d, 0xc7, 0x10, 0x9a, 0xe3, 0x73, 0x20, 0x89, 0x7e, 0x4f, 0x51, 0x49, 0x1a, 0x0e, 0xd5, 0xcb, 0x66, 0xf5, 0x59, 0x44, 0xa9, 0x93, 0x81, 0x39, 0xdd, 0x7d, 0xff, 0x5c, 0x25, 0xd9, 0x20, 0x6b, 0x9b, 0x00, 0x48, 0x60, 0x59, 0x87, 0xe6, 0xd6, 0x0a, 0xc2, 0x6b, 0xa9, 0x46, 0x06, 0x0c, 0xd5, 0xec, 0x35,
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA /* extended_example/sb_content_cert_test_10.bin */ 0x63, 0x63, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x03, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x03, 0x00, 0x00, 0x00, 0xf4, 0xad, 0x09, 0x7c, 0x21, 0x20, 0x32, 0x1d, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x00, 0xf0, 0x2f, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x10, 0xf0, 0x2f, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x20, 0xf0, 0x2f, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x73, 0x59, 0x89, 0x34, 0x16, 0x0f, 0x98, 0x59, 0xe3, 0x9c, 0xa8, 0x0f, 0xa3, 0x82, 0x91, 0xe3, 0x34, 0x8e, 0x05, 0x0c, 0xd9, 0x0d, 0x70, 0x18, 0xea, 0x2d, 0xa0, 0xcd, 0x21, 0xda, 0x3f, 0xc3, 0x34, 0x0f, 0x08, 0x05, 0xad, 0x39, 0x0c, 0x3e, 0xb0, 0xfb, 0x09, 0x4b, 0xde, 0xc0, 0x96, 0xa7, 0x36, 0x11, 0xd8, 0x90, 0xbf, 0x56, 0x16, 0xe3, 0x2b, 0x82, 0xd0, 0x79, 0x2a, 0x94, 0xaf, 0xee, 0xb7, 0xff, 0x7e, 0xb0, 0x4e, 0xbf, 0xaf, 0x07, 0x6c, 0x0e, 0x4f, 0xc5, 0xa4, 0xf2, 0xcc, 0x06, 0xb1, 0xde, 0xef, 0x16, 0xec, 0x73, 0xc4, 0x1d, 0x22, 0xa3, 0x22, 0xa1, 0x7b, 0xe0, 0x7c, 0xd2, 0x94, 0x25, 0x26, 0xf8, 0xab, 0x14, 0x52, 0xa0, 0xa4, 0x30, 0x06, 0xb4, 0x0d, 0x79, 0xa3, 0x92, 0xdb, 0x35, 0xca, 0xfd, 0xfb, 0xa6, 0xc5, 0xb1, 0x04, 0xae, 0xd6, 0x08, 0x1e, 0x32, 0xc1, 0xcf, 0xfd, 0x97, 0x9b, 0xf1, 0x3f, 0x6a, 0xdb, 0x6d, 0xec, 0x22, 0x1c, 0xbf, 0x18, 0xd5, 0xa1, 0x35, 0xbd, 0x08, 0x08, 0x58, 0x20, 0xd3, 0xd0, 0x0f, 0x5a, 0xa7, 0x78, 0x05, 0xcf, 0x75, 0x79, 0x58, 0x5e, 0x98, 0xd8, 0x8f, 0xe6, 0x26, 0x20, 0x6a, 0x69, 0xd3, 0x80, 0x03, 0x33, 0x81, 0xff, 0xd9, 0x06, 0x79, 0x71, 0x0d, 0xa5, 0xa7, 0x87, 0x77, 0x18, 0x7d, 0x05, 0x7a, 0xe6, 0xca, 0x8d, 0x4b, 0x63, 0xf8, 0x60, 0x6c, 0x92, 0x17, 0x80, 0x79, 0x0c, 0xcb, 0x7e, 0x30, 0x39, 0x71, 0x96, 0x06, 0xf6, 0x12, 0x90, 0x45, 0x4a, 0x9c, 0xdf, 0x74, 0x75, 0xbb, 0x98, 0xd4, 0x9d, 0x41, 0x35, 0x38, 0xd8, 0xa0, 0x69, 0x92, 0xb7, 0xc7, 0xd7, 0x09, 0xd1, 0x81, 0xb3, 0xf4, 0xc0, 0x0f, 0x10, 0xe0, 0x8a, 0xb3, 0xe6, 0xf1, 0x46, 0x62, 0xcf, 0xbc, 0xdd, 0x02, 0xe0, 0x1b, 0x72, 0x99, 0xd8, 0xae, 0x11, 0xb8, 0x42, 0x01, 0xd4, 0xe2, 0x32, 0x52, 0xa9, 0x9d, 0x6f, 0x2b, 0xf1, 0x68, 0xbd, 0x3e, 0xca, 0xfa, 0x02, 0xb7, 0xfd, 0x5e, 0x8c, 0x47, 0x26, 0x3a, 0x42, 0x90, 0xe8, 0xe6, 0xcf, 0x1f, 0x8b, 0xb3, 0x7d, 0xdf, 0xb8, 0x67, 0x07, 0x85, 0xac, 0xfa, 0x2c, 0x17, 0xec, 0xa1, 0x74, 0xfe, 0x91, 0xa3, 0xa8, 0xc9, 0xc7, 0x1a, 0x49, 0x59, 0xe6, 0x08, 0xbf, 0x8a, 0xd5, 0x9c, 0x5d, 0x9a, 0xc8, 0xa9, 0x46, 0x04, 0xbf, 0xfc, 0x42, 0x83, 0xaf, 0xa2, 0xed, 0x3a, 0x1d, 0xfe, 0xc2, 0xf2, 0xe1, 0x0d, 0x5c, 0x2d, 0xff, 0x5e, 0xcf, 0xbe, 0x26, 0x61, 0x6f, 0x4f, 0x0c, 0xd7, 0x9c, 0x53, 0x3c, 0x03, 0x05, 0x56, 0xe5, 0xf4, 0xc0, 0x5e, 0xdd, 0xb9, 0x8d, 0x08, 0xfc, 0x2b, 0x78, 0x02, 0xc9, 0x63, 0x80, 0xb3, 0x3e, 0x19, 0x89, 0x86, 0x80, 0x99, 0xe2, 0xea, 0x2d, 0x9f, 0xf4, 0x63, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA /* extended_example/sb_image1_enc.bin */ 0xad, 0xea, 0xc5, 0xdf, 0x69, 0xc6, 0x66, 0xf7, 0xef, 0x5c, 0xf4, 0x01, 0xf3, 0x21, 0x62, 0x14, 0xc6, 0x44, 0xaf, 0xb7, 0xd9, 0x65, 0xa1, 0xfe, 0xb0, 0x43, 0x75, 0x34, 0xec, 0x29, 0xd5, 0xef, 0x2e, 0xa7, 0x00, 0x90, 0x33, 0xf8, 0x95, 0xa8, 0x2d, 0xe5, 0x50, 0x1a, 0xa9, 0x8a, 0x17, 0xf9, 0xe1, 0x8e, 0xfb, 0x41, 0xa0, 0x13, 0xd1, 0x08, 0x27, 0xec, 0xa1, 0xbd, 0x43, 0xf4, 0xf1, 0xae, 0x40, 0x49, 0x17, 0x8e, 0x63, 0x19, 0x1e, 0xa6, 0xa8, 0x75, 0xc5, 0xd4, 0x9c, 0x54, 0x83, 0x81, 0x48, 0xe7, 0xc4, 0xbf, 0x94, 0x2e, 0xb6, 0x74, 0x66, 0x07, 0xc8, 0x57, 0xd2, 0x22, 0x4e, 0x5d, 0x9a, 0xa2, 0x1b, 0xfe, 0xa7, 0x0c, 0x42, 0xa9, 0xb2, 0x25, 0x01, 0x68, 0x0e, 0xc1, 0x88, 0x92,
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA /* extended_example/sb_image2_enc.bin */ 0x1b, 0xd9, 0x01, 0x59, 0x53, 0xec, 0xa0, 0xd1, 0x77, 0x9c, 0x12, 0x14, 0xd1, 0x14, 0xaf, 0x24, 0x7e, 0x5f, 0xcf, 0x68, 0x43, 0x75, 0x81, 0x2b, 0x69, 0xbd, 0xb4, 0x59, 0x78, 0x1d, 0xe0, 0x83, 0xe9, 0xce, 0x99, 0x61, 0x08, 0x98, 0x9b, 0x72, 0x7e, 0x89, 0x17, 0x44, 0xb1, 0xb4, 0x5a, 0xb3, 0x42, 0x69, 0x8f, 0x61, 0x96, 0x83, 0x4b, 0x5c, 0x10, 0x90, 0xfc, 0xdd, 0xa4, 0xc8, 0x85, 0xf6, 0x79, 0x1a, 0x96, 0x12, 0x93, 0x0d, 0xa1, 0x9e, 0x9a, 0x4a, 0xfc, 0xa4, 0x9a, 0xfa, 0xb4, 0xf9, 0x78, 0xd2, 0x92, 0x8f, 0xc6, 0x72, 0xa6, 0x6d, 0x7d, 0xe6, 0xf5, 0x20, 0x4c, 0x95, 0x78, 0x63, 0xc8, 0xdb, 0x82, 0x91, 0x2c, 0x48, 0xf8, 0x94, 0xb0, 0x63, 0x51, 0xc6, 0x89, 0xc3, 0xba, 0x33,
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA /* extended_example/sb_image3_enc.bin */ 0x54, 0x84, 0x91, 0xbd, 0x10, 0xa2, 0x58, 0x05, 0xbf, 0x42, 0x3c, 0xac, 0x6f, 0x32, 0x42, 0x43, 0xb1, 0x2f, 0xb0, 0x9e, 0x1e, 0x70, 0xd8, 0x66, 0xfc, 0xdd, 0x0f, 0xc0, 0x44, 0x50, 0xe1, 0x7a, 0xcd, 0xa7, 0x47, 0x99, 0x8a, 0xf0, 0x03, 0xca, 0x28, 0xe2, 0x18, 0x39, 0x55, 0xa6, 0xfd, 0x0e, 0x05, 0x63, 0x93, 0xc3, 0x86, 0x81, 0x7a, 0xe5, 0xfa, 0xb7, 0xaa, 0xeb, 0x07, 0x8e, 0x8c, 0x5e, 0x07, 0x5c, 0x8e, 0xc7, 0x40, 0xa2, 0xde, 0x3c, 0xad, 0xe8, 0xe2, 0xbd, 0x8f, 0xec, 0xe5, 0xc5, 0x9d, 0xe7, 0xe5, 0x76, 0x86, 0x41, 0xfa, 0xf0, 0x3d, 0x13, 0xa2, 0x8e, 0x85, 0xae, 0x34, 0x59, 0x4d, 0x59, 0x48, 0xd8, 0x42, 0x0b, 0xc8, 0x7c, 0xff, 0x91, 0x55, 0x40, 0xef, 0x47, 0x13, 0xb0,
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA_LENGTH /* sb_key1_cert_test_10.bin */ 840
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA_LENGTH /* sb_key2_cert_test_10.bin */ 840
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH /* sb_content_cert_test_10.bin */ 972
+#endif /* defined(CC_SB_X509_CERT_SUPPORTED) */
+#elif defined(DX_PLAT_MPS2_PLUS)
+#if defined(CORTEX_M33_FPGA)
+#if defined(CC_SB_X509_CERT_SUPPORTED)
+/************************************/
+/*          MPS2 CM33 X509          */
+/************************************/
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA /* example/sb_key_cert1_hbk0.bin */ 0x30, 0x82, 0x04, 0x6e, 0x30, 0x82, 0x02, 0xa6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x02, 0x3c, 0x84, 0x70, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x30, 0x35, 0x31, 0x34, 0x31, 0x31, 0x34, 0x32, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x35, 0x30, 0x33, 0x31, 0x34, 0x32, 0x30, 0x33, 0x39, 0x35, 0x36, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x4b, 0x65, 0x79, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc0, 0x68, 0x9a, 0xdf, 0x7a, 0x7f, 0x80, 0xad, 0xe1, 0xf1, 0x7d, 0xed, 0xbd, 0x3a, 0x23, 0xc6, 0x80, 0x87, 0x8d, 0x10, 0xf9, 0x99, 0x82, 0x6b, 0xbc, 0xec, 0x41, 0xaa, 0x94, 0xba, 0xcb, 0xbb, 0x6a, 0x59, 0xb2, 0x34, 0x41, 0x6b, 0x26, 0xf2, 0xb7, 0x5f, 0x96, 0xb0, 0x59, 0x93, 0xa9, 0x69, 0x8b, 0xac, 0x5c, 0x14, 0xb2, 0x51, 0xa8, 0x45, 0x2c, 0xd4, 0xe2, 0xfc, 0x37, 0xaf, 0x48, 0x16, 0x9f, 0x7e, 0xad, 0x37, 0x17, 0x0a, 0x2b, 0xc9, 0x2f, 0xf1, 0x5b, 0xdc, 0x78, 0xcf, 0x80, 0x92, 0xe4, 0xd8, 0x68, 0xb2, 0xc7, 0xd0, 0x4e, 0x9b, 0x66, 0x6e, 0x0a, 0x7a, 0xf7, 0x53, 0x60, 0x2e, 0x5e, 0xc6, 0x42, 0xa5, 0xdb, 0x94, 0xd1, 0x67, 0xde, 0x1f, 0x5d, 0xe3, 0x5e, 0x4b, 0x9d, 0xb8, 0x23, 0x3e, 0xdd, 0x79, 0xd8, 0xac, 0xf9, 0xd4, 0xbe, 0x77, 0xf1, 0xae, 0x8b, 0xbb, 0x94, 0xc7, 0xf8, 0xe8, 0xcc, 0x3a, 0xdb, 0x76, 0x8b, 0xb8, 0x5d, 0x99, 0x83, 0x29, 0x11, 0xe2, 0xfc, 0x38, 0x0d, 0x65, 0x95, 0x41, 0xbb, 0xd2, 0x8c, 0x77, 0x1b, 0x31, 0xb4, 0xb4, 0xb9, 0x4a, 0x59, 0x70, 0x72, 0x65, 0xb0, 0x32, 0xb8, 0x34, 0xd0, 0x4e, 0x62, 0x65, 0x9e, 0xfb, 0x49, 0x76, 0x64, 0x2f, 0x48, 0xe2, 0xe5, 0x00, 0xd7, 0xd1, 0xd4, 0xf4, 0xf6, 0x58, 0xc0, 0x04, 0x93, 0xee, 0x60, 0xd6, 0x94, 0xcd, 0xc5, 0x01, 0xc5, 0x77, 0xf7, 0xa0, 0xc7, 0xc3, 0x10, 0x5b, 0xdd, 0x36, 0x1f, 0x37, 0x07, 0xb1, 0x60, 0xef, 0x32, 0x7c, 0x86, 0xc3, 0xd7, 0x2a, 0x19, 0xfd, 0xac, 0xea, 0x2c, 0x34, 0x40, 0x8d, 0xdf, 0x78, 0x7e, 0xcf, 0xc7, 0xeb, 0x7d, 0x41, 0x25, 0xd3, 0x0d, 0x14, 0x5a, 0xdf, 0x90, 0xea, 0x8b, 0x68, 0xc3, 0x32, 0xaf, 0x53, 0xcf, 0x11, 0x24, 0x64, 0xbf, 0xf6, 0xf8, 0xdb, 0x09, 0x4e, 0xae, 0xbb, 0x32, 0x13, 0x9b, 0xc4, 0x90, 0xa7, 0x46, 0xc0, 0xe3, 0x88, 0xb7, 0x36, 0x78, 0x02, 0xab, 0x67, 0x61, 0x34, 0x17, 0x01, 0xc0, 0xe3, 0xc6, 0x2d, 0xfb, 0x3e, 0x5d, 0xf8, 0xd8, 0x43, 0x57, 0x4c, 0x84, 0x40, 0x21, 0x97, 0xc5, 0xe4, 0x06, 0x74, 0x3f, 0xa3, 0x22, 0x35, 0x48, 0x87, 0x33, 0xd8, 0xc5, 0x53, 0x76, 0x98, 0x0d, 0x02, 0x07, 0x48, 0x15, 0xf5, 0xf6, 0xb8, 0x56, 0x53, 0x08, 0x1c, 0xfe, 0xb4, 0x77, 0x4d, 0x9c, 0xa6, 0x1c, 0x99, 0xbb, 0x2b, 0x03, 0x03, 0xf3, 0x0c, 0x32, 0x84, 0x0f, 0x96, 0x67, 0x1a, 0x0d, 0x73, 0x13, 0xbc, 0x0c, 0xe4, 0x34, 0x41, 0x18, 0xb8, 0x09, 0x55, 0x2d, 0xe5, 0x75, 0x47, 0x03, 0xa3, 0xb2, 0xf2, 0x59, 0x94, 0x81, 0x27, 0x85, 0x98, 0x83, 0x94, 0x81, 0xc4, 0x8d, 0xc8, 0x80, 0xd6, 0xa9, 0xae, 0x02, 0x44, 0x45, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6e, 0x30, 0x6c, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x4d, 0xe1, 0xc6, 0x58, 0x5c, 0x3d, 0x03, 0x7a, 0x30, 0x2e, 0x06, 0x03, 0x64, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x24, 0x05, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0x83, 0x84, 0x0e, 0x48, 0xa1, 0x75, 0x24, 0xa5, 0x0e, 0x89, 0xca, 0xc6, 0x84, 0xf8, 0xf3, 0x8e, 0xb5, 0xc3, 0x9c, 0x1c, 0x3c, 0xa3, 0x46, 0xbf, 0x59, 0xc1, 0x8a, 0xd9, 0x6d, 0xfa, 0x77, 0xf0, 0x4b, 0xfb, 0x27, 0x92, 0x97, 0xdc, 0x1e, 0x89, 0x37, 0xce, 0xcf, 0x65, 0xf5, 0x00, 0x6f, 0xdf, 0xcf, 0x16, 0x39, 0xbe, 0x84, 0x38, 0xf2, 0x54, 0x68, 0xbf, 0xf3, 0x5f, 0x59, 0x4f, 0x33, 0x31, 0x25, 0x92, 0xef, 0x52, 0xdc, 0x05, 0x36, 0x19, 0x5b, 0xc3, 0xe5, 0xf4, 0xe5, 0xb8, 0xd5, 0xa2, 0x58, 0xdb, 0x3d, 0x76, 0x2c, 0x6a, 0x9f, 0x7c, 0xf7, 0x34, 0xec, 0x54, 0x4c, 0x33, 0x62, 0xee, 0x09, 0x0b, 0x84, 0x80, 0xe4, 0x7c, 0x7b, 0x11, 0x1c, 0x72, 0xea, 0xca, 0xb5, 0xb8, 0x37, 0xfa, 0x61, 0xe3, 0xcc, 0xda, 0xdd, 0x3c, 0xbb, 0x4d, 0xcb, 0x1e, 0xa9, 0xfa, 0x23, 0x3d, 0x22, 0xe1, 0xe7, 0xc4, 0xc3, 0xb1, 0x5e, 0x35, 0xf2, 0x9a, 0x26, 0x93, 0x77, 0x50, 0x87, 0x40, 0xad, 0x68, 0xe5, 0xa2, 0x37, 0x3b, 0x53, 0x5b, 0xcd, 0x02, 0xd7, 0x3a, 0x79, 0x97, 0x1c, 0xf7, 0x92, 0x33, 0xdc, 0xe6, 0xdb, 0xa0, 0x77, 0xdd, 0xea, 0xec, 0x17, 0x83, 0x5a, 0xb1, 0x0c, 0x11, 0xac, 0xc4, 0x49, 0x6b, 0xe8, 0xe5, 0x86, 0xaf, 0x1c, 0x1b, 0xff, 0x5c, 0xfd, 0x8a, 0x2c, 0x0a, 0x72, 0x0b, 0x58, 0x11, 0x3b, 0x1e, 0x00, 0x57, 0xc7, 0x83, 0x99, 0x89, 0x2e, 0xd1, 0x0f, 0x7e, 0x7a, 0xbe, 0x2a, 0x80, 0x21, 0x98, 0x21, 0xee, 0x62, 0x45, 0x82, 0x77, 0xd8, 0x54, 0xc2, 0x61, 0xd4, 0x11, 0x95, 0x35, 0xaa, 0xa2, 0xdb, 0x4d, 0x0f, 0x05, 0x70, 0x4a, 0x88, 0x5b, 0x1b, 0x7e, 0xc3, 0x42, 0x5e, 0xba, 0x41, 0x4e, 0x76, 0xa3, 0x75, 0x5a, 0x97, 0x1b, 0xc0, 0x11, 0xab, 0x0b, 0x86, 0x96, 0x15, 0x2e, 0x13, 0xba, 0x53, 0x90, 0xd4, 0xe2, 0xcd, 0x76, 0x5c, 0x6d, 0xb0, 0x1b, 0x2c, 0xc8, 0x1f, 0x1c, 0x97, 0x49, 0x67, 0x55, 0xe5, 0xcd, 0x9d, 0x8e, 0x9d, 0xe5, 0x3a, 0x84, 0x37, 0xdc, 0xc5, 0xb5, 0xda, 0xf0, 0xce, 0x91, 0xc1, 0x6b, 0x4d, 0x6e, 0x23, 0x07, 0x2a, 0xc5, 0xcd, 0x9f, 0x30, 0xad, 0x7e, 0xd6, 0x5c, 0x6f, 0x8e, 0x75, 0x30, 0xc9, 0x58, 0x70, 0xa4, 0xc7, 0x02, 0xac, 0xe2, 0x48, 0x75, 0x64, 0xb7, 0x62, 0xf1, 0x62, 0xb6, 0x74, 0xc9, 0xa5, 0x52, 0x4f, 0x03, 0xf1, 0x40, 0x74, 0x3b, 0x95, 0xec, 0x1b, 0x8e, 0x46, 0x2f, 0xe4, 0x73, 0xed, 0xbf, 0x09, 0xab, 0x1c, 0xf5, 0xa3, 0x70, 0xab, 0x32, 0x9a, 0xcb, 0x87, 0x79, 0x56, 0x3e, 0xf8, 0x62, 0x25, 0xdb, 0x25, 0x41, 0x48, 0x87, 0x0b, 0x94, 0x1f, 0xd6, 0xa1, 0x88, 0x8b, 0x46, 0xa1, 0x95, 0x80, 0x11, 0xc7,
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA /* example/sb_key_cert2_hbk0.bin */ 0x30, 0x82, 0x04, 0x6f, 0x30, 0x82, 0x02, 0xa7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x00, 0xfa, 0xd7, 0x58, 0x63, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x30, 0x35, 0x31, 0x34, 0x31, 0x31, 0x34, 0x32, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x35, 0x30, 0x33, 0x31, 0x34, 0x32, 0x30, 0x33, 0x39, 0x35, 0x36, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x4b, 0x65, 0x79, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6e, 0x30, 0x6c, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x2e, 0x06, 0x03, 0x64, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x24, 0x05, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0x90, 0x42, 0xa1, 0x9f, 0x68, 0x30, 0x4d, 0x40, 0xf2, 0x73, 0xb5, 0x6d, 0x37, 0x9c, 0x5f, 0xac, 0x57, 0xb8, 0x22, 0x0c, 0x4f, 0x2b, 0xa3, 0xd6, 0xc4, 0xc0, 0x23, 0xfc, 0xe5, 0xea, 0xe0, 0xa3, 0x15, 0x65, 0x6f, 0x13, 0xf6, 0xdb, 0xdf, 0xec, 0xad, 0x8e, 0x0e, 0x68, 0x22, 0xf7, 0x37, 0x1e, 0xfc, 0x0c, 0xc3, 0xcb, 0x84, 0x06, 0x4d, 0xc8, 0xa3, 0x2f, 0xbd, 0x21, 0x74, 0x1e, 0x8d, 0x80, 0x3c, 0xf2, 0x05, 0x7a, 0x2d, 0x14, 0xde, 0x41, 0x32, 0x58, 0x3c, 0x3e, 0x95, 0xe4, 0x6f, 0xfd, 0x25, 0x99, 0x08, 0x8d, 0x56, 0x0b, 0x73, 0x60, 0x59, 0x20, 0x38, 0x24, 0xd1, 0xb1, 0xf1, 0x8e, 0x88, 0x90, 0xbb, 0x4b, 0x82, 0x88, 0xfd, 0xe5, 0x53, 0x92, 0x7a, 0xf4, 0xac, 0xdc, 0x11, 0x20, 0x9d, 0x99, 0x79, 0xa7, 0x8e, 0xdf, 0x85, 0xf8, 0x67, 0x78, 0x4f, 0x89, 0x26, 0xf9, 0x93, 0xbf, 0xa2, 0xe1, 0xeb, 0xb8, 0x54, 0xb1, 0x0c, 0x99, 0x5b, 0x30, 0xea, 0x58, 0xd5, 0x94, 0xea, 0x2b, 0x97, 0x90, 0x3d, 0x0e, 0xc9, 0xe9, 0xff, 0x38, 0x71, 0x3a, 0xe5, 0xbe, 0xb9, 0x0d, 0x39, 0x13, 0xd8, 0x3c, 0x7c, 0x9e, 0xb5, 0x8a, 0x37, 0x2b, 0xbf, 0x3a, 0x6e, 0xf1, 0x4a, 0xb1, 0x57, 0xdc, 0x62, 0x18, 0xff, 0x56, 0xf6, 0x4f, 0x61, 0x0e, 0x7d, 0x64, 0x24, 0x36, 0xf1, 0xc7, 0x82, 0x45, 0x85, 0x9c, 0xde, 0xd2, 0x29, 0xd1, 0xba, 0xb1, 0xc9, 0xa0, 0x7b, 0xa9, 0xdf, 0x26, 0x29, 0xe9, 0xb1, 0x48, 0x24, 0x64, 0x8e, 0xad, 0xe2, 0x01, 0x74, 0x95, 0x15, 0x0c, 0x09, 0xd5, 0x02, 0xc4, 0x7f, 0x59, 0x64, 0x4e, 0x3c, 0x7a, 0x24, 0xc0, 0xaa, 0xb5, 0xd5, 0x5c, 0xf4, 0x83, 0x7a, 0xed, 0xda, 0x5f, 0x28, 0x37, 0xeb, 0x24, 0x3b, 0x91, 0xb0, 0x77, 0x29, 0x28, 0x14, 0x9d, 0xec, 0x2b, 0x94, 0x72, 0xa7, 0xdb, 0x5b, 0x06, 0xff, 0x3d, 0xef, 0x06, 0xa9, 0x09, 0x64, 0x99, 0x1a, 0x9f, 0xf0, 0xad, 0xd3, 0x5c, 0x34, 0x1c, 0xa0, 0x88, 0x0d, 0x00, 0x6f, 0xb0, 0x16, 0xb8, 0xd8, 0xdb, 0xfa, 0xa1, 0xc4, 0x14, 0xfd, 0x4c, 0x89, 0x6d, 0xea, 0x07, 0xd8, 0xf5, 0x14, 0x6f, 0xae, 0x4d, 0x51, 0x34, 0xa0, 0x9e, 0x15, 0xc3, 0xa4, 0x9b, 0xf7, 0xd8, 0x1c, 0x82, 0x33, 0xdb, 0xa2, 0x86, 0x8b, 0xe2, 0x29, 0x00, 0x8a, 0x22, 0x32, 0xf0, 0xa0, 0x52, 0x6f, 0xd1, 0xce, 0x28, 0xfe, 0x2f, 0x62, 0x96, 0x66, 0x8d, 0xe4, 0xe0, 0x47, 0x0b, 0x47, 0xc6, 0xa5, 0xe1, 0xf7, 0xd5, 0x03, 0x65, 0x6a, 0x20, 0xcf, 0xce, 0xda, 0x90, 0x6e, 0x2b, 0xa4, 0xa1, 0xb5, 0x67, 0xc4, 0xed, 0xa2, 0xfc, 0xa1, 0x20, 0x59, 0xeb, 0x08, 0xf8, 0x3b, 0xf1, 0x74, 0x3b, 0x80, 0x9e, 0x47, 0xcd, 0x59, 0x85,
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA /* example/sb_content_cert.bin */ 0x30, 0x82, 0x04, 0xde, 0x30, 0x82, 0x03, 0x16, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x78, 0x07, 0xcc, 0xe8, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x39, 0x30, 0x32, 0x30, 0x35, 0x31, 0x34, 0x31, 0x31, 0x34, 0x32, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x35, 0x30, 0x33, 0x31, 0x34, 0x32, 0x30, 0x33, 0x39, 0x35, 0x36, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x43, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xdd, 0x30, 0x81, 0xda, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x02, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x63, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x02, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x81, 0x9b, 0x06, 0x03, 0x64, 0x02, 0x04, 0x01, 0x01, 0xff, 0x04, 0x81, 0x90, 0x05, 0x00, 0x00, 0x00, 0x43, 0x62, 0x36, 0x5b, 0xac, 0xdb, 0x25, 0x94, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x00, 0x20, 0x38, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x10, 0x20, 0x38, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x20, 0x20, 0x38, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0x68, 0x77, 0x40, 0xb7, 0xe3, 0x03, 0xef, 0xf3, 0xc9, 0xf0, 0xbd, 0xe0, 0x2d, 0x45, 0xc7, 0x83, 0xff, 0xd3, 0x0a, 0xa0, 0xfe, 0x4d, 0xde, 0xc6, 0xa0, 0x61, 0x8e, 0xba, 0xe5, 0x7b, 0x74, 0x22, 0xdd, 0xbe, 0x53, 0x78, 0x9c, 0x28, 0x02, 0x3a, 0x56, 0xdf, 0x7a, 0x4f, 0x65, 0x57, 0x43, 0x7d, 0x99, 0xa5, 0xe1, 0x23, 0xef, 0x20, 0x7b, 0xb8, 0x96, 0x31, 0x3f, 0xec, 0xb3, 0xb3, 0x61, 0x6e, 0xa6, 0x6c, 0x71, 0x8f, 0x8a, 0x0e, 0x6f, 0xde, 0xaf, 0x6d, 0x20, 0xfb, 0xfb, 0x32, 0xde, 0x30, 0xfe, 0xd5, 0x3a, 0x5b, 0xd5, 0x0b, 0xae, 0xa4, 0x17, 0xb9, 0xee, 0x29, 0xb0, 0x6f, 0xbd, 0x8e, 0xd8, 0x52, 0x9a, 0x2a, 0xd1, 0x28, 0x6b, 0xbf, 0x8f, 0x06, 0x21, 0x3f, 0x4b, 0x12, 0x4e, 0x8f, 0x27, 0xfb, 0x83, 0xe3, 0x3d, 0x95, 0xcf, 0x17, 0x00, 0xdc, 0xcc, 0xf9, 0x91, 0x8f, 0x04, 0xbc, 0x2e, 0xb7, 0x30, 0x70, 0x54, 0x2d, 0xe9, 0xe1, 0x55, 0xae, 0x99, 0x83, 0x81, 0x9c, 0xc6, 0x0c, 0x04, 0x7d, 0x0d, 0x44, 0x4a, 0xb8, 0xe0, 0x67, 0x97, 0x3a, 0xf9, 0x59, 0x33, 0x45, 0x3f, 0x20, 0x0b, 0x5c, 0xc6, 0xcc, 0x1d, 0x0e, 0x71, 0x33, 0xa3, 0x4b, 0x06, 0x65, 0xfc, 0xc2, 0xfb, 0xca, 0x2b, 0x0d, 0xdc, 0x67, 0xb8, 0x9b, 0x28, 0x9b, 0xf0, 0x74, 0xf3, 0x25, 0x5f, 0xd4, 0x27, 0xcb, 0x4b, 0x99, 0x95, 0xb8, 0xe2, 0xb4, 0xec, 0xc3, 0xca, 0x55, 0x7c, 0x96, 0x69, 0x7a, 0x36, 0x20, 0x73, 0x6f, 0x74, 0xdc, 0x47, 0x3e, 0x23, 0xd5, 0x1c, 0xc2, 0x84, 0x43, 0x71, 0xfc, 0xb4, 0x75, 0xb4, 0x68, 0x83, 0x28, 0x5b, 0x1a, 0xd1, 0x6d, 0x44, 0x7a, 0xb0, 0x8f, 0x82, 0xe0, 0x1d, 0x4c, 0x87, 0x74, 0xa4, 0xcf, 0x65, 0xf6, 0x57, 0x11, 0x46, 0xba, 0xb6, 0x70, 0x32, 0xe8, 0x68, 0x9b, 0x8c, 0x86, 0x95, 0x0e, 0xc9, 0xac, 0x5e, 0xcb, 0xbd, 0x9b, 0xe8, 0x5d, 0xde, 0xcf, 0x04, 0x7d, 0xd7, 0x17, 0xb7, 0xa0, 0x4f, 0x3e, 0xef, 0x69, 0xaa, 0x96, 0x31, 0x57, 0x55, 0x07, 0x02, 0x8c, 0xc1, 0xeb, 0x9e, 0xf0, 0xdc, 0x3c, 0x56, 0x0c, 0x17, 0xd0, 0x05, 0x32, 0xf3, 0xd6, 0x59, 0xf3, 0xcc, 0x87, 0xbc, 0x6d, 0x42, 0x58, 0x43, 0x9e, 0x4b, 0xd5, 0x11, 0x17, 0x99, 0xba, 0x57, 0x80, 0xc5, 0xb0, 0x68, 0x56, 0xe1, 0x83, 0x5f, 0x33, 0x65, 0x66, 0x74, 0xe7, 0xb6, 0xfc, 0xe4, 0x6c, 0xaf, 0xf9, 0x12, 0x0d, 0xc9, 0x39, 0x7d, 0x29, 0x4e, 0xa9, 0x19, 0xd2, 0xe1, 0x03, 0xd6, 0x94, 0x04, 0x55, 0x43, 0x7e, 0x4d, 0xce, 0x05, 0x5b, 0xe8, 0x99, 0x26, 0x76, 0x37, 0xa6, 0x3f, 0x59, 0x77, 0x53, 0xd3, 0x23, 0xbc, 0x5e, 0x7e, 0x43, 0xb4, 0x2a, 0x3a, 0x16, 0x20, 0x70, 0x3b, 0x6f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA /* example/sb_image1_enc.bin */ 0x8d, 0xe5, 0xa3, 0x63, 0xfc, 0x4e, 0x84, 0x0e, 0xc2, 0x58, 0x36, 0x41, 0x70, 0x76, 0x7c, 0xde, 0xa0, 0x5f, 0x52, 0xcc, 0xd3, 0x52, 0xf9, 0xdc, 0xed, 0xef, 0x62, 0x1b, 0x23, 0x62, 0x87, 0xb0, 0xdc, 0x59, 0x58, 0x10, 0x97, 0x90, 0xb1, 0xbc, 0x76, 0xf3, 0xad, 0x0c, 0xb0, 0xd2, 0xdc, 0x18, 0x42, 0x7f, 0xbc, 0x66, 0xe7, 0x77, 0xf6, 0xcd, 0xc9, 0x94, 0x04, 0x0a, 0x3f, 0x84, 0x98, 0x05, 0x6e, 0x0e, 0x11, 0xc4, 0xbb, 0x06, 0xb2, 0xc9, 0x7f, 0x12, 0x4b, 0xd9, 0xce, 0x4d, 0x66, 0x3b, 0x8b, 0x26, 0x24, 0xe7, 0x85, 0xe2, 0xc5, 0xf2, 0xdf, 0xd1, 0x75, 0xf2, 0x94, 0xea, 0x75, 0x3b, 0xaa, 0x6d, 0x15, 0x68, 0xe8, 0x35, 0x18, 0x83, 0x02, 0x6c, 0x96, 0x4b, 0xb2, 0x8d, 0x17, 0xa6,
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA /* example/sb_image2_enc.bin */ 0x9f, 0x5e, 0xa3, 0xf1, 0x8e, 0x5d, 0x0f, 0x23, 0x4d, 0x3d, 0x57, 0x33, 0xc9, 0x4c, 0x03, 0x58, 0xaf, 0xc8, 0x45, 0x90, 0xa6, 0xf1, 0x5c, 0x06, 0xee, 0x3a, 0xa6, 0x27, 0x05, 0xfb, 0x34, 0xa9, 0x4e, 0xb3, 0xbc, 0xc4, 0x8f, 0xb9, 0xdf, 0xdd, 0x84, 0x76, 0x05, 0xc1, 0x7b, 0x82, 0x4d, 0x63, 0xe0, 0x66, 0xd6, 0xde, 0x10, 0x3b, 0xcb, 0x72, 0xac, 0xa0, 0x74, 0x0f, 0xaf, 0x2f, 0xf2, 0xbc, 0xcb, 0x6e, 0x41, 0xab, 0x1e, 0xd8, 0x4b, 0xa9, 0xdd, 0x67, 0x03, 0x54, 0x83, 0xdb, 0xd7, 0xe8, 0x74, 0x3b, 0xe3, 0x77, 0xc2, 0xce, 0x66, 0x0e, 0x2d, 0x72, 0xcf, 0x2d, 0x91, 0x90, 0xe1, 0xd5, 0x27, 0xca, 0x37, 0xae, 0x94, 0xe1, 0x76, 0xac, 0x36, 0xcb, 0x66, 0xe7, 0xa6, 0x50, 0x8f, 0x92,
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA /* example/sb_image3_enc.bin */ 0x69, 0x92, 0xf9, 0xf3, 0x31, 0x75, 0x0a, 0xf1, 0x62, 0x3e, 0xb9, 0x33, 0x84, 0x25, 0xea, 0x5c, 0x9c, 0x66, 0x35, 0x3b, 0x33, 0x01, 0x30, 0xc9, 0x7a, 0x85, 0xac, 0x63, 0xee, 0x49, 0x39, 0xd4, 0x75, 0xd6, 0xde, 0xe0, 0xc7, 0x79, 0x4d, 0x01, 0xf4, 0x46, 0xff, 0x92, 0x0d, 0xec, 0x75, 0xa5, 0x15, 0x28, 0xab, 0x3d, 0x53, 0x7e, 0xa8, 0xa3, 0xbd, 0xf1, 0x93, 0x7e, 0x8a, 0xa1, 0xbe, 0x06, 0xaf, 0x2f, 0x2d, 0x9f, 0xd0, 0x2a, 0x7c, 0x60, 0x43, 0x5b, 0xe7, 0x05, 0x57, 0x15, 0xf1, 0xdf, 0x19, 0xc4, 0x22, 0x2d, 0x71, 0x14, 0x58, 0x52, 0x74, 0x28, 0xc0, 0x44, 0x46, 0xf2, 0xee, 0x95, 0x0a, 0x17, 0x80, 0x2f, 0xd1, 0x36, 0xf6, 0xd5, 0xd2, 0xb7, 0x14, 0x33, 0x3a, 0xef, 0xce, 0xc7,
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA_LENGTH /* sb_key_cert1_hbk0.bin */ 1138
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA_LENGTH /* sb_key_cert2_hbk0.bin */ 1139
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH /* sb_content_cert.bin */ 1276
+#else
+/************************************/
+/*          MPS2 CM33 NOT_X509      */
+/************************************/
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA /* example/sb_key_cert1_hbk0.bin */ 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x68, 0x9a, 0xdf, 0x7a, 0x7f, 0x80, 0xad, 0xe1, 0xf1, 0x7d, 0xed, 0xbd, 0x3a, 0x23, 0xc6, 0x80, 0x87, 0x8d, 0x10, 0xf9, 0x99, 0x82, 0x6b, 0xbc, 0xec, 0x41, 0xaa, 0x94, 0xba, 0xcb, 0xbb, 0x6a, 0x59, 0xb2, 0x34, 0x41, 0x6b, 0x26, 0xf2, 0xb7, 0x5f, 0x96, 0xb0, 0x59, 0x93, 0xa9, 0x69, 0x8b, 0xac, 0x5c, 0x14, 0xb2, 0x51, 0xa8, 0x45, 0x2c, 0xd4, 0xe2, 0xfc, 0x37, 0xaf, 0x48, 0x16, 0x9f, 0x7e, 0xad, 0x37, 0x17, 0x0a, 0x2b, 0xc9, 0x2f, 0xf1, 0x5b, 0xdc, 0x78, 0xcf, 0x80, 0x92, 0xe4, 0xd8, 0x68, 0xb2, 0xc7, 0xd0, 0x4e, 0x9b, 0x66, 0x6e, 0x0a, 0x7a, 0xf7, 0x53, 0x60, 0x2e, 0x5e, 0xc6, 0x42, 0xa5, 0xdb, 0x94, 0xd1, 0x67, 0xde, 0x1f, 0x5d, 0xe3, 0x5e, 0x4b, 0x9d, 0xb8, 0x23, 0x3e, 0xdd, 0x79, 0xd8, 0xac, 0xf9, 0xd4, 0xbe, 0x77, 0xf1, 0xae, 0x8b, 0xbb, 0x94, 0xc7, 0xf8, 0xe8, 0xcc, 0x3a, 0xdb, 0x76, 0x8b, 0xb8, 0x5d, 0x99, 0x83, 0x29, 0x11, 0xe2, 0xfc, 0x38, 0x0d, 0x65, 0x95, 0x41, 0xbb, 0xd2, 0x8c, 0x77, 0x1b, 0x31, 0xb4, 0xb4, 0xb9, 0x4a, 0x59, 0x70, 0x72, 0x65, 0xb0, 0x32, 0xb8, 0x34, 0xd0, 0x4e, 0x62, 0x65, 0x9e, 0xfb, 0x49, 0x76, 0x64, 0x2f, 0x48, 0xe2, 0xe5, 0x00, 0xd7, 0xd1, 0xd4, 0xf4, 0xf6, 0x58, 0xc0, 0x04, 0x93, 0xee, 0x60, 0xd6, 0x94, 0xcd, 0xc5, 0x01, 0xc5, 0x77, 0xf7, 0xa0, 0xc7, 0xc3, 0x10, 0x5b, 0xdd, 0x36, 0x1f, 0x37, 0x07, 0xb1, 0x60, 0xef, 0x32, 0x7c, 0x86, 0xc3, 0xd7, 0x2a, 0x19, 0xfd, 0xac, 0xea, 0x2c, 0x34, 0x40, 0x8d, 0xdf, 0x78, 0x7e, 0xcf, 0xc7, 0xeb, 0x7d, 0x41, 0x25, 0xd3, 0x0d, 0x14, 0x5a, 0xdf, 0x90, 0xea, 0x8b, 0x68, 0xc3, 0x32, 0xaf, 0x53, 0xcf, 0x11, 0x24, 0x64, 0xbf, 0xf6, 0xf8, 0xdb, 0x09, 0x4e, 0xae, 0xbb, 0x32, 0x13, 0x9b, 0xc4, 0x90, 0xa7, 0x46, 0xc0, 0xe3, 0x88, 0xb7, 0x36, 0x78, 0x02, 0xab, 0x67, 0x61, 0x34, 0x17, 0x01, 0xc0, 0xe3, 0xc6, 0x2d, 0xfb, 0x3e, 0x5d, 0xf8, 0xd8, 0x43, 0x57, 0x4c, 0x84, 0x40, 0x21, 0x97, 0xc5, 0xe4, 0x06, 0x74, 0x3f, 0xa3, 0x22, 0x35, 0x48, 0x87, 0x33, 0xd8, 0xc5, 0x53, 0x76, 0x98, 0x0d, 0x02, 0x07, 0x48, 0x15, 0xf5, 0xf6, 0xb8, 0x56, 0x53, 0x08, 0x1c, 0xfe, 0xb4, 0x77, 0x4d, 0x9c, 0xa6, 0x1c, 0x99, 0xbb, 0x2b, 0x03, 0x03, 0xf3, 0x0c, 0x32, 0x84, 0x0f, 0x96, 0x67, 0x1a, 0x0d, 0x73, 0x13, 0xbc, 0x0c, 0xe4, 0x34, 0x41, 0x18, 0xb8, 0x09, 0x55, 0x2d, 0xe5, 0x75, 0x47, 0x03, 0xa3, 0xb2, 0xf2, 0x59, 0x94, 0x81, 0x27, 0x85, 0x98, 0x83, 0x94, 0x81, 0xc4, 0x8d, 0xc8, 0x80, 0xd6, 0xa9, 0xae, 0x02, 0x44, 0x45, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x4d, 0xe1, 0xc6, 0x58, 0x5c, 0x3d, 0x03, 0x7a, 0x05, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x27, 0x57, 0xa3, 0x16, 0x94, 0xa1, 0x75, 0x74, 0xec, 0x9f, 0x91, 0x7a, 0xdf, 0x09, 0xe9, 0x52, 0x1e, 0xce, 0x17, 0x3a, 0xd4, 0x1c, 0xfc, 0x75, 0x6e, 0x87, 0x09, 0x77, 0x53, 0x31, 0x79, 0x11, 0xb0, 0xc1, 0xed, 0x38, 0x8d, 0x81, 0x15, 0x4d, 0x14, 0xf4, 0xd7, 0x9e, 0x8b, 0x4f, 0x0b, 0x62, 0x48, 0x5f, 0x8c, 0x78, 0x71, 0x9f, 0x1b, 0xca, 0x89, 0xb6, 0x3b, 0x62, 0x21, 0xeb, 0x3a, 0xd5, 0x8f, 0xee, 0x34, 0xdc, 0x38, 0xf9, 0xfc, 0x6f, 0x8c, 0xa4, 0xf9, 0xaa, 0x85, 0x30, 0x09, 0x3e, 0x31, 0x21, 0x1a, 0xc7, 0xb4, 0x1c, 0xfa, 0x68, 0x3e, 0xa2, 0xee, 0x68, 0xc3, 0xb7, 0x40, 0xe5, 0xb0, 0x73, 0xb8, 0x20, 0x4c, 0xa8, 0xb3, 0x31, 0x05, 0x18, 0x7e, 0x59, 0x31, 0xdf, 0x2b, 0xa7, 0xfb, 0xdd, 0x8a, 0x6e, 0x6d, 0x0a, 0x43, 0x76, 0x76, 0xa1, 0x52, 0xf1, 0xbe, 0x6a, 0x59, 0x33, 0xef, 0x44, 0x5a, 0x1a, 0xe3, 0x02, 0xe6, 0x60, 0xfc, 0xae, 0xee, 0xe6, 0x09, 0xb7, 0xbb, 0xce, 0xe0, 0x18, 0xba, 0x68, 0xd1, 0x04, 0xd3, 0x21, 0x9f, 0xe9, 0x12, 0xe0, 0x99, 0x5b, 0x76, 0xc2, 0x4d, 0x91, 0x6a, 0x70, 0xe0, 0x4d, 0x5d, 0x09, 0x0a, 0x8b, 0x75, 0x1e, 0x5c, 0xc9, 0x99, 0x23, 0x08, 0xe6, 0xb5, 0xc4, 0x56, 0x46, 0x5d, 0x9f, 0x51, 0x82, 0xa6, 0x0d, 0x91, 0x3a, 0xc2, 0x2f, 0xa1, 0xa3, 0x5a, 0x3d, 0xe9, 0x65, 0x0f, 0x04, 0x3d, 0x9c, 0xcc, 0x67, 0x90, 0xab, 0x6a, 0xba, 0x58, 0xfa, 0x49, 0x0d, 0x68, 0xd6, 0x69, 0x60, 0x1a, 0x9a, 0xa6, 0x03, 0xe2, 0xcc, 0x89, 0xae, 0xca, 0xb5, 0x27, 0x7b, 0x37, 0x00, 0x03, 0x9c, 0x83, 0x1a, 0x79, 0xbd, 0xc3, 0x8c, 0x31, 0xfd, 0x11, 0x25, 0xfc, 0x25, 0x53, 0x53, 0xfe, 0x3b, 0x58, 0xab, 0x60, 0xd6, 0x71, 0xb3, 0x1a, 0x62, 0x19, 0xe7, 0x56, 0x3c, 0x15, 0xbc, 0xef, 0x03, 0x09, 0x71, 0x57, 0xbb, 0x0e, 0xe9, 0x1b, 0xfe, 0x16, 0xdb, 0xf9, 0x31, 0x0e, 0x95, 0xa6, 0x46, 0x8d, 0xdd, 0x32, 0x9f, 0x53, 0xb9, 0x91, 0xd9, 0xa1, 0xc8, 0x02, 0xaa, 0x06, 0x89, 0xd5, 0x7f, 0x2b, 0x5e, 0x53, 0xd8, 0x02, 0x98, 0xee, 0xfc, 0x82, 0xe1, 0x0c, 0xd5, 0x10, 0xb1, 0xe3, 0x64, 0x1d, 0xe6, 0xcb, 0xd1, 0xc9, 0x50, 0xf3, 0x53, 0x4e, 0x45, 0x2f, 0x97, 0x37, 0x43, 0x8d, 0x62, 0x0b, 0xc9, 0x16, 0x58, 0x66, 0x73, 0x43, 0x14, 0xc1, 0x90, 0xc1, 0x3e, 0xe6, 0xb6, 0x75, 0xc3, 0xb6, 0x6b, 0x27, 0x9b, 0x3a, 0x0d, 0x9a, 0xfb, 0x10, 0x7d, 0x3b, 0x96, 0x6d, 0x74, 0x4b, 0x71, 0x55, 0x3b, 0x9b, 0xa6, 0xaa, 0xb9, 0x3b, 0x09, 0x4d, 0x5b, 0x73, 0x5c, 0x6d, 0xee, 0xb6, 0xb4, 0x9e, 0x84, 0x68, 0x85, 0x70, 0x2d, 0xbc, 0x15,
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA /* example/sb_key_cert2_hbk0.bin */ 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x05, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x21, 0xa9, 0x33, 0x43, 0xa6, 0x82, 0x14, 0xea, 0x98, 0x86, 0x40, 0x71, 0x08, 0x47, 0x19, 0x3e, 0xba, 0x21, 0x64, 0xe5, 0xd2, 0x74, 0xa2, 0xdc, 0x93, 0xa8, 0x2f, 0x14, 0x71, 0xee, 0x7d, 0x7b, 0x1b, 0xba, 0x69, 0x93, 0xde, 0xf7, 0xa9, 0xbd, 0xfe, 0xc1, 0x0c, 0xcc, 0x29, 0xf7, 0x36, 0xa1, 0x03, 0x7e, 0xdb, 0xb1, 0x56, 0x67, 0xa0, 0xec, 0xaf, 0x05, 0x64, 0xcb, 0x15, 0x0f, 0xd1, 0xdb, 0xd5, 0x58, 0xcd, 0x38, 0x71, 0xed, 0xd8, 0x66, 0xa0, 0xb6, 0x45, 0xaf, 0x21, 0x94, 0x0d, 0xdc, 0xbf, 0x98, 0x8e, 0x6b, 0x94, 0xf6, 0xd5, 0x90, 0xe5, 0xd0, 0xa7, 0xcd, 0x78, 0x0a, 0x2c, 0xf7, 0x00, 0xb7, 0x1c, 0x5c, 0xc1, 0x7e, 0x5f, 0x0f, 0x94, 0xec, 0xac, 0xbc, 0xf0, 0x25, 0x6a, 0xd3, 0xc9, 0x0d, 0x4e, 0xf3, 0xee, 0x9d, 0xdd, 0xab, 0x12, 0x71, 0x5b, 0xed, 0x3c, 0xcb, 0x04, 0x64, 0x0a, 0x42, 0xf2, 0x10, 0xf8, 0x0d, 0x7e, 0xfe, 0x7f, 0x9a, 0xf7, 0x4e, 0xc8, 0x43, 0x54, 0xbe, 0x2c, 0x2e, 0xc7, 0x66, 0x04, 0xa7, 0xc9, 0xad, 0x71, 0xc4, 0x19, 0x96, 0x96, 0x7b, 0xc3, 0xec, 0xc5, 0x01, 0xf6, 0x32, 0xe0, 0x34, 0x60, 0x0b, 0x53, 0xbd, 0x96, 0x21, 0x3a, 0xb9, 0x47, 0xe2, 0x1f, 0x4b, 0xad, 0xbd, 0x92, 0xc7, 0xd8, 0x12, 0xaa, 0x65, 0x7c, 0xea, 0xae, 0x7b, 0xc9, 0x32, 0xb1, 0x5c, 0x48, 0x6c, 0xe9, 0xec, 0xc4, 0xa2, 0x64, 0xfe, 0x7a, 0x49, 0xd6, 0x8c, 0xbe, 0xb3, 0x8b, 0xac, 0x47, 0xd2, 0xc9, 0xfc, 0xd6, 0xbb, 0x11, 0x13, 0x99, 0x1d, 0x82, 0xee, 0xe2, 0x26, 0xf0, 0x9c, 0xcf, 0x64, 0x9a, 0x5b, 0x8b, 0x1b, 0x9a, 0x7e, 0x1c, 0xbd, 0x70, 0xac, 0x47, 0x23, 0x15, 0xdf, 0x07, 0x1f, 0x48, 0x09, 0x49, 0xc1, 0x5d, 0x2a, 0x15, 0x96, 0x62, 0xb4, 0x2d, 0x9c, 0x87, 0x7a, 0x60, 0x4e, 0x7c, 0x96, 0xf7, 0x99, 0x49, 0xe1, 0x5a, 0x2f, 0x07, 0x10, 0x7f, 0xda, 0x75, 0xf9, 0x77, 0x4e, 0x6f, 0xe7, 0x92, 0x0e, 0xc7, 0xae, 0x95, 0x3f, 0xb6, 0xfa, 0x8a, 0x0f, 0xe2, 0xef, 0xd8, 0xe5, 0xd5, 0x8d, 0x37, 0xd0, 0x11, 0x8d, 0x70, 0x69, 0x64, 0xa2, 0x79, 0x83, 0xde, 0xf1, 0xce, 0x93, 0x13, 0x72, 0xdb, 0x63, 0x4f, 0xdb, 0x8d, 0x08, 0x4f, 0x15, 0xef, 0xc8, 0x84, 0x00, 0xf9, 0x77, 0x33, 0x2d, 0x17, 0xa5, 0x9a, 0x35, 0xcb, 0x55, 0xa1, 0x8f, 0xc7, 0x60, 0xe3, 0x4e, 0xa7, 0x8b, 0xad, 0xef, 0xf6, 0x68, 0x5f, 0x3e, 0x5d, 0x35, 0xb2, 0x61, 0x20, 0x54, 0x9a, 0xda, 0x08, 0x39, 0x16, 0x3b, 0x34, 0x83, 0x10, 0x02, 0x36, 0x54, 0xa1, 0x4d, 0x4d, 0x5f, 0x9e, 0x78, 0x23, 0x1f, 0x2d, 0x8d, 0xb1, 0x6e, 0x41, 0x8e, 0xc9, 0x62, 0x99, 0x01, 0x55, 0x91,
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA /* example/sb_content_cert.bin */ 0x63, 0x63, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x03, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x05, 0x00, 0x00, 0x00, 0xef, 0xcc, 0x12, 0xe8, 0x10, 0x6e, 0x6c, 0x48, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x00, 0x20, 0x38, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x10, 0x20, 0x38, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x20, 0x20, 0x38, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x41, 0xef, 0x38, 0x53, 0xaf, 0x5c, 0xd2, 0xbb, 0x25, 0x87, 0x0e, 0xc6, 0xb4, 0x87, 0x9b, 0xc1, 0x02, 0x83, 0xee, 0x36, 0x4c, 0xb0, 0x11, 0x98, 0xe5, 0x23, 0x5d, 0xaf, 0xa8, 0xda, 0x25, 0x65, 0xd4, 0x8f, 0xd8, 0x74, 0xc2, 0x2c, 0x99, 0x93, 0xfa, 0x78, 0x73, 0x2f, 0x6b, 0x09, 0xce, 0x23, 0xf1, 0x64, 0xc8, 0x7b, 0x0a, 0x70, 0x54, 0x90, 0x43, 0x5b, 0xa7, 0x20, 0xa4, 0xa4, 0xf6, 0x1d, 0x97, 0x92, 0xcf, 0x24, 0xb7, 0x2d, 0x83, 0xdd, 0x5f, 0xc8, 0x3d, 0xeb, 0x5e, 0x24, 0xb7, 0x46, 0xd8, 0xd8, 0xd8, 0xaa, 0xeb, 0xe6, 0x92, 0x12, 0x48, 0xcf, 0x9c, 0x6e, 0x70, 0xaa, 0x1b, 0x6c, 0xc8, 0x41, 0xb2, 0xae, 0x87, 0xf2, 0x20, 0x70, 0x44, 0x05, 0x3e, 0xf2, 0x0a, 0x88, 0x90, 0xe8, 0xc8, 0xf9, 0x7c, 0xa4, 0x63, 0xe0, 0xa3, 0x83, 0x69, 0x33, 0xb3, 0x0b, 0xad, 0x4f, 0x72, 0xf6, 0xe5, 0x78, 0xfb, 0x73, 0xe3, 0xb3, 0xf9, 0x2c, 0x0f, 0xf4, 0x2c, 0xf6, 0xd5, 0x10, 0x12, 0xa3, 0x0d, 0x78, 0xe7, 0x75, 0x73, 0x11, 0x31, 0x3e, 0xab, 0xdd, 0xd6, 0x8b, 0x88, 0x90, 0x58, 0x2e, 0xc1, 0x1f, 0x49, 0x6a, 0x5d, 0xf1, 0xb1, 0xb8, 0x5f, 0x55, 0x77, 0x80, 0x66, 0x4b, 0xf2, 0x05, 0xa5, 0x15, 0x2d, 0x47, 0x23, 0x41, 0xab, 0x69, 0x3b, 0x11, 0xbe, 0x89, 0xea, 0x6e, 0x5f, 0x78, 0x60, 0x01, 0x9b, 0xca, 0xbc, 0xfd, 0x65, 0xf7, 0xa3, 0x71, 0x52, 0x53, 0xc5, 0xb0, 0xe3, 0x45, 0xce, 0x16, 0x08, 0xe0, 0xa5, 0xca, 0x5d, 0xe1, 0x8d, 0x4b, 0xc9, 0x6c, 0x04, 0xda, 0x90, 0x65, 0xb7, 0xfc, 0x2a, 0x85, 0xef, 0xbd, 0x13, 0x03, 0xc8, 0xff, 0x73, 0x55, 0x75, 0x89, 0x61, 0x2d, 0xab, 0x9a, 0xb3, 0x3c, 0x16, 0x4f, 0x79, 0x65, 0xf9, 0x1b, 0xc1, 0x96, 0x95, 0xc3, 0xe0, 0xa3, 0xb6, 0xd6, 0x05, 0xd3, 0x24, 0x7c, 0x8b, 0x5d, 0x72, 0x7f, 0x01, 0xdf, 0x84, 0xdb, 0x06, 0x81, 0xb9, 0x53, 0x2e, 0x9e, 0xc7, 0x7f, 0x73, 0xda, 0xe9, 0xa0, 0x3f, 0x03, 0x44, 0xf5, 0x43, 0x0d, 0x6c, 0xa3, 0x60, 0x72, 0x9e, 0x8a, 0xaa, 0x57, 0x21, 0x27, 0x36, 0xae, 0xe2, 0x02, 0x96, 0xd2, 0x6f, 0x97, 0x7f, 0x0b, 0x70, 0x98, 0xa3, 0xc2, 0xae, 0xbb, 0x07, 0xc5, 0x30, 0xea, 0xf5, 0x82, 0x07, 0x70, 0xc6, 0xa8, 0x92, 0xeb, 0x0a, 0x1e, 0x73, 0x5c, 0x65, 0x60, 0xef, 0x44, 0x22, 0x6a, 0xb2, 0x7a, 0x19, 0x77, 0xc8, 0xf4, 0xea, 0xb1, 0x00, 0x6c, 0x5a, 0x31, 0x9b, 0xa7, 0x25, 0x94, 0xaa, 0x4e, 0xa4, 0x52, 0xd5, 0x51, 0x6d, 0x7d, 0x16, 0xfe, 0x84, 0xd2, 0x8d, 0x92, 0x12, 0x4a, 0x76, 0xd7, 0x14, 0xed, 0xf3, 0x15, 0xb2, 0xab, 0x0b, 0xec, 0x29, 0x67, 0x51, 0xda, 0x7e, 0xa3, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA /* example/sb_image1_enc.bin */ 0x0f, 0xa7, 0xd2, 0xa6, 0x8f, 0x5f, 0x7f, 0x82, 0x86, 0xa8, 0xa2, 0x02, 0x37, 0xd0, 0x38, 0xc5, 0x94, 0x5e, 0x44, 0xb2, 0x37, 0x3a, 0xd4, 0x47, 0xcd, 0x23, 0x57, 0xc7, 0x70, 0x57, 0xb2, 0x0e, 0x26, 0x4c, 0x59, 0x8f, 0x5c, 0xf4, 0xf3, 0xc5, 0xcb, 0x4e, 0xbb, 0x57, 0x54, 0x23, 0x6b, 0xab, 0x11, 0x53, 0x26, 0x1d, 0x88, 0x1f, 0xd9, 0x51, 0x9c, 0x91, 0x6a, 0xf6, 0xaa, 0x78, 0xde, 0x15, 0x06, 0x99, 0x65, 0xbf, 0x75, 0xab, 0x32, 0xdc, 0xde, 0x37, 0x5f, 0x67, 0x34, 0x93, 0xc7, 0x61, 0xa6, 0x89, 0x4d, 0xe9, 0x6d, 0x87, 0x36, 0xb4, 0x2f, 0xd3, 0x9a, 0xae, 0x3f, 0x43, 0x6a, 0x70, 0x72, 0x9f, 0xf2, 0x13, 0xc9, 0xc3, 0x9f, 0x85, 0xd5, 0x45, 0xbc, 0x03, 0xa4, 0xd4, 0x58, 0xac,
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA /* example/sb_image2_enc.bin */ 0xbf, 0x8b, 0x7d, 0xed, 0x8a, 0x6b, 0x00, 0x12, 0x00, 0xe1, 0x0b, 0xb6, 0xd1, 0xc3, 0x01, 0x1d, 0x5f, 0x7d, 0x00, 0xf8, 0xf3, 0x45, 0x42, 0xc0, 0xab, 0x0b, 0xd3, 0x53, 0x9c, 0x1f, 0xfb, 0xed, 0x33, 0x90, 0x19, 0xe5, 0xd7, 0x1a, 0x6c, 0x62, 0x49, 0xdb, 0xf4, 0x11, 0x5d, 0xa4, 0x8d, 0x19, 0xf4, 0xc3, 0xe7, 0xa6, 0x23, 0x0e, 0x9a, 0x0e, 0x11, 0x91, 0x8c, 0xa0, 0x7d, 0x8c, 0x06, 0x23, 0x10, 0x7d, 0xca, 0x38, 0x00, 0x18, 0xfe, 0x88, 0x38, 0xb1, 0xa0, 0x15, 0x63, 0x52, 0x7f, 0xf4, 0x28, 0x1c, 0xe5, 0x3b, 0x23, 0x7a, 0x30, 0x40, 0xee, 0xb2, 0xbb, 0x13, 0x9f, 0x5b, 0x05, 0x38, 0x98, 0xa1, 0x50, 0x46, 0x5c, 0x3f, 0x42, 0xde, 0x61, 0xd6, 0x4c, 0x3f, 0xf3, 0x26, 0x57, 0x6c,
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA /* example/sb_image3_enc.bin */ 0xbc, 0xa9, 0xa1, 0x6e, 0x2c, 0x58, 0xb7, 0x6e, 0x2b, 0x70, 0x39, 0x5c, 0xd6, 0xdc, 0x5f, 0x55, 0xa8, 0xe3, 0x58, 0x98, 0xaf, 0x38, 0xa8, 0xcf, 0x28, 0x0b, 0x34, 0xb4, 0x5e, 0xd6, 0x35, 0x62, 0x25, 0x07, 0xd8, 0x69, 0x33, 0x67, 0x9d, 0xdc, 0x5b, 0xfc, 0xe8, 0xb1, 0xc6, 0xea, 0x77, 0x96, 0x6a, 0x85, 0xec, 0xc7, 0x23, 0x3e, 0xd9, 0x1a, 0x8c, 0xb3, 0x8c, 0xe3, 0xe9, 0x8b, 0x27, 0xe7, 0x75, 0x50, 0x01, 0x69, 0x04, 0xcf, 0xf3, 0xc7, 0x03, 0xb5, 0x31, 0x6b, 0x1d, 0x1a, 0xfb, 0xf0, 0x5f, 0xda, 0xcf, 0xaf, 0xfc, 0x62, 0x91, 0xad, 0xea, 0x1c, 0x6b, 0x10, 0xef, 0x33, 0xad, 0xce, 0x12, 0x6b, 0x88, 0xb1, 0x47, 0xfd, 0x4e, 0x40, 0x53, 0x88, 0x51, 0x02, 0xeb, 0xbd, 0x4e, 0xf0,
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA_LENGTH /* sb_key_cert1_hbk0.bin */ 840
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA_LENGTH /* sb_key_cert2_hbk0.bin */ 840
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH /* sb_content_cert.bin */ 972
+#endif /* defined(CC_SB_X509_CERT_SUPPORTED) */
+#else
+#if defined(CC_SB_X509_CERT_SUPPORTED)
+/************************************/
+/*          MPS2 CM3 X509           */
+/************************************/
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA /* extended_example/sb_key1_cert_test_10.bin */ 0x30, 0x82, 0x04, 0x6e, 0x30, 0x82, 0x02, 0xa6, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x32, 0x53, 0x49, 0x84, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x30, 0x38, 0x35, 0x33, 0x33, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x34, 0x30, 0x33, 0x30, 0x33, 0x31, 0x35, 0x32, 0x31, 0x35, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x4b, 0x65, 0x79, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6e, 0x30, 0x6c, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x2e, 0x06, 0x03, 0x64, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x24, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0xb3, 0x4b, 0xa0, 0xf2, 0x93, 0x2e, 0x2f, 0xa3, 0xd7, 0x14, 0x3f, 0xd4, 0x96, 0xab, 0xc7, 0x5f, 0x1d, 0xad, 0x9a, 0x15, 0xf6, 0x9b, 0x2e, 0xca, 0x6e, 0x01, 0xce, 0xc3, 0xb4, 0x60, 0xfb, 0x53, 0x7c, 0xf6, 0xf0, 0x78, 0x14, 0xd0, 0x7b, 0xb8, 0x10, 0x19, 0x7c, 0x4e, 0x77, 0xb9, 0xd0, 0x6e, 0xb4, 0x78, 0x1a, 0xe2, 0x6a, 0x2d, 0x0b, 0x11, 0xd2, 0x74, 0xa2, 0x60, 0xbf, 0x37, 0x1f, 0x48, 0x9c, 0xaa, 0xc4, 0x60, 0x64, 0x43, 0xe1, 0x54, 0xb0, 0xa5, 0x5c, 0xf9, 0xaa, 0x15, 0xd0, 0xac, 0x67, 0x11, 0x54, 0xae, 0x07, 0x10, 0x93, 0xea, 0x88, 0x9a, 0x98, 0xfd, 0x8d, 0xcb, 0xaf, 0x21, 0x41, 0x9c, 0xcc, 0x0c, 0x21, 0x89, 0xaa, 0xc2, 0x89, 0xa9, 0x58, 0x28, 0x04, 0x10, 0xdb, 0x14, 0x32, 0x97, 0x86, 0xc9, 0x24, 0x65, 0xe0, 0x92, 0x40, 0x28, 0x29, 0xf5, 0x95, 0xe7, 0x59, 0x19, 0x58, 0x08, 0xf8, 0x32, 0x76, 0x35, 0x0b, 0xcb, 0xed, 0xbc, 0xd6, 0xef, 0x26, 0x8c, 0x7c, 0x2e, 0x1f, 0xc5, 0xe8, 0xd1, 0xd8, 0x68, 0xc6, 0x15, 0x22, 0x4b, 0xe8, 0x58, 0x63, 0x32, 0x92, 0xe3, 0x68, 0xfc, 0x1b, 0xb9, 0xf6, 0x23, 0x3a, 0xce, 0xaf, 0x1c, 0x46, 0x49, 0x24, 0xdd, 0xaa, 0xc9, 0x7f, 0x47, 0x78, 0x0c, 0x6d, 0xe8, 0x99, 0xbe, 0x31, 0x31, 0x6b, 0x6d, 0xfa, 0x2b, 0x97, 0xc5, 0xd9, 0xe0, 0xda, 0x74, 0x35, 0xff, 0x83, 0x23, 0xbe, 0xc2, 0xc0, 0x5e, 0x89, 0xab, 0x22, 0xd9, 0x5c, 0xdb, 0x50, 0x00, 0x7e, 0x6b, 0x15, 0x57, 0xd8, 0xc6, 0xeb, 0xe7, 0x10, 0x94, 0x07, 0x9b, 0x42, 0x4f, 0xe5, 0x3b, 0x9b, 0x66, 0x21, 0xa9, 0xe6, 0xf8, 0x40, 0xc1, 0x7e, 0x11, 0xef, 0xdb, 0x00, 0x2b, 0x8a, 0x26, 0xbc, 0x9b, 0xbc, 0x57, 0x18, 0xb0, 0x8e, 0xb2, 0x63, 0xd0, 0x0a, 0x65, 0x9e, 0xd9, 0xba, 0x56, 0x91, 0xdf, 0x35, 0xc7, 0x8a, 0xd9, 0x3a, 0xaf, 0x7a, 0xad, 0x1a, 0x24, 0x87, 0xb2, 0x8c, 0x37, 0x5e, 0xa3, 0xb2, 0x60, 0xb9, 0x42, 0x02, 0xc8, 0x11, 0x48, 0xcb, 0xe9, 0x26, 0xfe, 0x3f, 0xe1, 0x81, 0xed, 0x83, 0x46, 0x5d, 0x1b, 0xcd, 0x95, 0xc8, 0x6d, 0x5c, 0xa6, 0x93, 0x7d, 0xb6, 0x11, 0x95, 0xc7, 0x94, 0x20, 0x82, 0x0c, 0xd7, 0xc8, 0x33, 0x47, 0x6d, 0xa6, 0x40, 0xb3, 0xa0, 0x7f, 0x69, 0x41, 0x7b, 0xce, 0xd0, 0x17, 0xa9, 0x8c, 0x27, 0xbb, 0x02, 0x4c, 0x3c, 0x56, 0x3c, 0xb4, 0x33, 0x3a, 0xe0, 0x22, 0x7d, 0xb8, 0xa0, 0x95, 0xe5, 0x44, 0x20, 0xb4, 0xc1, 0xea, 0x92, 0xfb, 0x26, 0x27, 0x4f, 0x2e, 0x2a, 0xac, 0x97, 0xe7, 0x81, 0x0e, 0x41, 0x84, 0xee, 0x26, 0x46, 0xc3, 0x4f, 0x34, 0x7d, 0x44, 0x67, 0x53, 0x23, 0x50, 0x64, 0x26, 0x7b, 0x6b,
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA /* extended_example/sb_key2_cert_test_10.bin */ 0x30, 0x82, 0x04, 0x6f, 0x30, 0x82, 0x02, 0xa7, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x05, 0x00, 0xd5, 0x96, 0x2d, 0xc6, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x30, 0x38, 0x35, 0x33, 0x33, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x34, 0x30, 0x33, 0x30, 0x33, 0x31, 0x35, 0x32, 0x31, 0x35, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x4b, 0x65, 0x79, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x6e, 0x30, 0x6c, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x2e, 0x06, 0x03, 0x64, 0x01, 0x03, 0x01, 0x01, 0xff, 0x04, 0x24, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0x3d, 0x5a, 0x36, 0x91, 0xc5, 0x87, 0x72, 0x89, 0x35, 0xff, 0x9f, 0xf2, 0x63, 0x59, 0xc5, 0xc6, 0xc8, 0xb5, 0xef, 0x07, 0xf6, 0xe1, 0x05, 0xdf, 0x30, 0x1b, 0xfe, 0x6e, 0x0f, 0xb5, 0x53, 0x71, 0xd1, 0xf7, 0x51, 0xfc, 0xc2, 0xf5, 0xfc, 0x22, 0x41, 0xd1, 0xb0, 0x56, 0x22, 0xf2, 0xdd, 0x96, 0xaf, 0xc7, 0xf8, 0x80, 0xc5, 0xd4, 0x55, 0xe6, 0xa2, 0x05, 0x91, 0x05, 0x64, 0xfe, 0xbe, 0xce, 0xa2, 0x2f, 0x18, 0x4a, 0x94, 0xe2, 0x24, 0x5a, 0xc0, 0xe8, 0x4a, 0x90, 0x18, 0x68, 0x5a, 0x94, 0x8b, 0x54, 0x38, 0xd6, 0x52, 0xbe, 0x84, 0x91, 0xc2, 0xb5, 0xc2, 0x9e, 0x25, 0x06, 0x70, 0xb7, 0xb5, 0xb8, 0xc5, 0x54, 0x48, 0x1b, 0x9a, 0x39, 0xb2, 0x33, 0xfc, 0xdc, 0x9d, 0xe7, 0x09, 0x06, 0xf1, 0x42, 0x8f, 0x9d, 0x14, 0xf4, 0x46, 0xc1, 0xba, 0xee, 0x7e, 0xa2, 0x4a, 0x84, 0xe6, 0x71, 0x61, 0x66, 0x04, 0xe8, 0xb3, 0xf8, 0xcb, 0x43, 0x22, 0xec, 0xe8, 0x0e, 0x61, 0xb8, 0x9f, 0xd9, 0x16, 0xae, 0xa5, 0xca, 0xe0, 0x07, 0xf7, 0x98, 0x65, 0xf6, 0xad, 0xb4, 0x4e, 0x6f, 0xa7, 0xd5, 0xfc, 0xfa, 0xdf, 0x31, 0xe5, 0x03, 0x83, 0xd6, 0xfa, 0xf8, 0x79, 0x27, 0xa4, 0x25, 0xb1, 0xf7, 0x75, 0x04, 0x96, 0x6c, 0x5d, 0xde, 0x9f, 0x53, 0xa6, 0x74, 0xa1, 0x51, 0x13, 0xb2, 0xc6, 0xc7, 0x2f, 0x8b, 0x51, 0x07, 0x91, 0x45, 0xaa, 0x9d, 0x97, 0x1d, 0x4f, 0x6e, 0x55, 0x12, 0x83, 0x24, 0xa8, 0x43, 0x0a, 0xbb, 0x9a, 0x76, 0xb5, 0xec, 0x21, 0x02, 0x6b, 0xde, 0x04, 0xe7, 0x57, 0x84, 0xc9, 0x98, 0x36, 0x2c, 0xa6, 0x7f, 0x71, 0xb0, 0xe9, 0x5e, 0x37, 0xde, 0xf3, 0x5f, 0x5d, 0xfd, 0x38, 0xc3, 0xec, 0x1d, 0x64, 0x31, 0xb9, 0xe5, 0x76, 0x89, 0x36, 0xcd, 0xd0, 0x86, 0xbd, 0x00, 0x0d, 0xe7, 0x37, 0xc0, 0x94, 0xe8, 0x13, 0x82, 0xf6, 0xd5, 0x05, 0xa7, 0xfe, 0x5e, 0x7a, 0x2f, 0x7f, 0x85, 0x85, 0xd9, 0x87, 0x0c, 0x37, 0x57, 0x76, 0x24, 0x12, 0x6e, 0x4b, 0x30, 0x07, 0x46, 0x02, 0xff, 0xf5, 0xbf, 0x37, 0x00, 0xf3, 0x69, 0x15, 0x76, 0x4a, 0xed, 0x2e, 0x63, 0x78, 0xfc, 0x25, 0xaa, 0x76, 0xa7, 0xd9, 0x34, 0x88, 0x3c, 0xc3, 0x9e, 0x51, 0x79, 0xba, 0x2a, 0x48, 0x5e, 0xe4, 0xda, 0x2d, 0xa4, 0xf1, 0x44, 0xdf, 0x4e, 0x63, 0x24, 0x3a, 0x16, 0xd4, 0x83, 0x27, 0xe4, 0x50, 0xfe, 0x7d, 0x3d, 0xea, 0xcc, 0x38, 0xf4, 0x66, 0xb0, 0x88, 0x3a, 0xe6, 0xc6, 0xde, 0xd3, 0x9e, 0x4f, 0x53, 0xa7, 0x01, 0x45, 0xc0, 0x54, 0xc6, 0x07, 0xce, 0x04, 0x69, 0x7f, 0x91, 0x91, 0xb7, 0x9c, 0xff, 0x60, 0xa6, 0xc2, 0xc8, 0x51, 0x91, 0xef, 0x81, 0xd7, 0xe4, 0x12, 0x83, 0xf2,
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA /* extended_example/sb_content_cert_test_10.bin */ 0x30, 0x82, 0x04, 0xde, 0x30, 0x82, 0x03, 0x16, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x04, 0x62, 0xd8, 0x68, 0xcd, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x03, 0x41, 0x52, 0x4d, 0x30, 0x20, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x31, 0x32, 0x35, 0x30, 0x38, 0x35, 0x33, 0x33, 0x36, 0x5a, 0x18, 0x0f, 0x32, 0x31, 0x35, 0x34, 0x30, 0x33, 0x30, 0x33, 0x31, 0x35, 0x32, 0x31, 0x35, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x43, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xdd, 0x30, 0x81, 0xda, 0x30, 0x1a, 0x06, 0x03, 0x64, 0x02, 0x01, 0x01, 0x01, 0xff, 0x04, 0x10, 0x63, 0x63, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x03, 0x00, 0x30, 0x1e, 0x06, 0x03, 0x64, 0x02, 0x02, 0x01, 0x01, 0xff, 0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x30, 0x81, 0x9b, 0x06, 0x03, 0x64, 0x02, 0x04, 0x01, 0x01, 0xff, 0x04, 0x81, 0x90, 0x03, 0x00, 0x00, 0x00, 0xa9, 0xf7, 0x0a, 0xfe, 0xc3, 0x0c, 0x61, 0x67, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x10, 0x00, 0x21, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x20, 0x00, 0x21, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x3d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x30, 0x30, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x03, 0x02, 0x01, 0x20, 0x03, 0x82, 0x01, 0x81, 0x00, 0x51, 0x72, 0x17, 0xc2, 0xa7, 0x44, 0x51, 0xe9, 0xf0, 0x3e, 0x8a, 0x03, 0x59, 0x08, 0x14, 0xf7, 0x3b, 0x61, 0x33, 0x41, 0x2b, 0x98, 0xba, 0xf7, 0x1d, 0xe2, 0xdc, 0x27, 0x43, 0x46, 0x2d, 0xd7, 0x2f, 0x9a, 0x17, 0xb5, 0xec, 0xc1, 0xcd, 0x49, 0x63, 0x56, 0x9f, 0x87, 0x72, 0xa1, 0xba, 0xb9, 0xc0, 0x38, 0x42, 0x7a, 0xb1, 0x98, 0xce, 0xf3, 0x63, 0xfc, 0x05, 0x82, 0xd9, 0xa5, 0x23, 0x8d, 0xc8, 0x4c, 0x50, 0xf7, 0xb9, 0x4c, 0x8b, 0x71, 0x57, 0x7e, 0xf5, 0xeb, 0x85, 0xb5, 0x56, 0xdb, 0xb8, 0xf7, 0xcc, 0x29, 0x52, 0x56, 0x37, 0x82, 0x91, 0x66, 0xe7, 0x98, 0x68, 0x8d, 0x3a, 0x49, 0xba, 0xc6, 0x7a, 0x22, 0xff, 0x68, 0x56, 0x17, 0x05, 0x96, 0x60, 0x29, 0x8d, 0x04, 0x88, 0xd1, 0xe6, 0x20, 0x00, 0xb2, 0x1c, 0x6c, 0xe4, 0x11, 0xbc, 0xa8, 0xf7, 0x70, 0xd7, 0x18, 0x43, 0xe2, 0xe2, 0xe4, 0x22, 0x43, 0xbc, 0x9d, 0xcb, 0x2a, 0x35, 0x74, 0xdf, 0x70, 0x25, 0xce, 0xe8, 0x1b, 0x24, 0xac, 0x12, 0x76, 0x4c, 0xc6, 0x14, 0xf4, 0x24, 0xa0, 0x67, 0x6c, 0x79, 0x9e, 0xd5, 0xb4, 0x76, 0x6e, 0x11, 0x8e, 0x75, 0xdc, 0x0f, 0xac, 0x02, 0x53, 0xe8, 0x8c, 0x84, 0x6d, 0x55, 0x00, 0x84, 0x97, 0xd3, 0x8d, 0x24, 0xd9, 0x77, 0x1e, 0x38, 0x89, 0x18, 0xb0, 0x0c, 0xe5, 0xf2, 0x61, 0x86, 0x5a, 0xec, 0x42, 0x4e, 0xd6, 0x46, 0xe3, 0x61, 0x65, 0x82, 0x51, 0x39, 0x74, 0xd2, 0xd9, 0x32, 0x96, 0xed, 0x88, 0x1f, 0xcb, 0xf2, 0x8c, 0x40, 0xe0, 0xf7, 0xb8, 0x07, 0x7d, 0xad, 0x5d, 0xd5, 0xc9, 0x67, 0x8f, 0x6c, 0xe6, 0x46, 0xb2, 0x0c, 0x1a, 0x29, 0xa9, 0x8d, 0xb5, 0x1c, 0x96, 0x01, 0xef, 0xcb, 0x19, 0xd1, 0x6d, 0x57, 0xac, 0x67, 0x9b, 0x08, 0x53, 0xd8, 0x9d, 0x95, 0x17, 0x05, 0x16, 0x0d, 0xb6, 0xa5, 0x88, 0x0e, 0xcf, 0xd9, 0x7b, 0x62, 0xfe, 0x7d, 0xdb, 0x7a, 0x95, 0xdc, 0xb5, 0x6d, 0x9e, 0x01, 0x8f, 0xb0, 0x0d, 0xfa, 0x8d, 0x4b, 0xe0, 0x02, 0xb7, 0x82, 0x6e, 0x51, 0xf4, 0x12, 0x73, 0x55, 0x23, 0xff, 0x16, 0x54, 0xf5, 0x50, 0x6a, 0xab, 0xac, 0x2e, 0xa9, 0x80, 0x15, 0x20, 0x59, 0xc9, 0xf1, 0xcc, 0x78, 0x85, 0xf8, 0x02, 0x33, 0xa7, 0x49, 0x0e, 0x1b, 0xce, 0x2f, 0x66, 0xf7, 0x05, 0x5c, 0xee, 0xb1, 0x68, 0x1e, 0xe5, 0x2a, 0x6c, 0x22, 0x2e, 0x8a, 0xdf, 0xe4, 0x6c, 0x80, 0xcd, 0x5e, 0x6d, 0xe6, 0xed, 0x95, 0x87, 0xfb, 0x9d, 0x7b, 0x21, 0x9b, 0x36, 0x0c, 0x07, 0xa2, 0x0c, 0x32, 0x8d, 0x2a, 0xc3, 0xfe, 0x01, 0xfd, 0xd5, 0x1c, 0xec, 0xca, 0x73, 0xd5, 0xf3, 0xc9, 0xd8, 0x63, 0xd6, 0x97, 0xa2, 0xaf, 0x8a, 0xea, 0x41, 0x62, 0x07, 0xd9, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA /* extended_example/sb_image1_enc.bin */ 0x55, 0x23, 0x80, 0xfe, 0x51, 0x6a, 0x55, 0x15, 0x6f, 0xb5, 0x2d, 0x98, 0x21, 0xd6, 0x6a, 0xa7, 0x06, 0x53, 0x67, 0x46, 0xb1, 0x88, 0x61, 0x21, 0x23, 0x81, 0xd6, 0xc1, 0x81, 0xdb, 0x1a, 0x17, 0x1c, 0xe5, 0x06, 0xaf, 0x37, 0x50, 0x2f, 0xd0, 0xac, 0x7b, 0xb1, 0xb7, 0x21, 0xf5, 0x82, 0x94, 0xca, 0x72, 0x57, 0x6e, 0x00, 0x4e, 0xe6, 0x5e, 0x1b, 0x81, 0xc6, 0x0a, 0xe7, 0x3c, 0x52, 0x84, 0x53, 0x97, 0x02, 0xe5, 0xf3, 0x74, 0x7a, 0x6c, 0xe7, 0x8c, 0x92, 0xf0, 0x38, 0x56, 0xa3, 0x0d, 0x82, 0xe9, 0xbe, 0x8e, 0x24, 0xae, 0x7e, 0x47, 0xb8, 0x88, 0x47, 0x6a, 0x34, 0xa8, 0x99, 0x4f, 0x6b, 0x03, 0x6e, 0xa1, 0x47, 0x9d, 0x38, 0x4d, 0xd0, 0x6d, 0x69, 0x35, 0xd5, 0x55, 0x68, 0xe1,
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA /* extended_example/sb_image2_enc.bin */ 0xf9, 0xa5, 0x94, 0x60, 0x00, 0x2a, 0xf9, 0xe0, 0x0f, 0x90, 0xf1, 0xde, 0x2b, 0x1a, 0xf0, 0x35, 0xa3, 0x70, 0x61, 0xdb, 0x6c, 0xd6, 0x44, 0x68, 0xe0, 0xb7, 0x5a, 0x95, 0xe1, 0x4a, 0x6a, 0x74, 0x6e, 0x9e, 0xd5, 0x4e, 0xb9, 0xc2, 0xe2, 0xac, 0x95, 0xbc, 0x57, 0x77, 0x3c, 0xf9, 0xf8, 0xb1, 0x78, 0xbf, 0x5b, 0x2c, 0x17, 0x38, 0x53, 0x32, 0x76, 0xf2, 0x02, 0x47, 0x3c, 0x9d, 0x88, 0x4e, 0x46, 0xf3, 0x5a, 0x70, 0x39, 0xa4, 0x3a, 0x67, 0x72, 0x7d, 0x97, 0x0b, 0x9c, 0xa8, 0x04, 0x4d, 0xb3, 0x32, 0xa2, 0x1b, 0x1c, 0xd7, 0xa0, 0x19, 0x73, 0x70, 0xc8, 0xbb, 0x34, 0x7b, 0x91, 0xc3, 0xaf, 0x13, 0xe5, 0xb8, 0xf0, 0x53, 0x3d, 0x09, 0xb2, 0x1f, 0xbc, 0x59, 0x39, 0x95, 0xed, 0xb7,
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA /* extended_example/sb_image3_enc.bin */ 0x19, 0x59, 0xa4, 0x2b, 0x3d, 0x3a, 0xab, 0xa9, 0x8f, 0x45, 0x37, 0xaa, 0xc0, 0x5b, 0x74, 0x87, 0x0c, 0x70, 0x88, 0xae, 0x3f, 0xaf, 0x82, 0xaf, 0xdc, 0x4d, 0x12, 0x81, 0xde, 0x06, 0xcb, 0x45, 0xb2, 0x16, 0xa0, 0x03, 0xf3, 0x6e, 0x3d, 0x27, 0xd9, 0x2a, 0x8d, 0x4b, 0x74, 0x9d, 0x31, 0x03, 0xd5, 0xd2, 0xdc, 0xe5, 0x8b, 0xc7, 0x84, 0x72, 0x3f, 0x93, 0xca, 0x85, 0x85, 0x72, 0x5a, 0x87, 0xaf, 0xb7, 0x9b, 0x83, 0x3f, 0x47, 0x7a, 0x24, 0x42, 0x56, 0xd6, 0x19, 0x87, 0xb4, 0xdb, 0xbb, 0x40, 0x88, 0x92, 0x67, 0x4c, 0x28, 0x21, 0x85, 0x21, 0xd7, 0x6a, 0xde, 0x28, 0xba, 0x88, 0xa7, 0x1b, 0xbd, 0xc8, 0x58, 0xb9, 0x68, 0xf8, 0x6e, 0x5a, 0x91, 0xa9, 0x7d, 0xf1, 0xa6, 0x5d, 0x44,
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA_LENGTH /* sb_key1_cert_test_10.bin */ 1138
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA_LENGTH /* sb_key2_cert_test_10.bin */ 1139
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH /* sb_content_cert_test_10.bin */ 1276
+#else
+/************************************/
+/*          MPS2 CM3 NOT_X509       */
+/************************************/
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA /* extended_example/sb_key1_cert_test_10.bin */ 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0x45, 0x8b, 0x30, 0x9a, 0xd0, 0xa0, 0xb0, 0xb6, 0xe3, 0xd4, 0x5f, 0xbb, 0xb8, 0x69, 0x19, 0xf7, 0x2c, 0xdb, 0xaa, 0x1c, 0x8c, 0x1e, 0x4e, 0x3f, 0xa6, 0x44, 0x03, 0xd5, 0x0d, 0xb0, 0x21, 0xa4, 0xaa, 0x21, 0x18, 0xfc, 0x2a, 0xae, 0x05, 0xb8, 0x01, 0x4d, 0xc1, 0x46, 0x79, 0x36, 0xdf, 0x76, 0x52, 0xa9, 0xf4, 0xb4, 0xa7, 0x81, 0x3e, 0x37, 0x8d, 0xab, 0x00, 0x26, 0xf4, 0x2b, 0x05, 0xbd, 0xe5, 0xf8, 0x30, 0x8c, 0x2a, 0x7c, 0xef, 0xab, 0xaf, 0x67, 0xe7, 0x2a, 0xb6, 0xa0, 0x6b, 0xe3, 0x1b, 0xef, 0x98, 0x35, 0xd6, 0x3b, 0x92, 0x8b, 0x30, 0x01, 0xc4, 0x84, 0xbc, 0x3b, 0x4e, 0x0a, 0xa5, 0x41, 0x48, 0x17, 0x6c, 0x3c, 0x8b, 0x7e, 0xda, 0xcb, 0x66, 0x8b, 0xe8, 0x2b, 0x74, 0x5e, 0x0a, 0x6f, 0xa7, 0xaf, 0x5c, 0xce, 0xbc, 0xbe, 0xe4, 0x1f, 0x78, 0x11, 0x2a, 0x11, 0x25, 0x7a, 0x45, 0xb5, 0x5f, 0xb8, 0xae, 0xc0, 0x59, 0x45, 0x33, 0xb3, 0x59, 0xf9, 0xe3, 0xde, 0x39, 0x73, 0x18, 0x18, 0x8a, 0xe8, 0xb6, 0x0e, 0x19, 0xc9, 0x5a, 0x7a, 0xb9, 0x57, 0xfc, 0x98, 0x60, 0x6c, 0xf3, 0x67, 0xec, 0x62, 0xc0, 0x24, 0x1e, 0x0b, 0x91, 0x41, 0x97, 0x43, 0xfc, 0xfc, 0xf2, 0x60, 0x3f, 0xce, 0xa5, 0x92, 0x7d, 0x9b, 0xc1, 0x09, 0x1e, 0x48, 0xef, 0xdb, 0x7e, 0x1f, 0x50, 0xa2, 0xed, 0x0f, 0xd4, 0x60, 0x8b, 0x52, 0x28, 0x2d, 0x42, 0x95, 0x07, 0xda, 0x6c, 0x93, 0x6e, 0xba, 0xa8, 0x5c, 0x5f, 0x05, 0x63, 0x6b, 0xb9, 0xdb, 0x57, 0xf4, 0x2b, 0xc4, 0x7d, 0x6b, 0xd3, 0x04, 0x1a, 0xc5, 0x9b, 0xab, 0x6c, 0x58, 0x5b, 0xf8, 0x43, 0x18, 0xc1, 0x12, 0x72, 0xe5, 0x52, 0x93, 0x98, 0xab, 0x7e, 0xed, 0xd0, 0x2f, 0x7f, 0x1c, 0x32, 0x6f, 0xc7, 0x83, 0xd1, 0x8c, 0x55, 0xf9, 0x85, 0x64, 0x35, 0x4b, 0xdb, 0x9e, 0x3e, 0x42, 0xbb, 0xf4, 0x4b, 0x4e, 0x5e, 0xe9, 0x7e, 0x85, 0x6a, 0x42, 0xe1, 0x38, 0xcc, 0xf0, 0xaf, 0xfd, 0xda, 0x10, 0xb5, 0x7d, 0x68, 0x3a, 0x6c, 0xbc, 0xb5, 0x1f, 0x2f, 0x54, 0x1d, 0xa1, 0xe9, 0x8f, 0x81, 0x0d, 0xe5, 0x7b, 0xa7, 0x31, 0x43, 0x78, 0x8e, 0xc9, 0x3b, 0x8b, 0xad, 0xdf, 0xdd, 0xa7, 0x4d, 0x6a, 0x33, 0x55, 0xfd, 0x88, 0x28, 0x05, 0xce, 0x2f, 0xf8, 0xcd, 0x2c, 0x1e, 0x82, 0x95, 0xf9, 0x03, 0x8a, 0x17, 0xf0, 0x30, 0xcb, 0x01, 0xbb, 0xe5, 0xcc, 0x1f, 0x9f, 0x65, 0xa5, 0x51, 0xab, 0x50, 0x49, 0x33, 0x76, 0x1f, 0xb7, 0x5c, 0x4b, 0xa9, 0xeb, 0x75, 0x6d, 0x6f, 0xf8, 0xae, 0xd7, 0xbc, 0x9e, 0x18, 0xcd, 0x3d, 0x2a, 0x2c, 0x27, 0xfe, 0x2b, 0xb0, 0xd4, 0x7f, 0x9e, 0x9c, 0xcb, 0x83, 0x6c, 0xbd, 0xd3, 0x39, 0xcc, 0xaa,
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA /* extended_example/sb_key2_cert_test_10.bin */ 0x63, 0x6b, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x03, 0x00, 0x00, 0x00, 0xda, 0x7b, 0xf1, 0x2f, 0x06, 0xb5, 0x3e, 0xe9, 0x0b, 0x4f, 0xa5, 0x9a, 0x2b, 0x75, 0xde, 0x4a, 0x85, 0x5e, 0x84, 0xaf, 0x59, 0xb3, 0x46, 0x9b, 0x0d, 0x88, 0x4e, 0xf8, 0xf7, 0x0a, 0x72, 0x1b, 0xf0, 0x9b, 0x52, 0x8e, 0xc7, 0xf3, 0x3d, 0x23, 0x42, 0xcd, 0xb6, 0x81, 0xf6, 0x24, 0xc4, 0xce, 0xb5, 0xb9, 0x4b, 0x0c, 0x83, 0xd6, 0x7d, 0x11, 0xdb, 0x4e, 0xca, 0xb1, 0xe4, 0xbf, 0xb8, 0x97, 0xa8, 0x93, 0xa1, 0x5b, 0x1d, 0xbd, 0xea, 0x04, 0x6d, 0xb2, 0x40, 0x00, 0x7d, 0x05, 0x7d, 0xe0, 0x6f, 0x51, 0xc8, 0xb5, 0xb5, 0x32, 0x9f, 0x70, 0x0f, 0xd8, 0xaa, 0x18, 0x90, 0x84, 0x96, 0x7c, 0x98, 0x08, 0x21, 0xd5, 0xfa, 0x93, 0xc8, 0x75, 0xb6, 0xf6, 0x65, 0x76, 0x34, 0x15, 0xd9, 0x41, 0x07, 0x0e, 0x3b, 0xf8, 0x47, 0xcf, 0xc1, 0xfe, 0x7b, 0xaa, 0x38, 0x70, 0xec, 0xe9, 0x93, 0x41, 0x7b, 0x72, 0x9a, 0x0e, 0x28, 0xe2, 0x1d, 0x26, 0x3b, 0xd6, 0xc8, 0xe5, 0xd7, 0x7a, 0xfe, 0xa7, 0xcb, 0x87, 0xd0, 0x93, 0x18, 0x61, 0xfc, 0xca, 0xe5, 0x57, 0xa0, 0x43, 0x8d, 0xa2, 0x70, 0x26, 0xf3, 0x44, 0xbe, 0x7e, 0xfc, 0x63, 0x8f, 0xd6, 0xd7, 0xbe, 0xed, 0x88, 0x0d, 0xe3, 0x54, 0x9d, 0x3d, 0xd5, 0xcc, 0xec, 0x83, 0x2a, 0x16, 0x1d, 0xc5, 0xda, 0xa6, 0xe1, 0x89, 0x62, 0x57, 0xdf, 0x47, 0x74, 0x89, 0x39, 0x70, 0x09, 0x11, 0x65, 0xec, 0xf6, 0x9e, 0xee, 0xc6, 0xc7, 0x59, 0x22, 0x65, 0x1a, 0xdc, 0xae, 0x9e, 0x90, 0x7b, 0x1c, 0xfc, 0x5d, 0xfc, 0xc7, 0x49, 0xc1, 0x0a, 0xae, 0x4c, 0xc1, 0xc9, 0x6f, 0xe1, 0x07, 0xef, 0xf5, 0x54, 0x4e, 0x77, 0x5c, 0x7c, 0xa5, 0xc1, 0xd5, 0x15, 0x70, 0xc5, 0xa5, 0xd4, 0x88, 0x52, 0xae, 0xbc, 0x37, 0x8a, 0x9d, 0x2a, 0x83, 0xc5, 0xe4, 0xe3, 0xa0, 0x5c, 0xed, 0xc8, 0x0c, 0x80, 0xc7, 0x53, 0xb6, 0x00, 0x53, 0x00, 0xa9, 0xce, 0x1d, 0xce, 0x8e, 0xa3, 0x73, 0xd7, 0x31, 0xd7, 0x8f, 0x48, 0x38, 0x91, 0x20, 0x38, 0xca, 0x64, 0x61, 0x6b, 0x16, 0xbb, 0xc4, 0x7e, 0xd5, 0xac, 0xca, 0x53, 0xb3, 0x7d, 0x4b, 0x04, 0xb6, 0xe3, 0xd9, 0x00, 0x55, 0xb4, 0x86, 0x17, 0xec, 0x64, 0x9e, 0x63, 0xf3, 0x53, 0x9b, 0x11, 0x38, 0x66, 0xfe, 0xd7, 0xd8, 0xe6, 0x6a, 0x3e, 0x2b, 0x56, 0xdd, 0xc5, 0x2d, 0xf9, 0xf9, 0x83, 0x6c, 0x82, 0x93, 0xad, 0xeb, 0x97, 0x10, 0x2e, 0x85, 0xce, 0xb5, 0xba, 0x95, 0x91, 0x92, 0x12, 0x8e, 0x29, 0x46, 0x9a, 0x63, 0x68, 0x59, 0xdc, 0x8d, 0xde, 0x06, 0x7a, 0x51, 0x86, 0xff, 0xd3, 0x6c, 0xea, 0x06, 0x18, 0x98, 0xe3, 0x19, 0x0f, 0x96, 0x07, 0x1b, 0x07, 0x28, 0xe6, 0x93, 0xaa, 0x6c, 0x3b, 0x35, 0x6a, 0x68, 0xb7, 0xe4, 0xa5, 0x7a, 0xbf, 0x43, 0xa2, 0x9a, 0xf9, 0x36, 0x8c, 0x22, 0x30, 0x34, 0x03, 0xde, 0xff, 0x1a, 0x20, 0xd2, 0xfb, 0x1f, 0x62, 0xe9, 0xf8, 0x17, 0x42, 0x3b, 0x3e, 0xa0,
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA /* extended_example/sb_content_cert_test_10.bin */ 0x63, 0x63, 0x42, 0x53, 0x00, 0x00, 0x01, 0x00, 0x8d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x03, 0x00, 0xc7, 0xad, 0x9d, 0x16, 0xab, 0x03, 0xd3, 0x71, 0x19, 0x96, 0x86, 0xa4, 0x7c, 0x53, 0x51, 0x93, 0x22, 0xc7, 0x8d, 0xa9, 0x78, 0x92, 0x5e, 0x0b, 0x9d, 0x55, 0x0a, 0x89, 0x8c, 0x56, 0x0b, 0xe0, 0x5f, 0x00, 0xaf, 0xac, 0x32, 0xee, 0x46, 0x83, 0x51, 0xfc, 0x8a, 0x9e, 0x30, 0x38, 0xe1, 0xf4, 0xe1, 0xfb, 0x49, 0x70, 0x17, 0x5c, 0x8f, 0xba, 0xb0, 0xe6, 0x48, 0xe3, 0x6c, 0x22, 0x80, 0x25, 0xd9, 0xb8, 0xfc, 0x7c, 0x53, 0x9e, 0x76, 0xcf, 0xb5, 0xc9, 0x2f, 0xe3, 0x67, 0x25, 0xce, 0xd7, 0x29, 0xf3, 0x02, 0x2d, 0x29, 0x2e, 0x42, 0x2c, 0xc6, 0xdc, 0x36, 0xe7, 0x25, 0x1c, 0xa6, 0x9a, 0x60, 0x69, 0xe2, 0x7c, 0x80, 0xe3, 0xc0, 0x37, 0x94, 0x59, 0x77, 0x00, 0xd5, 0x61, 0x5f, 0x07, 0x70, 0x04, 0x87, 0x1e, 0xc5, 0xb3, 0x94, 0xa8, 0xa4, 0xa0, 0xc4, 0xeb, 0x9d, 0xfc, 0x4c, 0x02, 0xb3, 0xc8, 0x81, 0xcd, 0x0a, 0xd9, 0x06, 0xce, 0x4c, 0xf9, 0x6a, 0x62, 0x6b, 0x36, 0x57, 0x17, 0xe4, 0xab, 0x75, 0x5c, 0x37, 0xfa, 0x50, 0x22, 0x69, 0x38, 0x92, 0xe8, 0x91, 0x27, 0x30, 0xd1, 0x57, 0xa0, 0x4f, 0x21, 0x0a, 0x8d, 0x17, 0xee, 0xe4, 0xa4, 0x8c, 0xdb, 0xc7, 0x2f, 0xb3, 0xc6, 0xdd, 0x0b, 0x54, 0x81, 0xcd, 0x14, 0x08, 0x1b, 0x50, 0x7b, 0x30, 0xd3, 0x5d, 0x97, 0xa3, 0x82, 0x15, 0x9a, 0x96, 0x69, 0xaf, 0x8f, 0x6b, 0xf2, 0x5b, 0x80, 0x1a, 0x21, 0x67, 0x37, 0x42, 0x56, 0xd9, 0x25, 0xb5, 0x72, 0xf6, 0x83, 0x25, 0x0f, 0x04, 0x12, 0x50, 0x7e, 0x74, 0xd6, 0xba, 0xe6, 0x51, 0x55, 0x69, 0xb2, 0xc7, 0xe0, 0x78, 0x5d, 0xe3, 0x31, 0xfb, 0x49, 0xed, 0x17, 0x4a, 0xd0, 0x70, 0xe2, 0x2c, 0x71, 0x7a, 0x3f, 0x15, 0x16, 0x68, 0x42, 0xac, 0x84, 0x51, 0x3c, 0x4e, 0x67, 0xfe, 0x13, 0x41, 0x80, 0x9c, 0x61, 0xd6, 0xd4, 0x84, 0xc8, 0x95, 0x66, 0x6d, 0x0a, 0x4f, 0x21, 0xee, 0x97, 0xb9, 0x02, 0x0e, 0x1b, 0x95, 0x73, 0xa2, 0xf0, 0x54, 0x31, 0x6a, 0xe9, 0xa6, 0xfa, 0x57, 0xad, 0x59, 0xc0, 0xf1, 0x50, 0xf9, 0xda, 0x4a, 0x13, 0xa9, 0x8a, 0x6f, 0x52, 0x12, 0x5c, 0x8f, 0x01, 0x91, 0xef, 0x1d, 0xe1, 0x16, 0xc3, 0xc3, 0x3d, 0xaf, 0xcc, 0xce, 0x5b, 0x92, 0x7d, 0xa5, 0xae, 0x70, 0x10, 0xa0, 0xac, 0x1d, 0x59, 0x8d, 0xb1, 0xf3, 0x14, 0x16, 0x49, 0x05, 0xeb, 0xf2, 0x99, 0x71, 0xb2, 0x59, 0x97, 0x43, 0x29, 0x1c, 0x82, 0x9d, 0x77, 0x00, 0x94, 0x7e, 0x77, 0x3a, 0x7e, 0x1f, 0x9a, 0x45, 0x61, 0x37, 0x2d, 0x6f, 0xcd, 0x26, 0x25, 0xec, 0xfa, 0x58, 0x87, 0x7a, 0x5d, 0xfd, 0xc8, 0x6a, 0x15, 0x62, 0x37, 0xcb, 0xb0, 0xdf, 0xaa, 0x63, 0x6c, 0x97, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1a, 0xa3, 0xc2, 0xd9, 0x60, 0xd8, 0x72, 0xa7, 0x03, 0x00, 0x00, 0x00, 0xd0, 0x8c, 0x7c, 0xac, 0x88, 0xc6, 0x3a, 0x2e, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x00, 0x00, 0x21, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x10, 0x00, 0x21, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x69, 0x4f, 0xfb, 0xfa, 0xa6, 0xfe, 0x6e, 0x79, 0xcf, 0x4a, 0xa9, 0x6c, 0xe3, 0x5f, 0x97, 0xb4, 0x52, 0xb5, 0x22, 0x2c, 0x3c, 0x9a, 0x32, 0x3e, 0x00, 0x06, 0x19, 0xd8, 0x56, 0xee, 0x19, 0x00, 0x20, 0x00, 0x21, 0x00, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x97, 0x56, 0xd4, 0xa0, 0xf5, 0xd7, 0x04, 0x24, 0x22, 0x17, 0xe0, 0x32, 0xa2, 0xb2, 0x09, 0x08, 0x3c, 0xe6, 0x9a, 0xea, 0x38, 0xe4, 0x5a, 0x94, 0x45, 0xc9, 0x86, 0xba, 0xc7, 0x9c, 0x42, 0x61, 0xb7, 0xc7, 0x87, 0x1b, 0x9d, 0x2f, 0x3b, 0x75, 0xfb, 0xe3, 0x10, 0xd8, 0x35, 0x94, 0xec, 0xf9, 0xb3, 0xb8, 0xaa, 0x1b, 0x06, 0x17, 0x4c, 0x5b, 0x87, 0xb8, 0x7a, 0x3a, 0xbc, 0x64, 0x38, 0x52, 0x25, 0x79, 0xc0, 0xfc, 0xd8, 0x7c, 0x49, 0x71, 0xa0, 0x43, 0xac, 0x6c, 0x44, 0xd9, 0x30, 0x23, 0xdf, 0x12, 0xdd, 0x9d, 0x73, 0x9a, 0x41, 0x13, 0x95, 0x80, 0xc3, 0xdd, 0x6c, 0x79, 0x9a, 0x0e, 0x9b, 0xa3, 0x9a, 0xee, 0xea, 0x17, 0x63, 0xac, 0x72, 0x83, 0x78, 0x83, 0xf9, 0x04, 0x46, 0x32, 0x79, 0xcf, 0xc0, 0x80, 0x69, 0xbd, 0x5b, 0x8b, 0xf0, 0x29, 0x5b, 0x4f, 0x0d, 0x94, 0x9f, 0xf3, 0xd0, 0xf9, 0x5a, 0x60, 0x88, 0x29, 0x47, 0x44, 0x70, 0x6e, 0x5f, 0xb4, 0xb9, 0x6c, 0x17, 0x2b, 0x79, 0xba, 0xa9, 0xaf, 0xbc, 0xc2, 0x6f, 0xaa, 0xac, 0xad, 0xdd, 0x20, 0x5c, 0x2c, 0x56, 0xc6, 0x5d, 0xe9, 0x0c, 0xe5, 0x63, 0x3d, 0xd0, 0xa1, 0xb1, 0xd7, 0x53, 0x27, 0xa8, 0x47, 0x1b, 0xa7, 0x6f, 0xd9, 0xd1, 0xe8, 0xd6, 0x5f, 0x3d, 0x9e, 0x03, 0xd9, 0x4a, 0x5a, 0x85, 0x58, 0xd2, 0xb2, 0x1f, 0x43, 0x9b, 0x8d, 0x43, 0x88, 0xe5, 0x1d, 0xa2, 0x66, 0xf6, 0xa7, 0x3f, 0x3f, 0xc6, 0x47, 0x55, 0x0f, 0x39, 0xc1, 0x4e, 0xda, 0x8c, 0x57, 0x20, 0xbe, 0x1a, 0x93, 0xa9, 0x74, 0x38, 0x0b, 0xf3, 0xe8, 0x54, 0x73, 0xed, 0xe5, 0x62, 0x3e, 0xdb, 0xd1, 0x3d, 0x1d, 0x1f, 0x52, 0x01, 0x25, 0xe9, 0xdd, 0xdd, 0xdb, 0x91, 0x36, 0xaf, 0x5a, 0xf7, 0x90, 0xea, 0xf4, 0x88, 0x55, 0xfd, 0x04, 0x4d, 0x9e, 0xfa, 0x06, 0xd0, 0x4b, 0xe5, 0xc0, 0x21, 0x0e, 0xbd, 0xad, 0x72, 0xe8, 0x72, 0x29, 0x2a, 0xf7, 0x5b, 0x70, 0x31, 0xec, 0xd3, 0x51, 0x38, 0x35, 0x93, 0x80, 0xf2, 0xa3, 0xe0, 0x14, 0x59, 0x59, 0xfe, 0x9b, 0x36, 0xa2, 0xb7, 0xcd, 0xb9, 0x41, 0x3a, 0x45, 0x23, 0xd2, 0xa9, 0xe0, 0x4f, 0xe2, 0x6b, 0xa3, 0xcf, 0xf8, 0xec, 0xc8, 0x15, 0xed, 0x5b, 0x65, 0x96, 0x04, 0x63, 0x8c, 0x53, 0x5e, 0xe4, 0xc1, 0x1e, 0x21, 0xa9, 0xa4, 0x2b, 0xdb, 0xa8, 0x0f, 0x33, 0xc0, 0x80, 0x69, 0x8c, 0xe7, 0xfb, 0x26, 0x32, 0x1d, 0xf8, 0x74, 0x1a, 0xad, 0x4f, 0x60, 0xdf, 0x0a, 0x57, 0xd7, 0xc5, 0x82, 0x1a, 0x44, 0x61, 0xa5, 0x9e, 0xd3, 0x7c, 0x16, 0xf9, 0x61, 0xb2, 0x1d, 0xc4, 0xbf, 0x0f, 0x89, 0x22, 0xc7, 0xd3, 0x39, 0x9f, 0xff, 0xfc, 0xb9, 0xaf, 0x78, 0x9f, 0xf4, 0x35, 0x00, 0x30, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA /* extended_example/sb_image1_enc.bin */ 0xd2, 0x8c, 0x25, 0x4d, 0x27, 0x70, 0xa6, 0x70, 0x31, 0xcc, 0x7f, 0x02, 0x9f, 0x06, 0x51, 0x0b, 0x5c, 0x18, 0xe3, 0x5e, 0x35, 0x16, 0x98, 0x84, 0x84, 0xe7, 0x84, 0xb5, 0xea, 0xf7, 0x44, 0xd7, 0x22, 0xe9, 0xd5, 0x40, 0x63, 0x8b, 0xb9, 0xc2, 0xbf, 0x43, 0xae, 0xff, 0xb6, 0xe8, 0xbf, 0xcd, 0xb7, 0x0f, 0xcc, 0x99, 0x3d, 0x50, 0x4b, 0x55, 0x5b, 0xbb, 0x0a, 0xbc, 0x97, 0x95, 0x0a, 0x06, 0x3e, 0x71, 0x66, 0x50, 0x23, 0x65, 0x64, 0x46, 0xca, 0xc8, 0xa3, 0x38, 0xd6, 0x23, 0xae, 0xdc, 0x32, 0x37, 0xc7, 0xdd, 0x8f, 0x38, 0x51, 0x74, 0xb3, 0xf3, 0x1f, 0x97, 0xa7, 0x72, 0x65, 0x00, 0x96, 0x38, 0x30, 0x71, 0xb3, 0x34, 0xad, 0xe9, 0xa8, 0x83, 0x26, 0x2e, 0x6c, 0xd1, 0x80, 0xad,
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA /* extended_example/sb_image2_enc.bin */ 0x59, 0x61, 0xfc, 0xe7, 0xce, 0xed, 0x25, 0xbb, 0xea, 0x60, 0x29, 0xb6, 0x57, 0xce, 0x36, 0x0c, 0x80, 0x05, 0x54, 0xa3, 0xd9, 0x47, 0x3a, 0x8c, 0x6a, 0x9d, 0x06, 0x62, 0x82, 0x89, 0x5a, 0xc1, 0xc8, 0x27, 0xe5, 0x89, 0xc9, 0xf2, 0x37, 0x24, 0x4f, 0x1b, 0xf7, 0x7c, 0x13, 0xc1, 0xb9, 0xd5, 0x04, 0x86, 0x12, 0xd4, 0xe0, 0x66, 0xc9, 0xe1, 0x5b, 0x70, 0x3c, 0x0b, 0xde, 0x01, 0x77, 0xce, 0x06, 0x32, 0x01, 0xf5, 0x3e, 0x76, 0x92, 0x8c, 0x23, 0x91, 0x48, 0xc0, 0x97, 0x7b, 0x40, 0x07, 0x55, 0x6a, 0xde, 0x31, 0xe9, 0xff, 0x88, 0xe6, 0x98, 0x03, 0x82, 0x6d, 0xe8, 0x27, 0xff, 0xa6, 0xc1, 0x46, 0xb4, 0x17, 0x87, 0x7b, 0x91, 0x15, 0xd2, 0x6c, 0x83, 0x5a, 0xd1, 0x5d, 0x7c, 0xee,
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA /* extended_example/sb_image3_enc.bin */ 0x37, 0x80, 0x22, 0xcf, 0xba, 0x00, 0xe3, 0x19, 0xc9, 0xb2, 0x3e, 0x27, 0x71, 0x06, 0xd1, 0xa0, 0xa4, 0xc8, 0x72, 0x55, 0x4a, 0xd1, 0x76, 0xff, 0xc0, 0x47, 0xbc, 0x70, 0x25, 0xb6, 0x3f, 0x52, 0x15, 0x3d, 0xaa, 0x70, 0x4e, 0x79, 0xef, 0x24, 0x60, 0xa2, 0x17, 0x78, 0x40, 0x14, 0x94, 0x24, 0x5b, 0x90, 0x68, 0x50, 0x60, 0x65, 0x19, 0xa3, 0x90, 0x33, 0xb6, 0x09, 0x9c, 0xeb, 0xd9, 0x0a, 0x61, 0xe5, 0xcd, 0x58, 0x34, 0x21, 0x7d, 0x6d, 0x5e, 0xab, 0x73, 0x4f, 0x58, 0x3f, 0x55, 0xaa, 0xcb, 0xf9, 0xf2, 0xc8, 0x0f, 0x24, 0x4d, 0x29, 0x6e, 0x9e, 0x04, 0xe8, 0x81, 0xc0, 0x88, 0xac, 0xb8, 0x0b, 0xd2, 0x5e, 0xd8, 0x6e, 0x7b, 0x9c, 0xa5, 0x08, 0x90, 0x83, 0x70, 0xc7, 0x73, 0x6a,
+#define RUNIT_SECURE_BOOT__CERT_1_BIN__DATA_LENGTH /* sb_key1_cert_test_10.bin */ 840
+#define RUNIT_SECURE_BOOT__CERT_2_BIN__DATA_LENGTH /* sb_key2_cert_test_10.bin */ 840
+#define RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH /* sb_content_cert_test_10.bin */ 972
+#endif /* defined(CC_SB_X509_CERT_SUPPORTED) */
+#endif /* defined(CORTEX_M33_FPGA) */
+#else
+#error "not supported"
+
+#endif /* defined(DX_PLAT_ZYNQ7000) */
+
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__PLAIN_TEXT_DATA /* extended_example/sb_image1.bin */ 0xc3, 0x1b, 0x35, 0xfc, 0xc8, 0xd4, 0x8a, 0x28, 0x55, 0x99, 0x3e, 0x74, 0x04, 0x03, 0x04, 0x79, 0x3e, 0x7f, 0x7b, 0x52, 0x97, 0x53, 0x28, 0x7b, 0x54, 0x2c, 0x8c, 0x5c, 0x34, 0x94, 0x5e, 0x39, 0x94, 0x4c, 0x24, 0x8c, 0x5b, 0x3a, 0x8e, 0x54, 0x2c, 0x98, 0x33, 0x0b, 0x7d, 0x5c, 0x3c, 0x9b, 0x55, 0x3a, 0x8a, 0x6e, 0x54, 0x9d, 0x3e, 0x1c, 0x84, 0x43, 0x24, 0x84, 0x4c, 0x2c, 0x8c, 0x54, 0x34, 0x94, 0x44, 0x24, 0x8c, 0x4c, 0x2c, 0x99, 0x56, 0x3a, 0x94, 0x57, 0x3c, 0x97, 0x5c, 0x40, 0x9c, 0x5c, 0x44, 0x94, 0x46, 0x35, 0x6e, 0x64, 0x4d, 0x9c, 0x74, 0x60, 0xa1, 0x4c, 0x34, 0x8c, 0x54, 0x3c, 0x94, 0x55, 0x3d, 0x95, 0x57, 0x3f, 0x97, 0x5c, 0x42, 0x9c, 0x37, 0x28, 0x5e, 0x5b,
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__PLAIN_TEXT_DATA /* extended_example/sb_image2.bin */ 0xc3, 0x1b, 0x35, 0xfc, 0xc8, 0xd4, 0x8a, 0x28, 0x55, 0x99, 0x3e, 0x74, 0x04, 0x03, 0x04, 0x79, 0x3e, 0x7f, 0x7b, 0x52, 0x97, 0x53, 0x28, 0x7b, 0x54, 0x2c, 0x8c, 0x5c, 0x34, 0x94, 0x5e, 0x39, 0x94, 0x4c, 0x24, 0x8c, 0x5b, 0x3a, 0x8e, 0x54, 0x2c, 0x98, 0x33, 0x0b, 0x7d, 0x5c, 0x3c, 0x9b, 0x55, 0x3a, 0x8a, 0x6e, 0x54, 0x9d, 0x3e, 0x1c, 0x84, 0x43, 0x24, 0x84, 0x4c, 0x2c, 0x8c, 0x54, 0x34, 0x94, 0x44, 0x24, 0x8c, 0x4c, 0x2c, 0x99, 0x56, 0x3a, 0x94, 0x57, 0x3c, 0x97, 0x5c, 0x40, 0x9c, 0x5c, 0x44, 0x94, 0x46, 0x35, 0x6e, 0x64, 0x4d, 0x9c, 0x74, 0x60, 0xa1, 0x4c, 0x34, 0x8c, 0x54, 0x3c, 0x94, 0x55, 0x3d, 0x95, 0x57, 0x3f, 0x97, 0x5c, 0x42, 0x9c, 0x37, 0x28, 0x5e, 0x5b,
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__PLAIN_TEXT_DATA /* extended_example/sb_image3.bin */ 0xc3, 0x1b, 0x35, 0xfc, 0xc8, 0xd4, 0x8a, 0x28, 0x55, 0x99, 0x3e, 0x74, 0x04, 0x03, 0x04, 0x79, 0x3e, 0x7f, 0x7b, 0x52, 0x97, 0x53, 0x28, 0x7b, 0x54, 0x2c, 0x8c, 0x5c, 0x34, 0x94, 0x5e, 0x39, 0x94, 0x4c, 0x24, 0x8c, 0x5b, 0x3a, 0x8e, 0x54, 0x2c, 0x98, 0x33, 0x0b, 0x7d, 0x5c, 0x3c, 0x9b, 0x55, 0x3a, 0x8a, 0x6e, 0x54, 0x9d, 0x3e, 0x1c, 0x84, 0x43, 0x24, 0x84, 0x4c, 0x2c, 0x8c, 0x54, 0x34, 0x94, 0x44, 0x24, 0x8c, 0x4c, 0x2c, 0x99, 0x56, 0x3a, 0x94, 0x57, 0x3c, 0x97, 0x5c, 0x40, 0x9c, 0x5c, 0x44, 0x94, 0x46, 0x35, 0x6e, 0x64, 0x4d, 0x9c, 0x74, 0x60, 0xa1, 0x4c, 0x34, 0x8c, 0x54, 0x3c, 0x94, 0x55, 0x3d, 0x95, 0x57, 0x3f, 0x97, 0x5c, 0x42, 0x9c, 0x37, 0x28, 0x5e, 0x5b,
+
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA_LENGTH /* sb_image1_enc.bin */ 112
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA_LENGTH /* sb_image2_enc.bin */ 112
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA_LENGTH /* sb_image3_enc.bin */ 112
+#define RUNIT_SECURE_BOOT__IMAGE_1_BIN__PLAIN_TEXT_DATA_LENGTH /* sb_image1.bin */ 112
+#define RUNIT_SECURE_BOOT__IMAGE_2_BIN__PLAIN_TEXT_DATA_LENGTH /* sb_image2.bin */ 112
+#define RUNIT_SECURE_BOOT__IMAGE_3_BIN__PLAIN_TEXT_DATA_LENGTH /* sb_image3.bin */ 112
+
+#endif /* RUNIT_SECURE_BOOT_SKIP_TEST */
+
+#define RUNIT_EXPECTED_SW_VERSION 5
+
+#if !RUNIT_SECURE_BOOT_SKIP_TEST
+/************************************************************
+ *
+ * types
+ *
+ ************************************************************/
+typedef struct RunItBinaryFile_t
+{
+    /** mainly for debug */
+    const char* name;
+    /** length of data */
+    uint32_t length;
+    /** the binary data */
+    uint8_t* data;
+} RunItBinaryFile_t;
+
+typedef struct RunItSecureBoot_SwCompEnc_t
+{
+    /** offset of image in flash */
+    uint32_t flashAddr;
+    /** address where to load the image in host's address space */
+    uint32_t virtualHostOffset;
+    /** binary file itself */
+    RunItBinaryFile_t* swCompBin;
+    /** plain text binary file used to compare result */
+    RunItBinaryFile_t* swCompPlainTextBin;
+} RunItSecureBoot_SwCompEnc_t;
+
+typedef struct RunItSecureBootCertInfo_t
+{
+    RunItBinaryFile_t* cert;
+    uint32_t storeFlashAddress;
+} RunItSecureBootCertInfo_t;
+
+typedef struct RunItSecureBoot_CertChain_t
+{
+    /** An Arrays of Maximum number of certificates */
+    RunItSecureBootCertInfo_t certArr[RUNIT_MAX_CHAIN_LENGTH];
+    /** a list of images in this certificate */
+    RunItSecureBoot_SwCompEnc_t *cntCompsInfo;
+    /** amount of images is the list */
+    uint8_t numOfSwCompImg;
+    uint32_t expSwVersion;
+}RunItSecureBoot_CertChain_t;
+
+/************************************************************
+ *
+ * static function prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_loadParams(RunItBinaryFile_t* pCertBin,
+                                     uint32_t flashAddr,
+                                     RunItSecureBoot_SwCompEnc_t *pListOfSWComps,
+                                     uint32_t numOfSwComps);
+static RunItError_t runIt_flashLoadSecureBootCertificates(void);
+static RunItError_t runIt_prepareFlash(void);
+
+/************************************************************
+ *
+ * variables
+ *
+ ************************************************************/
+static uint32_t OTP_SECURE_2_HBK128_VALUES[] = {
+
+    0x01020408,
+    0x01010101,
+    0x01020408,
+    0x02020202,
+    0x01020408,
+    0x04040404,
+    0x01020408,
+    0x08080808,
+    0x04030201,
+    0x08070605,
+    0x0c0b0a09,
+    0x000f0e0d,
+    0xa68dc2f8,
+    0xb7ae0c04,
+    0x0bd8d969,
+    0xb7cb523d,
+    0x3c3f60e0,
+    0x21f7b953,
+    0xfe56a24d,
+    0x4e3ec4ef,
+    0xc21f3c40,
+    0x2ff17bda,
+    0xe93eb506,
+    0x9aa54f0b,
+    0x4ade752b,
+    0x00000000,
+    0x00000000,
+    0x00000000,
+    0x00000000,
+    0xa68dc2f8,
+    0xb7ae0c04,
+    0x0bd8d969,
+    0xb7cb523d,
+    0x003f0038,
+    0x00000001,
+    0x00000000,
+    0x00000007,
+    0x00000000,
+    0x00000000,
+    0x00000000,
+    0x00000000,
+    0x00000000,
+    0x00000000,
+    0x00000000,
+
+//    /*  [0x00-0x07]: 256bit Device root key (HUK) */
+//    0x01020408, 0x01010101, 0x01020408, 0x02020202, 0x01020408, 0x04040404, 0x01020408, 0x08080808,
+//    /*  [0x08-0x0B]: 128bit ICV Provosioning secret (Kpicv) */
+//    0xEEEEAAAA, 0x11115555, 0x11115555, 0xEEEEAAAA,
+//    /*  [0x0C-0x0F]: 128bit ICV Provosioning secret (Kceicv) */
+//    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+//    /*  [0x10]: manufacturer programmed flag */
+//    0x3C0040E0,
+//    /*  [0x11-0x14]:  HBK0 */
+//    0x21F7B953, 0xFE56A24D, 0x4E3EC4EF, 0xC21F3C40,
+//    /*  [0x15-0x18]: HBK1 */
+//    0x2FF17BDA, 0xE93EB506, 0x9AA54F0B, 0x4ADE752B,
+//    /*  [0x19-0x1C]: 128bit OEM provisioning secret (Kcp) */
+//    0x0000AAAA,  0x11115555, 0x11115555, 0x0000AAAA,
+//    /*  [0x1D-0x20]: 128bit OEM code encryption secret (Kce) */
+//    0x00000000, 0x00000000, 0x00000000, 0x00000000,
+//    /*  [0x21]: OEM programmed flag */
+//    0x00005838,
+//    /*  [0x22-0x23]: Hbk0 trusted FW min version */
+//    0x00000001, 0x00000000,
+//    /*  [0x24-0x26]: Hbk1 trusted FW min version */
+//    0x00000003, 0x00000000, 0x00000000,
+//    /*  [0x27]: general purpose configuration flag */
+//    0x00000000,
+//    /*  [0x28-0x2B] - 128b DCU lock mask */
+//    0x55551111, 0xAAAAEEEE, 0x55551111, 0xAAAAEEEE,
+
+};
+
+uint8_t runItsecureBoot_Cert_1_Bin_data[] = { RUNIT_SECURE_BOOT__CERT_1_BIN__DATA };
+
+uint8_t runItsecureBoot_Cert_2_Bin_data[] = { RUNIT_SECURE_BOOT__CERT_2_BIN__DATA };
+
+uint8_t runItsecureBoot_Cert_3_Bin_data[] = { RUNIT_SECURE_BOOT__CERT_3_BIN__DATA };
+
+uint8_t runItsecureBoot_image1bin_data[] = { RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA };
+
+uint8_t runItsecureBoot_image2bin_data[] = { RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA };
+
+uint8_t runItsecureBoot_image3bin_data[] = { RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA };
+
+uint8_t runItsecureBoot_image1bin_plainTextData[] = { RUNIT_SECURE_BOOT__IMAGE_1_BIN__PLAIN_TEXT_DATA };
+
+uint8_t runItsecureBoot_image2bin_plainTextData[] = { RUNIT_SECURE_BOOT__IMAGE_2_BIN__PLAIN_TEXT_DATA };
+
+uint8_t runItsecureBoot_image3bin_plainTextData[] = { RUNIT_SECURE_BOOT__IMAGE_3_BIN__PLAIN_TEXT_DATA };
+
+RunItBinaryFile_t runItsecureBoot_key1CertBin =
+{
+    "KeyCert1" ,
+    RUNIT_SECURE_BOOT__CERT_1_BIN__DATA_LENGTH,
+    runItsecureBoot_Cert_1_Bin_data
+};
+
+RunItBinaryFile_t runItsecureBoot_key2CertBin =
+{
+    "KeyCert2" ,
+    RUNIT_SECURE_BOOT__CERT_2_BIN__DATA_LENGTH,
+    runItsecureBoot_Cert_2_Bin_data
+};
+
+RunItBinaryFile_t runItsecureBoot_contentEncCertBin =
+{
+    "ContentCert" ,
+    RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH,
+    runItsecureBoot_Cert_3_Bin_data
+};
+
+RunItBinaryFile_t runItsecureBoot_image1bin =
+{
+    "Image1" ,
+    RUNIT_SECURE_BOOT__IMAGE_1_BIN__DATA_LENGTH,
+    runItsecureBoot_image1bin_data,
+
+};
+
+RunItBinaryFile_t runItsecureBoot_image2bin =
+{
+    "Image2" ,
+    RUNIT_SECURE_BOOT__IMAGE_2_BIN__DATA_LENGTH,
+    runItsecureBoot_image2bin_data
+};
+
+RunItBinaryFile_t runItsecureBoot_image3bin =
+{
+    "Image3" ,
+    RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA_LENGTH,
+    runItsecureBoot_image3bin_data
+};
+
+RunItBinaryFile_t runItsecureBoot_image1PlainTextbin =
+{
+    "plainTextImage1" ,
+    RUNIT_SECURE_BOOT__IMAGE_1_BIN__PLAIN_TEXT_DATA_LENGTH,
+    runItsecureBoot_image1bin_plainTextData
+};
+
+RunItBinaryFile_t runItsecureBoot_image2PlainTextbin =
+{
+    "plainTextImage2" ,
+    RUNIT_SECURE_BOOT__IMAGE_2_BIN__PLAIN_TEXT_DATA_LENGTH,
+    runItsecureBoot_image2bin_plainTextData
+};
+
+RunItBinaryFile_t runItsecureBoot_image3PlainTextbin =
+{
+    "plainTextImage3" ,
+    RUNIT_SECURE_BOOT__IMAGE_3_BIN__PLAIN_TEXT_DATA_LENGTH,
+    runItsecureBoot_image3bin_plainTextData
+};
+
+RunItSecureBoot_SwCompEnc_t runItsecureBoot_cntCertEnc[] =
+{
+    {
+        RUNIT_SECURE_BOOT__IMAGE_PKG_1_FLASH_ADDRESS,
+        RUNIT_SECURE_BOOT__IMAGE_1_BIN__LOAD_ADDRESS,
+        &runItsecureBoot_image1bin,
+        &runItsecureBoot_image1PlainTextbin,
+    },
+    {
+        RUNIT_SECURE_BOOT__IMAGE_PKG_2_FLASH_ADDRESS,
+        RUNIT_SECURE_BOOT__IMAGE_2_BIN__LOAD_ADDRESS,
+        &runItsecureBoot_image2bin,
+        &runItsecureBoot_image2PlainTextbin,
+    },
+    {
+        RUNIT_SECURE_BOOT__IMAGE_PKG_3_FLASH_ADDRESS,
+        RUNIT_SECURE_BOOT__IMAGE_3_BIN__LOAD_ADDRESS,
+        &runItsecureBoot_image3bin,
+        &runItsecureBoot_image3PlainTextbin,
+    }
+};
+
+const RunItSecureBoot_CertChain_t runIt_secureBoot_CertChain = {
+    {
+        /* 0 length in binary file indicates that certificate is not in use */
+        { &runItsecureBoot_key1CertBin, RUNIT_SECURE_BOOT__KEY_PKG_1_FLASH_ADDRESS},
+        { &runItsecureBoot_key2CertBin, RUNIT_SECURE_BOOT__KEY_PKG_2_FLASH_ADDRESS},
+        { &runItsecureBoot_contentEncCertBin, RUNIT_SECURE_BOOT__CONTENT_PKG_1_FLASH_ADDRESS}
+    },
+    runItsecureBoot_cntCertEnc,
+    ARRAY_SIZE(runItsecureBoot_cntCertEnc),
+    RUNIT_EXPECTED_SW_VERSION
+};
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+/**
+ * @brief                   Load a certificate and a set of images to the flash as part of preparation towards the test.
+ *
+ * @param pCertBin          [input]  The binary to load to flash
+ * @param flashAddr         [input] The address to load to
+ * @param pListOfSWComps    [input] list of images to load
+ * @param numOfSwComps      [input] number of images in list
+ *
+ * @return                  RUNIT_ERROR__OK on success, RUNIT_ERROR__FAIL otherwise
+ */
+static RunItError_t runIt_loadParams(RunItBinaryFile_t* pCertBin,
+                                     uint32_t flashAddr,
+                                     RunItSecureBoot_SwCompEnc_t *pListOfSWComps,
+                                     uint32_t numOfSwComps)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+    uint32_t imageIndex;
+
+    RUNIT_PRINT_DBG("Loading cert[%s] to flash at offset[%#"PRIxPTR"]\n", pCertBin->name, (uintptr_t)flashAddr);
+
+    rc = runIt_flashWrite(flashAddr, pCertBin->data, pCertBin->length);
+    if (rc != RUNIT_ERROR__OK)
+    {
+        RUNIT_PRINT_ERROR("failed to load cert[%s] to flash at offset[%#"PRIxPTR"]\n", pCertBin->name, (uintptr_t)flashAddr);
+    }
+
+    for (imageIndex = 0; imageIndex < numOfSwComps; ++imageIndex)
+    {
+        uint32_t imageFlashAddr = pListOfSWComps[imageIndex].flashAddr;
+        RunItBinaryFile_t* pSwCompBin = pListOfSWComps[imageIndex].swCompBin;
+
+        RUNIT_PRINT_DBG("Loading image[%s] to flash at offset[%#"PRIxPTR"]\n", pSwCompBin->name, (uintptr_t)imageFlashAddr);
+
+        RUNIT_ASSERT(runIt_flashWrite(imageFlashAddr, pSwCompBin->data, pSwCompBin->length) == RUNIT_ERROR__OK);
+    }
+
+bail:
+    return rc;
+}
+
+/**
+ * @brief               Load the relevant boot certificates to Flash
+ *
+ * @return              RUNIT_ERROR__OK on success, RUNIT_ERROR__FAIL otherwise
+ */
+static RunItError_t runIt_flashLoadSecureBootCertificates(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const RunItSecureBoot_CertChain_t* pCertChain = &runIt_secureBoot_CertChain;
+    uint8_t chainIndex = 0;
+
+    const RunItSecureBootCertInfo_t *pCertInfo = NULL;
+
+    /* load Key certificate to Flash file */
+    pCertInfo = &pCertChain->certArr[chainIndex++];
+    RUNIT_ASSERT(runIt_loadParams(pCertInfo->cert,
+                                  pCertInfo->storeFlashAddress,
+                                  NULL,
+                                  0) == RUNIT_ERROR__OK);
+
+
+    /* load Key certificate to Flash file */
+    pCertInfo = &pCertChain->certArr[chainIndex++];
+    RUNIT_ASSERT(runIt_loadParams(pCertInfo->cert,
+                                  pCertInfo->storeFlashAddress,
+                                  NULL,
+                                  0) == RUNIT_ERROR__OK);
+
+
+    /* load Key certificate to Flash file */
+    pCertInfo = &pCertChain->certArr[chainIndex++];
+    RUNIT_ASSERT(runIt_loadParams(pCertInfo->cert,
+                                  pCertInfo->storeFlashAddress,
+                                  pCertChain->cntCompsInfo,
+                                  pCertChain->numOfSwCompImg) == RUNIT_ERROR__OK);
+
+bail:
+    return rc;
+}
+
+static RunItError_t runIt_prepareOtp(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    RUNIT_ASSERT(runIt_burnOtp((unsigned int *)OTP_SECURE_2_HBK128_VALUES, CC_MNG_LCS_SEC_ENABLED) == RUNIT_ERROR__OK);
+
+bail:
+    return rc;
+}
+
+static RunItError_t runIt_prepareFlash(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    RUNIT_ASSERT(runIt_flashInit(RUNIT_FLASH_SIZE) == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_flashLoadSecureBootCertificates() == RUNIT_ERROR__OK);
+
+bail:
+    return rc;
+}
+
+RunItError_t runIt_secureBoot(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const uint32_t LAST_IMAGE = 2;
+
+    CCSbCertInfo_t sbCertInfoCtx;
+
+    uint32_t *pWspace = NULL;
+    uint32_t *pImage3Ptr = NULL;
+    uint32_t *pCntCertPtr = NULL;
+
+    RunItPtr wspacePtr;
+    RunItPtr image3Ptr;
+    RunItPtr cntCertPtr;
+
+    const char* TEST_NAME = "SecureBoot";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    memset((uint8_t*) &sbCertInfoCtx, 0x0, sizeof(sbCertInfoCtx));
+
+    ALLOC32(wspacePtr, pWspace, CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES);
+    ALLOC32(cntCertPtr, pCntCertPtr, CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES);
+    ALLOC32(image3Ptr, pImage3Ptr, CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES);
+
+    /* read modify write certificate */
+    runIt_flashRead(RUNIT_SECURE_BOOT__CONTENT_PKG_1_FLASH_ADDRESS, (uint8_t*)pCntCertPtr, RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH);
+
+    RUNIT_ASSERT_API(mbedtls_sb_sw_image_store_address_change(pCntCertPtr,
+                                                              RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH,
+                                                              (CCAddr_t) RUNIT_SECURE_BOOT__IMAGE_PKG_3_NEW_FLASH_ADDRESS,
+                                                              LAST_IMAGE) == CC_OK);
+
+    runIt_flashWrite(RUNIT_SECURE_BOOT__CONTENT_PKG_1_FLASH_ADDRESS, (uint8_t*)pCntCertPtr, RUNIT_SECURE_BOOT__CERT_3_BIN__DATA_LENGTH);
+
+    /* move image 3 to new location */
+    runIt_flashRead(RUNIT_SECURE_BOOT__IMAGE_PKG_3_FLASH_ADDRESS, (uint8_t*)pImage3Ptr, RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA_LENGTH);
+    runIt_flashWrite(RUNIT_SECURE_BOOT__IMAGE_PKG_3_NEW_FLASH_ADDRESS, (uint8_t*)pImage3Ptr, RUNIT_SECURE_BOOT__IMAGE_3_BIN__DATA_LENGTH);
+
+    /* verify images and load them */
+    RUNIT_ASSERT_API(mbedtls_sb_cert_chain_cerification_init(&sbCertInfoCtx) == CC_OK);
+
+    RUNIT_ASSERT_API(mbedtls_sb_cert_verify_single((CCSbFlashReadFunc)runIt_flashReadWrap,
+                                                   NULL,
+                                                   RUNIT_SECURE_BOOT__KEY_PKG_1_FLASH_ADDRESS,
+                                                   &sbCertInfoCtx,
+                                                   NULL,
+                                                   0,
+                                                   pWspace,
+                                                   CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES) == CC_OK);
+
+    RUNIT_ASSERT_API(mbedtls_sb_cert_verify_single((CCSbFlashReadFunc)runIt_flashReadWrap,
+                                                   NULL,
+                                                   RUNIT_SECURE_BOOT__KEY_PKG_2_FLASH_ADDRESS,
+                                                   &sbCertInfoCtx,
+                                                   NULL,
+                                                   0,
+                                                   pWspace,
+                                                   CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES) == CC_OK);
+
+    RUNIT_ASSERT_API(mbedtls_sb_cert_verify_single((CCSbFlashReadFunc)runIt_flashReadWrap,
+                                                   NULL,
+                                                   RUNIT_SECURE_BOOT__CONTENT_PKG_1_FLASH_ADDRESS,
+                                                   &sbCertInfoCtx,
+                                                   NULL,
+                                                   0,
+                                                   pWspace,
+                                                   CC_SB_MIN_WORKSPACE_SIZE_IN_BYTES) == CC_OK);
+
+    /* no need to verify images were loaded succesfully since we do not allow loading in runtime */
+
+bail:
+
+    FREE_IF_NOT_NULL(wspacePtr);
+    FREE_IF_NOT_NULL(cntCertPtr);
+    FREE_IF_NOT_NULL(image3Ptr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "IS_X509[%s]", IS_X509);
+    return rc;
+}
+
+#endif /* !RUNIT_SECURE_BOOT_SKIP_TEST */
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_secureBootTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if !RUNIT_SECURE_BOOT_SKIP_TEST
+    const char* TEST_NAME = "SecureBoot";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_prepareFlash() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_prepareOtp() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_secureBoot() == RUNIT_ERROR__OK);
+
+bail:
+
+    runIt_flashFinalize();
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+#endif /* !RUNIT_SECURE_BOOT_SKIP_TEST */
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_sha.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_sha.c
new file mode 100644
index 0000000..20871b0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_sha.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/sha1.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+#include "mbedtls/timing.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+/************************************************************
+ *
+ * static functions prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_sha1Test(void);
+static RunItError_t runIt_sha224Test(void);
+static RunItError_t runIt_sha256Test(void);
+static RunItError_t runIt_sha384Test(void);
+static RunItError_t runIt_sha512Test(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_sha1Test(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_SHA1_C)
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA1.pdf */
+    static const char* INPUT_MESSAGE = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+    static const uint8_t DIGEST[] = { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 };
+
+    unsigned char sha1sum[20];
+    RunItPtr ctxPtr;
+    RunItPtr ctxClonedPtr;
+
+    mbedtls_sha1_context *pCtx = NULL;
+    mbedtls_sha1_context *pCtxCloned = NULL;
+
+    const char* TEST_NAME = "SHA1";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_sha1_context, ctxPtr, pCtx);
+    ALLOC_STRUCT(mbedtls_sha1_context, ctxClonedPtr, pCtxCloned);
+
+    /* Initialize sha engine */
+    RUNIT_API(mbedtls_sha1_init(pCtx));
+    RUNIT_ASSERT(mbedtls_sha1_starts_ret(pCtx) == 0);
+    RUNIT_ASSERT(mbedtls_sha1_update_ret(pCtx, (const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE)) == 0);
+    RUNIT_API(mbedtls_sha1_clone(pCtxCloned, pCtx));
+    RUNIT_ASSERT(mbedtls_sha1_finish_ret(pCtxCloned, sha1sum) == 0);
+
+    RUNIT_PRINT_BUF(sha1sum, 20, "result");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha1sum, DIGEST, 20) == 0);
+
+    /* test the wrapper function too */
+    memset(sha1sum, 0, sizeof(sha1sum));
+
+    RUNIT_API(mbedtls_sha1((const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE), sha1sum));
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha1sum, DIGEST, 20) == 0);
+
+bail:
+    RUNIT_API(mbedtls_sha1_free(pCtx));
+    RUNIT_API(mbedtls_sha1_free(pCtxCloned));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(ctxClonedPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+#endif /* MBEDTLS_SHA1_C */
+    return rc;
+}
+
+static RunItError_t runIt_sha224Test(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined(MBEDTLS_SHA256_C)
+    const int IS_SHA_224 = 1;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA224.pdf */
+    static const char* INPUT_MESSAGE = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+    static const uint8_t DIGEST[] = { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, 0x52, 0x52, 0x25, 0x25 };
+
+    unsigned char sha224sum[28];
+    RunItPtr ctxPtr;
+    RunItPtr ctxClonedPtr;
+
+    mbedtls_sha256_context *pCtx = NULL;
+    mbedtls_sha256_context *pCtxCloned = NULL;
+
+    const char* TEST_NAME = "SHA224";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_sha256_context, ctxPtr, pCtx);
+    ALLOC_STRUCT(mbedtls_sha256_context, ctxClonedPtr, pCtxCloned);
+
+    /* Initialize sha engine */
+    RUNIT_API(mbedtls_sha256_init(pCtx));
+    RUNIT_ASSERT(mbedtls_sha256_starts_ret(pCtx, IS_SHA_224) == 0);
+    RUNIT_ASSERT(mbedtls_sha256_update_ret(pCtx, (const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE)) == 0);
+    RUNIT_API(mbedtls_sha256_clone(pCtxCloned, pCtx));
+    RUNIT_ASSERT(mbedtls_sha256_finish_ret(pCtxCloned, sha224sum) == 0);
+
+    RUNIT_PRINT_BUF(sha224sum, 28, "result");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha224sum, DIGEST, 28) == 0);
+
+    /* test the wrapper function too */
+    memset(sha224sum, 0, sizeof(sha224sum));
+
+    RUNIT_API(mbedtls_sha256((const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE), sha224sum, IS_SHA_224));
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha224sum, DIGEST, 28) == 0);
+
+bail:
+    RUNIT_API(mbedtls_sha256_free(pCtx));
+    RUNIT_API(mbedtls_sha256_free(pCtxCloned));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(ctxClonedPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+#endif /* MBEDTLS_SHA256_C */
+    return rc;
+}
+
+static RunItError_t runIt_sha256Test(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_SHA256_C)
+    const int IS_SHA_224 = 0;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA256.pdf */
+    static const char* INPUT_MESSAGE = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+    static const uint8_t DIGEST[] = { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 };
+
+    unsigned char sha256sum[32];
+    RunItPtr ctxPtr;
+    RunItPtr ctxClonedPtr;
+
+    mbedtls_sha256_context *pCtx = NULL;
+    mbedtls_sha256_context *pCtxCloned = NULL;
+
+    const char* TEST_NAME = "SHA256";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_sha256_context, ctxPtr, pCtx);
+    ALLOC_STRUCT(mbedtls_sha256_context, ctxClonedPtr, pCtxCloned);
+
+    /* Initialize sha engine */
+    RUNIT_API(mbedtls_sha256_init(pCtx));
+    RUNIT_ASSERT(mbedtls_sha256_starts_ret(pCtx, IS_SHA_224) == 0);
+    RUNIT_ASSERT(mbedtls_sha256_update_ret(pCtx, (const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE)) == 0);
+    RUNIT_API(mbedtls_sha256_clone(pCtxCloned, pCtx));
+    RUNIT_ASSERT(mbedtls_sha256_finish_ret(pCtxCloned, sha256sum) == 0);
+
+    RUNIT_PRINT_BUF(sha256sum, 32, "result");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha256sum, DIGEST, 32) == 0);
+
+    /* test the wrapper function too */
+    memset(sha256sum, 0, sizeof(sha256sum));
+    RUNIT_API(mbedtls_sha256((const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE), sha256sum, IS_SHA_224));
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha256sum, DIGEST, 32) == 0);
+
+bail:
+    RUNIT_API(mbedtls_sha256_free(pCtx));
+    RUNIT_API(mbedtls_sha256_free(pCtxCloned));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(ctxClonedPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+#endif /* MBEDTLS_SHA256_C */
+    return rc;
+}
+
+static RunItError_t runIt_sha384Test(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_SHA512_C)
+    const int IS_SHA_384 = 1;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA384.pdf */
+    static const char* INPUT_MESSAGE = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+    static const uint8_t DIGEST[] = { 0x09,0x33,0x0C,0x33,0xF7,0x11,0x47,0xE8,0x3D,0x19,0x2F,0xC7,0x82,0xCD,0x1B,0x47,0x53,0x11,0x1B,0x17,0x3B,0x3B,0x05,0xD2,0x2F,0xA0,0x80,0x86,0xE3,0xB0,0xF7,0x12,0xFC,0xC7,0xC7,0x1A,0x55,0x7E,0x2D,0xB9,0x66,0xC3,0xE9,0xFA,0x91,0x74,0x60,0x39};
+
+    unsigned char sha512sum[48];
+    RunItPtr ctxPtr;
+    RunItPtr ctxClonedPtr;
+
+    mbedtls_sha512_context *pCtx = NULL;
+    mbedtls_sha512_context *pCtxCloned = NULL;
+
+    const char* TEST_NAME = "SHA384";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_sha512_context, ctxPtr, pCtx);
+    ALLOC_STRUCT(mbedtls_sha512_context, ctxClonedPtr, pCtxCloned);
+
+    /* Initialize sha engine */
+    RUNIT_API(mbedtls_sha512_init(pCtx));
+    RUNIT_API(mbedtls_sha512_starts(pCtx, IS_SHA_384));
+    RUNIT_API(mbedtls_sha512_update(pCtx, (const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE)));
+    RUNIT_API(mbedtls_sha512_clone(pCtxCloned, pCtx));
+    RUNIT_API(mbedtls_sha512_finish(pCtxCloned, sha512sum));
+
+    RUNIT_PRINT_BUF(sha512sum, 48, "result");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha512sum, DIGEST, 48) == 0);
+
+    /* test the wrapper function too */
+    memset(sha512sum, 0, sizeof(sha512sum));
+    RUNIT_API(mbedtls_sha512((const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE), sha512sum, IS_SHA_384));
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha512sum, DIGEST, 48) == 0);
+
+bail:
+    RUNIT_API(mbedtls_sha512_free(pCtx));
+    RUNIT_API(mbedtls_sha512_free(pCtxCloned));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(ctxClonedPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+#endif /* MBEDTLS_SHA512_C */
+    return rc;
+}
+
+static RunItError_t runIt_sha512Test(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined(MBEDTLS_SHA512_C)
+    const int IS_SHA_384 = 0;
+
+    /* https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-and-Guidelines/documents/examples/SHA256.pdf */
+    static const char* INPUT_MESSAGE = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu";
+    static const uint8_t DIGEST[] = { 0x8E,0x95,0x9B,0x75,0xDA,0xE3,0x13,0xDA,0x8C,0xF4,0xF7,0x28,0x14,0xFC,0x14,0x3F,0x8F,0x77,0x79,0xC6,0xEB,0x9F,0x7F,0xA1,0x72,0x99,0xAE,0xAD,0xB6,0x88,0x90,0x18,0x50,0x1D,0x28,0x9E,0x49,0x00,0xF7,0xE4,0x33,0x1B,0x99,0xDE,0xC4,0xB5,0x43,0x3A,0xC7,0xD3,0x29,0xEE,0xB6,0xDD,0x26,0x54,0x5E,0x96,0xE5,0x5B,0x87,0x4B,0xE9,0x09 };
+
+    unsigned char sha512sum[64];
+    RunItPtr ctxPtr;
+    RunItPtr ctxClonedPtr;
+
+    mbedtls_sha512_context *pCtx = NULL;
+    mbedtls_sha512_context *pCtxCloned = NULL;
+
+    const char* TEST_NAME = "SHA512";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_sha512_context, ctxPtr, pCtx);
+    ALLOC_STRUCT(mbedtls_sha512_context, ctxClonedPtr, pCtxCloned);
+
+    /* Initialize sha engine */
+    RUNIT_API(mbedtls_sha512_init(pCtx));
+    RUNIT_API(mbedtls_sha512_starts(pCtx, IS_SHA_384));
+    RUNIT_API(mbedtls_sha512_update(pCtx, (const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE)));
+    RUNIT_API(mbedtls_sha512_clone(pCtxCloned, pCtx));
+    RUNIT_API(mbedtls_sha512_finish(pCtxCloned, sha512sum));
+
+    RUNIT_PRINT_BUF(sha512sum, 64, "result");
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha512sum, DIGEST, 64) == 0);
+
+    /* test the wrapper function too */
+    memset(sha512sum, 0, sizeof(sha512sum));
+    RUNIT_API(mbedtls_sha512((const unsigned char*)INPUT_MESSAGE, strlen(INPUT_MESSAGE), sha512sum, IS_SHA_384));
+
+    /* compare result */
+    RUNIT_ASSERT(memcmp(sha512sum, DIGEST, 64) == 0);
+
+bail:
+    RUNIT_API(mbedtls_sha512_free(pCtx));
+    RUNIT_API(mbedtls_sha512_free(pCtxCloned));
+
+    FREE_IF_NOT_NULL(ctxPtr);
+    FREE_IF_NOT_NULL(ctxClonedPtr);
+
+    RUNIT_SUB_TEST_RESULT(TEST_NAME);
+#endif /* MBEDTLS_SHA512_C */
+    return rc;
+}
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_shaTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+    const char* TEST_NAME = "HASH";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_sha1Test() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_sha224Test() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_sha256Test() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_sha384Test() == RUNIT_ERROR__OK);
+    RUNIT_ASSERT(runIt_sha512Test() == RUNIT_ERROR__OK);
+
+bail:
+    RUNIT_TEST_RESULT(TEST_NAME);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_srp.c b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_srp.c
new file mode 100644
index 0000000..99b99b7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_srp.c
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <limits.h>
+
+/* mbedtls lib */
+#include "mbedtls/timing.h"
+
+/* CC lib */
+#if defined (CC_CONFIG_SUPPORT_SRP)
+#include "mbedtls_cc_srp.h"
+#endif
+
+/* pal */
+#include "test_pal_mem.h"
+
+/* local */
+#include "run_integration_pal_log.h"
+#include "run_integration_test.h"
+#include "run_integration_helper.h"
+
+
+/************************************************************
+ *
+ * defines
+ *
+ ************************************************************/
+#define RUNIT_SRP_DATA_SIZE_MAX 30
+
+/************************************************************
+ *
+ * static functions prototypes
+ *
+ ************************************************************/
+static RunItError_t runIt_srp(void);
+
+/************************************************************
+ *
+ * static functions
+ *
+ ************************************************************/
+static RunItError_t runIt_srp(void)
+{
+
+    RunItError_t rc = RUNIT_ERROR__OK;
+
+#if defined (CC_CONFIG_SUPPORT_SRP)
+    static char userName[] = "alice";
+    static size_t userNameSize = 5;
+    static char userPwd[] = "password123";
+    static size_t userPwdSize = 11;
+    static mbedtls_srp_version_t srpVer = CC_SRP_VER_HK;
+    static mbedtls_srp_group_param groupParams = {{0xEE,0xAF,0x0A,0xB9,0xAD,0xB3,0x8D,0xD6,0x9C,0x33,0xF8,0x0A,0xFA,0x8F,0xC5,0xE8,0x60,0x72,0x61,0x87,0x75,0xFF,0x3C,0x0B,0x9E,0xA2,0x31,0x4C,0x9C,0x25,0x65,0x76,0xD6,0x74,0xDF,0x74,0x96,0xEA,0x81,0xD3,0x38,0x3B,0x48,0x13,0xD6,0x92,0xC6,0xE0,0xE0,0xD5,0xD8,0xE2,0x50,0xB9,0x8B,0xE4,0x8E,0x49,0x5C,0x1D,0x60,0x89,0xDA,0xD1,0x5D,0xC7,0xD7,0xB4,0x61,0x54,0xD6,0xB6,0xCE,0x8E,0xF4,0xAD,0x69,0xB1,0x5D,0x49,0x82,0x55,0x9B,0x29,0x7B,0xCF,0x18,0x85,0xC5,0x29,0xF5,0x66,0x66,0x0E,0x57,0xEC,0x68,0xED,0xBC,0x3C,0x05,0x72,0x6C,0xC0,0x2F,0xD4,0xCB,0xF4,0x97,0x6E,0xAA,0x9A,0xFD,0x51,0x38,0xFE,0x83,0x76,0x43,0x5B,0x9F,0xC6,0x1D,0x2F,0xC0,0xEB,0x06,0xE3},0x2,1024,0,{0x0,0x0,0x0,0x0,0x0}};
+    static CCHashOperationMode_t hashMode = CC_HASH_SHA1_mode;
+    static size_t saltSize = 16;
+    static size_t privKeySize = 32;
+
+    // set the addresses in phys contig memory
+    RunItPtr hostCtxPtr;
+    RunItPtr userCtxPtr;
+    RunItPtr xBuffPtr;
+    RunItPtr uBuffPtr;
+    RunItPtr pwdVerifierPtr;
+    RunItPtr pubKeyAPtr;
+    RunItPtr pubKeyBPtr;
+    RunItPtr sessionKeyPtr;
+    RunItPtr userNamePtr;
+    RunItPtr userPwdPtr;
+    RunItPtr saltPtr;
+
+    mbedtls_srp_context *pHostCtx = NULL;
+    mbedtls_srp_context *pUserCtx = NULL;
+    mbedtls_srp_digest *x_Buff = NULL;
+    mbedtls_srp_digest *u_Buff = NULL;
+    mbedtls_srp_modulus *pwdVerifier = NULL;
+    mbedtls_srp_modulus *pubKeyA = NULL;
+    mbedtls_srp_modulus *pubKeyB = NULL;
+    mbedtls_srp_modulus *sessionKey = NULL;
+    char *pUserName = NULL;
+    char *pUserPwd = NULL;
+    uint8_t *pSalt = NULL;
+
+    uint8_t *pPwdVerifier = NULL;
+    uint8_t *pPubKeyA = NULL;
+    uint8_t *pPubKeyB = NULL;
+    uint8_t *pSessionKey = NULL;
+    uint8_t *pX_Buff = NULL;
+    uint8_t *pU_Buff = NULL;
+
+    const char* TEST_NAME = "SRP";
+    RUNIT_SUB_TEST_START(TEST_NAME);
+
+    ALLOC_STRUCT(mbedtls_srp_context, hostCtxPtr, pHostCtx);
+    ALLOC_STRUCT(mbedtls_srp_context, userCtxPtr, pUserCtx);
+    ALLOC_STRUCT(mbedtls_srp_digest, xBuffPtr, x_Buff);
+    ALLOC_STRUCT(mbedtls_srp_digest, uBuffPtr, u_Buff);
+    ALLOC_STRUCT(mbedtls_srp_modulus, pwdVerifierPtr, pwdVerifier);
+    ALLOC_STRUCT(mbedtls_srp_modulus, pubKeyAPtr, pubKeyA);
+    ALLOC_STRUCT(mbedtls_srp_modulus, pubKeyBPtr, pubKeyB);
+    ALLOC_STRUCT(mbedtls_srp_modulus, sessionKeyPtr, sessionKey);
+    ALLOC(userNamePtr, pUserName, RUNIT_SRP_DATA_SIZE_MAX);
+    ALLOC(userPwdPtr, pUserPwd, RUNIT_SRP_DATA_SIZE_MAX);
+    ALLOC(saltPtr, pSalt, saltSize);
+
+    pPwdVerifier = (uint8_t*)*pwdVerifier;
+    pPubKeyA = (uint8_t*)*pubKeyA;
+    pPubKeyB = (uint8_t*)*pubKeyB;
+    pSessionKey = (uint8_t*)*sessionKey;
+    pX_Buff = (uint8_t*)*x_Buff;
+    pU_Buff = (uint8_t*)*u_Buff;
+
+
+    // copy buffers to contig mememory
+    memcpy(pUserName, (uint8_t *) userName, userNameSize);
+    memcpy(pUserPwd, (uint8_t *) userPwd, userPwdSize);
+
+    // init host ctx
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_init(CC_SRP_HOST,
+                                        srpVer,
+                                        groupParams.modulus,
+                                        groupParams.gen,
+                                        groupParams.modSizeInBits,
+                                        hashMode,
+                                        (uint8_t *)pUserName,
+                                        userNameSize,
+                                        (uint8_t *)pUserPwd,
+                                        userPwdSize,
+                                        gpRndContext,
+                                        pHostCtx),
+                             0);
+
+    // init user ctx
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_init(CC_SRP_USER,
+                                        srpVer,
+                                        groupParams.modulus,
+                                        groupParams.gen,
+                                        groupParams.modSizeInBits,
+                                        hashMode,
+                                        (uint8_t *)pUserName,
+                                        userNameSize,
+                                        (uint8_t *)pUserPwd,
+                                        userPwdSize,
+                                        gpRndContext,
+                                        pUserCtx),
+                             0);
+
+    // calculates pSalt & password verifier
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_pwd_ver_create(saltSize, pSalt, pPwdVerifier, pUserCtx), 0);
+
+    // generate host public & private ephemeral key, known as B & b in RFC
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_host_pub_key_create(privKeySize, pPwdVerifier, pPubKeyB, pHostCtx), 0);
+
+    // generate user public & private ephemeral key, known as A & a in RFC
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_user_pub_key_create(privKeySize, pPubKeyA, pUserCtx), 0);
+
+    // calculates the user proof
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_user_proof_calc(saltSize, pSalt, pPubKeyA, pPubKeyB, pU_Buff, pSessionKey, pUserCtx), 0);
+
+    // verify host session key
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_host_proof_verify_and_calc(saltSize, pSalt, pPwdVerifier, pPubKeyA, pPubKeyB, pU_Buff, pX_Buff, pSessionKey, pHostCtx), 0);
+
+    // Verify the host proof
+    RUNIT_ASSERT_WITH_RESULT(mbedtls_srp_user_proof_verify(pSessionKey, pPubKeyA, pU_Buff, pX_Buff, pUserCtx), 0);
+
+bail:
+
+    mbedtls_srp_clear(pUserCtx);
+    mbedtls_srp_clear(pHostCtx);
+
+    FREE_IF_NOT_NULL(hostCtxPtr);
+    FREE_IF_NOT_NULL(userCtxPtr);
+    FREE_IF_NOT_NULL(xBuffPtr);
+    FREE_IF_NOT_NULL(uBuffPtr);
+    FREE_IF_NOT_NULL(pwdVerifierPtr);
+    FREE_IF_NOT_NULL(pubKeyAPtr);
+    FREE_IF_NOT_NULL(pubKeyBPtr);
+    FREE_IF_NOT_NULL(sessionKeyPtr);
+    FREE_IF_NOT_NULL(userNamePtr);
+    FREE_IF_NOT_NULL(userPwdPtr);
+    FREE_IF_NOT_NULL(saltPtr);
+
+    RUNIT_SUB_TEST_RESULT_W_PARAMS(TEST_NAME, "MODE[SHA1] SRP[HK] USER[%"PRIu32"B] PWD[%"PRIu32"B] SALT[%"PRIu32"B] KEY[%"PRIu32"B]",
+                                   (uint32_t)userNameSize, (uint32_t)userPwdSize, (uint32_t)saltSize, (uint32_t)privKeySize);
+#endif
+    return rc;
+
+}
+
+
+/************************************************************
+ *
+ * public functions
+ *
+ ************************************************************/
+RunItError_t runIt_srpTest(void)
+{
+    RunItError_t rc = RUNIT_ERROR__OK;
+#if defined (CC_CONFIG_SUPPORT_SRP)
+    const char* TEST_NAME = "SRP";
+    RUNIT_TEST_START(TEST_NAME);
+
+    RUNIT_ASSERT(runIt_srp() == RUNIT_ERROR__OK);
+
+bail:
+
+    RUNIT_TEST_RESULT(TEST_NAME);
+#else
+    (void) runIt_srp;
+#endif
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_test_api.h b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_test_api.h
new file mode 100644
index 0000000..98356df
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/integration_cc3x/runtime_integration_test/tests/run_integration_test_api.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _RUN_INTEGRATION_TEST_API_H_
+#define _RUN_INTEGRATION_TEST_API_H_
+
+#include "stdint.h"
+
+#include "run_integration_test.h"
+
+RunItError_t runIt_aesTest(void);
+RunItError_t runIt_rsaTest(void);
+RunItError_t runIt_ccmTest(void);
+RunItError_t runIt_gcmTest(void);
+RunItError_t runIt_shaTest(void);
+RunItError_t runIt_ecdsaTest(void);
+RunItError_t runIt_eciesTest(void);
+RunItError_t runIt_ecdhTest(void);
+RunItError_t runIt_ctrDrbgTest(void);
+RunItError_t runIt_keyDerivationTest(void);
+RunItError_t runIt_ChachaTest(void);
+RunItError_t runIt_srpTest(void);
+RunItError_t runIt_macTest(void);
+RunItError_t runIt_dhmTest(void);
+RunItError_t runIt_assetProvTest(void);
+RunItError_t runIt_extDmaTest(void);
+RunItError_t runIt_secureBootTest(void);
+#endif //_RUN_INTEGRATION_TEST_API_H_
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_cclib.c b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_cclib.c
new file mode 100644
index 0000000..da652ed
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_cclib.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include "cc_lib.h"
+#include "test_pal_thread.h"
+#include "test_pal_log.h"
+
+#define  THREAD_STACK_SIZE              (128*1024)
+
+typedef struct LibInitArgs {
+    void* p_rng;
+    void* p_entropy;
+    CCRndWorkBuff_t * rndWorkBuff_ptr;
+} LibInitArgs;
+
+uint32_t threadErr = 0;
+static CCRndContext_t gRndContext_ptr;
+
+static void* Test_LibInit(void *params ){
+    uint32_t rc;
+    LibInitArgs* threadArgs = (LibInitArgs*)params;
+    gRndContext_ptr.rndState = threadArgs->p_rng;
+    gRndContext_ptr.entropyCtx = threadArgs->p_entropy;
+
+    rc = CC_LibInit(&gRndContext_ptr, threadArgs->rndWorkBuff_ptr);
+    threadErr = rc;
+    return((void *)threadErr);
+
+}
+
+int Test_Proj_CC_LibInit_Wrap(void* p_rng, void* p_entropy, CCRndWorkBuff_t * rndWorkBuff_ptr){
+    uint32_t rc = 0;
+    uint32_t priority = Test_PalGetDefaultPriority();
+    int threadRc;
+    ThreadHandle threadHandle;
+    LibInitArgs params;
+
+    params.p_rng = p_rng;
+    params.p_entropy = p_entropy;
+    params.rndWorkBuff_ptr = rndWorkBuff_ptr;
+
+    threadHandle = Test_PalThreadCreate(THREAD_STACK_SIZE, Test_LibInit,
+                    priority, &params, NULL, 0, true);
+
+    if (threadHandle == NULL) {
+        TEST_PRINTF_ERROR("Test_PalThreadCreate failed\n");
+        return -1;
+    }
+
+    /* Wait till thread is complete before main continues */
+    threadRc = Test_PalThreadJoin(threadHandle, (void *)&rc);
+    if (threadRc != 0) {
+        TEST_PRINTF_ERROR("Test_PalThreadJoin failed\n");
+        return -1;
+    }
+
+    threadRc = Test_PalThreadDestroy(threadHandle);
+    if (threadRc != 0) {
+        TEST_PRINTF_ERROR("Test_PalThreadDestroy failed\n");
+    }
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_cclib.h b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_cclib.h
new file mode 100644
index 0000000..10b30b7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_cclib.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _TEST_PROJ_CCLIB_H_
+#define _TEST_PROJ_CCLIB_H_
+
+#include "cc_rnd_common.h"
+
+
+/****************************************************************************/
+/*
+ * @brief This function frees previously allocated resources
+ *
+ * @param[in/out] *pProcessMap - mapping regions
+  *
+ * @return rc - 0 for success, 1 for failure
+ */
+void Test_ProjFree(void);
+
+/****************************************************************************/
+/*
+ * @brief This function
+ *
+ * @param[in/out]
+  *
+ * @return rc -
+ */
+int Test_Proj_CC_LibInit_Wrap(void* p_rng,
+                              void* p_entropy,
+                              CCRndWorkBuff_t * rndWorkBuff_ptr);
+
+#endif //_TEST_PROJ_CCLIB_H_
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_defs.h b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_defs.h
new file mode 100644
index 0000000..d9f0d54
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_defs.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _TEST_PROJ_DEFS_H_
+#define _TEST_PROJ_DEFS_H_
+
+#include <stdint.h>
+
+#include "dx_reg_base_host.h"
+#include "dx_host.h"
+#include "dx_crys_kernel.h"
+#include "dx_env.h"
+#include "dx_nvm.h"
+#include "cc_regs.h"
+
+#define BITS_IN_32BIT_WORD 32
+
+/* Peripheral ID registers values */
+#define TEST_PID_0_VAL      0x000000C0UL
+#define TEST_PID_1_VAL      0x000000B0UL
+#define TEST_PID_2_VAL      0x0000001BUL
+#define TEST_PID_3_VAL      0x00000000UL
+#define TEST_PID_4_VAL      0x00000004UL
+#define TEST_PID_SIZE_WORDS     5
+
+/* Component ID registers values */
+#define TEST_CID_0_VAL      0x0DUL
+#define TEST_CID_1_VAL      0xF0UL
+#define TEST_CID_2_VAL      0x05UL
+#define TEST_CID_3_VAL      0xB1UL
+#define TEST_CID_SIZE_WORDS     4
+
+/* HW KEYS */
+#define TEST_SB_HUK_KEY            0
+#define TEST_SB_KCP_KEY            1
+#define TEST_SB_KCE_KEY            2
+#define TEST_SB_KPICV_KEY          3
+#define TEST_SB_KCEICV_KEY         4
+
+
+#define TEST_PROJ_LCS_CM 0
+#define TEST_PROJ_LCS_DM 1
+#define TEST_PROJ_LCS_SECURE 5
+#define TEST_PROJ_LCS_RMA 7
+#define INVALID_LCS     (-1)
+
+#define TST_SET_ENV_TO_SECURE()                     \
+    do {                                \
+        TEST_WRITE_TEE_ENV_REG( DX_ENV_APB_PPROT_OVERRIDE_REG_OFFSET, 0x9);  \
+    }while(0)
+
+/* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+#define WAIT_NVM_IDLE() \
+    do {                                            \
+        uint32_t regVal;                                \
+        do {                                        \
+            regVal = TEST_READ_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, NVM_IS_IDLE));            \
+            regVal = CC_REG_FLD_GET(0, NVM_IS_IDLE, VALUE, regVal);         \
+        }while( !regVal );                              \
+    }while(0)
+
+/* turn off DFA  */
+#define TURN_DFA_OFF() {\
+    uint32_t regVal;                            \
+    regVal = TEST_READ_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));          \
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, regVal, 0); \
+    CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_DFA_ENABLE_LOCK, regVal, 1);  \
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS)  ,regVal );    \
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, AES_DFA_IS_ON)  ,0 );         \
+}
+
+/****************************************************************************/
+/*                              External API                                */
+/*
+ * @brief This function Maps the proj HW.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_ProjMap(void);
+
+/****************************************************************************/
+/*
+ * @brief This function Maps the proj HW.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return none.
+ */
+void Test_ProjUnmap(void);
+
+/****************************************************************************/
+/*
+ * @brief This function reads LCS register and verifies that LCS value is as expected.
+ *
+ * @param[in] LCS correct value.
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_ProjCheckLcs(uint32_t nextLcs);
+
+
+/****************************************************************************/
+/*
+ * @brief This function reads LCS register, verifies that LCS value is as
+ *          expected and no HW errors exist in HUK, Kcp* and Kce*.
+ *
+ * @param[in] LCS correct value.
+ *
+ * @param[out]
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_ProjCheckLcsAndError(uint32_t  nextLcs);
+
+
+/****************************************************************************/
+/*
+ * @brief This function returns the current LCS value.
+ *
+ * @param[in]
+ *
+ * @param[out] LCS value.
+ *
+ * @return 0.
+ */
+uint32_t Test_ProjGetLcs(uint32_t *lcs);
+
+
+/****************************************************************************/
+/*
+ * @brief This function performs global reset of CC, AO and environment registers.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_ProjPerformPowerOnReset(void);
+
+/****************************************************************************/
+/*
+ * @brief This function resets CC and AO registers.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_ProjPerformColdReset(void);
+
+/****************************************************************************/
+/*
+ * @brief This function resets CC registers.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void Test_ProjPerformWarmReset(void);
+
+/****************************************************************************/
+/*
+ * @brief This function resets CC registers.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return
+ */
+uint32_t Test_ProjVerifyPIDReg(void);
+
+/****************************************************************************/
+/*
+ * @brief This function resets CC registers.
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return
+ */
+uint32_t Test_ProjVerifyCIDReg(void);
+
+
+#endif /* _TEST_PROJ_DEFS_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_hw.c b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_hw.c
new file mode 100644
index 0000000..23fb736
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_hw.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "test_proj.h"
+#include "test_proj_defs.h"
+#include "test_pal_time.h"
+#include "test_pal_log.h"
+
+#include "dx_id_registers.h"
+
+uint32_t Test_ProjCheckLcs(uint32_t  nextLcs)
+{
+    uint32_t regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE();
+
+    /* Read the LCS register */
+    regVal = TEST_READ_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    /* Verify lcs */
+    if(regVal != nextLcs) {
+        TEST_PRINTF_ERROR("actual LCS %d != expected LCS %d", regVal, nextLcs);
+        return TEST_COMPARE_ERR;
+    }
+
+    return TEST_OK;
+}
+
+
+uint32_t Test_ProjCheckLcsAndError(uint32_t  nextLcs)
+{
+    uint32_t regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE();
+
+    /* Read the LCS register */
+    regVal = TEST_READ_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    /* Verify lcs */
+    if(regVal != nextLcs) {
+                TEST_PRINTF_ERROR("actual LCS %d != expected LCS %d", regVal, nextLcs);
+        return TEST_COMPARE_ERR;
+    }
+
+    if ((CC_REG_FLD_GET(0, LCS_REG, ERROR_KDR_ZERO_CNT, regVal) != 0) ||
+            (CC_REG_FLD_GET(0, LCS_REG, ERROR_KPICV_ZERO_CNT, regVal) != 0) ||
+            (CC_REG_FLD_GET(0, LCS_REG, ERROR_KCEICV_ZERO_CNT, regVal) != 0) ||
+        (CC_REG_FLD_GET(0, LCS_REG, ERROR_PROV_ZERO_CNT, regVal) != 0) ||
+            (CC_REG_FLD_GET(0, LCS_REG, ERROR_KCE_ZERO_CNT, regVal) != 0)) {
+                TEST_PRINTF_ERROR("regVal 0x%x indicates error for LCS %d", regVal, nextLcs);
+        return TEST_HW_FAIL_ERR;
+    }
+
+    return TEST_OK;
+}
+
+
+uint32_t Test_ProjGetLcs(uint32_t  *lcs)
+{
+    uint32_t regVal = 0;
+
+    /* poll NVM register to be assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE();
+
+    /* Read the LCS register */
+    regVal = TEST_READ_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, LCS_REG));
+    regVal = CC_REG_FLD_GET(0, LCS_REG, LCS_REG, regVal);
+
+    *lcs = regVal;
+
+    return TEST_OK;
+}
+/* Global Reset of CC and AO and env regs */
+void Test_ProjPerformPowerOnReset(void)
+{
+    TEST_WRITE_TEE_ENV_REG(DX_ENV_CC_POR_N_ADDR_REG_OFFSET , 0x1UL);
+    Test_PalDelay(1000);
+
+    /* poll NVM register to assure that the NVM boot is finished (and LCS and the keys are valid) */
+    WAIT_NVM_IDLE();
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+
+    /* turn off the DFA since Cerberus doesn't support it */
+    TURN_DFA_OFF();
+    return;
+
+}
+
+
+/* Reset both CC and AO regs */
+void Test_ProjPerformColdReset(void)
+{
+    TEST_WRITE_TEE_ENV_REG(DX_ENV_CC_COLD_RST_REG_OFFSET , 0x1UL);
+    Test_PalDelay(1000);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+    /* turn off the DFA since Cerberus doesn't support it */
+    TURN_DFA_OFF();
+    return;
+}
+
+
+/* Reset only CC regs */
+void Test_ProjPerformWarmReset(void)
+{
+    TEST_WRITE_TEE_ENV_REG(DX_ENV_CC_RST_N_REG_OFFSET , 0x1UL);
+    Test_PalDelay(1000);
+
+#ifdef BIG__ENDIAN
+    /* Set DMA endianess to big */
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0xCCUL);
+#else /* LITTLE__ENDIAN */
+    TEST_WRITE_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, HOST_ENDIAN) , 0x00UL);
+#endif
+    return;
+
+}
+
+uint32_t Test_ProjVerifyPIDReg(void)
+{
+    uint32_t i = 0;
+    uint32_t pidReg = 0;
+    uint32_t pidValTable[TEST_PID_SIZE_WORDS][2] = {
+            {DX_PERIPHERAL_ID_0_REG_OFFSET, TEST_PID_0_VAL},
+            {DX_PERIPHERAL_ID_1_REG_OFFSET, TEST_PID_1_VAL},
+            {DX_PERIPHERAL_ID_2_REG_OFFSET, TEST_PID_2_VAL},
+            {DX_PERIPHERAL_ID_3_REG_OFFSET, TEST_PID_3_VAL},
+            {DX_PERIPHERAL_ID_4_REG_OFFSET, TEST_PID_4_VAL},
+            };
+
+
+    /* verify peripheral ID (PIDR) */
+    for (i=0; i<TEST_PID_SIZE_WORDS; i++) {
+        pidReg = TEST_READ_TEE_CC_REG(pidValTable[i][0]);
+        if (pidReg != pidValTable[i][1]) {
+            TEST_PRINTF_ERROR("ERROR: verify peripheral ID (PIDR) "
+                    "%d value=0x%08x expected 0x%08x\n", i,
+                pidReg, pidValTable[i][1]);
+            return 1;
+        }
+    }
+    return 0;
+}
+/******************************************************************************/
+uint32_t Test_ProjVerifyCIDReg(void)
+{
+    uint32_t i =0;
+    uint32_t cidReg = 0;
+
+    uint32_t cidValTable[TEST_CID_SIZE_WORDS][2] = {
+            {DX_COMPONENT_ID_0_REG_OFFSET, TEST_CID_0_VAL},
+            {DX_COMPONENT_ID_1_REG_OFFSET, TEST_CID_1_VAL},
+            {DX_COMPONENT_ID_2_REG_OFFSET, TEST_CID_2_VAL},
+            {DX_COMPONENT_ID_3_REG_OFFSET, TEST_CID_3_VAL},
+            };
+
+    /* verify component ID (CIDR) */
+    for (i=0; i<TEST_CID_SIZE_WORDS; i++) {
+        cidReg = TEST_READ_TEE_CC_REG(cidValTable[i][0]);
+        if (cidReg != cidValTable[i][1]) {
+            TEST_PRINTF_ERROR("ERROR: verify component ID (CIDR) "
+                    "%d value=0x%08x expected 0x%08x", i,
+                cidReg, cidValTable[i][1]);
+            return 1;
+        }
+    }
+    return 0;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_map.c b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_map.c
new file mode 100644
index 0000000..e6543ef
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_map.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include "test_proj.h"
+#include "test_proj_defs.h"
+
+#include "dx_reg_base_host.h"
+
+#include "test_pal_map_addrs.h"
+#include "test_pal_log.h"
+#include "test_pal_mem.h"
+#include "test_pal_mem_s.h"
+#include "board_configs.h"
+
+
+struct ProcessMappingArea_t processMap;
+
+uint32_t Test_ProjMap(void)
+{
+    uint32_t error = 0;
+
+    /* Initialize value */
+    memset(&processMap, 0, sizeof(struct ProcessMappingArea_t));
+
+    /* Init platform specific memories: DMAble & unmanaged */
+    error = Test_HalBoardInit();
+    if (error != 0) {
+        TEST_PRINTF_ERROR("Failed to Test_HalBoardInit 0x%x", error);
+        return error;
+    }
+#ifdef ARCH_V8M
+    processMap.processTeeUnmanagedBaseAddr = Test_PalGetUnmanagedBaseAddr_s();
+#else
+    processMap.processTeeUnmanagedBaseAddr = Test_PalGetUnmanagedBaseAddr();
+#endif
+
+    /* Set relevant mapping regions for CC312-r1 tests */
+    processMap.processTeeHwRegBaseAddr = (unsigned long)Test_PalIOMap((void *)DX_BASE_CC,
+                                                                        TEST_PROJ_CC_REG_MAP_AREA_LEN);
+    processMap.processTeeHwEnvBaseAddr = (unsigned long)Test_PalIOMap((void *)DX_BASE_ENV_REGS,
+                                                                       TEST_PROJ_CC_REG_MAP_AREA_LEN);
+
+    /* Verify all Maps succeeded */
+    if ((!VALID_MAPPED_ADDR(processMap.processTeeHwRegBaseAddr)) ||
+        (!VALID_MAPPED_ADDR(processMap.processTeeHwEnvBaseAddr)) ||
+    (!VALID_MAPPED_ADDR(processMap.processTeeUnmanagedBaseAddr))) {
+        TEST_PRINTF_ERROR("Failed to map, processTeeHwRegBaseAddr 0x%lx, processTeeHwEnvBaseAddr 0x%lx, \
+                 processTeeUnmanagedBaseAddr 0x%lx\n",
+                    processMap.processTeeHwRegBaseAddr,
+                    processMap.processTeeHwEnvBaseAddr,
+                     processMap.processTeeUnmanagedBaseAddr);
+        goto end_with_error;
+
+    }
+    return TEST_OK;
+
+end_with_error:
+    Test_ProjUnmap();
+    return TEST_MAPPING_ERR;
+
+}
+
+void Test_ProjUnmap(void)
+{
+    Test_PalUnmapAddr((void *)processMap.processTeeHwRegBaseAddr, TEST_PROJ_CC_REG_MAP_AREA_LEN);
+    Test_PalUnmapAddr((void *)processMap.processTeeHwEnvBaseAddr, TEST_PROJ_CC_REG_MAP_AREA_LEN);
+    Test_HalBoardFree();
+
+    memset((uint8_t *)&processMap, 0, sizeof(struct ProcessMappingArea_t));
+    return;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp.c b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp.c
new file mode 100644
index 0000000..2026ae2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp.c
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "cc_otp_defs.h"
+#include "cc_regs.h"
+#include "dx_crys_kernel.h"
+#include "cc_pal_types.h"
+
+#include "test_proj_otp.h"
+#include "test_proj_defs.h"
+#include "test_proj_otp.h"
+
+#include "test_pal_log.h"
+#include "test_pal_time.h"
+
+void Test_ProjWriteOtpWord(uint32_t offsetInWords, uint32_t value)
+{
+    TEST_WRITE_OTP_BY_ENV(offsetInWords, value);
+}
+
+void Test_ProjWriteOtpField(uint32_t offsetInWords, uint32_t sizeWords, uint32_t *buff)
+{
+    uint32_t i = 0;
+
+    for (i = 0; i < sizeWords; i++) {
+        Test_ProjWriteOtpWord(offsetInWords + i, buff[i]);
+        Test_PalDelay(1000);
+    }
+}
+
+uint32_t Test_ProjReadOtpWord(uint32_t offsetInWords)
+{
+    uint32_t read_value = 0;
+
+    read_value = TEST_READ_OTP_BY_ENV(offsetInWords);
+
+    return read_value;
+}
+
+uint32_t Test_ProjSetZeroBitsOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value)
+{
+    uint32_t hwWord;
+
+    switch (keyType) {
+        case TEST_KCP_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCE_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KPICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCEICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_HUK_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, HUK_ZERO_BITS, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        default:
+            TEST_PRINTF_ERROR("ERROR: can't set zero bits for this type of key\n")
+            ;
+            return TEST_INVALID_PARAM_ERR;
+    }
+    return TEST_OK;
+}
+
+uint32_t Test_ProjSetNotInUseOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value)
+{
+    uint32_t hwWord;
+
+    switch (keyType) {
+        // TBD HBK
+        case TEST_KCP_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCE_KEY:
+            hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KPICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_KCEICV_KEY:
+            hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+            CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_NOT_IN_USE, hwWord, value);
+            otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+            break;
+        case TEST_HUK_KEY:
+        default:
+            TEST_PRINTF_ERROR("ERROR: can't set notInUse bit for this type of key\n")
+            ;
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+    return TEST_OK;
+}
+
+uint32_t Test_ProjSetKeyOtpBuff(uint32_t *otpBuf, uint32_t *keyBuff, uint32_t keyType)
+{
+    uint32_t zeroCount = 0;
+    uint32_t keySizeInWords = 0;
+    uint32_t keyOffsetInOtp = 0;
+    uint32_t rc = TEST_OK;
+
+    switch (keyType) {
+        case TEST_HUK_KEY:
+            keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_HUK_OFFSET;
+            break;
+        case TEST_KCP_KEY:
+            keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCP_OFFSET;
+            break;
+        case TEST_KCE_KEY:
+            keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCE_OFFSET;
+            break;
+        case TEST_KPICV_KEY:
+            keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KPICV_OFFSET;
+            break;
+        case TEST_KCEICV_KEY:
+            keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCEICV_OFFSET;
+            break;
+        default:
+            TEST_PRINTF_ERROR("ERROR: key type is not supported %d\n", keyType);
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+
+    if (keyBuff != NULL) {
+        memcpy((uint8_t *) (otpBuf + keyOffsetInOtp),
+               (uint8_t *) keyBuff,
+               keySizeInWords * sizeof(uint32_t));
+    }
+
+    TEST_CALC_BUFF_ZEROS((otpBuf + keyOffsetInOtp), keySizeInWords, zeroCount);
+
+    if (keyType != TEST_HUK_KEY) {
+        rc = Test_ProjSetNotInUseOtpBuff(otpBuf, keyType, 0);
+    }
+
+    rc = rc & Test_ProjSetZeroBitsOtpBuff(otpBuf, keyType, zeroCount);
+    return rc;
+}
+
+uint32_t Test_ProjBurnOtpPlain(uint32_t *otpBuf, uint32_t nextLcs, OtpChipState_t chipIndication)
+{
+
+    uint32_t error = 0;
+    uint32_t i = 0;
+
+    CC_UNUSED_PARAM(chipIndication);
+
+    /* Clean OTP */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        Test_ProjWriteOtpWord(i, 0);
+        Test_PalDelay(1000);
+    }
+    /* Perform SW reset to reach CM LCS */
+    Test_ProjPerformPowerOnReset();
+    Test_PalDelay(1000);
+
+    /* Copy new OTP buffer */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        TEST_PRINTF("writing Otp [0x%X] 0x%X", i, otpBuf[i]);
+        Test_ProjWriteOtpWord(i, otpBuf[i]);
+        Test_PalDelay(1000);
+    }
+
+    /*  Perform SW reset after writing to OTP new values */
+    Test_ProjPerformPowerOnReset();
+
+    /* verify LCS */
+    error = Test_ProjCheckLcs(nextLcs);
+    if (error == 0) {
+        TEST_PRINTF(" OTP burn succeeded with new LCS = 0x%02x \n", nextLcs);
+    } else {
+        TEST_PRINTF_ERROR("Error: Failed to burn OTP!!\n");
+    }
+
+    return error;
+}
+
+uint32_t Test_ProjBurnOtp(uint32_t *otpBuf, uint32_t nextLcs, OtpChipState_t chipIndication)
+{
+
+    uint32_t error = 0;
+    uint32_t i = 0;
+
+    if (nextLcs != TEST_PROJ_LCS_CM) {
+        for (i = TEST_HUK_KEY; i <= TEST_KCEICV_KEY; i++) {
+            /* rtl key is not a part of OTP image => skip it */
+            if (i == TEST_RTL_KEY) {
+                continue;
+            };
+            /* set the the key to OTP buffer*/
+            Test_ProjSetKeyOtpBuff(otpBuf, NULL, i);
+        }
+    }
+
+    error = Test_ProjBurnOtpPlain(otpBuf, nextLcs, chipIndication);
+
+    return error;
+}
+
+uint32_t Test_ProjBurnCmOtp(OtpChipState_t chipIndication)
+{
+
+    uint32_t error = 0;
+    uint32_t i = 0;
+
+    CC_UNUSED_PARAM(chipIndication);
+
+    /* Clean OTP */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        TEST_WRITE_OTP_BY_ENV(i, 0);
+        Test_PalDelay(1000);
+    }
+
+    /*  Perform SW reset after writing to OTP new values */
+    Test_ProjPerformPowerOnReset();
+
+    /* verify LCS */
+    error = Test_ProjCheckLcs(TEST_PROJ_LCS_CM);
+    if (error == 0) {
+        TEST_PRINTF(" OTP burn succeeded with TEST_PROJ_LCS_DM\n");
+    } else {
+        TEST_PRINTF_ERROR("Error: Failed to burn OTP!!\n");
+    }
+
+    return error;
+}
+
+uint32_t Test_ProjBurnDmOtp(uint32_t *otpBuf, OtpChipState_t chipIndication)
+{
+
+    uint32_t error = 0;
+    uint32_t i = 0;
+
+    CC_UNUSED_PARAM(chipIndication);
+
+    /* Clean OTP */
+    for (i = 0; i < TEST_OTP_SIZE_IN_WORDS; i++) {
+        TEST_WRITE_OTP_BY_ENV(i, 0);
+        Test_PalDelay(1000);
+    }
+
+    /* Perform SW reset to reach CM LCS */
+    Test_ProjPerformPowerOnReset();
+    Test_PalDelay(1000);
+
+    /* Prepare OTP */
+    Test_ProjSetKeyOtpBuff(otpBuf, NULL, TEST_HUK_KEY);
+    Test_ProjSetKeyOtpBuff(otpBuf, NULL, TEST_KPICV_KEY);
+    Test_ProjSetKeyOtpBuff(otpBuf, NULL, TEST_KCEICV_KEY);
+
+    /* Copy new OTP buffer */
+    Test_ProjWriteOtpField(CC_OTP_HUK_OFFSET, CC_OTP_HUK_SIZE_IN_WORDS, &otpBuf[CC_OTP_HUK_OFFSET]);
+    Test_ProjWriteOtpField(CC_OTP_KPICV_OFFSET,
+                           CC_OTP_KPICV_SIZE_IN_WORDS,
+                           &otpBuf[CC_OTP_KPICV_OFFSET]);
+    Test_ProjWriteOtpField(CC_OTP_KCEICV_OFFSET,
+                           CC_OTP_KCEICV_SIZE_IN_WORDS,
+                           &otpBuf[CC_OTP_KCEICV_OFFSET]);
+    Test_ProjWriteOtpField(CC_OTP_MANUFACTURE_FLAG_OFFSET,
+                           1,
+                           &otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET]);
+    Test_ProjWriteOtpField(CC_OTP_HBK0_OFFSET,
+                           CC_OTP_HBK0_SIZE_IN_WORDS,
+                           &otpBuf[CC_OTP_HBK0_OFFSET]);
+    Test_ProjWriteOtpField(CC_OTP_HBK0_MIN_VERSION_OFFSET,
+                           CC_OTP_HBK0_MIN_VERSION_SIZE_IN_WORDS,
+                           &otpBuf[CC_OTP_HBK0_MIN_VERSION_OFFSET]);
+    Test_ProjWriteOtpField(CC_OTP_ICV_GENERAL_PURPOSE_FLAG_OFFSET,
+                           CC_OTP_ICV_GENERAL_PURPOSE_FLAG_SIZE_IN_WORDS,
+                           &otpBuf[CC_OTP_ICV_GENERAL_PURPOSE_FLAG_OFFSET]);
+    Test_ProjWriteOtpField(CC_OTP_DCU_OFFSET, CC_OTP_DCU_SIZE_IN_WORDS, &otpBuf[CC_OTP_DCU_OFFSET]);
+
+    /*  Perform SW reset after writing to OTP new values */
+    Test_ProjPerformPowerOnReset();
+
+    /* verify LCS */
+    error = Test_ProjCheckLcs(TEST_PROJ_LCS_DM);
+    if (error == 0) {
+        TEST_PRINTF(" OTP burn succeeded with TEST_PROJ_LCS_DM\n");
+    } else {
+        TEST_PRINTF_ERROR("Error: Failed to burn OTP!!\n");
+    }
+
+    return error;
+}
+
+uint32_t Test_ProjSetKdrInOtpBuff(uint32_t *otp, uint8_t *kdrBuff)
+{
+    int i = 0;
+    int zeroCount = 0;
+    int kdrZeroSize = ((0x1 << CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SIZE) - 1);
+    int kdrZeroMask = (kdrZeroSize << CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SHIFT);
+
+    if ((NULL == otp) || (NULL == kdrBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    for (i = 0; i < CC_OTP_HUK_SIZE_IN_WORDS; i++) {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&kdrBuff[i * sizeof(uint32_t)], otp[CC_OTP_START_OFFSET+i])
+    }
+
+    TEST_CALC_BUFF_ZEROS(&otp[CC_OTP_START_OFFSET], CC_OTP_HUK_SIZE_IN_WORDS, zeroCount);
+    otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(kdrZeroMask);
+    otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount)
+                    << CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SHIFT;
+    return TEST_OK;
+
+}
+
+uint32_t Test_ProjSetHbkInOtpBuff(uint32_t *otp,
+                                  uint8_t *hbkBuff,
+                                  OtpHbkTypes_t type,
+                                  uint8_t isFullHbk)
+{
+    uint32_t i = 0;
+    uint32_t zeroCount = 0;
+    uint32_t otpStartOffset =
+                    (type == TEST_OTP_HBK1_TYPE) ? CC_OTP_HBK1_OFFSET : CC_OTP_HBK0_OFFSET;
+    uint32_t hbkStartOffset = (type == TEST_OTP_HBK1_TYPE) ? CC_OTP_HBK0_SIZE_IN_WORDS : 0;
+    uint32_t hbkWordSize;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otp) || (NULL == hbkBuff)) {
+        TEST_PRINTF_ERROR("ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+    TEST_PRINTF_ERROR("type %d\n", type);
+
+    if ((type == TEST_OTP_HBK0_TYPE) || (type == TEST_OTP_HBK1_TYPE)) {
+        hbkWordSize = CC_OTP_HBK0_SIZE_IN_WORDS;
+    } else if (type == TEST_OTP_HBK_256_TYPE) {
+        hbkWordSize = CC_OTP_HBK_SIZE_IN_WORDS;
+    } else {
+        TEST_PRINTF_ERROR("ilegal type %d\n", type);
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+    /* clear OTP HBK value */
+    memset(&otp[otpStartOffset], 0, hbkWordSize * sizeof(uint32_t));
+
+    if (isFullHbk == 1) {
+        //clear ICV HBK zero count & clear HBK0 usage
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0x7F000000);
+        hwWord = otp[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+        CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, HBK0_NOT_IN_USE, hwWord, 1);
+    }
+
+    TEST_PRINTF_ERROR("writing hbk otpStartOffset %d, hbkWordSize %d\n",
+                      otpStartOffset,
+                      hbkWordSize);
+
+    for (i = 0; i < hbkWordSize; i++) {
+        TEST_CONVERT_BYTE_ARR_TO_WORD(&hbkBuff[(hbkStartOffset + i) * sizeof(uint32_t)],
+                                      otp[otpStartOffset + i]);
+    }
+
+    TEST_CALC_BUFF_ZEROS(&otp[otpStartOffset], hbkWordSize, zeroCount);
+
+    if (type == TEST_OTP_HBK0_TYPE) {
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] &= ~(0xFF000000);
+        otp[CC_OTP_MANUFACTURE_FLAG_OFFSET] |= (zeroCount)
+                        << CC_OTP_MANUFACTURE_FLAG_HBK0_ZERO_BITS_BIT_SHIFT;
+        TEST_PRINTF_ERROR("zeros for HBK0 %d\n", zeroCount);
+    } else {
+        otp[CC_OTP_OEM_FLAG_OFFSET] &= ~(0xFF);
+        otp[CC_OTP_OEM_FLAG_OFFSET] |= (zeroCount) << CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT;
+    }
+
+    TEST_PRINTF_ERROR("otp[0x%lx] 0x%x, otp[0x%lx] 0x%x\n",
+                      CC_OTP_OEM_FLAG_OFFSET,
+                      otp[CC_OTP_OEM_FLAG_OFFSET],
+                      CC_OTP_MANUFACTURE_FLAG_OFFSET,
+                      otp[CC_OTP_MANUFACTURE_FLAG_OFFSET]);
+
+    return TEST_OK;
+}
+
+uint32_t Test_ProjSetKpicvInOtpBuff(uint32_t *otpBuf, uint8_t *kpicvBuff)
+{
+    int zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) || (NULL == kpicvBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *) (otpBuf + CC_OTP_KPICV_OFFSET),
+           (uint8_t *) kpicvBuff,
+           CC_OTP_KPICV_SIZE_IN_WORDS * sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KPICV_OFFSET], CC_OTP_KPICV_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KPICV_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+
+uint32_t Test_ProjSetKceicvOtpBuff(uint32_t *otpBuf, uint8_t *kceicvBuff)
+{
+    int zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) || (NULL == kceicvBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *) (otpBuf + CC_OTP_KCEICV_OFFSET),
+           (uint8_t *) kceicvBuff,
+           CC_OTP_KCEICV_SIZE_IN_WORDS * sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCEICV_OFFSET], CC_OTP_KCEICV_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_MANUFACTURE_FLAG, KCEICV_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_MANUFACTURE_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+
+uint32_t Test_ProjSetKcpOtpBuff(uint32_t *otpBuf, uint8_t *kcpBuff)
+{
+    int zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) || (NULL == kcpBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *) (otpBuf + CC_OTP_KCP_OFFSET),
+           (uint8_t *) kcpBuff,
+           CC_OTP_KCP_SIZE_IN_WORDS * sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCP_OFFSET], CC_OTP_KCP_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCP_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+
+uint32_t Test_ProjSetKceOtpBuff(uint32_t *otpBuf, uint8_t *kceBuff)
+{
+    int zeroCount = 0;
+    uint32_t hwWord = 0;
+
+    if ((NULL == otpBuf) || (NULL == kceBuff)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+    memcpy((uint8_t *) (otpBuf + CC_OTP_KCE_OFFSET),
+           (uint8_t *) kceBuff,
+           CC_OTP_KCE_SIZE_IN_WORDS * sizeof(uint32_t));
+
+    TEST_CALC_BUFF_ZEROS(&otpBuf[CC_OTP_KCE_OFFSET], CC_OTP_KCE_SIZE_IN_WORDS, zeroCount);
+    hwWord = otpBuf[CC_OTP_OEM_FLAG_OFFSET];
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_ZERO_BITS, hwWord, zeroCount);
+    CC_REG_FLD_SET2(0, OTP_OEM_FLAG, KCE_NOT_IN_USE, hwWord, 0);
+    otpBuf[CC_OTP_OEM_FLAG_OFFSET] = hwWord;
+    return TEST_OK;
+}
+
+uint32_t Test_ProjGetKeySizeInWordsOtp(uint32_t keyType, uint32_t* keySizeInWords)
+{
+    // TBD HBK??
+    switch (keyType) {
+        case TEST_HUK_KEY:
+            *keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
+            break;
+        case TEST_KCP_KEY:
+            *keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
+            break;
+        case TEST_KCE_KEY:
+            *keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
+            break;
+        case TEST_KPICV_KEY:
+            *keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
+            break;
+        case TEST_KCEICV_KEY:
+            *keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
+            break;
+        default:
+            *keySizeInWords = 0;
+            TEST_PRINTF_ERROR("ERROR: key type %d is not supported\n", keyType)
+            ;
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+    return 0;
+}
+
+/**
+ * This function gets hw key and its size from otp buffer to user buffer
+ *
+ */
+uint32_t Test_ProjGetKeyOtpBuff(uint32_t *otpBuf,
+                                uint32_t keyType,
+                                uint32_t *keySizeInWords,
+                                uint32_t *keyBuff)
+{
+    uint32_t keyOffsetInOtp = 0;
+    uint32_t rc = TEST_OK;
+
+    if ((NULL == otpBuf) || (NULL == keyBuff) || (NULL == keySizeInWords)) {
+        TEST_PRINTF_ERROR(" ilegal params\n");
+        return TEST_INVALID_PARAM_ERR;
+    }
+
+    // TBD HBK??
+    switch (keyType) {
+        case TEST_HUK_KEY:
+            *keySizeInWords = CC_OTP_HUK_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_HUK_OFFSET;
+            break;
+        case TEST_KCP_KEY:
+            *keySizeInWords = CC_OTP_KCP_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCP_OFFSET;
+            break;
+        case TEST_KCE_KEY:
+            *keySizeInWords = CC_OTP_KCE_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCE_OFFSET;
+            break;
+        case TEST_KPICV_KEY:
+            *keySizeInWords = CC_OTP_KPICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KPICV_OFFSET;
+            break;
+        case TEST_KCEICV_KEY:
+            *keySizeInWords = CC_OTP_KCEICV_SIZE_IN_WORDS;
+            keyOffsetInOtp = CC_OTP_KCEICV_OFFSET;
+            break;
+        default:
+            *keySizeInWords = 0;
+            TEST_PRINTF_ERROR("ERROR: key type is not supported\n")
+            ;
+            return TEST_INVALID_PARAM_ERR;
+
+    }
+    memcpy((uint8_t *) keyBuff,
+           (uint8_t *) (otpBuf + keyOffsetInOtp),
+           (*keySizeInWords) * sizeof(uint32_t));
+
+    return rc;
+}
+
+uint32_t Test_ProjSetSwVerInOtpBuff(uint32_t *otp, uint32_t offset, uint32_t max_size)
+{
+    uint32_t i;
+
+    for (i = 0; i < max_size; i++) {
+        if (otp[offset + i] < 0xFFFFFFFF) {
+            memset(&otp[offset + i + 1], 0x0, (max_size - i - 1) * sizeof(uint32_t));
+            break;
+        }
+    }
+
+    return TEST_OK;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp.h b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp.h
new file mode 100644
index 0000000..29590d7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _TEST_PROJ_OTP_H__
+#define _TEST_PROJ_OTP_H__
+
+#include <stdint.h>
+#include "cc_otp_defs.h"
+#include "test_proj.h"
+
+/* HW KEYS */
+#define TEST_HUK_KEY            0
+#define TEST_RTL_KEY        1
+#define TEST_KCP_KEY            2
+#define TEST_KCE_KEY            3
+#define TEST_KPICV_KEY          4
+#define TEST_KCEICV_KEY         5
+
+#define TEST_HBK0_KEY           16
+#define TEST_HBK1_KEY           17
+#define TEST_HBK_FULL_KEY       18
+
+/* OTP memory mapping */
+#define ENV_OTP_START_OFFSET        0x2000UL
+#define TEST_OTP_SIZE_IN_WORDS      0x2C
+#define MAX_OTP_SIZE_IN_WORDS       0x7FF
+#define TEST_OTP_LAST_WORD_IN_MASK 0x20
+
+typedef enum {
+    TEST_CHIP_STATE_NOT_INITIALIZED = 0,
+    TEST_CHIP_STATE_TEST = 1,
+    TEST_CHIP_STATE_PRODUCTION = 2,
+    TEST_CHIP_STATE_ERROR = 3,
+} OtpChipState_t;
+
+typedef enum otpHbkTypes_t {
+    TEST_OTP_HBK0_TYPE = 1,    //HBK0
+    TEST_OTP_HBK1_TYPE = 2,    //HBK1
+    TEST_OTP_HBK_256_TYPE = 4,    //HBK
+} OtpHbkTypes_t;
+
+#define TEST_CALC_BUFF_ZEROS(wordBuf, buffWordSize, zeros) {\
+    uint32_t i = 0;\
+    uint32_t j = 0;\
+    uint32_t mask = 0;\
+    zeros = 0;\
+    for (i = 0; i< buffWordSize; i++) {\
+        for (j = 0; j< BITS_IN_32BIT_WORD; j++) {\
+            mask = 0x1;\
+            if (!(*(wordBuf+i) & (mask << j))) {\
+                zeros++;\
+            }\
+        }\
+    }\
+}
+
+#define TEST_WRITE_OTP_BY_REG(offset, val)  \
+        TEST_WRITE_TEE_CC_REG(CC_OTP_BASE_ADDR +(offset*sizeof(uint32_t)), val)
+
+#define TEST_READ_OTP_BY_REG(offset)   \
+        TEST_READ_TEE_CC_REG(CC_OTP_BASE_ADDR+ (offset*sizeof(uint32_t)))
+
+#define TEST_WRITE_OTP_BY_ENV(wordOffset, val) \
+        TEST_WRITE_TEE_ENV_REG(ENV_OTP_START_OFFSET + ((wordOffset)*sizeof(uint32_t)), val)
+
+#define TEST_READ_OTP_BY_ENV(wordOffset) \
+        TEST_READ_TEE_ENV_REG(ENV_OTP_START_OFFSET + ((wordOffset)*sizeof(uint32_t)))
+
+#define SET_OTP_DCU_LOCK(otpBuff, val) {\
+    uint32_t ii = 0; \
+    for (ii = 0; ii < CC_OTP_DCU_SIZE_IN_WORDS; ii++) { \
+        otpBuff[CC_OTP_DCU_OFFSET+ii] = val; \
+    } \
+}
+
+/* calc OTP memory length:
+ read RTL OTP address width. The supported sizes are 6 (for 2 Kbits),7,8,9,10,11 (for 64 Kbits).
+ convert value parameter to addresses of 32b words */
+#define GET_OTP_LENGTH(otpLength)                           \
+    do {                                                \
+        otpLength = TEST_READ_TEE_CC_REG(CC_REG_OFFSET(HOST_RGF, OTP_ADDR_WIDTH_DEF));  \
+        otpLength = CC_REG_FLD_GET(0, OTP_ADDR_WIDTH_DEF, VALUE, otpLength);            \
+        otpLength = (1 << otpLength);                               \
+    }while(0)
+
+typedef struct TestOtpMask_t {
+    uint32_t isPCI;
+    uint32_t* mask;
+} TestOtpMask_t;
+
+extern uint32_t OTP_CM_VALUES[];
+extern uint32_t OTP_DM_HBK_VALUES[];
+extern uint32_t gTestOtpMaskV1[];
+extern uint32_t gTestOtpMaskV2[];
+
+extern TestOtpMask_t gOtpStatus;
+
+/******************************/
+/*   function declaration     */
+/*****************************/
+
+/*
+ * @brief This function sets teh chip indication status in a buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+void Test_ProjSetChipIndication(uint32_t *otpValues, OtpChipState_t chipIndication);
+
+/*
+ * @brief This function writes to OTP using environment register including RTL mask
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+void Test_ProjWriteOtpWord(uint32_t offsetInWords, uint32_t value);
+
+/*
+ * @brief This function reads to OTP using environment register including RTL mask
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjReadOtpWord(uint32_t offsetInWords);
+
+/*
+ * @brief This function sets the key in OTP buffer including number of zeroes and RTL mask
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetKeyOtpBuff(uint32_t *otpBuf, uint32_t *keyBuff, uint32_t keyType);
+
+/*
+ * @brief This function burns OTP buffer with the required chip indication flag
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjBurnCmOtp(OtpChipState_t chipIndication);
+
+/*
+ * @brief This function burns OTP buffer with the required chip indication flag
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjBurnDmOtp(uint32_t *otpBuf, OtpChipState_t chipIndication);
+
+/*
+ * @brief This function burns OTP buffer (as is) with the required chip indication flag
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjBurnOtpPlain(uint32_t *otpBuf, uint32_t nextLcs, OtpChipState_t chipIndication);
+
+/*
+ * @brief This function burns OTP buffer with the required chip indication flag (including key integrity setting)
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+
+ */
+uint32_t Test_ProjBurnOtp(uint32_t *otpBuf, uint32_t nextLcs, OtpChipState_t chipIndication);
+
+/*
+ * @brief This function sets the chip indication status in global variable and defines the right mask to use
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+void Test_ProjSetOtpBufState(uint8_t isPCIMode);
+
+/*
+ * @brief This function sets the zero count in OTP buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetZeroBitsOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value);
+
+/*
+ * @brief This function sets HUK buffer in OTP buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetKdrInOtpBuff(uint32_t *otp, uint8_t *kdrBuff);
+
+/*
+ * @brief This function sets HBK buffer in OTP buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetHbkInOtpBuff(uint32_t *otp,
+                                  uint8_t *hbkBuff,
+                                  OtpHbkTypes_t type,
+                                  uint8_t isFullHbk);
+
+/*
+ * @brief This function sets KPICV buffer in OTP buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetKpicvInOtpBuff(uint32_t *otpBuf, uint8_t *kpicvBuff);
+
+/*
+ * @brief This function sets KCEICV buffer in OTP buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetKceicvOtpBuff(uint32_t *otpBuf, uint8_t *kceicvBuff);
+
+/*
+ * @brief This function sets KCP buffer in OTP buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetKcpOtpBuff(uint32_t *otpBuf, uint8_t *kcpBuff);
+
+/*
+ * @brief This function sets KCE buffer in OTP buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetKceOtpBuff(uint32_t *otpBuf, uint8_t *kceBuff);
+
+/*
+ * @brief This function sets default OTP used for llhw tests
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetNotInUseOtpBuff(uint32_t *otpBuf, uint32_t keyType, uint32_t value);
+
+/*
+ * @brief This function sets default OTP used for llhw tests
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjGetKeySizeInWordsOtp(uint32_t keyType, uint32_t* keySizeInWords);
+
+/*
+ * @brief This function sets default OTP used for llhw tests
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjGetKeyOtpBuff(uint32_t *otpBuf,
+                                uint32_t keyType,
+                                uint32_t *keySizeInWords,
+                                uint32_t *keyBuff);
+
+/*
+ * @brief This function sets default OTP used for llhw tests
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+uint32_t Test_ProjSetSwVerInOtpBuff(uint32_t *otp, uint32_t offset, uint32_t max_size);
+
+/*
+ * @brief This function sets default OTP used for llhw tests
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return void -
+ */
+
+#endif //_TEST_PROJ_OTP_H__
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp_data.c b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp_data.c
new file mode 100644
index 0000000..3b5a506
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/cc312_r1/test_proj_otp_data.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <stdint.h>
+
+uint32_t OTP_CM_VALUES[] = { /* no PCI or TCI mode*/
+
+/*  [0x00-0x07]: 256bit Device root key (HUK) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x08-0x0B]: 128bit ICV Provosioning secret (Kpicv) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x0C-0x0F]: 128bit ICV Provosioning secret (Kceicv) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x10]: manufacturer programmed flag */
+0x00000000,
+/*  [0x11-0x18]: a single 256b SHA256 (Hbk), or, two 128b truncated SHA256 HBK0 and HBK1 */
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x19-0x1C]: 128bit OEM provisioning secret (Kcp) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x1D-0x20]: 128bit OEM code encryption secret (Kce) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x21]: OEM programmed flag */
+0x00000000,
+/*  [0x22-0x23]: Hbk0 trusted FW min version */
+0x00000000, 0x00000000,
+/*  [0x24-0x26]: Hbk1 trusted FW min version */
+0x00000000, 0x00000000, 0x00000000,
+/*  [0x27]: general purpose configuration flag */
+0x00000000,
+/*  [0x28-0x2B] - 128b DCU lock mask */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+
+};
+
+
+uint32_t OTP_DM_HBK_VALUES[] = {
+
+/*  [0x00-0x07]: 256bit Device root key (HUK) */
+0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001,
+/*  [0x08-0x0B]: 128bit ICV Provosioning secret (Kpicv) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x0C-0x0F]: 128bit ICV Provosioning secret (Kceicv) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x10]: manufacturer programmed flag */
+0x808080f8,
+/*  [0x11-0x18]: a single 256b SHA256 (Hbk), or, two 128b truncated SHA256 HBK0 and HBK1 */
+0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x19-0x1C]: 128bit OEM provisioning secret (Kcp) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x1D-0x20]: 128bit OEM code encryption secret (Kce) */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+/*  [0x21]: OEM programmed flag */
+0x00000000,
+/*  [0x22-0x23]: Hbk0 trusted FW min version */
+0x00000000, 0x00000000,
+/*  [0x24-0x26]: Hbk1 trusted FW min version */
+0x00000000, 0x00000000, 0x00000000,
+/*  [0x27]: general purpose configuration flag */
+0x00000000,
+/*  [0x28-0x2B] - 128b DCU lock mask */
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+
+};
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/test_proj.c b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/test_proj.c
new file mode 100644
index 0000000..8f1677c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/test_proj.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#include "test_proj_defs.h"
+#include "test_proj.h"
+#include "dx_env.h"
+
+uint32_t Test_ProjInit(void)
+{
+    uint32_t error = 0;
+
+    error = Test_ProjMap();
+    if (error != 0) {
+        return error;
+    }
+    TEST_WRITE_TEE_ENV_REG(DX_ENV_APB_PPROT_OVERRIDE_REG_OFFSET, 0x9);
+
+    return error;
+
+}
+
+void Test_ProjFree(void)
+{
+    Test_ProjUnmap();
+    return;
+}
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/test_proj.h b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/test_proj.h
new file mode 100644
index 0000000..d9237eb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/cc3x/test_proj.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _TEST_PROJ_H_
+#define _TEST_PROJ_H_
+
+#include <stdint.h>
+#include "test_proj_common.h"
+
+#define TEST_PROJ_CC_REG_MAP_AREA_LEN     0x20000
+
+struct ProcessMappingArea_t {
+    unsigned long       processTeeHwRegBaseAddr;
+    unsigned long       processTeeHwEnvBaseAddr;
+    unsigned long       processTeeUnmanagedBaseAddr;
+};
+
+extern struct ProcessMappingArea_t processMap;
+
+#define TEST_READ_TEE_CC_REG(offset) \
+        *(volatile uint32_t *)(processMap.processTeeHwRegBaseAddr + (offset))
+
+#define TEST_WRITE_TEE_CC_REG(offset, val)  { \
+    volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(processMap.processTeeHwRegBaseAddr + (offset))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++); \
+}
+
+#define TEST_READ_TEE_ENV_REG(offset) \
+        *(volatile uint32_t *)(processMap.processTeeHwEnvBaseAddr + (offset))
+
+#define TEST_WRITE_TEE_ENV_REG(offset, val)  { \
+        volatile uint32_t ii1; \
+        (*(volatile uint32_t *)(processMap.processTeeHwEnvBaseAddr + (offset))) = (uint32_t)(val); \
+        for(ii1=0; ii1<500; ii1++); \
+}
+
+
+/****************************************************************************/
+/*                              External API                                */
+/****************************************************************************/
+/*
+ * @brief This function initializes platform, i.e maps its relevant memory regions.
+ *
+ * @param[in/out] *pProcessMap - mapping regions
+ *
+ * @return rc - 0 for success, 1 for failure.
+ */
+uint32_t Test_ProjInit(void);
+
+/****************************************************************************/
+/*
+ * @brief This function frees previously allocated resources
+ *
+ * @param[in/out] *pProcessMap - mapping regions
+  *
+ * @return rc - 0 for success, 1 for failure
+ */
+void Test_ProjFree(void);
+
+#endif //_TEST_PROJ_H_
+
diff --git a/lib/ext/cryptocell-312-runtime/host/src/tests/proj/test_proj_common.h b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/test_proj_common.h
new file mode 100644
index 0000000..9d11cbb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/tests/proj/test_proj_common.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _TEST_PROJ_COMMON_H_
+#define _TEST_PROJ_COMMON_H_
+
+
+
+/* Error types */
+/*! Defines test proj base error. */
+#define TEST_PROJ_BASE_ERROR     (0x00FFFF00)
+
+#define TEST_OK                 (0x00000000)
+#define TEST_INVALID_PARAM_ERR  (TEST_PROJ_BASE_ERROR + 0x00000001)
+#define TEST_COMPARE_ERR        (TEST_PROJ_BASE_ERROR + 0x00000002)
+#define TEST_HW_FAIL_ERR        (TEST_PROJ_BASE_ERROR + 0x00000003)
+#define TEST_MAPPING_ERR        (TEST_PROJ_BASE_ERROR + 0x00000004)
+#define TEST_EXECUTE_FAIL       (TEST_PROJ_BASE_ERROR + 0x00000005)
+#define TEST_MAX_THREADS        16
+#define TEST_MAX_FILE_NAME      256
+#define THREAD_STACK_SIZE       (128*1024) /* stack has 128KB for 64bit CPU */
+
+
+#ifdef BIG__ENDIAN
+#define TEST_CONVERT_BYTE_ARR_TO_WORD(inPtr, outWord) {\
+    outWord = (*inPtr<<24);\
+    outWord |= (*(inPtr+1)<<16);\
+    outWord |= (*(inPtr+2)<<8);\
+    outWord |= (*(inPtr+3));\
+}
+#else
+#define TEST_CONVERT_BYTE_ARR_TO_WORD(inPtr, outWord) {\
+    outWord = (*(inPtr+3))<<24;\
+    outWord |= (*(inPtr+2))<<16;\
+    outWord |= (*(inPtr+1))<<8;\
+    outWord |= (*inPtr);\
+}
+#endif
+
+#endif /* _TEST_PROJ_COMMON_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/host/src/utils/mbedtls_cc_util_key_derivation.c b/lib/ext/cryptocell-312-runtime/host/src/utils/mbedtls_cc_util_key_derivation.c
new file mode 100644
index 0000000..dfb496a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/host/src/utils/mbedtls_cc_util_key_derivation.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/************* Include Files ****************/
+#include "cc_pal_types.h"
+#include "cc_pal_mem.h"
+#include "cc_util_int_defs.h"
+#include "cc_sym_error.h"
+#include "cc_aes_defs.h"
+#include "mbedtls_cc_util_defs.h"
+#include "cc_util_error.h"
+#include "mbedtls_cc_util_key_derivation.h"
+#include "cc_hal_plat.h"
+#include "cc_regs.h"
+#include "cc_pal_mutex.h"
+#include "cc_pal_abort.h"
+#include "cc_util_cmac.h"
+#include "cc_fips_defs.h"
+#include "cc_hash_defs.h"
+#include "cc_general_defs.h"
+#include "mbedtls/md.h"
+
+CCUtilError_t mbedtls_util_key_derivation( mbedtls_util_keytype_t             keyType,
+                      mbedtls_util_keydata             *pUserKey,
+                    mbedtls_util_prftype_t             prfType,
+                                    CCHashOperationMode_t       hashMode,
+                                    const uint8_t               *pLabel,
+                                    size_t                      labelSize,
+                                    const uint8_t               *pContextData,
+                                    size_t                      contextSize,
+                                    uint8_t                     *pDerivedKey,
+                                    size_t                      derivedKeySize)
+{
+        uint32_t                rc = 0;
+        uint32_t                dataSize, i, iterationNum, numIteration, bytesToCopy;
+        uint8_t                 dataIn[CC_UTIL_MAX_KDF_SIZE_IN_BYTES] = {0};
+        uint8_t                 tmp[CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES];
+        CCHashResultBuf_t       hmacResultBuff;
+        size_t                  length, lengthReverse, prfUpperLimit;
+        UtilKeyType_t           utilKeyType;
+        uint8_t*                srcToCopy;
+        size_t origDerivedKeySize;
+
+        const mbedtls_md_info_t *mdInfo = NULL;
+
+        CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
+
+        /* Check input */
+        if(pDerivedKey == NULL)
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+
+        /* Check PRF type */
+        if ((CC_UTIL_PRF_CMAC != prfType) && (CC_UTIL_PRF_HMAC != prfType)) {
+                return CC_UTIL_INVALID_PRF_TYPE;
+        }
+
+        if ((CC_UTIL_PRF_HMAC == prfType) && (hashMode >= CC_HASH_MD5_mode)){
+                return CC_UTIL_INVALID_HASH_MODE;
+        }
+        origDerivedKeySize = derivedKeySize;
+        /* Check key type */
+        switch (keyType) {
+        case CC_UTIL_ROOT_KEY:
+                if (CC_UTIL_PRF_HMAC == prfType) {
+                        return CC_UTIL_INVALID_PRF_TYPE;
+                }
+
+                utilKeyType = UTIL_ROOT_KEY;
+                break;
+        case CC_UTIL_USER_KEY:
+                if (!pUserKey) {
+                        return CC_UTIL_INVALID_KEY_TYPE;
+                }
+                if (!pUserKey->pKey) {
+                        return CC_UTIL_INVALID_KEY_TYPE;
+                }
+
+                utilKeyType = UTIL_USER_KEY;
+                break;
+        default:
+                return CC_UTIL_INVALID_KEY_TYPE;
+        }
+
+        /* Check Label, Context, DerivedKey sizes */
+        if (derivedKeySize > CC_UTIL_MAX_DERIVED_KEY_SIZE_IN_BYTES)
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+
+        if ( ((labelSize != 0) && (pLabel == NULL)) ||
+             (labelSize == 0) ||
+             (labelSize > CC_UTIL_MAX_LABEL_LENGTH_IN_BYTES) ) {
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+        }
+
+        if ( ((contextSize != 0) && (pContextData == NULL)) ||
+             (contextSize == 0) ||
+             (contextSize > CC_UTIL_MAX_CONTEXT_LENGTH_IN_BYTES) ) {
+                return CC_UTIL_ILLEGAL_PARAMS_ERROR;
+        }
+
+        /* Generate dataIn buffer for CMAC: iteration || Label || 0x00 || context || length */
+
+        if(CC_UTIL_PRF_CMAC == prfType) {
+                prfUpperLimit = CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES;
+        } else { /* CC_UTIL_PRF_HMAC */
+                if (CC_TRUE == HmacSupportedHashModes_t[hashMode]) {
+            mdInfo = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashMode] );
+            if( mdInfo == NULL ){
+                return CC_UTIL_INVALID_HASH_MODE;
+            }
+                        prfUpperLimit = HmacHashInfo_t[hashMode].hashResultSize;
+                } else {
+                        return CC_UTIL_UNSUPPORTED_HASH_MODE;
+                }
+        }
+
+        i = 1;
+        numIteration = (derivedKeySize + prfUpperLimit - 1) / prfUpperLimit;
+        length = derivedKeySize*8;
+        if (length > 0xFF){
+                dataSize = CC_UTIL_FIX_DATA_MAX_SIZE_IN_BYTES;
+        } else {
+                dataSize = CC_UTIL_FIX_DATA_MIN_SIZE_IN_BYTES;
+        }
+
+        dataSize += labelSize+contextSize;
+
+        if (labelSize!=0) {
+                CC_PalMemCopy((uint8_t*)&dataIn[i], pLabel, labelSize);
+                i+=labelSize;
+        }
+
+        dataIn[i++] = 0x00;
+
+        if (contextSize!=0) {
+                CC_PalMemCopy((uint8_t*)&dataIn[i], pContextData, contextSize);
+                i+=contextSize;
+        }
+
+        if (length > 0xFF) {
+                /* Reverse words order and bytes in each word */
+                lengthReverse = ((length & 0xFF00)>>8) | ((length & 0xFF)<<8);
+                CC_PalMemCopy((uint8_t*)&dataIn[i], (uint8_t*)&lengthReverse, 2);
+        } else {
+                CC_PalMemCopy((uint8_t*)&dataIn[i], (uint8_t*)&length, 1);
+        }
+
+        srcToCopy = ((CC_UTIL_PRF_CMAC == prfType) ? tmp : (uint8_t*)&hmacResultBuff);
+        for (iterationNum = 0; iterationNum < numIteration; iterationNum++) {
+                dataIn[0] = iterationNum+1;
+                if(CC_UTIL_PRF_CMAC == prfType) {
+                        rc = UtilCmacDeriveKey(utilKeyType, (CCAesUserKeyData_t*)pUserKey, dataIn, dataSize, tmp);
+                }
+                else { /* CC_UTIL_PRF_HMAC */
+            rc = mbedtls_md_hmac( mdInfo,
+                          pUserKey->pKey,
+                          pUserKey->keySize,
+                          dataIn,
+                          dataSize,
+                          (unsigned char*)hmacResultBuff );
+                }
+
+                if (rc != CC_SUCCESS){
+                        return rc;
+                }
+
+                /* concatenate the latest PRF result */
+                /* copy only number of bits that required... */
+                if (derivedKeySize > prfUpperLimit) {
+                        bytesToCopy = prfUpperLimit;
+                        derivedKeySize -= prfUpperLimit;
+                } else{
+                    bytesToCopy = derivedKeySize;
+                }
+
+                if(bytesToCopy<=(origDerivedKeySize-iterationNum*prfUpperLimit) /*to avoid memory corruption*/&&
+                        ( bytesToCopy<=CC_HASH_RESULT_SIZE_IN_WORDS*sizeof(uint32_t) ) /*to remove static analyzer warnings*/)
+                {
+                    CC_PalMemCopy((uint8_t*)&pDerivedKey[iterationNum*prfUpperLimit], srcToCopy, bytesToCopy);
+                }else{
+                    return CC_UTIL_DATA_OUT_SIZE_INVALID_ERROR;
+                }
+        }
+
+        return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/prepare_mbedtls.sh b/lib/ext/cryptocell-312-runtime/prepare_mbedtls.sh
new file mode 100755
index 0000000..76a95d0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/prepare_mbedtls.sh
@@ -0,0 +1,204 @@
+#===============================================================================
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#===============================================================================
+
+#!/bin/bash
+PROJ_ROOT=$(pwd)
+MBEDTLS_ROOT_DIR=$PROJ_ROOT/mbedtls
+HOST_PROJ_ROOT=$PROJ_ROOT/host
+MBEDTLS_ALT_API=$PROJ_ROOT/shared/include/mbedtls
+MBEDTLS_PAL_INCDIRS+="$PROJ_ROOT/shared/include $PROJ_ROOT/shared/hw/include $PROJ_ROOT/shared/include/pal $PROJ_ROOT/shared/include/proj/cc3x $PROJ_ROOT/host/src/tests/common"
+MBEDTLS_CFLAGS=" -DUSE_MBEDTLS_CRYPTOCELL -I$MBEDTLS_ALT_API -I$PROJ_ROOT/host/include -I$PROJ_ROOT/shared/include/crypto_api/cc3x/ -I$PROJ_ROOT/shared/include/crypto_api/"
+#=========================== BUILD MBEDTLS LIBRARIES ==============================
+
+
+CORTEX=$ARM_CPU
+
+if [ "$CROSS_COMPILE" == "armcc" ]; then
+	TEE_OS=freertos
+elif [ "$CROSS_COMPILE" == "arm-xilinx-linux-gnueabi-" ]; then
+	TEE_OS=linux
+elif [ "$CROSS_COMPILE" == "arm-none-eabi-" ]; then
+	if [ "$CORTEX" == "cortex-m33" ] || [ "$CORTEX" == "cortex-m3" ]; then
+		TEE_OS=freertos
+	else
+		TEE_OS=no_os
+	fi
+elif [ "$CROSS_COMPILE" == "armclang" ]; then
+	TEE_OS=freertos
+fi
+
+# Set mbedtls_cflags according to the target's operating system (TEE_OS)
+if [ "$TEE_OS" == "freertos" ]; then
+    MBEDTLS_LDFLAGS+="-L$PROJ_ROOT/host/lib/libcc_312.a "
+    MBEDTLS_CFLAGS+=" -DMBEDTLS_CONFIG_FILE='<config-cc312-mps2-freertos.h>' "
+    MBEDTLS_CFLAGS+=" -I$KERNEL_DIR/OS/FreeRTOS/Source/include/"
+    MBEDTLS_PAL_INCDIRS+=" $PROJ_ROOT/shared/include/pal/freertos/"
+
+    if [ "$CROSS_COMPILE" == "armcc" ]; then
+        MBEDTLS_CFLAGS+=" -DARMCM3 "
+        MBEDTLS_CFLAGS+=" -I$KERNEL_DIR/OS/FreeRTOS/Source/portable/ARMCC/ARM_CM3/ "
+        MBEDTLS_CFLAGS+=" --cpu=cortex-m3 "
+    elif [ "$CROSS_COMPILE" == "arm-none-eabi-" ]; then
+        if [ "$CORTEX" == "cortex-m3" ]; then
+            MBEDTLS_CFLAGS +=" -mcpu=cortex-m3 "
+            MBEDTLS_CFLAGS+=" -DARMCM3 "
+            MBEDTLS_CFLAGS+=" -I$KERNEL_DIR/OS/FreeRTOS/Source/portable/GCC/ARM_CM3/ "
+        elif [ "$CORTEX" == "cortex-m33" ]; then
+            MBEDTLS_CFLAGS+=" -march=armv8-m.main "
+            MBEDTLS_CFLAGS+=" -mcmse "
+            MBEDTLS_CFLAGS+=" -DSSE_200 "
+            MBEDTLS_CFLAGS+=" -I$KERNEL_DIR/OS/FreeRTOS/Source/portable/GCC/ARM_CM33/ "
+        fi
+    elif [ "$CROSS_COMPILE" == "armclang" ]; then
+        if [ "$CORTEX" == "cortex-m3" ]; then
+            MBEDTLS_CFLAGS+=" --target=arm-arm-none-eabi -mcpu=cortex-m3 "
+            MBEDTLS_CFLAGS+=" -mlittle-endian -xc "
+            MBEDTLS_CFLAGS+=" -DARMCM3 "
+            MBEDTLS_CFLAGS+=" -I$KERNEL_DIR/OS/FreeRTOS/Source/portable/ARMCLANG/ARM_CM3/ "
+        elif [ "$CORTEX" == "cortex-m33" ]; then
+            MBEDTLS_CFLAGS+=" --target=arm-arm-none-eabi -march=armv8-m.main "
+            MBEDTLS_CFLAGS+=" -mlittle-endian -xc "
+            MBEDTLS_CFLAGS+=" -mcmse "
+            MBEDTLS_CFLAGS+=" -mfpu=none "
+            MBEDTLS_CFLAGS+=" -DSSE_200 "
+            MBEDTLS_CFLAGS+=" -I$KERNEL_DIR/OS/FreeRTOS/Source/portable/ARMCLANG/ARM_CM33/ "
+        fi
+    fi
+fi
+
+if [ "$TEE_OS" == "no_os" ]; then
+    MBEDTLS_CFLAGS+=" -DMBEDTLS_CONFIG_FILE='<config-cc312-mps2-no-os.h>' "
+    MBEDTLS_PAL_INCDIRS+=" $PROJ_ROOT/shared/include/pal/no_os/"
+fi
+
+if [ "$TEE_OS" == "linux" ]; then
+    MBEDTLS_CFLAGS+=" -DMBEDTLS_CONFIG_FILE='<config-cc312.h>' "
+fi
+
+if [ "$CROSS_COMPILE" == "armcc" ]; then
+    export CC="armcc"
+    export AR="armar"
+    MBEDTLS_CFLAGS+=" --thumb "
+
+    # Suppresses license management warning
+    MBEDTLS_CFLAGS+=" --diag_suppress 9931 "
+
+    MBEDTLS_LDFLAGS+="-L$PROJ_ROOT/host/lib/libcc_312.a "
+    MBEDTLS_TESTS_SRCFILES+="$PROJ_ROOT/host/src/tests/common/tests_hw_access_freertos.c $PROJ_ROOT/host/src/tests/common/tests_phys_map_freertos.c"
+
+	if [ -d $MBEDTLS_ROOT_DIR ]; then
+        #surpress warning levels in library makefile as arm-compiler-5 armcc does not seem to supoort it.
+	    sed -i '/WARNING_CFLAGS /d' $MBEDTLS_ROOT_DIR/library/Makefile
+
+	    #change debug flag -g3 to -g to comply with arm-compiler-5 armcc flags
+	    sed -i 's|g3|g| g ' $MBEDTLS_ROOT_DIR/library/Makefile
+    fi
+elif [ "$CROSS_COMPILE" == "arm-xilinx-linux-gnueabi-" ]; then
+
+    export CC="arm-xilinx-linux-gnueabi-gcc"
+    export AR="arm-xilinx-linux-gnueabi-ar"
+
+    MBEDTLS_TESTS_LDFLAGS+="-L../../host/lib -lpal_linux -lcc_312 -lpthread "
+    # as we cannot change mbedtls Makefile, we add these libs before mbedtls* in order to pass link
+    export LOCAL_LDFLAGS+="-L$PROJ_ROOT/host/lib -L$PROJ_ROOT/mbedtls/library -Wl,--start-group -lcc_312 "
+    export LOCAL_LDFLAGS+="-lmbedtls "
+    export LOCAL_LDFLAGS+="-lmbedx509 "
+    export LOCAL_LDFLAGS+="-lmbedcrypto "
+    export LOCAL_LDFLAGS+="-Wl,--end-group "
+
+    MBEDTLS_PAL_INCDIRS+=" $PROJ_ROOT/shared/include/pal/cc_linux/"
+    MBEDTLS_TESTS_SRCFILES+="$PROJ_ROOT/host/src/tests/common/tests_hw_access_iot.c $PROJ_ROOT/host/src/tests/common/tests_phys_map.c"
+
+    # make sure mbedTLS library makefile is untouched (from above section)
+    if [ -d $MBEDTLS_ROOT_DIR ];
+    then
+        cd $MBEDTLS_ROOT_DIR
+        git checkout -q -- $MBEDTLS_ROOT_DIR/library/Makefile
+    fi
+elif [ "$CROSS_COMPILE" == "arm-none-eabi-" ]; then
+    export CC="arm-none-eabi-gcc"
+    export AR="arm-none-eabi-ar"
+    MBEDTLS_CFLAGS+=" -mthumb "
+    MBEDTLS_PAL_INCDIRS+=" $MBEDTLS_ROOT_DIR/include/mbedtls"
+elif [ "$CROSS_COMPILE" == "armclang" ]; then
+    export CC="armclang"
+    export AR="armar"
+    MBEDTLS_CFLAGS+=" -mthumb "
+    MBEDTLS_CFLAGS+=" -Wno-license-management "
+    MBEDTLS_PAL_INCDIRS+=" $MBEDTLS_ROOT_DIR/include/mbedtls "
+else
+    export CC="cc"
+    export AR="ar"
+fi
+
+MBEDTLS_CFLAGS+=-I${MBEDTLS_PAL_INCDIRS// / -I}
+
+if [ "$DEBUG" == "" ]; then
+    MBEDTLS_CFLAGS+=" -O2"
+fi
+
+function mbedtls_git
+{
+    cd $PROJ_ROOT
+    if [ ! -d $MBEDTLS_ROOT_DIR ];
+    then
+        echo "cloning mbedtls into $MBEDTLS_ROOT_DIR"
+        git clone -b "mbedtls-2.16.2"  https://github.com/ARMmbed/mbedtls.git $MBEDTLS_ROOT_DIR
+    else
+        echo "rebase mbedtls $MBEDTLS_ROOT_DIR"
+        cd $MBEDTLS_ROOT_DIR
+        git pull --rebase
+    fi
+}
+
+
+function mbedtls_build_lib
+{
+    cd $MBEDTLS_ROOT_DIR
+    echo CFLAGS=$MBEDTLS_CFLAGS
+    CFLAGS=$MBEDTLS_CFLAGS make -j8 lib
+
+    if [[ $? -ne 0 ]]; then
+        exit 1;
+    fi
+
+    if [[ "$CROSS_COMPILE" == "armcc" ]] || [[ "$CROSS_COMPILE" == "arm-none-eabi-" ]] || [[ "$CROSS_COMPILE" == "armclang" ]]; then
+        sync
+        cd $MBEDTLS_ROOT_DIR
+        cp `find library/ -name *.a` $KERNEL_DIR/lib/
+    fi
+}
+
+#============================== CLEAN MBEDTLS =================================
+function mbedtls_clean
+{
+    cd $PROJ_ROOT/mbedtls
+    make clean
+}
+if [ "$#" == "0" ];
+then
+    echo "Usage: $0 clone|lib|all"
+    exit 1
+fi
+
+MODE=$1
+
+echo Running prepare_mbedtls.sh with $MODE
+if [ "$MODE" == "clone" ] || [ "$MODE" == "all" ]
+then
+    mbedtls_git
+fi
+
+if [ "$MODE" == "lib" ] || [ "$MODE" == "all" ]
+then
+    mbedtls_build_lib
+fi
+
+if [ "$MODE" == "clean" ]
+then
+    mbedtls_clean
+fi
diff --git a/lib/ext/cryptocell-312-runtime/proj.ext.cfg b/lib/ext/cryptocell-312-runtime/proj.ext.cfg
new file mode 100644
index 0000000..463fcdf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/proj.ext.cfg
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# External project configuration for cc312
+
+# definitions for TRNG
+# TRNG mode: 0 for FE TRNG, 1 for TRNG90B
+CC_CONFIG_TRNG_MODE = 0
+
+# indicates whether the project supports srp
+CC_CONFIG_SUPPORT_SRP = 1
+
+# indicates whether the project supports chacha\poly
+CC_CONFIG_CC_CHACHA_POLY_SUPPORT = 1
+
+#indicates whether to use X509 certificate format or proprietary
+CC_CONFIG_SB_X509_CERT_SUPPORTED = 0
+
+#indicates whether the project supports External DMA
+CC_CONFIG_SUPPORT_EXT_DMA = 0
+
+#indicates whether the project supports SB run time.
+CC_CONFIG_SUPPORT_SB_RT = 1
+
+#indicates that CryptoCell is working with mbedtls
+USE_MBEDTLS_CRYPTOCELL = 1
diff --git a/lib/ext/cryptocell-312-runtime/runtime_release_info.txt b/lib/ext/cryptocell-312-runtime/runtime_release_info.txt
new file mode 100644
index 0000000..4eb1e6e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/runtime_release_info.txt
@@ -0,0 +1,4 @@
+Release Tag = cc312r1-1.3.0-rel-rc10-20190708-1221
+mbedtls.d81c.tgz
+sw-cc312-1.3.0.6227ff8b22.tgz
+sw-cc312_integration_tests-1.1.0.6227ff8b22.tgz
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/cc312_cerberus_Register_Description.htm b/lib/ext/cryptocell-312-runtime/shared/hw/include/cc312_cerberus_Register_Description.htm
new file mode 100755
index 0000000..872a8f9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/cc312_cerberus_Register_Description.htm
@@ -0,0 +1,13221 @@
+<table align="center" frame="border" rules="cols" border="1">
+   <tr>
+      <td valign="top"> created by          : </td>
+   </tr>
+   <tr>
+      <td valign="top"> generated by        : yoesha01</td>
+   </tr>
+   <tr>
+      <td valign="top"> generated from      : /home/hw/yoesha01/P4/cc_7/cc312_cerberus/env/src/regs/XL/regdb_iot.xlsx</td>
+   </tr>
+   <tr>
+      <td valign="top"> IDesignSpec rev     : idsbatch v 4.12.19.1 </td>
+   </tr>
+   <tr>
+      <td valign="top"> XML Revision        : </td>
+   </tr>
+</table>
+<center>
+   <h1>chip : CryptoCell</h1>
+</center>
+<table border="0">
+   <tr>
+      <td width="40"></td>
+      <td>
+         <table frame="border">
+            <tr>
+               <td align="center" colspan="3"><b>LEGEND</b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>RO : Read Only                                             </b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>WO : Write Only                                            </b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>RW : Read/Write                                            </b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>RW1: Read/Write once                                       </b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>W1 : Write once                                            </b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>RWC: Read/Write change (Register value changes internally) </b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>RC : Read Change  (Readable, register valus changes)       </b></td>
+            </tr>
+            <tr>
+               <td colspan="3"><b>WM : Write Modify (Write triggers an internal FSM)         </b></td>
+            </tr>
+         </table>
+      </td>
+   </tr>
+</table>
+<table border="0">
+   <tr>
+      <td width="40"></td>
+      <td>
+         <table frame="border">
+            <tr>
+               <td align="center" colspan="3"><b>INDEX</b></td>
+            </tr>
+            <tr>
+               <td width="100">1.1</td>
+               <td>block: <a href="#1.1">PKA</a></td>
+               <td width="60"></td>
+               <td>0x000000000</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.1</td>
+               <td>reg: <a href="#1.1.1">MEMORY_MAP0</a></td>
+               <td width="60"></td>
+               <td>0x000000000</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.2</td>
+               <td>reg: <a href="#1.1.2">MEMORY_MAP1</a></td>
+               <td width="60"></td>
+               <td>0x000000004</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.3</td>
+               <td>reg: <a href="#1.1.3">MEMORY_MAP2</a></td>
+               <td width="60"></td>
+               <td>0x000000008</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.4</td>
+               <td>reg: <a href="#1.1.4">MEMORY_MAP3</a></td>
+               <td width="60"></td>
+               <td>0x00000000C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.5</td>
+               <td>reg: <a href="#1.1.5">MEMORY_MAP4</a></td>
+               <td width="60"></td>
+               <td>0x000000010</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.6</td>
+               <td>reg: <a href="#1.1.6">MEMORY_MAP5</a></td>
+               <td width="60"></td>
+               <td>0x000000014</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.7</td>
+               <td>reg: <a href="#1.1.7">MEMORY_MAP6</a></td>
+               <td width="60"></td>
+               <td>0x000000018</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.8</td>
+               <td>reg: <a href="#1.1.8">MEMORY_MAP7</a></td>
+               <td width="60"></td>
+               <td>0x00000001C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.9</td>
+               <td>reg: <a href="#1.1.9">MEMORY_MAP8</a></td>
+               <td width="60"></td>
+               <td>0x000000020</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.10</td>
+               <td>reg: <a href="#1.1.10">MEMORY_MAP9</a></td>
+               <td width="60"></td>
+               <td>0x000000024</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.11</td>
+               <td>reg: <a href="#1.1.11">MEMORY_MAP10</a></td>
+               <td width="60"></td>
+               <td>0x000000028</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.12</td>
+               <td>reg: <a href="#1.1.12">MEMORY_MAP11</a></td>
+               <td width="60"></td>
+               <td>0x00000002C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.13</td>
+               <td>reg: <a href="#1.1.13">MEMORY_MAP12</a></td>
+               <td width="60"></td>
+               <td>0x000000030</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.14</td>
+               <td>reg: <a href="#1.1.14">MEMORY_MAP13</a></td>
+               <td width="60"></td>
+               <td>0x000000034</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.15</td>
+               <td>reg: <a href="#1.1.15">MEMORY_MAP14</a></td>
+               <td width="60"></td>
+               <td>0x000000038</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.16</td>
+               <td>reg: <a href="#1.1.16">MEMORY_MAP15</a></td>
+               <td width="60"></td>
+               <td>0x00000003C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.17</td>
+               <td>reg: <a href="#1.1.17">MEMORY_MAP16</a></td>
+               <td width="60"></td>
+               <td>0x000000040</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.18</td>
+               <td>reg: <a href="#1.1.18">MEMORY_MAP17</a></td>
+               <td width="60"></td>
+               <td>0x000000044</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.19</td>
+               <td>reg: <a href="#1.1.19">MEMORY_MAP18</a></td>
+               <td width="60"></td>
+               <td>0x000000048</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.20</td>
+               <td>reg: <a href="#1.1.20">MEMORY_MAP19</a></td>
+               <td width="60"></td>
+               <td>0x00000004C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.21</td>
+               <td>reg: <a href="#1.1.21">MEMORY_MAP20</a></td>
+               <td width="60"></td>
+               <td>0x000000050</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.22</td>
+               <td>reg: <a href="#1.1.22">MEMORY_MAP21</a></td>
+               <td width="60"></td>
+               <td>0x000000054</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.23</td>
+               <td>reg: <a href="#1.1.23">MEMORY_MAP22</a></td>
+               <td width="60"></td>
+               <td>0x000000058</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.24</td>
+               <td>reg: <a href="#1.1.24">MEMORY_MAP23</a></td>
+               <td width="60"></td>
+               <td>0x00000005C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.25</td>
+               <td>reg: <a href="#1.1.25">MEMORY_MAP24</a></td>
+               <td width="60"></td>
+               <td>0x000000060</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.26</td>
+               <td>reg: <a href="#1.1.26">MEMORY_MAP25</a></td>
+               <td width="60"></td>
+               <td>0x000000064</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.27</td>
+               <td>reg: <a href="#1.1.27">MEMORY_MAP26</a></td>
+               <td width="60"></td>
+               <td>0x000000068</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.28</td>
+               <td>reg: <a href="#1.1.28">MEMORY_MAP27</a></td>
+               <td width="60"></td>
+               <td>0x00000006C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.29</td>
+               <td>reg: <a href="#1.1.29">MEMORY_MAP28</a></td>
+               <td width="60"></td>
+               <td>0x000000070</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.30</td>
+               <td>reg: <a href="#1.1.30">MEMORY_MAP29</a></td>
+               <td width="60"></td>
+               <td>0x000000074</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.31</td>
+               <td>reg: <a href="#1.1.31">MEMORY_MAP30</a></td>
+               <td width="60"></td>
+               <td>0x000000078</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.32</td>
+               <td>reg: <a href="#1.1.32">MEMORY_MAP31</a></td>
+               <td width="60"></td>
+               <td>0x00000007C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.33</td>
+               <td>reg: <a href="#1.1.33">OPCODE</a></td>
+               <td width="60"></td>
+               <td>0x000000080</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.34</td>
+               <td>reg: <a href="#1.1.34">N_NP_T0_T1_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x000000084</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.35</td>
+               <td>reg: <a href="#1.1.35">PKA_STATUS</a></td>
+               <td width="60"></td>
+               <td>0x000000088</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.36</td>
+               <td>reg: <a href="#1.1.36">PKA_SW_RESET</a></td>
+               <td width="60"></td>
+               <td>0x00000008C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.37</td>
+               <td>reg: <a href="#1.1.37">PKA_L0</a></td>
+               <td width="60"></td>
+               <td>0x000000090</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.38</td>
+               <td>reg: <a href="#1.1.38">PKA_L1</a></td>
+               <td width="60"></td>
+               <td>0x000000094</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.39</td>
+               <td>reg: <a href="#1.1.39">PKA_L2</a></td>
+               <td width="60"></td>
+               <td>0x000000098</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.40</td>
+               <td>reg: <a href="#1.1.40">PKA_L3</a></td>
+               <td width="60"></td>
+               <td>0x00000009C</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.41</td>
+               <td>reg: <a href="#1.1.41">PKA_L4</a></td>
+               <td width="60"></td>
+               <td>0x0000000A0</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.42</td>
+               <td>reg: <a href="#1.1.42">PKA_L5</a></td>
+               <td width="60"></td>
+               <td>0x0000000A4</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.43</td>
+               <td>reg: <a href="#1.1.43">PKA_L6</a></td>
+               <td width="60"></td>
+               <td>0x0000000A8</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.44</td>
+               <td>reg: <a href="#1.1.44">PKA_L7</a></td>
+               <td width="60"></td>
+               <td>0x0000000AC</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.45</td>
+               <td>reg: <a href="#1.1.45">PKA_PIPE_RDY</a></td>
+               <td width="60"></td>
+               <td>0x0000000B0</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.46</td>
+               <td>reg: <a href="#1.1.46">PKA_DONE</a></td>
+               <td width="60"></td>
+               <td>0x0000000B4</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.47</td>
+               <td>reg: <a href="#1.1.47">PKA_MON_SELECT</a></td>
+               <td width="60"></td>
+               <td>0x0000000B8</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.48</td>
+               <td>reg: <a href="#1.1.48">PKA_VERSION</a></td>
+               <td width="60"></td>
+               <td>0x0000000C4</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.49</td>
+               <td>reg: <a href="#1.1.49">PKA_MON_READ</a></td>
+               <td width="60"></td>
+               <td>0x0000000D0</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.50</td>
+               <td>reg: <a href="#1.1.50">PKA_SRAM_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x0000000D4</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.51</td>
+               <td>reg: <a href="#1.1.51">PKA_SRAM_WDATA</a></td>
+               <td width="60"></td>
+               <td>0x0000000D8</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.52</td>
+               <td>reg: <a href="#1.1.52">PKA_SRAM_RDATA</a></td>
+               <td width="60"></td>
+               <td>0x0000000DC</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.53</td>
+               <td>reg: <a href="#1.1.53">PKA_SRAM_WR_CLR</a></td>
+               <td width="60"></td>
+               <td>0x0000000E0</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.54</td>
+               <td>reg: <a href="#1.1.54">PKA_SRAM_RADDR</a></td>
+               <td width="60"></td>
+               <td>0x0000000E4</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.55</td>
+               <td>reg: <a href="#1.1.55">PKA_WORD_ACCESS</a></td>
+               <td width="60"></td>
+               <td>0x0000000F0</td>
+            </tr>
+            <tr>
+               <td width="100">1.1.56</td>
+               <td>reg: <a href="#1.1.56">PKA_BUFF_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x0000000F8</td>
+            </tr>
+            <tr>
+               <td width="100">1.2</td>
+               <td>block: <a href="#1.2">RNG</a></td>
+               <td width="60"></td>
+               <td>0x000000100</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.1</td>
+               <td>reg: <a href="#1.2.1">RNG_IMR</a></td>
+               <td width="60"></td>
+               <td>0x000000100</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.2</td>
+               <td>reg: <a href="#1.2.2">RNG_ISR</a></td>
+               <td width="60"></td>
+               <td>0x000000104</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.3</td>
+               <td>reg: <a href="#1.2.3">RNG_ICR</a></td>
+               <td width="60"></td>
+               <td>0x000000108</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.4</td>
+               <td>reg: <a href="#1.2.4">TRNG_CONFIG</a></td>
+               <td width="60"></td>
+               <td>0x00000010C</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.5</td>
+               <td>reg: <a href="#1.2.5">TRNG_VALID</a></td>
+               <td width="60"></td>
+               <td>0x000000110</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.6</td>
+               <td>reg: <a href="#1.2.6">EHR_DATA_0</a></td>
+               <td width="60"></td>
+               <td>0x000000114</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.7</td>
+               <td>reg: <a href="#1.2.7">EHR_DATA_1</a></td>
+               <td width="60"></td>
+               <td>0x000000118</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.8</td>
+               <td>reg: <a href="#1.2.8">EHR_DATA_2</a></td>
+               <td width="60"></td>
+               <td>0x00000011C</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.9</td>
+               <td>reg: <a href="#1.2.9">EHR_DATA_3</a></td>
+               <td width="60"></td>
+               <td>0x000000120</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.10</td>
+               <td>reg: <a href="#1.2.10">EHR_DATA_4</a></td>
+               <td width="60"></td>
+               <td>0x000000124</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.11</td>
+               <td>reg: <a href="#1.2.11">EHR_DATA_5</a></td>
+               <td width="60"></td>
+               <td>0x000000128</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.12</td>
+               <td>reg: <a href="#1.2.12">RND_SOURCE_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x00000012C</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.13</td>
+               <td>reg: <a href="#1.2.13">SAMPLE_CNT1</a></td>
+               <td width="60"></td>
+               <td>0x000000130</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.14</td>
+               <td>reg: <a href="#1.2.14">AUTOCORR_STATISTIC</a></td>
+               <td width="60"></td>
+               <td>0x000000134</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.15</td>
+               <td>reg: <a href="#1.2.15">TRNG_DEBUG_CONTROL</a></td>
+               <td width="60"></td>
+               <td>0x000000138</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.16</td>
+               <td>reg: <a href="#1.2.16">RNG_SW_RESET</a></td>
+               <td width="60"></td>
+               <td>0x000000140</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.17</td>
+               <td>reg: <a href="#1.2.17">RNG_DEBUG_EN_INPUT</a></td>
+               <td width="60"></td>
+               <td>0x0000001B4</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.18</td>
+               <td>reg: <a href="#1.2.18">RNG_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x0000001B8</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.19</td>
+               <td>reg: <a href="#1.2.19">RST_BITS_COUNTER</a></td>
+               <td width="60"></td>
+               <td>0x0000001BC</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.20</td>
+               <td>reg: <a href="#1.2.20">RNG_VERSION</a></td>
+               <td width="60"></td>
+               <td>0x0000001C0</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.21</td>
+               <td>reg: <a href="#1.2.21">RNG_CLK_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x0000001C4</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.22</td>
+               <td>reg: <a href="#1.2.22">RNG_DMA_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x0000001C8</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.23</td>
+               <td>reg: <a href="#1.2.23">RNG_DMA_SRC_MASK</a></td>
+               <td width="60"></td>
+               <td>0x0000001CC</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.24</td>
+               <td>reg: <a href="#1.2.24">RNG_DMA_SRAM_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x0000001D0</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.25</td>
+               <td>reg: <a href="#1.2.25">RNG_DMA_SAMPLES_NUM</a></td>
+               <td width="60"></td>
+               <td>0x0000001D4</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.26</td>
+               <td>reg: <a href="#1.2.26">RNG_WATCHDOG_VAL</a></td>
+               <td width="60"></td>
+               <td>0x0000001D8</td>
+            </tr>
+            <tr>
+               <td width="100">1.2.27</td>
+               <td>reg: <a href="#1.2.27">RNG_DMA_STATUS</a></td>
+               <td width="60"></td>
+               <td>0x0000001DC</td>
+            </tr>
+            <tr>
+               <td width="100">1.3</td>
+               <td>block: <a href="#1.3">CHACHA</a></td>
+               <td width="60"></td>
+               <td>0x000000380</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.1</td>
+               <td>reg: <a href="#1.3.1">CHACHA_CONTROL_REG</a></td>
+               <td width="60"></td>
+               <td>0x000000380</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.2</td>
+               <td>reg: <a href="#1.3.2">CHACHA_VERSION</a></td>
+               <td width="60"></td>
+               <td>0x000000384</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.3</td>
+               <td>reg: <a href="#1.3.3">CHACHA_KEY0</a></td>
+               <td width="60"></td>
+               <td>0x000000388</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.4</td>
+               <td>reg: <a href="#1.3.4">CHACHA_KEY1</a></td>
+               <td width="60"></td>
+               <td>0x00000038C</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.5</td>
+               <td>reg: <a href="#1.3.5">CHACHA_KEY2</a></td>
+               <td width="60"></td>
+               <td>0x000000390</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.6</td>
+               <td>reg: <a href="#1.3.6">CHACHA_KEY3</a></td>
+               <td width="60"></td>
+               <td>0x000000394</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.7</td>
+               <td>reg: <a href="#1.3.7">CHACHA_KEY4</a></td>
+               <td width="60"></td>
+               <td>0x000000398</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.8</td>
+               <td>reg: <a href="#1.3.8">CHACHA_KEY5</a></td>
+               <td width="60"></td>
+               <td>0x00000039C</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.9</td>
+               <td>reg: <a href="#1.3.9">CHACHA_KEY6</a></td>
+               <td width="60"></td>
+               <td>0x0000003A0</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.10</td>
+               <td>reg: <a href="#1.3.10">CHACHA_KEY7</a></td>
+               <td width="60"></td>
+               <td>0x0000003A4</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.11</td>
+               <td>reg: <a href="#1.3.11">CHACHA_IV_0</a></td>
+               <td width="60"></td>
+               <td>0x0000003A8</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.12</td>
+               <td>reg: <a href="#1.3.12">CHACHA_IV_1</a></td>
+               <td width="60"></td>
+               <td>0x0000003AC</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.13</td>
+               <td>reg: <a href="#1.3.13">CHACHA_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x0000003B0</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.14</td>
+               <td>reg: <a href="#1.3.14">CHACHA_HW_FLAGS</a></td>
+               <td width="60"></td>
+               <td>0x0000003B4</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.15</td>
+               <td>reg: <a href="#1.3.15">CHACHA_BLOCK_CNT_LSB</a></td>
+               <td width="60"></td>
+               <td>0x0000003B8</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.16</td>
+               <td>reg: <a href="#1.3.16">CHACHA_BLOCK_CNT_MSB</a></td>
+               <td width="60"></td>
+               <td>0x0000003BC</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.17</td>
+               <td>reg: <a href="#1.3.17">CHACHA_SW_RESET</a></td>
+               <td width="60"></td>
+               <td>0x0000003C0</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.18</td>
+               <td>reg: <a href="#1.3.18">CHACHA_FOR_POLY_KEY0</a></td>
+               <td width="60"></td>
+               <td>0x0000003C4</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.19</td>
+               <td>reg: <a href="#1.3.19">CHACHA_FOR_POLY_KEY1</a></td>
+               <td width="60"></td>
+               <td>0x0000003C8</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.20</td>
+               <td>reg: <a href="#1.3.20">CHACHA_FOR_POLY_KEY2</a></td>
+               <td width="60"></td>
+               <td>0x0000003CC</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.21</td>
+               <td>reg: <a href="#1.3.21">CHACHA_FOR_POLY_KEY3</a></td>
+               <td width="60"></td>
+               <td>0x0000003D0</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.22</td>
+               <td>reg: <a href="#1.3.22">CHACHA_FOR_POLY_KEY4</a></td>
+               <td width="60"></td>
+               <td>0x0000003D4</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.23</td>
+               <td>reg: <a href="#1.3.23">CHACHA_FOR_POLY_KEY5</a></td>
+               <td width="60"></td>
+               <td>0x0000003D8</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.24</td>
+               <td>reg: <a href="#1.3.24">CHACHA_FOR_POLY_KEY6</a></td>
+               <td width="60"></td>
+               <td>0x0000003DC</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.25</td>
+               <td>reg: <a href="#1.3.25">CHACHA_FOR_POLY_KEY7</a></td>
+               <td width="60"></td>
+               <td>0x0000003E0</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.26</td>
+               <td>reg: <a href="#1.3.26">CHACHA_BYTE_WORD_ORDER_CNTL_REG</a></td>
+               <td width="60"></td>
+               <td>0x0000003E4</td>
+            </tr>
+            <tr>
+               <td width="100">1.3.27</td>
+               <td>reg: <a href="#1.3.27">CHACHA_DEBUG_REG</a></td>
+               <td width="60"></td>
+               <td>0x0000003E8</td>
+            </tr>
+            <tr>
+               <td width="100">1.4</td>
+               <td>block: <a href="#1.4">AES</a></td>
+               <td width="60"></td>
+               <td>0x000000400</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.1</td>
+               <td>reg: <a href="#1.4.1">AES_KEY_0_0</a></td>
+               <td width="60"></td>
+               <td>0x000000400</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.2</td>
+               <td>reg: <a href="#1.4.2">AES_KEY_0_1</a></td>
+               <td width="60"></td>
+               <td>0x000000404</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.3</td>
+               <td>reg: <a href="#1.4.3">AES_KEY_0_2</a></td>
+               <td width="60"></td>
+               <td>0x000000408</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.4</td>
+               <td>reg: <a href="#1.4.4">AES_KEY_0_3</a></td>
+               <td width="60"></td>
+               <td>0x00000040C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.5</td>
+               <td>reg: <a href="#1.4.5">AES_KEY_0_4</a></td>
+               <td width="60"></td>
+               <td>0x000000410</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.6</td>
+               <td>reg: <a href="#1.4.6">AES_KEY_0_5</a></td>
+               <td width="60"></td>
+               <td>0x000000414</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.7</td>
+               <td>reg: <a href="#1.4.7">AES_KEY_0_6</a></td>
+               <td width="60"></td>
+               <td>0x000000418</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.8</td>
+               <td>reg: <a href="#1.4.8">AES_KEY_0_7</a></td>
+               <td width="60"></td>
+               <td>0x00000041C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.9</td>
+               <td>reg: <a href="#1.4.9">AES_KEY_1_0</a></td>
+               <td width="60"></td>
+               <td>0x000000420</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.10</td>
+               <td>reg: <a href="#1.4.10">AES_KEY_1_1</a></td>
+               <td width="60"></td>
+               <td>0x000000424</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.11</td>
+               <td>reg: <a href="#1.4.11">AES_KEY_1_2</a></td>
+               <td width="60"></td>
+               <td>0x000000428</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.12</td>
+               <td>reg: <a href="#1.4.12">AES_KEY_1_3</a></td>
+               <td width="60"></td>
+               <td>0x00000042C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.13</td>
+               <td>reg: <a href="#1.4.13">AES_KEY_1_4</a></td>
+               <td width="60"></td>
+               <td>0x000000430</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.14</td>
+               <td>reg: <a href="#1.4.14">AES_KEY_1_5</a></td>
+               <td width="60"></td>
+               <td>0x000000434</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.15</td>
+               <td>reg: <a href="#1.4.15">AES_KEY_1_6</a></td>
+               <td width="60"></td>
+               <td>0x000000438</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.16</td>
+               <td>reg: <a href="#1.4.16">AES_KEY_1_7</a></td>
+               <td width="60"></td>
+               <td>0x00000043C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.17</td>
+               <td>reg: <a href="#1.4.17">AES_IV_0_0</a></td>
+               <td width="60"></td>
+               <td>0x000000440</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.18</td>
+               <td>reg: <a href="#1.4.18">AES_IV_0_1</a></td>
+               <td width="60"></td>
+               <td>0x000000444</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.19</td>
+               <td>reg: <a href="#1.4.19">AES_IV_0_2</a></td>
+               <td width="60"></td>
+               <td>0x000000448</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.20</td>
+               <td>reg: <a href="#1.4.20">AES_IV_0_3</a></td>
+               <td width="60"></td>
+               <td>0x00000044C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.21</td>
+               <td>reg: <a href="#1.4.21">AES_IV_1_0</a></td>
+               <td width="60"></td>
+               <td>0x000000450</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.22</td>
+               <td>reg: <a href="#1.4.22">AES_IV_1_1</a></td>
+               <td width="60"></td>
+               <td>0x000000454</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.23</td>
+               <td>reg: <a href="#1.4.23">AES_IV_1_2</a></td>
+               <td width="60"></td>
+               <td>0x000000458</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.24</td>
+               <td>reg: <a href="#1.4.24">AES_IV_1_3</a></td>
+               <td width="60"></td>
+               <td>0x00000045C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.25</td>
+               <td>reg: <a href="#1.4.25">AES_CTR_0_0</a></td>
+               <td width="60"></td>
+               <td>0x000000460</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.26</td>
+               <td>reg: <a href="#1.4.26">AES_CTR_0_1</a></td>
+               <td width="60"></td>
+               <td>0x000000464</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.27</td>
+               <td>reg: <a href="#1.4.27">AES_CTR_0_2</a></td>
+               <td width="60"></td>
+               <td>0x000000468</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.28</td>
+               <td>reg: <a href="#1.4.28">AES_CTR_0_3</a></td>
+               <td width="60"></td>
+               <td>0x00000046C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.29</td>
+               <td>reg: <a href="#1.4.29">AES_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x000000470</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.30</td>
+               <td>reg: <a href="#1.4.30">AES_SK</a></td>
+               <td width="60"></td>
+               <td>0x000000478</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.31</td>
+               <td>reg: <a href="#1.4.31">AES_CMAC_INIT</a></td>
+               <td width="60"></td>
+               <td>0x00000047C</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.32</td>
+               <td>reg: <a href="#1.4.32">AES_SK1</a></td>
+               <td width="60"></td>
+               <td>0x0000004B4</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.33</td>
+               <td>reg: <a href="#1.4.33">AES_REMAINING_BYTES</a></td>
+               <td width="60"></td>
+               <td>0x0000004BC</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.34</td>
+               <td>reg: <a href="#1.4.34">AES_CONTROL</a></td>
+               <td width="60"></td>
+               <td>0x0000004C0</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.35</td>
+               <td>reg: <a href="#1.4.35">AES_HW_FLAGS</a></td>
+               <td width="60"></td>
+               <td>0x0000004C8</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.36</td>
+               <td>reg: <a href="#1.4.36">AES_CTR_NO_INCREMENT</a></td>
+               <td width="60"></td>
+               <td>0x0000004D8</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.37</td>
+               <td>reg: <a href="#1.4.37">AES_DFA_IS_ON</a></td>
+               <td width="60"></td>
+               <td>0x0000004F0</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.38</td>
+               <td>reg: <a href="#1.4.38">AES_DFA_ERR_STATUS</a></td>
+               <td width="60"></td>
+               <td>0x0000004F8</td>
+            </tr>
+            <tr>
+               <td width="100">1.4.39</td>
+               <td>reg: <a href="#1.4.39">AES_CMAC_SIZE0_KICK</a></td>
+               <td width="60"></td>
+               <td>0x000000524</td>
+            </tr>
+            <tr>
+               <td width="100">1.5</td>
+               <td>block: <a href="#1.5">HASH</a></td>
+               <td width="60"></td>
+               <td>0x000000640</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.1</td>
+               <td>reg: <a href="#1.5.1">HASH_H0</a></td>
+               <td width="60"></td>
+               <td>0x000000640</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.2</td>
+               <td>reg: <a href="#1.5.2">HASH_H1</a></td>
+               <td width="60"></td>
+               <td>0x000000644</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.3</td>
+               <td>reg: <a href="#1.5.3">HASH_H2</a></td>
+               <td width="60"></td>
+               <td>0x000000648</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.4</td>
+               <td>reg: <a href="#1.5.4">HASH_H3</a></td>
+               <td width="60"></td>
+               <td>0x00000064C</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.5</td>
+               <td>reg: <a href="#1.5.5">HASH_H4</a></td>
+               <td width="60"></td>
+               <td>0x000000650</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.6</td>
+               <td>reg: <a href="#1.5.6">HASH_H5</a></td>
+               <td width="60"></td>
+               <td>0x000000654</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.7</td>
+               <td>reg: <a href="#1.5.7">HASH_H6</a></td>
+               <td width="60"></td>
+               <td>0x000000658</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.8</td>
+               <td>reg: <a href="#1.5.8">HASH_H7</a></td>
+               <td width="60"></td>
+               <td>0x00000065C</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.9</td>
+               <td>reg: <a href="#1.5.9">HASH_H8</a></td>
+               <td width="60"></td>
+               <td>0x000000660</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.10</td>
+               <td>reg: <a href="#1.5.10">AUTO_HW_PADDING</a></td>
+               <td width="60"></td>
+               <td>0x000000684</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.11</td>
+               <td>reg: <a href="#1.5.11">HASH_XOR_DIN</a></td>
+               <td width="60"></td>
+               <td>0x000000688</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.12</td>
+               <td>reg: <a href="#1.5.12">LOAD_INIT_STATE</a></td>
+               <td width="60"></td>
+               <td>0x000000694</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.13</td>
+               <td>reg: <a href="#1.5.13">HASH_SEL_AES_MAC</a></td>
+               <td width="60"></td>
+               <td>0x0000006A4</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.14</td>
+               <td>reg: <a href="#1.5.14">HASH_VERSION</a></td>
+               <td width="60"></td>
+               <td>0x0000007B0</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.15</td>
+               <td>reg: <a href="#1.5.15">HASH_CONTROL</a></td>
+               <td width="60"></td>
+               <td>0x0000007C0</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.16</td>
+               <td>reg: <a href="#1.5.16">HASH_PAD_EN</a></td>
+               <td width="60"></td>
+               <td>0x0000007C4</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.17</td>
+               <td>reg: <a href="#1.5.17">HASH_PAD_CFG</a></td>
+               <td width="60"></td>
+               <td>0x0000007C8</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.18</td>
+               <td>reg: <a href="#1.5.18">HASH_CUR_LEN_0</a></td>
+               <td width="60"></td>
+               <td>0x0000007CC</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.19</td>
+               <td>reg: <a href="#1.5.19">HASH_CUR_LEN_1</a></td>
+               <td width="60"></td>
+               <td>0x0000007D0</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.20</td>
+               <td>reg: <a href="#1.5.20">HASH_PARAM</a></td>
+               <td width="60"></td>
+               <td>0x0000007DC</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.21</td>
+               <td>reg: <a href="#1.5.21">HASH_AES_SW_RESET</a></td>
+               <td width="60"></td>
+               <td>0x0000007E4</td>
+            </tr>
+            <tr>
+               <td width="100">1.5.22</td>
+               <td>reg: <a href="#1.5.22">HASH_ENDIANESS</a></td>
+               <td width="60"></td>
+               <td>0x0000007E8</td>
+            </tr>
+            <tr>
+               <td width="100">1.6</td>
+               <td>block: <a href="#1.6">MISC</a></td>
+               <td width="60"></td>
+               <td>0x000000800</td>
+            </tr>
+            <tr>
+               <td width="100">1.6.1</td>
+               <td>reg: <a href="#1.6.1">AES_CLK_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x000000810</td>
+            </tr>
+            <tr>
+               <td width="100">1.6.2</td>
+               <td>reg: <a href="#1.6.2">HASH_CLK_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x000000818</td>
+            </tr>
+            <tr>
+               <td width="100">1.6.3</td>
+               <td>reg: <a href="#1.6.3">PKA_CLK_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x00000081C</td>
+            </tr>
+            <tr>
+               <td width="100">1.6.4</td>
+               <td>reg: <a href="#1.6.4">DMA_CLK_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x000000820</td>
+            </tr>
+            <tr>
+               <td width="100">1.6.5</td>
+               <td>reg: <a href="#1.6.5">CLK_STATUS</a></td>
+               <td width="60"></td>
+               <td>0x000000824</td>
+            </tr>
+            <tr>
+               <td width="100">1.6.6</td>
+               <td>reg: <a href="#1.6.6">CHACHA_CLK_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x000000858</td>
+            </tr>
+            <tr>
+               <td width="100">1.7</td>
+               <td>block: <a href="#1.7">CC_CTL</a></td>
+               <td width="60"></td>
+               <td>0x000000900</td>
+            </tr>
+            <tr>
+               <td width="100">1.7.1</td>
+               <td>reg: <a href="#1.7.1">CRYPTO_CTL</a></td>
+               <td width="60"></td>
+               <td>0x000000900</td>
+            </tr>
+            <tr>
+               <td width="100">1.7.2</td>
+               <td>reg: <a href="#1.7.2">CRYPTO_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x000000910</td>
+            </tr>
+            <tr>
+               <td width="100">1.7.3</td>
+               <td>reg: <a href="#1.7.3">HASH_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x00000091C</td>
+            </tr>
+            <tr>
+               <td width="100">1.7.4</td>
+               <td>reg: <a href="#1.7.4">CONTEXT_ID</a></td>
+               <td width="60"></td>
+               <td>0x000000930</td>
+            </tr>
+            <tr>
+               <td width="100">1.8</td>
+               <td>block: <a href="#1.8">GHASH</a></td>
+               <td width="60"></td>
+               <td>0x000000960</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.1</td>
+               <td>reg: <a href="#1.8.1">GHASH_SUBKEY_0_0</a></td>
+               <td width="60"></td>
+               <td>0x000000960</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.2</td>
+               <td>reg: <a href="#1.8.2">GHASH_SUBKEY_0_1</a></td>
+               <td width="60"></td>
+               <td>0x000000964</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.3</td>
+               <td>reg: <a href="#1.8.3">GHASH_SUBKEY_0_2</a></td>
+               <td width="60"></td>
+               <td>0x000000968</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.4</td>
+               <td>reg: <a href="#1.8.4">GHASH_SUBKEY_0_3</a></td>
+               <td width="60"></td>
+               <td>0x00000096C</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.5</td>
+               <td>reg: <a href="#1.8.5">GHASH_IV_0_0</a></td>
+               <td width="60"></td>
+               <td>0x000000970</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.6</td>
+               <td>reg: <a href="#1.8.6">GHASH_IV_0_1</a></td>
+               <td width="60"></td>
+               <td>0x000000974</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.7</td>
+               <td>reg: <a href="#1.8.7">GHASH_IV_0_2</a></td>
+               <td width="60"></td>
+               <td>0x000000978</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.8</td>
+               <td>reg: <a href="#1.8.8">GHASH_IV_0_3</a></td>
+               <td width="60"></td>
+               <td>0x00000097C</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.9</td>
+               <td>reg: <a href="#1.8.9">GHASH_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x000000980</td>
+            </tr>
+            <tr>
+               <td width="100">1.8.10</td>
+               <td>reg: <a href="#1.8.10">GHASH_INIT</a></td>
+               <td width="60"></td>
+               <td>0x000000984</td>
+            </tr>
+            <tr>
+               <td width="100">1.9</td>
+               <td>block: <a href="#1.9">HOST_RGF</a></td>
+               <td width="60"></td>
+               <td>0x000000A00</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.1</td>
+               <td>reg: <a href="#1.9.1">HOST_RGF_IRR</a></td>
+               <td width="60"></td>
+               <td>0x000000A00</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.2</td>
+               <td>reg: <a href="#1.9.2">HOST_RGF_IMR</a></td>
+               <td width="60"></td>
+               <td>0x000000A04</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.3</td>
+               <td>reg: <a href="#1.9.3">HOST_RGF_ICR</a></td>
+               <td width="60"></td>
+               <td>0x000000A08</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.4</td>
+               <td>reg: <a href="#1.9.4">HOST_RGF_ENDIAN</a></td>
+               <td width="60"></td>
+               <td>0x000000A0C</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.5</td>
+               <td>reg: <a href="#1.9.5">HOST_RGF_SIGNATURE</a></td>
+               <td width="60"></td>
+               <td>0x000000A24</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.6</td>
+               <td>reg: <a href="#1.9.6">HOST_BOOT</a></td>
+               <td width="60"></td>
+               <td>0x000000A28</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.7</td>
+               <td>reg: <a href="#1.9.7">HOST_CRYPTOKEY_SEL</a></td>
+               <td width="60"></td>
+               <td>0x000000A38</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.8</td>
+               <td>reg: <a href="#1.9.8">HOST_CORE_CLK_GATING_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x000000A78</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.9</td>
+               <td>reg: <a href="#1.9.9">HOST_CC_IS_IDLE</a></td>
+               <td width="60"></td>
+               <td>0x000000A7C</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.10</td>
+               <td>reg: <a href="#1.9.10">HOST_POWERDOWN</a></td>
+               <td width="60"></td>
+               <td>0x000000A80</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.11</td>
+               <td>reg: <a href="#1.9.11">HOST_REMOVE_GHASH_ENGINE</a></td>
+               <td width="60"></td>
+               <td>0x000000A84</td>
+            </tr>
+            <tr>
+               <td width="100">1.9.12</td>
+               <td>reg: <a href="#1.9.12">HOST_REMOVE_CHACHA_ENGINE</a></td>
+               <td width="60"></td>
+               <td>0x000000A88</td>
+            </tr>
+            <tr>
+               <td width="100">1.10</td>
+               <td>block: <a href="#1.10">AHB</a></td>
+               <td width="60"></td>
+               <td>0x000000B00</td>
+            </tr>
+            <tr>
+               <td width="100">1.10.1</td>
+               <td>reg: <a href="#1.10.1">AHBM_SINGLES</a></td>
+               <td width="60"></td>
+               <td>0x000000B00</td>
+            </tr>
+            <tr>
+               <td width="100">1.10.2</td>
+               <td>reg: <a href="#1.10.2">AHBM_HPROT</a></td>
+               <td width="60"></td>
+               <td>0x000000B04</td>
+            </tr>
+            <tr>
+               <td width="100">1.10.3</td>
+               <td>reg: <a href="#1.10.3">AHBM_HMASTLOCK</a></td>
+               <td width="60"></td>
+               <td>0x000000B08</td>
+            </tr>
+            <tr>
+               <td width="100">1.10.4</td>
+               <td>reg: <a href="#1.10.4">AHBM_HNONSEC</a></td>
+               <td width="60"></td>
+               <td>0x000000B0C</td>
+            </tr>
+            <tr>
+               <td width="100">1.11</td>
+               <td>block: <a href="#1.11">DIN</a></td>
+               <td width="60"></td>
+               <td>0x000000C00</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.1</td>
+               <td>reg: <a href="#1.11.1">DIN_BUFFER</a></td>
+               <td width="60"></td>
+               <td>0x000000C00</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.2</td>
+               <td>reg: <a href="#1.11.2">DIN_MEM_DMA_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x000000C20</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.3</td>
+               <td>reg: <a href="#1.11.3">SRC_LLI_WORD0</a></td>
+               <td width="60"></td>
+               <td>0x000000C28</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.4</td>
+               <td>reg: <a href="#1.11.4">SRC_LLI_WORD1</a></td>
+               <td width="60"></td>
+               <td>0x000000C2C</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.5</td>
+               <td>reg: <a href="#1.11.5">SRAM_SRC_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x000000C30</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.6</td>
+               <td>reg: <a href="#1.11.6">DIN_SRAM_BYTES_LEN</a></td>
+               <td width="60"></td>
+               <td>0x000000C34</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.7</td>
+               <td>reg: <a href="#1.11.7">DIN_SRAM_DMA_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x000000C38</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.8</td>
+               <td>reg: <a href="#1.11.8">DIN_SRAM_ENDIANNESS</a></td>
+               <td width="60"></td>
+               <td>0x000000C3C</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.9</td>
+               <td>reg: <a href="#1.11.9">DIN_CPU_DATA_SIZE</a></td>
+               <td width="60"></td>
+               <td>0x000000C48</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.10</td>
+               <td>reg: <a href="#1.11.10">FIFO_IN_EMPTY</a></td>
+               <td width="60"></td>
+               <td>0x000000C50</td>
+            </tr>
+            <tr>
+               <td width="100">1.11.11</td>
+               <td>reg: <a href="#1.11.11">DIN_FIFO_RST_PNTR</a></td>
+               <td width="60"></td>
+               <td>0x000000C58</td>
+            </tr>
+            <tr>
+               <td width="100">1.12</td>
+               <td>block: <a href="#1.12">DOUT</a></td>
+               <td width="60"></td>
+               <td>0x000000D00</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.1</td>
+               <td>reg: <a href="#1.12.1">DOUT_BUFFER</a></td>
+               <td width="60"></td>
+               <td>0x000000D00</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.2</td>
+               <td>reg: <a href="#1.12.2">DOUT_MEM_DMA_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x000000D20</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.3</td>
+               <td>reg: <a href="#1.12.3">DST_LLI_WORD0</a></td>
+               <td width="60"></td>
+               <td>0x000000D28</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.4</td>
+               <td>reg: <a href="#1.12.4">DST_LLI_WORD1</a></td>
+               <td width="60"></td>
+               <td>0x000000D2C</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.5</td>
+               <td>reg: <a href="#1.12.5">SRAM_DEST_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x000000D30</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.6</td>
+               <td>reg: <a href="#1.12.6">DOUT_SRAM_BYTES_LEN</a></td>
+               <td width="60"></td>
+               <td>0x000000D34</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.7</td>
+               <td>reg: <a href="#1.12.7">DOUT_SRAM_DMA_BUSY</a></td>
+               <td width="60"></td>
+               <td>0x000000D38</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.8</td>
+               <td>reg: <a href="#1.12.8">DOUT_SRAM_ENDIANNESS</a></td>
+               <td width="60"></td>
+               <td>0x000000D3C</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.9</td>
+               <td>reg: <a href="#1.12.9">READ_ALIGN_LAST</a></td>
+               <td width="60"></td>
+               <td>0x000000D44</td>
+            </tr>
+            <tr>
+               <td width="100">1.12.10</td>
+               <td>reg: <a href="#1.12.10">DOUT_FIFO_EMPTY</a></td>
+               <td width="60"></td>
+               <td>0x000000D50</td>
+            </tr>
+            <tr>
+               <td width="100">1.13</td>
+               <td>block: <a href="#1.13">HOST_SRAM</a></td>
+               <td width="60"></td>
+               <td>0x000000F00</td>
+            </tr>
+            <tr>
+               <td width="100">1.13.1</td>
+               <td>reg: <a href="#1.13.1">SRAM_DATA</a></td>
+               <td width="60"></td>
+               <td>0x000000F00</td>
+            </tr>
+            <tr>
+               <td width="100">1.13.2</td>
+               <td>reg: <a href="#1.13.2">SRAM_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x000000F04</td>
+            </tr>
+            <tr>
+               <td width="100">1.13.3</td>
+               <td>reg: <a href="#1.13.3">SRAM_DATA_READY</a></td>
+               <td width="60"></td>
+               <td>0x000000F08</td>
+            </tr>
+            <tr>
+               <td width="100">1.14</td>
+               <td>block: <a href="#1.14">ID_REGISTERS</a></td>
+               <td width="60"></td>
+               <td>0x000000F10</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.1</td>
+               <td>reg: <a href="#1.14.1">PERIPHERAL_ID_4</a></td>
+               <td width="60"></td>
+               <td>0x000000FD0</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.2</td>
+               <td>reg: <a href="#1.14.2">PIDRESERVED0</a></td>
+               <td width="60"></td>
+               <td>0x000000FD4</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.3</td>
+               <td>reg: <a href="#1.14.3">PIDRESERVED1</a></td>
+               <td width="60"></td>
+               <td>0x000000FD8</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.4</td>
+               <td>reg: <a href="#1.14.4">PIDRESERVED2</a></td>
+               <td width="60"></td>
+               <td>0x000000FDC</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.5</td>
+               <td>reg: <a href="#1.14.5">PERIPHERAL_ID_0</a></td>
+               <td width="60"></td>
+               <td>0x000000FE0</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.6</td>
+               <td>reg: <a href="#1.14.6">PERIPHERAL_ID_1</a></td>
+               <td width="60"></td>
+               <td>0x000000FE4</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.7</td>
+               <td>reg: <a href="#1.14.7">PERIPHERAL_ID_2</a></td>
+               <td width="60"></td>
+               <td>0x000000FE8</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.8</td>
+               <td>reg: <a href="#1.14.8">PERIPHERAL_ID_3</a></td>
+               <td width="60"></td>
+               <td>0x000000FEC</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.9</td>
+               <td>reg: <a href="#1.14.9">COMPONENT_ID_0</a></td>
+               <td width="60"></td>
+               <td>0x000000FF0</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.10</td>
+               <td>reg: <a href="#1.14.10">COMPONENT_ID_1</a></td>
+               <td width="60"></td>
+               <td>0x000000FF4</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.11</td>
+               <td>reg: <a href="#1.14.11">COMPONENT_ID_2</a></td>
+               <td width="60"></td>
+               <td>0x000000FF8</td>
+            </tr>
+            <tr>
+               <td width="100">1.14.12</td>
+               <td>reg: <a href="#1.14.12">COMPONENT_ID_3</a></td>
+               <td width="60"></td>
+               <td>0x000000FFC</td>
+            </tr>
+            <tr>
+               <td width="100">1.15</td>
+               <td>block: <a href="#1.15">AO</a></td>
+               <td width="60"></td>
+               <td>0x000001E00</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.1</td>
+               <td>reg: <a href="#1.15.1">HOST_DCU_EN0</a></td>
+               <td width="60"></td>
+               <td>0x000001E00</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.2</td>
+               <td>reg: <a href="#1.15.2">HOST_DCU_EN1</a></td>
+               <td width="60"></td>
+               <td>0x000001E04</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.3</td>
+               <td>reg: <a href="#1.15.3">HOST_DCU_EN2</a></td>
+               <td width="60"></td>
+               <td>0x000001E08</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.4</td>
+               <td>reg: <a href="#1.15.4">HOST_DCU_EN3</a></td>
+               <td width="60"></td>
+               <td>0x000001E0C</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.5</td>
+               <td>reg: <a href="#1.15.5">HOST_DCU_LOCK0</a></td>
+               <td width="60"></td>
+               <td>0x000001E10</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.6</td>
+               <td>reg: <a href="#1.15.6">HOST_DCU_LOCK1</a></td>
+               <td width="60"></td>
+               <td>0x000001E14</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.7</td>
+               <td>reg: <a href="#1.15.7">HOST_DCU_LOCK2</a></td>
+               <td width="60"></td>
+               <td>0x000001E18</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.8</td>
+               <td>reg: <a href="#1.15.8">HOST_DCU_LOCK3</a></td>
+               <td width="60"></td>
+               <td>0x000001E1C</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.9</td>
+               <td>reg: <a href="#1.15.9">AO_ICV_DCU_RESTRICTION_MASK0</a></td>
+               <td width="60"></td>
+               <td>0x000001E20</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.10</td>
+               <td>reg: <a href="#1.15.10">AO_ICV_DCU_RESTRICTION_MASK1</a></td>
+               <td width="60"></td>
+               <td>0x000001E24</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.11</td>
+               <td>reg: <a href="#1.15.11">AO_ICV_DCU_RESTRICTION_MASK2</a></td>
+               <td width="60"></td>
+               <td>0x000001E28</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.12</td>
+               <td>reg: <a href="#1.15.12">AO_ICV_DCU_RESTRICTION_MASK3</a></td>
+               <td width="60"></td>
+               <td>0x000001E2C</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.13</td>
+               <td>reg: <a href="#1.15.13">AO_CC_SEC_DEBUG_RESET</a></td>
+               <td width="60"></td>
+               <td>0x000001E30</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.14</td>
+               <td>reg: <a href="#1.15.14">HOST_AO_LOCK_BITS</a></td>
+               <td width="60"></td>
+               <td>0x000001E34</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.15</td>
+               <td>reg: <a href="#1.15.15">AO_APB_FILTERING</a></td>
+               <td width="60"></td>
+               <td>0x000001E38</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.16</td>
+               <td>reg: <a href="#1.15.16">AO_CC_GPPC</a></td>
+               <td width="60"></td>
+               <td>0x000001E3C</td>
+            </tr>
+            <tr>
+               <td width="100">1.15.17</td>
+               <td>reg: <a href="#1.15.17">HOST_RGF_CC_SW_RST</a></td>
+               <td width="60"></td>
+               <td>0x000001E40</td>
+            </tr>
+            <tr>
+               <td width="100">1.16</td>
+               <td>block: <a href="#1.16">NVM</a></td>
+               <td width="60"></td>
+               <td>0x000001F00</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.1</td>
+               <td>reg: <a href="#1.16.1">AIB_FUSE_PROG_COMPLETED</a></td>
+               <td width="60"></td>
+               <td>0x000001F04</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.2</td>
+               <td>reg: <a href="#1.16.2">NVM_DEBUG_STATUS</a></td>
+               <td width="60"></td>
+               <td>0x000001F08</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.3</td>
+               <td>reg: <a href="#1.16.3">LCS_IS_VALID</a></td>
+               <td width="60"></td>
+               <td>0x000001F0C</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.4</td>
+               <td>reg: <a href="#1.16.4">NVM_IS_IDLE</a></td>
+               <td width="60"></td>
+               <td>0x000001F10</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.5</td>
+               <td>reg: <a href="#1.16.5">LCS_REG</a></td>
+               <td width="60"></td>
+               <td>0x000001F14</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.6</td>
+               <td>reg: <a href="#1.16.6">HOST_SHADOW_KDR_REG</a></td>
+               <td width="60"></td>
+               <td>0x000001F18</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.7</td>
+               <td>reg: <a href="#1.16.7">HOST_SHADOW_KCP_REG</a></td>
+               <td width="60"></td>
+               <td>0x000001F1C</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.8</td>
+               <td>reg: <a href="#1.16.8">HOST_SHADOW_KCE_REG</a></td>
+               <td width="60"></td>
+               <td>0x000001F20</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.9</td>
+               <td>reg: <a href="#1.16.9">HOST_SHADOW_KPICV_REG</a></td>
+               <td width="60"></td>
+               <td>0x000001F24</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.10</td>
+               <td>reg: <a href="#1.16.10">HOST_SHADOW_KCEICV_REG</a></td>
+               <td width="60"></td>
+               <td>0x000001F28</td>
+            </tr>
+            <tr>
+               <td width="100">1.16.11</td>
+               <td>reg: <a href="#1.16.11">OTP_ADDR_WIDTH_DEF</a></td>
+               <td width="60"></td>
+               <td>0x000001F2C</td>
+            </tr>
+            <tr>
+               <td width="100">1.17</td>
+               <td>block: <a href="#1.17">ENV_CC_MEMORIES</a></td>
+               <td width="60"></td>
+               <td>0x060004000</td>
+            </tr>
+            <tr>
+               <td width="100">1.17.1</td>
+               <td>reg: <a href="#1.17.1">ENV_FUSE_READY</a></td>
+               <td width="60"></td>
+               <td>0x060004000</td>
+            </tr>
+            <tr>
+               <td width="100">1.17.2</td>
+               <td>reg: <a href="#1.17.2">ENV_PERF_RAM_MASTER</a></td>
+               <td width="60"></td>
+               <td>0x0600040EC</td>
+            </tr>
+            <tr>
+               <td width="100">1.17.3</td>
+               <td>reg: <a href="#1.17.3">ENV_PERF_RAM_ADDR_HIGH4</a></td>
+               <td width="60"></td>
+               <td>0x0600040F0</td>
+            </tr>
+            <tr>
+               <td width="100">1.17.4</td>
+               <td>reg: <a href="#1.17.4">ENV_FUSES_RAM</a></td>
+               <td width="60"></td>
+               <td>0x0600043EC</td>
+            </tr>
+            <tr>
+               <td width="100">1.18</td>
+               <td>block: <a href="#1.18">FPGA_ENV_REGS</a></td>
+               <td width="60"></td>
+               <td>0x060005000</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.1</td>
+               <td>reg: <a href="#1.18.1">ENV_FPGA_PKA_DEBUG_MODE</a></td>
+               <td width="60"></td>
+               <td>0x060005024</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.2</td>
+               <td>reg: <a href="#1.18.2">ENV_FPGA_SCAN_MODE</a></td>
+               <td width="60"></td>
+               <td>0x060005030</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.3</td>
+               <td>reg: <a href="#1.18.3">ENV_FPGA_CC_ALLOW_SCAN</a></td>
+               <td width="60"></td>
+               <td>0x060005034</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.4</td>
+               <td>reg: <a href="#1.18.4">ENV_FPGA_CC_HOST_INT</a></td>
+               <td width="60"></td>
+               <td>0x0600050A0</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.5</td>
+               <td>reg: <a href="#1.18.5">ENV_FPGA_CC_PUB_HOST_INT</a></td>
+               <td width="60"></td>
+               <td>0x0600050A4</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.6</td>
+               <td>reg: <a href="#1.18.6">ENV_FPGA_CC_RST_N</a></td>
+               <td width="60"></td>
+               <td>0x0600050A8</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.7</td>
+               <td>reg: <a href="#1.18.7">ENV_FPGA_RST_OVERRIDE</a></td>
+               <td width="60"></td>
+               <td>0x0600050AC</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.8</td>
+               <td>reg: <a href="#1.18.8">ENV_FPGA_CC_POR_N_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x0600050E0</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.9</td>
+               <td>reg: <a href="#1.18.9">ENV_FPGA_CC_COLD_RST</a></td>
+               <td width="60"></td>
+               <td>0x0600050FC</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.10</td>
+               <td>reg: <a href="#1.18.10">ENV_FPGA_DUMMY_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x060005108</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.11</td>
+               <td>reg: <a href="#1.18.11">ENV_FPGA_COUNTER_CLR</a></td>
+               <td width="60"></td>
+               <td>0x060005118</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.12</td>
+               <td>reg: <a href="#1.18.12">ENV_FPGA_COUNTER_RD</a></td>
+               <td width="60"></td>
+               <td>0x06000511C</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.13</td>
+               <td>reg: <a href="#1.18.13">ENV_FPGA_RNG_DEBUG_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x060005430</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.14</td>
+               <td>reg: <a href="#1.18.14">ENV_FPGA_CC_LCS</a></td>
+               <td width="60"></td>
+               <td>0x06000543C</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.15</td>
+               <td>reg: <a href="#1.18.15">ENV_FPGA_CC_IS_CM_DM_SECURE_RMA</a></td>
+               <td width="60"></td>
+               <td>0x060005440</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.16</td>
+               <td>reg: <a href="#1.18.16">ENV_FPGA_DCU_EN</a></td>
+               <td width="60"></td>
+               <td>0x060005444</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.17</td>
+               <td>reg: <a href="#1.18.17">ENV_FPGA_CC_LCS_IS_VALID</a></td>
+               <td width="60"></td>
+               <td>0x060005448</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.18</td>
+               <td>reg: <a href="#1.18.18">ENV_FPGA_POWER_DOWN</a></td>
+               <td width="60"></td>
+               <td>0x060005478</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.19</td>
+               <td>reg: <a href="#1.18.19">ENV_FPGA_DCU_H_EN</a></td>
+               <td width="60"></td>
+               <td>0x060005484</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.20</td>
+               <td>reg: <a href="#1.18.20">ENV_FPGA_VERSION</a></td>
+               <td width="60"></td>
+               <td>0x060005488</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.21</td>
+               <td>reg: <a href="#1.18.21">ENV_FPGA_ROSC_WRITE</a></td>
+               <td width="60"></td>
+               <td>0x06000548C</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.22</td>
+               <td>reg: <a href="#1.18.22">ENV_FPGA_ROSC_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x060005490</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.23</td>
+               <td>reg: <a href="#1.18.23">ENV_FPGA_RESET_SESSION_KEY</a></td>
+               <td width="60"></td>
+               <td>0x060005494</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.24</td>
+               <td>reg: <a href="#1.18.24">ENV_FPGA_SESSION_KEY_0</a></td>
+               <td width="60"></td>
+               <td>0x0600054A0</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.25</td>
+               <td>reg: <a href="#1.18.25">ENV_FPGA_SESSION_KEY_1</a></td>
+               <td width="60"></td>
+               <td>0x0600054A4</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.26</td>
+               <td>reg: <a href="#1.18.26">ENV_FPGA_SESSION_KEY_2</a></td>
+               <td width="60"></td>
+               <td>0x0600054A8</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.27</td>
+               <td>reg: <a href="#1.18.27">ENV_FPGA_SESSION_KEY_3</a></td>
+               <td width="60"></td>
+               <td>0x0600054AC</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.28</td>
+               <td>reg: <a href="#1.18.28">ENV_FPGA_SESSION_KEY_VALID</a></td>
+               <td width="60"></td>
+               <td>0x0600054B0</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.29</td>
+               <td>reg: <a href="#1.18.29">ENV_FPGA_SPIDEN</a></td>
+               <td width="60"></td>
+               <td>0x0600054D0</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.30</td>
+               <td>reg: <a href="#1.18.30">ENV_FPGA_AXIM_USER_PARAMS</a></td>
+               <td width="60"></td>
+               <td>0x060005600</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.31</td>
+               <td>reg: <a href="#1.18.31">ENV_FPGA_SECURITY_MODE_OVERRIDE</a></td>
+               <td width="60"></td>
+               <td>0x060005604</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.32</td>
+               <td>reg: <a href="#1.18.32">ENV_FPGA_SRAM_ENABLE</a></td>
+               <td width="60"></td>
+               <td>0x060005608</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.33</td>
+               <td>reg: <a href="#1.18.33">ENV_FPGA_APB_FIPS_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x060005650</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.34</td>
+               <td>reg: <a href="#1.18.34">ENV_FPGA_APB_FIPS_VAL</a></td>
+               <td width="60"></td>
+               <td>0x060005654</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.35</td>
+               <td>reg: <a href="#1.18.35">ENV_FPGA_APB_FIPS_MASK</a></td>
+               <td width="60"></td>
+               <td>0x060005658</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.36</td>
+               <td>reg: <a href="#1.18.36">ENV_FPGA_APB_FIPS_CNT</a></td>
+               <td width="60"></td>
+               <td>0x06000565C</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.37</td>
+               <td>reg: <a href="#1.18.37">ENV_FPGA_APB_FIPS_NEW_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x060005660</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.38</td>
+               <td>reg: <a href="#1.18.38">ENV_FPGA_APB_FIPS_NEW_VAL</a></td>
+               <td width="60"></td>
+               <td>0x060005664</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.39</td>
+               <td>reg: <a href="#1.18.39">ENV_FPGA_APB_PPROT_OVERRIDE</a></td>
+               <td width="60"></td>
+               <td>0x060005668</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.40</td>
+               <td>reg: <a href="#1.18.40">ENV_FPGA_APBP_FIPS_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x060005670</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.41</td>
+               <td>reg: <a href="#1.18.41">ENV_FPGA_APBP_FIPS_VAL</a></td>
+               <td width="60"></td>
+               <td>0x060005674</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.42</td>
+               <td>reg: <a href="#1.18.42">ENV_FPGA_APBP_FIPS_MASK</a></td>
+               <td width="60"></td>
+               <td>0x060005678</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.43</td>
+               <td>reg: <a href="#1.18.43">ENV_FPGA_APBP_FIPS_CNT</a></td>
+               <td width="60"></td>
+               <td>0x06000567C</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.44</td>
+               <td>reg: <a href="#1.18.44">ENV_FPGA_APBP_FIPS_NEW_ADDR</a></td>
+               <td width="60"></td>
+               <td>0x060005680</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.45</td>
+               <td>reg: <a href="#1.18.45">ENV_FPGA_APBP_FIPS_NEW_VAL</a></td>
+               <td width="60"></td>
+               <td>0x060005684</td>
+            </tr>
+            <tr>
+               <td width="100">1.18.46</td>
+               <td>reg: <a href="#1.18.46">ENV_FPGA_AO_CC_GPPC</a></td>
+               <td width="60"></td>
+               <td>0x060005700</td>
+            </tr>
+            <tr>
+               <td width="100">1.19</td>
+               <td>block: <a href="#1.19">ENV_PERF_RAM_BASE</a></td>
+               <td width="60"></td>
+               <td>0x060006000</td>
+            </tr>
+            <tr>
+               <td width="100">1.19.1</td>
+               <td>reg: <a href="#1.19.1">ENV_PERF_RAM_BASE</a></td>
+               <td width="60"></td>
+               <td>0x060006000</td>
+            </tr>
+         </table>
+      </td>
+   </tr>
+</table><br><a name="1"></a><table border="0" width="95%" bgcolor="#993333">
+   <td><b><font color="#FFFF00" size="+2">1 : Chip: CryptoCell</font></b></td>
+   <td align="right"><font color="#FFFF00" size="+2">0x000000000</font></td>
+</table><br><br>
+Blocks:
+<br><a href="#1.1">PKA</a><br><a href="#1.2">RNG</a><br><a href="#1.3">CHACHA</a><br><a href="#1.4">AES</a><br><a href="#1.5">HASH</a><br><a href="#1.6">MISC</a><br><a href="#1.7">CC_CTL</a><br><a href="#1.8">GHASH</a><br><a href="#1.9">HOST_RGF</a><br><a href="#1.10">AHB</a><br><a href="#1.11">DIN</a><br><a href="#1.12">DOUT</a><br><a href="#1.13">HOST_SRAM</a><br><a href="#1.14">ID_REGISTERS</a><br><a href="#1.15">AO</a><br><a href="#1.16">NVM</a><br><a href="#1.17">ENV_CC_MEMORIES</a><br><a href="#1.18">FPGA_ENV_REGS</a><br><a href="#1.19">ENV_PERF_RAM_BASE</a><br><a name="1.1"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.1 : Block: PKA</font></b></td>
+   <td align="right"><font color="#000000">0x000000000</font></td>
+</table><br><a name="1.1.1"></a><br>1.1.1 : <b>Reg : MEMORY_MAP0</b> : 0x000000000<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R0 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.1.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.1.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R0 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.1.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.2"></a><br>1.1.2 : <b>Reg : MEMORY_MAP1</b> : 0x000000004<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R1 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.2.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.2.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R1 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.2.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.3"></a><br>1.1.3 : <b>Reg : MEMORY_MAP2</b> : 0x000000008<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R2 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.3.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.3.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP2</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R2 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.3.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.4"></a><br>1.1.4 : <b>Reg : MEMORY_MAP3</b> : 0x00000000C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R3 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.4.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.4.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP3</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R3 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.4.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.5"></a><br>1.1.5 : <b>Reg : MEMORY_MAP4</b> : 0x000000010<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R4 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.5.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.5.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP4</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R4 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.5.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.6"></a><br>1.1.6 : <b>Reg : MEMORY_MAP5</b> : 0x000000014<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R5 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.6.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.6.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP5</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R5 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.6.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.7"></a><br>1.1.7 : <b>Reg : MEMORY_MAP6</b> : 0x000000018<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R6 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP6</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.7.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.7.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP6</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R6 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.7.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.8"></a><br>1.1.8 : <b>Reg : MEMORY_MAP7</b> : 0x00000001C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R7 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP7</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.8.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.8.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP7</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R7 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.8.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.9"></a><br>1.1.9 : <b>Reg : MEMORY_MAP8</b> : 0x000000020<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R8 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP8</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.9.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.9.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP8</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R8 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.9.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.10"></a><br>1.1.10 : <b>Reg : MEMORY_MAP9</b> : 0x000000024<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R9 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP9</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.10.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.10.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP9</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R9 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.10.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.11"></a><br>1.1.11 : <b>Reg : MEMORY_MAP10</b> : 0x000000028<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R10 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP10</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.11.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.11.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP10</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R10 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.11.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.12"></a><br>1.1.12 : <b>Reg : MEMORY_MAP11</b> : 0x00000002C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R11 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP11</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.12.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.12.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP11</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R11 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.12.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.13"></a><br>1.1.13 : <b>Reg : MEMORY_MAP12</b> : 0x000000030<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R12 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP12</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.13.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.13.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP12</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R12 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.13.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.14"></a><br>1.1.14 : <b>Reg : MEMORY_MAP13</b> : 0x000000034<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R13 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP13</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.14.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.14.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP13</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R13 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.14.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.15"></a><br>1.1.15 : <b>Reg : MEMORY_MAP14</b> : 0x000000038<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R14 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP14</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.15.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.15.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP14</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R14 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.15.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.16"></a><br>1.1.16 : <b>Reg : MEMORY_MAP15</b> : 0x00000003C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R15 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP15</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.16.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.16.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP15</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R15 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.16.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.17"></a><br>1.1.17 : <b>Reg : MEMORY_MAP16</b> : 0x000000040<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R16 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP16</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.17.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.17.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP16</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R16 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.17.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.18"></a><br>1.1.18 : <b>Reg : MEMORY_MAP17</b> : 0x000000044<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R17 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP17</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.18.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.18.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP17</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R17 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.18.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.19"></a><br>1.1.19 : <b>Reg : MEMORY_MAP18</b> : 0x000000048<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R18 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP18</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.19.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.19.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP18</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R18 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.19.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.20"></a><br>1.1.20 : <b>Reg : MEMORY_MAP19</b> : 0x00000004C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R19 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP19</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.20.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.20.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP19</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R19 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.20.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.21"></a><br>1.1.21 : <b>Reg : MEMORY_MAP20</b> : 0x000000050<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R20 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP20</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.21.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.21.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP20</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R20 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.21.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.22"></a><br>1.1.22 : <b>Reg : MEMORY_MAP21</b> : 0x000000054<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R21 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP21</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.22.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.22.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP21</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R21 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.22.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.23"></a><br>1.1.23 : <b>Reg : MEMORY_MAP22</b> : 0x000000058<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R22 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP22</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.23.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.23.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP22</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R22 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.23.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.24"></a><br>1.1.24 : <b>Reg : MEMORY_MAP23</b> : 0x00000005C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R23 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP23</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.24.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.24.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP23</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R23 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.24.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.25"></a><br>1.1.25 : <b>Reg : MEMORY_MAP24</b> : 0x000000060<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R24 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP24</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.25.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.25.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP24</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R24 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.25.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.26"></a><br>1.1.26 : <b>Reg : MEMORY_MAP25</b> : 0x000000064<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R25 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP25</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.26.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.26.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP25</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R25 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.26.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.27"></a><br>1.1.27 : <b>Reg : MEMORY_MAP26</b> : 0x000000068<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R26 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP26</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.27.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.27.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP26</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R26 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.27.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.28"></a><br>1.1.28 : <b>Reg : MEMORY_MAP27</b> : 0x00000006C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R27 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP27</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.28.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.28.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP27</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R27 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.28.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.29"></a><br>1.1.29 : <b>Reg : MEMORY_MAP28</b> : 0x000000070<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R28 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP28</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.29.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.29.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP28</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R28 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.29.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.30"></a><br>1.1.30 : <b>Reg : MEMORY_MAP29</b> : 0x000000074<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R29 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP29</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.30.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.30.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP29</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R29 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.30.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.31"></a><br>1.1.31 : <b>Reg : MEMORY_MAP30</b> : 0x000000078<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R30 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP30</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.31.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.31.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP30</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R30 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.31.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.32"></a><br>1.1.32 : <b>Reg : MEMORY_MAP31</b> : 0x00000007C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual register R31 to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">MEMORY_MAP31</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.32.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.32.2"></a>10:1
+      </td>
+      <td valign="top">MEMORY_MAP31</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the R31 register to.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.32.3"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.33"></a><br>1.1.33 : <b>Reg : OPCODE</b> : 0x000000080<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the PKA's OPCODE.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">OPCODE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.33.1"></a>5:0
+      </td>
+      <td valign="top">TAG</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Holds the opreation's tag or the operand C virtual address.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.33.2"></a>11:6
+      </td>
+      <td valign="top">REG_R</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Result register virtual address 0-15.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.33.3"></a>17:12
+      </td>
+      <td valign="top">REG_B</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Operand B virtual address 0-15.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.33.4"></a>23:18
+      </td>
+      <td valign="top">REG_A</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Operand A virtual address 0-15.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.33.5"></a>26:24
+      </td>
+      <td valign="top">LEN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The length of the operation. The value serves as a pointer to PKA length register, for example, if the value is 0, PKA_L0
+         holds the size of the operation.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.33.6"></a>31:27
+      </td>
+      <td valign="top">OPCODE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines the PKA operation:<br>@0x4 - Add,Inc<br>@0x5 - Sub,Dec,Neg<br>@0x6 - ModAdd,ModInc<br>@0x7 - ModSub,ModDec,ModNeg<br>@0x8 - AND,TST0,CLR0<br>@0x9 - OR,COPY,SET0<br>@0xa - XOR,FLIP0,INVERT,COMPARE<br>@0xc - SHR0<br>@0xd - SHR1<br>@0xe - SHL0<br>@0xf - SHL1<br>@0x10 - MulLow<br>@0x11 - ModMul<br>@0x12 - ModMulN<br>@0x13 - ModExp<br>@0x14 - Division<br>@0x15 - Div<br>@0x16 - ModDiv<br>@0x00 - Terminate
+      </td>
+   </tr>
+</table><a name="1.1.34"></a><br>1.1.34 : <b>Reg : N_NP_T0_T1_ADDR</b> : 0x000000084<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps N_NP_T0_T1 to a virtual address.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">N_NP_T0_T1_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.34.1"></a>4:0
+      </td>
+      <td valign="top">N_VIRTUAL_ADDR</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Virtual address of register N.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.34.2"></a>9:5
+      </td>
+      <td valign="top">NP_VIRTUAL_ADDR</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Virtual address of register NP.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.34.3"></a>14:10
+      </td>
+      <td valign="top">T0_VIRTUAL_ADDR</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Virtual address of temporary register number 0</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.34.4"></a>19:15
+      </td>
+      <td valign="top">T1_VIRTUAL_ADDR</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Virtual address of temporary register number 1</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.34.5"></a>31:20
+      </td>
+      <td valign="top">Reserved</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.35"></a><br>1.1.35 : <b>Reg : PKA_STATUS</b> : 0x000000088<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the PKA pipe status.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_STATUS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.1"></a>3:0
+      </td>
+      <td valign="top">ALU_MSB_4BITS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The most significant 4-bits of the operand updated in shift operation.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.2"></a>7:4
+      </td>
+      <td valign="top">ALU_LSB_4BITS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The least significant 4-bits of the operand updated in shift operation.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.3"></a>8:8
+      </td>
+      <td valign="top">ALU_SIGN_OUT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicates the last operation's sign (MSB).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.4"></a>9:9
+      </td>
+      <td valign="top">ALU_CARRY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Holds the carry of the last ALU operation.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.5"></a>10:10
+      </td>
+      <td valign="top">ALU_CARRY_MOD</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">holds the carry of the last Modular operation.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.6"></a>11:11
+      </td>
+      <td valign="top">ALU_SUB_IS_ZERO</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicates the last subtraction operation's sign .</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.7"></a>12:12
+      </td>
+      <td valign="top">ALU_OUT_ZERO</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Indicates if the result of ALU OUT is zero.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.8"></a>13:13
+      </td>
+      <td valign="top">ALU_MODOVRFLW</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Modular overflow flag.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.9"></a>14:14
+      </td>
+      <td valign="top">DIV_BY_ZERO</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indication if the division is done by zero.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.10"></a>15:15
+      </td>
+      <td valign="top">MODINV_OF_ZERO</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicates the Modular inverse of zero.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.11"></a>20:16
+      </td>
+      <td valign="top">OPCODE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Opcode of the last operation</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.35.12"></a>31:21
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.36"></a><br>1.1.36 : <b>Reg : PKA_SW_RESET</b> : 0x00000008C<br><b>reg sep address</b> : <b> reg host address</b> : <br>Writing to this register triggers a software reset of the PKA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_SW_RESET</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.36.1"></a>0:0
+      </td>
+      <td valign="top">PKA_SW_RESET</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The reset mechanism takes about four PKA clock cycles until the reset line is deasserted</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.36.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.37"></a><br>1.1.37 : <b>Reg : PKA_L0</b> : 0x000000090<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.37.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.37.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.38"></a><br>1.1.38 : <b>Reg : PKA_L1</b> : 0x000000094<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.38.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.38.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.39"></a><br>1.1.39 : <b>Reg : PKA_L2</b> : 0x000000098<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.39.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L2</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.39.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.40"></a><br>1.1.40 : <b>Reg : PKA_L3</b> : 0x00000009C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.40.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L3</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.40.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.41"></a><br>1.1.41 : <b>Reg : PKA_L4</b> : 0x0000000A0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.41.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L4</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.41.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.42"></a><br>1.1.42 : <b>Reg : PKA_L5</b> : 0x0000000A4<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.42.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L5</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.42.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.43"></a><br>1.1.43 : <b>Reg : PKA_L6</b> : 0x0000000A8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L6</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.43.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L6</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.43.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.44"></a><br>1.1.44 : <b>Reg : PKA_L7</b> : 0x0000000AC<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds one of the optional size of the operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_L7</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.44.1"></a>12:0
+      </td>
+      <td valign="top">PKA_L7</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of the operation in bytes.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.44.2"></a>31:13
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.45"></a><br>1.1.45 : <b>Reg : PKA_PIPE_RDY</b> : 0x0000000B0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This  register indicates whether the PKA pipe is ready to receive a new OPCODE.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_PIPE_RDY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.45.1"></a>0:0
+      </td>
+      <td valign="top">PKA_PIPE_RDY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Indication whether PKA pipe is ready for new OPCODE.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.45.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.46"></a><br>1.1.46 : <b>Reg : PKA_DONE</b> : 0x0000000B4<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register indicates whether PKA operation is completed.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_DONE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.46.1"></a>0:0
+      </td>
+      <td valign="top">PKA_DONE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Indicates if PKA operation is completed, and pipe is empty.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.46.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.47"></a><br>1.1.47 : <b>Reg : PKA_MON_SELECT</b> : 0x0000000B8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines which PKA FSM monitor is being output.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_MON_SELECT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.47.1"></a>3:0
+      </td>
+      <td valign="top">PKA_MON_SELECT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines which PKA FSM monitor is being output.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.47.2"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.1.48"></a><br>1.1.48 : <b>Reg : PKA_VERSION</b> : 0x0000000C4<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the pka version<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_VERSION</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.48.1"></a>31:0
+      </td>
+      <td valign="top">PKA_VERSION</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">This is the PKA version</td>
+   </tr>
+</table><a name="1.1.49"></a><br>1.1.49 : <b>Reg : PKA_MON_READ</b> : 0x0000000D0<br><b>reg sep address</b> : <b> reg host address</b> : <br>The PKA monitor bus register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_MON_READ</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.49.1"></a>31:0
+      </td>
+      <td valign="top">PKA_MON_READ</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This is the PKA monitor bus register output</td>
+   </tr>
+</table><a name="1.1.50"></a><br>1.1.50 : <b>Reg : PKA_SRAM_ADDR</b> : 0x0000000D4<br><b>reg sep address</b> : <b> reg host address</b> : <br>first address given to PKA SRAM for write transactions.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_SRAM_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.50.1"></a>31:0
+      </td>
+      <td valign="top">PKA_SRAM_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PKA SRAM write starting address</td>
+   </tr>
+</table><a name="1.1.51"></a><br>1.1.51 : <b>Reg : PKA_SRAM_WDATA</b> : 0x0000000D8<br><b>reg sep address</b> : <b> reg host address</b> : <br>Write data to PKA SRAM.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_SRAM_WDATA</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.51.1"></a>31:0
+      </td>
+      <td valign="top">PKA_SRAM_WDATA</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">32 bit write to PKA SRAM:  triggers the SRAM write DMA address automatically incremented</td>
+   </tr>
+</table><a name="1.1.52"></a><br>1.1.52 : <b>Reg : PKA_SRAM_RDATA</b> : 0x0000000DC<br><b>reg sep address</b> : <b> reg host address</b> : <br>Read data from PKA SRAM.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_SRAM_RDATA</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.52.1"></a>31:0
+      </td>
+      <td valign="top">PKA_SRAM_RDATA</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">32 bit read from PKA SRAM: read - triggers the SRAM read DMA address automatically incremented</td>
+   </tr>
+</table><a name="1.1.53"></a><br>1.1.53 : <b>Reg : PKA_SRAM_WR_CLR</b> : 0x0000000E0<br><b>reg sep address</b> : <b> reg host address</b> : <br>Write buffer clean.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_SRAM_WR_CLR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.53.1"></a>31:0
+      </td>
+      <td valign="top">PKA_SRAM_WR_CLR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Clear the write buffer.</td>
+   </tr>
+</table><a name="1.1.54"></a><br>1.1.54 : <b>Reg : PKA_SRAM_RADDR</b> : 0x0000000E4<br><b>reg sep address</b> : <b> reg host address</b> : <br>first address given to PKA SRAM for read transactions.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_SRAM_RADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.54.1"></a>31:0
+      </td>
+      <td valign="top">PKA_SRAM_RADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PKA SRAM read starting address</td>
+   </tr>
+</table><a name="1.1.55"></a><br>1.1.55 : <b>Reg : PKA_WORD_ACCESS</b> : 0x0000000F0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the data  written to PKA memory using the wop opcode.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_WORD_ACCESS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.55.1"></a>31:0
+      </td>
+      <td valign="top">PKA_WORD_ACCESS</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">32 bit read/write data.</td>
+   </tr>
+</table><a name="1.1.56"></a><br>1.1.56 : <b>Reg : PKA_BUFF_ADDR</b> : 0x0000000F8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register maps the virtual buffer registers  to a physical address in memory.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_BUFF_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.56.1"></a>11:0
+      </td>
+      <td valign="top">PKA_BUF_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the physical address in memory to map the buffer registers.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.1.56.2"></a>31:12
+      </td>
+      <td valign="top">RESEREVED1</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.1">(top of block)</a><a name="1.2"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.2 : Block: RNG</font></b></td>
+   <td align="right"><font color="#000000">0x000000100</font></td>
+</table><br><a name="1.2.1"></a><br>1.2.1 : <b>Reg : RNG_IMR</b> : 0x000000100<br><b>reg sep address</b> : <b> reg host address</b> : <br>Interrupt masking register.<br>Consists of {prng_imr trng_imr} bit[31-16] - PRNG_IMR bit[15-0] - TRNG_IMR <br>(Ws - PRNG bit exists only if PRNG_EXISTS flag)<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_IMR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.1.1"></a>0:0
+      </td>
+      <td valign="top">EHR_VALID_INT_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1'b1 - masks the EHR interrupt. No interrupt is generated. <br>See RNG_ISR for explanation on this interrupt.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.1.2"></a>1:1
+      </td>
+      <td valign="top">AUTOCORR_ERR_INT_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1'b1 - masks the autocorrelation interrupt. No interrupt is generated. <br>See RNG_ISR for explanation on this interrupt.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.1.3"></a>2:2
+      </td>
+      <td valign="top">CRNGT_ERR_INT_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1'b1 - masks the CRNGT error interrupt. No interrupt is generated. <br>See RNG_ISR for explanation on this interrupt.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.1.4"></a>3:3
+      </td>
+      <td valign="top">VN_ERR_INT_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1'b1 - masks the Von-Neumann error interrupt. No interrupt is generated. <br>See RNG_ISR for explanation on this interrupt.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.1.5"></a>4:4
+      </td>
+      <td valign="top">WATCHDOG_INT_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1'b1 - masks the watchdog interrupt. No interrupt is generated. <br>See RNG_ISR for explanation on this interrupt.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.1.6"></a>5:5
+      </td>
+      <td valign="top">RNG_DMA_DONE_INT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1'b1 - masks the RNG DMA completion interrupt. No interrupt is generated. <br>See RNG_ISR for explanation on this interrupt.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.1.7"></a>31:6
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.2"></a><br>1.2.2 : <b>Reg : RNG_ISR</b> : 0x000000104<br><b>reg sep address</b> : <b> reg host address</b> : <br>Status register. <br>If corresponding RNG_IMR bit is unmasked, an interrupt is generated. <br>Consists of trng_isr and prng_isr bit[15-0] - TRNG bit[31-16] - PRNG<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_ISR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.1"></a>0:0
+      </td>
+      <td valign="top">EHR_VALID</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates that 192 bits have been collected in the TRNG and are ready to be read.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.2"></a>1:1
+      </td>
+      <td valign="top">AUTOCORR_ERR</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates Autocorrelation test failed four times in a row. When it set ,TRNG ceases to function until next reset.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.3"></a>2:2
+      </td>
+      <td valign="top">CRNGT_ERR</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates CRNGT in the TRNG test failed. Failure occurs when two consecutive blocks of 16 collected bits are equal.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.4"></a>3:3
+      </td>
+      <td valign="top">VN_ERR</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates Von Neumann error. Error in von Neumann occurs if 32 consecutive collected bits are identical, ZERO, or ONE.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.5"></a>4:4
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.6"></a>5:5
+      </td>
+      <td valign="top">RNG_DMA_DONE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates RNG DMA to SRAM is completed.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.7"></a>15:6
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.8"></a>16:16
+      </td>
+      <td valign="top">RESEEDING_DONE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates completion of reseeding algorithm with no errors.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.9"></a>17:17
+      </td>
+      <td valign="top">INSTANTIATION_DONE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates completion of instantiation algorithm with no errors.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.10"></a>18:18
+      </td>
+      <td valign="top">FINAL_UPDATE_DONE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates completion of final update algorithm.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.11"></a>19:19
+      </td>
+      <td valign="top">OUTPUT_READY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates that the result of PRNG is valid and ready to be read. The result can be read from the RNG_READOUT register.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.12"></a>20:20
+      </td>
+      <td valign="top">RESEED_CNTR_FULL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates that the reseed counter has reached 2^48, requiring to run the reseed algorithm before generating new random
+         numbers.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.13"></a>21:21
+      </td>
+      <td valign="top">RESEED_CNTR_TOP_40</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates that the top 40 bits of the reseed counter are set (that is the reseed counter is larger than 2^48-2^8). This
+         is a recommendation for running the reseed algorithm before the counter reaches its max value.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.14"></a>22:22
+      </td>
+      <td valign="top">PRNG_CRNGT_ERR</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates CRNGT in the PRNG test failed. Failure occurs when two consecutive results of AES are equal</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.15"></a>23:23
+      </td>
+      <td valign="top">REQ_SIZE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates that the request size counter (which represents how many generations of random bits in the PRNG have been produced)
+         has reached 2^12, thus requiring a working state update before generating new random numbers.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.16"></a>24:24
+      </td>
+      <td valign="top">KAT_ERR</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates that one of the KAT (Known Answer Tests) tests has failed. When set, the entire engine ceases to function.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.17"></a>26:25
+      </td>
+      <td valign="top">WHICH_KAT_ERR</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When the KAT_ERR bit is set, these bits represent which Known Answer Test had failed:<br>@2'b00 - first test of instantiation<br>@2'b01 - second test of instantiation<br>@2'b10 - first test of reseeding<br>@2'b11 - second test of reseeding
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.2.18"></a>31:27
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.3"></a><br>1.2.3 : <b>Reg : RNG_ICR</b> : 0x000000108<br><b>reg sep address</b> : <b> reg host address</b> : <br>Interrupt/status bit clear Register. Consists of trng_icr and prng_icr bit[15-0] - TRNG bit[31-16] - PRNG<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_ICR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.1"></a>0:0
+      </td>
+      <td valign="top">EHR_VALID</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.2"></a>1:1
+      </td>
+      <td valign="top">AUTOCORR_ERR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Cannot be cleared by SW! Only RNG reset clears this bit.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.3"></a>2:2
+      </td>
+      <td valign="top">CRNGT_ERR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.4"></a>3:3
+      </td>
+      <td valign="top">VN_ERR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.5"></a>4:4
+      </td>
+      <td valign="top">RNG_WATCHDOG</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.6"></a>5:5
+      </td>
+      <td valign="top">RNG_DMA_DONE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.7"></a>15:6
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.8"></a>16:16
+      </td>
+      <td valign="top">RESEEDING_DONE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.9"></a>17:17
+      </td>
+      <td valign="top">INSTANTIATION_DONE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.10"></a>18:18
+      </td>
+      <td valign="top">FINAL_UPDATE_DONE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.11"></a>19:19
+      </td>
+      <td valign="top">OUTPUT_READY</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.12"></a>20:20
+      </td>
+      <td valign="top">RESEED_CNTR_FULL</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.13"></a>21:21
+      </td>
+      <td valign="top">RESEED_CNTR_TOP_40</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.14"></a>22:22
+      </td>
+      <td valign="top">PRNG_CRNGT_ERR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.15"></a>23:23
+      </td>
+      <td valign="top">REQ_SIZE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 - clears corresponding bit in RNG_ISR</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.16"></a>24:24
+      </td>
+      <td valign="top">KAT_ERR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Cannot be cleared by SW! Only RNG reset clears this bit.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.17"></a>26:25
+      </td>
+      <td valign="top">WHICH_KAT_ERR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Cannot be cleared by SW! Only RNG reset clears this bit.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.3.18"></a>31:27
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.4"></a><br>1.2.4 : <b>Reg : TRNG_CONFIG</b> : 0x00000010C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register handles TRNG configuration<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">TRNG_CONFIG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.4.1"></a>1:0
+      </td>
+      <td valign="top">RND_SRC_SEL</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines the length of the oscillator ring (= the number of inverters) out of four possible selections.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.4.2"></a>2:2
+      </td>
+      <td valign="top">SOP_SEL</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Secure Output Port selection:<br>@1'b1 - sop_data port reflects TRNG output (EHR_DATA). <br>@1'b0 - sop_data port reflects PRNG output (RNG_READOUT). <br>NOTE: Secure output is used for direct connection of the RNG block outputs to an engine input key. <br>If CryptoCell does not include a HW PRNG - this field should be set to 1.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.4.3"></a>31:3
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.5"></a><br>1.2.5 : <b>Reg : TRNG_VALID</b> : 0x000000110<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register indicates that the TRNG data is valid.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">TRNG_VALID</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.5.1"></a>0:0
+      </td>
+      <td valign="top">EHR_VALID</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 indicates that collection of bits in the TRNG is completed, and data can be read from the EHR_DATA register.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.5.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.6"></a><br>1.2.6 : <b>Reg : EHR_DATA_0</b> : 0x000000114<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register contains the data collected in the TRNG[31_0].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">EHR_DATA_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.6.1"></a>31:0
+      </td>
+      <td valign="top">EHR_DATA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the data collected in the TRNG[31_0] .<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).
+      </td>
+   </tr>
+</table><a name="1.2.7"></a><br>1.2.7 : <b>Reg : EHR_DATA_1</b> : 0x000000118<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register contains the data collected in the TRNG[63_32].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">EHR_DATA_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.7.1"></a>31:0
+      </td>
+      <td valign="top">EHR_DATA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the data collected in the TRNG[63_32].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).
+      </td>
+   </tr>
+</table><a name="1.2.8"></a><br>1.2.8 : <b>Reg : EHR_DATA_2</b> : 0x00000011C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register contains the data collected in the TRNG[95_64].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">EHR_DATA_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.8.1"></a>31:0
+      </td>
+      <td valign="top">EHR_DATA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the data collected in the TRNG[95_64].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).
+      </td>
+   </tr>
+</table><a name="1.2.9"></a><br>1.2.9 : <b>Reg : EHR_DATA_3</b> : 0x000000120<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register contains the data collected in the TRNG[127_96].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">EHR_DATA_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.9.1"></a>31:0
+      </td>
+      <td valign="top">EHR_DATA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the data collected in the TRNG[127_96].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).
+      </td>
+   </tr>
+</table><a name="1.2.10"></a><br>1.2.10 : <b>Reg : EHR_DATA_4</b> : 0x000000124<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register contains the data collected in the TRNG[159_128].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">EHR_DATA_4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.10.1"></a>31:0
+      </td>
+      <td valign="top">EHR_DATA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the data collected in the TRNG[159_128].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).
+      </td>
+   </tr>
+</table><a name="1.2.11"></a><br>1.2.11 : <b>Reg : EHR_DATA_5</b> : 0x000000128<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register contains the data collected in the TRNG[191_160].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">EHR_DATA_5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.11.1"></a>31:0
+      </td>
+      <td valign="top">EHR_DATA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Contains the data collected in the TRNG[191_160].<br>NOTE: can only be set while in debug mode (rng_debug_enable input is set).
+      </td>
+   </tr>
+</table><a name="1.2.12"></a><br>1.2.12 : <b>Reg : RND_SOURCE_ENABLE</b> : 0x00000012C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the enable signal for the random source.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RND_SOURCE_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.12.1"></a>0:0
+      </td>
+      <td valign="top">RND_SRC_EN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Enable signal for the random source.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.12.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.13"></a><br>1.2.13 : <b>Reg : SAMPLE_CNT1</b> : 0x000000130<br><b>reg sep address</b> : <b> reg host address</b> : <br>Counts clocks between sampling of random bit.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SAMPLE_CNT1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.13.1"></a>31:0
+      </td>
+      <td valign="top">SAMPLE_CNTR1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Sets the number of rng_clk cycles between two consecutive ring oscillator samples.<br>NOTE: If the Von-Neumann is bypassed, the minimum value for sample counter must not be less than decimal seventeen.
+      </td>
+   </tr>
+</table><a name="1.2.14"></a><br>1.2.14 : <b>Reg : AUTOCORR_STATISTIC</b> : 0x000000134<br><b>reg sep address</b> : <b> reg host address</b> : <br>Statistics about autocorrelation test activations.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AUTOCORR_STATISTIC</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.14.1"></a>13:0
+      </td>
+      <td valign="top">AUTOCORR_TRYS</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Count each time an autocorrelation test starts. Any write to the register resets the counter. Stops collecting statistics
+         if one of the counters has reached the limit.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.14.2"></a>21:14
+      </td>
+      <td valign="top">AUTOCORR_FAILS</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Count each time an autocorrelation test fails. Any write to the register resets the counter. Stops collecting statistics if
+         one of the counters has reached the limit.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.14.3"></a>31:22
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.15"></a><br>1.2.15 : <b>Reg : TRNG_DEBUG_CONTROL</b> : 0x000000138<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is used to debug the TRNG<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">TRNG_DEBUG_CONTROL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.15.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.15.2"></a>1:1
+      </td>
+      <td valign="top">VNC_BYPASS</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this bit is set, the Von-Neumann balancer is bypassed (including the 32 consecutive bits test).<br>NOTE: Can only be set while in debug mode. If TRNG_TESTS_BYPASS_EN HW flag is defined, this bit can be set while not in debug
+         mode.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.15.3"></a>2:2
+      </td>
+      <td valign="top">TRNG_CRNGT_BYPASS</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this bit is set, the CRNGT test in the TRNG is bypassed. <br>NOTE: Can only be set while in debug mode. If TRNG_TESTS_BYPASS_EN HW flag is defined, this bit can be set while not in debug
+         mode.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.15.4"></a>3:3
+      </td>
+      <td valign="top">AUTO_CORRELATE_BYPASS</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this bit is set, the autocorrelation test in the TRNG module is bypassed.<br>NOTE: Can only be set while in debug mode. If TRNG_TESTS_BYPASS_EN HW flag is defined, this bit can be set while not in debug
+         mode.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.15.5"></a>31:4
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.16"></a><br>1.2.16 : <b>Reg : RNG_SW_RESET</b> : 0x000000140<br><b>reg sep address</b> : <b> reg host address</b> : <br>Generate SW reset solely to RNG block.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_SW_RESET</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.16.1"></a>0:0
+      </td>
+      <td valign="top">RNG_SW_RESET</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Any value written (1'b0 or 1'b1) causes a reset cycle to the TRNG block. <br>The reset mechanism takes about four RNG clock cycles until the reset line is de-asserted.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.16.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.17"></a><br>1.2.17 : <b>Reg : RNG_DEBUG_EN_INPUT</b> : 0x0000001B4<br><b>reg sep address</b> : <b> reg host address</b> : <br>Defines the RNG in debug mode<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_DEBUG_EN_INPUT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.17.1"></a>0:0
+      </td>
+      <td valign="top">RNG_DEBUG_EN</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reflects the rng_debug_enable input port</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.17.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.18"></a><br>1.2.18 : <b>Reg : RNG_BUSY</b> : 0x0000001B8<br><b>reg sep address</b> : <b> reg host address</b> : <br>RNG busy indication<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.18.1"></a>0:0
+      </td>
+      <td valign="top">RNG_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reflects rng_busy output port which Consists of trng_busy and prng_busy.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.18.2"></a>1:1
+      </td>
+      <td valign="top">TRNG_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reflects trng_busy.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.18.3"></a>2:2
+      </td>
+      <td valign="top">PRNG_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reflects prng_busy.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.18.4"></a>31:3
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.19"></a><br>1.2.19 : <b>Reg : RST_BITS_COUNTER</b> : 0x0000001BC<br><b>reg sep address</b> : <b> reg host address</b> : <br>Resets the counter of collected bits in the TRNG<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RST_BITS_COUNTER</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.19.1"></a>0:0
+      </td>
+      <td valign="top">RST_BITS_COUNTER</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing any value to this address resets the bits counter and trng valid registers.<br>RND_SORCE_ENABLE register must be unset in order for reset to take place.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.19.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.20"></a><br>1.2.20 : <b>Reg : RNG_VERSION</b> : 0x0000001C0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the RNG version<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_VERSION</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.1"></a>0:0
+      </td>
+      <td valign="top">EHR_WIDTH_192</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">@1'b0 - 128 bit EHR<br>@1'b1 - 192 bit EHR
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.2"></a>1:1
+      </td>
+      <td valign="top">CRNGT_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">@1'b0 - does not exist<br>@1'b1 - exists
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.3"></a>2:2
+      </td>
+      <td valign="top">AUTOCORR_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">@1'b0 - does not exist<br>@1'b1 - exists
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.4"></a>3:3
+      </td>
+      <td valign="top">TRNG_TESTS_BYPASS_EN</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">@1'b0 - trng tests bypass not enabled<br>@1'b1 - trng tests bypass enabled
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.5"></a>4:4
+      </td>
+      <td valign="top">PRNG_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - does not exist<br>@1'b1 - exists
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.6"></a>5:5
+      </td>
+      <td valign="top">KAT_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - does not exist<br>@1'b1 - exists
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.7"></a>6:6
+      </td>
+      <td valign="top">RESEEDING_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - does not exist<br>@1'b1 - exists
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.8"></a>7:7
+      </td>
+      <td valign="top">RNG_USE_5_SBOXES</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - 20 SBOX AES<br>@1'b1 - 5 SBOX AES
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.20.9"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.21"></a><br>1.2.21 : <b>Reg : RNG_CLK_ENABLE</b> : 0x0000001C4<br><b>reg sep address</b> : <b> reg host address</b> : <br>Writing to this register enables/disables the RNG clock.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_CLK_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.21.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 enables RNG clock.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.21.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.22"></a><br>1.2.22 : <b>Reg : RNG_DMA_ENABLE</b> : 0x0000001C8<br><b>reg sep address</b> : <b> reg host address</b> : <br>Writing to this register enables/disables the RNG DMA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_DMA_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.22.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 enables RNG DMA to SRAM. The Value is cleared when DMA completes its operation.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.22.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.23"></a><br>1.2.23 : <b>Reg : RNG_DMA_SRC_MASK</b> : 0x0000001CC<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines which ring-oscillator length should be used when using the RNG DMA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_DMA_SRC_MASK</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.23.1"></a>0:0
+      </td>
+      <td valign="top">EN_SRC_SEL0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 enables SRC_SEL 0.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.23.2"></a>1:1
+      </td>
+      <td valign="top">EN_SRC_SEL1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 enables SRC_SEL 1.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.23.3"></a>2:2
+      </td>
+      <td valign="top">EN_SRC_SEL2</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 enables SRC_SEL 2.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.23.4"></a>3:3
+      </td>
+      <td valign="top">EN_SRC_SEL3</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing value 1'b1 enables SRC_SEL 3.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.23.5"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.24"></a><br>1.2.24 : <b>Reg : RNG_DMA_SRAM_ADDR</b> : 0x0000001D0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines the start address of the DMA for the TRNG data.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_DMA_SRAM_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.24.1"></a>10:0
+      </td>
+      <td valign="top">RNG_SRAM_DMA_ADDR</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines the start address of the DMA for the TRNG data.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.24.2"></a>31:11
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.25"></a><br>1.2.25 : <b>Reg : RNG_DMA_SAMPLES_NUM</b> : 0x0000001D4<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines the number of 192-bits samples that the DMA collects per RNG configuration.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_DMA_SAMPLES_NUM</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.25.1"></a>7:0
+      </td>
+      <td valign="top">RNG_SAMPLES_NUM</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines the number of 192-bits samples that the DMA collects per RNG configuration.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.25.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.2.26"></a><br>1.2.26 : <b>Reg : RNG_WATCHDOG_VAL</b> : 0x0000001D8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines the maximum number of clock cycles per TRNG collection of 192 samples. If the number of cycles for a
+collection exceeds this threshold, TRNG signals an interrupt.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_WATCHDOG_VAL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.26.1"></a>31:0
+      </td>
+      <td valign="top">RNG_WATCHDOG_VAL</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines the maximum number of clock cycles per TRNG collection of 192 samples. If the number of cycles for a collection exceeds
+         this threshold, TRNG signals an interrupt.
+      </td>
+   </tr>
+</table><a name="1.2.27"></a><br>1.2.27 : <b>Reg : RNG_DMA_STATUS</b> : 0x0000001DC<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the RNG DMA status.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">RNG_DMA_STATUS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.27.1"></a>0:0
+      </td>
+      <td valign="top">RNG_DMA_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicates whether DMA is busy.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.27.2"></a>2:1
+      </td>
+      <td valign="top">DMA_SRC_SEL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The active ring oscillator length using by DMA</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.27.3"></a>10:3
+      </td>
+      <td valign="top">NUM_OF_SAMPLES</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Number of samples already collected in the current ring oscillator chain length.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.2.27.4"></a>31:11
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.2">(top of block)</a><a name="1.3"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.3 : Block: CHACHA</font></b></td>
+   <td align="right"><font color="#000000">0x000000380</font></td>
+</table><br><a name="1.3.1"></a><br>1.3.1 : <b>Reg : CHACHA_CONTROL_REG</b> : 0x000000380<br><b>reg sep address</b> : <b> reg host address</b> : <br>CHACHA general configuration.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_CONTROL_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.1"></a>0:0
+      </td>
+      <td valign="top">CHACHA_OR_SALSA</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Core: <br>@1'b0 - ChaCha mode. <br>@1'b1 - Salsa mode.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.2"></a>1:1
+      </td>
+      <td valign="top">INIT_FROM_HOST</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Start init for new Message:<br>@1'b0 - disable. <br>@1'b1 - enable.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.3"></a>2:2
+      </td>
+      <td valign="top">CALC_KEY_FOR_POLY1305</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Only if ChaCha core:<br>@1'b0 - disable. <br>@1'b1 - enable.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.4"></a>3:3
+      </td>
+      <td valign="top">KEY_LEN</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">For All Core: <br>@1'b0 - 256 bit. <br>@1'b1 - 128 bit.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.5"></a>5:4
+      </td>
+      <td valign="top">NUM_OF_ROUNDS</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The core of ChaCha is a hash function which based on rotation operations. The hash function consist in application of 20 rounds
+         (default value). In additional, ChaCha have two variants (they work exactly as the original algorithm): ChaCha20/8 and ChaCha20/12
+         (using 8 and 12 rounds). <br>Default value 00<br>@00 - 20 rounds <br>@01 - 12 rounds<br>@10 - 8 rounds <br>@11 - N/A
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.6"></a>8:6
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.7"></a>9:9
+      </td>
+      <td valign="top">RESET_BLOCK_CNT</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">For new message</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.8"></a>10:10
+      </td>
+      <td valign="top">USE_IV_96BIT</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">If use 96bit IV</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.1.9"></a>31:11
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved1</td>
+   </tr>
+</table><a name="1.3.2"></a><br>1.3.2 : <b>Reg : CHACHA_VERSION</b> : 0x000000384<br><b>reg sep address</b> : <b> reg host address</b> : <br>CHACHA Version<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_VERSION</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.2.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_VERSION</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top"></td>
+   </tr>
+</table><a name="1.3.3"></a><br>1.3.3 : <b>Reg : CHACHA_KEY0</b> : 0x000000388<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 255:224 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.3.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 255:224 of CHACHA Key</td>
+   </tr>
+</table><a name="1.3.4"></a><br>1.3.4 : <b>Reg : CHACHA_KEY1</b> : 0x00000038C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 223:192 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.4.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY1</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 223:192 of  CHACHA Key</td>
+   </tr>
+</table><a name="1.3.5"></a><br>1.3.5 : <b>Reg : CHACHA_KEY2</b> : 0x000000390<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits191:160 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.5.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY2</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits191:160 of  CHACHA Key</td>
+   </tr>
+</table><a name="1.3.6"></a><br>1.3.6 : <b>Reg : CHACHA_KEY3</b> : 0x000000394<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits159:128 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.6.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY3</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 159:128 of  CHACHA Key</td>
+   </tr>
+</table><a name="1.3.7"></a><br>1.3.7 : <b>Reg : CHACHA_KEY4</b> : 0x000000398<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 127:96 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.7.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY4</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 127:96 of  CHACHA Key</td>
+   </tr>
+</table><a name="1.3.8"></a><br>1.3.8 : <b>Reg : CHACHA_KEY5</b> : 0x00000039C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 95:64 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.8.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY5</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 95:64 of  CHACHA Key</td>
+   </tr>
+</table><a name="1.3.9"></a><br>1.3.9 : <b>Reg : CHACHA_KEY6</b> : 0x0000003A0<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 63:32 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY6</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.9.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY6</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 63:32 of  CHACHA Key</td>
+   </tr>
+</table><a name="1.3.10"></a><br>1.3.10 : <b>Reg : CHACHA_KEY7</b> : 0x0000003A4<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of CHACHA Key<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_KEY7</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.10.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_KEY7</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of  CHACHA Key</td>
+   </tr>
+</table><a name="1.3.11"></a><br>1.3.11 : <b>Reg : CHACHA_IV_0</b> : 0x0000003A8<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of CHACHA_IV0 register<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_IV_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.11.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_IV_0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of CHACHA_IV0 register</td>
+   </tr>
+</table><a name="1.3.12"></a><br>1.3.12 : <b>Reg : CHACHA_IV_1</b> : 0x0000003AC<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of CHACHA_IV1 register<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_IV_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.12.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_IV_1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of CHACHA_IV1 register</td>
+   </tr>
+</table><a name="1.3.13"></a><br>1.3.13 : <b>Reg : CHACHA_BUSY</b> : 0x0000003B0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is set when the CHACHA/SALSA core is active<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.13.1"></a>0:0
+      </td>
+      <td valign="top">CHACHA_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">CHACHA_BUSY Register. this register is set when the CHACHA/SALSA core is active</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.13.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.3.14"></a><br>1.3.14 : <b>Reg : CHACHA_HW_FLAGS</b> : 0x0000003B4<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the pre-synthesis HW flag configuration of the CHACHA/SALSA engine<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_HW_FLAGS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.14.1"></a>0:0
+      </td>
+      <td valign="top">CHACHA_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">If this flag is set, the Salsa/ChaCha engine include ChaCha implementation:<br>@1'b0 - disable. <br>@1'b1 - enable.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.14.2"></a>1:1
+      </td>
+      <td valign="top">SALSA_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">If this flag is set, the Salsa/ChaCha engine include Salsa implementation:<br>@1'b0 - disable. <br>@1'b1 - enable.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.14.3"></a>2:2
+      </td>
+      <td valign="top">FAST_CHACHA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">If this flag is set, the next matrix calculated when the current one is written to data output path (same flag for Salsa core):<br>@1'b0 - disable. <br>@1'b1 - enable.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.14.4"></a>31:3
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.3.15"></a><br>1.3.15 : <b>Reg : CHACHA_BLOCK_CNT_LSB</b> : 0x0000003B8<br><b>reg sep address</b> : <b> reg host address</b> : <br>The two first words (n) in the last row of the cipher matrix are the block counter. At the end of each block (512b), the block_cnt
+for the next block is written by HW to the block_cnt_lsb and block_cnt_msb  registers. Need  reset block counter , if  start
+new message.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_BLOCK_CNT_LSB</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.15.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_BLOCK_CNT_LSB</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of CHACHA_BLOCK_CNT_LSB register. <br>This register holds the chacha block counter bits 31:0
+      </td>
+   </tr>
+</table><a name="1.3.16"></a><br>1.3.16 : <b>Reg : CHACHA_BLOCK_CNT_MSB</b> : 0x0000003BC<br><b>reg sep address</b> : <b> reg host address</b> : <br>The two first words (n) in the last row of the cipher matrix are the block counter. At the end of each block (512b), the block_cnt
+for the next block is written by HW to the block_cnt_lsb and block_cnt_msb  registers. Need  reset block counter , if  start
+new message.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_BLOCK_CNT_MSB</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.16.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_BLOCK_CNT_MSB</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of CHACHA_BLOCK_CNT_MSB register. <br>This register holds the chacha block counter bits 63:32
+      </td>
+   </tr>
+</table><a name="1.3.17"></a><br>1.3.17 : <b>Reg : CHACHA_SW_RESET</b> : 0x0000003C0<br><b>reg sep address</b> : <b> reg host address</b> : <br>Resets  CHACHA/SALSA engine.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_SW_RESET</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.17.1"></a>0:0
+      </td>
+      <td valign="top">CHACH_SW_RESET</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing to this address resets the only FSM of CHACHA engine. The reset takes 4 CORE_CLK cycles.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.17.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.3.18"></a><br>1.3.18 : <b>Reg : CHACHA_FOR_POLY_KEY0</b> : 0x0000003C4<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 255:224 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.18.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 255:224 of CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.19"></a><br>1.3.19 : <b>Reg : CHACHA_FOR_POLY_KEY1</b> : 0x0000003C8<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 223:192 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.19.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 223:192 of  CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.20"></a><br>1.3.20 : <b>Reg : CHACHA_FOR_POLY_KEY2</b> : 0x0000003CC<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits191:160 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.20.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY2</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits191:160 of  CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.21"></a><br>1.3.21 : <b>Reg : CHACHA_FOR_POLY_KEY3</b> : 0x0000003D0<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits159:128 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.21.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY3</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 159:128 of  CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.22"></a><br>1.3.22 : <b>Reg : CHACHA_FOR_POLY_KEY4</b> : 0x0000003D4<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 127:96 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.22.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY4</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 127:96 of  CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.23"></a><br>1.3.23 : <b>Reg : CHACHA_FOR_POLY_KEY5</b> : 0x0000003D8<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 95:64 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.23.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY5</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 95:64 of  CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.24"></a><br>1.3.24 : <b>Reg : CHACHA_FOR_POLY_KEY6</b> : 0x0000003DC<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 63:32 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY6</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.24.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY6</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 63:32 of  CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.25"></a><br>1.3.25 : <b>Reg : CHACHA_FOR_POLY_KEY7</b> : 0x0000003E0<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of CHACHA_FOR_POLY_KEY<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_FOR_POLY_KEY7</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.25.1"></a>31:0
+      </td>
+      <td valign="top">CHACHA_FOR_POLY_KEY7</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of  CHACHA_FOR_POLY_KEY</td>
+   </tr>
+</table><a name="1.3.26"></a><br>1.3.26 : <b>Reg : CHACHA_BYTE_WORD_ORDER_CNTL_REG</b> : 0x0000003E4<br><b>reg sep address</b> : <b> reg host address</b> : <br>CHACHA/SALSA DATA ORDER configuration.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_BYTE_WORD_ORDER_CNTL_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.26.1"></a>0:0
+      </td>
+      <td valign="top">CHACHA_DIN_WORD_ORDER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Change the words order of the input data.<br>@1'b0 - disable. <br>@1'b1 - enable. (reverse each word in 128 bit input ( w0-&gt;w3, w1-&gt;w2, w2-&gt;w1,w3-w0))
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.26.2"></a>1:1
+      </td>
+      <td valign="top">CHACHA_DIN_BYTE_ORDER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Change the byte order of the input data.<br>@1'b0 - disable. <br>@1'b1 - enable. (reverse each byte in each word input (b0-&gt;b3, b1-&gt;b2, b2-&gt;b1,b3-&gt;b0))
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.26.3"></a>2:2
+      </td>
+      <td valign="top">CHACHA_CORE_MATRIX_LBE_ORDER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Change the quarter of a matrix order in core<br>@1'b0 - disable. <br>@1'b1 - enable. (reverse each quarter of a matrix (m[0-127]-&gt;m[384-511], m[128-255]-&gt;m[256-383], m[256-383]-&gt;m[128-255], m[384-511]-&gt;m[0-127]))
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.26.4"></a>3:3
+      </td>
+      <td valign="top">CHACHA_DOUT_WORD_ORDER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Change the words order of the output data.<br>@1'b0 - disable. <br>@1'b1 - enable. (reverse each word in 128 bit output ( w0-&gt;w3, w1-&gt;w2, w2-&gt;w1,w3-w0))
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.26.5"></a>4:4
+      </td>
+      <td valign="top">CHACHA_DOUT_BYTE_ORDER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Change the byte order of the output data.<br>@1'b0 - disable. <br>@1'b1 - enable. (reverse each byte in each word output (b0-&gt;b3, b1-&gt;b2, b2-&gt;b1,b3-&gt;b0))
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.26.6"></a>31:5
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.3.27"></a><br>1.3.27 : <b>Reg : CHACHA_DEBUG_REG</b> : 0x0000003E8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is used to debug the CHACHA engine<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_DEBUG_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.27.1"></a>1:0
+      </td>
+      <td valign="top">CHACHA_DEBUG_FSM_STATE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">CHACHA_DEBUG_FSM_STATE<br>@0x0 - IDLE_STATE<br>@0x1 - INIT_STATE<br>@0x2 - ROUNDS_STATE<br>@0x3 - FINAL_STATE
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.3.27.2"></a>31:2
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.3">(top of block)</a><a name="1.4"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.4 : Block: AES</font></b></td>
+   <td align="right"><font color="#000000">0x000000400</font></td>
+</table><br><a name="1.4.1"></a><br>1.4.1 : <b>Reg : AES_KEY_0_0</b> : 0x000000400<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.1.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of AES Key0.</td>
+   </tr>
+</table><a name="1.4.2"></a><br>1.4.2 : <b>Reg : AES_KEY_0_1</b> : 0x000000404<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 63:32 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.2.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_1</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 63:32 of AES Key0.</td>
+   </tr>
+</table><a name="1.4.3"></a><br>1.4.3 : <b>Reg : AES_KEY_0_2</b> : 0x000000408<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 95:64 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.3.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_2</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 95:64 of AES Key0.</td>
+   </tr>
+</table><a name="1.4.4"></a><br>1.4.4 : <b>Reg : AES_KEY_0_3</b> : 0x00000040C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 127:96 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.4.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_3</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 127:96 of AES Key0.</td>
+   </tr>
+</table><a name="1.4.5"></a><br>1.4.5 : <b>Reg : AES_KEY_0_4</b> : 0x000000410<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 159:128 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling
+operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.5.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_4</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 159:128 of AES Key0 .</td>
+   </tr>
+</table><a name="1.4.6"></a><br>1.4.6 : <b>Reg : AES_KEY_0_5</b> : 0x000000414<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 191:160 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling
+operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.6.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_5</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 191:160 of AES Key0.</td>
+   </tr>
+</table><a name="1.4.7"></a><br>1.4.7 : <b>Reg : AES_KEY_0_6</b> : 0x000000418<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 223:192 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling
+operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_6</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.7.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_6</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 223:192 of AES Key0.</td>
+   </tr>
+</table><a name="1.4.8"></a><br>1.4.8 : <b>Reg : AES_KEY_0_7</b> : 0x00000041C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 255:224 of AES Key0 (used as the AES key in non-tunneling operations, and as the first tunnel stage key in tunneling
+operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_0_7</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.8.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_0_7</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 255:224 of AES Key0.</td>
+   </tr>
+</table><a name="1.4.9"></a><br>1.4.9 : <b>Reg : AES_KEY_1_0</b> : 0x000000420<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.9.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.10"></a><br>1.4.10 : <b>Reg : AES_KEY_1_1</b> : 0x000000424<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 63:32 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.10.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_1</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 63:32 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.11"></a><br>1.4.11 : <b>Reg : AES_KEY_1_2</b> : 0x000000428<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 95:64 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.11.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_2</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 95:64 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.12"></a><br>1.4.12 : <b>Reg : AES_KEY_1_3</b> : 0x00000042C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 127:96 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.12.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_3</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 127:96 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.13"></a><br>1.4.13 : <b>Reg : AES_KEY_1_4</b> : 0x000000430<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 159:128 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.13.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_4</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 159:128 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.14"></a><br>1.4.14 : <b>Reg : AES_KEY_1_5</b> : 0x000000434<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 191:160 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.14.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_5</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 191:160 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.15"></a><br>1.4.15 : <b>Reg : AES_KEY_1_6</b> : 0x000000438<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 223:192 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_6</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.15.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_6</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 223:192 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.16"></a><br>1.4.16 : <b>Reg : AES_KEY_1_7</b> : 0x00000043C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 255:224 of AES Key1 (used as the second AES tunnel stage key in tunneling operations).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_KEY_1_7</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.16.1"></a>31:0
+      </td>
+      <td valign="top">AES_KEY_1_7</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 255:224 of AES Key1.</td>
+   </tr>
+</table><a name="1.4.17"></a><br>1.4.17 : <b>Reg : AES_IV_0_0</b> : 0x000000440<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of AES_IV0 register. <br>AES IV0 is used as the AES IV (Initialization Value) register in non-tunneling operations, <br>and as the first tunnel stage IV register in tunneling operations. <br>The IV register should be loaded according to the AES mode:<br>in AES CBC/CBC-MAC - the AES IV register should be loaded with the IV (initialization vector).<br>in XTS-AES - the AES IV register should be loaded with the 'T' value (unless the HW T calculation mode is active, in which
+the 'T' value is calculated by the HW).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_0_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.17.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_0_0</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of AES_IV0 register. <br>For the description of AES_IV0, see the AES_IV_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.18"></a><br>1.4.18 : <b>Reg : AES_IV_0_1</b> : 0x000000444<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 63:32 of AES_IV0 128b register. <br>For the description of AES_IV0, see the AES_IV_0_0 register description<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_0_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.18.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_0_1</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 63:32 of AES_IV0 register. <br>For the description of AES_IV0, see the AES_IV_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.19"></a><br>1.4.19 : <b>Reg : AES_IV_0_2</b> : 0x000000448<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 95:64 of AES_IV0 128b register. <br>For the description of AES_IV0, see the AES_IV_0_0 register description<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_0_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.19.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_0_2</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 95:64 of AES_IV0 register. <br>For the description of AES_IV0, see the AES_IV_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.20"></a><br>1.4.20 : <b>Reg : AES_IV_0_3</b> : 0x00000044C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 127:96 of AES_IV0 128b register. <br>For the description of AES_IV0, see the AES_IV_0_0 register description<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_0_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.20.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_0_3</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 127:96 of AES_IV0 register. <br>For the description of AES_IV0, see the AES_IV_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.21"></a><br>1.4.21 : <b>Reg : AES_IV_1_0</b> : 0x000000450<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of AES_IV1 128b register. <br>AES IV1 is used as the AES IV (Initialization Value) register as the second tunnel stage IV register in tunneling operations.
+<br>The IV register should be loaded according to the AES mode:<br>in AES CBC/CBC-MAC - the AES IV register should be loaded with the IV (initialization vector).<br>in XTS-AES - the AES IV register should be loaded with the 'T' value (unless the HW T calculation mode is active, in which
+the 'T' value is calculated by the HW.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_1_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.21.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_1_0</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of AES_IV1 register. <br>For the description of AES_IV1, see the AES_IV_1_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.22"></a><br>1.4.22 : <b>Reg : AES_IV_1_1</b> : 0x000000454<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 63:32 of AES_IV1 128b register. <br>For the description of AES_IV1, see the AES_IV_1_0 register description<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_1_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.22.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_1_1</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 63:32 of AES_IV1 register. <br>For the description of AES_IV1, see the AES_IV_1_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.23"></a><br>1.4.23 : <b>Reg : AES_IV_1_2</b> : 0x000000458<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 95:64 of AES_IV1 128b register. <br>For the description of AES_IV1, see the AES_IV_1_0 register description<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_1_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.23.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_1_2</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 95:64 of AES_IV1 register. <br>For the description of AES_IV1, see the AES_IV_1_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.24"></a><br>1.4.24 : <b>Reg : AES_IV_1_3</b> : 0x00000045C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 127:96 of AES_IV1 128b register. <br>For the description of AES_IV1, see the AES_IV_1_0 register description<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_IV_1_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.24.1"></a>31:0
+      </td>
+      <td valign="top">AES_IV_1_3</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 127:96 of AES_IV1 register. <br>For the description of AES_IV1, see the AES_IV_1_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.25"></a><br>1.4.25 : <b>Reg : AES_CTR_0_0</b> : 0x000000460<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 31:0 of AES_CTR0 128b register. <br>AES CTR0 is used as the AES CTR (counter) register in non-tunneling operations, and as the first tunnel stage CTR register
+in tunneling operations. <br>The CTR register should be loaded according to the AES mode:<br>in AES CTR/GCTR - the AES CTR register should be loaded with the counter value.<br>in XTS-AES - the AES CTR register should be loaded with the 'i' value (in order to calculate the T value from it, if HW T
+calculation is supported).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CTR_0_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.25.1"></a>31:0
+      </td>
+      <td valign="top">AES_CTR_0_0</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 31:0 of AES_CTR0 register. <br>For the description of AES_CTR0, see the AES_CTR_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.26"></a><br>1.4.26 : <b>Reg : AES_CTR_0_1</b> : 0x000000464<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 63:32 of AES_CTR0 128b register. <br>For the description of AES_CTR0, see the AES_CTR_0_0 register description.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CTR_0_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.26.1"></a>31:0
+      </td>
+      <td valign="top">AES_CTR_0_1</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 63:32 of AES_CTR0 register. <br>For the description of AES_CTR0, see the AES_CTR_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.27"></a><br>1.4.27 : <b>Reg : AES_CTR_0_2</b> : 0x000000468<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 95:64 of AES_CTR0 128b register. <br>For the description of AES_CTR0, see the AES_CTR_0_0 register description.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CTR_0_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.27.1"></a>31:0
+      </td>
+      <td valign="top">AES_CTR_0_2</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 95:64 of AES_CTR0 register. <br>For the description of AES_CTR0, see the AES_CTR_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.28"></a><br>1.4.28 : <b>Reg : AES_CTR_0_3</b> : 0x00000046C<br><b>reg sep address</b> : <b> reg host address</b> : <br>bits 127:96 of AES_CTR0 128b register. <br>For the description of AES_CTR0, see the AES_CTR_0_0 register description.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CTR_0_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.28.1"></a>31:0
+      </td>
+      <td valign="top">AES_CTR_0_3</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 127:96 of AES_CTR0 register. <br>For the description of AES_CTR0, see the AES_CTR_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.4.29"></a><br>1.4.29 : <b>Reg : AES_BUSY</b> : 0x000000470<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is set when the AES core is active<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.29.1"></a>0:0
+      </td>
+      <td valign="top">AES_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AES_BUSY Register. this register is set when the AES core is active</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.29.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">31'b0</td>
+   </tr>
+</table><a name="1.4.30"></a><br>1.4.30 : <b>Reg : AES_SK</b> : 0x000000478<br><b>reg sep address</b> : <b> reg host address</b> : <br>writing to this address causes sampling of the HW key to the AES_KEY0 register<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_SK</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.30.1"></a>0:0
+      </td>
+      <td valign="top">AES_SK</td>
+      <td valign="top" align="center">wm</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">writing to this address causes sampling of the HW key to the AES_KEY0 register</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.30.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wm</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.4.31"></a><br>1.4.31 : <b>Reg : AES_CMAC_INIT</b> : 0x00000047C<br><b>reg sep address</b> : <b> reg host address</b> : <br>Writing to this address triggers the AES engine generating of K1 and K2 for AES CMAC operations.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CMAC_INIT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.31.1"></a>0:0
+      </td>
+      <td valign="top">AES_CMAC_INIT</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing to this address starts the generating of K1 and K2 for AES CMAC operations</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.31.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.4.32"></a><br>1.4.32 : <b>Reg : AES_SK1</b> : 0x0000004B4<br><b>reg sep address</b> : <b> reg host address</b> : <br>writing to this address causes sampling of the HW key to the AES_KEY1 register<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_SK1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.32.1"></a>0:0
+      </td>
+      <td valign="top">AES_SK1</td>
+      <td valign="top" align="center">wm</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">writing to this address causes sampling of the HW key to the AES_KEY1 register</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.32.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wm</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.4.33"></a><br>1.4.33 : <b>Reg : AES_REMAINING_BYTES</b> : 0x0000004BC<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register should be set with the amount of remaining bytes until the end of the current AES operation. The AES engine
+counts down from this value to determine the last / one before last blocks in AES CMAC, XTS AES and AES CCM.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_REMAINING_BYTES</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.33.1"></a>31:0
+      </td>
+      <td valign="top">AES_REMAINING_BYTES</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This register should be set with the amount of remaining bytes until the end of the current AES operation. The AES engine
+         counts down from this value to determine the last / one before last blocks in AES CMAC, XTS AES and AES CCM.
+      </td>
+   </tr>
+</table><a name="1.4.34"></a><br>1.4.34 : <b>Reg : AES_CONTROL</b> : 0x0000004C0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the configuration of the AES engine<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CONTROL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.1"></a>0:0
+      </td>
+      <td valign="top">DEC_KEY0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines whether the AES performs Decrypt/Encrypt operations, in non-tunneling operations:<br>@0 - Encrypt<br>@1 - Decrypt
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.2"></a>1:1
+      </td>
+      <td valign="top">MODE0_IS_CBC_CTS</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">If MODE_KEY0 is set to 3'b001 (CBC), and this field is set - the mode is CBC-CTS. In addition, If MODE_KEY0 is set to 3'b010
+         (CTR), and this field is set - the mode is GCTR.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.3"></a>4:2
+      </td>
+      <td valign="top">MODE_KEY0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines the AES mode in non tunneling operations, and the AES mode of the first stage in tunneling operations:<br>@000 - ECB<br>@001 - CBC<br>@010 - CTR <br>@011 - CBC MAC<br>@100 - XEX/XTS<br>@101 - XCBC-MAC <br>@110 -OFB<br>@111 - CMAC
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.4"></a>7:5
+      </td>
+      <td valign="top">MODE_KEY1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines the AES mode of the second stage operation in tunneling operations:<br>@000 - ECB<br>@001 - CBC<br>@010 - CTR <br>@011 - CBC MAC<br>@100 - XEX/XTS<br>@101 - XCBC-MAC <br>@110 -OFB<br>@111 - CMAC
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.5"></a>8:8
+      </td>
+      <td valign="top">CBC_IS_ESSIV</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">If MODE_KEY0 is set to 3'b001 (CBC), and this field is set - the mode is CBC-with ESSIV.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.6"></a>9:9
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.7"></a>10:10
+      </td>
+      <td valign="top">AES_TUNNEL_IS_ON</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines whether the AES performs dual-tunnel operations or standard non-tunneling operations:<br>@0 - standard non-tunneling operations<br>@1 - tunneling operations.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.8"></a>11:11
+      </td>
+      <td valign="top">CBC_IS_BITLOCKER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">If MODE_KEY0 is set to 3'b001 (CBC), and this field is set - the mode isBITLOCKER.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.9"></a>13:12
+      </td>
+      <td valign="top">NK_KEY0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines the AES Key length in non tunneling operations, and the AES key length of the first stage in tunneling
+         operations:<br>@00 - 128 bits key<br>@01 - 192 bits key <br>@10 - 256 bits key <br>@11 - N/A
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.10"></a>15:14
+      </td>
+      <td valign="top">NK_KEY1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines the AES key length of the second stage operation in tunneling operations:<br>@00 - 128 bits key <br>@01 - 192 bits key <br>@10 - 256 bits key <br>@11 - N/A
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.11"></a>21:16
+      </td>
+      <td valign="top">RESERVED2</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.12"></a>22:22
+      </td>
+      <td valign="top">AES_TUNNEL1_DECRYPT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines whether the second tunnel stage performs encrypt or decrypt operation :<br>@0 - the second tunnel stage performs encrypt operations. <br>@1 - the second tunnel stage performs decrypt operations.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.13"></a>23:23
+      </td>
+      <td valign="top">AES_TUN_B1_USES_PADDED_DATA_IN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines, for tunneling operations, the data that is fed to the second tunneling stage:<br>@0 - the output of the first block (standard tunneling operation).<br>@1- data_in after padding rather than the output of the first block.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.14"></a>24:24
+      </td>
+      <td valign="top">AES_TUNNEL0_ENCRYPT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines whether the first tunnel stage performs encrypt or decrypt operation :<br>@0 - the first tunnel stage performs decrypt operations.<br>@1 - the first tunnel stage performs encrypt operations.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.15"></a>25:25
+      </td>
+      <td valign="top">AES_OUTPUT_MID_TUNNEL_DATA</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This fields determines whether the AES output is the result of the first or second tunneling stage:<br>@0 - The AES engine outputs the result of the second tunnel stage (standard tunneling).<br>@1 - The AES engine outputs the result of the first tunnel stage.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.16"></a>26:26
+      </td>
+      <td valign="top">AES_TUNNEL_B1_PAD_EN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines whether the input data to the second tunnel stage is padded with zeroes (according to the remaining_bytes
+         value) or not:<br>@0 - The data input to the second tunnel block is not padded with zeros.<br>@1 - The data input to the second tunnel block is padded with zeros.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.17"></a>27:27
+      </td>
+      <td valign="top">RESERVED3</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.18"></a>28:28
+      </td>
+      <td valign="top">AES_OUT_MID_TUN_TO_HASH</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines for AES-TO-HASH-AND-DOUT tunneling operations, whether the AES outputs to the HASH the result of the
+         first or the second tunneling stage:<br>@0 - The AES engine writes to the hash the result of the second tunnel stage.<br>@1 - The AES engine writes to the hash the result of the first tunnel stage.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.19"></a>29:29
+      </td>
+      <td valign="top">AES_XOR_CRYPTOKEY</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field determines the value that is written to AES_KEY0, when AES_SK is kicked:<br>@0 - The value that is written to AES_KEY0 is the value of the HW cryptokey, as is.<br>@1 - The value that is written to AES_KEY0 is the value of the HW cryptokey xored with the current value of AES_KEY0.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.20"></a>30:30
+      </td>
+      <td valign="top">RESERVED4</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.34.21"></a>31:31
+      </td>
+      <td valign="top">DIRECT_ACCESS</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Using direct access and not the din-dout interface</td>
+   </tr>
+</table><a name="1.4.35"></a><br>1.4.35 : <b>Reg : AES_HW_FLAGS</b> : 0x0000004C8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the pre-synthesis HW flag configuration of the AES engine<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_HW_FLAGS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.1"></a>0:0
+      </td>
+      <td valign="top">SUPPORT_256_192_KEY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">the SUPPORT_256_192_KEY flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.2"></a>1:1
+      </td>
+      <td valign="top">AES_LARGE_RKEK</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">the AES_LARGE_RKEK flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.3"></a>2:2
+      </td>
+      <td valign="top">DPA_CNTRMSR_EXIST</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">the DPA_CNTRMSR_EXIST flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.4"></a>3:3
+      </td>
+      <td valign="top">CTR_EXIST</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">the CTR_EXIST flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.5"></a>4:4
+      </td>
+      <td valign="top">ONLY_ENCRYPT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">the ONLY_ENCRYPT flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.6"></a>5:5
+      </td>
+      <td valign="top">USE_SBOX_TABLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">the USE_SBOX_TABLE flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.7"></a>7:6
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.8"></a>8:8
+      </td>
+      <td valign="top">USE_5_SBOXES</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">the USE_5_SBOXES flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.9"></a>9:9
+      </td>
+      <td valign="top">AES_SUPPORT_PREV_IV</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">the AES_SUPPORT_PREV_IV flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.10"></a>10:10
+      </td>
+      <td valign="top">aes_tunnel_exists</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">the aes_tunnel_exists flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.11"></a>11:11
+      </td>
+      <td valign="top">SECOND_REGS_SET_EXIST</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">the SECOND_REGS_SET_EXIST flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.12"></a>12:12
+      </td>
+      <td valign="top">DFA_CNTRMSR_EXIST</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">the DFA_CNTRMSR_EXIST flag</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.35.13"></a>31:13
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.4.36"></a><br>1.4.36 : <b>Reg : AES_CTR_NO_INCREMENT</b> : 0x0000004D8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register enables the AES CTR no increment mode (in which the counter mode is not incremented between 2 blocks)<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CTR_NO_INCREMENT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.36.1"></a>0:0
+      </td>
+      <td valign="top">AES_CTR_NO_INCREMENT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field enables the AES CTR "no increment" mode (in which the counter mode is not incremented between 2 blocks)</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.36.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.4.37"></a><br>1.4.37 : <b>Reg : AES_DFA_IS_ON</b> : 0x0000004F0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register disable/enable the AES dfa.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_DFA_IS_ON</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.37.1"></a>0:0
+      </td>
+      <td valign="top">AES_DFA_IS_ON</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">writing to this register turns the DFA counter-measures on. this register exists only if DFA countermeasures are supported</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.37.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.4.38"></a><br>1.4.38 : <b>Reg : AES_DFA_ERR_STATUS</b> : 0x0000004F8<br><b>reg sep address</b> : <b> reg host address</b> : <br>dfa error status register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_DFA_ERR_STATUS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.38.1"></a>0:0
+      </td>
+      <td valign="top">AES_DFA_ERR_STATUS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">after a DFA violation this register is set and the AES block is disabled) until the next reset. this register only exists
+         if DFA countermeasures is are supported
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.38.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.4.39"></a><br>1.4.39 : <b>Reg : AES_CMAC_SIZE0_KICK</b> : 0x000000524<br><b>reg sep address</b> : <b> reg host address</b> : <br>writing to this address triggers the AES engine to perform a CMAC operation with size 0. The CMAC result can be read from
+the AES_IV0 register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CMAC_SIZE0_KICK</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.39.1"></a>0:0
+      </td>
+      <td valign="top">AES_CMAC_SIZE0_KICK</td>
+      <td valign="top" align="center">wm</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">writing to this address triggers the AES engine to perform a CMAC operation with size 0. The CMAC result can be read from
+         the AES_IV0 register.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.4.39.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wm</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.4">(top of block)</a><a name="1.5"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.5 : Block: HASH</font></b></td>
+   <td align="right"><font color="#000000">0x000000640</font></td>
+</table><br><a name="1.5.1"></a><br>1.5.1 : <b>Reg : HASH_H0</b> : 0x000000640<br><b>reg sep address</b> : <b> reg host address</b> : <br>H0 data. can only be written in the following HASH_CONTROL modes: MD5 SHA1 SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.1.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H0</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.2"></a><br>1.5.2 : <b>Reg : HASH_H1</b> : 0x000000644<br><b>reg sep address</b> : <b> reg host address</b> : <br>H1 data. can only be written in the following HASH_CONTROL modes: MD5 SHA1 SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.2.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H1</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.3"></a><br>1.5.3 : <b>Reg : HASH_H2</b> : 0x000000648<br><b>reg sep address</b> : <b> reg host address</b> : <br>H2 data. can only be written in the following HASH_CONTROL modes: MD5 SHA1 SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.3.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H2</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.4"></a><br>1.5.4 : <b>Reg : HASH_H3</b> : 0x00000064C<br><b>reg sep address</b> : <b> reg host address</b> : <br>H3 data. can only be written in the following HASH_CONTROL modes: MD5 SHA1 SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.4.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H3</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.5"></a><br>1.5.5 : <b>Reg : HASH_H4</b> : 0x000000650<br><b>reg sep address</b> : <b> reg host address</b> : <br>H4 data. can only be written in the following HASH_CONTROL modes: SHA1 SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.5.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H4</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.6"></a><br>1.5.6 : <b>Reg : HASH_H5</b> : 0x000000654<br><b>reg sep address</b> : <b> reg host address</b> : <br>H5 data. can only be written in the following HASH_CONTROL modes: SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H5</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.6.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H5</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.7"></a><br>1.5.7 : <b>Reg : HASH_H6</b> : 0x000000658<br><b>reg sep address</b> : <b> reg host address</b> : <br>H6 data. can only be written in the following HASH_CONTROL modes: SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H6</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.7.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H6</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.8"></a><br>1.5.8 : <b>Reg : HASH_H7</b> : 0x00000065C<br><b>reg sep address</b> : <b> reg host address</b> : <br>H7 data. can only be written in the following HASH_CONTROL modes: SHA224 SHA256 SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H7</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.8.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H7</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.9"></a><br>1.5.9 : <b>Reg : HASH_H8</b> : 0x000000660<br><b>reg sep address</b> : <b> reg host address</b> : <br>H8 data. can only be written in the following HASH_CONTROL modes: SHA384 SHA512<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_H8</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.9.1"></a>31:0
+      </td>
+      <td valign="top">HASH_H8</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1) Write initial Hash value. <br>2) Read final Hash value - result.
+      </td>
+   </tr>
+</table><a name="1.5.10"></a><br>1.5.10 : <b>Reg : AUTO_HW_PADDING</b> : 0x000000684<br><b>reg sep address</b> : <b> reg host address</b> : <br>HW padding automatically activated by engine. For the special case of ZERO bytes data vector this register should not be used!
+instead use HASH_PAD_CFG<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AUTO_HW_PADDING</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.10.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - Enable Automatic HW padding (No need for SW intervention by writing PAD_CFG). <br>Note: Not supported for 0 bytes !<br>Note: Disable this register when HASH op is done
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.10.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.11"></a><br>1.5.11 : <b>Reg : HASH_XOR_DIN</b> : 0x000000688<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is always xored with the input to the hash engine,it should be '0' if xored is not reqiured .<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_XOR_DIN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.11.1"></a>31:0
+      </td>
+      <td valign="top">HASH_XOR_DATA</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This register holds the value to be xor-ed with hash input data.</td>
+   </tr>
+</table><a name="1.5.12"></a><br>1.5.12 : <b>Reg : LOAD_INIT_STATE</b> : 0x000000694<br><b>reg sep address</b> : <b> reg host address</b> : <br>Indication to HASH that the following data is to be loaded into initial value registers in HASH(H0:H15) or IV to AES MAC<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">LOAD_INIT_STATE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.12.1"></a>0:0
+      </td>
+      <td valign="top">LOAD</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Load data to initial state registers. digest/iv for hash/aes_mac. When done loading data this bit should be reset</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.12.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.13"></a><br>1.5.13 : <b>Reg : HASH_SEL_AES_MAC</b> : 0x0000006A4<br><b>reg sep address</b> : <b> reg host address</b> : <br>select the AES MAC module rather than the hash module<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_SEL_AES_MAC</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.13.1"></a>0:0
+      </td>
+      <td valign="top">HASH_SEL_AES_MAC</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - select the hash module<br>@1'b1 - select the AES mac module
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.13.2"></a>1:1
+      </td>
+      <td valign="top">GHASH_SEL</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - select the hash module<br>@1'b1 -  select the ghash module
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.13.3"></a>31:2
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.14"></a><br>1.5.14 : <b>Reg : HASH_VERSION</b> : 0x0000007B0<br><b>reg sep address</b> : <b> reg host address</b> : <br>HASH VERSION Register<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_VERSION</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.14.1"></a>7:0
+      </td>
+      <td valign="top">FIXES</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top"></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.14.2"></a>11:8
+      </td>
+      <td valign="top">MINOR_VERSION_NUMBER</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">minor version number</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.14.3"></a>15:12
+      </td>
+      <td valign="top">MAJOR_VERSION_NUMBER</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">major version number</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.14.4"></a>31:16
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.15"></a><br>1.5.15 : <b>Reg : HASH_CONTROL</b> : 0x0000007C0<br><b>reg sep address</b> : <b> reg host address</b> : <br>HASH_CONTROL Register. selects which HASH mode to run<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_CONTROL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.15.1"></a>1:0
+      </td>
+      <td valign="top">MODE_0_1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bits 1:0 of the HASH mode field. The hash mode field possible values are:<br>@4'b0000 - MD5 if present<br>@4'b0001 - SHA-1<br>@4'b0010 - SHA-256<br>@4'b1010 - SHA-224
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.15.2"></a>2:2
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.15.3"></a>3:3
+      </td>
+      <td valign="top">MODE_3</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">bit 3 of the HASH mode field. The hash mode field possible values are:4'b0000 - MD5 if present 4'b0001 - SHA-1 4'b0010 - SHA-256
+         4'b1010 - SHA-224
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.15.4"></a>31:4
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.16"></a><br>1.5.16 : <b>Reg : HASH_PAD_EN</b> : 0x0000007C4<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register enables the hash hw padding .<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_PAD_EN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.16.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1 - Enable generation of padding by HW Pad block.<br>0 - Disable generation of padding by HW Pad block.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.16.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.17"></a><br>1.5.17 : <b>Reg : HASH_PAD_CFG</b> : 0x0000007C8<br><b>reg sep address</b> : <b> reg host address</b> : <br>HASH_PAD_CFG Register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_PAD_CFG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.17.1"></a>1:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.17.2"></a>2:2
+      </td>
+      <td valign="top">DO_PAD</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Enable Padding generation. must be reset upon completion of padding.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.17.3"></a>31:3
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.18"></a><br>1.5.18 : <b>Reg : HASH_CUR_LEN_0</b> : 0x0000007CC<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register hold the length of current hash operation bit 31:0.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_CUR_LEN_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.18.1"></a>31:0
+      </td>
+      <td valign="top">Length</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Represent the current length of valid bits where digest need to be computed In Bytes.</td>
+   </tr>
+</table><a name="1.5.19"></a><br>1.5.19 : <b>Reg : HASH_CUR_LEN_1</b> : 0x0000007D0<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register hold the length of current hash operation bit 63:32.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_CUR_LEN_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.19.1"></a>31:0
+      </td>
+      <td valign="top">Length</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Represent the current length of valid bits where digest need to be computed In Bytes.</td>
+   </tr>
+</table><a name="1.5.20"></a><br>1.5.20 : <b>Reg : HASH_PARAM</b> : 0x0000007DC<br><b>reg sep address</b> : <b> reg host address</b> : <br>HASH_PARAM Register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_PARAM</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.1"></a>3:0
+      </td>
+      <td valign="top">CW</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Indicates the number of concurrent words the hash is using to compute signature. 1 - One concurrent w(t). 2 - Two concurrent
+         w(t).
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.2"></a>7:4
+      </td>
+      <td valign="top">CH</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicate if Hi adders are present for each Hi value or 1 adder is shared for all Hi. 0 - One Hi value is updated at a time
+         1 - All Hi values are updated at the same time.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.3"></a>11:8
+      </td>
+      <td valign="top">DW</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Determine the granularity of word size. 0 - 32 bit word data. 1 - 64 bit word data.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.4"></a>12:12
+      </td>
+      <td valign="top">SHA_512_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicate if SHA-512 is present in the design. By default SHA-1 and SHA-256 are present. 0 - SHA-1 and SHA-256 are present
+         only 1 - SHA-1 and all SHA-2 are present (SHA-256 SHA-512).
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.5"></a>13:13
+      </td>
+      <td valign="top">PAD_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Indicate if pad block is present in the design. 0 - pad function is not supported by hardware. 1 - pad function is supported
+         by hardware.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.6"></a>14:14
+      </td>
+      <td valign="top">MD5_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicate if MD5 is present in HW</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.7"></a>15:15
+      </td>
+      <td valign="top">HMAC_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicate if HMAC logic is present in the design</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.8"></a>16:16
+      </td>
+      <td valign="top">SHA_256_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Indicate if SHA-256 is present in the design</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.9"></a>17:17
+      </td>
+      <td valign="top">HASH_COMPARE_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicate if COMPARE digest logic is present in the design</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.10"></a>18:18
+      </td>
+      <td valign="top">DUMP_HASH_TO_DOUT_EXISTS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicate if HASH to dout is present in the design</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.20.11"></a>31:19
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.21"></a><br>1.5.21 : <b>Reg : HASH_AES_SW_RESET</b> : 0x0000007E4<br><b>reg sep address</b> : <b> reg host address</b> : <br>HASH_AES_SW_RESET Register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_AES_SW_RESET</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.21.1"></a>0:0
+      </td>
+      <td valign="top">HASH_AES_SW_RESET</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Hash receive reset internally.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.21.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.5.22"></a><br>1.5.22 : <b>Reg : HASH_ENDIANESS</b> : 0x0000007E8<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register hold the HASH_ENDIANESS configuration.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_ENDIANESS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.22.1"></a>0:0
+      </td>
+      <td valign="top">ENDIAN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The default value is little-endian. The data and generation of padding can be swapped to be big-endian.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.5.22.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.5">(top of block)</a><a name="1.6"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.6 : Block: MISC</font></b></td>
+   <td align="right"><font color="#000000">0x000000800</font></td>
+</table><br><a name="1.6.1"></a><br>1.6.1 : <b>Reg : AES_CLK_ENABLE</b> : 0x000000810<br><b>reg sep address</b> : <b> reg host address</b> : <br>The AES clock enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AES_CLK_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.1.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the AES clock is enabled.<br>@1'b0 - the AES clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.1.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.6.2"></a><br>1.6.2 : <b>Reg : HASH_CLK_ENABLE</b> : 0x000000818<br><b>reg sep address</b> : <b> reg host address</b> : <br>The HASH clock enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_CLK_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.2.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the HASH clock is enabled.<br>@1'b0 - the HASH clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.2.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.6.3"></a><br>1.6.3 : <b>Reg : PKA_CLK_ENABLE</b> : 0x00000081C<br><b>reg sep address</b> : <b> reg host address</b> : <br>The PKA clock enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PKA_CLK_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.3.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the PKA clock is enabled.<br>@1'b0 - the PKA clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.3.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.6.4"></a><br>1.6.4 : <b>Reg : DMA_CLK_ENABLE</b> : 0x000000820<br><b>reg sep address</b> : <b> reg host address</b> : <br>DMA_CLK enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DMA_CLK_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.4.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the DMA clock is enabled.<br>@1'b0 - the DMA clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.4.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.6.5"></a><br>1.6.5 : <b>Reg : CLK_STATUS</b> : 0x000000824<br><b>reg sep address</b> : <b> reg host address</b> : <br>The CryptoCell clocks' status register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CLK_STATUS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.1"></a>0:0
+      </td>
+      <td valign="top">AES_CLK_STATUS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the AES clock is enabled.<br>@1'b0 - the AES clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.2"></a>1:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the DES clock is enabled.<br>@1'b0 - the DES clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.3"></a>2:2
+      </td>
+      <td valign="top">HASH_CLK_STATUS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the HASH clock is enabled.<br>@1'b0 - the HASH clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.4"></a>3:3
+      </td>
+      <td valign="top">PKA_CLK_STATUS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the PKA clock is enabled.<br>@1'b0 - the PKA clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.5"></a>6:4
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.6"></a>7:7
+      </td>
+      <td valign="top">CHACHA_CLK_STATUS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the CHACHA clock is enabled.<br>@1'b0 - the CHACHA clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.7"></a>8:8
+      </td>
+      <td valign="top">DMA_CLK_STATUS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">@1'b1 - the DMA clock is enabled.<br>@1'b0 - the DMA clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.5.8"></a>31:9
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.6.6"></a><br>1.6.6 : <b>Reg : CHACHA_CLK_ENABLE</b> : 0x000000858<br><b>reg sep address</b> : <b> reg host address</b> : <br>CHACHA /SALSA clock enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CHACHA_CLK_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.6.1"></a>0:0
+      </td>
+      <td valign="top">EN</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b1 - the CHACHA / SALSA clock is enabled.<br>@1'b0 - the CHACHA / SALSA  clock is disabled.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.6.6.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.6">(top of block)</a><a name="1.7"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.7 : Block: CC_CTL</font></b></td>
+   <td align="right"><font color="#000000">0x000000900</font></td>
+</table><br><a name="1.7.1"></a><br>1.7.1 : <b>Reg : CRYPTO_CTL</b> : 0x000000900<br><b>reg sep address</b> : <b> reg host address</b> : <br>Defines the cryptographic flow.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CRYPTO_CTL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.1.1"></a>4:0
+      </td>
+      <td valign="top">MODE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Determines the active cryptographic engine:<br>@5'b0000 - BYPASS<br>@5'b0001 - AES<br>@5'b0010 - AES_TO_HASH<br>@5'b0011 - AES_AND_HASH<br>@5'b0100 - DES<br>@5'b0101 - DES_TO_HASH<br>@5'b0110 - DES_AND_HASH<br>@5'b0111 - HASH<br>@5'b1001 - AES_MAC_AND_BYPASS<br>@5'b1010 - AES_TO_HASH_AND_DOUT<br>@5'b1011 - Reserved<br>@5'b1000 - Reserved
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.1.2"></a>31:5
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.7.2"></a><br>1.7.2 : <b>Reg : CRYPTO_BUSY</b> : 0x000000910<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is set when the cryptographic core is busy.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CRYPTO_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.2.1"></a>0:0
+      </td>
+      <td valign="top">CRYPTO_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - Ready<br>@1'b1 - Busy<br>Asserted when AES_BUSY or DES_BUSY or HASH_BUSY are asserted or when the DIN FIFO is not empty.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.2.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.7.3"></a><br>1.7.3 : <b>Reg : HASH_BUSY</b> : 0x00000091C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is set when the Hash engine is busy.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HASH_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.3.1"></a>0:0
+      </td>
+      <td valign="top">HASH_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - Ready<br>@1'b1 - Busy<br>Asserted when hash engine is busy.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.3.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.7.4"></a><br>1.7.4 : <b>Reg : CONTEXT_ID</b> : 0x000000930<br><b>reg sep address</b> : <b> reg host address</b> : <br>A general RD/WR register. For Firmware use.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">CONTEXT_ID</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.4.1"></a>7:0
+      </td>
+      <td valign="top">CONTEXT_ID</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Context ID</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.7.4.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.7">(top of block)</a><a name="1.8"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.8 : Block: GHASH</font></b></td>
+   <td align="right"><font color="#000000">0x000000960</font></td>
+</table><br><a name="1.8.1"></a><br>1.8.1 : <b>Reg : GHASH_SUBKEY_0_0</b> : 0x000000960<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 31:0 of GHASH Key0 (used as the GHASH module key).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_SUBKEY_0_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.1.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_SUBKEY_0_0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 31:0 of GHASH Key0.</td>
+   </tr>
+</table><a name="1.8.2"></a><br>1.8.2 : <b>Reg : GHASH_SUBKEY_0_1</b> : 0x000000964<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 63:32 of GHASH Key0 (used as the GHASH module key).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_SUBKEY_0_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.2.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_SUBKEY_0_1</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 63:32 of GHASH Key0.</td>
+   </tr>
+</table><a name="1.8.3"></a><br>1.8.3 : <b>Reg : GHASH_SUBKEY_0_2</b> : 0x000000968<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 95:64 of GHASH Key0 (used as the GHASH module key).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_SUBKEY_0_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.3.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_SUBKEY_0_2</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 95:64 of GHASH Key0.</td>
+   </tr>
+</table><a name="1.8.4"></a><br>1.8.4 : <b>Reg : GHASH_SUBKEY_0_3</b> : 0x00000096C<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 127:96 of GHASH Key0 (used as the GHASH module key).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_SUBKEY_0_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.4.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_SUBKEY_0_3</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 127:96 of GHASH Key0.</td>
+   </tr>
+</table><a name="1.8.5"></a><br>1.8.5 : <b>Reg : GHASH_IV_0_0</b> : 0x000000970<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 31:0 of GHASH_IV0 register. <br>GHASH IV0 is used as the GHASH IV (Initialization Value) register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_IV_0_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.5.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_IV_0_0</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 31:0 of GHASH_IV0 register of the GHASH module. <br>For the description of GHASH_IV0, see the GHASH_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.8.6"></a><br>1.8.6 : <b>Reg : GHASH_IV_0_1</b> : 0x000000974<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 63:32 of GHASH_IV0 register. <br>GHASH IV0 is used as the GHASH IV (Initialization Value) register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_IV_0_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.6.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_IV_0_1</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 63:32 of GHASH_IV0 register of the GHASH module. <br>For the description of GHASH_IV0, see the GHASH_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.8.7"></a><br>1.8.7 : <b>Reg : GHASH_IV_0_2</b> : 0x000000978<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 95:64 of GHASH_IV0 register. <br>GHASH IV0 is used as the GHASH IV (Initialization Value) register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_IV_0_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.7.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_IV_0_2</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 95:64 of GHASH_IV0 register of the GHASH module. <br>For the description of GHASH_IV0, see the GHASH_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.8.8"></a><br>1.8.8 : <b>Reg : GHASH_IV_0_3</b> : 0x00000097C<br><b>reg sep address</b> : <b> reg host address</b> : <br>Bits 127:96 of GHASH_IV0 register. <br>GHASH IV0 is used as the GHASH IV (Initialization Value) register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_IV_0_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.8.1"></a>31:0
+      </td>
+      <td valign="top">GHASH_IV_0_3</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Bits 127:96 of GHASH_IV0 register of the GHASH module. <br>For the description of GHASH_IV0, see the GHASH_0_0 register description
+      </td>
+   </tr>
+</table><a name="1.8.9"></a><br>1.8.9 : <b>Reg : GHASH_BUSY</b> : 0x000000980<br><b>reg sep address</b> : <b> reg host address</b> : <br>The GHASH module GHASH_BUSY Register. This register is set when the GHASH core is active.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.9.1"></a>0:0
+      </td>
+      <td valign="top">GHASH_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">GHASH_BUSY Register. this register is set when the GHASH core is active</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.9.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.8.10"></a><br>1.8.10 : <b>Reg : GHASH_INIT</b> : 0x000000984<br><b>reg sep address</b> : <b> reg host address</b> : <br>Writing to this address sets the GHASH engine to be ready to a new GHASH operation.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">GHASH_INIT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.10.1"></a>0:0
+      </td>
+      <td valign="top">GHASH_INIT</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing to this address sets the GHASH engine to be ready to a new GHASH operation.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.8.10.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.8">(top of block)</a><a name="1.9"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.9 : Block: HOST_RGF</font></b></td>
+   <td align="right"><font color="#000000">0x000000A00</font></td>
+</table><br><a name="1.9.1"></a><br>1.9.1 : <b>Reg : HOST_RGF_IRR</b> : 0x000000A00<br><b>reg sep address</b> : <b> reg host address</b> : <br>The Interrupt Request register. Each bit of this register holds the interrupt status of a single interrupt source.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_RGF_IRR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.1"></a>3:0
+      </td>
+      <td valign="top">unused0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.2"></a>4:4
+      </td>
+      <td valign="top">SRAM_TO_DIN_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The SRAM to DIN DMA done interrupt status. This interrupt is asserted when all data was delivered to DIN buffer from SRAM.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.3"></a>5:5
+      </td>
+      <td valign="top">DOUT_TO_SRAM_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The DOUT to SRAM DMA done interrupt status. This interrupt is asserted when all data was delivered to SRAM buffer from DOUT.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.4"></a>6:6
+      </td>
+      <td valign="top">MEM_TO_DIN_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The memory to DIN DMA done interrupt status. This interrupt is asserted when all data was delivered to DIN buffer from memory.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.5"></a>7:7
+      </td>
+      <td valign="top">DOUT_TO_MEM_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The DOUT to memory DMA done interrupt status. This interrupt is asserted when all data was delivered to memory buffer from
+         DOUT.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.6"></a>8:8
+      </td>
+      <td valign="top">AHB_ERR_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The AXI error interrupt status.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.7"></a>9:9
+      </td>
+      <td valign="top">PKA_EXP_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The PKA end of operation interrupt status.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.8"></a>10:10
+      </td>
+      <td valign="top">RNG_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The RNG interrupt status.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.9"></a>11:11
+      </td>
+      <td valign="top">SYM_DMA_COMPLETED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The GPR interrupt status.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.1.10"></a>31:12
+      </td>
+      <td valign="top">RESERVED2</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.9.2"></a><br>1.9.2 : <b>Reg : HOST_RGF_IMR</b> : 0x000000A04<br><b>reg sep address</b> : <b> reg host address</b> : <br>The Interrupt Mask register. Each bit of this register holds the mask of a single interrupt source.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_RGF_IMR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.1"></a>3:0
+      </td>
+      <td valign="top">unused0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.2"></a>4:4
+      </td>
+      <td valign="top">SRAM_TO_DIN_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The SRAM to DIN DMA done interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.3"></a>5:5
+      </td>
+      <td valign="top">DOUT_TO_SRAM_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The DOUT to SRAM DMA done interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.4"></a>6:6
+      </td>
+      <td valign="top">MEM_TO_DIN_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The memory to DIN DMA done interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.5"></a>7:7
+      </td>
+      <td valign="top">DOUT_TO_MEM_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The DOUT to memory DMA done interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.6"></a>8:8
+      </td>
+      <td valign="top">AXI_ERR_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The AXI error interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.7"></a>9:9
+      </td>
+      <td valign="top">PKA_EXP_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The PKA end of operation interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.8"></a>10:10
+      </td>
+      <td valign="top">RNG_INT_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The RNG interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.9"></a>11:11
+      </td>
+      <td valign="top">SYM_DMA_COMPLETED_MASK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">The GPR interrupt mask.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.2.10"></a>31:12
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.9.3"></a><br>1.9.3 : <b>Reg : HOST_RGF_ICR</b> : 0x000000A08<br><b>reg sep address</b> : <b> reg host address</b> : <br>Interrupt Clear Register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_RGF_ICR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.1"></a>3:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.2"></a>4:4
+      </td>
+      <td valign="top">SRAM_TO_DIN_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The SRAM to DIN DMA done interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.3"></a>5:5
+      </td>
+      <td valign="top">DOUT_TO_SRAM_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The DOUT to SRAM DMA done interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.4"></a>6:6
+      </td>
+      <td valign="top">MEM_TO_DIN_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The memory to DIN DMA done interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.5"></a>7:7
+      </td>
+      <td valign="top">DOUT_TO_MEM_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The DOUT to memory DMA done interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.6"></a>8:8
+      </td>
+      <td valign="top">AXI_ERR_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The AXI error interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.7"></a>9:9
+      </td>
+      <td valign="top">PKA_EXP_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The PKA end of operation interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.8"></a>10:10
+      </td>
+      <td valign="top">RNG_INT_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The RNG interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.9"></a>11:11
+      </td>
+      <td valign="top">SYM_DMA_COMPLETED_CLEAR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The GPR interrupt clear.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.3.10"></a>31:12
+      </td>
+      <td valign="top">RESERVED2</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.9.4"></a><br>1.9.4 : <b>Reg : HOST_RGF_ENDIAN</b> : 0x000000A0C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines the endianness of the Host-accessible registers.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_RGF_ENDIAN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.1"></a>2:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.2"></a>3:3
+      </td>
+      <td valign="top">DOUT_WR_BG</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DOUT write endianness:<br>@1'b0 - little endian <br>@1'b1 - big endian
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.3"></a>6:4
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.4"></a>7:7
+      </td>
+      <td valign="top">DIN_RD_BG</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DIN write endianness:<br>@1'b0 - little endian <br>@1'b1 - big endian
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.5"></a>10:8
+      </td>
+      <td valign="top">RESERVED2</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.6"></a>11:11
+      </td>
+      <td valign="top">DOUT_WR_WBG</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DOUT write word endianness:<br>@1'b0 - little endian <br>@1'b1 - big endian
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.7"></a>14:12
+      </td>
+      <td valign="top">RESERVED3</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.8"></a>15:15
+      </td>
+      <td valign="top">DIN_RD_WBG</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DIN write word endianness:<br>@1'b0 - little endian <br>@1'b1 - big endian
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.4.9"></a>31:16
+      </td>
+      <td valign="top">RESERVED4</td>
+      <td valign="top" align="center">rw1</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.9.5"></a><br>1.9.5 : <b>Reg : HOST_RGF_SIGNATURE</b> : 0x000000A24<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the CryptoCell product signature.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_RGF_SIGNATURE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.5.1"></a>31:0
+      </td>
+      <td valign="top">HOST_SIGNATURE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Identification &#8220;signature&#8221;: always returns a fixed value, used by Host driver to verify CryptoCell presence at this address.</td>
+   </tr>
+</table><a name="1.9.6"></a><br>1.9.6 : <b>Reg : HOST_BOOT</b> : 0x000000A28<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the values of CryptoCell's pre-synthesis flags<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_BOOT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.1"></a>0:0
+      </td>
+      <td valign="top">SYNTHESIS_CONFIG</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">POWER_GATING_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.2"></a>1:1
+      </td>
+      <td valign="top">LARGE_RKEK_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">LARGE_RKEK_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.3"></a>2:2
+      </td>
+      <td valign="top">HASH_IN_FUSES_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">HASH_IN_FUSES_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.4"></a>3:3
+      </td>
+      <td valign="top">EXT_MEM_SECURED_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">EXT_MEM_SECURED_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.5"></a>4:4
+      </td>
+      <td valign="top">Reserved</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.6"></a>5:5
+      </td>
+      <td valign="top">RKEK_ECC_EXISTS_LOCAL_N</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">RKEK_ECC_EXISTS_LOCAL_N</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.7"></a>8:6
+      </td>
+      <td valign="top">SRAM_SIZE_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SRAM_SIZE_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.8"></a>9:9
+      </td>
+      <td valign="top">DSCRPTR_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DSCRPTR_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.9"></a>10:10
+      </td>
+      <td valign="top">PAU_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PAU_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.10"></a>11:11
+      </td>
+      <td valign="top">RNG_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">RNG_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.11"></a>12:12
+      </td>
+      <td valign="top">PKA_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">PKA_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.12"></a>13:13
+      </td>
+      <td valign="top">RC4_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">RC4_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.13"></a>14:14
+      </td>
+      <td valign="top">SHA_512_PRSNT_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SHA_512_PRSNT_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.14"></a>15:15
+      </td>
+      <td valign="top">SHA_256_PRSNT_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">SHA_256_PRSNT_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.15"></a>16:16
+      </td>
+      <td valign="top">MD5_PRSNT_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">MD5_PRSNT_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.16"></a>17:17
+      </td>
+      <td valign="top">HASH_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">HASH_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.17"></a>18:18
+      </td>
+      <td valign="top">C2_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">C2_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.18"></a>19:19
+      </td>
+      <td valign="top">DES_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DES_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.19"></a>20:20
+      </td>
+      <td valign="top">AES_XCBC_MAC_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AES_XCBC_MAC_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.20"></a>21:21
+      </td>
+      <td valign="top">AES_CMAC_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">AES_CMAC_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.21"></a>22:22
+      </td>
+      <td valign="top">AES_CCM_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">AES_CCM_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.22"></a>23:23
+      </td>
+      <td valign="top">AES_XEX_HW_T_CALC_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AES_XEX_HW_T_CALC_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.23"></a>24:24
+      </td>
+      <td valign="top">AES_XEX_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AES_XEX_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.24"></a>25:25
+      </td>
+      <td valign="top">CTR_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">CTR_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.25"></a>26:26
+      </td>
+      <td valign="top">AES_DIN_BYTE_RESOLUTION_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">AES_DIN_BYTE_RESOLUTION_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.26"></a>27:27
+      </td>
+      <td valign="top">TUNNELING_ENB_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">TUNNELING_ENB_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.27"></a>28:28
+      </td>
+      <td valign="top">SUPPORT_256_192_KEY_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">SUPPORT_256_192_KEY_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.28"></a>29:29
+      </td>
+      <td valign="top">ONLY_ENCRYPT_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">ONLY_ENCRYPT_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.29"></a>30:30
+      </td>
+      <td valign="top">AES_EXISTS_LOCAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">AES_EXISTS_LOCAL</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.6.30"></a>31:31
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.9.7"></a><br>1.9.7 : <b>Reg : HOST_CRYPTOKEY_SEL</b> : 0x000000A38<br><b>reg sep address</b> : <b> reg host address</b> : <br>AES hardware key select.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_CRYPTOKEY_SEL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.7.1"></a>2:0
+      </td>
+      <td valign="top">SEL_CRYPTO_KEY</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Select the source of the HW key that is used by the AES engine: <br>@3'h0 - RKEK<br>@3'h1 -the Krtl.<br>@3'h2 - the provision key KCP.<br>@3'h3 - the code encryption key KCE.                      <br>@3'h4 - the KPICV, The ICV provisioning key .<br>@3'h5 - the code encryption key KCEICV<br>NOTE:<br>When "kprtl_lock" is set - kprtl will be masked (trying to load it will load zeros to the AES key register.<br>When "kcertl_lock" is set - kcertl will be masked (trying to load it will load zeros to the AES key register.<br>When scan_mode is asserted &#8211; all the RTL keys (Krtll) will be masked.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.7.2"></a>31:3
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.9.8"></a><br>1.9.8 : <b>Reg : HOST_CORE_CLK_GATING_ENABLE</b> : 0x000000A78<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register enables  the core clk gating by masking/enabling the  cc_idle_state output signal.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_CORE_CLK_GATING_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.8.1"></a>0:0
+      </td>
+      <td valign="top">HOST_CORE_CLK_GATING_ENABLE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Enable the core clk gating,</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.8.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.9.9"></a><br>1.9.9 : <b>Reg : HOST_CC_IS_IDLE</b> : 0x000000A7C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the idle indication of CC . Note: This is a special register, affected by internal logic. Test result
+of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_CC_IS_IDLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.1"></a>0:0
+      </td>
+      <td valign="top">HOST_CC_IS_IDLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Read if CC is idle.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.2"></a>1:1
+      </td>
+      <td valign="top">HOST_CC_IS_IDLE_EVENT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The event that indicates that CC is idle.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.3"></a>2:2
+      </td>
+      <td valign="top">SYM_IS_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">symetric flow is busy</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.4"></a>3:3
+      </td>
+      <td valign="top">AHB_IS_IDLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">ahb stste machine is idle</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.5"></a>4:4
+      </td>
+      <td valign="top">NVM_ARB_IS_IDLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">nvm arbiter is idle</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.6"></a>5:5
+      </td>
+      <td valign="top">NVM_IS_IDLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">nvm is idle</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.7"></a>6:6
+      </td>
+      <td valign="top">FATAL_WR</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">fatal write</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.8"></a>7:7
+      </td>
+      <td valign="top">RNG_IS_IDLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">rng is idle</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.9"></a>8:8
+      </td>
+      <td valign="top">PKA_IS_IDLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">pka is idle</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.10"></a>9:9
+      </td>
+      <td valign="top">CRYPTO_IS_IDLE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">crypto flow is done</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.9.11"></a>31:10
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.9.10"></a><br>1.9.10 : <b>Reg : HOST_POWERDOWN</b> : 0x000000A80<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register start the power-down sequence.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_POWERDOWN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.10.1"></a>0:0
+      </td>
+      <td valign="top">HOST_POWERDOWN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Power down enable register.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.10.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.9.11"></a><br>1.9.11 : <b>Reg : HOST_REMOVE_GHASH_ENGINE</b> : 0x000000A84<br><b>reg sep address</b> : <b> reg host address</b> : <br>These inputs are to be statically tied to 0 or 1 by the customers. When such an input is set, the matching engines inputs
+are tied to zero and its outputs are disconnected, so that the engine will be entirely removed by Synthesis<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_REMOVE_GHASH_ENGINE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.11.1"></a>0:0
+      </td>
+      <td valign="top">HOST_REMOVE_GHASH_ENGINE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Read the Remove_chacha_engine input</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.11.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.9.12"></a><br>1.9.12 : <b>Reg : HOST_REMOVE_CHACHA_ENGINE</b> : 0x000000A88<br><b>reg sep address</b> : <b> reg host address</b> : <br>These inputs are to be statically tied to 0 or 1 by the customers. When such an input is set, the matching engines inputs
+are tied to zero and its outputs are disconnected, so that the engine will be entirely removed by Synthesis<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_REMOVE_CHACHA_ENGINE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.12.1"></a>0:0
+      </td>
+      <td valign="top">HOST_REMOVE_CHACHA_ENGINE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Read the Remove_ghash_engine  input</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.9.12.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a href="#1.9">(top of block)</a><a name="1.10"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.10 : Block: AHB</font></b></td>
+   <td align="right"><font color="#000000">0x000000B00</font></td>
+</table><br><a name="1.10.1"></a><br>1.10.1 : <b>Reg : AHBM_SINGLES</b> : 0x000000B00<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register forces the ahb transactions to be always singles.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AHBM_SINGLES</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.1.1"></a>0:0
+      </td>
+      <td valign="top">AHB_SINGLES</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Force ahb singles</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.1.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.10.2"></a><br>1.10.2 : <b>Reg : AHBM_HPROT</b> : 0x000000B04<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the ahb prot value<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AHBM_HPROT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.2.1"></a>3:0
+      </td>
+      <td valign="top">AHB_PROT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The ahb prot value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.2.2"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.10.3"></a><br>1.10.3 : <b>Reg : AHBM_HMASTLOCK</b> : 0x000000B08<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds ahb hmastlock value<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AHBM_HMASTLOCK</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.3.1"></a>0:0
+      </td>
+      <td valign="top">AHB_HMASTLOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The hmastlock value.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.3.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.10.4"></a><br>1.10.4 : <b>Reg : AHBM_HNONSEC</b> : 0x000000B0C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds ahb hnonsec value<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AHBM_HNONSEC</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.4.1"></a>0:0
+      </td>
+      <td valign="top">AHB_WRITE_HNONSEC</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The hnonsec value for write transaction.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.4.2"></a>1:1
+      </td>
+      <td valign="top">AHB_READ_HNONSEC</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The hnonsec value for read transaction.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.10.4.3"></a>31:2
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.10">(top of block)</a><a name="1.11"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.11 : Block: DIN</font></b></td>
+   <td align="right"><font color="#000000">0x000000C00</font></td>
+</table><br><a name="1.11.1"></a><br>1.11.1 : <b>Reg : DIN_BUFFER</b> : 0x000000C00<br><b>reg sep address</b> : <b> reg host address</b> : <br>This address can be used by the CPU to write data directly to the DIN buffer to be sent to engines.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DIN_BUFFER</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.1.1"></a>31:0
+      </td>
+      <td valign="top">DIN_BUFFER_DATA</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This register is mapped into 8 addresses in order to enable a CPU burst.</td>
+   </tr>
+</table><a name="1.11.2"></a><br>1.11.2 : <b>Reg : DIN_MEM_DMA_BUSY</b> : 0x000000C20<br><b>reg sep address</b> : <b> reg host address</b> : <br>Indicates whether memory (AXI) source DMA (DIN) is busy.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DIN_MEM_DMA_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.2.1"></a>0:0
+      </td>
+      <td valign="top">DIN_MEM_DMA_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DIN memory DMA busy:<br>@1'b1 - busy<br>@1'b0 - not busy
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.2.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.11.3"></a><br>1.11.3 : <b>Reg : SRC_LLI_WORD0</b> : 0x000000C28<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is used in direct LLI mode - holds the location of the data source in the memory (AXI).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SRC_LLI_WORD0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.3.1"></a>31:0
+      </td>
+      <td valign="top">SRC_LLI_WORD0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Source address within memory.</td>
+   </tr>
+</table><a name="1.11.4"></a><br>1.11.4 : <b>Reg : SRC_LLI_WORD1</b> : 0x000000C2C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is used in direct LLI mode - holds the number of bytes to be read from the memory (AXI). Writing to this register
+triggers the DMA.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SRC_LLI_WORD1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.4.1"></a>29:0
+      </td>
+      <td valign="top">BYTES_NUM</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Total number of bytes to read using DMA in this entry</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.4.2"></a>30:30
+      </td>
+      <td valign="top">FIRST</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - Indicates the first LLI entry</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.4.3"></a>31:31
+      </td>
+      <td valign="top">LAST</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - Indicates the last LLI entry</td>
+   </tr>
+</table><a name="1.11.5"></a><br>1.11.5 : <b>Reg : SRAM_SRC_ADDR</b> : 0x000000C30<br><b>reg sep address</b> : <b> reg host address</b> : <br>Location of data (start address) to be read from SRAM.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SRAM_SRC_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.5.1"></a>31:0
+      </td>
+      <td valign="top">SRAM_SOURCE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SRAM source base address of data</td>
+   </tr>
+</table><a name="1.11.6"></a><br>1.11.6 : <b>Reg : DIN_SRAM_BYTES_LEN</b> : 0x000000C34<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the size of the data (in bytes) to be read from the SRAM.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DIN_SRAM_BYTES_LEN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.6.1"></a>31:0
+      </td>
+      <td valign="top">BYTES_LEN</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of data to read from SRAM (bytes). This is the trigger to the SRAM SRC DMA.</td>
+   </tr>
+</table><a name="1.11.7"></a><br>1.11.7 : <b>Reg : DIN_SRAM_DMA_BUSY</b> : 0x000000C38<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the status of the SRAM DMA DIN.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DIN_SRAM_DMA_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.7.1"></a>0:0
+      </td>
+      <td valign="top">BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DIN SRAM DMA busy:<br>@1'b1 - busy<br>@1'b0 - not busy
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.7.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.11.8"></a><br>1.11.8 : <b>Reg : DIN_SRAM_ENDIANNESS</b> : 0x000000C3C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines the endianness of the DIN interface to SRAM.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DIN_SRAM_ENDIANNESS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.8.1"></a>0:0
+      </td>
+      <td valign="top">SRAM_DIN_ENDIANNESS</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines the endianness of DIN interface to SRAM:<br>@1'b1 - big-endianness<br>@1'b0 - little endianness
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.8.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.11.9"></a><br>1.11.9 : <b>Reg : DIN_CPU_DATA_SIZE</b> : 0x000000C48<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register hold the number of bytes to be transmited using external DMA<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DIN_CPU_DATA_SIZE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.9.1"></a>15:0
+      </td>
+      <td valign="top">CPU_DIN_SIZE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When using external DMA, the size of transmited data in bytes should be written to this register.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.9.2"></a>31:16
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.11.10"></a><br>1.11.10 : <b>Reg : FIFO_IN_EMPTY</b> : 0x000000C50<br><b>reg sep address</b> : <b> reg host address</b> : <br>DIN FIFO empty indication<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">FIFO_IN_EMPTY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.10.1"></a>0:0
+      </td>
+      <td valign="top">EMPTY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">1'b1 - FIFO empty</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.10.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.11.11"></a><br>1.11.11 : <b>Reg : DIN_FIFO_RST_PNTR</b> : 0x000000C58<br><b>reg sep address</b> : <b> reg host address</b> : <br>Writing to this register resets the DIN_FIFO pointers.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DIN_FIFO_RST_PNTR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.11.1"></a>0:0
+      </td>
+      <td valign="top">RST</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing any value to this address resets the DIN_FIFO pointers.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.11.11.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.11">(top of block)</a><a name="1.12"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.12 : Block: DOUT</font></b></td>
+   <td align="right"><font color="#000000">0x000000D00</font></td>
+</table><br><a name="1.12.1"></a><br>1.12.1 : <b>Reg : DOUT_BUFFER</b> : 0x000000D00<br><b>reg sep address</b> : <b> reg host address</b> : <br>Cryptographic result - CPU can directly access it.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DOUT_BUFFER</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.1.1"></a>31:0
+      </td>
+      <td valign="top">DOUT_BUFFER_DATA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This address can be used by the CPU to read data directly from the DOUT buffer.</td>
+   </tr>
+</table><a name="1.12.2"></a><br>1.12.2 : <b>Reg : DOUT_MEM_DMA_BUSY</b> : 0x000000D20<br><b>reg sep address</b> : <b> reg host address</b> : <br>DOUT memory DMA busy - Indicates that memory (AXI) destination DMA (DOUT) is busy,<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DOUT_MEM_DMA_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.2.1"></a>0:0
+      </td>
+      <td valign="top">DOUT_MEM_DMA_BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DOUT memory DMA busy:<br>@1'b1 - busy<br>@1'b0 - not busy
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.2.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.12.3"></a><br>1.12.3 : <b>Reg : DST_LLI_WORD0</b> : 0x000000D28<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is used in direct LLI mode - holds the location of the data destination in the memory (AXI)<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DST_LLI_WORD0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.3.1"></a>31:0
+      </td>
+      <td valign="top">DST_LLI_WORD0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Destination address within memory</td>
+   </tr>
+</table><a name="1.12.4"></a><br>1.12.4 : <b>Reg : DST_LLI_WORD1</b> : 0x000000D2C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register is used in direct LLI mode - holds the number of bytes to be written to the memory (AXI). <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DST_LLI_WORD1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.4.1"></a>29:0
+      </td>
+      <td valign="top">BYTES_NUM</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Total byte number to be written by DMA in this entry</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.4.2"></a>30:30
+      </td>
+      <td valign="top">FIRST</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - Indicates the first LLI entry</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.4.3"></a>31:31
+      </td>
+      <td valign="top">LAST</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - Indicates the last LLI entry</td>
+   </tr>
+</table><a name="1.12.5"></a><br>1.12.5 : <b>Reg : SRAM_DEST_ADDR</b> : 0x000000D30<br><b>reg sep address</b> : <b> reg host address</b> : <br>Location of result to be sent to in SRAM<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SRAM_DEST_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.5.1"></a>31:0
+      </td>
+      <td valign="top">SRAM_DEST</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SRAM destination base address for data.</td>
+   </tr>
+</table><a name="1.12.6"></a><br>1.12.6 : <b>Reg : DOUT_SRAM_BYTES_LEN</b> : 0x000000D34<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the size of the data (in bytes) to be written to the SRAM.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DOUT_SRAM_BYTES_LEN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.6.1"></a>31:0
+      </td>
+      <td valign="top">BYTES_LEN</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Size of data to write to SRAM (bytes). This is the trigger to the SRAM DST DMA.</td>
+   </tr>
+</table><a name="1.12.7"></a><br>1.12.7 : <b>Reg : DOUT_SRAM_DMA_BUSY</b> : 0x000000D38<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the status of the SRAM DMA DOUT.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DOUT_SRAM_DMA_BUSY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.7.1"></a>0:0
+      </td>
+      <td valign="top">BUSY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">@1'b0 - all data was written to SRAM.<br>@1'b1 - DOUT SRAM DMA busy.
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.7.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.12.8"></a><br>1.12.8 : <b>Reg : DOUT_SRAM_ENDIANNESS</b> : 0x000000D3C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register defines the endianness of the DOUT interface from SRAM.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DOUT_SRAM_ENDIANNESS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.8.1"></a>0:0
+      </td>
+      <td valign="top">DOUT_SRAM_ENDIANNESS</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Defines the endianness of DOUT interface from SRAM:<br>@1'b1 - big-endianness<br>@1'b0 - little endianness
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.8.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.12.9"></a><br>1.12.9 : <b>Reg : READ_ALIGN_LAST</b> : 0x000000D44<br><b>reg sep address</b> : <b> reg host address</b> : <br>Indication that the next read from the CPU is the last one. This is needed only when the data size is NOT modulo 4 (e.g. HASH
+padding).<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">READ_ALIGN_LAST</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.9.1"></a>0:0
+      </td>
+      <td valign="top">LAST</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - Flush the read aligner content (used for reading the last data).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.9.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.12.10"></a><br>1.12.10 : <b>Reg : DOUT_FIFO_EMPTY</b> : 0x000000D50<br><b>reg sep address</b> : <b> reg host address</b> : <br>DOUT_FIFO_EMPTY Register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">DOUT_FIFO_EMPTY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.10.1"></a>0:0
+      </td>
+      <td valign="top">DOUT_FIFO_EMPTY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">@1'b0 - DOUT FIFO is not empty <br>@1'b1 - DOUT FIFO is empty
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.12.10.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.12">(top of block)</a><a name="1.13"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.13 : Block: HOST_SRAM</font></b></td>
+   <td align="right"><font color="#000000">0x000000F00</font></td>
+</table><br><a name="1.13.1"></a><br>1.13.1 : <b>Reg : SRAM_DATA</b> : 0x000000F00<br><b>reg sep address</b> : <b> reg host address</b> : <br>READ WRITE DATA FROM SRAM<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SRAM_DATA</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.13.1.1"></a>31:0
+      </td>
+      <td valign="top">SRAM_DATA</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">32 bit write or read from SRAM: read - triggers the SRAM read DMA address automatically incremented write - triggers the SRAM
+         write DMA address automatically incremented
+      </td>
+   </tr>
+</table><a name="1.13.2"></a><br>1.13.2 : <b>Reg : SRAM_ADDR</b> : 0x000000F04<br><b>reg sep address</b> : <b> reg host address</b> : <br>first address given to SRAM DMA for read/write transactions from SRAM<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SRAM_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.13.2.1"></a>14:0
+      </td>
+      <td valign="top">SRAM_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SRAM starting address</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.13.2.2"></a>31:15
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">17'b0</td>
+   </tr>
+</table><a name="1.13.3"></a><br>1.13.3 : <b>Reg : SRAM_DATA_READY</b> : 0x000000F08<br><b>reg sep address</b> : <b> reg host address</b> : <br>The SRAM content is ready for read in SRAM_DATA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">SRAM_DATA_READY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.13.3.1"></a>0:0
+      </td>
+      <td valign="top">SRAM_READY</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">SRAM content is ready for read in SRAM_DATA.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.13.3.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.13">(top of block)</a><a name="1.14"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.14 : Block: ID_REGISTERS</font></b></td>
+   <td align="right"><font color="#000000">0x000000F10</font></td>
+</table><br><a name="1.14.1"></a><br>1.14.1 : <b>Reg : PERIPHERAL_ID_4</b> : 0x000000FD0<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PERIPHERAL_ID_4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.1.1"></a>3:0
+      </td>
+      <td valign="top">DES_2_JEP106</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Continuation Code. 0x4 for ARM products.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.1.2"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.2"></a><br>1.14.2 : <b>Reg : PIDRESERVED0</b> : 0x000000FD4<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PIDRESERVED0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.2.1"></a>31:0
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.3"></a><br>1.14.3 : <b>Reg : PIDRESERVED1</b> : 0x000000FD8<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PIDRESERVED1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.3.1"></a>31:0
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.4"></a><br>1.14.4 : <b>Reg : PIDRESERVED2</b> : 0x000000FDC<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PIDRESERVED2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.4.1"></a>31:0
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.5"></a><br>1.14.5 : <b>Reg : PERIPHERAL_ID_0</b> : 0x000000FE0<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PERIPHERAL_ID_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.5.1"></a>7:0
+      </td>
+      <td valign="top">PART_0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Identification register part number, bits[7:0]</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.5.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.6"></a><br>1.14.6 : <b>Reg : PERIPHERAL_ID_1</b> : 0x000000FE4<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PERIPHERAL_ID_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.6.1"></a>3:0
+      </td>
+      <td valign="top">PART_1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Identification register part number, bits[11:8]</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.6.2"></a>7:4
+      </td>
+      <td valign="top">DES_0_JEP106</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x3</td>
+      <td valign="top">identification code, bits[3:0]. 0x3B for ARM products.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.6.3"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.7"></a><br>1.14.7 : <b>Reg : PERIPHERAL_ID_2</b> : 0x000000FE8<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PERIPHERAL_ID_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.7.1"></a>2:0
+      </td>
+      <td valign="top">DES_1_JEP106</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">identification code, bits[6:4]. 0x3B for ARM products.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.7.2"></a>3
+      </td>
+      <td valign="top">JEDEC</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">constant 0x1. Indicates that a JEDEC assigned value is used.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.7.3"></a>7:4
+      </td>
+      <td valign="top">REVISION</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">starts at zero and increments for every new IP release.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.7.4"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.8"></a><br>1.14.8 : <b>Reg : PERIPHERAL_ID_3</b> : 0x000000FEC<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">PERIPHERAL_ID_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.8.1"></a>3:0
+      </td>
+      <td valign="top">CMOD</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Customer Modified, normally zero, but if a partner applies any changes themselves, they must change this value.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.8.2"></a>7:4
+      </td>
+      <td valign="top">REVAND</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">starts at zero for every Revision, and increments if metal fixes are applied between 2 IP releases.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.8.3"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.9"></a><br>1.14.9 : <b>Reg : COMPONENT_ID_0</b> : 0x000000FF0<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">COMPONENT_ID_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.9.1"></a>7:0
+      </td>
+      <td valign="top">PRMBL_0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">constant 0xD</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.9.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.10"></a><br>1.14.10 : <b>Reg : COMPONENT_ID_1</b> : 0x000000FF4<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">COMPONENT_ID_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.10.1"></a>3:0
+      </td>
+      <td valign="top">PRMBL_1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">constant 0x0</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.10.2"></a>7:4
+      </td>
+      <td valign="top">CLASS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">component type 0 0xF for Cryptocell</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.10.3"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.11"></a><br>1.14.11 : <b>Reg : COMPONENT_ID_2</b> : 0x000000FF8<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">COMPONENT_ID_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.11.1"></a>7:0
+      </td>
+      <td valign="top">PRMBL_2</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">constant 0x5</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.11.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a name="1.14.12"></a><br>1.14.12 : <b>Reg : COMPONENT_ID_3</b> : 0x000000FFC<br><b>reg sep address</b> : <b> reg host address</b> : <br><br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">COMPONENT_ID_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.12.1"></a>7:0
+      </td>
+      <td valign="top">PRMBL_3</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">constant 0xB1</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.14.12.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved<br>Note: This is a special register, this registers
+      </td>
+   </tr>
+</table><a href="#1.14">(top of block)</a><a name="1.15"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.15 : Block: AO</font></b></td>
+   <td align="right"><font color="#000000">0x000001E00</font></td>
+</table><br><a name="1.15.1"></a><br>1.15.1 : <b>Reg : HOST_DCU_EN0</b> : 0x000001E00<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU [31:0] enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_EN0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.1.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_EN0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Debug Control Unit (DCU) Enable bits.</td>
+   </tr>
+</table><a name="1.15.2"></a><br>1.15.2 : <b>Reg : HOST_DCU_EN1</b> : 0x000001E04<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU  [63:32] enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_EN1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.2.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_EN1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Debug Control Unit (DCU) Enable bits.</td>
+   </tr>
+</table><a name="1.15.3"></a><br>1.15.3 : <b>Reg : HOST_DCU_EN2</b> : 0x000001E08<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU  [95:64] enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_EN2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.3.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_EN2</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Debug Control Unit (DCU) Enable bits.</td>
+   </tr>
+</table><a name="1.15.4"></a><br>1.15.4 : <b>Reg : HOST_DCU_EN3</b> : 0x000001E0C<br><b>reg sep address</b> : <b> reg host address</b> : 1E0C<br>The DCU [1271:96]  enable register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_EN3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.4.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_EN3</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Debug Control Unit (DCU) Enable bits.</td>
+   </tr>
+</table><a name="1.15.5"></a><br>1.15.5 : <b>Reg : HOST_DCU_LOCK0</b> : 0x000001E10<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU lock register.Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_LOCK0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.5.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_LOCK0</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DCU_lock  [31:0] register (a dedicated lock register per DCU bit).</td>
+   </tr>
+</table><a name="1.15.6"></a><br>1.15.6 : <b>Reg : HOST_DCU_LOCK1</b> : 0x000001E14<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU lock register.Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_LOCK1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.6.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_LOCK1</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DCU_lock [63:32]  register (a dedicated lock register per DCU bit).</td>
+   </tr>
+</table><a name="1.15.7"></a><br>1.15.7 : <b>Reg : HOST_DCU_LOCK2</b> : 0x000001E18<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU lock register.Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_LOCK2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.7.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_LOCK2</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DCU_lock  [95:64]  register (a dedicated lock register per DCU bit).</td>
+   </tr>
+</table><a name="1.15.8"></a><br>1.15.8 : <b>Reg : HOST_DCU_LOCK3</b> : 0x000001E1C<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU lock register.Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_DCU_LOCK3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.8.1"></a>31:0
+      </td>
+      <td valign="top">HOST_DCU_LOCK3</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">DCU_lock  [127:96] register (a dedicated lock register per DCU bit).</td>
+   </tr>
+</table><a name="1.15.9"></a><br>1.15.9 : <b>Reg : AO_ICV_DCU_RESTRICTION_MASK0</b> : 0x000001E20<br><b>reg sep address</b> : <b> reg host address</b> : <br>The DCU lock register.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AO_ICV_DCU_RESTRICTION_MASK0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.9.1"></a>31:0
+      </td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK  [31:0] parameter, that will be a customer modifiable.</td>
+   </tr>
+</table><a name="1.15.10"></a><br>1.15.10 : <b>Reg : AO_ICV_DCU_RESTRICTION_MASK1</b> : 0x000001E24<br><b>reg sep address</b> : <b> reg host address</b> : <br>The "ICV_DCU_restriction_mask" parameter is read by FW during the secure debug verification to prevent OEM from setting specific
+DCUs that protect ICV secrets<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AO_ICV_DCU_RESTRICTION_MASK1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.10.1"></a>31:0
+      </td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK   [63:32] parameter, that will be a customer modifiable.</td>
+   </tr>
+</table><a name="1.15.11"></a><br>1.15.11 : <b>Reg : AO_ICV_DCU_RESTRICTION_MASK2</b> : 0x000001E28<br><b>reg sep address</b> : <b> reg host address</b> : <br>The "ICV_DCU_restriction_mask" parameter is read by FW during the secure debug verification to prevent OEM from setting specific
+DCUs that protect ICV secrets<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AO_ICV_DCU_RESTRICTION_MASK2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.11.1"></a>31:0
+      </td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK2</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK  [95:64]  parameter, that will be a customer modifiable.</td>
+   </tr>
+</table><a name="1.15.12"></a><br>1.15.12 : <b>Reg : AO_ICV_DCU_RESTRICTION_MASK3</b> : 0x000001E2C<br><b>reg sep address</b> : <b> reg host address</b> : <br>The "ICV_DCU_restriction_mask" parameter is read by FW during the secure debug verification to prevent OEM from setting specific
+DCUs that protect ICV secrets<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AO_ICV_DCU_RESTRICTION_MASK3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.12.1"></a>31:0
+      </td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK3</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AO_ICV_DCU_RESTRICTION_MASK  [127:96]  parameter, that will be a customer modifiable.</td>
+   </tr>
+</table><a name="1.15.13"></a><br>1.15.13 : <b>Reg : AO_CC_SEC_DEBUG_RESET</b> : 0x000001E30<br><b>reg sep address</b> : <b> reg host address</b> : <br>The reset-upon-debug indication<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AO_CC_SEC_DEBUG_RESET</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.13.1"></a>0:0
+      </td>
+      <td valign="top">AO_CC_SEC_DEBUG_RESET</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">For resets Cerberus, and prevents loading the HW keys after that reset</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.13.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.15.14"></a><br>1.15.14 : <b>Reg : HOST_AO_LOCK_BITS</b> : 0x000001E34<br><b>reg sep address</b> : <b> reg host address</b> : <br>These masks will define, per LCS, which DCU bits will be tied to zero, even if the Host tries to set them. Note: This is a
+special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_AO_LOCK_BITS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.1"></a>0:0
+      </td>
+      <td valign="top">HOST_FATAL_ERR</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When the "FATAL_ERROR" register is asserted - HW keys will not be copied from OTP</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.2"></a>1:1
+      </td>
+      <td valign="top">HOST_KPICV_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this FW controlled register is set, the Kpicv HW key is masked (to zero).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.3"></a>2:2
+      </td>
+      <td valign="top">HOST_KCEICV_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this FW controlled register is set, the Kceicv HW key is masked (to zero).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.4"></a>3:3
+      </td>
+      <td valign="top">HOST_KCP_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this FW controlled register is set, the Kcp HW key is masked (to zero).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.5"></a>4:4
+      </td>
+      <td valign="top">HOST_KCE_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this FW controlled register is set, the Kce HW key is masked (to zero).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.6"></a>5:5
+      </td>
+      <td valign="top">HOST_ICV_RMA_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The ICV_RMA_LOCK register is set-once (per POR).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.7"></a>6:6
+      </td>
+      <td valign="top">RESET_UPON_DEBUG_DISABLE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The RESET_UPON_DEBUG_DISABLE register is set-once (per POR).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.8"></a>7:7
+      </td>
+      <td valign="top">HOST_FORCE_DFA_ENABLE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">When this FW controlled register is set, the AES DFA countermeasures are enabled/disabled (regardless of the AES_DFA_IS_ON
+         register value).
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.9"></a>8:8
+      </td>
+      <td valign="top">HOST_DFA_ENABLE_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">When this FW control is set, the DFA_ENABLE register can't be written until the next POR. The DFA_ENABLE_LOCK register is
+         set-once (per POR).
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.14.10"></a>31:9
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.15.15"></a><br>1.15.15 : <b>Reg : AO_APB_FILTERING</b> : 0x000001E38<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register holds the AO_APB_FILTERING data. Note: This is a special register, affected by internal logic. Test result of
+this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AO_APB_FILTERING</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.1"></a>0:0
+      </td>
+      <td valign="top">ONLY_SEC_ACCESS_ALLOW</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">when this FW controlled register is set, the APB slave accepts only secure accesses</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.2"></a>1:1
+      </td>
+      <td valign="top">ONLY_SEC_ACCESS_ALLOW_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">when this FW controlled register is set, the ONLY_SEC_ACCESS_ALLOWED register can't be modified (until the next POR).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.3"></a>2:2
+      </td>
+      <td valign="top">ONLY_PRIV_ACCESS_ALLOW</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">when this FW controlled register is set, the APB slave accepts only privileged accesses</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.4"></a>3:3
+      </td>
+      <td valign="top">ONLY_PRIV_ACCESS_ALLOW_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">when this FW controlled register is set, the APBC_ONLY_PRIV_ACCESS_ALLOWED register can't be modified (until the next POR)</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.5"></a>4:4
+      </td>
+      <td valign="top">APBC_ONLY_SEC_ACCESS_ALLOW</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">when this FW controlled register is set, the APB-C slave accepts only secure accesses</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.6"></a>5:5
+      </td>
+      <td valign="top">APBC_ONLY_SEC_ACCESS_ALLOW_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">when this FW controlled register is set, the APBC_ONLY_SEC_ACCESS_ALLOWED register can't be modified (until the next POR).</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.7"></a>6:6
+      </td>
+      <td valign="top">APBC_ONLY_PRIV_ACCESS_ALLOW</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">when this FW controlled register is set, the APB-C slave accepts only privileged accesses</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.8"></a>7:7
+      </td>
+      <td valign="top">APBC_ONLY_PRIV_ACCESS_ALLOW_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">when this FW controlled register is set, the APBC_ONLY_PRIV_ACCESS_ALLOWED register can't be modified (until the next POR)</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.9"></a>8:8
+      </td>
+      <td valign="top">APBC_ONLY_INST_ACCESS_ALLOW</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">when this FW controlled register is set, the APB-C slave accepts only instruction accesses</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.10"></a>9:9
+      </td>
+      <td valign="top">APBC_ONLY_INST_ACCESS_ALLOW_LOCK</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">when this FW controlled register is set, the APBC_ONLY_INST_ACCESS_ALLOWED register can't be modified (until the next POR)</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.15.11"></a>31:10
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.15.16"></a><br>1.15.16 : <b>Reg : AO_CC_GPPC</b> : 0x000001E3C<br><b>reg sep address</b> : <b> reg host address</b> : <br>holds the AO_CC_GPPC value from AO<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AO_CC_GPPC</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.16.1"></a>7:0
+      </td>
+      <td valign="top">AO_CC_GPPC</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">The AO_CC_GPPC value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.16.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.15.17"></a><br>1.15.17 : <b>Reg : HOST_RGF_CC_SW_RST</b> : 0x000001E40<br><b>reg sep address</b> : <b> reg host address</b> : <br>Writing to this register generates a general reset to CryptoCell. This reset takes about 4 core clock cycles.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_RGF_CC_SW_RST</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.17.1"></a>0:0
+      </td>
+      <td valign="top">HOST_RGF_CC_SW_RST</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Writing '1' to this field generates a general reset to CryptoCell.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.15.17.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.15">(top of block)</a><a name="1.16"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.16 : Block: NVM</font></b></td>
+   <td align="right"><font color="#000000">0x000001F00</font></td>
+</table><br><a name="1.16.1"></a><br>1.16.1 : <b>Reg : AIB_FUSE_PROG_COMPLETED</b> : 0x000001F04<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register reflects the fuse_aib_prog_completed input, which indicates that the fuse programming was completed.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">AIB_FUSE_PROG_COMPLETED</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.1.1"></a>0:0
+      </td>
+      <td valign="top">AIB_FUSE_PROG_COMPLETED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicates if the fuse programming operation has been completed.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.1.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.2"></a><br>1.16.2 : <b>Reg : NVM_DEBUG_STATUS</b> : 0x000001F08<br><b>reg sep address</b> : <b> reg host address</b> : <br>AIB debug status register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">NVM_DEBUG_STATUS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.2.1"></a>0:0
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.2.2"></a>3:1
+      </td>
+      <td valign="top">NVM_SM</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Main nvm fsm<br>3'b000 - IDLE<br>3'b001 - READ_DUMMY<br>3'b010 - READ_MAN_FLAG<br>3'b011 - READ_OEM_FLAG<br>3'b100 - READ_GPPC<br>3'b101 - DECODE<br>3'b110 - OTP_LCS_VALID<br>3'b111 - LCS_IS_VALID
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.2.3"></a>31:4
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.3"></a><br>1.16.3 : <b>Reg : LCS_IS_VALID</b> : 0x000001F0C<br><b>reg sep address</b> : <b> reg host address</b> : <br>Indicates that the LCS register holds a valid value.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">LCS_IS_VALID</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.3.1"></a>0:0
+      </td>
+      <td valign="top">LCS_IS_VALID_REG</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicates whether LCS is valid.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.3.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.4"></a><br>1.16.4 : <b>Reg : NVM_IS_IDLE</b> : 0x000001F10<br><b>reg sep address</b> : <b> reg host address</b> : <br>Indicates that the LCS register holds a valid value.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">NVM_IS_IDLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.4.1"></a>0:0
+      </td>
+      <td valign="top">NVM_IS_IDLE_REG</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indicates whether  the NVM manager finishes its operation, calculates the LCS, reads the HW keys, compares the number of zeros
+         and clears the keys
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.4.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.5"></a><br>1.16.5 : <b>Reg : LCS_REG</b> : 0x000001F14<br><b>reg sep address</b> : <b> reg host address</b> : <br>The lifecycle state register.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">LCS_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.1"></a>2:0
+      </td>
+      <td valign="top">LCS_REG</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Indicates the LCS (Lifecycle State) value.<br>3'b000 - CM<br>3'b001 - DM<br>3'b101 - SE<br>3'b111 - RMA
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.2"></a>7:3
+      </td>
+      <td valign="top">RESERVED0</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.3"></a>8:8
+      </td>
+      <td valign="top">ERROR_KDR_ZERO_CNT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indication that the number of zeroes in the loaded KDR is not equal to the value set in the manufacture flag.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.4"></a>9:9
+      </td>
+      <td valign="top">ERROR_PROV_ZERO_CNT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indication that the number of zeroes in the loaded KCP  is not equal to the value set in the OEM flag.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.5"></a>10:10
+      </td>
+      <td valign="top">ERROR_KCE_ZERO_CNT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indication that the number of zeroes in the loaded KCE is not equal to the value set in the OEM flag.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.6"></a>11:11
+      </td>
+      <td valign="top">ERROR_KPICV_ZERO_CNT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indication that the number of zeroes in the loaded KPICV is not equal to the value set in the manufacture flag.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.7"></a>12:12
+      </td>
+      <td valign="top">ERROR_KCEICV_ZERO_CNT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Indication that the number of zeroes in the loaded KCEICV is not equal to the value set in the manufacture flag.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.5.8"></a>31:13
+      </td>
+      <td valign="top">RESERVED1</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.6"></a><br>1.16.6 : <b>Reg : HOST_SHADOW_KDR_REG</b> : 0x000001F18<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register interface is used to update the RKEK(KDR) registers when the device is in  CM or DM mode , it is Write-once
+(per warm boot) in RMA LCS, The RKEK is updated by shifting .<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_SHADOW_KDR_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.6.1"></a>0:0
+      </td>
+      <td valign="top">HOST_SHADOW_KDR_REG</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field is used to update the KDR registers when the device is in CM , DM or RMA mode, The KDR is updated by shifting .</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.6.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.7"></a><br>1.16.7 : <b>Reg : HOST_SHADOW_KCP_REG</b> : 0x000001F1C<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register interface is used to update the KCP registers when the device is in CM or DM mode, The KCP is updated by shifting<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_SHADOW_KCP_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.7.1"></a>0:0
+      </td>
+      <td valign="top">HOST_SHADOW_KCP_REG</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field is used to update the KCP registers when the device is in CM or DM mode, The KCP is updated by shifting</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.7.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.8"></a><br>1.16.8 : <b>Reg : HOST_SHADOW_KCE_REG</b> : 0x000001F20<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register interface is used to update the KCE registers when the device is in CM or DM mode, The KCE is updated by shifting<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_SHADOW_KCE_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.8.1"></a>0:0
+      </td>
+      <td valign="top">HOST_SHADOW_KCE_REG</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field is used to update the KCE registers when the device is in CM or DM mode, The KCE is updated by shifting</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.8.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.9"></a><br>1.16.9 : <b>Reg : HOST_SHADOW_KPICV_REG</b> : 0x000001F24<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register interface is used to update the KPICV registers when the device is in CM or DM mode, The KPICV  is updated by
+shifting<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_SHADOW_KPICV_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.9.1"></a>0:0
+      </td>
+      <td valign="top">HOST_SHADOW_KPICV_REG</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field is used to update the KPICV  registers when the device is in CM or DM mode, The KPICV  is updated by shifting</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.9.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.10"></a><br>1.16.10 : <b>Reg : HOST_SHADOW_KCEICV_REG</b> : 0x000001F28<br><b>reg sep address</b> : <b> reg host address</b> : <br>This register interface is used to update the KCEICV registers when the device is in CM or DM mode, The KCEICV is updated
+by shifting<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">HOST_SHADOW_KCEICV_REG</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.10.1"></a>0:0
+      </td>
+      <td valign="top">HOST_SHADOW_KCEICV_REG</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">This field is used to update the KCEICV registers when the device is in CM or DM mode, The KCEICV is updated by shifting</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.10.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a name="1.16.11"></a><br>1.16.11 : <b>Reg : OTP_ADDR_WIDTH_DEF</b> : 0x000001F2C<br><b>reg sep address</b> : <b> reg host address</b> : <br>OTP_ADDR_WIDTH parameter, that will define the integrated OTP address width (address in words). The supported sizes are 6
+(for 2 Kbits),7,8,9,11 (for 64 Kbits). The default value in the provided RTL will be 6.<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">OTP_ADDR_WIDTH_DEF</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.11.1"></a>3:0
+      </td>
+      <td valign="top">OTP_ADDR_WIDTH_DEF</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x</td>
+      <td valign="top">Holds the OTP_ADDR_WIDTH_DEF value.</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.16.11.2"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Reserved</td>
+   </tr>
+</table><a href="#1.16">(top of block)</a><a name="1.17"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.17 : Block: ENV_CC_MEMORIES</font></b></td>
+   <td align="right"><font color="#000000">0x060004000</font></td>
+</table><br><a name="1.17.1"></a><br>1.17.1 : <b>Reg : ENV_FUSE_READY</b> : 0x060004000<br><b>reg sep address</b> : <b> reg host address</b> : <br>keep FUSE ready de-asserted (used in Discretix internal DSM tests only)<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FUSE_READY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.17.1.1"></a>0:0
+      </td>
+      <td valign="top">FUSE_READY</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'0 - FUSE ready kept low , 1'1 - FUSE ready released</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.17.1.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">31'b0</td>
+   </tr>
+</table><a name="1.17.2"></a><br>1.17.2 : <b>Reg : ENV_PERF_RAM_MASTER</b> : 0x0600040EC<br><b>reg sep address</b> : <b> reg host address</b> : <br>selects who's the Performance RAM master<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_PERF_RAM_MASTER</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.17.2.1"></a>0:0
+      </td>
+      <td valign="top">PERF_RAM_MASTER</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b0 - sw_monitor_sni0er, 1'b1 - HOST</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.17.2.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">selects who's the Performance RAM master</td>
+   </tr>
+</table><a name="1.17.3"></a><br>1.17.3 : <b>Reg : ENV_PERF_RAM_ADDR_HIGH4</b> : 0x0600040F0<br><b>reg sep address</b> : <b> reg host address</b> : <br>4 bits to concat with ENV_PERF_RAM_BASE[11]<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_PERF_RAM_ADDR_HIGH4</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.17.3.1"></a>1:0
+      </td>
+      <td valign="top">ADDR_HIGH_4</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">4 bits to concatenate: perf ram address = {ENV_PERF_RAM_ADDR_HIGH[3:0] ENV_PERF_RAM_BASE[11:2]}</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.17.3.2"></a>31:2
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">4 bits to concat with ENV_PERF_RAM_BASE[11</td>
+   </tr>
+</table><a name="1.17.4"></a><br>1.17.4 : <b>Reg : ENV_FUSES_RAM</b> : 0x0600043EC<br><b>reg sep address</b> : <b> reg host address</b> : <br>Using this address the HOST gains access to the aib_slave_model (fuses). (Actually there are 256 words hidden here.)<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FUSES_RAM</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.17.4.1"></a>31:0
+      </td>
+      <td valign="top">FUSE_VAL</td>
+      <td valign="top" align="center">r/wc</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Fuse value</td>
+   </tr>
+</table><a href="#1.17">(top of block)</a><a name="1.18"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.18 : Block: FPGA_ENV_REGS</font></b></td>
+   <td align="right"><font color="#000000">0x060005000</font></td>
+</table><br><a name="1.18.1"></a><br>1.18.1 : <b>Reg : ENV_FPGA_PKA_DEBUG_MODE</b> : 0x060005024<br><b>reg sep address</b> : <b> reg host address</b> : <br>Drive PKA debug mode <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_PKA_DEBUG_MODE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.1.1"></a>0:0
+      </td>
+      <td valign="top">PKA_DEBUG_MODE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - PKA in debug mode</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.1.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">0</td>
+   </tr>
+</table><a name="1.18.2"></a><br>1.18.2 : <b>Reg : ENV_FPGA_SCAN_MODE</b> : 0x060005030<br><b>reg sep address</b> : <b> reg host address</b> : <br>CryptoCell scan_mode input<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SCAN_MODE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.2.1"></a>0:0
+      </td>
+      <td valign="top">SCAN_MODE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">when Scan mode is set RKEKs are reset</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.2.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">0</td>
+   </tr>
+</table><a name="1.18.3"></a><br>1.18.3 : <b>Reg : ENV_FPGA_CC_ALLOW_SCAN</b> : 0x060005034<br><b>reg sep address</b> : <b> reg host address</b> : <br>CryptoCell allow_scan output<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_ALLOW_SCAN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.3.1"></a>0:0
+      </td>
+      <td valign="top">CC_ALLOW_SCAN</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">When low scan can not be performed. Reset value is: 1'b1</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.3.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">0</td>
+   </tr>
+</table><a name="1.18.4"></a><br>1.18.4 : <b>Reg : ENV_FPGA_CC_HOST_INT</b> : 0x0600050A0<br><b>reg sep address</b> : <b> reg host address</b> : <br>CryptoCell interrupt value<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_HOST_INT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.4.1"></a>0:0
+      </td>
+      <td valign="top">CC_HOST_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">CryptoCell interrupt to Host Active High</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.4.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">0</td>
+   </tr>
+</table><a name="1.18.5"></a><br>1.18.5 : <b>Reg : ENV_FPGA_CC_PUB_HOST_INT</b> : 0x0600050A4<br><b>reg sep address</b> : <b> reg host address</b> : <br>CryptoCell public host interrupt value<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_PUB_HOST_INT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.5.1"></a>0:0
+      </td>
+      <td valign="top">CC_PUB_HOST_INT</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">CryptoCell interrupt to public Host Active High</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.5.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">0</td>
+   </tr>
+</table><a name="1.18.6"></a><br>1.18.6 : <b>Reg : ENV_FPGA_CC_RST_N</b> : 0x0600050A8<br><b>reg sep address</b> : <b> reg host address</b> : <br>generate reset cycle towards CryptoCell<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_RST_N</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.6.1"></a>0:0
+      </td>
+      <td valign="top">CC_RST_N</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - generate reset cycle towards CryptoCell</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.6.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">generate reset cycle towards CryptoCell</td>
+   </tr>
+</table><a name="1.18.7"></a><br>1.18.7 : <b>Reg : ENV_FPGA_RST_OVERRIDE</b> : 0x0600050AC<br><b>reg sep address</b> : <b> reg host address</b> : <br>Force high all reset lines in CryptoCell<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_RST_OVERRIDE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.7.1"></a>0:0
+      </td>
+      <td valign="top">RST_OVERRIDE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - doesn't permit SW_RST or SYS_RST to CryptoCell or any engine</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.7.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Force high all reset lines in CryptoCell<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.
+      </td>
+   </tr>
+</table><a name="1.18.8"></a><br>1.18.8 : <b>Reg : ENV_FPGA_CC_POR_N_ADDR</b> : 0x0600050E0<br><b>reg sep address</b> : <b> reg host address</b> : <br>CryptoCell power ON <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_POR_N_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.8.1"></a>0:0
+      </td>
+      <td valign="top">CC_POR_N_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x1</td>
+      <td valign="top">Active low. When asserted indicates that the entire system is powered on and not only the CryptoCell. If there's no potential
+         powering down of the CryptoCell in the SoC this input must be connected to the SYS_RST_n input
+      </td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.8.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">CryptoCell power ON</td>
+   </tr>
+</table><a name="1.18.9"></a><br>1.18.9 : <b>Reg : ENV_FPGA_CC_COLD_RST</b> : 0x0600050FC<br><b>reg sep address</b> : <b> reg host address</b> : <br>CryptoCell cold reset<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_COLD_RST</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.9.1"></a>0:0
+      </td>
+      <td valign="top">ENV_CC_COLD_RST</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">CryptoCell cold reset assertion</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.9.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">CryptoCell cold reset</td>
+   </tr>
+</table><a name="1.18.10"></a><br>1.18.10 : <b>Reg : ENV_FPGA_DUMMY_ADDR</b> : 0x060005108<br><b>reg sep address</b> : <b> reg host address</b> : <br>dummy environment register <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_DUMMY_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.10.1"></a>31:0
+      </td>
+      <td valign="top">ENV_DUMMY_ADDR</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">0</td>
+   </tr>
+</table><a name="1.18.11"></a><br>1.18.11 : <b>Reg : ENV_FPGA_COUNTER_CLR</b> : 0x060005118<br><b>reg sep address</b> : <b> reg host address</b> : <br>clear and start the SW counter<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_COUNTER_CLR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.11.1"></a>0:0
+      </td>
+      <td valign="top">COUNTER_CLR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - clear/start counter</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.11.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">clear and start the SW counter</td>
+   </tr>
+</table><a name="1.18.12"></a><br>1.18.12 : <b>Reg : ENV_FPGA_COUNTER_RD</b> : 0x06000511C<br><b>reg sep address</b> : <b> reg host address</b> : <br>clear and start the SW counter<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_COUNTER_RD</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.12.1"></a>31:0
+      </td>
+      <td valign="top">COUNTER_VAL</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SW counter value</td>
+   </tr>
+</table><a name="1.18.13"></a><br>1.18.13 : <b>Reg : ENV_FPGA_RNG_DEBUG_ENABLE</b> : 0x060005430<br><b>reg sep address</b> : <b> reg host address</b> : <br>set RNG debug port<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_RNG_DEBUG_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.13.1"></a>0:0
+      </td>
+      <td valign="top">DEBUG_EN</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - RNG debug port asserted</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.13.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">31'b0</td>
+   </tr>
+</table><a name="1.18.14"></a><br>1.18.14 : <b>Reg : ENV_FPGA_CC_LCS</b> : 0x06000543C<br><b>reg sep address</b> : <b> reg host address</b> : <br>LCS register value<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_LCS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.14.1"></a>7:0
+      </td>
+      <td valign="top">LCS</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">LCS data</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.14.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">24'b0</td>
+   </tr>
+</table><a name="1.18.15"></a><br>1.18.15 : <b>Reg : ENV_FPGA_CC_IS_CM_DM_SECURE_RMA</b> : 0x060005440<br><b>reg sep address</b> : <b> reg host address</b> : <br>read the lcs states if it is CM DM SECURED or RMA<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_IS_CM_DM_SECURE_RMA</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.15.1"></a>0:0
+      </td>
+      <td valign="top">IS_CM</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - lcs state is CM 1'b0 - not</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.15.2"></a>1:1
+      </td>
+      <td valign="top">IS_DM</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - lcs state is DM 1'b0 - not</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.15.3"></a>2:2
+      </td>
+      <td valign="top">IS_SECURE</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - lcs state is SECURE 1'b0 - not</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.15.4"></a>3:3
+      </td>
+      <td valign="top">IS_RMA</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">1'b1 - lcs state is RMA 1'b0 - not</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.15.5"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">28'b0</td>
+   </tr>
+</table><a name="1.18.16"></a><br>1.18.16 : <b>Reg : ENV_FPGA_DCU_EN</b> : 0x060005444<br><b>reg sep address</b> : <b> reg host address</b> : <br>read the lcs states if it is CM DM SECURED or RMA <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_DCU_EN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.16.1"></a>31:0
+      </td>
+      <td valign="top">DCU_EN</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Every bit in this sets of bits sets the matching dcu_en signal to a single dcu.</td>
+   </tr>
+</table><a name="1.18.17"></a><br>1.18.17 : <b>Reg : ENV_FPGA_CC_LCS_IS_VALID</b> : 0x060005448<br><b>reg sep address</b> : <b> reg host address</b> : <br>boot process finished reading LCS from NVM and write it to LCS register<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_CC_LCS_IS_VALID</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.17.1"></a>0:0
+      </td>
+      <td valign="top">LCS_IS_VALID</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">LCS data is valid</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.17.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">31'b0</td>
+   </tr>
+</table><a name="1.18.18"></a><br>1.18.18 : <b>Reg : ENV_FPGA_POWER_DOWN</b> : 0x060005478<br><b>reg sep address</b> : <b> reg host address</b> : <br>ENV_POWER_DOWN change bus to X's in DX simulations ONLY !<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_POWER_DOWN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.18.1"></a>31:0
+      </td>
+      <td valign="top">ENV_POWER_DOWN</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">write pulse of power down indication. Used for Internal DX simulations ONLY !</td>
+   </tr>
+</table><a name="1.18.19"></a><br>1.18.19 : <b>Reg : ENV_FPGA_DCU_H_EN</b> : 0x060005484<br><b>reg sep address</b> : <b> reg host address</b> : <br>read the lcs states if it is CM DM SECURED or RMA <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_DCU_H_EN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.19.1"></a>31:0
+      </td>
+      <td valign="top">DCU_EN</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Every bit in this sets of bits sets the matching dcu_en signal to a single dcu.</td>
+   </tr>
+</table><a name="1.18.20"></a><br>1.18.20 : <b>Reg : ENV_FPGA_VERSION</b> : 0x060005488<br><b>reg sep address</b> : <b> reg host address</b> : <br>version of FPGA <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_VERSION</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.20.1"></a>31:0
+      </td>
+      <td valign="top">FPGA_VERSION</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Define the FPGA version.</td>
+   </tr>
+</table><a name="1.18.21"></a><br>1.18.21 : <b>Reg : ENV_FPGA_ROSC_WRITE</b> : 0x06000548C<br><b>reg sep address</b> : <b> reg host address</b> : <br>ROSC write select<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_ROSC_WRITE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.21.1"></a>0:0
+      </td>
+      <td valign="top">ROSC_PSEL</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">rosc psel</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.21.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">31'b0</td>
+   </tr>
+</table><a name="1.18.22"></a><br>1.18.22 : <b>Reg : ENV_FPGA_ROSC_ADDR</b> : 0x060005490<br><b>reg sep address</b> : <b> reg host address</b> : <br>ROSC ADDRRESS<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_ROSC_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.22.1"></a>7:0
+      </td>
+      <td valign="top">ROSC_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">rosc address</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.22.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">24'b0</td>
+   </tr>
+</table><a name="1.18.23"></a><br>1.18.23 : <b>Reg : ENV_FPGA_RESET_SESSION_KEY</b> : 0x060005494<br><b>reg sep address</b> : <b> reg host address</b> : <br>Reset the session key<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_RESET_SESSION_KEY</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.23.1"></a>0:0
+      </td>
+      <td valign="top">RESET_SESSION_KEY</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">async reset for the session key - (fpga env only)</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.23.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">31'b0</td>
+   </tr>
+</table><a name="1.18.24"></a><br>1.18.24 : <b>Reg : ENV_FPGA_SESSION_KEY_0</b> : 0x0600054A0<br><b>reg sep address</b> : <b> reg host address</b> : <br>Session key 0<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SESSION_KEY_0</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.24.1"></a>31:0
+      </td>
+      <td valign="top">SESSION_KEY_0</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Session key 0</td>
+   </tr>
+</table><a name="1.18.25"></a><br>1.18.25 : <b>Reg : ENV_FPGA_SESSION_KEY_1</b> : 0x0600054A4<br><b>reg sep address</b> : <b> reg host address</b> : <br>Session key 0<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SESSION_KEY_1</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.25.1"></a>31:0
+      </td>
+      <td valign="top">SESSION_KEY_1</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Session key 1</td>
+   </tr>
+</table><a name="1.18.26"></a><br>1.18.26 : <b>Reg : ENV_FPGA_SESSION_KEY_2</b> : 0x0600054A8<br><b>reg sep address</b> : <b> reg host address</b> : <br>Session key 1<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SESSION_KEY_2</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.26.1"></a>31:0
+      </td>
+      <td valign="top">SESSION_KEY_2</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Session key 2</td>
+   </tr>
+</table><a name="1.18.27"></a><br>1.18.27 : <b>Reg : ENV_FPGA_SESSION_KEY_3</b> : 0x0600054AC<br><b>reg sep address</b> : <b> reg host address</b> : <br>Session key 1<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SESSION_KEY_3</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.27.1"></a>31:0
+      </td>
+      <td valign="top">SESSION_KEY_3</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Session key 3</td>
+   </tr>
+</table><a name="1.18.28"></a><br>1.18.28 : <b>Reg : ENV_FPGA_SESSION_KEY_VALID</b> : 0x0600054B0<br><b>reg sep address</b> : <b> reg host address</b> : <br>Session key valid<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SESSION_KEY_VALID</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.28.1"></a>0:0
+      </td>
+      <td valign="top">SESSION_KEY_VALID</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Session key valid</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.28.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.29"></a><br>1.18.29 : <b>Reg : ENV_FPGA_SPIDEN</b> : 0x0600054D0<br><b>reg sep address</b> : <b> reg host address</b> : <br>spiden override<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SPIDEN</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.29.1"></a>0:0
+      </td>
+      <td valign="top">SPIDEN</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">spiden value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.29.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.30"></a><br>1.18.30 : <b>Reg : ENV_FPGA_AXIM_USER_PARAMS</b> : 0x060005600<br><b>reg sep address</b> : <b> reg host address</b> : <br>axim master cache coherency configuration override<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_AXIM_USER_PARAMS</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.30.1"></a>4:0
+      </td>
+      <td valign="top">ARUSER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">aruser override value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.30.2"></a>9:5
+      </td>
+      <td valign="top">AWUSER</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">awuser override value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.30.3"></a>31:10
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.31"></a><br>1.18.31 : <b>Reg : ENV_FPGA_SECURITY_MODE_OVERRIDE</b> : 0x060005604<br><b>reg sep address</b> : <b> reg host address</b> : <br>axim master prot override <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SECURITY_MODE_OVERRIDE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.31.1"></a>0:0
+      </td>
+      <td valign="top">AWPROT_NS_BIT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AWPROT override value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.31.2"></a>1:1
+      </td>
+      <td valign="top">AWPROT_NS_OVERRIDE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AWPROT override enable</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.31.3"></a>2:2
+      </td>
+      <td valign="top">ARPROT_NS_BIT</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">ARPROT override value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.31.4"></a>3:3
+      </td>
+      <td valign="top">ARPROT_NS_OVERRIDE</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">ARPROT override enable</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.31.5"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.32"></a><br>1.18.32 : <b>Reg : ENV_FPGA_SRAM_ENABLE</b> : 0x060005608<br><b>reg sep address</b> : <b> reg host address</b> : <br>SRAM enable<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_SRAM_ENABLE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.32.1"></a>0:0
+      </td>
+      <td valign="top">SRAM_ENABLE</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">sram enable bit</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.32.2"></a>31:1
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.33"></a><br>1.18.33 : <b>Reg : ENV_FPGA_APB_FIPS_ADDR</b> : 0x060005650<br><b>reg sep address</b> : <b> reg host address</b> : <br>the secure host register offset for fips access match<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APB_FIPS_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.33.1"></a>11:0
+      </td>
+      <td valign="top">FIPS_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SECURE HOST FIPS register offset</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.33.2"></a>31:12
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.34"></a><br>1.18.34 : <b>Reg : ENV_FPGA_APB_FIPS_VAL</b> : 0x060005654<br><b>reg sep address</b> : <b> reg host address</b> : <br>the secure host write data  for fips access match<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APB_FIPS_VAL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.34.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_DATA</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SECURE HOST FIPS  data</td>
+   </tr>
+</table><a name="1.18.35"></a><br>1.18.35 : <b>Reg : ENV_FPGA_APB_FIPS_MASK</b> : 0x060005658<br><b>reg sep address</b> : <b> reg host address</b> : <br>the secure host write data  mask for fips access match<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APB_FIPS_MASK</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.35.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_MASK</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SECURE HOST FIPS  data mask</td>
+   </tr>
+</table><a name="1.18.36"></a><br>1.18.36 : <b>Reg : ENV_FPGA_APB_FIPS_CNT</b> : 0x06000565C<br><b>reg sep address</b> : <b> reg host address</b> : <br>the secure host fips access counter thershold <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APB_FIPS_CNT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.36.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_CNT</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SECURE HOST FIPS  CNT</td>
+   </tr>
+</table><a name="1.18.37"></a><br>1.18.37 : <b>Reg : ENV_FPGA_APB_FIPS_NEW_ADDR</b> : 0x060005660<br><b>reg sep address</b> : <b> reg host address</b> : <br>the secure host register offset of the new register after FIPS cnt reached<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APB_FIPS_NEW_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.37.1"></a>11:0
+      </td>
+      <td valign="top">FIPS_NEW_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SECURE HOST FIPS NEW register offset</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.37.2"></a>31:12
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.38"></a><br>1.18.38 : <b>Reg : ENV_FPGA_APB_FIPS_NEW_VAL</b> : 0x060005664<br><b>reg sep address</b> : <b> reg host address</b> : <br>the secure host new write data after fips cnt reached<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APB_FIPS_NEW_VAL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.38.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_DATA</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">SECURE HOST FIPS NEW  data</td>
+   </tr>
+</table><a name="1.18.39"></a><br>1.18.39 : <b>Reg : ENV_FPGA_APB_PPROT_OVERRIDE</b> : 0x060005668<br><b>reg sep address</b> : <b> reg host address</b> : <br>apbs  pprot override <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APB_PPROT_OVERRIDE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.39.1"></a>2:0
+      </td>
+      <td valign="top">PPROT_OVERRIDE_VAL</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PPROT override value</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.39.2"></a>3:3
+      </td>
+      <td valign="top">PPROT_OVERRIDE_CNTL</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PPROT override control ;1 = ovveride</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.39.3"></a>31:4
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">rw</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">ARPROT override value</td>
+   </tr>
+</table><a name="1.18.40"></a><br>1.18.40 : <b>Reg : ENV_FPGA_APBP_FIPS_ADDR</b> : 0x060005670<br><b>reg sep address</b> : <b> reg host address</b> : <br>the public host register offset for fips access match<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APBP_FIPS_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.40.1"></a>11:0
+      </td>
+      <td valign="top">FIPS_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PUBLIC HOST FIPS register offset</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.40.2"></a>31:12
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.41"></a><br>1.18.41 : <b>Reg : ENV_FPGA_APBP_FIPS_VAL</b> : 0x060005674<br><b>reg sep address</b> : <b> reg host address</b> : <br>the public host write data  for fips access match<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APBP_FIPS_VAL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.41.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_DATA</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PUBLIC HOST FIPS  data</td>
+   </tr>
+</table><a name="1.18.42"></a><br>1.18.42 : <b>Reg : ENV_FPGA_APBP_FIPS_MASK</b> : 0x060005678<br><b>reg sep address</b> : <b> reg host address</b> : <br>the public host write data  mask for fips access match<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APBP_FIPS_MASK</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.42.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_MASK</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PUBLIC HOST FIPS  data mask</td>
+   </tr>
+</table><a name="1.18.43"></a><br>1.18.43 : <b>Reg : ENV_FPGA_APBP_FIPS_CNT</b> : 0x06000567C<br><b>reg sep address</b> : <b> reg host address</b> : <br>the public host fips access counter thershold <br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APBP_FIPS_CNT</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.43.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_CNT</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PUBLIC HOST FIPS  CNT</td>
+   </tr>
+</table><a name="1.18.44"></a><br>1.18.44 : <b>Reg : ENV_FPGA_APBP_FIPS_NEW_ADDR</b> : 0x060005680<br><b>reg sep address</b> : <b> reg host address</b> : <br>the public host register offset of the new register after FIPS cnt reached<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APBP_FIPS_NEW_ADDR</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.44.1"></a>11:0
+      </td>
+      <td valign="top">FIPS_NEW_ADDR</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PUBLIC HOST FIPS NEW register offset</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.44.2"></a>31:12
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a name="1.18.45"></a><br>1.18.45 : <b>Reg : ENV_FPGA_APBP_FIPS_NEW_VAL</b> : 0x060005684<br><b>reg sep address</b> : <b> reg host address</b> : <br>the public host new write data after fips cnt reached<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_APBP_FIPS_NEW_VAL</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.45.1"></a>31:0
+      </td>
+      <td valign="top">FIPS_DATA</td>
+      <td valign="top" align="center">wo</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">PUBLIC HOST FIPS NEW  data</td>
+   </tr>
+</table><a name="1.18.46"></a><br>1.18.46 : <b>Reg : ENV_FPGA_AO_CC_GPPC</b> : 0x060005700<br><b>reg sep address</b> : <b> reg host address</b> : <br>holds the AO_CC_GPPC value from AO<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_FPGA_AO_CC_GPPC</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.46.1"></a>7:0
+      </td>
+      <td valign="top">AO_CC_GPPC</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">AO_CC_GPPC</td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.18.46.2"></a>31:8
+      </td>
+      <td valign="top">RESERVED</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">reserved</td>
+   </tr>
+</table><a href="#1.18">(top of block)</a><a name="1.19"></a><br><table frame="border" width="95%" BORDERCOLOR="#993333">
+   <td><b><font color="#000000">1.19 : Block: ENV_PERF_RAM_BASE</font></b></td>
+   <td align="right"><font color="#000000">0x060006000</font></td>
+</table><br><a name="1.19.1"></a><br>1.19.1 : <b>Reg : ENV_PERF_RAM_BASE</b> : 0x060006000<br><b>reg sep address</b> : <b> reg host address</b> : <br>Performance RAM base address Data read from performance RAM<br>Note: This is a special register, affected by internal logic. Test result of this register is NA.<br><table border="1" bgcolor="#EEEEEE" width="800">
+   <tr>
+      <td colspan="32" align="center">ENV_PERF_RAM_BASE</td>
+   </tr>
+   <tr></tr>
+</table>
+<table border="1" width="800">
+   <tr>
+      <td width="40"><b>bits</b></td>
+      <td width="100"><b>Field name</b></td>
+      <td width="20"><b>permission</b></td>
+      <td width="40"><b>default</b></td>
+      <td width="600"><b>Description</b></td>
+   </tr>
+   <tr>
+      <td valign="top" align="center"><a name="1.19.1.1"></a>31:0
+      </td>
+      <td valign="top">PERF_RAM_D</td>
+      <td valign="top" align="center">ro</td>
+      <td valign="top" align="center">0x0</td>
+      <td valign="top">Data read from performance RAM</td>
+   </tr>
+</table><a href="#1.19">(top of block)</a><br><a href="#1">(top of chip)</a><hr WIDTH="100%" SIZE="3" NOSHADE="1">***** Copyright 2012 All Rights Reserved. *****
\ No newline at end of file
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_crys_kernel.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_crys_kernel.h
new file mode 100644
index 0000000..9a12875
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_crys_kernel.h
@@ -0,0 +1,853 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_CRYS_KERNEL_H__
+#define __DX_CRYS_KERNEL_H__
+// --------------------------------------
+// BLOCK: AES
+// --------------------------------------
+#define DX_AES_KEY_0_0_REG_OFFSET   0x0400UL
+#define DX_AES_KEY_0_0_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_0_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_0_1_REG_OFFSET   0x0404UL
+#define DX_AES_KEY_0_1_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_1_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_0_2_REG_OFFSET   0x0408UL
+#define DX_AES_KEY_0_2_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_2_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_0_3_REG_OFFSET   0x040CUL
+#define DX_AES_KEY_0_3_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_3_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_0_4_REG_OFFSET   0x0410UL
+#define DX_AES_KEY_0_4_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_4_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_0_5_REG_OFFSET   0x0414UL
+#define DX_AES_KEY_0_5_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_5_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_0_6_REG_OFFSET   0x0418UL
+#define DX_AES_KEY_0_6_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_6_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_0_7_REG_OFFSET   0x041CUL
+#define DX_AES_KEY_0_7_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_0_7_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_0_REG_OFFSET   0x0420UL
+#define DX_AES_KEY_1_0_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_0_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_1_REG_OFFSET   0x0424UL
+#define DX_AES_KEY_1_1_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_1_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_2_REG_OFFSET   0x0428UL
+#define DX_AES_KEY_1_2_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_2_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_3_REG_OFFSET   0x042CUL
+#define DX_AES_KEY_1_3_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_3_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_4_REG_OFFSET   0x0430UL
+#define DX_AES_KEY_1_4_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_4_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_5_REG_OFFSET   0x0434UL
+#define DX_AES_KEY_1_5_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_5_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_6_REG_OFFSET   0x0438UL
+#define DX_AES_KEY_1_6_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_6_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_KEY_1_7_REG_OFFSET   0x043CUL
+#define DX_AES_KEY_1_7_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_KEY_1_7_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_IV_0_0_REG_OFFSET    0x0440UL
+#define DX_AES_IV_0_0_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_0_0_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_IV_0_1_REG_OFFSET    0x0444UL
+#define DX_AES_IV_0_1_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_0_1_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_IV_0_2_REG_OFFSET    0x0448UL
+#define DX_AES_IV_0_2_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_0_2_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_IV_0_3_REG_OFFSET    0x044CUL
+#define DX_AES_IV_0_3_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_0_3_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_IV_1_0_REG_OFFSET    0x0450UL
+#define DX_AES_IV_1_0_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_1_0_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_IV_1_1_REG_OFFSET    0x0454UL
+#define DX_AES_IV_1_1_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_1_1_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_IV_1_2_REG_OFFSET    0x0458UL
+#define DX_AES_IV_1_2_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_1_2_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_IV_1_3_REG_OFFSET    0x045CUL
+#define DX_AES_IV_1_3_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_IV_1_3_VALUE_BIT_SIZE    0x20UL
+#define DX_AES_CTR_0_0_REG_OFFSET   0x0460UL
+#define DX_AES_CTR_0_0_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_CTR_0_0_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_CTR_0_1_REG_OFFSET   0x0464UL
+#define DX_AES_CTR_0_1_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_CTR_0_1_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_CTR_0_2_REG_OFFSET   0x0468UL
+#define DX_AES_CTR_0_2_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_CTR_0_2_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_CTR_0_3_REG_OFFSET   0x046CUL
+#define DX_AES_CTR_0_3_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_CTR_0_3_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_BUSY_REG_OFFSET  0x0470UL
+#define DX_AES_BUSY_VALUE_BIT_SHIFT     0x0UL
+#define DX_AES_BUSY_VALUE_BIT_SIZE  0x1UL
+#define DX_AES_SK_REG_OFFSET    0x0478UL
+#define DX_AES_SK_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_SK_VALUE_BIT_SIZE    0x1UL
+#define DX_AES_CMAC_INIT_REG_OFFSET     0x047CUL
+#define DX_AES_CMAC_INIT_VALUE_BIT_SHIFT    0x0UL
+#define DX_AES_CMAC_INIT_VALUE_BIT_SIZE     0x1UL
+#define DX_AES_SK1_REG_OFFSET   0x04B4UL
+#define DX_AES_SK1_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_SK1_VALUE_BIT_SIZE   0x1UL
+#define DX_AES_REMAINING_BYTES_REG_OFFSET   0x04BCUL
+#define DX_AES_REMAINING_BYTES_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_REMAINING_BYTES_VALUE_BIT_SIZE   0x20UL
+#define DX_AES_CONTROL_REG_OFFSET   0x04C0UL
+#define DX_AES_CONTROL_DEC_KEY0_BIT_SHIFT   0x0UL
+#define DX_AES_CONTROL_DEC_KEY0_BIT_SIZE    0x1UL
+#define DX_AES_CONTROL_MODE0_IS_CBC_CTS_BIT_SHIFT   0x1UL
+#define DX_AES_CONTROL_MODE0_IS_CBC_CTS_BIT_SIZE    0x1UL
+#define DX_AES_CONTROL_MODE_KEY0_BIT_SHIFT  0x2UL
+#define DX_AES_CONTROL_MODE_KEY0_BIT_SIZE   0x3UL
+#define DX_AES_CONTROL_MODE_KEY1_BIT_SHIFT  0x5UL
+#define DX_AES_CONTROL_MODE_KEY1_BIT_SIZE   0x3UL
+#define DX_AES_CONTROL_CBC_IS_ESSIV_BIT_SHIFT   0x8UL
+#define DX_AES_CONTROL_CBC_IS_ESSIV_BIT_SIZE    0x1UL
+#define DX_AES_CONTROL_AES_TUNNEL_IS_ON_BIT_SHIFT   0xAUL
+#define DX_AES_CONTROL_AES_TUNNEL_IS_ON_BIT_SIZE    0x1UL
+#define DX_AES_CONTROL_CBC_IS_BITLOCKER_BIT_SHIFT   0xBUL
+#define DX_AES_CONTROL_CBC_IS_BITLOCKER_BIT_SIZE    0x1UL
+#define DX_AES_CONTROL_NK_KEY0_BIT_SHIFT    0xCUL
+#define DX_AES_CONTROL_NK_KEY0_BIT_SIZE     0x2UL
+#define DX_AES_CONTROL_NK_KEY1_BIT_SHIFT    0xEUL
+#define DX_AES_CONTROL_NK_KEY1_BIT_SIZE     0x2UL
+#define DX_AES_CONTROL_AES_TUNNEL1_DECRYPT_BIT_SHIFT    0x16UL
+#define DX_AES_CONTROL_AES_TUNNEL1_DECRYPT_BIT_SIZE     0x1UL
+#define DX_AES_CONTROL_AES_TUN_B1_USES_PADDED_DATA_IN_BIT_SHIFT     0x17UL
+#define DX_AES_CONTROL_AES_TUN_B1_USES_PADDED_DATA_IN_BIT_SIZE  0x1UL
+#define DX_AES_CONTROL_AES_TUNNEL0_ENCRYPT_BIT_SHIFT    0x18UL
+#define DX_AES_CONTROL_AES_TUNNEL0_ENCRYPT_BIT_SIZE     0x1UL
+#define DX_AES_CONTROL_AES_OUTPUT_MID_TUNNEL_DATA_BIT_SHIFT     0x19UL
+#define DX_AES_CONTROL_AES_OUTPUT_MID_TUNNEL_DATA_BIT_SIZE  0x1UL
+#define DX_AES_CONTROL_AES_TUNNEL_B1_PAD_EN_BIT_SHIFT   0x1AUL
+#define DX_AES_CONTROL_AES_TUNNEL_B1_PAD_EN_BIT_SIZE    0x1UL
+#define DX_AES_CONTROL_AES_OUT_MID_TUN_TO_HASH_BIT_SHIFT    0x1CUL
+#define DX_AES_CONTROL_AES_OUT_MID_TUN_TO_HASH_BIT_SIZE     0x1UL
+#define DX_AES_CONTROL_AES_XOR_CRYPTOKEY_BIT_SHIFT  0x1DUL
+#define DX_AES_CONTROL_AES_XOR_CRYPTOKEY_BIT_SIZE   0x1UL
+#define DX_AES_CONTROL_DIRECT_ACCESS_BIT_SHIFT  0x1FUL
+#define DX_AES_CONTROL_DIRECT_ACCESS_BIT_SIZE   0x1UL
+#define DX_AES_HW_FLAGS_REG_OFFSET  0x04C8UL
+#define DX_AES_HW_FLAGS_SUPPORT_256_192_KEY_BIT_SHIFT   0x0UL
+#define DX_AES_HW_FLAGS_SUPPORT_256_192_KEY_BIT_SIZE    0x1UL
+#define DX_AES_HW_FLAGS_AES_LARGE_RKEK_BIT_SHIFT    0x1UL
+#define DX_AES_HW_FLAGS_AES_LARGE_RKEK_BIT_SIZE     0x1UL
+#define DX_AES_HW_FLAGS_DPA_CNTRMSR_EXIST_BIT_SHIFT     0x2UL
+#define DX_AES_HW_FLAGS_DPA_CNTRMSR_EXIST_BIT_SIZE  0x1UL
+#define DX_AES_HW_FLAGS_CTR_EXIST_BIT_SHIFT     0x3UL
+#define DX_AES_HW_FLAGS_CTR_EXIST_BIT_SIZE  0x1UL
+#define DX_AES_HW_FLAGS_ONLY_ENCRYPT_BIT_SHIFT  0x4UL
+#define DX_AES_HW_FLAGS_ONLY_ENCRYPT_BIT_SIZE   0x1UL
+#define DX_AES_HW_FLAGS_USE_SBOX_TABLE_BIT_SHIFT    0x5UL
+#define DX_AES_HW_FLAGS_USE_SBOX_TABLE_BIT_SIZE     0x1UL
+#define DX_AES_HW_FLAGS_USE_5_SBOXES_BIT_SHIFT  0x8UL
+#define DX_AES_HW_FLAGS_USE_5_SBOXES_BIT_SIZE   0x1UL
+#define DX_AES_HW_FLAGS_AES_SUPPORT_PREV_IV_BIT_SHIFT   0x9UL
+#define DX_AES_HW_FLAGS_AES_SUPPORT_PREV_IV_BIT_SIZE    0x1UL
+#define DX_AES_HW_FLAGS_AES_TUNNEL_EXISTS_BIT_SHIFT     0xAUL
+#define DX_AES_HW_FLAGS_AES_TUNNEL_EXISTS_BIT_SIZE  0x1UL
+#define DX_AES_HW_FLAGS_SECOND_REGS_SET_EXIST_BIT_SHIFT     0xBUL
+#define DX_AES_HW_FLAGS_SECOND_REGS_SET_EXIST_BIT_SIZE  0x1UL
+#define DX_AES_HW_FLAGS_DFA_CNTRMSR_EXIST_BIT_SHIFT     0xCUL
+#define DX_AES_HW_FLAGS_DFA_CNTRMSR_EXIST_BIT_SIZE  0x1UL
+#define DX_AES_CTR_NO_INCREMENT_REG_OFFSET  0x04D8UL
+#define DX_AES_CTR_NO_INCREMENT_VALUE_BIT_SHIFT     0x0UL
+#define DX_AES_CTR_NO_INCREMENT_VALUE_BIT_SIZE  0x1UL
+#define DX_AES_DFA_IS_ON_REG_OFFSET     0x04F0UL
+#define DX_AES_DFA_IS_ON_VALUE_BIT_SHIFT    0x0UL
+#define DX_AES_DFA_IS_ON_VALUE_BIT_SIZE     0x1UL
+#define DX_AES_DFA_ERR_STATUS_REG_OFFSET    0x04F8UL
+#define DX_AES_DFA_ERR_STATUS_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_DFA_ERR_STATUS_VALUE_BIT_SIZE    0x1UL
+#define DX_AES_CMAC_SIZE0_KICK_REG_OFFSET   0x0524UL
+#define DX_AES_CMAC_SIZE0_KICK_VALUE_BIT_SHIFT  0x0UL
+#define DX_AES_CMAC_SIZE0_KICK_VALUE_BIT_SIZE   0x1UL
+// --------------------------------------
+// BLOCK: MISC
+// --------------------------------------
+#define DX_AES_CLK_ENABLE_REG_OFFSET    0x0810UL
+#define DX_AES_CLK_ENABLE_VALUE_BIT_SHIFT   0x0UL
+#define DX_AES_CLK_ENABLE_VALUE_BIT_SIZE    0x1UL
+#define DX_HASH_CLK_ENABLE_REG_OFFSET   0x0818UL
+#define DX_HASH_CLK_ENABLE_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_CLK_ENABLE_VALUE_BIT_SIZE   0x1UL
+#define DX_PKA_CLK_ENABLE_REG_OFFSET    0x081CUL
+#define DX_PKA_CLK_ENABLE_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_CLK_ENABLE_VALUE_BIT_SIZE    0x1UL
+#define DX_DMA_CLK_ENABLE_REG_OFFSET    0x0820UL
+#define DX_DMA_CLK_ENABLE_VALUE_BIT_SHIFT   0x0UL
+#define DX_DMA_CLK_ENABLE_VALUE_BIT_SIZE    0x1UL
+#define DX_CLK_STATUS_REG_OFFSET    0x0824UL
+#define DX_CLK_STATUS_AES_CLK_STATUS_BIT_SHIFT  0x0UL
+#define DX_CLK_STATUS_AES_CLK_STATUS_BIT_SIZE   0x1UL
+#define DX_CLK_STATUS_HASH_CLK_STATUS_BIT_SHIFT     0x2UL
+#define DX_CLK_STATUS_HASH_CLK_STATUS_BIT_SIZE  0x1UL
+#define DX_CLK_STATUS_PKA_CLK_STATUS_BIT_SHIFT  0x3UL
+#define DX_CLK_STATUS_PKA_CLK_STATUS_BIT_SIZE   0x1UL
+#define DX_CLK_STATUS_CHACHA_CLK_STATUS_BIT_SHIFT   0x7UL
+#define DX_CLK_STATUS_CHACHA_CLK_STATUS_BIT_SIZE    0x1UL
+#define DX_CLK_STATUS_DMA_CLK_STATUS_BIT_SHIFT  0x8UL
+#define DX_CLK_STATUS_DMA_CLK_STATUS_BIT_SIZE   0x1UL
+#define DX_CHACHA_CLK_ENABLE_REG_OFFSET     0x0858UL
+#define DX_CHACHA_CLK_ENABLE_VALUE_BIT_SHIFT    0x0UL
+#define DX_CHACHA_CLK_ENABLE_VALUE_BIT_SIZE     0x1UL
+// --------------------------------------
+// BLOCK: CC_CTL
+// --------------------------------------
+#define DX_CRYPTO_CTL_REG_OFFSET    0x0900UL
+#define DX_CRYPTO_CTL_VALUE_BIT_SHIFT   0x0UL
+#define DX_CRYPTO_CTL_VALUE_BIT_SIZE    0x5UL
+#define DX_CRYPTO_BUSY_REG_OFFSET   0x0910UL
+#define DX_CRYPTO_BUSY_VALUE_BIT_SHIFT  0x0UL
+#define DX_CRYPTO_BUSY_VALUE_BIT_SIZE   0x1UL
+#define DX_HASH_BUSY_REG_OFFSET     0x091CUL
+#define DX_HASH_BUSY_VALUE_BIT_SHIFT    0x0UL
+#define DX_HASH_BUSY_VALUE_BIT_SIZE     0x1UL
+#define DX_CONTEXT_ID_REG_OFFSET    0x0930UL
+#define DX_CONTEXT_ID_VALUE_BIT_SHIFT   0x0UL
+#define DX_CONTEXT_ID_VALUE_BIT_SIZE    0x8UL
+// --------------------------------------
+// BLOCK: DIN
+// --------------------------------------
+#define DX_DIN_BUFFER_REG_OFFSET    0x0C00UL
+#define DX_DIN_BUFFER_VALUE_BIT_SHIFT   0x0UL
+#define DX_DIN_BUFFER_VALUE_BIT_SIZE    0x20UL
+#define DX_DIN_MEM_DMA_BUSY_REG_OFFSET  0x0C20UL
+#define DX_DIN_MEM_DMA_BUSY_VALUE_BIT_SHIFT     0x0UL
+#define DX_DIN_MEM_DMA_BUSY_VALUE_BIT_SIZE  0x1UL
+#define DX_SRC_LLI_WORD0_REG_OFFSET     0x0C28UL
+#define DX_SRC_LLI_WORD0_VALUE_BIT_SHIFT    0x0UL
+#define DX_SRC_LLI_WORD0_VALUE_BIT_SIZE     0x20UL
+#define DX_SRC_LLI_WORD1_REG_OFFSET     0x0C2CUL
+#define DX_SRC_LLI_WORD1_BYTES_NUM_BIT_SHIFT    0x0UL
+#define DX_SRC_LLI_WORD1_BYTES_NUM_BIT_SIZE     0x1EUL
+#define DX_SRC_LLI_WORD1_FIRST_BIT_SHIFT    0x1EUL
+#define DX_SRC_LLI_WORD1_FIRST_BIT_SIZE     0x1UL
+#define DX_SRC_LLI_WORD1_LAST_BIT_SHIFT     0x1FUL
+#define DX_SRC_LLI_WORD1_LAST_BIT_SIZE  0x1UL
+#define DX_SRAM_SRC_ADDR_REG_OFFSET     0x0C30UL
+#define DX_SRAM_SRC_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_SRAM_SRC_ADDR_VALUE_BIT_SIZE     0x20UL
+#define DX_DIN_SRAM_BYTES_LEN_REG_OFFSET    0x0C34UL
+#define DX_DIN_SRAM_BYTES_LEN_VALUE_BIT_SHIFT   0x0UL
+#define DX_DIN_SRAM_BYTES_LEN_VALUE_BIT_SIZE    0x20UL
+#define DX_DIN_SRAM_DMA_BUSY_REG_OFFSET     0x0C38UL
+#define DX_DIN_SRAM_DMA_BUSY_VALUE_BIT_SHIFT    0x0UL
+#define DX_DIN_SRAM_DMA_BUSY_VALUE_BIT_SIZE     0x1UL
+#define DX_DIN_SRAM_ENDIANNESS_REG_OFFSET   0x0C3CUL
+#define DX_DIN_SRAM_ENDIANNESS_VALUE_BIT_SHIFT  0x0UL
+#define DX_DIN_SRAM_ENDIANNESS_VALUE_BIT_SIZE   0x1UL
+#define DX_DIN_CPU_DATA_SIZE_REG_OFFSET     0x0C48UL
+#define DX_DIN_CPU_DATA_SIZE_VALUE_BIT_SHIFT    0x0UL
+#define DX_DIN_CPU_DATA_SIZE_VALUE_BIT_SIZE     0x10UL
+#define DX_FIFO_IN_EMPTY_REG_OFFSET     0x0C50UL
+#define DX_FIFO_IN_EMPTY_VALUE_BIT_SHIFT    0x0UL
+#define DX_FIFO_IN_EMPTY_VALUE_BIT_SIZE     0x1UL
+#define DX_DIN_FIFO_RST_PNTR_REG_OFFSET     0x0C58UL
+#define DX_DIN_FIFO_RST_PNTR_VALUE_BIT_SHIFT    0x0UL
+#define DX_DIN_FIFO_RST_PNTR_VALUE_BIT_SIZE     0x1UL
+// --------------------------------------
+// BLOCK: DOUT
+// --------------------------------------
+#define DX_DOUT_BUFFER_REG_OFFSET   0x0D00UL
+#define DX_DOUT_BUFFER_VALUE_BIT_SHIFT  0x0UL
+#define DX_DOUT_BUFFER_VALUE_BIT_SIZE   0x20UL
+#define DX_DOUT_MEM_DMA_BUSY_REG_OFFSET     0x0D20UL
+#define DX_DOUT_MEM_DMA_BUSY_VALUE_BIT_SHIFT    0x0UL
+#define DX_DOUT_MEM_DMA_BUSY_VALUE_BIT_SIZE     0x1UL
+#define DX_DST_LLI_WORD0_REG_OFFSET     0x0D28UL
+#define DX_DST_LLI_WORD0_VALUE_BIT_SHIFT    0x0UL
+#define DX_DST_LLI_WORD0_VALUE_BIT_SIZE     0x20UL
+#define DX_DST_LLI_WORD1_REG_OFFSET     0x0D2CUL
+#define DX_DST_LLI_WORD1_BYTES_NUM_BIT_SHIFT    0x0UL
+#define DX_DST_LLI_WORD1_BYTES_NUM_BIT_SIZE     0x1EUL
+#define DX_DST_LLI_WORD1_FIRST_BIT_SHIFT    0x1EUL
+#define DX_DST_LLI_WORD1_FIRST_BIT_SIZE     0x1UL
+#define DX_DST_LLI_WORD1_LAST_BIT_SHIFT     0x1FUL
+#define DX_DST_LLI_WORD1_LAST_BIT_SIZE  0x1UL
+#define DX_SRAM_DEST_ADDR_REG_OFFSET    0x0D30UL
+#define DX_SRAM_DEST_ADDR_VALUE_BIT_SHIFT   0x0UL
+#define DX_SRAM_DEST_ADDR_VALUE_BIT_SIZE    0x20UL
+#define DX_DOUT_SRAM_BYTES_LEN_REG_OFFSET   0x0D34UL
+#define DX_DOUT_SRAM_BYTES_LEN_VALUE_BIT_SHIFT  0x0UL
+#define DX_DOUT_SRAM_BYTES_LEN_VALUE_BIT_SIZE   0x20UL
+#define DX_DOUT_SRAM_DMA_BUSY_REG_OFFSET    0x0D38UL
+#define DX_DOUT_SRAM_DMA_BUSY_VALUE_BIT_SHIFT   0x0UL
+#define DX_DOUT_SRAM_DMA_BUSY_VALUE_BIT_SIZE    0x1UL
+#define DX_DOUT_SRAM_ENDIANNESS_REG_OFFSET  0x0D3CUL
+#define DX_DOUT_SRAM_ENDIANNESS_VALUE_BIT_SHIFT     0x0UL
+#define DX_DOUT_SRAM_ENDIANNESS_VALUE_BIT_SIZE  0x1UL
+#define DX_READ_ALIGN_LAST_REG_OFFSET   0x0D44UL
+#define DX_READ_ALIGN_LAST_VALUE_BIT_SHIFT  0x0UL
+#define DX_READ_ALIGN_LAST_VALUE_BIT_SIZE   0x1UL
+#define DX_DOUT_FIFO_EMPTY_REG_OFFSET   0x0D50UL
+#define DX_DOUT_FIFO_EMPTY_VALUE_BIT_SHIFT  0x0UL
+#define DX_DOUT_FIFO_EMPTY_VALUE_BIT_SIZE   0x1UL
+// --------------------------------------
+// BLOCK: HASH
+// --------------------------------------
+#define DX_HASH_H0_REG_OFFSET   0x0640UL
+#define DX_HASH_H0_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H0_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H1_REG_OFFSET   0x0644UL
+#define DX_HASH_H1_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H1_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H2_REG_OFFSET   0x0648UL
+#define DX_HASH_H2_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H2_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H3_REG_OFFSET   0x064CUL
+#define DX_HASH_H3_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H3_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H4_REG_OFFSET   0x0650UL
+#define DX_HASH_H4_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H4_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H5_REG_OFFSET   0x0654UL
+#define DX_HASH_H5_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H5_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H6_REG_OFFSET   0x0658UL
+#define DX_HASH_H6_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H6_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H7_REG_OFFSET   0x065CUL
+#define DX_HASH_H7_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H7_VALUE_BIT_SIZE   0x20UL
+#define DX_HASH_H8_REG_OFFSET   0x0660UL
+#define DX_HASH_H8_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_H8_VALUE_BIT_SIZE   0x20UL
+#define DX_AUTO_HW_PADDING_REG_OFFSET   0x0684UL
+#define DX_AUTO_HW_PADDING_VALUE_BIT_SHIFT  0x0UL
+#define DX_AUTO_HW_PADDING_VALUE_BIT_SIZE   0x1UL
+#define DX_HASH_XOR_DIN_REG_OFFSET  0x0688UL
+#define DX_HASH_XOR_DIN_VALUE_BIT_SHIFT     0x0UL
+#define DX_HASH_XOR_DIN_VALUE_BIT_SIZE  0x20UL
+#define DX_LOAD_INIT_STATE_REG_OFFSET   0x0694UL
+#define DX_LOAD_INIT_STATE_VALUE_BIT_SHIFT  0x0UL
+#define DX_LOAD_INIT_STATE_VALUE_BIT_SIZE   0x1UL
+#define DX_HASH_SEL_AES_MAC_REG_OFFSET  0x06A4UL
+#define DX_HASH_SEL_AES_MAC_HASH_SEL_AES_MAC_BIT_SHIFT  0x0UL
+#define DX_HASH_SEL_AES_MAC_HASH_SEL_AES_MAC_BIT_SIZE   0x1UL
+#define DX_HASH_SEL_AES_MAC_GHASH_SEL_BIT_SHIFT     0x1UL
+#define DX_HASH_SEL_AES_MAC_GHASH_SEL_BIT_SIZE  0x1UL
+#define DX_HASH_VERSION_REG_OFFSET  0x07B0UL
+#define DX_HASH_VERSION_FIXES_BIT_SHIFT     0x0UL
+#define DX_HASH_VERSION_FIXES_BIT_SIZE  0x8UL
+#define DX_HASH_VERSION_MINOR_VERSION_NUMBER_BIT_SHIFT  0x8UL
+#define DX_HASH_VERSION_MINOR_VERSION_NUMBER_BIT_SIZE   0x4UL
+#define DX_HASH_VERSION_MAJOR_VERSION_NUMBER_BIT_SHIFT  0xCUL
+#define DX_HASH_VERSION_MAJOR_VERSION_NUMBER_BIT_SIZE   0x4UL
+#define DX_HASH_CONTROL_REG_OFFSET  0x07C0UL
+#define DX_HASH_CONTROL_MODE_0_1_BIT_SHIFT  0x0UL
+#define DX_HASH_CONTROL_MODE_0_1_BIT_SIZE   0x2UL
+#define DX_HASH_CONTROL_MODE_3_BIT_SHIFT    0x3UL
+#define DX_HASH_CONTROL_MODE_3_BIT_SIZE     0x1UL
+#define DX_HASH_PAD_EN_REG_OFFSET   0x07C4UL
+#define DX_HASH_PAD_EN_VALUE_BIT_SHIFT  0x0UL
+#define DX_HASH_PAD_EN_VALUE_BIT_SIZE   0x1UL
+#define DX_HASH_PAD_CFG_REG_OFFSET  0x07C8UL
+#define DX_HASH_PAD_CFG_VALUE_BIT_SHIFT     0x2UL
+#define DX_HASH_PAD_CFG_VALUE_BIT_SIZE  0x1UL
+#define DX_HASH_CUR_LEN_0_REG_OFFSET    0x07CCUL
+#define DX_HASH_CUR_LEN_0_VALUE_BIT_SHIFT   0x0UL
+#define DX_HASH_CUR_LEN_0_VALUE_BIT_SIZE    0x20UL
+#define DX_HASH_CUR_LEN_1_REG_OFFSET    0x07D0UL
+#define DX_HASH_CUR_LEN_1_VALUE_BIT_SHIFT   0x0UL
+#define DX_HASH_CUR_LEN_1_VALUE_BIT_SIZE    0x20UL
+#define DX_HASH_PARAM_REG_OFFSET    0x07DCUL
+#define DX_HASH_PARAM_CW_BIT_SHIFT  0x0UL
+#define DX_HASH_PARAM_CW_BIT_SIZE   0x4UL
+#define DX_HASH_PARAM_CH_BIT_SHIFT  0x4UL
+#define DX_HASH_PARAM_CH_BIT_SIZE   0x4UL
+#define DX_HASH_PARAM_DW_BIT_SHIFT  0x8UL
+#define DX_HASH_PARAM_DW_BIT_SIZE   0x4UL
+#define DX_HASH_PARAM_SHA_512_EXISTS_BIT_SHIFT  0xCUL
+#define DX_HASH_PARAM_SHA_512_EXISTS_BIT_SIZE   0x1UL
+#define DX_HASH_PARAM_PAD_EXISTS_BIT_SHIFT  0xDUL
+#define DX_HASH_PARAM_PAD_EXISTS_BIT_SIZE   0x1UL
+#define DX_HASH_PARAM_MD5_EXISTS_BIT_SHIFT  0xEUL
+#define DX_HASH_PARAM_MD5_EXISTS_BIT_SIZE   0x1UL
+#define DX_HASH_PARAM_HMAC_EXISTS_BIT_SHIFT     0xFUL
+#define DX_HASH_PARAM_HMAC_EXISTS_BIT_SIZE  0x1UL
+#define DX_HASH_PARAM_SHA_256_EXISTS_BIT_SHIFT  0x10UL
+#define DX_HASH_PARAM_SHA_256_EXISTS_BIT_SIZE   0x1UL
+#define DX_HASH_PARAM_HASH_COMPARE_EXISTS_BIT_SHIFT     0x11UL
+#define DX_HASH_PARAM_HASH_COMPARE_EXISTS_BIT_SIZE  0x1UL
+#define DX_HASH_PARAM_DUMP_HASH_TO_DOUT_EXISTS_BIT_SHIFT    0x12UL
+#define DX_HASH_PARAM_DUMP_HASH_TO_DOUT_EXISTS_BIT_SIZE     0x1UL
+#define DX_HASH_AES_SW_RESET_REG_OFFSET     0x07E4UL
+#define DX_HASH_AES_SW_RESET_VALUE_BIT_SHIFT    0x0UL
+#define DX_HASH_AES_SW_RESET_VALUE_BIT_SIZE     0x1UL
+#define DX_HASH_ENDIANESS_REG_OFFSET    0x07E8UL
+#define DX_HASH_ENDIANESS_VALUE_BIT_SHIFT   0x0UL
+#define DX_HASH_ENDIANESS_VALUE_BIT_SIZE    0x1UL
+// --------------------------------------
+// BLOCK: GHASH
+// --------------------------------------
+#define DX_GHASH_SUBKEY_0_0_REG_OFFSET  0x0960UL
+#define DX_GHASH_SUBKEY_0_0_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_SUBKEY_0_0_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_SUBKEY_0_1_REG_OFFSET  0x0964UL
+#define DX_GHASH_SUBKEY_0_1_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_SUBKEY_0_1_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_SUBKEY_0_2_REG_OFFSET  0x0968UL
+#define DX_GHASH_SUBKEY_0_2_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_SUBKEY_0_2_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_SUBKEY_0_3_REG_OFFSET  0x096CUL
+#define DX_GHASH_SUBKEY_0_3_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_SUBKEY_0_3_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_IV_0_0_REG_OFFSET  0x0970UL
+#define DX_GHASH_IV_0_0_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_IV_0_0_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_IV_0_1_REG_OFFSET  0x0974UL
+#define DX_GHASH_IV_0_1_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_IV_0_1_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_IV_0_2_REG_OFFSET  0x0978UL
+#define DX_GHASH_IV_0_2_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_IV_0_2_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_IV_0_3_REG_OFFSET  0x097CUL
+#define DX_GHASH_IV_0_3_VALUE_BIT_SHIFT     0x0UL
+#define DX_GHASH_IV_0_3_VALUE_BIT_SIZE  0x20UL
+#define DX_GHASH_BUSY_REG_OFFSET    0x0980UL
+#define DX_GHASH_BUSY_VALUE_BIT_SHIFT   0x0UL
+#define DX_GHASH_BUSY_VALUE_BIT_SIZE    0x1UL
+#define DX_GHASH_INIT_REG_OFFSET    0x0984UL
+#define DX_GHASH_INIT_VALUE_BIT_SHIFT   0x0UL
+#define DX_GHASH_INIT_VALUE_BIT_SIZE    0x1UL
+// --------------------------------------
+// BLOCK: PKA
+// --------------------------------------
+#define DX_MEMORY_MAP0_REG_OFFSET   0x0000UL
+#define DX_MEMORY_MAP0_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP0_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP1_REG_OFFSET   0x0004UL
+#define DX_MEMORY_MAP1_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP1_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP2_REG_OFFSET   0x0008UL
+#define DX_MEMORY_MAP2_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP2_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP3_REG_OFFSET   0x000CUL
+#define DX_MEMORY_MAP3_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP3_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP4_REG_OFFSET   0x0010UL
+#define DX_MEMORY_MAP4_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP4_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP5_REG_OFFSET   0x0014UL
+#define DX_MEMORY_MAP5_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP5_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP6_REG_OFFSET   0x0018UL
+#define DX_MEMORY_MAP6_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP6_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP7_REG_OFFSET   0x001CUL
+#define DX_MEMORY_MAP7_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP7_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP8_REG_OFFSET   0x0020UL
+#define DX_MEMORY_MAP8_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP8_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP9_REG_OFFSET   0x0024UL
+#define DX_MEMORY_MAP9_VALUE_BIT_SHIFT  0x1UL
+#define DX_MEMORY_MAP9_VALUE_BIT_SIZE   0xAUL
+#define DX_MEMORY_MAP10_REG_OFFSET  0x0028UL
+#define DX_MEMORY_MAP10_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP10_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP11_REG_OFFSET  0x002CUL
+#define DX_MEMORY_MAP11_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP11_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP12_REG_OFFSET  0x0030UL
+#define DX_MEMORY_MAP12_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP12_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP13_REG_OFFSET  0x0034UL
+#define DX_MEMORY_MAP13_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP13_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP14_REG_OFFSET  0x0038UL
+#define DX_MEMORY_MAP14_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP14_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP15_REG_OFFSET  0x003CUL
+#define DX_MEMORY_MAP15_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP15_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP16_REG_OFFSET  0x0040UL
+#define DX_MEMORY_MAP16_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP16_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP17_REG_OFFSET  0x0044UL
+#define DX_MEMORY_MAP17_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP17_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP18_REG_OFFSET  0x0048UL
+#define DX_MEMORY_MAP18_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP18_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP19_REG_OFFSET  0x004CUL
+#define DX_MEMORY_MAP19_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP19_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP20_REG_OFFSET  0x0050UL
+#define DX_MEMORY_MAP20_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP20_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP21_REG_OFFSET  0x0054UL
+#define DX_MEMORY_MAP21_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP21_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP22_REG_OFFSET  0x0058UL
+#define DX_MEMORY_MAP22_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP22_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP23_REG_OFFSET  0x005CUL
+#define DX_MEMORY_MAP23_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP23_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP24_REG_OFFSET  0x0060UL
+#define DX_MEMORY_MAP24_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP24_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP25_REG_OFFSET  0x0064UL
+#define DX_MEMORY_MAP25_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP25_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP26_REG_OFFSET  0x0068UL
+#define DX_MEMORY_MAP26_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP26_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP27_REG_OFFSET  0x006CUL
+#define DX_MEMORY_MAP27_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP27_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP28_REG_OFFSET  0x0070UL
+#define DX_MEMORY_MAP28_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP28_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP29_REG_OFFSET  0x0074UL
+#define DX_MEMORY_MAP29_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP29_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP30_REG_OFFSET  0x0078UL
+#define DX_MEMORY_MAP30_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP30_VALUE_BIT_SIZE  0xAUL
+#define DX_MEMORY_MAP31_REG_OFFSET  0x007CUL
+#define DX_MEMORY_MAP31_VALUE_BIT_SHIFT     0x1UL
+#define DX_MEMORY_MAP31_VALUE_BIT_SIZE  0xAUL
+#define DX_OPCODE_REG_OFFSET    0x0080UL
+#define DX_OPCODE_TAG_BIT_SHIFT     0x0UL
+#define DX_OPCODE_TAG_BIT_SIZE  0x6UL
+#define DX_OPCODE_REG_R_BIT_SHIFT   0x6UL
+#define DX_OPCODE_REG_R_BIT_SIZE    0x6UL
+#define DX_OPCODE_REG_B_BIT_SHIFT   0xCUL
+#define DX_OPCODE_REG_B_BIT_SIZE    0x6UL
+#define DX_OPCODE_REG_A_BIT_SHIFT   0x12UL
+#define DX_OPCODE_REG_A_BIT_SIZE    0x6UL
+#define DX_OPCODE_LEN_BIT_SHIFT     0x18UL
+#define DX_OPCODE_LEN_BIT_SIZE  0x3UL
+#define DX_OPCODE_OPCODE_BIT_SHIFT  0x1BUL
+#define DX_OPCODE_OPCODE_BIT_SIZE   0x5UL
+#define DX_N_NP_T0_T1_ADDR_REG_OFFSET   0x0084UL
+#define DX_N_NP_T0_T1_ADDR_N_VIRTUAL_ADDR_BIT_SHIFT     0x0UL
+#define DX_N_NP_T0_T1_ADDR_N_VIRTUAL_ADDR_BIT_SIZE  0x5UL
+#define DX_N_NP_T0_T1_ADDR_NP_VIRTUAL_ADDR_BIT_SHIFT    0x5UL
+#define DX_N_NP_T0_T1_ADDR_NP_VIRTUAL_ADDR_BIT_SIZE     0x5UL
+#define DX_N_NP_T0_T1_ADDR_T0_VIRTUAL_ADDR_BIT_SHIFT    0xAUL
+#define DX_N_NP_T0_T1_ADDR_T0_VIRTUAL_ADDR_BIT_SIZE     0x5UL
+#define DX_N_NP_T0_T1_ADDR_T1_VIRTUAL_ADDR_BIT_SHIFT    0xFUL
+#define DX_N_NP_T0_T1_ADDR_T1_VIRTUAL_ADDR_BIT_SIZE     0x5UL
+#define DX_PKA_STATUS_REG_OFFSET    0x0088UL
+#define DX_PKA_STATUS_ALU_MSB_4BITS_BIT_SHIFT   0x0UL
+#define DX_PKA_STATUS_ALU_MSB_4BITS_BIT_SIZE    0x4UL
+#define DX_PKA_STATUS_ALU_LSB_4BITS_BIT_SHIFT   0x4UL
+#define DX_PKA_STATUS_ALU_LSB_4BITS_BIT_SIZE    0x4UL
+#define DX_PKA_STATUS_ALU_SIGN_OUT_BIT_SHIFT    0x8UL
+#define DX_PKA_STATUS_ALU_SIGN_OUT_BIT_SIZE     0x1UL
+#define DX_PKA_STATUS_ALU_CARRY_BIT_SHIFT   0x9UL
+#define DX_PKA_STATUS_ALU_CARRY_BIT_SIZE    0x1UL
+#define DX_PKA_STATUS_ALU_CARRY_MOD_BIT_SHIFT   0xAUL
+#define DX_PKA_STATUS_ALU_CARRY_MOD_BIT_SIZE    0x1UL
+#define DX_PKA_STATUS_ALU_SUB_IS_ZERO_BIT_SHIFT     0xBUL
+#define DX_PKA_STATUS_ALU_SUB_IS_ZERO_BIT_SIZE  0x1UL
+#define DX_PKA_STATUS_ALU_OUT_ZERO_BIT_SHIFT    0xCUL
+#define DX_PKA_STATUS_ALU_OUT_ZERO_BIT_SIZE     0x1UL
+#define DX_PKA_STATUS_ALU_MODOVRFLW_BIT_SHIFT   0xDUL
+#define DX_PKA_STATUS_ALU_MODOVRFLW_BIT_SIZE    0x1UL
+#define DX_PKA_STATUS_DIV_BY_ZERO_BIT_SHIFT     0xEUL
+#define DX_PKA_STATUS_DIV_BY_ZERO_BIT_SIZE  0x1UL
+#define DX_PKA_STATUS_MODINV_OF_ZERO_BIT_SHIFT  0xFUL
+#define DX_PKA_STATUS_MODINV_OF_ZERO_BIT_SIZE   0x1UL
+#define DX_PKA_STATUS_OPCODE_BIT_SHIFT  0x10UL
+#define DX_PKA_STATUS_OPCODE_BIT_SIZE   0x5UL
+#define DX_PKA_SW_RESET_REG_OFFSET  0x008CUL
+#define DX_PKA_SW_RESET_VALUE_BIT_SHIFT     0x0UL
+#define DX_PKA_SW_RESET_VALUE_BIT_SIZE  0x1UL
+#define DX_PKA_L0_REG_OFFSET    0x0090UL
+#define DX_PKA_L0_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L0_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_L1_REG_OFFSET    0x0094UL
+#define DX_PKA_L1_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L1_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_L2_REG_OFFSET    0x0098UL
+#define DX_PKA_L2_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L2_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_L3_REG_OFFSET    0x009CUL
+#define DX_PKA_L3_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L3_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_L4_REG_OFFSET    0x00A0UL
+#define DX_PKA_L4_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L4_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_L5_REG_OFFSET    0x00A4UL
+#define DX_PKA_L5_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L5_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_L6_REG_OFFSET    0x00A8UL
+#define DX_PKA_L6_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L6_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_L7_REG_OFFSET    0x00ACUL
+#define DX_PKA_L7_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_L7_VALUE_BIT_SIZE    0xDUL
+#define DX_PKA_PIPE_RDY_REG_OFFSET  0x00B0UL
+#define DX_PKA_PIPE_RDY_VALUE_BIT_SHIFT     0x0UL
+#define DX_PKA_PIPE_RDY_VALUE_BIT_SIZE  0x1UL
+#define DX_PKA_DONE_REG_OFFSET  0x00B4UL
+#define DX_PKA_DONE_VALUE_BIT_SHIFT     0x0UL
+#define DX_PKA_DONE_VALUE_BIT_SIZE  0x1UL
+#define DX_PKA_MON_SELECT_REG_OFFSET    0x00B8UL
+#define DX_PKA_MON_SELECT_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_MON_SELECT_VALUE_BIT_SIZE    0x4UL
+#define DX_PKA_VERSION_REG_OFFSET   0x00C4UL
+#define DX_PKA_VERSION_VALUE_BIT_SHIFT  0x0UL
+#define DX_PKA_VERSION_VALUE_BIT_SIZE   0x20UL
+#define DX_PKA_MON_READ_REG_OFFSET  0x00D0UL
+#define DX_PKA_MON_READ_VALUE_BIT_SHIFT     0x0UL
+#define DX_PKA_MON_READ_VALUE_BIT_SIZE  0x20UL
+#define DX_PKA_SRAM_ADDR_REG_OFFSET     0x00D4UL
+#define DX_PKA_SRAM_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_PKA_SRAM_ADDR_VALUE_BIT_SIZE     0x20UL
+#define DX_PKA_SRAM_WDATA_REG_OFFSET    0x00D8UL
+#define DX_PKA_SRAM_WDATA_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_SRAM_WDATA_VALUE_BIT_SIZE    0x20UL
+#define DX_PKA_SRAM_RDATA_REG_OFFSET    0x00DCUL
+#define DX_PKA_SRAM_RDATA_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_SRAM_RDATA_VALUE_BIT_SIZE    0x20UL
+#define DX_PKA_SRAM_WR_CLR_REG_OFFSET   0x00E0UL
+#define DX_PKA_SRAM_WR_CLR_VALUE_BIT_SHIFT  0x0UL
+#define DX_PKA_SRAM_WR_CLR_VALUE_BIT_SIZE   0x20UL
+#define DX_PKA_SRAM_RADDR_REG_OFFSET    0x00E4UL
+#define DX_PKA_SRAM_RADDR_VALUE_BIT_SHIFT   0x0UL
+#define DX_PKA_SRAM_RADDR_VALUE_BIT_SIZE    0x20UL
+#define DX_PKA_WORD_ACCESS_REG_OFFSET   0x00F0UL
+#define DX_PKA_WORD_ACCESS_VALUE_BIT_SHIFT  0x0UL
+#define DX_PKA_WORD_ACCESS_VALUE_BIT_SIZE   0x20UL
+#define DX_PKA_BUFF_ADDR_REG_OFFSET     0x00F8UL
+#define DX_PKA_BUFF_ADDR_PKA_BUF_ADDR_BIT_SHIFT     0x0UL
+#define DX_PKA_BUFF_ADDR_PKA_BUF_ADDR_BIT_SIZE  0xCUL
+#define DX_PKA_BUFF_ADDR_RESEREVED1_BIT_SHIFT   0xCUL
+#define DX_PKA_BUFF_ADDR_RESEREVED1_BIT_SIZE    0x14UL
+// --------------------------------------
+// BLOCK: AHB
+// --------------------------------------
+#define DX_AHBM_SINGLES_REG_OFFSET  0x0B00UL
+#define DX_AHBM_SINGLES_VALUE_BIT_SHIFT     0x0UL
+#define DX_AHBM_SINGLES_VALUE_BIT_SIZE  0x1UL
+#define DX_AHBM_HPROT_REG_OFFSET    0x0B04UL
+#define DX_AHBM_HPROT_VALUE_BIT_SHIFT   0x0UL
+#define DX_AHBM_HPROT_VALUE_BIT_SIZE    0x4UL
+#define DX_AHBM_HMASTLOCK_REG_OFFSET    0x0B08UL
+#define DX_AHBM_HMASTLOCK_VALUE_BIT_SHIFT   0x0UL
+#define DX_AHBM_HMASTLOCK_VALUE_BIT_SIZE    0x1UL
+#define DX_AHBM_HNONSEC_REG_OFFSET  0x0B0CUL
+#define DX_AHBM_HNONSEC_AHB_WRITE_HNONSEC_BIT_SHIFT     0x0UL
+#define DX_AHBM_HNONSEC_AHB_WRITE_HNONSEC_BIT_SIZE  0x1UL
+#define DX_AHBM_HNONSEC_AHB_READ_HNONSEC_BIT_SHIFT  0x1UL
+#define DX_AHBM_HNONSEC_AHB_READ_HNONSEC_BIT_SIZE   0x1UL
+// --------------------------------------
+// BLOCK: AO
+// --------------------------------------
+#define DX_HOST_DCU_EN0_REG_OFFSET  0x1E00UL
+#define DX_HOST_DCU_EN0_VALUE_BIT_SHIFT     0x0UL
+#define DX_HOST_DCU_EN0_VALUE_BIT_SIZE  0x20UL
+#define DX_HOST_DCU_EN1_REG_OFFSET  0x1E04UL
+#define DX_HOST_DCU_EN1_VALUE_BIT_SHIFT     0x0UL
+#define DX_HOST_DCU_EN1_VALUE_BIT_SIZE  0x20UL
+#define DX_HOST_DCU_EN2_REG_OFFSET  0x1E08UL
+#define DX_HOST_DCU_EN2_VALUE_BIT_SHIFT     0x0UL
+#define DX_HOST_DCU_EN2_VALUE_BIT_SIZE  0x20UL
+#define DX_HOST_DCU_EN3_REG_OFFSET  0x1E0CUL
+#define DX_HOST_DCU_EN3_VALUE_BIT_SHIFT     0x0UL
+#define DX_HOST_DCU_EN3_VALUE_BIT_SIZE  0x20UL
+#define DX_HOST_DCU_LOCK0_REG_OFFSET    0x1E10UL
+#define DX_HOST_DCU_LOCK0_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_DCU_LOCK0_VALUE_BIT_SIZE    0x20UL
+#define DX_HOST_DCU_LOCK1_REG_OFFSET    0x1E14UL
+#define DX_HOST_DCU_LOCK1_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_DCU_LOCK1_VALUE_BIT_SIZE    0x20UL
+#define DX_HOST_DCU_LOCK2_REG_OFFSET    0x1E18UL
+#define DX_HOST_DCU_LOCK2_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_DCU_LOCK2_VALUE_BIT_SIZE    0x20UL
+#define DX_HOST_DCU_LOCK3_REG_OFFSET    0x1E1CUL
+#define DX_HOST_DCU_LOCK3_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_DCU_LOCK3_VALUE_BIT_SIZE    0x20UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK0_REG_OFFSET  0x1E20UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK0_VALUE_BIT_SHIFT     0x0UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK0_VALUE_BIT_SIZE  0x20UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK1_REG_OFFSET  0x1E24UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK1_VALUE_BIT_SHIFT     0x0UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK1_VALUE_BIT_SIZE  0x20UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK2_REG_OFFSET  0x1E28UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK2_VALUE_BIT_SHIFT     0x0UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK2_VALUE_BIT_SIZE  0x20UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK3_REG_OFFSET  0x1E2CUL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK3_VALUE_BIT_SHIFT     0x0UL
+#define DX_AO_ICV_DCU_RESTRICTION_MASK3_VALUE_BIT_SIZE  0x20UL
+#define DX_AO_CC_SEC_DEBUG_RESET_REG_OFFSET     0x1E30UL
+#define DX_AO_CC_SEC_DEBUG_RESET_VALUE_BIT_SHIFT    0x0UL
+#define DX_AO_CC_SEC_DEBUG_RESET_VALUE_BIT_SIZE     0x1UL
+#define DX_HOST_AO_LOCK_BITS_REG_OFFSET     0x1E34UL
+#define DX_HOST_AO_LOCK_BITS_HOST_FATAL_ERR_BIT_SHIFT   0x0UL
+#define DX_HOST_AO_LOCK_BITS_HOST_FATAL_ERR_BIT_SIZE    0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KPICV_LOCK_BIT_SHIFT  0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KPICV_LOCK_BIT_SIZE   0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KCEICV_LOCK_BIT_SHIFT     0x2UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KCEICV_LOCK_BIT_SIZE  0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KCP_LOCK_BIT_SHIFT    0x3UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KCP_LOCK_BIT_SIZE     0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KCE_LOCK_BIT_SHIFT    0x4UL
+#define DX_HOST_AO_LOCK_BITS_HOST_KCE_LOCK_BIT_SIZE     0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_ICV_RMA_LOCK_BIT_SHIFT    0x5UL
+#define DX_HOST_AO_LOCK_BITS_HOST_ICV_RMA_LOCK_BIT_SIZE     0x1UL
+#define DX_HOST_AO_LOCK_BITS_RESET_UPON_DEBUG_DISABLE_BIT_SHIFT     0x6UL
+#define DX_HOST_AO_LOCK_BITS_RESET_UPON_DEBUG_DISABLE_BIT_SIZE  0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_FORCE_DFA_ENABLE_BIT_SHIFT    0x7UL
+#define DX_HOST_AO_LOCK_BITS_HOST_FORCE_DFA_ENABLE_BIT_SIZE     0x1UL
+#define DX_HOST_AO_LOCK_BITS_HOST_DFA_ENABLE_LOCK_BIT_SHIFT     0x8UL
+#define DX_HOST_AO_LOCK_BITS_HOST_DFA_ENABLE_LOCK_BIT_SIZE  0x1UL
+#define DX_AO_APB_FILTERING_REG_OFFSET  0x1E38UL
+#define DX_AO_APB_FILTERING_ONLY_SEC_ACCESS_ALLOW_BIT_SHIFT     0x0UL
+#define DX_AO_APB_FILTERING_ONLY_SEC_ACCESS_ALLOW_BIT_SIZE  0x1UL
+#define DX_AO_APB_FILTERING_ONLY_SEC_ACCESS_ALLOW_LOCK_BIT_SHIFT    0x1UL
+#define DX_AO_APB_FILTERING_ONLY_SEC_ACCESS_ALLOW_LOCK_BIT_SIZE     0x1UL
+#define DX_AO_APB_FILTERING_ONLY_PRIV_ACCESS_ALLOW_BIT_SHIFT    0x2UL
+#define DX_AO_APB_FILTERING_ONLY_PRIV_ACCESS_ALLOW_BIT_SIZE     0x1UL
+#define DX_AO_APB_FILTERING_ONLY_PRIV_ACCESS_ALLOW_LOCK_BIT_SHIFT   0x3UL
+#define DX_AO_APB_FILTERING_ONLY_PRIV_ACCESS_ALLOW_LOCK_BIT_SIZE    0x1UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_SEC_ACCESS_ALLOW_BIT_SHIFT    0x4UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_SEC_ACCESS_ALLOW_BIT_SIZE     0x1UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_SEC_ACCESS_ALLOW_LOCK_BIT_SHIFT   0x5UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_SEC_ACCESS_ALLOW_LOCK_BIT_SIZE    0x1UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_PRIV_ACCESS_ALLOW_BIT_SHIFT   0x6UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_PRIV_ACCESS_ALLOW_BIT_SIZE    0x1UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_PRIV_ACCESS_ALLOW_LOCK_BIT_SHIFT  0x7UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_PRIV_ACCESS_ALLOW_LOCK_BIT_SIZE   0x1UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_INST_ACCESS_ALLOW_BIT_SHIFT   0x8UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_INST_ACCESS_ALLOW_BIT_SIZE    0x1UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_INST_ACCESS_ALLOW_LOCK_BIT_SHIFT  0x9UL
+#define DX_AO_APB_FILTERING_APBC_ONLY_INST_ACCESS_ALLOW_LOCK_BIT_SIZE   0x1UL
+#define DX_AO_CC_GPPC_REG_OFFSET    0x1E3CUL
+#define DX_AO_CC_GPPC_VALUE_BIT_SHIFT   0x0UL
+#define DX_AO_CC_GPPC_VALUE_BIT_SIZE    0x8UL
+#define DX_HOST_RGF_CC_SW_RST_REG_OFFSET    0x1E40UL
+#define DX_HOST_RGF_CC_SW_RST_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_RGF_CC_SW_RST_VALUE_BIT_SIZE    0x1UL
+// --------------------------------------
+// BLOCK: CHACHA
+// --------------------------------------
+#define DX_CHACHA_CONTROL_REG_REG_OFFSET    0x0380UL
+#define DX_CHACHA_CONTROL_REG_CHACHA_OR_SALSA_BIT_SHIFT     0x0UL
+#define DX_CHACHA_CONTROL_REG_CHACHA_OR_SALSA_BIT_SIZE  0x1UL
+#define DX_CHACHA_CONTROL_REG_INIT_FROM_HOST_BIT_SHIFT  0x1UL
+#define DX_CHACHA_CONTROL_REG_INIT_FROM_HOST_BIT_SIZE   0x1UL
+#define DX_CHACHA_CONTROL_REG_CALC_KEY_FOR_POLY1305_BIT_SHIFT   0x2UL
+#define DX_CHACHA_CONTROL_REG_CALC_KEY_FOR_POLY1305_BIT_SIZE    0x1UL
+#define DX_CHACHA_CONTROL_REG_KEY_LEN_BIT_SHIFT     0x3UL
+#define DX_CHACHA_CONTROL_REG_KEY_LEN_BIT_SIZE  0x1UL
+#define DX_CHACHA_CONTROL_REG_NUM_OF_ROUNDS_BIT_SHIFT   0x4UL
+#define DX_CHACHA_CONTROL_REG_NUM_OF_ROUNDS_BIT_SIZE    0x2UL
+#define DX_CHACHA_CONTROL_REG_RESET_BLOCK_CNT_BIT_SHIFT     0x9UL
+#define DX_CHACHA_CONTROL_REG_RESET_BLOCK_CNT_BIT_SIZE  0x1UL
+#define DX_CHACHA_CONTROL_REG_USE_IV_96BIT_BIT_SHIFT    0xAUL
+#define DX_CHACHA_CONTROL_REG_USE_IV_96BIT_BIT_SIZE     0x1UL
+#define DX_CHACHA_VERSION_REG_OFFSET    0x0384UL
+#define DX_CHACHA_VERSION_VALUE_BIT_SHIFT   0x0UL
+#define DX_CHACHA_VERSION_VALUE_BIT_SIZE    0x20UL
+#define DX_CHACHA_KEY0_REG_OFFSET   0x0388UL
+#define DX_CHACHA_KEY0_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY0_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_KEY1_REG_OFFSET   0x038CUL
+#define DX_CHACHA_KEY1_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY1_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_KEY2_REG_OFFSET   0x0390UL
+#define DX_CHACHA_KEY2_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY2_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_KEY3_REG_OFFSET   0x0394UL
+#define DX_CHACHA_KEY3_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY3_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_KEY4_REG_OFFSET   0x0398UL
+#define DX_CHACHA_KEY4_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY4_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_KEY5_REG_OFFSET   0x039CUL
+#define DX_CHACHA_KEY5_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY5_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_KEY6_REG_OFFSET   0x03A0UL
+#define DX_CHACHA_KEY6_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY6_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_KEY7_REG_OFFSET   0x03A4UL
+#define DX_CHACHA_KEY7_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_KEY7_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_IV_0_REG_OFFSET   0x03A8UL
+#define DX_CHACHA_IV_0_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_IV_0_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_IV_1_REG_OFFSET   0x03ACUL
+#define DX_CHACHA_IV_1_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_IV_1_VALUE_BIT_SIZE   0x20UL
+#define DX_CHACHA_BUSY_REG_OFFSET   0x03B0UL
+#define DX_CHACHA_BUSY_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_BUSY_VALUE_BIT_SIZE   0x1UL
+#define DX_CHACHA_HW_FLAGS_REG_OFFSET   0x03B4UL
+#define DX_CHACHA_HW_FLAGS_CHACHA_EXISTS_BIT_SHIFT  0x0UL
+#define DX_CHACHA_HW_FLAGS_CHACHA_EXISTS_BIT_SIZE   0x1UL
+#define DX_CHACHA_HW_FLAGS_SALSA_EXISTS_BIT_SHIFT   0x1UL
+#define DX_CHACHA_HW_FLAGS_SALSA_EXISTS_BIT_SIZE    0x1UL
+#define DX_CHACHA_HW_FLAGS_FAST_CHACHA_BIT_SHIFT    0x2UL
+#define DX_CHACHA_HW_FLAGS_FAST_CHACHA_BIT_SIZE     0x1UL
+#define DX_CHACHA_BLOCK_CNT_LSB_REG_OFFSET  0x03B8UL
+#define DX_CHACHA_BLOCK_CNT_LSB_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_BLOCK_CNT_LSB_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_BLOCK_CNT_MSB_REG_OFFSET  0x03BCUL
+#define DX_CHACHA_BLOCK_CNT_MSB_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_BLOCK_CNT_MSB_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_SW_RESET_REG_OFFSET   0x03C0UL
+#define DX_CHACHA_SW_RESET_VALUE_BIT_SHIFT  0x0UL
+#define DX_CHACHA_SW_RESET_VALUE_BIT_SIZE   0x1UL
+#define DX_CHACHA_FOR_POLY_KEY0_REG_OFFSET  0x03C4UL
+#define DX_CHACHA_FOR_POLY_KEY0_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY0_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_FOR_POLY_KEY1_REG_OFFSET  0x03C8UL
+#define DX_CHACHA_FOR_POLY_KEY1_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY1_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_FOR_POLY_KEY2_REG_OFFSET  0x03CCUL
+#define DX_CHACHA_FOR_POLY_KEY2_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY2_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_FOR_POLY_KEY3_REG_OFFSET  0x03D0UL
+#define DX_CHACHA_FOR_POLY_KEY3_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY3_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_FOR_POLY_KEY4_REG_OFFSET  0x03D4UL
+#define DX_CHACHA_FOR_POLY_KEY4_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY4_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_FOR_POLY_KEY5_REG_OFFSET  0x03D8UL
+#define DX_CHACHA_FOR_POLY_KEY5_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY5_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_FOR_POLY_KEY6_REG_OFFSET  0x03DCUL
+#define DX_CHACHA_FOR_POLY_KEY6_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY6_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_FOR_POLY_KEY7_REG_OFFSET  0x03E0UL
+#define DX_CHACHA_FOR_POLY_KEY7_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_FOR_POLY_KEY7_VALUE_BIT_SIZE  0x20UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_REG_OFFSET   0x03E4UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DIN_WORD_ORDER_BIT_SHIFT  0x0UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DIN_WORD_ORDER_BIT_SIZE   0x1UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DIN_BYTE_ORDER_BIT_SHIFT  0x1UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DIN_BYTE_ORDER_BIT_SIZE   0x1UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_CORE_MATRIX_LBE_ORDER_BIT_SHIFT   0x2UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_CORE_MATRIX_LBE_ORDER_BIT_SIZE    0x1UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DOUT_WORD_ORDER_BIT_SHIFT     0x3UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DOUT_WORD_ORDER_BIT_SIZE  0x1UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DOUT_BYTE_ORDER_BIT_SHIFT     0x4UL
+#define DX_CHACHA_BYTE_WORD_ORDER_CNTL_REG_CHACHA_DOUT_BYTE_ORDER_BIT_SIZE  0x1UL
+#define DX_CHACHA_DEBUG_REG_REG_OFFSET  0x03E8UL
+#define DX_CHACHA_DEBUG_REG_VALUE_BIT_SHIFT     0x0UL
+#define DX_CHACHA_DEBUG_REG_VALUE_BIT_SIZE  0x2UL
+
+#endif  // __DX_CRYS_KERNEL_H__
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_env.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_env.h
new file mode 100644
index 0000000..2656a37
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_env.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_ENV_H__
+#define __DX_ENV_H__
+
+// --------------------------------------
+// BLOCK: FPGA_ENV_REGS
+// --------------------------------------
+#define DX_ENV_PKA_DEBUG_MODE_REG_OFFSET   0x024UL
+#define DX_ENV_PKA_DEBUG_MODE_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_PKA_DEBUG_MODE_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_SCAN_MODE_REG_OFFSET   0x030UL
+#define DX_ENV_SCAN_MODE_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SCAN_MODE_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_CC_ALLOW_SCAN_REG_OFFSET   0x034UL
+#define DX_ENV_CC_ALLOW_SCAN_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_CC_ALLOW_SCAN_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_CC_HOST_INT_REG_OFFSET   0x0A0UL
+#define DX_ENV_CC_HOST_INT_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_HOST_INT_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_CC_PUB_HOST_INT_REG_OFFSET   0x0A4UL
+#define DX_ENV_CC_PUB_HOST_INT_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_PUB_HOST_INT_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_CC_RST_N_REG_OFFSET   0x0A8UL
+#define DX_ENV_CC_RST_N_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_CC_RST_N_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_RST_OVERRIDE_REG_OFFSET   0x0ACUL
+#define DX_ENV_RST_OVERRIDE_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_RST_OVERRIDE_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_CC_POR_N_ADDR_REG_OFFSET   0x0E0UL
+#define DX_ENV_CC_POR_N_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_CC_POR_N_ADDR_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_CC_COLD_RST_REG_OFFSET   0x0FCUL
+#define DX_ENV_CC_COLD_RST_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_COLD_RST_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_DUMMY_ADDR_REG_OFFSET   0x108UL
+#define DX_ENV_DUMMY_ADDR_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_DUMMY_ADDR_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_COUNTER_CLR_REG_OFFSET   0x118UL
+#define DX_ENV_COUNTER_CLR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_COUNTER_CLR_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_COUNTER_RD_REG_OFFSET   0x11CUL
+#define DX_ENV_COUNTER_RD_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_COUNTER_RD_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_RNG_DEBUG_ENABLE_REG_OFFSET   0x430UL
+#define DX_ENV_RNG_DEBUG_ENABLE_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_RNG_DEBUG_ENABLE_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_CC_LCS_REG_OFFSET   0x43CUL
+#define DX_ENV_CC_LCS_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_LCS_VALUE_BIT_SIZE    0x8UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_REG_OFFSET   0x440UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_CM_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_CM_BIT_SIZE    0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_DM_BIT_SHIFT   0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_DM_BIT_SIZE    0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_SECURE_BIT_SHIFT   0x2UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_SECURE_BIT_SIZE    0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_RMA_BIT_SHIFT  0x3UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_RMA_BIT_SIZE   0x1UL
+#define DX_ENV_DCU_EN_REG_OFFSET   0x444UL
+#define DX_ENV_DCU_EN_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_DCU_EN_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_CC_LCS_IS_VALID_REG_OFFSET   0x448UL
+#define DX_ENV_CC_LCS_IS_VALID_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_LCS_IS_VALID_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_POWER_DOWN_REG_OFFSET   0x478UL
+#define DX_ENV_POWER_DOWN_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_POWER_DOWN_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_DCU_H_EN_REG_OFFSET   0x484UL
+#define DX_ENV_DCU_H_EN_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_DCU_H_EN_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_VERSION_REG_OFFSET   0x488UL
+#define DX_ENV_VERSION_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_VERSION_VALUE_BIT_SIZE   0x20UL
+#define DX_ENV_ROSC_WRITE_REG_OFFSET   0x48CUL
+#define DX_ENV_ROSC_WRITE_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_ROSC_WRITE_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_ROSC_ADDR_REG_OFFSET   0x490UL
+#define DX_ENV_ROSC_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_ROSC_ADDR_VALUE_BIT_SIZE     0x8UL
+#define DX_ENV_RESET_SESSION_KEY_REG_OFFSET   0x494UL
+#define DX_ENV_RESET_SESSION_KEY_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_RESET_SESSION_KEY_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_SESSION_KEY_0_REG_OFFSET   0x4A0UL
+#define DX_ENV_SESSION_KEY_0_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_0_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_1_REG_OFFSET   0x4A4UL
+#define DX_ENV_SESSION_KEY_1_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_1_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_2_REG_OFFSET   0x4A8UL
+#define DX_ENV_SESSION_KEY_2_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_2_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_3_REG_OFFSET   0x4ACUL
+#define DX_ENV_SESSION_KEY_3_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_3_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_VALID_REG_OFFSET   0x4B0UL
+#define DX_ENV_SESSION_KEY_VALID_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_VALID_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_SPIDEN_REG_OFFSET   0x4D0UL
+#define DX_ENV_SPIDEN_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_SPIDEN_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_AXIM_USER_PARAMS_REG_OFFSET   0x600UL
+#define DX_ENV_AXIM_USER_PARAMS_ARUSER_BIT_SHIFT    0x0UL
+#define DX_ENV_AXIM_USER_PARAMS_ARUSER_BIT_SIZE     0x5UL
+#define DX_ENV_AXIM_USER_PARAMS_AWUSER_BIT_SHIFT    0x5UL
+#define DX_ENV_AXIM_USER_PARAMS_AWUSER_BIT_SIZE     0x5UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_REG_OFFSET   0x604UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_BIT_BIT_SHIFT   0x0UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_BIT_BIT_SIZE    0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_OVERRIDE_BIT_SHIFT  0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_OVERRIDE_BIT_SIZE   0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_BIT_BIT_SHIFT   0x2UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_BIT_BIT_SIZE    0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_OVERRIDE_BIT_SHIFT  0x3UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_OVERRIDE_BIT_SIZE   0x1UL
+#define DX_ENV_SRAM_ENABLE_REG_OFFSET   0x608UL
+#define DX_ENV_SRAM_ENABLE_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_SRAM_ENABLE_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_APB_FIPS_ADDR_REG_OFFSET   0x650UL
+#define DX_ENV_APB_FIPS_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_APB_FIPS_ADDR_VALUE_BIT_SIZE     0xCUL
+#define DX_ENV_APB_FIPS_VAL_REG_OFFSET   0x654UL
+#define DX_ENV_APB_FIPS_VAL_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_APB_FIPS_VAL_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_APB_FIPS_MASK_REG_OFFSET   0x658UL
+#define DX_ENV_APB_FIPS_MASK_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_APB_FIPS_MASK_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_APB_FIPS_CNT_REG_OFFSET   0x65CUL
+#define DX_ENV_APB_FIPS_CNT_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_APB_FIPS_CNT_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_APB_FIPS_NEW_ADDR_REG_OFFSET   0x660UL
+#define DX_ENV_APB_FIPS_NEW_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_APB_FIPS_NEW_ADDR_VALUE_BIT_SIZE     0xCUL
+#define DX_ENV_APB_FIPS_NEW_VAL_REG_OFFSET   0x664UL
+#define DX_ENV_APB_FIPS_NEW_VAL_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_APB_FIPS_NEW_VAL_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_APB_PPROT_OVERRIDE_REG_OFFSET   0x668UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SHIFT  0x0UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SIZE   0x3UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SHIFT     0x3UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SIZE  0x1UL
+#define DX_ENV_APBSC_FIPS_ADDR_REG_OFFSET   0x670UL
+#define DX_ENV_APBSC_FIPS_ADDR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_APBSC_FIPS_ADDR_VALUE_BIT_SIZE   0xCUL
+#define DX_ENV_APBSC_FIPS_VAL_REG_OFFSET   0x674UL
+#define DX_ENV_APBSC_FIPS_VAL_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_APBSC_FIPS_VAL_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_APBSC_FIPS_MASK_REG_OFFSET   0x678UL
+#define DX_ENV_APBSC_FIPS_MASK_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_APBSC_FIPS_MASK_VALUE_BIT_SIZE   0x20UL
+#define DX_ENV_APBSC_FIPS_CNT_REG_OFFSET   0x67CUL
+#define DX_ENV_APBSC_FIPS_CNT_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_APBSC_FIPS_CNT_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_APBSC_FIPS_NEW_ADDR_REG_OFFSET   0x680UL
+#define DX_ENV_APBSC_FIPS_NEW_ADDR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_APBSC_FIPS_NEW_ADDR_VALUE_BIT_SIZE   0xCUL
+#define DX_ENV_APBSC_FIPS_NEW_VAL_REG_OFFSET   0x684UL
+#define DX_ENV_APBSC_FIPS_NEW_VAL_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_APBSC_FIPS_NEW_VAL_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_REG_OFFSET   0x688UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SHIFT    0x0UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SIZE     0x3UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SHIFT   0x3UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SIZE    0x1UL
+#define DX_ENV_AO_CC_GPPC_REG_OFFSET   0x700UL
+#define DX_ENV_AO_CC_GPPC_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_AO_CC_GPPC_VALUE_BIT_SIZE    0x8UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_REG_OFFSET   0x704UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SHIFT     0x0UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SIZE  0x3UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SHIFT    0x3UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SIZE     0x1UL
+#define DX_ENV_CC_IS_IDLE_REG_OFFSET   0x708UL
+#define DX_ENV_CC_IS_IDLE_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_IS_IDLE_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_CC_POWERDOWN_RDY_REG_OFFSET   0x70CUL
+#define DX_ENV_CC_POWERDOWN_RDY_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_CC_POWERDOWN_RDY_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_CC_STATIC_CFG_REG_OFFSET   0x710UL
+#define DX_ENV_CC_STATIC_CFG_USER_OTP_FILTERING_DISABLE_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_STATIC_CFG_USER_OTP_FILTERING_DISABLE_BIT_SIZE    0x1UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_GHASH_ENGINE_BIT_SHIFT  0x1UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_GHASH_ENGINE_BIT_SIZE   0x1UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_CHACHA_ENGINE_BIT_SHIFT 0x2UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_CHACHA_ENGINE_BIT_SIZE  0x1UL
+#define DX_ENV_FUSE_AIB_1K_OFFSET_REG_OFFSET   0x714UL
+#define DX_ENV_FUSE_AIB_1K_OFFSET_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_FUSE_AIB_1K_OFFSET_VALUE_BIT_SIZE    0x2UL
+#define DX_ENV_CC_IS_IDLE_CNTR_REG_OFFSET   0x720UL
+#define DX_ENV_CC_IS_IDLE_CNTR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_IS_IDLE_CNTR_VALUE_BIT_SIZE   0x20UL
+
+// --------------------------------------
+// BLOCK: ENV_CC_MEMORIES
+// --------------------------------------
+#define DX_ENV_FUSE_READY_REG_OFFSET    0x0000UL
+#define DX_ENV_FUSE_READY_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_FUSE_READY_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_PERF_RAM_MASTER_REG_OFFSET   0x00ECUL
+#define DX_ENV_PERF_RAM_MASTER_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_PERF_RAM_MASTER_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_PERF_RAM_ADDR_HIGH4_REG_OFFSET   0x00F0UL
+#define DX_ENV_PERF_RAM_ADDR_HIGH4_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_PERF_RAM_ADDR_HIGH4_VALUE_BIT_SIZE   0x2UL
+#define DX_ENV_FUSES_RAM_REG_OFFSET     0x03ECUL
+#define DX_ENV_FUSES_RAM_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_FUSES_RAM_VALUE_BIT_SIZE     0x20UL
+// --------------------------------------
+// BLOCK: ENV_PERF_RAM_BASE
+// --------------------------------------
+#define DX_ENV_PERF_RAM_BASE_REG_OFFSET     0x0000UL
+#define DX_ENV_PERF_RAM_BASE_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_PERF_RAM_BASE_VALUE_BIT_SIZE     0x20UL
+
+#endif /*__DX_ENV_H__*/
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_fpga_env.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_fpga_env.h
new file mode 100644
index 0000000..5be5a6e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_fpga_env.h
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+// --------------------------------------
+// BLOCK: FPGA_ENV_REGS
+// --------------------------------------
+#define DX_ENV_PKA_DEBUG_MODE_REG_OFFSET   0x024UL
+#define DX_ENV_PKA_DEBUG_MODE_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_PKA_DEBUG_MODE_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_SCAN_MODE_REG_OFFSET   0x030UL
+#define DX_ENV_SCAN_MODE_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SCAN_MODE_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_CC_ALLOW_SCAN_REG_OFFSET   0x034UL
+#define DX_ENV_CC_ALLOW_SCAN_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_CC_ALLOW_SCAN_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_CC_HOST_INT_REG_OFFSET   0x0A0UL
+#define DX_ENV_CC_HOST_INT_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_HOST_INT_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_CC_PUB_HOST_INT_REG_OFFSET   0x0A4UL
+#define DX_ENV_CC_PUB_HOST_INT_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_PUB_HOST_INT_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_CC_RST_N_REG_OFFSET   0x0A8UL
+#define DX_ENV_CC_RST_N_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_CC_RST_N_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_RST_OVERRIDE_REG_OFFSET   0x0ACUL
+#define DX_ENV_RST_OVERRIDE_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_RST_OVERRIDE_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_CC_POR_N_ADDR_REG_OFFSET   0x0E0UL
+#define DX_ENV_CC_POR_N_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_CC_POR_N_ADDR_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_CC_COLD_RST_REG_OFFSET   0x0FCUL
+#define DX_ENV_CC_COLD_RST_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_COLD_RST_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_DUMMY_ADDR_REG_OFFSET   0x108UL
+#define DX_ENV_DUMMY_ADDR_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_DUMMY_ADDR_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_COUNTER_CLR_REG_OFFSET   0x118UL
+#define DX_ENV_COUNTER_CLR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_COUNTER_CLR_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_COUNTER_RD_REG_OFFSET   0x11CUL
+#define DX_ENV_COUNTER_RD_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_COUNTER_RD_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_RNG_DEBUG_ENABLE_REG_OFFSET   0x430UL
+#define DX_ENV_RNG_DEBUG_ENABLE_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_RNG_DEBUG_ENABLE_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_CC_LCS_REG_OFFSET   0x43CUL
+#define DX_ENV_CC_LCS_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_LCS_VALUE_BIT_SIZE    0x8UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_REG_OFFSET   0x440UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_CM_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_CM_BIT_SIZE    0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_DM_BIT_SHIFT   0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_DM_BIT_SIZE    0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_SECURE_BIT_SHIFT   0x2UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_SECURE_BIT_SIZE    0x1UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_RMA_BIT_SHIFT  0x3UL
+#define DX_ENV_CC_IS_CM_DM_SECURE_RMA_IS_RMA_BIT_SIZE   0x1UL
+#define DX_ENV_DCU_EN_REG_OFFSET   0x444UL
+#define DX_ENV_DCU_EN_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_DCU_EN_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_CC_LCS_IS_VALID_REG_OFFSET   0x448UL
+#define DX_ENV_CC_LCS_IS_VALID_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_LCS_IS_VALID_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_POWER_DOWN_REG_OFFSET   0x478UL
+#define DX_ENV_POWER_DOWN_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_POWER_DOWN_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_DCU_H_EN_REG_OFFSET   0x484UL
+#define DX_ENV_DCU_H_EN_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_DCU_H_EN_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_VERSION_REG_OFFSET   0x488UL
+#define DX_ENV_VERSION_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_VERSION_VALUE_BIT_SIZE   0x20UL
+#define DX_ENV_ROSC_WRITE_REG_OFFSET   0x48CUL
+#define DX_ENV_ROSC_WRITE_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_ROSC_WRITE_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_ROSC_ADDR_REG_OFFSET   0x490UL
+#define DX_ENV_ROSC_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_ROSC_ADDR_VALUE_BIT_SIZE     0x8UL
+#define DX_ENV_RESET_SESSION_KEY_REG_OFFSET   0x494UL
+#define DX_ENV_RESET_SESSION_KEY_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_RESET_SESSION_KEY_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_SESSION_KEY_0_REG_OFFSET   0x4A0UL
+#define DX_ENV_SESSION_KEY_0_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_0_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_1_REG_OFFSET   0x4A4UL
+#define DX_ENV_SESSION_KEY_1_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_1_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_2_REG_OFFSET   0x4A8UL
+#define DX_ENV_SESSION_KEY_2_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_2_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_3_REG_OFFSET   0x4ACUL
+#define DX_ENV_SESSION_KEY_3_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_3_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_SESSION_KEY_VALID_REG_OFFSET   0x4B0UL
+#define DX_ENV_SESSION_KEY_VALID_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_SESSION_KEY_VALID_VALUE_BIT_SIZE     0x1UL
+#define DX_ENV_SPIDEN_REG_OFFSET   0x4D0UL
+#define DX_ENV_SPIDEN_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_SPIDEN_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_AXIM_USER_PARAMS_REG_OFFSET   0x600UL
+#define DX_ENV_AXIM_USER_PARAMS_ARUSER_BIT_SHIFT    0x0UL
+#define DX_ENV_AXIM_USER_PARAMS_ARUSER_BIT_SIZE     0x5UL
+#define DX_ENV_AXIM_USER_PARAMS_AWUSER_BIT_SHIFT    0x5UL
+#define DX_ENV_AXIM_USER_PARAMS_AWUSER_BIT_SIZE     0x5UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_REG_OFFSET   0x604UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_BIT_BIT_SHIFT   0x0UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_BIT_BIT_SIZE    0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_OVERRIDE_BIT_SHIFT  0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_AWPROT_NS_OVERRIDE_BIT_SIZE   0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_BIT_BIT_SHIFT   0x2UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_BIT_BIT_SIZE    0x1UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_OVERRIDE_BIT_SHIFT  0x3UL
+#define DX_ENV_SECURITY_MODE_OVERRIDE_ARPROT_NS_OVERRIDE_BIT_SIZE   0x1UL
+#define DX_ENV_SRAM_ENABLE_REG_OFFSET   0x608UL
+#define DX_ENV_SRAM_ENABLE_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_SRAM_ENABLE_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_APB_FIPS_ADDR_REG_OFFSET   0x650UL
+#define DX_ENV_APB_FIPS_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_APB_FIPS_ADDR_VALUE_BIT_SIZE     0xCUL
+#define DX_ENV_APB_FIPS_VAL_REG_OFFSET   0x654UL
+#define DX_ENV_APB_FIPS_VAL_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_APB_FIPS_VAL_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_APB_FIPS_MASK_REG_OFFSET   0x658UL
+#define DX_ENV_APB_FIPS_MASK_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_APB_FIPS_MASK_VALUE_BIT_SIZE     0x20UL
+#define DX_ENV_APB_FIPS_CNT_REG_OFFSET   0x65CUL
+#define DX_ENV_APB_FIPS_CNT_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_APB_FIPS_CNT_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_APB_FIPS_NEW_ADDR_REG_OFFSET   0x660UL
+#define DX_ENV_APB_FIPS_NEW_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_APB_FIPS_NEW_ADDR_VALUE_BIT_SIZE     0xCUL
+#define DX_ENV_APB_FIPS_NEW_VAL_REG_OFFSET   0x664UL
+#define DX_ENV_APB_FIPS_NEW_VAL_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_APB_FIPS_NEW_VAL_VALUE_BIT_SIZE  0x20UL
+#define DX_ENV_APB_PPROT_OVERRIDE_REG_OFFSET   0x668UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SHIFT  0x0UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SIZE   0x3UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SHIFT     0x3UL
+#define DX_ENV_APB_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SIZE  0x1UL
+#define DX_ENV_APBSC_FIPS_ADDR_REG_OFFSET   0x670UL
+#define DX_ENV_APBSC_FIPS_ADDR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_APBSC_FIPS_ADDR_VALUE_BIT_SIZE   0xCUL
+#define DX_ENV_APBSC_FIPS_VAL_REG_OFFSET   0x674UL
+#define DX_ENV_APBSC_FIPS_VAL_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_APBSC_FIPS_VAL_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_APBSC_FIPS_MASK_REG_OFFSET   0x678UL
+#define DX_ENV_APBSC_FIPS_MASK_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_APBSC_FIPS_MASK_VALUE_BIT_SIZE   0x20UL
+#define DX_ENV_APBSC_FIPS_CNT_REG_OFFSET   0x67CUL
+#define DX_ENV_APBSC_FIPS_CNT_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_APBSC_FIPS_CNT_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_APBSC_FIPS_NEW_ADDR_REG_OFFSET   0x680UL
+#define DX_ENV_APBSC_FIPS_NEW_ADDR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_APBSC_FIPS_NEW_ADDR_VALUE_BIT_SIZE   0xCUL
+#define DX_ENV_APBSC_FIPS_NEW_VAL_REG_OFFSET   0x684UL
+#define DX_ENV_APBSC_FIPS_NEW_VAL_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_APBSC_FIPS_NEW_VAL_VALUE_BIT_SIZE    0x20UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_REG_OFFSET   0x688UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SHIFT    0x0UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SIZE     0x3UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SHIFT   0x3UL
+#define DX_ENV_APBSC_PPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SIZE    0x1UL
+#define DX_ENV_AO_CC_GPPC_REG_OFFSET   0x700UL
+#define DX_ENV_AO_CC_GPPC_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_AO_CC_GPPC_VALUE_BIT_SIZE    0x8UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_REG_OFFSET   0x704UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SHIFT     0x0UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_VAL_BIT_SIZE  0x3UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SHIFT    0x3UL
+#define DX_ENV_AHBM_HPROT_OVERRIDE_PPROT_OVERRIDE_CNTL_BIT_SIZE     0x1UL
+#define DX_ENV_CC_IS_IDLE_REG_OFFSET   0x708UL
+#define DX_ENV_CC_IS_IDLE_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_IS_IDLE_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_CC_POWERDOWN_RDY_REG_OFFSET   0x70CUL
+#define DX_ENV_CC_POWERDOWN_RDY_VALUE_BIT_SHIFT     0x0UL
+#define DX_ENV_CC_POWERDOWN_RDY_VALUE_BIT_SIZE  0x1UL
+#define DX_ENV_CC_STATIC_CFG_REG_OFFSET   0x710UL
+#define DX_ENV_CC_STATIC_CFG_USER_OTP_FILTERING_DISABLE_BIT_SHIFT   0x0UL
+#define DX_ENV_CC_STATIC_CFG_USER_OTP_FILTERING_DISABLE_BIT_SIZE    0x1UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_GHASH_ENGINE_BIT_SHIFT  0x1UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_GHASH_ENGINE_BIT_SIZE   0x1UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_CHACHA_ENGINE_BIT_SHIFT 0x2UL
+#define DX_ENV_CC_STATIC_CFG_REMOVE_CHACHA_ENGINE_BIT_SIZE  0x1UL
+#define DX_ENV_FUSE_AIB_1K_OFFSET_REG_OFFSET   0x714UL
+#define DX_ENV_FUSE_AIB_1K_OFFSET_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_FUSE_AIB_1K_OFFSET_VALUE_BIT_SIZE    0x2UL
+#define DX_ENV_CC_IS_IDLE_CNTR_REG_OFFSET   0x720UL
+#define DX_ENV_CC_IS_IDLE_CNTR_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_CC_IS_IDLE_CNTR_VALUE_BIT_SIZE   0x20UL
+
+// --------------------------------------
+// BLOCK: ENV_CC_MEMORIES
+// --------------------------------------
+#define DX_ENV_FUSE_READY_REG_OFFSET    0x0000UL
+#define DX_ENV_FUSE_READY_VALUE_BIT_SHIFT   0x0UL
+#define DX_ENV_FUSE_READY_VALUE_BIT_SIZE    0x1UL
+#define DX_ENV_PERF_RAM_MASTER_REG_OFFSET   0x00ECUL
+#define DX_ENV_PERF_RAM_MASTER_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_PERF_RAM_MASTER_VALUE_BIT_SIZE   0x1UL
+#define DX_ENV_PERF_RAM_ADDR_HIGH4_REG_OFFSET   0x00F0UL
+#define DX_ENV_PERF_RAM_ADDR_HIGH4_VALUE_BIT_SHIFT  0x0UL
+#define DX_ENV_PERF_RAM_ADDR_HIGH4_VALUE_BIT_SIZE   0x2UL
+#define DX_ENV_FUSES_RAM_REG_OFFSET     0x03ECUL
+#define DX_ENV_FUSES_RAM_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_FUSES_RAM_VALUE_BIT_SIZE     0x20UL
+// --------------------------------------
+// BLOCK: ENV_PERF_RAM_BASE
+// --------------------------------------
+#define DX_ENV_PERF_RAM_BASE_REG_OFFSET     0x0000UL
+#define DX_ENV_PERF_RAM_BASE_VALUE_BIT_SHIFT    0x0UL
+#define DX_ENV_PERF_RAM_BASE_VALUE_BIT_SIZE     0x20UL
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_host.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_host.h
new file mode 100644
index 0000000..f2e3dbc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_host.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_HOST_H__
+#define __DX_HOST_H__
+
+// --------------------------------------
+// BLOCK: HOST
+// --------------------------------------
+#define DX_HOST_IRR_REG_OFFSET  0x0A00UL
+#define DX_HOST_IRR_SRAM_TO_DIN_INT_BIT_SHIFT   0x4UL
+#define DX_HOST_IRR_SRAM_TO_DIN_INT_BIT_SIZE    0x1UL
+#define DX_HOST_IRR_DOUT_TO_SRAM_INT_BIT_SHIFT  0x5UL
+#define DX_HOST_IRR_DOUT_TO_SRAM_INT_BIT_SIZE   0x1UL
+#define DX_HOST_IRR_MEM_TO_DIN_INT_BIT_SHIFT    0x6UL
+#define DX_HOST_IRR_MEM_TO_DIN_INT_BIT_SIZE     0x1UL
+#define DX_HOST_IRR_DOUT_TO_MEM_INT_BIT_SHIFT   0x7UL
+#define DX_HOST_IRR_DOUT_TO_MEM_INT_BIT_SIZE    0x1UL
+#define DX_HOST_IRR_AHB_ERR_INT_BIT_SHIFT   0x8UL
+#define DX_HOST_IRR_AHB_ERR_INT_BIT_SIZE    0x1UL
+#define DX_HOST_IRR_PKA_EXP_INT_BIT_SHIFT   0x9UL
+#define DX_HOST_IRR_PKA_EXP_INT_BIT_SIZE    0x1UL
+#define DX_HOST_IRR_RNG_INT_BIT_SHIFT   0xAUL
+#define DX_HOST_IRR_RNG_INT_BIT_SIZE    0x1UL
+#define DX_HOST_IRR_SYM_DMA_COMPLETED_BIT_SHIFT     0xBUL
+#define DX_HOST_IRR_SYM_DMA_COMPLETED_BIT_SIZE  0x1UL
+#define DX_HOST_IMR_REG_OFFSET  0x0A04UL
+#define DX_HOST_IMR_SRAM_TO_DIN_MASK_BIT_SHIFT  0x4UL
+#define DX_HOST_IMR_SRAM_TO_DIN_MASK_BIT_SIZE   0x1UL
+#define DX_HOST_IMR_DOUT_TO_SRAM_MASK_BIT_SHIFT     0x5UL
+#define DX_HOST_IMR_DOUT_TO_SRAM_MASK_BIT_SIZE  0x1UL
+#define DX_HOST_IMR_MEM_TO_DIN_MASK_BIT_SHIFT   0x6UL
+#define DX_HOST_IMR_MEM_TO_DIN_MASK_BIT_SIZE    0x1UL
+#define DX_HOST_IMR_DOUT_TO_MEM_MASK_BIT_SHIFT  0x7UL
+#define DX_HOST_IMR_DOUT_TO_MEM_MASK_BIT_SIZE   0x1UL
+#define DX_HOST_IMR_AXI_ERR_MASK_BIT_SHIFT  0x8UL
+#define DX_HOST_IMR_AXI_ERR_MASK_BIT_SIZE   0x1UL
+#define DX_HOST_IMR_PKA_EXP_MASK_BIT_SHIFT  0x9UL
+#define DX_HOST_IMR_PKA_EXP_MASK_BIT_SIZE   0x1UL
+#define DX_HOST_IMR_RNG_INT_MASK_BIT_SHIFT  0xAUL
+#define DX_HOST_IMR_RNG_INT_MASK_BIT_SIZE   0x1UL
+#define DX_HOST_IMR_SYM_DMA_COMPLETED_MASK_BIT_SHIFT    0xBUL
+#define DX_HOST_IMR_SYM_DMA_COMPLETED_MASK_BIT_SIZE     0x1UL
+#define DX_HOST_ICR_REG_OFFSET  0x0A08UL
+#define DX_HOST_ICR_SRAM_TO_DIN_CLEAR_BIT_SHIFT     0x4UL
+#define DX_HOST_ICR_SRAM_TO_DIN_CLEAR_BIT_SIZE  0x1UL
+#define DX_HOST_ICR_DOUT_TO_SRAM_CLEAR_BIT_SHIFT    0x5UL
+#define DX_HOST_ICR_DOUT_TO_SRAM_CLEAR_BIT_SIZE     0x1UL
+#define DX_HOST_ICR_MEM_TO_DIN_CLEAR_BIT_SHIFT  0x6UL
+#define DX_HOST_ICR_MEM_TO_DIN_CLEAR_BIT_SIZE   0x1UL
+#define DX_HOST_ICR_DOUT_TO_MEM_CLEAR_BIT_SHIFT     0x7UL
+#define DX_HOST_ICR_DOUT_TO_MEM_CLEAR_BIT_SIZE  0x1UL
+#define DX_HOST_ICR_AXI_ERR_CLEAR_BIT_SHIFT     0x8UL
+#define DX_HOST_ICR_AXI_ERR_CLEAR_BIT_SIZE  0x1UL
+#define DX_HOST_ICR_PKA_EXP_CLEAR_BIT_SHIFT     0x9UL
+#define DX_HOST_ICR_PKA_EXP_CLEAR_BIT_SIZE  0x1UL
+#define DX_HOST_ICR_RNG_INT_CLEAR_BIT_SHIFT     0xAUL
+#define DX_HOST_ICR_RNG_INT_CLEAR_BIT_SIZE  0x1UL
+#define DX_HOST_ICR_SYM_DMA_COMPLETED_CLEAR_BIT_SHIFT   0xBUL
+#define DX_HOST_ICR_SYM_DMA_COMPLETED_CLEAR_BIT_SIZE    0x1UL
+#define DX_HOST_ENDIAN_REG_OFFSET   0x0A0CUL
+#define DX_HOST_ENDIAN_DOUT_WR_BG_BIT_SHIFT     0x3UL
+#define DX_HOST_ENDIAN_DOUT_WR_BG_BIT_SIZE  0x1UL
+#define DX_HOST_ENDIAN_DIN_RD_BG_BIT_SHIFT  0x7UL
+#define DX_HOST_ENDIAN_DIN_RD_BG_BIT_SIZE   0x1UL
+#define DX_HOST_ENDIAN_DOUT_WR_WBG_BIT_SHIFT    0xBUL
+#define DX_HOST_ENDIAN_DOUT_WR_WBG_BIT_SIZE     0x1UL
+#define DX_HOST_ENDIAN_DIN_RD_WBG_BIT_SHIFT     0xFUL
+#define DX_HOST_ENDIAN_DIN_RD_WBG_BIT_SIZE  0x1UL
+#define DX_HOST_SIGNATURE_REG_OFFSET    0x0A24UL
+#define DX_HOST_SIGNATURE_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_SIGNATURE_VALUE_BIT_SIZE    0x20UL
+#define DX_HOST_BOOT_REG_OFFSET     0x0A28UL
+#define DX_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SHIFT     0x0UL
+#define DX_HOST_BOOT_SYNTHESIS_CONFIG_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SHIFT     0x1UL
+#define DX_HOST_BOOT_LARGE_RKEK_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SHIFT  0x2UL
+#define DX_HOST_BOOT_HASH_IN_FUSES_LOCAL_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SHIFT    0x3UL
+#define DX_HOST_BOOT_EXT_MEM_SECURED_LOCAL_BIT_SIZE     0x1UL
+#define DX_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SHIFT  0x5UL
+#define DX_HOST_BOOT_RKEK_ECC_EXISTS_LOCAL_N_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SHIFT  0x6UL
+#define DX_HOST_BOOT_SRAM_SIZE_LOCAL_BIT_SIZE   0x3UL
+#define DX_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SHIFT     0x9UL
+#define DX_HOST_BOOT_DSCRPTR_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SHIFT     0xAUL
+#define DX_HOST_BOOT_PAU_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SHIFT     0xBUL
+#define DX_HOST_BOOT_RNG_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SHIFT     0xCUL
+#define DX_HOST_BOOT_PKA_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SHIFT     0xDUL
+#define DX_HOST_BOOT_RC4_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SHIFT  0xEUL
+#define DX_HOST_BOOT_SHA_512_PRSNT_LOCAL_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SHIFT  0xFUL
+#define DX_HOST_BOOT_SHA_256_PRSNT_LOCAL_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SHIFT  0x10UL
+#define DX_HOST_BOOT_MD5_PRSNT_LOCAL_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SHIFT    0x11UL
+#define DX_HOST_BOOT_HASH_EXISTS_LOCAL_BIT_SIZE     0x1UL
+#define DX_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SHIFT  0x12UL
+#define DX_HOST_BOOT_C2_EXISTS_LOCAL_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SHIFT     0x13UL
+#define DX_HOST_BOOT_DES_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SHIFT    0x14UL
+#define DX_HOST_BOOT_AES_XCBC_MAC_EXISTS_LOCAL_BIT_SIZE     0x1UL
+#define DX_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SHIFT    0x15UL
+#define DX_HOST_BOOT_AES_CMAC_EXISTS_LOCAL_BIT_SIZE     0x1UL
+#define DX_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SHIFT     0x16UL
+#define DX_HOST_BOOT_AES_CCM_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SHIFT  0x17UL
+#define DX_HOST_BOOT_AES_XEX_HW_T_CALC_LOCAL_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SHIFT     0x18UL
+#define DX_HOST_BOOT_AES_XEX_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SHIFT     0x19UL
+#define DX_HOST_BOOT_CTR_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SHIFT    0x1AUL
+#define DX_HOST_BOOT_AES_DIN_BYTE_RESOLUTION_LOCAL_BIT_SIZE     0x1UL
+#define DX_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SHIFT  0x1BUL
+#define DX_HOST_BOOT_TUNNELING_ENB_LOCAL_BIT_SIZE   0x1UL
+#define DX_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SHIFT    0x1CUL
+#define DX_HOST_BOOT_SUPPORT_256_192_KEY_LOCAL_BIT_SIZE     0x1UL
+#define DX_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SHIFT   0x1DUL
+#define DX_HOST_BOOT_ONLY_ENCRYPT_LOCAL_BIT_SIZE    0x1UL
+#define DX_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SHIFT     0x1EUL
+#define DX_HOST_BOOT_AES_EXISTS_LOCAL_BIT_SIZE  0x1UL
+#define DX_HOST_CRYPTOKEY_SEL_REG_OFFSET    0x0A38UL
+#define DX_HOST_CRYPTOKEY_SEL_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_CRYPTOKEY_SEL_VALUE_BIT_SIZE    0x3UL
+#define DX_HOST_CORE_CLK_GATING_ENABLE_REG_OFFSET   0x0A78UL
+#define DX_HOST_CORE_CLK_GATING_ENABLE_VALUE_BIT_SHIFT  0x0UL
+#define DX_HOST_CORE_CLK_GATING_ENABLE_VALUE_BIT_SIZE   0x1UL
+#define DX_HOST_CC_IS_IDLE_REG_OFFSET   0x0A7CUL
+#define DX_HOST_CC_IS_IDLE_HOST_CC_IS_IDLE_BIT_SHIFT    0x0UL
+#define DX_HOST_CC_IS_IDLE_HOST_CC_IS_IDLE_BIT_SIZE     0x1UL
+#define DX_HOST_CC_IS_IDLE_HOST_CC_IS_IDLE_EVENT_BIT_SHIFT  0x1UL
+#define DX_HOST_CC_IS_IDLE_HOST_CC_IS_IDLE_EVENT_BIT_SIZE   0x1UL
+#define DX_HOST_CC_IS_IDLE_SYM_IS_BUSY_BIT_SHIFT    0x2UL
+#define DX_HOST_CC_IS_IDLE_SYM_IS_BUSY_BIT_SIZE     0x1UL
+#define DX_HOST_CC_IS_IDLE_AHB_IS_IDLE_BIT_SHIFT    0x3UL
+#define DX_HOST_CC_IS_IDLE_AHB_IS_IDLE_BIT_SIZE     0x1UL
+#define DX_HOST_CC_IS_IDLE_NVM_ARB_IS_IDLE_BIT_SHIFT    0x4UL
+#define DX_HOST_CC_IS_IDLE_NVM_ARB_IS_IDLE_BIT_SIZE     0x1UL
+#define DX_HOST_CC_IS_IDLE_NVM_IS_IDLE_BIT_SHIFT    0x5UL
+#define DX_HOST_CC_IS_IDLE_NVM_IS_IDLE_BIT_SIZE     0x1UL
+#define DX_HOST_CC_IS_IDLE_FATAL_WR_BIT_SHIFT   0x6UL
+#define DX_HOST_CC_IS_IDLE_FATAL_WR_BIT_SIZE    0x1UL
+#define DX_HOST_CC_IS_IDLE_RNG_IS_IDLE_BIT_SHIFT    0x7UL
+#define DX_HOST_CC_IS_IDLE_RNG_IS_IDLE_BIT_SIZE     0x1UL
+#define DX_HOST_CC_IS_IDLE_PKA_IS_IDLE_BIT_SHIFT    0x8UL
+#define DX_HOST_CC_IS_IDLE_PKA_IS_IDLE_BIT_SIZE     0x1UL
+#define DX_HOST_CC_IS_IDLE_CRYPTO_IS_IDLE_BIT_SHIFT     0x9UL
+#define DX_HOST_CC_IS_IDLE_CRYPTO_IS_IDLE_BIT_SIZE  0x1UL
+#define DX_HOST_POWERDOWN_REG_OFFSET    0x0A80UL
+#define DX_HOST_POWERDOWN_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_POWERDOWN_VALUE_BIT_SIZE    0x1UL
+#define DX_HOST_REMOVE_GHASH_ENGINE_REG_OFFSET  0x0A84UL
+#define DX_HOST_REMOVE_GHASH_ENGINE_VALUE_BIT_SHIFT     0x0UL
+#define DX_HOST_REMOVE_GHASH_ENGINE_VALUE_BIT_SIZE  0x1UL
+#define DX_HOST_REMOVE_CHACHA_ENGINE_REG_OFFSET     0x0A88UL
+#define DX_HOST_REMOVE_CHACHA_ENGINE_VALUE_BIT_SHIFT    0x0UL
+#define DX_HOST_REMOVE_CHACHA_ENGINE_VALUE_BIT_SIZE     0x1UL
+// --------------------------------------
+// BLOCK: HOST_SRAM
+// --------------------------------------
+#define DX_SRAM_DATA_REG_OFFSET     0x0F00UL
+#define DX_SRAM_DATA_VALUE_BIT_SHIFT    0x0UL
+#define DX_SRAM_DATA_VALUE_BIT_SIZE     0x20UL
+#define DX_SRAM_ADDR_REG_OFFSET     0x0F04UL
+#define DX_SRAM_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_SRAM_ADDR_VALUE_BIT_SIZE     0xFUL
+#define DX_SRAM_DATA_READY_REG_OFFSET   0x0F08UL
+#define DX_SRAM_DATA_READY_VALUE_BIT_SHIFT  0x0UL
+#define DX_SRAM_DATA_READY_VALUE_BIT_SIZE   0x1UL
+#endif //__DX_HOST_H__
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_id_registers.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_id_registers.h
new file mode 100644
index 0000000..737ae51
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_id_registers.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_ID_REGS_H__
+#define __DX_ID_REGS_H__
+
+// --------------------------------------
+// BLOCK: ID_REGISTERS
+// --------------------------------------
+#define DX_PERIPHERAL_ID_4_REG_OFFSET   0x0FD0UL
+#define DX_PERIPHERAL_ID_4_VALUE_BIT_SHIFT  0x0UL
+#define DX_PERIPHERAL_ID_4_VALUE_BIT_SIZE   0x4UL
+#define DX_PIDRESERVED0_REG_OFFSET  0x0FD4UL
+#define DX_PIDRESERVED1_REG_OFFSET  0x0FD8UL
+#define DX_PIDRESERVED2_REG_OFFSET  0x0FDCUL
+#define DX_PERIPHERAL_ID_0_REG_OFFSET   0x0FE0UL
+#define DX_PERIPHERAL_ID_0_VALUE_BIT_SHIFT  0x0UL
+#define DX_PERIPHERAL_ID_0_VALUE_BIT_SIZE   0x8UL
+#define DX_PERIPHERAL_ID_1_REG_OFFSET   0x0FE4UL
+#define DX_PERIPHERAL_ID_1_PART_1_BIT_SHIFT     0x0UL
+#define DX_PERIPHERAL_ID_1_PART_1_BIT_SIZE  0x4UL
+#define DX_PERIPHERAL_ID_1_DES_0_JEP106_BIT_SHIFT   0x4UL
+#define DX_PERIPHERAL_ID_1_DES_0_JEP106_BIT_SIZE    0x4UL
+#define DX_PERIPHERAL_ID_2_REG_OFFSET   0x0FE8UL
+#define DX_PERIPHERAL_ID_2_DES_1_JEP106_BIT_SHIFT   0x0UL
+#define DX_PERIPHERAL_ID_2_DES_1_JEP106_BIT_SIZE    0x3UL
+#define DX_PERIPHERAL_ID_2_JEDEC_BIT_SHIFT  0x3UL
+#define DX_PERIPHERAL_ID_2_JEDEC_BIT_SIZE   0x1UL
+#define DX_PERIPHERAL_ID_2_REVISION_BIT_SHIFT   0x4UL
+#define DX_PERIPHERAL_ID_2_REVISION_BIT_SIZE    0x4UL
+#define DX_PERIPHERAL_ID_3_REG_OFFSET   0x0FECUL
+#define DX_PERIPHERAL_ID_3_CMOD_BIT_SHIFT   0x0UL
+#define DX_PERIPHERAL_ID_3_CMOD_BIT_SIZE    0x4UL
+#define DX_PERIPHERAL_ID_3_REVAND_BIT_SHIFT     0x4UL
+#define DX_PERIPHERAL_ID_3_REVAND_BIT_SIZE  0x4UL
+#define DX_COMPONENT_ID_0_REG_OFFSET    0x0FF0UL
+#define DX_COMPONENT_ID_0_VALUE_BIT_SHIFT   0x0UL
+#define DX_COMPONENT_ID_0_VALUE_BIT_SIZE    0x8UL
+#define DX_COMPONENT_ID_1_REG_OFFSET    0x0FF4UL
+#define DX_COMPONENT_ID_1_PRMBL_1_BIT_SHIFT     0x0UL
+#define DX_COMPONENT_ID_1_PRMBL_1_BIT_SIZE  0x4UL
+#define DX_COMPONENT_ID_1_CLASS_BIT_SHIFT   0x4UL
+#define DX_COMPONENT_ID_1_CLASS_BIT_SIZE    0x4UL
+#define DX_COMPONENT_ID_2_REG_OFFSET    0x0FF8UL
+#define DX_COMPONENT_ID_2_VALUE_BIT_SHIFT   0x0UL
+#define DX_COMPONENT_ID_2_VALUE_BIT_SIZE    0x8UL
+#define DX_COMPONENT_ID_3_REG_OFFSET    0x0FFCUL
+#define DX_COMPONENT_ID_3_VALUE_BIT_SHIFT   0x0UL
+#define DX_COMPONENT_ID_3_VALUE_BIT_SIZE    0x8UL
+
+#endif //__DX_ID_REGS_H__
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_nvm.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_nvm.h
new file mode 100644
index 0000000..3122261
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_nvm.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_NVM_H__
+#define __DX_NVM_H__
+
+// --------------------------------------
+// BLOCK: NVM
+// --------------------------------------
+#define DX_AIB_FUSE_PROG_COMPLETED_REG_OFFSET   0x1F04UL
+#define DX_AIB_FUSE_PROG_COMPLETED_VALUE_BIT_SHIFT  0x0UL
+#define DX_AIB_FUSE_PROG_COMPLETED_VALUE_BIT_SIZE   0x1UL
+#define DX_NVM_DEBUG_STATUS_REG_OFFSET  0x1F08UL
+#define DX_NVM_DEBUG_STATUS_VALUE_BIT_SHIFT     0x1UL
+#define DX_NVM_DEBUG_STATUS_VALUE_BIT_SIZE  0x3UL
+#define DX_LCS_IS_VALID_REG_OFFSET  0x1F0CUL
+#define DX_LCS_IS_VALID_VALUE_BIT_SHIFT     0x0UL
+#define DX_LCS_IS_VALID_VALUE_BIT_SIZE  0x1UL
+#define DX_NVM_IS_IDLE_REG_OFFSET   0x1F10UL
+#define DX_NVM_IS_IDLE_VALUE_BIT_SHIFT  0x0UL
+#define DX_NVM_IS_IDLE_VALUE_BIT_SIZE   0x1UL
+#define DX_LCS_REG_REG_OFFSET   0x1F14UL
+#define DX_LCS_REG_LCS_REG_BIT_SHIFT    0x0UL
+#define DX_LCS_REG_LCS_REG_BIT_SIZE     0x3UL
+#define DX_LCS_REG_ERROR_KDR_ZERO_CNT_BIT_SHIFT     0x8UL
+#define DX_LCS_REG_ERROR_KDR_ZERO_CNT_BIT_SIZE  0x1UL
+#define DX_LCS_REG_ERROR_PROV_ZERO_CNT_BIT_SHIFT    0x9UL
+#define DX_LCS_REG_ERROR_PROV_ZERO_CNT_BIT_SIZE     0x1UL
+#define DX_LCS_REG_ERROR_KCE_ZERO_CNT_BIT_SHIFT     0xAUL
+#define DX_LCS_REG_ERROR_KCE_ZERO_CNT_BIT_SIZE  0x1UL
+#define DX_LCS_REG_ERROR_KPICV_ZERO_CNT_BIT_SHIFT   0xBUL
+#define DX_LCS_REG_ERROR_KPICV_ZERO_CNT_BIT_SIZE    0x1UL
+#define DX_LCS_REG_ERROR_KCEICV_ZERO_CNT_BIT_SHIFT  0xCUL
+#define DX_LCS_REG_ERROR_KCEICV_ZERO_CNT_BIT_SIZE   0x1UL
+#define DX_HOST_SHADOW_KDR_REG_REG_OFFSET   0x1F18UL
+#define DX_HOST_SHADOW_KDR_REG_VALUE_BIT_SHIFT  0x0UL
+#define DX_HOST_SHADOW_KDR_REG_VALUE_BIT_SIZE   0x1UL
+#define DX_HOST_SHADOW_KCP_REG_REG_OFFSET   0x1F1CUL
+#define DX_HOST_SHADOW_KCP_REG_VALUE_BIT_SHIFT  0x0UL
+#define DX_HOST_SHADOW_KCP_REG_VALUE_BIT_SIZE   0x1UL
+#define DX_HOST_SHADOW_KCE_REG_REG_OFFSET   0x1F20UL
+#define DX_HOST_SHADOW_KCE_REG_VALUE_BIT_SHIFT  0x0UL
+#define DX_HOST_SHADOW_KCE_REG_VALUE_BIT_SIZE   0x1UL
+#define DX_HOST_SHADOW_KPICV_REG_REG_OFFSET     0x1F24UL
+#define DX_HOST_SHADOW_KPICV_REG_VALUE_BIT_SHIFT    0x0UL
+#define DX_HOST_SHADOW_KPICV_REG_VALUE_BIT_SIZE     0x1UL
+#define DX_HOST_SHADOW_KCEICV_REG_REG_OFFSET    0x1F28UL
+#define DX_HOST_SHADOW_KCEICV_REG_VALUE_BIT_SHIFT   0x0UL
+#define DX_HOST_SHADOW_KCEICV_REG_VALUE_BIT_SIZE    0x1UL
+#define DX_OTP_ADDR_WIDTH_DEF_REG_OFFSET    0x1F2CUL
+#define DX_OTP_ADDR_WIDTH_DEF_VALUE_BIT_SHIFT   0x0UL
+#define DX_OTP_ADDR_WIDTH_DEF_VALUE_BIT_SIZE    0x4UL
+
+#endif //__DX_NVM_H__
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_reg_base_host.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_reg_base_host.h
new file mode 100644
index 0000000..001de06
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_reg_base_host.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __DX_REG_BASE_HOST_H__
+#define __DX_REG_BASE_HOST_H__
+
+/* Identify platform: Xilinx Zynq7000 ZC706 */
+#define DX_PLAT_ZYNQ7000 1
+#define DX_PLAT_ZYNQ7000_ZC706 1
+
+#define DX_BASE_CC 0x60000000
+
+#define DX_BASE_ENV_REGS 0x40008000
+#define DX_BASE_ENV_CC_MEMORIES 0x40008000
+#define DX_BASE_ENV_PERF_RAM 0x40009000
+
+#define DX_BASE_HOST_RGF 0x0UL
+#define DX_BASE_CRY_KERNEL     0x0UL
+#define DX_BASE_ROM     0x40000000
+
+#define DX_BASE_RNG 0x0000UL
+#endif /*__DX_REG_BASE_HOST_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_reg_common.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_reg_common.h
new file mode 100644
index 0000000..b865651
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_reg_common.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __DX_REG_COMMON_H__
+#define __DX_REG_COMMON_H__
+
+#define DX_DEV_SIGNATURE 0x10E00000UL
+
+#endif /*__DX_REG_COMMON_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_rng.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_rng.h
new file mode 100644
index 0000000..4de479d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/dx_rng.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_RNG_H__
+#define __DX_RNG_H__
+
+// --------------------------------------
+// BLOCK: RNG
+// --------------------------------------
+#define DX_RNG_IMR_REG_OFFSET   0x0100UL
+#define DX_RNG_IMR_EHR_VALID_INT_MASK_BIT_SHIFT     0x0UL
+#define DX_RNG_IMR_EHR_VALID_INT_MASK_BIT_SIZE  0x1UL
+#define DX_RNG_IMR_AUTOCORR_ERR_INT_MASK_BIT_SHIFT  0x1UL
+#define DX_RNG_IMR_AUTOCORR_ERR_INT_MASK_BIT_SIZE   0x1UL
+#define DX_RNG_IMR_CRNGT_ERR_INT_MASK_BIT_SHIFT     0x2UL
+#define DX_RNG_IMR_CRNGT_ERR_INT_MASK_BIT_SIZE  0x1UL
+#define DX_RNG_IMR_VN_ERR_INT_MASK_BIT_SHIFT    0x3UL
+#define DX_RNG_IMR_VN_ERR_INT_MASK_BIT_SIZE     0x1UL
+#define DX_RNG_IMR_WATCHDOG_INT_MASK_BIT_SHIFT  0x4UL
+#define DX_RNG_IMR_WATCHDOG_INT_MASK_BIT_SIZE   0x1UL
+#define DX_RNG_IMR_RNG_DMA_DONE_INT_BIT_SHIFT   0x5UL
+#define DX_RNG_IMR_RNG_DMA_DONE_INT_BIT_SIZE    0x1UL
+#define DX_RNG_ISR_REG_OFFSET   0x0104UL
+#define DX_RNG_ISR_EHR_VALID_BIT_SHIFT  0x0UL
+#define DX_RNG_ISR_EHR_VALID_BIT_SIZE   0x1UL
+#define DX_RNG_ISR_AUTOCORR_ERR_BIT_SHIFT   0x1UL
+#define DX_RNG_ISR_AUTOCORR_ERR_BIT_SIZE    0x1UL
+#define DX_RNG_ISR_CRNGT_ERR_BIT_SHIFT  0x2UL
+#define DX_RNG_ISR_CRNGT_ERR_BIT_SIZE   0x1UL
+#define DX_RNG_ISR_VN_ERR_BIT_SHIFT     0x3UL
+#define DX_RNG_ISR_VN_ERR_BIT_SIZE  0x1UL
+#define DX_RNG_ISR_RNG_DMA_DONE_BIT_SHIFT   0x5UL
+#define DX_RNG_ISR_RNG_DMA_DONE_BIT_SIZE    0x1UL
+#define DX_RNG_ISR_RESEEDING_DONE_BIT_SHIFT     0x10UL
+#define DX_RNG_ISR_RESEEDING_DONE_BIT_SIZE  0x1UL
+#define DX_RNG_ISR_INSTANTIATION_DONE_BIT_SHIFT     0x11UL
+#define DX_RNG_ISR_INSTANTIATION_DONE_BIT_SIZE  0x1UL
+#define DX_RNG_ISR_FINAL_UPDATE_DONE_BIT_SHIFT  0x12UL
+#define DX_RNG_ISR_FINAL_UPDATE_DONE_BIT_SIZE   0x1UL
+#define DX_RNG_ISR_OUTPUT_READY_BIT_SHIFT   0x13UL
+#define DX_RNG_ISR_OUTPUT_READY_BIT_SIZE    0x1UL
+#define DX_RNG_ISR_RESEED_CNTR_FULL_BIT_SHIFT   0x14UL
+#define DX_RNG_ISR_RESEED_CNTR_FULL_BIT_SIZE    0x1UL
+#define DX_RNG_ISR_RESEED_CNTR_TOP_40_BIT_SHIFT     0x15UL
+#define DX_RNG_ISR_RESEED_CNTR_TOP_40_BIT_SIZE  0x1UL
+#define DX_RNG_ISR_PRNG_CRNGT_ERR_BIT_SHIFT     0x16UL
+#define DX_RNG_ISR_PRNG_CRNGT_ERR_BIT_SIZE  0x1UL
+#define DX_RNG_ISR_REQ_SIZE_BIT_SHIFT   0x17UL
+#define DX_RNG_ISR_REQ_SIZE_BIT_SIZE    0x1UL
+#define DX_RNG_ISR_KAT_ERR_BIT_SHIFT    0x18UL
+#define DX_RNG_ISR_KAT_ERR_BIT_SIZE     0x1UL
+#define DX_RNG_ISR_WHICH_KAT_ERR_BIT_SHIFT  0x19UL
+#define DX_RNG_ISR_WHICH_KAT_ERR_BIT_SIZE   0x2UL
+#define DX_RNG_ICR_REG_OFFSET   0x0108UL
+#define DX_RNG_ICR_EHR_VALID_BIT_SHIFT  0x0UL
+#define DX_RNG_ICR_EHR_VALID_BIT_SIZE   0x1UL
+#define DX_RNG_ICR_AUTOCORR_ERR_BIT_SHIFT   0x1UL
+#define DX_RNG_ICR_AUTOCORR_ERR_BIT_SIZE    0x1UL
+#define DX_RNG_ICR_CRNGT_ERR_BIT_SHIFT  0x2UL
+#define DX_RNG_ICR_CRNGT_ERR_BIT_SIZE   0x1UL
+#define DX_RNG_ICR_VN_ERR_BIT_SHIFT     0x3UL
+#define DX_RNG_ICR_VN_ERR_BIT_SIZE  0x1UL
+#define DX_RNG_ICR_RNG_WATCHDOG_BIT_SHIFT   0x4UL
+#define DX_RNG_ICR_RNG_WATCHDOG_BIT_SIZE    0x1UL
+#define DX_RNG_ICR_RNG_DMA_DONE_BIT_SHIFT   0x5UL
+#define DX_RNG_ICR_RNG_DMA_DONE_BIT_SIZE    0x1UL
+#define DX_RNG_ICR_RESEEDING_DONE_BIT_SHIFT     0x10UL
+#define DX_RNG_ICR_RESEEDING_DONE_BIT_SIZE  0x1UL
+#define DX_RNG_ICR_INSTANTIATION_DONE_BIT_SHIFT     0x11UL
+#define DX_RNG_ICR_INSTANTIATION_DONE_BIT_SIZE  0x1UL
+#define DX_RNG_ICR_FINAL_UPDATE_DONE_BIT_SHIFT  0x12UL
+#define DX_RNG_ICR_FINAL_UPDATE_DONE_BIT_SIZE   0x1UL
+#define DX_RNG_ICR_OUTPUT_READY_BIT_SHIFT   0x13UL
+#define DX_RNG_ICR_OUTPUT_READY_BIT_SIZE    0x1UL
+#define DX_RNG_ICR_RESEED_CNTR_FULL_BIT_SHIFT   0x14UL
+#define DX_RNG_ICR_RESEED_CNTR_FULL_BIT_SIZE    0x1UL
+#define DX_RNG_ICR_RESEED_CNTR_TOP_40_BIT_SHIFT     0x15UL
+#define DX_RNG_ICR_RESEED_CNTR_TOP_40_BIT_SIZE  0x1UL
+#define DX_RNG_ICR_PRNG_CRNGT_ERR_BIT_SHIFT     0x16UL
+#define DX_RNG_ICR_PRNG_CRNGT_ERR_BIT_SIZE  0x1UL
+#define DX_RNG_ICR_REQ_SIZE_BIT_SHIFT   0x17UL
+#define DX_RNG_ICR_REQ_SIZE_BIT_SIZE    0x1UL
+#define DX_RNG_ICR_KAT_ERR_BIT_SHIFT    0x18UL
+#define DX_RNG_ICR_KAT_ERR_BIT_SIZE     0x1UL
+#define DX_RNG_ICR_WHICH_KAT_ERR_BIT_SHIFT  0x19UL
+#define DX_RNG_ICR_WHICH_KAT_ERR_BIT_SIZE   0x2UL
+#define DX_TRNG_CONFIG_REG_OFFSET   0x010CUL
+#define DX_TRNG_CONFIG_RND_SRC_SEL_BIT_SHIFT    0x0UL
+#define DX_TRNG_CONFIG_RND_SRC_SEL_BIT_SIZE     0x2UL
+#define DX_TRNG_CONFIG_SOP_SEL_BIT_SHIFT    0x2UL
+#define DX_TRNG_CONFIG_SOP_SEL_BIT_SIZE     0x1UL
+#define DX_TRNG_VALID_REG_OFFSET    0x0110UL
+#define DX_TRNG_VALID_VALUE_BIT_SHIFT   0x0UL
+#define DX_TRNG_VALID_VALUE_BIT_SIZE    0x1UL
+#define DX_EHR_DATA_0_REG_OFFSET    0x0114UL
+#define DX_EHR_DATA_0_VALUE_BIT_SHIFT   0x0UL
+#define DX_EHR_DATA_0_VALUE_BIT_SIZE    0x20UL
+#define DX_EHR_DATA_1_REG_OFFSET    0x0118UL
+#define DX_EHR_DATA_1_VALUE_BIT_SHIFT   0x0UL
+#define DX_EHR_DATA_1_VALUE_BIT_SIZE    0x20UL
+#define DX_EHR_DATA_2_REG_OFFSET    0x011CUL
+#define DX_EHR_DATA_2_VALUE_BIT_SHIFT   0x0UL
+#define DX_EHR_DATA_2_VALUE_BIT_SIZE    0x20UL
+#define DX_EHR_DATA_3_REG_OFFSET    0x0120UL
+#define DX_EHR_DATA_3_VALUE_BIT_SHIFT   0x0UL
+#define DX_EHR_DATA_3_VALUE_BIT_SIZE    0x20UL
+#define DX_EHR_DATA_4_REG_OFFSET    0x0124UL
+#define DX_EHR_DATA_4_VALUE_BIT_SHIFT   0x0UL
+#define DX_EHR_DATA_4_VALUE_BIT_SIZE    0x20UL
+#define DX_EHR_DATA_5_REG_OFFSET    0x0128UL
+#define DX_EHR_DATA_5_VALUE_BIT_SHIFT   0x0UL
+#define DX_EHR_DATA_5_VALUE_BIT_SIZE    0x20UL
+#define DX_RND_SOURCE_ENABLE_REG_OFFSET     0x012CUL
+#define DX_RND_SOURCE_ENABLE_VALUE_BIT_SHIFT    0x0UL
+#define DX_RND_SOURCE_ENABLE_VALUE_BIT_SIZE     0x1UL
+#define DX_SAMPLE_CNT1_REG_OFFSET   0x0130UL
+#define DX_SAMPLE_CNT1_VALUE_BIT_SHIFT  0x0UL
+#define DX_SAMPLE_CNT1_VALUE_BIT_SIZE   0x20UL
+#define DX_AUTOCORR_STATISTIC_REG_OFFSET    0x0134UL
+#define DX_AUTOCORR_STATISTIC_AUTOCORR_TRYS_BIT_SHIFT   0x0UL
+#define DX_AUTOCORR_STATISTIC_AUTOCORR_TRYS_BIT_SIZE    0xEUL
+#define DX_AUTOCORR_STATISTIC_AUTOCORR_FAILS_BIT_SHIFT  0xEUL
+#define DX_AUTOCORR_STATISTIC_AUTOCORR_FAILS_BIT_SIZE   0x8UL
+#define DX_TRNG_DEBUG_CONTROL_REG_OFFSET    0x0138UL
+#define DX_TRNG_DEBUG_CONTROL_VNC_BYPASS_BIT_SHIFT  0x1UL
+#define DX_TRNG_DEBUG_CONTROL_VNC_BYPASS_BIT_SIZE   0x1UL
+#define DX_TRNG_DEBUG_CONTROL_TRNG_CRNGT_BYPASS_BIT_SHIFT   0x2UL
+#define DX_TRNG_DEBUG_CONTROL_TRNG_CRNGT_BYPASS_BIT_SIZE    0x1UL
+#define DX_TRNG_DEBUG_CONTROL_AUTO_CORRELATE_BYPASS_BIT_SHIFT   0x3UL
+#define DX_TRNG_DEBUG_CONTROL_AUTO_CORRELATE_BYPASS_BIT_SIZE    0x1UL
+#define DX_RNG_SW_RESET_REG_OFFSET  0x0140UL
+#define DX_RNG_SW_RESET_VALUE_BIT_SHIFT     0x0UL
+#define DX_RNG_SW_RESET_VALUE_BIT_SIZE  0x1UL
+#define DX_RNG_DEBUG_EN_INPUT_REG_OFFSET    0x01B4UL
+#define DX_RNG_DEBUG_EN_INPUT_VALUE_BIT_SHIFT   0x0UL
+#define DX_RNG_DEBUG_EN_INPUT_VALUE_BIT_SIZE    0x1UL
+#define DX_RNG_BUSY_REG_OFFSET  0x01B8UL
+#define DX_RNG_BUSY_RNG_BUSY_BIT_SHIFT  0x0UL
+#define DX_RNG_BUSY_RNG_BUSY_BIT_SIZE   0x1UL
+#define DX_RNG_BUSY_TRNG_BUSY_BIT_SHIFT     0x1UL
+#define DX_RNG_BUSY_TRNG_BUSY_BIT_SIZE  0x1UL
+#define DX_RNG_BUSY_PRNG_BUSY_BIT_SHIFT     0x2UL
+#define DX_RNG_BUSY_PRNG_BUSY_BIT_SIZE  0x1UL
+#define DX_RST_BITS_COUNTER_REG_OFFSET  0x01BCUL
+#define DX_RST_BITS_COUNTER_VALUE_BIT_SHIFT     0x0UL
+#define DX_RST_BITS_COUNTER_VALUE_BIT_SIZE  0x1UL
+#define DX_RNG_VERSION_REG_OFFSET   0x01C0UL
+#define DX_RNG_VERSION_EHR_WIDTH_192_BIT_SHIFT  0x0UL
+#define DX_RNG_VERSION_EHR_WIDTH_192_BIT_SIZE   0x1UL
+#define DX_RNG_VERSION_CRNGT_EXISTS_BIT_SHIFT   0x1UL
+#define DX_RNG_VERSION_CRNGT_EXISTS_BIT_SIZE    0x1UL
+#define DX_RNG_VERSION_AUTOCORR_EXISTS_BIT_SHIFT    0x2UL
+#define DX_RNG_VERSION_AUTOCORR_EXISTS_BIT_SIZE     0x1UL
+#define DX_RNG_VERSION_TRNG_TESTS_BYPASS_EN_BIT_SHIFT   0x3UL
+#define DX_RNG_VERSION_TRNG_TESTS_BYPASS_EN_BIT_SIZE    0x1UL
+#define DX_RNG_VERSION_PRNG_EXISTS_BIT_SHIFT    0x4UL
+#define DX_RNG_VERSION_PRNG_EXISTS_BIT_SIZE     0x1UL
+#define DX_RNG_VERSION_KAT_EXISTS_BIT_SHIFT     0x5UL
+#define DX_RNG_VERSION_KAT_EXISTS_BIT_SIZE  0x1UL
+#define DX_RNG_VERSION_RESEEDING_EXISTS_BIT_SHIFT   0x6UL
+#define DX_RNG_VERSION_RESEEDING_EXISTS_BIT_SIZE    0x1UL
+#define DX_RNG_VERSION_RNG_USE_5_SBOXES_BIT_SHIFT   0x7UL
+#define DX_RNG_VERSION_RNG_USE_5_SBOXES_BIT_SIZE    0x1UL
+#define DX_RNG_CLK_ENABLE_REG_OFFSET    0x01C4UL
+#define DX_RNG_CLK_ENABLE_VALUE_BIT_SHIFT   0x0UL
+#define DX_RNG_CLK_ENABLE_VALUE_BIT_SIZE    0x1UL
+#define DX_RNG_DMA_ENABLE_REG_OFFSET    0x01C8UL
+#define DX_RNG_DMA_ENABLE_VALUE_BIT_SHIFT   0x0UL
+#define DX_RNG_DMA_ENABLE_VALUE_BIT_SIZE    0x1UL
+#define DX_RNG_DMA_SRC_MASK_REG_OFFSET  0x01CCUL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL0_BIT_SHIFT   0x0UL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL0_BIT_SIZE    0x1UL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL1_BIT_SHIFT   0x1UL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL1_BIT_SIZE    0x1UL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL2_BIT_SHIFT   0x2UL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL2_BIT_SIZE    0x1UL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL3_BIT_SHIFT   0x3UL
+#define DX_RNG_DMA_SRC_MASK_EN_SRC_SEL3_BIT_SIZE    0x1UL
+#define DX_RNG_DMA_SRAM_ADDR_REG_OFFSET     0x01D0UL
+#define DX_RNG_DMA_SRAM_ADDR_VALUE_BIT_SHIFT    0x0UL
+#define DX_RNG_DMA_SRAM_ADDR_VALUE_BIT_SIZE     0xBUL
+#define DX_RNG_DMA_SAMPLES_NUM_REG_OFFSET   0x01D4UL
+#define DX_RNG_DMA_SAMPLES_NUM_VALUE_BIT_SHIFT  0x0UL
+#define DX_RNG_DMA_SAMPLES_NUM_VALUE_BIT_SIZE   0x8UL
+#define DX_RNG_WATCHDOG_VAL_REG_OFFSET  0x01D8UL
+#define DX_RNG_WATCHDOG_VAL_VALUE_BIT_SHIFT     0x0UL
+#define DX_RNG_WATCHDOG_VAL_VALUE_BIT_SIZE  0x20UL
+#define DX_RNG_DMA_STATUS_REG_OFFSET    0x01DCUL
+#define DX_RNG_DMA_STATUS_RNG_DMA_BUSY_BIT_SHIFT    0x0UL
+#define DX_RNG_DMA_STATUS_RNG_DMA_BUSY_BIT_SIZE     0x1UL
+#define DX_RNG_DMA_STATUS_DMA_SRC_SEL_BIT_SHIFT     0x1UL
+#define DX_RNG_DMA_STATUS_DMA_SRC_SEL_BIT_SIZE  0x2UL
+#define DX_RNG_DMA_STATUS_NUM_OF_SAMPLES_BIT_SHIFT  0x3UL
+#define DX_RNG_DMA_STATUS_NUM_OF_SAMPLES_BIT_SIZE   0x8UL
+#endif //__DX_RNG_H__
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/mps2.cm33/dx_reg_base_host.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/mps2.cm33/dx_reg_base_host.h
new file mode 100644
index 0000000..54f0413
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/mps2.cm33/dx_reg_base_host.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_REG_BASE_HOST_H__
+#define __DX_REG_BASE_HOST_H__
+
+/* Identify platform: ARM MPS2 PLUS */
+#define DX_PLAT_MPS2_PLUS 1
+
+#define DX_BASE_CC 0x50088000
+#define DX_BASE_CODE 0x1E000000
+
+#define DX_BASE_ENV_REGS 0x400A8000
+#define DX_BASE_ENV_NVM_LOW 0x400AA000
+#define DX_BASE_ENV_NVM_HI  0x400AB000
+#define DX_BASE_ENV_PERF_RAM 0x400A9000
+
+#define DX_BASE_HOST_RGF 0x0UL
+#define DX_BASE_CRY_KERNEL     0x0UL
+
+#define DX_BASE_RNG 0x0000UL
+
+#endif /*__DX_REG_BASE_HOST_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/mps2/dx_reg_base_host.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/mps2/dx_reg_base_host.h
new file mode 100644
index 0000000..ac957b0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/mps2/dx_reg_base_host.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_REG_BASE_HOST_H__
+#define __DX_REG_BASE_HOST_H__
+
+/* Identify platform: ARM MPS2 PLUS */
+#define DX_PLAT_MPS2_PLUS 1
+
+#define DX_BASE_CC 0x50010000
+#define DX_BASE_CODE 0x50030000
+
+#define DX_BASE_ENV_REGS 0x50028000
+#define DX_BASE_ENV_NVM_LOW 0x5002A000
+#define DX_BASE_ENV_NVM_HI  0x5002B000
+#define DX_BASE_ENV_PERF_RAM 0x40009000
+
+#define DX_BASE_HOST_RGF 0x0UL
+#define DX_BASE_CRY_KERNEL     0x0UL
+
+#define DX_BASE_RNG 0x0000UL
+#endif /*__DX_REG_BASE_HOST_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/musca_b1/dx_reg_base_host.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/musca_b1/dx_reg_base_host.h
new file mode 100644
index 0000000..1d97bf1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/musca_b1/dx_reg_base_host.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __DX_REG_BASE_HOST_H__
+#define __DX_REG_BASE_HOST_H__
+
+/* Identify platform: ARM MUSCA_B1 */
+#define DX_PLAT_MUSCA_B1 1
+
+#define DX_BASE_CC 0x50088000
+#define DX_BASE_CODE 0x50030000 //# not used
+
+#define DX_BASE_ENV_REGS 0x500A0000 //TODO need confirm
+
+#define DX_BASE_HOST_RGF 0x0UL
+#define DX_BASE_CRY_KERNEL     0x0UL
+
+#define DX_BASE_RNG 0x0000UL
+#endif /*__DX_REG_BASE_HOST_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/hw/include/zynq/dx_reg_base_host.h b/lib/ext/cryptocell-312-runtime/shared/hw/include/zynq/dx_reg_base_host.h
new file mode 100644
index 0000000..001de06
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/hw/include/zynq/dx_reg_base_host.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef __DX_REG_BASE_HOST_H__
+#define __DX_REG_BASE_HOST_H__
+
+/* Identify platform: Xilinx Zynq7000 ZC706 */
+#define DX_PLAT_ZYNQ7000 1
+#define DX_PLAT_ZYNQ7000_ZC706 1
+
+#define DX_BASE_CC 0x60000000
+
+#define DX_BASE_ENV_REGS 0x40008000
+#define DX_BASE_ENV_CC_MEMORIES 0x40008000
+#define DX_BASE_ENV_PERF_RAM 0x40009000
+
+#define DX_BASE_HOST_RGF 0x0UL
+#define DX_BASE_CRY_KERNEL     0x0UL
+#define DX_BASE_ROM     0x40000000
+
+#define DX_BASE_RNG 0x0000UL
+#endif /*__DX_REG_BASE_HOST_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_bitops.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_bitops.h
new file mode 100644
index 0000000..d1b60c5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_bitops.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*! @file
+@brief This file defines bit-field operations macros.
+*/
+
+#ifndef _CC_BITOPS_H_
+#define _CC_BITOPS_H_
+
+
+/*! Defintion of number of 32bit maximum value. */
+#define CC_32BIT_MAX_VALUE  (0xFFFFFFFFUL)
+
+/*! Definition for bitmask */
+#define BITMASK(mask_size) (((mask_size) < 32) ?    \
+    ((1UL << (mask_size)) - 1) : 0xFFFFFFFFUL)
+/*! Definition for bitmask in a given offset. */
+#define BITMASK_AT(mask_size, mask_offset) (BITMASK(mask_size) << (mask_offset))
+
+/*! Definition for getting bits value from a word. */
+#define BITFIELD_GET(word, bit_offset, bit_size) \
+    (((word) >> (bit_offset)) & BITMASK(bit_size))
+/*! Definition for setting bits value from a word. */
+#define BITFIELD_SET(word, bit_offset, bit_size, new_val)   do {    \
+    word = ((word) & ~BITMASK_AT(bit_size, bit_offset)) |       \
+        (((new_val) & BITMASK(bit_size)) << (bit_offset));  \
+} while (0)
+
+/*!Definition for is val aligned to "align" ("align" must be power of 2). */
+#ifndef IS_ALIGNED
+#define IS_ALIGNED(val, align)      \
+    (((uintptr_t)(val) & ((align) - 1)) == 0)
+#endif
+/*!Definition swap endianity for 32 bits word. */
+#define SWAP_ENDIAN(word)       \
+    (((word) >> 24) | (((word) & 0x00FF0000) >> 8) | \
+    (((word) & 0x0000FF00) << 8) | (((word) & 0x000000FF) << 24))
+
+#ifdef BIG__ENDIAN
+#define SWAP_TO_LE(word) SWAP_ENDIAN(word)
+#define SWAP_TO_BE(word) word
+#else
+/*! Definition for swapping to LE. */
+#define SWAP_TO_LE(word) word
+/*! Definition for swapping to BE. */
+#define SWAP_TO_BE(word) SWAP_ENDIAN(word)
+#endif
+
+/*!Align X to uint32_t size. */
+#ifndef ALIGN_TO_4BYTES
+#define ALIGN_TO_4BYTES(x)      (((unsigned long)(x) + (CC_32BIT_WORD_SIZE-1)) & ~(CC_32BIT_WORD_SIZE-1))
+#endif
+
+
+
+/*! Definition for is val a multiple of "mult" ("mult" must be power of 2). */
+#define IS_MULT(val, mult)              \
+    (((val) & ((mult) - 1)) == 0)
+
+/*! Definition for is NULL address. */
+#define IS_NULL_ADDR(adr)       \
+    (!(adr))
+
+#endif /*_CC_BITOPS_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_crypto_ctx.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_crypto_ctx.h
new file mode 100644
index 0000000..9128c71
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_crypto_ctx.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_CRYPTO_CTX_H_
+#define _CC_CRYPTO_CTX_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#define INT32_MAX 0x7FFFFFFFL
+#else
+#include <stdint.h>
+#endif
+
+
+#ifndef max
+#define max(a, b) ((a) > (b) ? (a) : (b))
+#define min(a, b) ((a) < (b) ? (a) : (b))
+#endif
+
+/* context size */
+#ifndef CC_CTX_SIZE_LOG2
+#if (CC_SUPPORT_SHA > 256)
+#define CC_CTX_SIZE_LOG2 8
+#else
+#define CC_CTX_SIZE_LOG2 7
+#endif
+#endif
+#define CC_CTX_SIZE (1<<CC_CTX_SIZE_LOG2)
+#define CC_DRV_CTX_SIZE_WORDS (CC_CTX_SIZE >> 2)
+
+#define CC_DRV_DES_IV_SIZE 8
+#define CC_DRV_DES_BLOCK_SIZE 8
+
+#define CC_DRV_DES_ONE_KEY_SIZE 8
+#define CC_DRV_DES_DOUBLE_KEY_SIZE 16
+#define CC_DRV_DES_TRIPLE_KEY_SIZE 24
+#define CC_DRV_DES_KEY_SIZE_MAX CC_DRV_DES_TRIPLE_KEY_SIZE
+
+#define CC_AES_IV_SIZE 16
+#define CC_AES_IV_SIZE_WORDS (CC_AES_IV_SIZE >> 2)
+
+#define CC_AES_BLOCK_SIZE 16
+#define CC_AES_BLOCK_SIZE_WORDS 4
+
+#define CC_AES_128_BIT_KEY_SIZE 16
+#define CC_AES_128_BIT_KEY_SIZE_WORDS   (CC_AES_128_BIT_KEY_SIZE >> 2)
+#define CC_AES_192_BIT_KEY_SIZE 24
+#define CC_AES_192_BIT_KEY_SIZE_WORDS   (CC_AES_192_BIT_KEY_SIZE >> 2)
+#define CC_AES_256_BIT_KEY_SIZE 32
+#define CC_AES_256_BIT_KEY_SIZE_WORDS   (CC_AES_256_BIT_KEY_SIZE >> 2)
+#define CC_AES_KEY_SIZE_MAX         CC_AES_256_BIT_KEY_SIZE
+#define CC_AES_KEY_SIZE_WORDS_MAX       (CC_AES_KEY_SIZE_MAX >> 2)
+
+#define CC_MD5_DIGEST_SIZE  16
+#define CC_SHA1_DIGEST_SIZE     20
+#define CC_SHA224_DIGEST_SIZE   28
+#define CC_SHA256_DIGEST_SIZE   32
+#define CC_SHA256_DIGEST_SIZE_IN_WORDS 8
+#define CC_SHA384_DIGEST_SIZE   48
+#define CC_SHA512_DIGEST_SIZE   64
+
+#define CC_SHA1_BLOCK_SIZE 64
+#define CC_SHA1_BLOCK_SIZE_IN_WORDS 16
+#define CC_MD5_BLOCK_SIZE 64
+#define CC_MD5_BLOCK_SIZE_IN_WORDS 16
+#define CC_SHA224_BLOCK_SIZE 64
+#define CC_SHA256_BLOCK_SIZE 64
+#define CC_SHA256_BLOCK_SIZE_IN_WORDS 16
+#define CC_SHA1_224_256_BLOCK_SIZE 64
+#define CC_SHA384_BLOCK_SIZE 128
+#define CC_SHA512_BLOCK_SIZE 128
+
+#if (CC_SUPPORT_SHA > 256)
+#define CC_DIGEST_SIZE_MAX CC_SHA512_DIGEST_SIZE
+#define CC_HASH_BLOCK_SIZE_MAX CC_SHA512_BLOCK_SIZE /*1024b*/
+#define DRV_HASH_LENGTH_WORDS       4
+#else /* Only up to SHA256 */
+#define CC_DIGEST_SIZE_MAX CC_SHA256_DIGEST_SIZE
+#define CC_HASH_BLOCK_SIZE_MAX CC_SHA256_BLOCK_SIZE /*512b*/
+#define DRV_HASH_LENGTH_WORDS       2
+#endif
+
+#define CC_HMAC_BLOCK_SIZE_MAX CC_HASH_BLOCK_SIZE_MAX
+
+#define CC_MULTI2_SYSTEM_KEY_SIZE       32
+#define CC_MULTI2_DATA_KEY_SIZE         8
+#define CC_MULTI2_SYSTEM_N_DATA_KEY_SIZE    (CC_MULTI2_SYSTEM_KEY_SIZE + CC_MULTI2_DATA_KEY_SIZE)
+#define CC_MULTI2_BLOCK_SIZE                    8
+#define CC_MULTI2_IV_SIZE                   8
+#define CC_MULTI2_MIN_NUM_ROUNDS                8
+#define CC_MULTI2_MAX_NUM_ROUNDS                128
+
+#define CC_DRV_ALG_MAX_BLOCK_SIZE CC_HASH_BLOCK_SIZE_MAX
+
+enum drv_engine_type {
+    DRV_ENGINE_NULL = 0,
+    DRV_ENGINE_AES = 1,
+    DRV_ENGINE_DES = 2,
+    DRV_ENGINE_HASH = 3,
+    DRV_ENGINE_RC4 = 4,
+    DRV_ENGINE_DOUT = 5,
+    DRV_ENGINE_RESERVE32B = INT32_MAX,
+};
+
+enum drv_crypto_alg {
+    DRV_CRYPTO_ALG_NULL = -1,
+    DRV_CRYPTO_ALG_AES  = 0,
+    DRV_CRYPTO_ALG_DES  = 1,
+    DRV_CRYPTO_ALG_HASH = 2,
+    DRV_CRYPTO_ALG_C2   = 3,
+    DRV_CRYPTO_ALG_HMAC = 4,
+    DRV_CRYPTO_ALG_AEAD = 5,
+    DRV_CRYPTO_ALG_BYPASS = 6,
+    DRV_CRYPTO_ALG_NUM = 7,
+    DRV_CRYPTO_ALG_RESERVE32B = INT32_MAX
+};
+
+enum drv_crypto_direction {
+    DRV_CRYPTO_DIRECTION_NULL = -1,
+    DRV_CRYPTO_DIRECTION_ENCRYPT = 0,
+    DRV_CRYPTO_DIRECTION_DECRYPT = 1,
+    DRV_CRYPTO_DIRECTION_DECRYPT_ENCRYPT = 3,
+    DRV_CRYPTO_DIRECTION_RESERVE32B = INT32_MAX
+};
+
+enum drv_cipher_mode {
+    DRV_CIPHER_NULL_MODE = -1,
+    DRV_CIPHER_ECB = 0,
+    DRV_CIPHER_CBC = 1,
+    DRV_CIPHER_CTR = 2,
+    DRV_CIPHER_CBC_MAC = 3,
+    DRV_CIPHER_XTS = 4,
+    DRV_CIPHER_XCBC_MAC = 5,
+    DRV_CIPHER_OFB = 6,
+    DRV_CIPHER_CMAC = 7,
+    DRV_CIPHER_CCM = 8,
+    DRV_CIPHER_CBC_CTS = 11,
+    DRV_CIPHER_GCTR = 12,
+    DRV_CIPHER_ESSIV = 13,
+    DRV_CIPHER_BITLOCKER = 14,
+    DRV_CIPHER_RESERVE32B = INT32_MAX
+};
+
+enum drv_hash_mode {
+    DRV_HASH_NULL = -1,
+    DRV_HASH_SHA1 = 0,
+    DRV_HASH_SHA256 = 1,
+    DRV_HASH_SHA224 = 2,
+    DRV_HASH_SHA512 = 3,
+    DRV_HASH_SHA384 = 4,
+    DRV_HASH_MD5 = 5,
+    DRV_HASH_CBC_MAC = 6,
+    DRV_HASH_XCBC_MAC = 7,
+    DRV_HASH_CMAC = 8,
+    DRV_HASH_MODE_NUM = 9,
+    DRV_HASH_RESERVE32B = INT32_MAX
+};
+
+enum drv_hash_hw_mode {
+    DRV_HASH_HW_MD5 = 0,
+    DRV_HASH_HW_SHA1 = 1,
+    DRV_HASH_HW_SHA256 = 2,
+    DRV_HASH_HW_SHA224 = 10,
+    DRV_HASH_HW_SHA512 = 4,
+    DRV_HASH_HW_SHA384 = 12,
+    DRV_HASH_HW_GHASH = 6,
+    DRV_HASH_HW_RESERVE32B = INT32_MAX
+};
+
+enum drv_multi2_mode {
+    DRV_MULTI2_NULL = -1,
+    DRV_MULTI2_ECB = 0,
+    DRV_MULTI2_CBC = 1,
+    DRV_MULTI2_OFB = 2,
+    DRV_MULTI2_RESERVE32B = INT32_MAX
+};
+
+
+/* drv_crypto_key_type[1:0] is mapped to cipher_do[1:0] */
+/* drv_crypto_key_type[2] is mapped to cipher_config2 */
+enum drv_crypto_key_type {
+    DRV_NULL_KEY = -1,
+    DRV_USER_KEY = 0,       /* 0x000 */
+    DRV_ROOT_KEY = 1,       /* 0x001 */
+    DRV_PROVISIONING_KEY = 2,   /* 0x010 */
+    DRV_SESSION_KEY = 3,        /* 0x011 */
+    DRV_APPLET_KEY = 4,     /* NA */
+    DRV_PLATFORM_KEY = 5,       /* 0x101 */
+    DRV_CUSTOMER_KEY = 6,       /* 0x110 */
+    DRV_END_OF_KEYS = INT32_MAX,
+};
+
+enum drv_crypto_padding_type {
+    DRV_PADDING_NONE = 0,
+    DRV_PADDING_PKCS7 = 1,
+    DRV_PADDING_RESERVE32B = INT32_MAX
+};
+
+
+typedef enum DrvAeadCcmFlow {
+    DRV_AEAD_FLOW_NULL = 0,
+    DRV_AEAD_FLOW_ADATA_INIT,
+    DRV_AEAD_FLOW_ADATA_PROCESS,
+    DRV_AEAD_FLOW_TEXT_DATA_INIT,
+    DRV_AEAD_FLOW_TEXT_DATA_PROCESS,
+    DRV_AEAD_FLOW_RESERVE32B = INT32_MAX,
+} DrvAeadCcmFlow_e;
+
+typedef enum DataBlockType {
+    FIRST_BLOCK,
+    MIDDLE_BLOCK,
+    LAST_BLOCK,
+    RESERVE32B_BLOCK = INT32_MAX
+}DataBlockType_t;
+
+typedef enum DrvAesCoreEngine {
+     DRV_AES_ENGINE1,
+     DRV_AES_ENGINE2,
+     DRV_AES_ENGINES_RESERVE32B = INT32_MAX
+}DrvAesCoreEngine_t;
+
+typedef enum TunnelOp {
+     TUNNEL_OP_INVALID = -1,
+     TUNNEL_OFF = 0,
+     TUNNEL_ON = 1,
+     TunnelOp_OPTIONS,
+     TunnelOp_END = INT32_MAX,
+} TunnelOp_t;
+
+/*******************************************************************/
+/***************** DESCRIPTOR BASED CONTEXTS ***********************/
+/*******************************************************************/
+
+struct drv_ctx_hash {
+    uint8_t  digest[CC_DIGEST_SIZE_MAX];
+    uint32_t CurrentDigestedLength[DRV_HASH_LENGTH_WORDS];
+    uint32_t k0[CC_HMAC_BLOCK_SIZE_MAX/sizeof(uint32_t)]; /* not used in hash operation */
+    uint32_t k0_size;
+    enum drv_crypto_alg alg; /* ssi_drv_crypto_alg_HASH */
+    enum drv_hash_mode mode;
+    uint32_t dataCompleted;
+    uint32_t hmacFinalization;
+    /* reserve to end of allocated context size */
+    uint32_t reserved[CC_DRV_CTX_SIZE_WORDS - 5 -
+            DRV_HASH_LENGTH_WORDS - CC_DIGEST_SIZE_MAX/sizeof(uint32_t) - CC_HMAC_BLOCK_SIZE_MAX/sizeof(uint32_t)];
+};
+
+struct drv_ctx_cipher {
+    /* block_state is the AES engine block state.
+    *  It is used by the host to pass IV or counter at initialization.
+    *  It is used by SeP for intermediate block chaining state and for
+    *  returning MAC algorithms results.           */
+    uint8_t block_state[CC_AES_BLOCK_SIZE];
+    uint8_t key[CC_AES_KEY_SIZE_MAX];
+    uint8_t xex_key[CC_AES_KEY_SIZE_MAX];
+    enum drv_crypto_alg alg; /* DRV_CRYPTO_ALG_AES */
+    enum drv_cipher_mode mode;
+    enum drv_crypto_direction direction;
+    enum drv_crypto_key_type crypto_key_type;
+    enum drv_crypto_padding_type padding_type;
+    uint32_t key_size; /* numeric value in bytes   */
+    uint32_t data_unit_size; /* required for XTS */
+     /* this flag indicates whether the user processed at least
+    one data block:
+    "0" no data blocks processed
+    "1" at least one data block processed */
+    DataBlockType_t dataBlockType;
+    TunnelOp_t isTunnelOp;
+    DrvAesCoreEngine_t engineCore;
+    uint32_t tunnetDir;
+    /* reserve to end of allocated context size */
+    uint32_t reserved[CC_DRV_CTX_SIZE_WORDS - 11 -
+        CC_AES_BLOCK_SIZE/sizeof(uint32_t) - 2 *
+        (CC_AES_KEY_SIZE_MAX/sizeof(uint32_t))];
+};
+
+/* authentication and encryption with associated data class */
+struct drv_ctx_aead {
+    /* block_state1/2 is the AES engine block state */
+    uint8_t block_state[CC_AES_BLOCK_SIZE];
+    uint8_t key[CC_AES_KEY_SIZE_MAX];
+    uint8_t mac_state[CC_AES_BLOCK_SIZE]; /* MAC result */
+    uint8_t nonce[CC_AES_BLOCK_SIZE]; /* nonce buffer */
+    enum drv_crypto_alg alg; /* ssi_drv_crypto_alg_AES */
+    enum drv_cipher_mode mode;
+    enum drv_crypto_direction direction;
+    uint32_t key_size; /* numeric value in bytes   */
+    uint32_t nonce_size; /* nonce size (octets) */
+    uint32_t header_size; /* finit additional data size (octets) */
+    uint32_t text_size; /* finit text data size (octets) */
+    uint32_t tag_size; /* mac size, element of {4, 6, 8, 10, 12, 14, 16} */
+    uint32_t internalMode; /* auth/encrypt/decrypt modes */
+    uint32_t q; /* an element of {2, 3, 4, 5, 6, 7, 8}; */
+    uint32_t headerRemainingBytes; /* associated data remaining bytes */
+    DrvAeadCcmFlow_e nextProcessingState; /* points to the next machine state */
+    /* reserve to end of allocated context size */
+    uint32_t reserved[CC_DRV_CTX_SIZE_WORDS - 12 -
+        3 * (CC_AES_BLOCK_SIZE/sizeof(uint32_t)) -
+        CC_AES_KEY_SIZE_MAX/sizeof(uint32_t)];
+};
+
+/*******************************************************************/
+/***************** MESSAGE BASED CONTEXTS **************************/
+/*******************************************************************/
+
+
+/* Get the address of a @member within a given @ctx address
+   @ctx: The context address
+   @type: Type of context structure
+   @member: Associated context field */
+#define GET_CTX_FIELD_ADDR(ctx, type, member) (ctx + offsetof(type, member))
+
+#endif /* _CC_CRYPTO_CTX_H_ */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_crypto_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_crypto_defs.h
new file mode 100644
index 0000000..6808261
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_crypto_defs.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/** \file
+ * \brief This file contains common cryptographic definitions.
+ *
+ */
+
+#ifndef _CC_CRYPTO_DEFS_H
+#define _CC_CRYPTO_DEFS_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Hash Definitions ******************************/
+
+#define HASH_MD5_DIGEST_SIZE_IN_BYTES       16
+#define HASH_SHA1_DIGEST_SIZE_IN_BYTES      20
+#define HASH_SHA224_DIGEST_SIZE_IN_BYTES    28
+#define HASH_SHA256_DIGEST_SIZE_IN_BYTES    32
+#define HASH_SHA384_DIGEST_SIZE_IN_BYTES    48
+#define HASH_SHA512_DIGEST_SIZE_IN_BYTES    64
+
+#define HASH_MD5_BLOCK_SIZE_IN_BYTES        64
+#define HASH_SHA1_BLOCK_SIZE_IN_BYTES       64
+#define HASH_SHA224_BLOCK_SIZE_IN_BYTES     64
+#define HASH_SHA256_BLOCK_SIZE_IN_BYTES     64
+#define HASH_SHA384_BLOCK_SIZE_IN_BYTES     128
+#define HASH_SHA512_BLOCK_SIZE_IN_BYTES     128
+
+
+
+/************************ AES Definitions ******************************/
+
+#define AES_BLOCK_SIZE_IN_BYTES     16
+
+#define AES_IV_SIZE_IN_BYTES        AES_BLOCK_SIZE_IN_BYTES
+
+
+/* AES-CCM Definitions */
+#define AES_CCM_NONCE_LENGTH_MIN    7
+#define AES_CCM_NONCE_LENGTH_MAX    13
+
+#define AES_CCM_TAG_LENGTH_MIN      4
+#define AES_CCM_TAG_LENGTH_MAX      16
+
+
+
+/************************ DES Definitions ******************************/
+
+#define DES_IV_SIZE_IN_BYTES        8
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_hal.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_hal.h
new file mode 100644
index 0000000..fd52354
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_hal.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef __CC_HAL_H__
+#define __CC_HAL_H__
+
+/*!
+@file
+@brief This file contains HAL definitions and APIs.
+*/
+
+#include <stdint.h>
+#include "cc_hal_plat.h"
+#include "cc_pal_types_plat.h"
+
+/*! HAL return code definitions. */
+typedef enum {
+    CC_HAL_OK = 0,
+    CC_HAL_ENODEV,        /* Device not opened or does not exist */
+    CC_HAL_EINTERNAL,     /* Internal driver error (check system log) */
+    CC_HAL_MAPFAILED,
+    CC_HAL_ENOTSUP,       /* Unsupported function/option */
+    CC_HAL_ENOPERM,       /* Not enough permissions for request */
+    CC_HAL_EINVAL,        /* Invalid parameters */
+    CC_HAL_ENORSC,        /* No resources available (e.g., memory) */
+    CC_HAL_RESERVE32B = 0x7FFFFFFFL
+} CCHalRetCode_t;
+
+/*!
+ * @brief This function is used to map ARM TrustZone CryptoCell TEE registers to Host virtual address space.
+    It is called by ::CC_LibInit, and returns a non-zero value in case of failure.
+        The existing implementation supports Linux environment. In case virtual addressing is not used, the function can be minimized to contain only the
+    following line, and return OK:
+        gCcRegBase = (uint32_t)DX_BASE_CC;
+  @return CC_HAL_OK on success.
+  @return A non-zero value in case of failure.
+*/
+int CC_HalInit(void);
+
+
+/*!
+ * @brief This function is used to wait for the IRR interrupt signal.
+ *
+ * @return CCError_t - return CC_OK upon success
+ */
+CCError_t CC_HalWaitInterrupt(uint32_t data /*!< [in] The interrupt bits to wait upon. */ );
+
+/*!
+ * @brief This function is used to wait for the IRR interrupt signal.
+ * The existing implementation performs a "busy wait" on the IRR.
+ *
+ * @return CCError_t - return CC_OK upon success
+ */
+CCError_t CC_HalWaitInterruptRND(uint32_t data);
+
+/*!
+ * @brief This function clears the DSCRPTR_COMPLETION bit in the ICR signal.
+ */
+void CC_HalClearInterrupt(uint32_t data);
+
+/*!
+ * @brief This function is called by CC_LibInit and is used for initializing the ARM TrustZone CryptoCell TEE cache settings registers.
+          The existing implementation sets the registers to their default values in HCCC cache coherency mode
+      (ARCACHE = 0x2, AWCACHE = 0x7, AWCACHE_LAST = 0x7).
+          These values should be changed by the customer in case the customer's platform requires different HCCC values, or in case SCCC is needed
+      (the values for SCCC are ARCACHE = 0x3, AWCACHE = 0x3, AWCACHE_LAST = 0x3).
+
+ * @return void
+ */
+void CC_HalInitHWCacheParams(void);
+
+/*!
+ * @brief This function is used to unmap ARM TrustZone CryptoCell TEE registers' virtual address.
+      It is called by CC_LibFini, and returns a non-zero value in case of failure.
+      In case virtual addressing is not used, the function can be minimized to be an empty function returning OK.
+   @return CC_HAL_OK on success.
+   @return A non-zero value in case of failure.
+ */
+int CC_HalTerminate(void);
+
+/*!
+ * @brief This function is used to clear the interrupt vector.
+
+ * @return void.
+ */
+void CC_HalClearInterruptBit(uint32_t data /*!< [in] The interrupt bits to clear. */);
+
+/*!
+ * @brief This function is used to mask IRR interrupts.
+
+ * @return void.
+ */
+void CC_HalMaskInterrupt(uint32_t data /*!< [in] The interrupt bits to mask. */);
+
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_lli_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_lli_defs.h
new file mode 100644
index 0000000..ff74c8c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_lli_defs.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_LLI_DEFS_H_
+#define _CC_LLI_DEFS_H_
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+#include "cc_bitops.h"
+
+/* Max DLLI size */
+#define DLLI_SIZE_BIT_SIZE  0x18    // DX_DSCRPTR_QUEUE_WORD1_DIN_SIZE_BIT_SIZE
+
+#define CC_MAX_MLLI_ENTRY_SIZE 0x10000
+
+#define LLI_SET_ADDR(lli_p, addr) \
+        BITFIELD_SET(((uint32_t *)(lli_p))[LLI_WORD0_OFFSET], LLI_LADDR_BIT_OFFSET, LLI_LADDR_BIT_SIZE, (addr & UINT32_MAX)); \
+        BITFIELD_SET(((uint32_t *)(lli_p))[LLI_WORD1_OFFSET], LLI_HADDR_BIT_OFFSET, LLI_HADDR_BIT_SIZE, ((addr >> 32) & UINT16_MAX));
+
+#define LLI_SET_SIZE(lli_p, size) \
+        BITFIELD_SET(((uint32_t *)(lli_p))[LLI_WORD1_OFFSET], LLI_SIZE_BIT_OFFSET, LLI_SIZE_BIT_SIZE, size)
+
+
+/* Size of entry */
+#define LLI_ENTRY_WORD_SIZE 2
+#define LLI_ENTRY_BYTE_SIZE (LLI_ENTRY_WORD_SIZE * sizeof(uint32_t))
+
+/* Word0[31:0] = ADDR[31:0] */
+#define LLI_WORD0_OFFSET 0
+#define LLI_LADDR_BIT_OFFSET 0
+#define LLI_LADDR_BIT_SIZE 32
+/* Word1[31:16] = ADDR[47:32]; Word1[15:0] = SIZE */
+#define LLI_WORD1_OFFSET 1
+#define LLI_SIZE_BIT_OFFSET 0
+#define LLI_SIZE_BIT_SIZE 16
+#define LLI_HADDR_BIT_OFFSET 16
+#define LLI_HADDR_BIT_SIZE 16
+
+
+#endif /*_CC_LLI_DEFS_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_mng/mbedtls_cc_mng.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_mng/mbedtls_cc_mng.h
new file mode 100644
index 0000000..4c4691b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_mng/mbedtls_cc_mng.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_management
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all CryptoCell Management APIs and definitions.
+
+ The following terms, used throughout this module, are defined in
+ <em>Arm® v8-M Architecture Reference Manual</em>:
+ <ul><li>Privileged and unprivileged modes.</li>
+ <li>Secure and Non-secure modes.</li></ul>
+ */
+
+
+
+#ifndef _MBEDTLS_CC_MNG_H
+#define _MBEDTLS_CC_MNG_H
+
+/* *********************** Includes ***************************** */
+#include "cc_pal_types_plat.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* *********************** Defines ***************************** */
+/* LCS. */
+/*! Chip manufacturer (CM LCS). */
+#define CC_MNG_LCS_CM       0x0
+/*! Device manufacturer (DM LCS). */
+#define CC_MNG_LCS_DM       0x1
+/*! Security enabled (Secure LCS). */
+#define CC_MNG_LCS_SEC_ENABLED  0x5
+/*! RMA (RMA LCS). */
+#define CC_MNG_LCS_RMA      0x7
+
+/* *********************** Macros ***************************** */
+
+
+/* *********************** Enums ***************************** */
+/*! RMA statuses. */
+typedef enum  {
+    /*! Non-RMA: bit [30] = 0, bit [31] = 0. */
+    CC_MNG_NON_RMA              = 0,
+    /*! Pending RMA: bit [30] = 1, bit [31] = 0. */
+    CC_MNG_PENDING_RMA          = 1,
+    /*! Illegal state: bit [30] = 0, bit [31] = 1. */
+    CC_MNG_ILLEGAL_STATE        = 2,
+    /*! RMA: bit [30] = 1, bit [31] = 1. */
+    CC_MNG_RMA                  = 3,
+    /*! Reserved. */
+    CC_MNG_END_OF_RMA_STATUS    = 0x7FFFFFFF
+}mbedtls_mng_rmastatus;
+
+/*! AES HW key types. */
+typedef enum  {
+    /*! Device root key (HUK). */
+    CC_MNG_HUK_KEY         = 0,
+    /*! Platform key (Krtl). */
+    CC_MNG_RTL_KEY         = 1,
+    /*! ICV provisioning key (Kcp). */
+    CC_MNG_PROV_KEY        = 2,
+    /*! OEM code-encryption key (Kce). */
+    CC_MNG_CE_KEY          = 3,
+    /*! OEM provisioning key (Kpicv). */
+    CC_MNG_ICV_PROV_KEY    = 4,
+    /*! ICV code-encryption key (Kceicv). */
+    CC_MNG_ICV_CE_KEY      = 5,
+    /*! Total number of HW Keys. */
+    CC_MNG_TOTAL_HW_KEYS   = 6,
+    /*! Reserved. */
+    CC_MNG_END_OF_KEY_TYPE = 0x7FFFFFFF
+}mbedtls_mng_keytype;
+
+/*! APB-C only part IDs. */
+typedef enum  {
+    /*! Secure accesses. */
+    CC_MNG_APBC_SEC_ID      = 0,
+    /*! Privileged accesses. */
+    CC_MNG_APBC_PRIV_ID     = 1,
+    /*! Instruction accesses. */
+    CC_MNG_APBC_INST_ID     = 2,
+    /*! Total part IDs. */
+    CC_MNG_APBC_TOTAL_ID    = 3,
+    /*! Reserved. */
+    CC_MNG_APBC_END_OF_ID   = 0x7FFFFFFF
+}mbedtls_mng_apbc_parts;
+
+/*! APB-C part configuration. */
+typedef enum  {
+    /*! Use APB-C as an input when there is no need to change bits.
+    Modify bit = 0. */
+    CC_MNG_APBC_NO_CHANGE           = 0,
+    /*! Use APB-C as an input when you need to set the 'Allow' bit to '0' and
+    leave this part unlocked. Modify bit = 1, Allow bit = 0, Allow Lock
+    bit = 0. */
+    CC_MNG_APBC_ALLOW_0_ALLOWLOCK_0 = 1,
+    /*! Use APB-C as an input when you need to set the 'Allow' bit to '0' and
+    lock this part. Modify bit = 1, Allow bit = 0, Allow Lock bit = 1. */
+    CC_MNG_APBC_ALLOW_0_ALLOWLOCK_1 = 2,
+    /*! Use APB-C as an input when you need to set the 'Allow' bit to '1' and
+    leave this part unlocked. Modify bit = 1, Allow bit = 1, Allow Lock
+    bit = 0. */
+    CC_MNG_APBC_ALLOW_1_ALLOWLOCK_0 = 3,
+    /*! Use APB-C as an input when you need to set the 'Allow' bit to '1' and
+    lock this part. Modify bit = 1, Allow bit = 1, Allow Lock bit = 1. */
+    CC_MNG_APBC_ALLOW_1_ALLOWLOCK_1 = 4,
+    /*! Total parts. */
+    CC_MNG_APBC_TOTAL_PARTS_CONFIG  = 5,
+    /*! Reserved. */
+    CC_MNG_APBC_END_OF_PARTS_CONFIG = 0x7FFFFFFF
+}mbedtls_mng_apbc_parts_config;
+
+/************************ Typedefs  ****************************/
+
+/*! A uint8_t representation for the APB-C parts in the AO_APB_FILTERING
+register. */
+typedef union mbedtls_mng_apbc_part{
+    /*! A representation of the APB-C value in the AO_APB_FILTERING register.*/
+    uint8_t apbcPartVal;
+    /*! A representation of the APB-C parts in the AO_APB_FILTERING register.*/
+    struct {
+        /*! APB-C accepts only 'mbedtls_mng_apbc_parts' accesses. */
+        uint8_t accessAllow       :   1;
+        /*! APB-C \p accessAllow cannot be modified. */
+        uint8_t accessAllowLock   :   1;
+        /*! User decided to modify the upper couple. */
+        uint8_t accessModify      :   1;
+        /*! APB-C part access bits. */
+        uint8_t rfu               :   5;
+    }apbcPartBits;
+}mbedtls_mng_apbc_part;
+
+/*! Input to the mbedtls_mng_apbc_config_set() function. */
+typedef union mbedtls_mng_apbcconfig{
+    /*! APB-C configuration values. */
+    uint32_t apbcConfigVal;
+    /*! An array of the configuration bits for the Secure, Privileged, and
+    Instruction parts. */
+    mbedtls_mng_apbc_part apbcPart[CC_MNG_APBC_TOTAL_ID + 1];
+}mbedtls_mng_apbcconfig;
+
+
+/* ****************************************** Public Functions **************************************** */
+/*
+Management APIs enable to set, get or obtain device status by reading or writing the
+appropriate registers or the OTP.
+*/
+/* ********************************************************************************************** */
+/*!
+  @brief This function reads the OTP word of the OEM flags,
+         and returns the OEM RMA flag status: TRUE or FALSE.
+
+  The function returns the value only in DM LCS or Secure LCS.
+  It validates the device RoT configuration, and returns the
+  value only if both HBK0 and HBK1 are supported.
+  Otherwise, it returns FALSE regardless of the OTP status.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_pending_rma_status_get(
+        /*! [out] The RMA status. */
+        uint32_t *rmaStatus
+                                      );
+
+/*!
+  @brief This function verifies and returns the CryptoCell HW version.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_hw_version_get(
+        /*! [out] The part number. */
+        uint32_t *partNumber,
+        /*! [out] The HW version. */
+        uint32_t *revision
+);
+
+/*!
+  @brief This function sets CryptoCell to Secured mode.
+
+  Setting CryptoCell to Secured mode can only be done while CryptoCell is idle.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_cc_sec_mode_set(
+        /*! [in] True: Set CryptoCell to Secured mode. False: Set CryptoCell
+        to non-Secured mode. */
+        CCBool_t isSecAccessMode,
+        /*! [in] True: Lock CryptoCell to current mode. False: Do not lock
+        CryptoCell to current mode. Allows calling this function again. */
+        CCBool_t isSecModeLock
+);
+
+/*!
+  @brief This function sets CryptoCell to Privileged mode.
+
+  Setting CryptoCell to Privileged mode can only be done while CryptoCell is idle.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_cc_priv_mode_set(
+        /*! [in] True: Set CryptoCell to privileged mode. False: Set
+        CryptoCell to unprivileged mode. */
+        CCBool_t isPrivAccessMode,
+        /*! [in] True: Lock CryptoCell to current mode. False: Do not lock
+        CryptoCell to current mode. Allows calling this function again. */
+        CCBool_t isPrivModeLock
+);
+
+/*!
+  @brief This function sets the shadow register of one of the
+  HW Keys when the device is in CM LCS or DM LCS.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_debug_key_set(
+        /*! [in] The type of the HW key. One of the following values: HUK,
+        Kcp, Kce, Kpicv, or Kceicv. */
+        mbedtls_mng_keytype keyType,
+        /*! [in] A pointer to the buffer holding the HW key. */
+        uint32_t *pHwKey,
+        /*! [in] The size of the HW key in bytes. */
+        size_t keySize
+);
+
+/*!
+  @brief This function retrieves the general configuration from the OTP.
+         See <em>Arm CryptoCell-312 Software Integrators Manual</em>.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_gen_config_get(
+        /*! [out] The OTP configuration word. */
+        uint32_t *pOtpWord
+                               );
+
+/*!
+  @brief This function locks the usage of either Kcp, Kce, or both during runtime,
+         in either Secure LCS or RMA LCS.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_oem_key_lock(
+        /*! [in] The flag for locking Kcp usage. */
+        CCBool_t kcpLock,
+        /*! [in] The flag for locking Kce usage. */
+        CCBool_t kceLock
+);
+
+/*!
+  @brief This function sets CryptoCell APB-C into one of the following modes:
+         Secured access mode, Privileged access mode, or Instruction access
+         mode.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_apbc_config_set(
+        /*! Secured access mode. */
+        mbedtls_mng_apbc_parts_config securePartCfg,
+        /*! Privileged access mode.*/
+        mbedtls_mng_apbc_parts_config privPartCfg,
+        /*! Instruction access mode. */
+        mbedtls_mng_apbc_parts_config instPartCfg
+);
+/*!
+  @brief This function requests usage of, or releases, the APB-C.
+
+  @note This function must be called before and after each use of APB-C.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_apbc_access(
+        /*! [in] TRUE: Request usage of APB-C. FALSE: Free APB-C. */
+        CCBool_t isApbcAccessUsed
+                           );
+
+/*!
+  @brief This function is called once the external PMU decides to power-down
+  CryptoCell.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_suspend(
+        /*! [in] A pointer to a buffer that can be used for backup. */
+        uint8_t *pBackupBuffer,
+        /*! [in] The size of the backup buffer. Must be at least
+        \c CC_MNG_MIN_BACKUP_SIZE_IN_BYTES. */
+        size_t backupSize
+);
+
+/*!
+  @brief This function is called once the external PMU decides to power-up
+  CryptoCell.
+
+  @return CC_OK on success.
+  @return A non-zero value from mbedtls_cc_mng_error.h on failure.
+ */
+int mbedtls_mng_resume(
+        /*! [in] A pointer to a buffer that can be used for backup. */
+        uint8_t *pBackupBuffer,
+        /*! [in] The size of the backup buffer. Must be at least
+        \c CC_MNG_MIN_BACKUP_SIZE_IN_BYTES. */
+        size_t backupSize
+);
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif // _MBEDTLS_CC_MNG_H
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_mng/mbedtls_cc_mng_error.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_mng/mbedtls_cc_mng_error.h
new file mode 100644
index 0000000..fac6e6b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_mng/mbedtls_cc_mng_error.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*!
+ @addtogroup cc_management_error
+ @{
+*/
+
+/*!
+ @file
+ @brief This file contains the error definitions of the CryptoCell management APIs.
+ */
+
+
+#ifndef _MBEDTLS_CC_MNG_ERROR_H
+#define _MBEDTLS_CC_MNG_ERROR_H
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* CryptoCell Management module errors. CC_MNG_MODULE_ERROR_BASE = 0x00F02900 */
+
+/*! Illegal input parameter. */
+#define CC_MNG_ILLEGAL_INPUT_PARAM_ERR      (CC_MNG_MODULE_ERROR_BASE + 0x00UL)
+/*! Illegal operation. */
+#define CC_MNG_ILLEGAL_OPERATION_ERR        (CC_MNG_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal Peripheral ID. */
+#define CC_MNG_ILLEGAL_PIDR_ERR             (CC_MNG_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal Component ID. */
+#define CC_MNG_ILLEGAL_CIDR_ERR             (CC_MNG_MODULE_ERROR_BASE + 0x03UL)
+/*! APB Secure is locked. */
+#define CC_MNG_APB_SECURE_IS_LOCKED_ERR         (CC_MNG_MODULE_ERROR_BASE + 0x04UL)
+/*! APB Privilege is locked. */
+#define CC_MNG_APB_PRIVILEGE_IS_LOCKED_ERR  (CC_MNG_MODULE_ERROR_BASE + 0x05UL)
+/*! APBC Secure is locked. */
+#define CC_MNG_APBC_SECURE_IS_LOCKED_ERR    (CC_MNG_MODULE_ERROR_BASE + 0x06UL)
+/*! APBC Privilege is locked. */
+#define CC_MNG_APBC_PRIVILEGE_IS_LOCKED_ERR (CC_MNG_MODULE_ERROR_BASE + 0x07UL)
+/*! APBC Instruction is locked. */
+#define CC_MNG_APBC_INSTRUCTION_IS_LOCKED_ERR   (CC_MNG_MODULE_ERROR_BASE + 0x08UL)
+/*! Invalid Key type. */
+#define CC_MNG_INVALID_KEY_TYPE_ERROR       (CC_MNG_MODULE_ERROR_BASE + 0x09UL)
+/*! Illegal size of HUK. */
+#define CC_MNG_ILLEGAL_HUK_SIZE_ERR     (CC_MNG_MODULE_ERROR_BASE + 0x0AUL)
+/*! Illegal size for any HW key other than HUK. */
+#define CC_MNG_ILLEGAL_HW_KEY_SIZE_ERR      (CC_MNG_MODULE_ERROR_BASE + 0x0BUL)
+/*! HW key is locked. */
+#define CC_MNG_HW_KEY_IS_LOCKED_ERR         (CC_MNG_MODULE_ERROR_BASE + 0x0CUL)
+/*! Kcp is locked. */
+#define CC_MNG_KCP_IS_LOCKED_ERR            (CC_MNG_MODULE_ERROR_BASE + 0x0DUL)
+/*! Kce is locked. */
+#define CC_MNG_KCE_IS_LOCKED_ERR        (CC_MNG_MODULE_ERROR_BASE + 0x0EUL)
+/*! RMA Illegal state. */
+#define CC_MNG_RMA_ILLEGAL_STATE_ERR        (CC_MNG_MODULE_ERROR_BASE + 0x0FUL)
+/*! Error returned from AO_APB_FILTERING write operation. */
+#define CC_MNG_AO_APB_WRITE_FAILED_ERR      (CC_MNG_MODULE_ERROR_BASE + 0x10UL)
+/*! APBC access failure. */
+#define CC_MNG_APBC_ACCESS_FAILED_ERR       (CC_MNG_MODULE_ERROR_BASE + 0x11UL)
+/*! APBC already-off failure. */
+#define CC_MNG_APBC_ACCESS_ALREADY_OFF_ERR  (CC_MNG_MODULE_ERROR_BASE + 0x12UL)
+/*! APBC access is on failure. */
+#define CC_MNG_APBC_ACCESS_IS_ON_ERR        (CC_MNG_MODULE_ERROR_BASE + 0x13UL)
+/*! PM SUSPEND/RESUME failure. */
+#define CC_MNG_PM_SUSPEND_RESUME_FAILED_ERR (CC_MNG_MODULE_ERROR_BASE + 0x14UL)
+/*! SW version failure. */
+#define CC_MNG_ILLEGAL_SW_VERSION_ERR       (CC_MNG_MODULE_ERROR_BASE + 0x15UL)
+/*! Hash Public Key NA. */
+#define CC_MNG_HASH_NOT_PROGRAMMED_ERR      (CC_MNG_MODULE_ERROR_BASE + 0x16UL)
+/*! Illegal hash boot key zero count in the OTP error. */
+#define CC_MNG_HBK_ZERO_COUNT_ERR           (CC_MNG_MODULE_ERROR_BASE + 0x17UL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif // _MBEDTLS_CC_MNG_ERROR_H
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_regs.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_regs.h
new file mode 100644
index 0000000..00e5d74
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_regs.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*!
+ * @file
+ * @brief This file contains macro definitions for accessing ARM TrustZone CryptoCell register space.
+ */
+
+#ifndef _CC_REGS_H_
+#define _CC_REGS_H_
+
+#include "cc_bitops.h"
+
+#if !defined(CC_REE) && !defined(CC_IOT) && !defined(CC_SB_SUPPORT_IOT)
+#include "dx_nvm.h"
+#endif
+
+/* Register Offset macro */
+#define CC_REG_OFFSET(unit_name, reg_name)               \
+    (DX_BASE_ ## unit_name + DX_ ## reg_name ## _REG_OFFSET)
+
+#define CC_REG_BIT_SHIFT(reg_name, field_name)               \
+    (DX_ ## reg_name ## _ ## field_name ## _BIT_SHIFT)
+
+/* Register Offset macros (from registers base address in host) */
+#if defined(CC_REE) || defined(CC_TEE) || defined(CC_IOT) || defined(CC_SB_SUPPORT_IOT)
+
+#include "dx_reg_base_host.h"
+
+/* Read-Modify-Write a field of a register */
+#define MODIFY_REGISTER_FLD(unitName, regName, fldName, fldVal)         \
+do {                                            \
+    uint32_t regVal;                            \
+    regVal = READ_REGISTER(CC_REG_ADDR(unitName, regName));       \
+    CC_REG_FLD_SET(unitName, regName, fldName, regVal, fldVal); \
+    WRITE_REGISTER(CC_REG_ADDR(unitName, regName), regVal);       \
+} while (0)
+
+#else
+#error Execution domain is not CC_REE/CC_TEE/CC_IOT
+#endif
+
+/* Registers address macros for ENV registers (development FPGA only) */
+#ifdef DX_BASE_ENV_REGS
+
+/* This offset should be added to mapping address of DX_BASE_ENV_REGS */
+#define CC_ENV_REG_OFFSET(reg_name) (DX_ENV_ ## reg_name ## _REG_OFFSET)
+
+#endif /*DX_BASE_ENV_REGS*/
+
+/*! Bit fields get */
+#define CC_REG_FLD_GET(unit_name, reg_name, fld_name, reg_val)        \
+    (DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20 ?          \
+    reg_val /*!< \internal Optimization for 32b fields */ :               \
+    BITFIELD_GET(reg_val, DX_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT, \
+             DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE))
+
+/*! Bit fields access */
+#define CC_REG_FLD_GET2(unit_name, reg_name, fld_name, reg_val)       \
+    (CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20 ?          \
+    reg_val /*!< \internal Optimization for 32b fields */ :               \
+    BITFIELD_GET(reg_val, CC_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT, \
+             CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE))
+
+/*! Bit fields set */
+#define CC_REG_FLD_SET(                                               \
+    unit_name, reg_name, fld_name, reg_shadow_var, new_fld_val)      \
+do {                                                                     \
+    if (DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20)       \
+        reg_shadow_var = new_fld_val; /*!< \internal Optimization for 32b fields */\
+    else                                                             \
+        BITFIELD_SET(reg_shadow_var,                             \
+            DX_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT,  \
+            DX_ ## reg_name ## _ ## fld_name ## _BIT_SIZE,   \
+            new_fld_val);                                    \
+} while (0)
+
+/*! Bit fields set */
+#define CC_REG_FLD_SET2(                                               \
+    unit_name, reg_name, fld_name, reg_shadow_var, new_fld_val)      \
+do {                                                                     \
+    if (CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE == 0x20)       \
+        reg_shadow_var = new_fld_val; /*!< \internal Optimization for 32b fields */\
+    else                                                             \
+        BITFIELD_SET(reg_shadow_var,                             \
+            CC_ ## reg_name ## _ ## fld_name ## _BIT_SHIFT,  \
+            CC_ ## reg_name ## _ ## fld_name ## _BIT_SIZE,   \
+            new_fld_val);                                    \
+} while (0)
+
+/* Usage example:
+   uint32_t reg_shadow = READ_REGISTER(CC_REG_ADDR(CRY_KERNEL,AES_CONTROL));
+   CC_REG_FLD_SET(CRY_KERNEL,AES_CONTROL,NK_KEY0,reg_shadow, 3);
+   CC_REG_FLD_SET(CRY_KERNEL,AES_CONTROL,NK_KEY1,reg_shadow, 1);
+   WRITE_REGISTER(CC_REG_ADDR(CRY_KERNEL,AES_CONTROL), reg_shadow);
+ */
+
+#endif /*_CC_REGS_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_sym_error.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_sym_error.h
new file mode 100644
index 0000000..a808df5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_sym_error.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __CC_ERROR_H__
+#define __CC_ERROR_H__
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#define INT32_MAX 0x7FFFFFFFL
+#else
+#include <stdint.h>
+#endif
+
+
+typedef enum CCSymRetCode {
+    CC_RET_OK = 0, /* No error */
+    CC_RET_UNSUPP_ALG, /* Unsupported algorithm */
+    CC_RET_UNSUPP_ALG_MODE, /* Unsupported algorithm mode */
+    CC_RET_UNSUPP_OPERATION, /* Unsupported operation */
+    CC_RET_UNSUPP_HWKEY, /* Unsupported hw key */
+    CC_RET_INV_HWKEY, /* invalid hw key */
+    CC_RET_INVARG, /* Invalid parameter */
+    CC_RET_INVARG_KEY_SIZE, /* Invalid key size */
+    CC_RET_INVARG_CTX_IDX, /* Invalid context index */
+    CC_RET_INVARG_CTX, /* Bad or corrupted context */
+    CC_RET_INVARG_BAD_ADDR, /* Bad address */
+    CC_RET_INVARG_INCONSIST_DMA_TYPE, /* DIN is inconsist with DOUT DMA type */
+    CC_RET_PERM, /* Operation not permitted */
+    CC_RET_NOEXEC, /* Execution format error */
+    CC_RET_BUSY, /* Resource busy */
+    CC_RET_NOMEM, /* Out of memory */
+    CC_RET_OSFAULT, /* Internal TEE_OS error */
+    CCSYMCRYPTO_RET_RESERVE32 = INT32_MAX /* assure this enum is 32b */
+}CCSymRetCode_t;
+
+
+#endif /*__CC_ERROR_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_asset_prov_int.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_asset_prov_int.h
new file mode 100644
index 0000000..a909877
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_asset_prov_int.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_UTIL_ASSET_PROV_INT_H
+#define  _CC_UTIL_ASSET_PROV_INT_H
+
+/*!
+@file
+@brief This file contains the functions and definitions for the ICV or OEM Asset provisioning in run-time library.
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "cc_pal_types.h"
+#include "cc_bitops.h"
+
+#define CC_ASSET_PROV_MAX_ASSET_SIZE  (4*CC_1K_SIZE_IN_BYTES)
+
+#define CC_ASSET_PROV_TOKEN     0x41736574UL
+#define CC_ASSET_PROV_VERSION   0x10000UL
+
+#define CC_ASSET_PROV_NONCE_SIZE    12
+#define CC_ASSET_PROV_RESERVED_SIZE     8
+#define CC_ASSET_PROV_RESERVED_WORD_SIZE    (CC_ASSET_PROV_RESERVED_SIZE/CC_32BIT_WORD_SIZE)
+#define CC_ASSET_PROV_TAG_SIZE      16
+#define CC_ASSET_PROV_BLOCK_SIZE    16
+
+#define CC_ASSET_PROV_ADATA_SIZE    (3*CC_32BIT_WORD_SIZE+CC_ASSET_PROV_RESERVED_SIZE)  // token||version||assetSize||reserved
+
+
+typedef struct {
+        uint32_t  token;
+        uint32_t  version;
+        uint32_t  assetSize;
+        uint32_t  reserved[CC_ASSET_PROV_RESERVED_WORD_SIZE];
+        uint8_t   nonce[CC_ASSET_PROV_NONCE_SIZE];
+        uint8_t   encAsset[CC_ASSET_PROV_MAX_ASSET_SIZE+CC_ASSET_PROV_TAG_SIZE];
+}CCAssetProvPkg_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_CC_UTIL_ASSET_PROV_INT_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_defs.h
new file mode 100644
index 0000000..c100f6c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_defs.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_UTIL_DEFS_H
+#define  _CC_UTIL_DEFS_H
+
+/*!
+@defgroup cc_utils CryptoCell utility APIs
+@{
+@ingroup cryptocell_api
+@brief This group is the utility apis group
+@}
+
+@file
+@brief This file contains CryptoCell Util general definitions.
+@defgroup cc_utils_defs CryptoCell utils general definitions
+@{
+@ingroup cc_utils
+
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types_plat.h"
+#include "cc_util_key_derivation_defs.h"
+
+
+/******************************************************************************
+*                           DEFINITIONS
+******************************************************************************/
+/*! Supported AES key size in bits. */
+#define CC_UTIL_AES_128BIT_SIZE 16  // same as CC_AES_128_BIT_KEY_SIZE
+#define CC_UTIL_AES_192BIT_SIZE 24  // same as CC_AES_192_BIT_KEY_SIZE
+#define CC_UTIL_AES_256BIT_SIZE 32  // same as CC_AES_256_BIT_KEY_SIZE
+/*****************************************/
+/* CMAC derive key definitions*/
+/*****************************************/
+/*! Minimal data size for CMAC derivation operation. */
+#define CC_UTIL_CMAC_DERV_MIN_DATA_IN_SIZE  CC_UTIL_FIX_DATA_MIN_SIZE_IN_BYTES+2
+/*! Maximal data size for CMAC derivation operation. */
+#define CC_UTIL_CMAC_DERV_MAX_DATA_IN_SIZE  CC_UTIL_MAX_KDF_SIZE_IN_BYTES
+/*! AES CMAC result size in bytes. */
+#define CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES   0x10UL
+/*! AES CMAC result size in words. */
+#define CC_UTIL_AES_CMAC_RESULT_SIZE_IN_WORDS   (CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES/sizeof(uint32_t))
+
+/*! Util Error type. */
+typedef uint32_t CCUtilError_t;
+/*! Defines the CMAC result buffer. */
+typedef uint8_t CCUtilAesCmacResult_t[CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES];
+
+
+/*! Key Data. */
+typedef struct CCKeyData_t {
+    uint8_t*  pKey;     /*!< Pointer to the key. */
+    size_t    keySize;  /*!< The key size in bytes. */
+}CCKeyData_t;
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /*_CC_UTIL_DEFS_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_error.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_error.h
new file mode 100644
index 0000000..65983ab
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/cc_util_error.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_utils_errors
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the error definitions of the CryptoCell utility APIs.
+ */
+
+#ifndef  _CC_UTIL_ERROR_H
+#define  _CC_UTIL_ERROR_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/***********************/
+/* Util return codes   */
+/***********************/
+/*! Success definition. */
+#define CC_UTIL_OK                                      0x00UL
+/*! The error base address definition. */
+#define CC_UTIL_MODULE_ERROR_BASE                       0x80000000
+/*! Illegal key type. */
+#define CC_UTIL_INVALID_KEY_TYPE                        (CC_UTIL_MODULE_ERROR_BASE + 0x00UL)
+/*! Illegal data-in pointer. */
+#define CC_UTIL_DATA_IN_POINTER_INVALID_ERROR           (CC_UTIL_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal data-in size. */
+#define CC_UTIL_DATA_IN_SIZE_INVALID_ERROR              (CC_UTIL_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal data-out pointer. */
+#define CC_UTIL_DATA_OUT_POINTER_INVALID_ERROR          (CC_UTIL_MODULE_ERROR_BASE + 0x03UL)
+/*! Illegal data-out size. */
+#define CC_UTIL_DATA_OUT_SIZE_INVALID_ERROR             (CC_UTIL_MODULE_ERROR_BASE + 0x04UL)
+/*! Fatal error. */
+#define CC_UTIL_FATAL_ERROR                             (CC_UTIL_MODULE_ERROR_BASE + 0x05UL)
+/*! Illegal parameters. */
+#define CC_UTIL_ILLEGAL_PARAMS_ERROR                    (CC_UTIL_MODULE_ERROR_BASE + 0x06UL)
+/*! Invalid address given. */
+#define CC_UTIL_BAD_ADDR_ERROR                          (CC_UTIL_MODULE_ERROR_BASE + 0x07UL)
+/*! Illegal domain for endorsement key. */
+#define CC_UTIL_EK_DOMAIN_INVALID_ERROR                 (CC_UTIL_MODULE_ERROR_BASE + 0x08UL)
+/*! HUK is not valid. */
+#define CC_UTIL_KDR_INVALID_ERROR                       (CC_UTIL_MODULE_ERROR_BASE + 0x09UL)
+/*! LCS is not valid. */
+#define CC_UTIL_LCS_INVALID_ERROR                       (CC_UTIL_MODULE_ERROR_BASE + 0x0AUL)
+/*! Session key is not valid. */
+#define CC_UTIL_SESSION_KEY_ERROR                       (CC_UTIL_MODULE_ERROR_BASE + 0x0BUL)
+/*! Illegal user key size. */
+#define CC_UTIL_INVALID_USER_KEY_SIZE                   (CC_UTIL_MODULE_ERROR_BASE + 0x0DUL)
+/*! Illegal LCS for the required operation. */
+#define CC_UTIL_ILLEGAL_LCS_FOR_OPERATION_ERR           (CC_UTIL_MODULE_ERROR_BASE + 0x0EUL)
+/*! Invalid PRF type. */
+#define CC_UTIL_INVALID_PRF_TYPE                        (CC_UTIL_MODULE_ERROR_BASE + 0x0FUL)
+/*! Invalid hash mode. */
+#define CC_UTIL_INVALID_HASH_MODE                       (CC_UTIL_MODULE_ERROR_BASE + 0x10UL)
+/*! Unsupported hash mode. */
+#define CC_UTIL_UNSUPPORTED_HASH_MODE                   (CC_UTIL_MODULE_ERROR_BASE + 0x11UL)
+/*! Key is unusable */
+#define CC_UTIL_KEY_UNUSABLE_ERROR                       (CC_UTIL_MODULE_ERROR_BASE + 0x12UL)
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /*_CC_UTIL_ERROR_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_defs.h
new file mode 100644
index 0000000..b13ed24
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_defs.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_utils_defs
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains general definitions of the CryptoCell utility APIs.
+ */
+
+#ifndef  _MBEDTLS_CC_UTIL_DEFS_H
+#define  _MBEDTLS_CC_UTIL_DEFS_H
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types_plat.h"
+#include "mbedtls_cc_util_key_derivation_defs.h"
+
+
+/******************************************************************************
+*                           DEFINITIONS
+******************************************************************************/
+/*! The size of the AES 128-bit key in bytes. */
+#define CC_UTIL_AES_128BIT_SIZE 16
+/*! The size of the AES 192-bit key in bytes. */
+#define CC_UTIL_AES_192BIT_SIZE 24
+/*! The size of the AES 256-bit key in bytes. */
+#define CC_UTIL_AES_256BIT_SIZE 32
+/*****************************************/
+/* CMAC derive key definitions*/
+/*****************************************/
+/*! The minimal size of the data for the CMAC derivation operation. */
+#define CC_UTIL_CMAC_DERV_MIN_DATA_IN_SIZE  CC_UTIL_FIX_DATA_MIN_SIZE_IN_BYTES+2
+/*! The maximal size of the data for CMAC derivation operation. */
+#define CC_UTIL_CMAC_DERV_MAX_DATA_IN_SIZE  CC_UTIL_MAX_KDF_SIZE_IN_BYTES
+/*! The size of the AES CMAC result in bytes. */
+#define CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES   0x10UL
+/*! The size of the AES CMAC result in words. */
+#define CC_UTIL_AES_CMAC_RESULT_SIZE_IN_WORDS   (CC_UTIL_AES_CMAC_RESULT_SIZE_IN_BYTES/sizeof(uint32_t))
+
+/*! Util error type. */
+typedef uint32_t CCUtilError_t;
+
+
+
+/*! The key data. */
+typedef struct mbedtls_util_keydata {
+    /*! A pointer to the key. */
+    uint8_t*  pKey;
+    /*! The size of the key in bytes. */
+    size_t    keySize;
+}mbedtls_util_keydata;
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /*_MBEDTLS_CC_UTIL_DEFS_H*/
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_key_derivation.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_key_derivation.h
new file mode 100644
index 0000000..18d8b37
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_key_derivation.h
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_utils_key_derivation
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the CryptoCell utility key-derivation function APIs.
+
+ The key-derivation function is defined as specified in the
+ <em>KDF in Counter Mode</em> section in <em>NIST Special Publication
+ 800-108: Recommendation for Key Derivation Using Pseudorandom Functions</em>.
+ */
+
+#ifndef  _MBEDTLS_CC_UTIL_KEY_DERIVATION_H
+#define  _MBEDTLS_CC_UTIL_KEY_DERIVATION_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "mbedtls_cc_util_defs.h"
+#include "mbedtls_cc_util_key_derivation_defs.h"
+#include "cc_hash_defs.h"
+
+/******************************************************************************
+*                           DEFINITIONS
+******************************************************************************/
+
+/*! Derivation type of the input key. */
+typedef enum  {
+    /*! The user key.*/
+    CC_UTIL_USER_KEY = 0,
+    /*! The device root key (the HUK).*/
+    CC_UTIL_ROOT_KEY = 1,
+    /*! Total number of keys.*/
+    CC_UTIL_TOTAL_KEYS = 2,
+    /*! Reserved.*/
+    CC_UTIL_END_OF_KEY_TYPE = 0x7FFFFFFF
+}mbedtls_util_keytype_t;
+
+/*! Pseudo-random function type for key derivation. */
+typedef enum {
+    /*! The CMAC function.*/
+    CC_UTIL_PRF_CMAC = 0,
+    /*! The HMAC function.*/
+    CC_UTIL_PRF_HMAC = 1,
+    /*! The total number of pseudo-random functions.*/
+    CC_UTIL_TOTAL_PRFS = 2,
+    /*! Reserved.*/
+    CC_UTIL_END_OF_PRF_TYPE = 0x7FFFFFFF
+}mbedtls_util_prftype_t;
+
+
+/*!
+  @brief  This function performs key derivation.
+
+  It is defined as specified in the <em>KDF in Counter Mode</em> section in
+  <em>NIST Special Publication 800-108: Recommendation for Key Derivation
+  Using Pseudorandom Functions</em>.
+
+  The derivation is based on length l, label L, context C, and derivation key
+  Ki.
+
+  AES-CMAC or HMAC are used as the pseudo-random function (PRF).
+
+  @note   You must define the label and context for each use-case well
+  when using this API.
+
+  @return \c CC_UTIL_OK on success.
+  @return A non-zero value from cc_util_error.h on failure.
+ */
+/*  A key-derivation function can iterates n times until l bits of keying material are generated.
+        For each of the iterations of the PRF, i=1 to n, do:
+        result(0) = 0;
+        K(i) = PRF (Ki, [i] || Label || 0x00 || Context || length);
+        results(i) = result(i-1) || K(i);
+
+        concisely, result(i) = K(i) || k(i-1) || .... || k(0)*/
+CCUtilError_t mbedtls_util_key_derivation(
+    /*! [in] The key type that is used as an input to a key-derivation
+    function: \p CC_UTIL_USER_KEY or \p CC_UTIL_ROOT_KEY. */
+    mbedtls_util_keytype_t        keyType,
+    /*! [in] A pointer to the key buffer of the user, in case of \p
+    CC_UTIL_USER_KEY. */
+    mbedtls_util_keydata        *pUserKey,
+    /*! [in] The PRF type that is used as an input to a key-derivation
+    function: \p CC_UTIL_PRF_CMAC or \p CC_UTIL_PRF_HMAC. */
+    mbedtls_util_prftype_t        prfType,
+    /*! [in] One of the supported hash modes that are defined in \p
+    CCHashOperationMode_t. */
+    CCHashOperationMode_t       hashMode,
+    /*! [in] A string that identifies the purpose for the derived keying
+    material.*/
+    const uint8_t               *pLabel,
+    /*! [in] The label size must be in range of 1 to 64 bytes in length. */
+    size_t                      labelSize,
+    /*! [in] A binary string containing the information related to the derived
+    keying material. */
+    const uint8_t               *pContextData,
+    /*! [in] The context size must be in range of 1 to 64 bytes in length. */
+    size_t                      contextSize,
+    /*! [out] Keying material output. Must be at least the size of \p
+    derivedKeySize. */
+    uint8_t                     *pDerivedKey,
+    /*! [in] The size of the derived keying material in bytes, up to 4080
+    bytes. */
+    size_t                      derivedKeySize
+    );
+
+
+/*!
+  @brief  This function performs key derivation using using AES-CMAC.
+
+  It is defined as specified in the <em>KDF in Counter Mode</em> section in
+  <em>NIST Special Publication 800-108: Recommendation for Key Derivation
+  Using Pseudorandom Functions</em>.
+
+  The derivation is based on length l, label L, context C, and derivation key
+  Ki.
+
+  @return \c CC_UTIL_OK on success.
+  @return A non-zero value from cc_util_error.h on failure.
+ */
+#define mbedtls_util_key_derivation_cmac(keyType, pUserKey, pLabel, labelSize, pContextData, contextSize, pDerivedKey, derivedKeySize) \
+    mbedtls_util_key_derivation(keyType, pUserKey, CC_UTIL_PRF_CMAC, CC_HASH_OperationModeLast, pLabel, labelSize, pContextData, contextSize, pDerivedKey, derivedKeySize)
+
+
+/*!
+  @brief  This function performs key derivation using HMAC.
+
+  It is defined as specified in the <em>KDF in Counter Mode</em> section in
+  <em>NIST Special Publication 800-108: Recommendation for Key Derivation
+  Using Pseudorandom Functions</em>.
+
+  The derivation is based on length l, label L, context C, and derivation key
+  Ki.
+
+  HMAC is used as the pseudo-random function (PRF).
+
+ @return \c CC_UTIL_OK on success.
+ @return A non-zero value from cc_util_error.h on failure.
+ */
+#define mbedtls_util_key_derivation_hmac(keyType, pUserKey, hashMode, pLabel, labelSize, pContextData, contextSize, pDerivedKey, derivedKeySize) \
+    mbedtls_util_key_derivation(keyType, pUserKey, CC_UTIL_PRF_HMAC, hashMode, pLabel, labelSize, pContextData, contextSize, pDerivedKey, derivedKeySize)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /*_MBEDTLS_CC_UTIL_KEY_DERIVATION_H*/
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_key_derivation_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_key_derivation_defs.h
new file mode 100644
index 0000000..4ba96b7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/cc_util/mbedtls_cc_util_key_derivation_defs.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_utils_key_defs
+ @{
+*/
+
+/*!
+ @file
+ @brief This file contains the definitions for the key-derivation API.
+ */
+
+
+#ifndef  _CC_UTIL_KEY_DERIVATION_DEFS_H
+#define  _CC_UTIL_KEY_DERIVATION_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/******************************************************************************
+*                           DEFINITIONS
+******************************************************************************/
+
+/*! The maximal length of the label in bytes. */
+#define CC_UTIL_MAX_LABEL_LENGTH_IN_BYTES   64
+/*! The maximal length of the context in bytes. */
+#define CC_UTIL_MAX_CONTEXT_LENGTH_IN_BYTES     64
+/*! The minimal size of the fixed data in bytes. */
+#define CC_UTIL_FIX_DATA_MIN_SIZE_IN_BYTES  3 /*!< \internal counter, 0x00, lengt(-0xff) */
+/*! The maximal size of the fixed data in bytes. */
+#define CC_UTIL_FIX_DATA_MAX_SIZE_IN_BYTES  4 /*!< \internal counter, 0x00, lengt(0x100-0xff0) */
+/*! The maximal size of the derived-key material in bytes. */
+#define CC_UTIL_MAX_KDF_SIZE_IN_BYTES (CC_UTIL_MAX_LABEL_LENGTH_IN_BYTES+CC_UTIL_MAX_CONTEXT_LENGTH_IN_BYTES+CC_UTIL_FIX_DATA_MAX_SIZE_IN_BYTES)
+/*! The maximal size of the derived-key in bytes. */
+#define CC_UTIL_MAX_DERIVED_KEY_SIZE_IN_BYTES 4080
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+*/
+#endif /*_CC_UTIL_KEY_DERIVATION_DEFS_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_aes_defs_proj.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_aes_defs_proj.h
new file mode 100644
index 0000000..d2e9cd6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_aes_defs_proj.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_aes_defs_proj
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains project definitions that are used for CryptoCell
+ AES APIs.
+ */
+
+#ifndef CC_AES_DEFS_PROJ_H
+#define CC_AES_DEFS_PROJ_H
+
+#include "cc_pal_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/*! The size of the context prototype of the user in words.
+See ::CCAesUserContext_t.*/
+#define CC_AES_USER_CTX_SIZE_IN_WORDS (4+8+8+4)
+
+/*! The maximal size of the AES key in words. */
+#define CC_AES_KEY_MAX_SIZE_IN_WORDS 8
+/*! The maximal size of the AES key in bytes. */
+#define CC_AES_KEY_MAX_SIZE_IN_BYTES (CC_AES_KEY_MAX_SIZE_IN_WORDS * sizeof(uint32_t))
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/*!
+ @}
+ */
+
+#endif /* #ifndef CC_AES_DEFS_PROJ_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ec_edw_api.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ec_edw_api.h
new file mode 100644
index 0000000..291c18c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ec_edw_api.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_EC_EDW_API_H
+#define _CC_EC_EDW_API_H
+
+#include "cc_pal_types.h"
+#include "cc_hash_defs.h"
+#include "cc_rnd_common.h"
+#include "cc_pka_defs_hw.h"
+#include "cc_bitops.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+@file
+@brief This file contains the CryptoCell APIs used for EC EDW (Edwards) ed25519 algorithms.
+@defgroup cryptocell_ec CryptoCell EC 25519 curve APIs
+@{
+@ingroup cryptocell_api
+
+
+@note  Algorithms of Montgomery and Edwards elliptic curves cryptography were developed by
+       Daniel.J.Bernstein.
+*/
+
+/*! EC Edwards ed25519 modulus and order sizes in bits, words and bytes.  */
+/*! EC Edwards modulus size in bits. */
+#define CC_EC_EDW_MOD_SIZE_IN_BITS  255U   /*!<\internal MOD - EC Edw modulus size*/
+/*! EC Edwards order size in bits. */
+#define CC_EC_EDW_ORD_SIZE_IN_BITS  255U   /*!<\internal ORD - EC Edw generator order size*/
+/*! EC Edwards modulus size in words. */
+#define CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS ((CC_EC_EDW_MOD_SIZE_IN_BITS + CC_BITS_IN_32BIT_WORD - 1) / CC_BITS_IN_32BIT_WORD)
+/*! EC Edwards modulus size in bytes. */
+#define CC_EC_EDW_MOD_SIZE_IN_BYTES  (CC_EC_EDW_MOD_SIZE_IN_32BIT_WORDS * CC_32BIT_WORD_SIZE)
+/*! EC Edwards order size in words. */
+#define CC_EC_EDW_ORD_SIZE_IN_32BIT_WORDS ((CC_EC_EDW_MOD_SIZE_IN_BITS + CC_BITS_IN_32BIT_WORD - 1) / CC_BITS_IN_32BIT_WORD)
+/*! EC Edwards order size in bytes. */
+#define CC_EC_EDW_ORD_SIZE_IN_BYTES  (CC_EC_EDW_ORD_SIZE_IN_32BIT_WORDS * CC_32BIT_WORD_SIZE)
+
+/*! Constant sizes of special EC_MONT buffers and arrays  */
+/*! EC Edwards seed size in bytes. */
+#define CC_EC_EDW_SEED_BYTES       CC_EC_EDW_MOD_SIZE_IN_BYTES
+/*! EC Edwards secret key size in bytes. */
+#define CC_EC_EDW_SECRET_KEY_BYTES (2 * CC_EC_EDW_MOD_SIZE_IN_BYTES)
+/*! EC Edwards signatue size in bytes. */
+#define CC_EC_EDW_SIGNATURE_BYTES  (2 * CC_EC_EDW_ORD_SIZE_IN_BYTES)
+/*! EC Edwards scalar size in bytes. */
+#define CC_EC_EDW_SCALARBYTES     CC_EC_EDW_ORD_SIZE_IN_BYTES
+/*! EC Edwards scalar multiplication size in bytes. */
+#define CC_EC_EDW_SCALARMULTBYTES CC_EC_EDW_MOD_SIZE_IN_BYTES
+
+/*! EC_EDW temp buffer size definition. */
+#define CC_EC_EDW_TEMP_BUFF_SIZE_IN_32BIT_WORD   (10*CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS + (sizeof(CCHashUserContext_t)+CC_32BIT_WORD_SIZE-1)/CC_32BIT_WORD_SIZE)
+
+/*! EC_EDW temp buffer type definition. */
+typedef struct {
+    /*! Internal buffer. */
+        uint32_t buff[CC_EC_EDW_TEMP_BUFF_SIZE_IN_32BIT_WORD];
+ } CCEcEdwTempBuff_t;
+
+
+
+/******************************************************************************/
+/*!
+@brief The function creates EC Edwards signature on the message.
+\note Used detached form of signature, separated from the message.
+      Implemented algorithm of Bernstein D. etc. sign ed25519.
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h or cc_hash_error.h.
+*/
+CIMPORT_C CCError_t CC_EcEdwSign (
+                      uint8_t       *pSign,                /*!< [out] Pointer to the detached signature. */
+                      size_t        *pSignSize,            /*!< [in/out] Pointer to the total size of the signature ;
+                                            In  - the buffer size, which (must be at least 2*EC order size);
+                                            Out - the actual size of output data. */
+                      const uint8_t *pMsg,                 /*!< [in] Pointer to the message. */
+                      size_t         msgSize,              /*!< [in] Message size in bytes: must be less, than
+                                            (CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - 2*(EC_EDW modulus size)). */
+                      const uint8_t *pSignSecrKey,         /*!< [in] Pointer to the signer secret key (seed || pulKey) */
+                      size_t         secrKeySize,          /*!< [in] Size of signer secret key in bytes: (must be 2*EC order size). */
+                      CCEcEdwTempBuff_t *pTempBuff     /*!< [in] pointer to the temp buffer. */);
+
+
+
+/******************************************************************************/
+/*!
+@brief The function verifies the EC Edwards ed25519 signature on the message.
+\note The input signature is in detached form, i.e. separated from the message.
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h or cc_hash_error.h.
+*/
+CIMPORT_C CCError_t CC_EcEdwVerify(
+                       const uint8_t *pSign,                /*!< [in] Pointer to detached signature, i.e. the
+                                         signature is separated from the message. */
+                       size_t         signSize,             /*!< [in] Size of the signature in bytes, it must be
+                                         equal to two EC Order size in bytes. */
+                       const uint8_t *pSignPublKey,         /*!< [in] Pointer to signer public key. */
+                       size_t         publKeySize,          /*!< [in] Size of the signer public key in bytes; must be
+                                         equal to EC modulus size. */
+                       uint8_t       *pMsg,                 /*!< [in] Pointer to the message. */
+                       size_t         msgSize,              /*!< [in] Pointer to the message size in bytes. Must be less than
+                                         (CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES - 2*(EC_EDW modulus size)). */
+                       CCEcEdwTempBuff_t *pEcEdwTempBuff    /*!< [in] Pointer to temp buffer. */);
+
+
+
+/*******************************************************************/
+/*!
+@brief The function randomly generates Ec ed25519 private and public keys
+       using given seed.
+       The generation is performed using EC Edwards ed25519 algorithm.
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h or cc_hash_error.h.
+*/
+CIMPORT_C CCError_t CC_EcEdwSeedKeyPair (
+                         const uint8_t *pSeed,                  /*!< [in] Pointer to the given seed. */
+                         size_t         seedSize,               /*!< [in] Size of the seed in bytes, must be equal the EC order size
+                                             in bytes. */
+                         uint8_t       *pSecrKey,               /*!< [out] Pointer to the secret key, including the seed, concatenated
+                                             with the public key. */
+                         size_t        *pSecrKeySize,           /*!< [in/out] Pointer to the size of the secret key buffer in bytes
+                                             (must be at least 2*EC order size). */
+                         uint8_t       *pPublKey,               /*!< [out] Pointer to the public key. */
+                         size_t        *pPublKeySize,           /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                In  - the size of buffer must be at least EC modulus size;
+                                                Out - the actual size. */
+                         CCEcEdwTempBuff_t *pTempBuff       /*!< [in] Pointer to the temp buffer, for internal use. */);
+
+/*******************************************************************/
+/*!
+ @brief The function randomly generates the EC Edwards ed25519 private and
+    public keys.
+    The generation is performed using EC Edwards ed25519 algorithm.
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h, cc_hash_error.h or cc_rnd_error.
+*/
+CIMPORT_C CCError_t CC_EcEdwKeyPair (
+                     uint8_t       *pSecrKey,               /*!< [out] Pointer to the secret key (including seed and public key). */
+                     size_t        *pSecrKeySize,           /*!< [in/out] Pointer to the size of the secret key in bytes,
+                                              (must be at least 2*EC order size). */
+                     uint8_t       *pPublKey,               /*!< [out] Pointer to the public key. */
+                     size_t        *pPublKeySize,           /*!< [in/out] - Pointer to the size of the public key in bytes.
+                                            In  - the size of buffer must be at least EC modulus size;
+                                            Out - the actual size. */
+                     CCRndContext_t *pRndContext,           /*!< [in/out] Pointer to the RND context buffer. */
+                     CCEcEdwTempBuff_t *pTempBuff           /*!< [in] Pointer to the temp buffer. */);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ec_mont_api.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ec_mont_api.h
new file mode 100644
index 0000000..062d8ca
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ec_mont_api.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef CC_EC_MONT_API_TW_H
+#define CC_EC_MONT_API_TW_H
+
+#include "cc_pal_types.h"
+#include "cc_rnd_common.h"
+#include "cc_pka_defs_hw.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+@file
+@brief This file contains the CryptoCell APIs used for EC MONT (Montgomery Curve25519) algorithms.
+@defgroup cc_ec_mont CryptoCell EC Montgomery APIs
+@{
+@ingroup cryptocell_ec
+
+
+
+\note  Implemented algorithms according to Montgomery elliptic curves cryptography,
+       developed by Daniel J.Bernstein etc.
+*/
+
+/*! EC Montgomery curve25519 modulus size in bits, words and bytes  */
+/*! EC Montgomery modulus size in bits. */
+#define CC_EC_MONT_MOD_SIZE_IN_BITS  255U
+/*! EC Montgomery modulus size in words. */
+#define CC_EC_MONT_MOD_SIZE_IN_32BIT_WORDS ((CC_EC_MONT_MOD_SIZE_IN_BITS + CC_BITS_IN_32BIT_WORD - 1) / CC_BITS_IN_32BIT_WORD)
+/*! EC Montgomery modulus size in bytes. */
+#define CC_EC_MONT_MOD_SIZE_IN_BYTES       ((CC_EC_MONT_MOD_SIZE_IN_BITS + CC_BITS_IN_BYTE - 1) / CC_BITS_IN_BYTE)
+
+/*! Constant sizes of special EC_MONT buffers and arrays  */
+/*! EC Montgomery scalar size in bytes. */
+#define CC_EC_MONT_SCALARBYTES     (CC_EC_MONT_MOD_SIZE_IN_32BIT_WORDS * CC_32BIT_WORD_SIZE)
+/*! EC Montgomery scalar multiplication size in bytes. */
+#define CC_EC_MONT_SCALARMULTBYTES (CC_EC_MONT_MOD_SIZE_IN_32BIT_WORDS * CC_32BIT_WORD_SIZE)
+/*! EC Montgomery scalar seed size in bytes. */
+#define CC_EC_MONT_SEEDBYTES       (CC_EC_MONT_MOD_SIZE_IN_32BIT_WORDS * CC_32BIT_WORD_SIZE)
+
+/*! EC Montgomery domains ID-s enumerator. */
+typedef enum
+{
+    CC_EC_MONT_DOMAIN_CURVE_25519,  /*!< EC Curve25519 */
+    /*! EC Montgomery last domain. */
+    CC_EC_MONT_DOMAIN_OFF_MODE,
+    /*! Reserved. */
+    CC_EC_MONT_DOMAIN_LAST = 0x7FFFFFFF
+}CCEcMontDomainId_t;
+
+
+/*! EC_MONT scalar mult temp buffer type definition */
+typedef struct {
+    /*! Internal temporary buffer. */
+        uint32_t ecMontScalarMultTempBuff[CC_EC_MONT_TEMP_BUFF_SIZE_IN_32BIT_WORDS]; //! ! Change as needed
+} CCEcMontScalrMultTempBuff_t;
+
+/*! EC_MONT temp buffer type definition */
+typedef struct {
+        /* Don't change sequence order of the buffers */
+    /*! Internal temporary buffer. */
+        uint32_t ecMontScalar[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+    /*! Internal temporary buffer. */
+        uint32_t ecMontResPoint[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+    /*! Internal temporary buffer. */
+        uint32_t ecMontInPoint[CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS];
+    /*! Internal temporary buffer. */
+        CCEcMontScalrMultTempBuff_t  ecMontScalrMultTempBuff;// if needed ?
+} CCEcMontTempBuff_t;
+
+
+/*********************************************************************/
+/*!
+@brief The function performs EC Montgomery (Curve25519) scalar multiplication:
+       resPoint = scalar * point.
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h.
+*/
+CIMPORT_C CCError_t CC_EcMontScalarmult(
+                                uint8_t       *pResPoint,       /*!< [out] Pointer to the public (secret) key. */
+                                size_t        *pResPointSize,   /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                       In  - the size of the buffer. must be at least EC modulus
+                                                                             size (for curve25519 - 32 bytes).
+                                                                       Out - the actual size. */
+                                const uint8_t *pScalar,         /*!< [in] Pointer to the secret (private) key. */
+                                size_t         scalarSize,      /*!< [in] Pointer to the size of the secret key in bytes;
+                                                                     must be equal to EC order size (for curve25519 - 32 bytes). */
+                                const uint8_t *pInPoint,        /*!< [in] Pointer to the input point (compressed). */
+                                size_t         inPointSize,     /*!< [in] Size of the point - must be equal to CC_EC_MONT_MOD_SIZE_IN_BYTES. */
+                                CCEcMontTempBuff_t *ecMontTempBuff  /*!< [in] Pointer to temp buffer, for internal use. */);
+
+
+
+/*********************************************************************/
+/*!
+@brief The function performs EC Montgomery (Curve25519) scalar multiplication of base point:
+       res = scalar * base_point.
+
+       Note: all byte arrays have LE order of bytes, i.e. LS byte is on left most place.
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h.
+*/
+CIMPORT_C CCError_t CC_EcMontScalarmultBase(
+                                uint8_t       *pResPoint,      /*!< [out] Pointer to the public (secret) key. */
+                                size_t        *pResPointSize,  /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                      In  - the size of buffer must be at least EC modulus size
+                                     (for curve25519 - 32 bytes);
+                                                                      Out - the actual size. */
+                                const uint8_t *pScalar,        /*!< [in] Pointer to the secret (private) key. */
+                                size_t         scalarSize,     /*!< [in] Pointer to the size of the scalar in bytes -
+                                                                    must be equal to EC order size (for curve25519 - 32 bytes). */
+                                CCEcMontTempBuff_t *pEcMontTempBuff /*!< [in] Pointer to temp buffer, for internal use. */);
+
+
+/*******************************************************************/
+/*!
+@brief The function randomly generates  private and public keys for Montgomery
+       Curve25519. it uses CC_EcMontKeyPair with the Generator point of the Curve
+
+
+\note All byte arrays are in LE order of bytes, i.e. LS byte is on the left most place.\par
+\note LS and MS bits of the Secret key are set according to EC Montgomery scalar mult. algorithm:
+      secrKey[0] &= 248; secrKey[31] &= 127; secrKey[31] |= 64;
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h or cc_rnd_error.h.
+
+*/
+CIMPORT_C CCError_t CC_EcMontKeyPair (
+                      uint8_t *pPublKey,                    /*!< [out] Pointer to the public key. */
+                      size_t  *pPublKeySize,                /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                  In  - the size of the buffer must be at least EC order size
+                                                                        (for curve25519 - 32 bytes);
+                                                                  Out - the actual size. */
+                      uint8_t *pSecrKey,                    /*!< [out] Pointer to the secret key, including. */
+                      size_t  *pSecrKeySize,                /*!< [in/out] Pointer to the size of buffer for the secret key in bytes -
+                                                                 must be at least EC order size (for curve25519 - 32 bytes). */
+                      CCRndContext_t *pRndContext,      /*!< [in/out] Pointer to the RND context buffer. */
+                      CCEcMontTempBuff_t *pEcMontTempBuff /*!< [in] Pointer to the temp buffer, for internal use. */);
+
+
+/*******************************************************************/
+
+/*!
+@brief The function randomly generates  private and public keys for Montgomery
+       Curve25519, using a configurable base point
+
+
+\note All byte arrays are in LE order of bytes, i.e. LS byte is on the left most place.\par
+\note LS and MS bits of the Secret key are set according to EC Montgomery scalar mult. algorithm:
+      secrKey[0] &= 248; secrKey[31] &= 127; secrKey[31] |= 64;
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h or cc_rnd_error.h.
+
+*/
+CIMPORT_C CCError_t CC_EcMontKeyPairBase (
+                      uint8_t *pPublKey,                    /*!< [out] Pointer to the public key. */
+                      size_t  *pPublKeySize,                /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                  In  - the size of the buffer must be at least EC order size
+                                                                        (for curve25519 - 32 bytes);
+                                                                  Out - the actual size. */
+                      uint8_t *pSecrKey,                    /*!< [out] Pointer to the secret key, including. */
+                      size_t  *pSecrKeySize,                /*!< [in/out] Pointer to the size of buffer for the secret key in bytes -
+                                                                 must be at least EC order size (for curve25519 - 32 bytes). */
+                      const uint8_t  *pInPoint,          /*!< [in] Pointer to the input point (compressed). */
+                      size_t         inPointSize,        /*!< [in] Size of the point - must be equal to CC_EC_MONT_MOD_SIZE_IN_BYTES. */
+                      CCRndContext_t *pRndContext,      /*!< [in/out] Pointer to the RND context buffer. */
+                      CCEcMontTempBuff_t *pEcMontTempBuff /*!< [in] Pointer to the temp buffer, for internal use. */);
+
+
+/*******************************************************************/
+
+/*!
+@brief The function generates private and public keys for Montgomery algorithms.
+
+       The generation performed using given seed.
+
+
+@return CC_OK on success,
+@return A non-zero value on failure as defined cc_ec_mont_edw_error.h or cc_hash_error.h.
+*/
+CIMPORT_C CCError_t CC_EcMontSeedKeyPair (
+                          uint8_t       *pPublKey,       /*!< [out] Pointer to the public (secret) key. */
+                          size_t        *pPublKeySize,   /*!< [in/out] Pointer to the size of the public key in bytes.
+                                                                 In  - the size of buffer must be at least EC order size
+                                                                       (for curve25519 - 32 bytes);
+                                                                 Out - the actual size. */
+                          uint8_t       *pSecrKey,       /*!< [out] Pointer to the secret (private) key. */
+                          size_t        *pSecrKeySize,   /*!< [in/out] Pointer to the size of the secret key in bytes
+                                                                  In  - the size of buffer must be at least EC order size
+                                                                        (for curve25519 - 32 bytes);
+                                                                  Out - the actual size. */
+                          const uint8_t *pSeed,          /*!< [in] Pointer to the given seed - 32 bytes. */
+                          size_t         seedSize,       /*!< [in/] Size of the seed in bytes (must be equal to CC_EC_MONT_SEEDBYTES). */
+                          CCEcMontTempBuff_t *pEcMontTempBuff  /*!< [in] Pointer to a temp buffer, for internal use. */);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ecpki_domain.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ecpki_domain.h
new file mode 100644
index 0000000..59ce0c4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_ecpki_domain.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef CC_ECPKI_DOMAIN_H
+#define CC_ECPKI_DOMAIN_H
+
+
+/*!
+@file
+@brief This file defines the ecpki build domain API.
+@defgroup cc_ecpki_domain CryptoCell ECC domain APIs
+@{
+@ingroup cryptocell_ecpki
+
+*/
+
+
+#include "cc_error.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+
+/**********************************************************************************
+ *                CC_EcpkiGetEcDomain function                *
+ **********************************************************************************/
+
+/*!
+ * @brief  The function returns a pointer to an ECDSA saved domain (one of the supported domains).
+ *
+ * @return Domain pointer on success.
+ * @return NULL on failure.
+ */
+
+const CCEcpkiDomain_t *CC_EcpkiGetEcDomain(CCEcpkiDomainID_t domainId /*!< [in] Index of one of the domain Id (must be one of the supported domains). */);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_hash_defs_proj.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_hash_defs_proj.h
new file mode 100644
index 0000000..80d10c6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_hash_defs_proj.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_hash_defs_proj
+ @{
+ */
+
+
+/*!
+ @file
+ @brief This file contains the project-specific definitions of hash APIs.
+ */
+
+#ifndef _CC_HASH_DEFS_PROJ_H
+#define _CC_HASH_DEFS_PROJ_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/*! The size of the context prototype of the user in words.
+See ::CCHashUserContext_t. */
+#define CC_HASH_USER_CTX_SIZE_IN_WORDS 60
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_pka_defs_hw.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_pka_defs_hw.h
new file mode 100644
index 0000000..a567017
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_pka_defs_hw.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pka_defs_hw
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all of the enums and definitions that are used in
+ PKA APIs.
+ */
+
+#ifndef _CC_PKA_DEFS_HW_H_
+#define _CC_PKA_DEFS_HW_H_
+
+#include "cc_pal_types.h"
+#include "cc_pka_hw_plat_defs.h"
+
+/* The valid key sizes in bits for RSA primitives (exponentiation) */
+/*! The maximal RSA modulus size. */
+#define CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS ((CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS + CC_PKA_WORD_SIZE_IN_BITS) / CC_BITS_IN_32BIT_WORD )
+/*! The maximal EC modulus size. */
+#define CC_ECPKI_MODUL_MAX_LENGTH_IN_BITS   521
+
+/*! The size of the buffers for Barrett modulus tag NP, used in PKI
+algorithms. */
+#define CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS 5
+/*! The size of the buffers for Barrett modulus tag NP, used in ECC. */
+#define CC_PKA_ECPKI_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS  CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS
+/*! The actual size of Barrett modulus tag NP in words for current
+HW platform. */
+#define CC_PKA_BARRETT_MOD_TAG_SIZE_IN_WORDS  \
+    (((CC_PKA_WORD_SIZE_IN_BITS + PKA_EXTRA_BITS - 1) + (CC_BITS_IN_32BIT_WORD - 1)) / CC_BITS_IN_32BIT_WORD )
+/*! The maximal size of the PKA modulus. */
+#define CC_PKA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS
+/*! The maximal size of the PKA public-key in words. */
+#define CC_PKA_PUB_KEY_BUFF_SIZE_IN_WORDS (2*CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS)
+/*! The maximal size of the PKA private-key in words. */
+#define CC_PKA_PRIV_KEY_BUFF_SIZE_IN_WORDS (2*CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS)
+/*! The maximal size of the PKA KG buffer in words */
+#define CC_PKA_KGDATA_BUFF_SIZE_IN_WORDS   (3*CC_PKA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS + 3*CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS)
+
+/*! The maximal size of the EC modulus in words. */
+#define CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS  18 /*!< \internal [(CC_ECPKI_MODUL_MAX_LENGTH_IN_BITS + 31)/(sizeof(uint32_t)) + 1] */
+/*! The maximal size of the EC order in words. */
+#define CC_ECPKI_ORDER_MAX_LENGTH_IN_WORDS  (CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1)
+/*! The maximal size of the EC domain in words. */
+#define CC_PKA_DOMAIN_BUFF_SIZE_IN_WORDS (2*CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS)
+
+/*! The ECC NAF buffer definitions. */
+#define COUNT_NAF_WORDS_PER_KEY_WORD  8  /*!< \internal Change according to NAF representation (? 2)*/
+/*! The maximal length of the ECC NAF buffer. */
+#define CC_PKA_ECDSA_NAF_BUFF_MAX_LENGTH_IN_WORDS (COUNT_NAF_WORDS_PER_KEY_WORD*CC_ECPKI_ORDER_MAX_LENGTH_IN_WORDS + 1)
+
+#ifndef CC_SUPPORT_ECC_SCA_SW_PROTECT
+/* on fast SCA non protected mode required additional buffers for NAF key */
+/*! The size of the Scalar buffer in words. */
+#define CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS (CC_PKA_ECDSA_NAF_BUFF_MAX_LENGTH_IN_WORDS+CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+2)
+#else
+/*! The size of the Scalar buffer in words. */
+#define CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS  1 /*(4*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)*/
+#endif
+/*! The size of the ECC temporary buffer in words. */
+#define CC_PKA_ECPKI_BUILD_TMP_BUFF_MAX_LENGTH_IN_WORDS (3*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS)
+/*! The size of the ECC sign temporary buffer in words. */
+#define CC_PKA_ECDSA_SIGN_BUFF_MAX_LENGTH_IN_WORDS (6*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS+CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS)
+/*! The size of the ECC ECDH temporary-buffer in words. */
+#define CC_PKA_ECDH_BUFF_MAX_LENGTH_IN_WORDS (2*CC_ECPKI_ORDER_MAX_LENGTH_IN_WORDS + CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS)
+/*! The size of the PKA KG temporary-buffer in words. */
+#define CC_PKA_KG_BUFF_MAX_LENGTH_IN_WORDS (2*CC_ECPKI_ORDER_MAX_LENGTH_IN_WORDS + CC_PKA_ECPKI_SCALAR_MUL_BUFF_MAX_LENGTH_IN_WORDS)
+/*! The size of the ECC verify temporary-buffer in words. */
+#define CC_PKA_ECDSA_VERIFY_BUFF_MAX_LENGTH_IN_WORDS (3*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)
+
+/* *************************************************************************** */
+/*! The maximal size of the modulus buffers for CC_EC_MONT and EC_EDW in
+bytes.*/
+#define CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_BYTES  32U  /*!< \internal for Curve25519 */
+/*! The maximal size of the modulus buffers for CC_EC_MONT and EC_EDW in
+words. */
+#define CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS   8U  /*!< \internal for Curve25519 */
+/*! The size of the ECC Montgomery temporary buffer in words. */
+#define CC_EC_MONT_TEMP_BUFF_SIZE_IN_32BIT_WORDS  (8 * CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS) /*!< \internal Change according to actual requirements */
+/*! The size of the ECC Edwards temporary buffer in words. */
+#define CC_EC_EDW_TEMP_BUFF_SIZE_IN_32BIT_WORDS   (8*CC_EC_MONT_EDW_MODULUS_MAX_SIZE_IN_WORDS + (sizeof(CCHashUserContext_t)+CC_32BIT_WORD_SIZE-1)/CC_32BIT_WORD_SIZE)
+
+/*!
+ @}
+ */
+#endif /*_CC_PKA_DEFS_HW_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_rnd_common.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_rnd_common.h
new file mode 100644
index 0000000..9ec29b6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/cc_rnd_common.h
@@ -0,0 +1,246 @@
+/**************************************************************************************
+* Copyright (c) 2016-2019, Arm Limited (or its affiliates). All rights reserved       *
+*                                                                                     *
+* This file and the related binary are licensed under the following license:          *
+*                                                                                     *
+* ARM Object Code and Header Files License, v1.0 Redistribution.                      *
+*                                                                                     *
+* Redistribution and use of object code, header files, and documentation, without     *
+* modification, are permitted provided that the following conditions are met:         *
+*                                                                                     *
+* 1) Redistributions must reproduce the above copyright notice and the                *
+*    following disclaimer in the documentation and/or other materials                 *
+*    provided with the distribution.                                                  *
+*                                                                                     *
+* 2) Unless to the extent explicitly permitted by law, no reverse                     *
+*    engineering, decompilation, or disassembly of is permitted.                      *
+*                                                                                     *
+* 3) Redistribution and use is permitted solely for the purpose of                    *
+*    developing or executing applications that are targeted for use                   *
+*    on an ARM-based product.                                                         *
+*                                                                                     *
+* DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND                  *
+* CONTRIBUTORS "AS IS." ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT             *
+* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT,        *
+* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          *
+* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,   *
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED            *
+* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR              *
+* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF              *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING                *
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS                  *
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                        *
+**************************************************************************************/
+
+/*!
+ @addtogroup cc_rnd
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the CryptoCell random-number generation (RNG) APIs.
+
+ The random-number generation module implements <em>NIST Special Publication
+ 800-90A: Recommendation for Random Number Generation Using Deterministic
+ Random Bit Generators.</em>
+ */
+
+
+#ifndef _CC_RND_COMMON_H
+#define _CC_RND_COMMON_H
+
+#include "cc_error.h"
+#include "cc_aes_defs.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/* RND seed and additional input sizes */
+/*! The maximal size of the random seed in words. */
+#define CC_RND_SEED_MAX_SIZE_WORDS                  12
+#ifndef USE_MBEDTLS_CRYPTOCELL
+#ifndef CC_RND_ADDITINAL_INPUT_MAX_SIZE_WORDS
+/*! The maximal size of the additional input-data in words. */
+#define CC_RND_ADDITINAL_INPUT_MAX_SIZE_WORDS   CC_RND_SEED_MAX_SIZE_WORDS
+#endif
+#endif
+/* maximal requested size counter (12 bits active) - maximal count
+of generated random 128 bit blocks allowed per one request of
+Generate function according NIST 800-90 it is (2^12 - 1) = 0x3FFFF */
+/* Max size for one RNG generation (in bits) =
+  max_num_of_bits_per_request = 2^19 (FIPS 800-90 Tab.3) */
+/*! The maximal size of the generated vector in bits. */
+#define CC_RND_MAX_GEN_VECTOR_SIZE_BITS       0x7FFFF
+/*! The maximal size of the generated random vector in bytes. */
+#define CC_RND_MAX_GEN_VECTOR_SIZE_BYTES    0xFFFF
+/*! The maximal size of the generated vector in bytes. */
+#define CC_RND_REQUESTED_SIZE_COUNTER  0x3FFFF
+
+/*   Definitions of temp buffer for RND_DMA  */
+/*******************************************************************/
+/*   Definitions of temp buffer for DMA  */
+/*! The size of the temporary buffer in words. */
+#define CC_RND_WORK_BUFFER_SIZE_WORDS 136
+
+/*! The definition of the RAM buffer, for internal use in instantiation or
+reseeding operations. */
+typedef struct
+{
+    /*! The internal buffer. */
+    uint32_t ccRndIntWorkBuff[CC_RND_WORK_BUFFER_SIZE_WORDS];
+}CCRndWorkBuff_t;
+
+
+/* RND source buffer inner (entrpopy) offset       */
+/*! The definition of the internal offset in words. */
+#define CC_RND_TRNG_SRC_INNER_OFFSET_WORDS    2
+/*! The definition of the internal offset in bytes. */
+#define CC_RND_TRNG_SRC_INNER_OFFSET_BYTES    (CC_RND_TRNG_SRC_INNER_OFFSET_WORDS*sizeof(uint32_t))
+
+
+/************************ Enumerators  ****************************/
+
+/*! The definition of the random operation modes. */
+typedef  enum
+{
+    /*! HW entropy estimation: 800-90B or full. */
+    CC_RND_FE  = 1,
+    /*! Reserved. */
+    CC_RND_ModeLast = 0x7FFFFFFF,
+} CCRndMode_t;
+
+
+/************************ Structs  *****************************/
+
+
+/* The internal state of DRBG mechanism based on AES CTR and CBC-MAC
+   algorithms. It is set as global data defined by the following
+   structure  */
+/*!
+
+  @brief The structure for the RND state.
+  This includes internal data that must be saved by the user between boots.
+ */
+typedef  struct
+{
+#ifndef USE_MBEDTLS_CRYPTOCELL
+    /* Seed buffer, consists from concatenated Key||V: max size 12 words */
+    /*! The random-seed buffer. */
+    uint32_t  Seed[CC_RND_SEED_MAX_SIZE_WORDS];
+    /* Previous value for continuous test */
+    /*! The previous random data, used for continuous test. */
+    uint32_t  PreviousRandValue[CC_AES_CRYPTO_BLOCK_SIZE_IN_WORDS];
+    /* AdditionalInput buffer max size = seed max size words + 4w for padding*/
+    /*! The previous additional-input buffer. */
+    uint32_t  PreviousAdditionalInput[CC_RND_ADDITINAL_INPUT_MAX_SIZE_WORDS+3];
+    /*! The additional-input buffer. */
+    uint32_t  AdditionalInput[CC_RND_ADDITINAL_INPUT_MAX_SIZE_WORDS+4];
+    /*! The size of the additional input in words. */
+    uint32_t  AddInputSizeWords;
+    /*! The size of the entropy source in words. */
+    uint32_t  EntropySourceSizeWords;
+    /*! The Reseed counter (32-bit active). Indicates the number of requests
+    for entropy since instantiation or reseeding. */
+    uint32_t  ReseedCounter;
+    /*! The key size in words, according to security strength: 128 bits:
+    4 words. 256 bits: 8 words. */
+    uint32_t KeySizeWords;
+    /* State flag (see definition of StateFlag above), containing bit-fields, defining:
+    - b'0: instantiation steps:   0 - not done, 1 - done;
+    - 2b'9,8: working or testing mode: 0 - working, 1 - KAT DRBG test, 2 -
+      KAT TRNG test;
+    b'16: flag defining is Previous random valid or not:
+            0 - not valid, 1 - valid */
+    /*! The state flag used internally in the code. */
+    uint32_t StateFlag;
+    /* validation tag */
+    /*! The validation tag used internally in the code. */
+    uint32_t ValidTag;
+    /*! The size of the RND source entropy in bits. */
+    uint32_t  EntropySizeBits;
+
+#endif
+    /*! The TRNG process state used internally in the code. */
+    uint32_t TrngProcesState;
+
+} CCRndState_t;
+
+
+/*! The RND vector-generation function pointer. */
+typedef int (*CCRndGenerateVectWorkFunc_t)(        \
+        /*! A pointer to the RND-state context. */
+        void              *rndState_ptr, \
+        /*! A pointer to the output buffer. */
+        unsigned char     *out_ptr, \
+        /*! The size of the output in bytes. */
+        size_t            outSizeBytes
+        );
+
+
+/*! The definition of the RND context that includes the CryptoCell
+    RND state structure, and a function pointer for the RND-generation
+    function. */
+typedef  struct
+{
+        /*! A pointer to the internal state of the RND.
+        Note: This pointer should be allocated in a physical and contiguous
+        memory, that is accessible to the CryptoCell DMA. This pointer should
+        be allocated and assigned before calling CC_LibInit(). */
+       void *   rndState;
+       /*! A pointer to the entropy context. Note: This pointer should be
+       allocated and assigned before calling CC_LibInit(). */
+       void *   entropyCtx;
+       /*! A pointer to the user-given function for generation a random
+       vector. */
+       CCRndGenerateVectWorkFunc_t rndGenerateVectFunc;
+} CCRndContext_t;
+
+
+
+
+
+/*****************************************************************************/
+/**********************        Public Functions      *************************/
+/*****************************************************************************/
+
+
+/****************************************************************************************/
+/*!
+ @brief This function sets the RND vector-generation function into the RND
+ context.
+
+ It is called as part of Arm CryptoCell library initialization, to
+ set the RND vector generation function into the primary RND context.
+
+ @note It must be called before any other API that requires the RND context as
+ a parameter.
+
+ @return \c CC_OK on success.
+ @return A non-zero value from cc_rnd_error.h on failure.
+ */
+CCError_t CC_RndSetGenerateVectorFunc(
+            /*! [in/out] A pointer to the RND context buffer that is allocated
+            by the user, which is used to maintain the RND state, as well as
+            pointers to the functions used for random vector generation. */
+            CCRndContext_t *rndContext_ptr,
+            /*! [in] A pointer to the \c CC_RndGenerateVector random
+            vector-generation function. */
+            CCRndGenerateVectWorkFunc_t rndGenerateVectFunc
+);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /* #ifndef _CC_RND_COMMON_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_aes_ext_dma.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_aes_ext_dma.h
new file mode 100644
index 0000000..093febb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_aes_ext_dma.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*!
+ @addtogroup aes_ext_dma
+ @{
+*/
+
+/*!
+ @file
+ @brief This file contains all the CryptoCell AES external DMA APIs, their
+ enums and definitions.
+ */
+
+
+#ifndef _MBEDTLS_AES_EXT_DMA_H
+#define _MBEDTLS_AES_EXT_DMA_H
+
+#include "cc_aes_defs_proj.h"
+#include "cc_pal_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+  @brief This function initializes the external DMA Control. It configures the
+  AES mode, the direction (encryption or decryption), and the data size.
+
+  @return \c CC_OK on success.
+  @return A non-zero value from cc_aes_error.h on failure.
+ */
+int mbedtls_aes_ext_dma_init(
+    /*! [in] AES key size. Valid values are: 128 bits, 192 bits, or 256 bits. */
+    unsigned int keybits,
+    /*! [in] 0: Encrypt. 1: Decrypt. */
+    int   encryptDecryptFlag,
+    /*! [in] AES mode. Supported modes are: ECB, CBC, CTR, CBC_MAC, CMAC,
+    or OFB. */
+    CCAesOperationMode_t operationMode
+    );
+
+
+/*!
+  @brief This function configures the key.
+
+  @return \c CC_OK on success.
+  @return A non-zero value from cc_aes_error.h on failure.
+ */
+int  mbedtls_aes_ext_dma_set_key(
+    /*! [in] AES mode. Supported modes are: ECB, CBC, CTR, CBC_MAC, CMAC or
+    OFB. */
+    CCAesOperationMode_t operationMode,
+    /*! [in] The AES key buffer. */
+    const unsigned char *key,
+    /*! [in] The size of the AES Key. Valid values are: 128 bits, 192 bits, or
+    256 bits. */
+    unsigned int keybits
+    );
+
+
+/*!
+  @brief This function configures the IV.
+
+  @return \c CC_OK on success.
+  @return A non-zero value from cc_aes_error.h on failure.
+ */
+int mbedtls_aes_ext_dma_set_iv(
+    /*! [in] AES mode. Supported modes are: ECB, CBC, CTR, CBC_MAC, CMAC or
+    OFB. */
+    CCAesOperationMode_t operationMode,
+    /*! [in] The AES IV buffer. */
+    unsigned char       *iv,
+    /*! [in] The size of the IV. Must be 16 bytes. */
+    unsigned int         iv_size
+    );
+
+/*!
+  @brief This function configures data size which will be written to external
+  DMA interface.
+
+  @return \c CC_OK on success.
+  @return A non-zero value from cc_aes_error.h on failure.
+ */
+int mbedtls_aes_ext_dma_set_data_size(
+    /*! [in] Size of input data in bytes. */
+    uint32_t                dataSize,
+    /*! [in] The AES mode. Supported modes are: ECB, CBC, CTR, CBC_MAC, CMAC
+    or OFB. */
+    CCAesOperationMode_t    operationMode
+);
+
+
+/*!
+  @brief This function returns the IV after an AES CMAC or a CBCMAC operation.
+
+  @return \c CC_OK on success.
+  @return A non-zero value from cc_aes_error.h on failure.
+ */
+int mbedtls_aes_ext_dma_finish(
+    /*! [in] The AES mode. Supported modes are: ECB, CBC, CTR, CBC_MAC, CMAC or OFB. */
+    CCAesOperationMode_t operationMode,
+    /*! [out] The AES IV buffer. */
+    unsigned char       *iv,
+    /*! [in] The size of the IV. Must be 16 bytes. */
+    unsigned int         iv_size
+    );
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+*/
+
+#endif /* #ifndef MBEDTLS_AES_EXT_DMA_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_aes_key_wrap.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_aes_key_wrap.h
new file mode 100644
index 0000000..9b9ce42
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_aes_key_wrap.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains all of the CryptoCell key-wrapping APIs, their enums and definitions.
+
+ The APIs support AES key wrapping as defined in <em>NIST SP 800-38F: Recommendation for
+ Block Cipher Modes of Operation: Methods for Key Wrapping</em>.
+ */
+
+/*!
+ @defgroup cc_aes_keywrap CryptoCell AES key-wrapping APIs
+ @brief Contains CryptoCell key-wrapping APIs.
+
+ See mbedtls_cc_aes_key_wrap.h.
+ @{
+ @ingroup cc_aes
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_AES_KEY_WRAP_H
+#define _MBEDTLS_CC_AES_KEY_WRAP_H
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/************************ Defines ******************************/
+/*! The size of the AES key-wrapping semiblock in Bytes. */
+#define CC_AES_KEYWRAP_SEMIBLOCK_SIZE_BYTES     (CC_AES_BLOCK_SIZE_IN_BYTES >> 1)
+/*! The size of the AES key-wrapping semiblock in words. */
+#define CC_AES_KEYWRAP_SEMIBLOCK_SIZE_WORDS     (CC_AES_KEYWRAP_SEMIBLOCK_SIZE_BYTES >> 2)
+/*! The AES key-wrapping semiblock to Bytes shift. */
+#define CC_AES_KEYWRAP_SEMIBLOCK_TO_BYTES_SHFT      3
+/*! AES key-wrapping with padding (KWP) maximum Bytes of padding. */
+#define CC_AES_KEYWRAP_MAX_PAD_LEN                  7
+
+/**********************************/
+/** ICVs - Integrity Check Value **/
+/**********************************/
+
+/*! The 64-bit default ICV for KW mode. */
+#define CC_AES_KEYWRAP_ICV1             {0xA6A6A6A6, 0xA6A6A6A6}
+/*! The 32-bit default ICV for KWP mode. */
+#define CC_AES_KEYWRAP_ICV2             {0xA65959A6, 0x00000000}
+
+/************************ Typedefs  ****************************/
+/*! Supported modes of the AES key-wrapping operation: KW and KWP, as defined in
+ <em>NIST SP 800-38F: Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping</em>. */
+typedef enum keyWrapMode {
+    CC_AES_KEYWRAP_KW_MODE      = 0, /*!< KW mode. */
+    CC_AES_KEYWRAP_KWP_MODE     = 1, /*!< KWP mode. */
+    CC_AES_KEYWRAP_NUM_OF_MODES = 2, /*!< Allowed number of AES key-wrapping modes. */
+    CC_AES_KEYWRAP_RESERVE32B   = INT32_MAX /*!< Reserved. */
+}mbedtls_keywrap_mode_t;
+
+
+/******************************************* Public Functions *****************************************/
+
+/******************************************************************************************************/
+/********                       AES key-wrapping FUNCTION                                     *********/
+/******************************************************************************************************/
+
+/*!
+ @brief This is the AES wrapping or encryption function.
+
+ AES key-wrapping specifies a deterministic authenticated-encryption mode of operation of the
+ AES, according to <em>NIST SP 800-38F: Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping</em>.
+ Its purpose is to protect cryptographic keys.
+ It uses units of 8 Bytes called semiblocks. The minimal number of input semiblocks is:
+ <ul><li>For KW mode: 2 semiblocks.</li>
+ <li>For KWP mode: 1 semiblock.</li></ul>
+
+ The maximal size of the output in Bytes is 64KB. This is a system restriction.
+ The input to key-wrapping includes the following elements:
+ <ul><li>Payload - text data that is both authenticated and encrypted.</li>
+ <li>Key - The encryption key for the AES operation.</li></ul>
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_aes_key_wrap_error.h.
+ */
+CCError_t mbedtls_aes_key_wrap(
+            mbedtls_keywrap_mode_t keyWrapFlag,      /*!< [in] The key-wrapping mode: KW or KWP. */
+            uint8_t*      keyBuf,                    /*!< [in] A pointer to AES key-wrapping key. */
+            size_t        keySize,                   /*!< [in] The size of the key in Bytes. Valid values are:
+                                                          16 Bytes, 24 Bytes, or 32 Bytes. */
+            uint8_t*      pPlainText,                /*!< [in] A pointer to the plain-text data for encryption. The buffer must be contiguous. */
+            size_t        plainTextSize,             /*!< [in] The size of the plain-text data in Bytes. */
+            uint8_t*      pCipherText,               /*!< [out] A pointer to the cipher-text output data. The buffer must be contiguous. */
+            size_t*       pCipherTextSize            /*!< [in/out] Input: A pointer to the size of the cipher-text output data buffer.
+                                                          Output: The actual size of the cipher-text output data in Bytes. */
+);
+
+/*!
+ @brief This is the AES unwrapping or decryption function.
+
+ AES key-wrapping specifies a deterministic authenticated-encryption mode of operation of the
+ AES, according to <em>NIST SP 800-38F: Recommendation for Block Cipher Modes of Operation: Methods for Key Wrapping</em>.
+ Its purpose is to protect cryptographic keys.
+ It uses units of 8 Bytes called semiblocks. The minimal number of input semiblocks is:
+ <ul><li>For KW mode: 2 semiblocks.</li>
+ <li>For KWP mode: 1 semiblock.</li></ul>
+ The maximal size of the output in bytes is 64KB. This is a system restriction.
+ Input to key-wrapping includes the following elements:
+ <ul><li>Payload - text data that is both authenticated and encrypted.</li>
+ <li>Key - The encryption key for the AES operation.</li></ul>
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_aes_key_wrap_error.h.
+ */
+CCError_t mbedtls_aes_key_unwrap(
+              mbedtls_keywrap_mode_t keyWrapFlag,    /*!< [in] The enumerator defining the key-wrapping mode: KW or KWP. */
+              uint8_t*      keyBuf,                  /*!< [in] A pointer to AES key-wrapping key. */
+              size_t        keySize,                 /*!< [in] The size of the key in Bytes. Valid values are:
+                                                          16 Bytes, 24 Bytes, or 32 Bytes.              */
+              uint8_t*      pCipherText,             /*!< [in] A pointer to the cipher-text data for decryption. The buffer must be contiguous. */
+              size_t        cipherTextSize,          /*!< [in] The size of the cipher-text data in Bytes. */
+              uint8_t*      pPlainText,              /*!< [out] A pointer to the plain-text output data. The buffer must be contiguous. */
+              size_t*       pPlainTextSize           /*!< [in/out] Input: A pointer to the size of the plain-text output data buffer.
+                                                           Output: The actual size of the plain-text output data in Bytes. */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*#ifndef _MBEDTLS_CC_AES_KEY_WRAP_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_aes_key_wrap_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_aes_key_wrap_error.h
new file mode 100644
index 0000000..db48f86
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_aes_key_wrap_error.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file mbedtls_cc_aes_key_wrap_error.h
+ @brief This file contains the error definitions of the CryptoCell AES key-wrapping APIs.
+ */
+
+/*!
+ @defgroup cc_aes_keywrap_error Specific errors of the CryptoCell AES key-wrapping APIs
+ @brief Contains the CryptoCell AES key-wrapping-API error definitions.
+
+ See mbedtls_cc_aes_key_wrap_error.h.
+ @{
+ @ingroup cc_aes_keywrap
+ @}
+ */
+
+#ifndef _CC_AES_KEYWRAP_ERROR_H
+#define _CC_AES_KEYWRAP_ERROR_H
+
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* CryptoCell AES key-wrapping module errors. #CC_AES_KEYWRAP_MODULE_ERROR_BASE = 0x00F02800 */
+
+/*! Invalid data-in text pointer. */
+#define CC_AES_KEYWRAP_DATA_IN_POINTER_INVALID_ERROR        (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x00UL)
+/*! Invalid data-out text pointer. */
+#define CC_AES_KEYWRAP_DATA_OUT_POINTER_INVALID_ERROR       (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x01UL)
+/*! Invalid key pointer. */
+#define CC_AES_KEYWRAP_INVALID_KEY_POINTER_ERROR            (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x02UL)
+/*! Invalid key size. */
+#define CC_AES_KEYWRAP_ILLEGAL_KEY_SIZE_ERROR           (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x03UL)
+/*! Illegal semiblocks number. */
+#define CC_AES_KEYWRAP_SEMIBLOCKS_NUM_ILLEGAL           (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x04UL)
+/*! Invalid parameter pointer. */
+#define CC_AES_KEYWRAP_ILLEGAL_PARAMETER_PTR_ERROR              (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x05UL)
+/*! Invalid encryption mode. */
+#define CC_AES_KEYWRAP_INVALID_ENCRYPT_MODE_ERROR       (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x06UL)
+/*! Illegal data-in size. */
+#define CC_AES_KEYWRAP_DATA_IN_SIZE_ILLEGAL         (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x07UL)
+/*! Illegal data-out size. */
+#define CC_AES_KEYWRAP_DATA_OUT_SIZE_ILLEGAL            (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x08UL)
+/*! Illegal key-wrapping mode. */
+#define CC_AES_KEYWRAP_INVALID_KEYWRAP_MODE_ERROR       (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x09UL)
+/*! Key Unwrap comparison failure. */
+#define CC_AES_KEYWRAP_UNWRAP_COMPARISON_ERROR          (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0x0AUL)
+
+/*! Not supported. */
+#define CC_AES_KEYWRAP_IS_NOT_SUPPORTED             (CC_AES_KEYWRAP_MODULE_ERROR_BASE + 0xFFUL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CC_AES_KEYWRAP_ERROR_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ccm_star.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ccm_star.h
new file mode 100644
index 0000000..59642fb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ccm_star.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_aesccm_star
+ @{
+ */
+
+/*!
+ @file
+
+ @brief This file contains the CryptoCell AES-CCM star APIs, their enums and
+ definitions.
+
+ This API supports AES-CCM*, as defined in <em>IEEE 802.15.4: IEEE Standard
+ for Local and metropolitan area networks— Part 15.4: Low-Rate Wireless
+ Personal Area Networks (LR-WPANs)</em>, with the instantiations defined in
+ section B.3.2, and the nonce defined in section 7.3.2.
+ */
+
+
+#ifndef _MBEDTLS_AES_CCM_STAR_H
+#define _MBEDTLS_AES_CCM_STAR_H
+
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+
+#include "mbedtls/ccm.h"
+#include "mbedtls_ccm_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Enums ********************************/
+
+/************************ Structs  ******************************/
+
+/************************ context Structs  ******************************/
+
+/*!
+ @brief     This function receives the MAC source address, the frame counter,
+            and the MAC size, and returns the required nonce for AES-CCM*, as
+            defined in <em>IEEE 802.15.4: IEEE Standard for Local and
+            metropolitan area networks— Part 15.4: Low-Rate Wireless Personal
+            Area Networks (LR-WPANs)</em>.
+
+ @note      This API should be called before mbedtls_ccm_star_encrypt_and_tag()
+            or mbedtls_ccm_star_auth_decrypt(). The generated nonce should
+            be provided to these functions. \par
+
+ @return              \c zero on success.
+ @return              A non-zero value on failure, as defined in ccm.h.
+ */
+int mbedtls_ccm_star_nonce_generate(
+        /*! The MAC address in EUI-64 format. */
+        unsigned char * src_addr,
+        /*! The MAC frame counter. */
+        uint32_t frame_counter,
+        /*! The size of the AES-CCM* MAC tag in bytes:
+            4, 6, 8, 10, 12, 14 or 16. */
+        uint8_t size_of_t,
+        /*! The required nonce for AES-CCM*. */
+        unsigned char * nonce_buf);
+
+
+ #ifdef __cplusplus
+}
+#endif
+
+#endif /* _MBEDTLS_AES_CCM_STAR_H */
+
+/*!
+@}
+ */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha.h
new file mode 100644
index 0000000..9562bfb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains all of the CryptoCell ChaCha APIs, their enums and definitions.
+ */
+
+/*!
+ @defgroup cc_chacha CryptoCell ChaCha APIs
+ @brief Contains all CryptoCell ChaCha APIs. See mbedtls_cc_chacha.h.
+
+ The ChaCha family of stream ciphers is a variant of the Salsa20 family of stream ciphers.
+ For more information, see <em>ChaCha, a variant of Salsa20</em>.
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_CHACHA_H
+#define _MBEDTLS_CC_CHACHA_H
+
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/*! The size of the ChaCha user-context in words. */
+#define CC_CHACHA_USER_CTX_SIZE_IN_WORDS 17
+
+/*! The size of the ChaCha block in words. */
+#define CC_CHACHA_BLOCK_SIZE_IN_WORDS 16
+/*! The size of the ChaCha block in Bytes. */
+#define CC_CHACHA_BLOCK_SIZE_IN_BYTES  (CC_CHACHA_BLOCK_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/*! The maximal size of the nonce buffer in words. */
+#define CC_CHACHA_NONCE_MAX_SIZE_IN_WORDS   3
+/*! The maximal size of the nonce buffer in Bytes. */
+#define CC_CHACHA_NONCE_MAX_SIZE_IN_BYTES  (CC_CHACHA_NONCE_MAX_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/*! The maximal size of the ChaCha key in words. */
+#define CC_CHACHA_KEY_MAX_SIZE_IN_WORDS 8
+/*! The maximal size of the ChaCha key in Bytes. */
+#define CC_CHACHA_KEY_MAX_SIZE_IN_BYTES (CC_CHACHA_KEY_MAX_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/************************ Enums ********************************/
+
+/*! The ChaCha operation:<ul><li>Encrypt</li><li>Decrypt</li></ul>. */
+typedef enum {
+    CC_CHACHA_Decrypt = 0, /*!< A ChaCha decrypt operation. */
+    CC_CHACHA_Encrypt = 1, /*!< A ChaCha encrypt operation. */
+    CC_CHACHA_EncryptNumOfOptions, /*!< The maximal number of encrypt or decrypt operations for the ChaCha engine. */
+    CC_CHACHA_EncryptModeLast = 0x7FFFFFFF, /*!< Reserved. */
+
+}mbedtls_chacha_encrypt_mode_t;
+
+/*! The allowed nonce-size values of the ChaCha engine in bits. */
+typedef enum {
+        CC_CHACHA_Nonce64BitSize = 0, /*!< A 64-bit nonce size. */
+        CC_CHACHA_Nonce96BitSize = 1, /*!< A 96-bit nonce size. */
+        CC_CHACHA_NonceSizeNumOfOptions, /*!< The maximal number of nonce sizes for the ChaCha engine. */
+        CC_CHACHA_NonceSizeLast = 0x7FFFFFFF, /*!< Reserved. */
+}mbedtls_chacha_nonce_size_t;
+
+/************************ Typedefs  ****************************/
+
+/*! The definition of the 12-Byte array of the nonce buffer. */
+typedef uint8_t mbedtls_chacha_nonce[CC_CHACHA_NONCE_MAX_SIZE_IN_BYTES];
+
+/*! The definition of the key buffer of the ChaCha engine. */
+typedef uint8_t mbedtls_chacha_key[CC_CHACHA_KEY_MAX_SIZE_IN_BYTES];
+
+
+/************************ context Structs  ******************************/
+
+/*!
+  @brief The context prototype of the user.
+
+  The argument type that is passed by the user to the ChaCha API.
+
+  The context saves the state of the operation. It must be saved by the user
+  until the end of the API flow, for example, until ::mbedtls_chacha_free is called.
+*/
+typedef struct mbedtls_chacha_user_context {
+    /* The allocated buffer must be double the size of the actual context
+     * + 1 word for offset management */
+    uint32_t buff[CC_CHACHA_USER_CTX_SIZE_IN_WORDS]; /*!< The context buffer for internal use */
+}mbedtls_chacha_user_context;
+
+/************************ Public Variables **********************/
+
+
+/************************ Public Functions **********************/
+
+/****************************************************************************************************/
+
+/*!
+  @brief This function initializes the context for ChaCha-engine operations.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure as defined in mbedtls_cc_chacha_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_chacha_init(
+        mbedtls_chacha_user_context    *pContextID,        /*!< [in] A pointer to the ChaCha context buffer that is allocated by the user and used for the ChaCha operation. */
+        mbedtls_chacha_nonce          pNonce,           /*!< [in] A buffer containing a nonce. */
+        mbedtls_chacha_nonce_size_t      nonceSize,         /*!< [in]  An enumerator defining the nonce size. Valid values are: 64bits or 96bits. */
+        mbedtls_chacha_key            pKey,               /*!< [in] A pointer to the key buffer of the user. */
+        uint32_t                     initialCounter,     /*!< [in] An initial counter. */
+        mbedtls_chacha_encrypt_mode_t    EncryptDecryptFlag  /*!< [in] A flag specifying whether the ChaCha engine should perform an Encrypt operation or a Decrypt operation. */
+);
+
+
+/*!
+  @brief This function processes aligned blocks of the ChaCha engine.
+
+  The data-in size should be a multiple of the ChaCha block size.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure as defined in mbedtls_cc_chacha_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_chacha_block(
+        mbedtls_chacha_user_context    *pContextID,     /*!< [in] A pointer to the context buffer. */
+        uint8_t                     *pDataIn,           /*!< [in] A pointer to the buffer of the input data to the ChaCha engine.
+                                                                  The pointer does not need to be aligned. Must not be null. */
+        size_t                      dataInSize,         /*!< [in] The size of the input data.
+                                                                  Must be a multiple of ::CC_CHACHA_BLOCK_SIZE_IN_BYTES Bytes, and must not be zero. */
+        uint8_t                     *pDataOut           /*!< [out] A pointer to the buffer of the output data from the ChaCha engine.
+                                                                   The pointer does not need to be aligned. Must not be null. */
+        );
+
+
+/*!
+  @brief This function processes the remaining ChaCha data.
+
+  The data-in size should be smaller than the ChaCha block size.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure as defined in mbedtls_cc_chacha_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_chacha_finish(
+        mbedtls_chacha_user_context    *pContextID,     /*!< [in]  A pointer to the context buffer. */
+        uint8_t                     *pDataIn,           /*!< [in]  A pointer to the buffer of the input data to the ChaCha engine.
+                                                                   The pointer does not need to be aligned. If dataInSize = 0,
+                                                                   an input buffer is not required. */
+        size_t                      dataInSize,         /*!< [in]  The size of the input data. Valid values are:Zero or
+                                                                   values that are not multiples of ::CC_CHACHA_BLOCK_SIZE_IN_BYTES. */
+        uint8_t                     *pDataOut           /*!< [out] A pointer to the buffer of the output data from the ChaCha engine.
+                                                                   The pointer does not need to be aligned. If dataInSize = 0,
+                                                                   an output buffer is not required. */
+);
+
+
+/*!
+  @brief This function frees the context used for ChaCha operations.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure as defined in mbedtls_cc_chacha_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_chacha_free(
+        mbedtls_chacha_user_context *pContextID    /*!< [in] A pointer to the context buffer. */
+);
+
+
+/*!
+  @brief This function performs the ChaCha operation in one integrated process.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure as defined in mbedtls_cc_chacha_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_chacha(
+        mbedtls_chacha_nonce           pNonce,              /*!< [in]  A buffer containing a nonce. */
+        mbedtls_chacha_nonce_size_t    nonceSize,           /*!< [in]  An enumerator defining the size of the nonce.
+                                                                       Valid values are: 64bits or 96bits. */
+        mbedtls_chacha_key             pKey,                /*!< [in]  A pointer to the key buffer of the user. */
+        uint32_t                       initialCounter,      /*!< [in]  An initial counter. */
+        mbedtls_chacha_encrypt_mode_t  encryptDecryptFlag,  /*!< [in]  A flag specifying which operation the ChaCha engine should
+                                                                       perform: encrypt or decrypt. */
+        uint8_t                        *pDataIn,            /*!< [in]  A pointer to the buffer of the input-data to the ChaCha engine.
+                                                                       The pointer does not need to be aligned. Must not be null. */
+        size_t                         dataInSize,          /*!< [in]  The size of the input data. Must not be zero. */
+        uint8_t                        *pDataOut            /*!< [out] A pointer to the buffer of the output data from the ChaCha.
+                                                                       The pointer does not need to be aligned. Must not be null. */
+);
+
+
+/***********************************************************************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _MBEDTLS_CC_CHACHA_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_error.h
new file mode 100644
index 0000000..3b8e303
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_error.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains the error definitions of the CryptoCell ChaCha APIs.
+ */
+
+/*!
+ @defgroup cc_chacha_error Specific errors of the CryptoCell ChaCha APIs
+ @brief Contains the CryptoCell ChaCha-API error definitions. See mbedtls_cc_chacha_error.h.
+
+ @{
+ @ingroup cc_chacha
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_CHACHA_ERROR_H
+#define _MBEDTLS_CC_CHACHA_ERROR_H
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+
+
+/************************ Defines ******************************/
+
+/* The base address of errors for the ChaCha module - 0x00F02200. */
+/*! Illegal Nonce. */
+#define CC_CHACHA_INVALID_NONCE_ERROR                           (CC_CHACHA_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal key size. */
+#define CC_CHACHA_ILLEGAL_KEY_SIZE_ERROR                    (CC_CHACHA_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal key pointer. */
+#define CC_CHACHA_INVALID_KEY_POINTER_ERROR                 (CC_CHACHA_MODULE_ERROR_BASE + 0x03UL)
+/*! Illegal operation mode. */
+#define CC_CHACHA_INVALID_ENCRYPT_MODE_ERROR                (CC_CHACHA_MODULE_ERROR_BASE + 0x04UL)
+/*! Illegal data-in pointer. */
+#define CC_CHACHA_DATA_IN_POINTER_INVALID_ERROR             (CC_CHACHA_MODULE_ERROR_BASE + 0x05UL)
+/*! Illegal data-out pointer. */
+#define CC_CHACHA_DATA_OUT_POINTER_INVALID_ERROR            (CC_CHACHA_MODULE_ERROR_BASE + 0x06UL)
+/*! Illegal user context. */
+#define CC_CHACHA_INVALID_USER_CONTEXT_POINTER_ERROR            (CC_CHACHA_MODULE_ERROR_BASE + 0x07UL)
+/*! Illegal user context size. */
+#define CC_CHACHA_CTX_SIZES_ERROR                               (CC_CHACHA_MODULE_ERROR_BASE + 0x08UL)
+/*! Illegal nonce pointer. */
+#define CC_CHACHA_INVALID_NONCE_PTR_ERROR                       (CC_CHACHA_MODULE_ERROR_BASE + 0x09UL)
+/*! Illegal data-in size. */
+#define CC_CHACHA_DATA_IN_SIZE_ILLEGAL                          (CC_CHACHA_MODULE_ERROR_BASE + 0x0AUL)
+/*! General error. */
+#define CC_CHACHA_GENERAL_ERROR                         (CC_CHACHA_MODULE_ERROR_BASE + 0x0BUL)
+/*! ChaCha is not supported. */
+#define CC_CHACHA_IS_NOT_SUPPORTED                          (CC_CHACHA_MODULE_ERROR_BASE + 0xFFUL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif//_MBEDTLS_CC_CHACHA_ERROR_H
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_poly.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_poly.h
new file mode 100644
index 0000000..7e39feb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_poly.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains all of the CryptoCell ChaCha-POLY APIs, their enums and definitions.
+ */
+
+/*!
+ @defgroup cc_chacha_poly CryptoCell ChaCha-POLY APIs
+ @brief Contains CryptoCell ChaCha-POLY APIs. See mbedtls_cc_chacha_poly.h.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_CHACHA_POLY_H
+#define _MBEDTLS_CC_CHACHA_POLY_H
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+#include "mbedtls_cc_chacha.h"
+#include "mbedtls_cc_poly.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*!
+  @brief This function performs the ChaCha-POLY encryption and authentication operation.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure as defined in mbedtls_cc_chacha_poly_error.h.
+*/
+CIMPORT_C CCError_t  mbedtls_chacha_poly(
+        mbedtls_chacha_nonce             pNonce,             /*!< [in] A pointer to a buffer containing the nonce value. */
+        mbedtls_chacha_key               pKey,               /*!< [in] A pointer to the key buffer of the user. */
+        mbedtls_chacha_encrypt_mode_t    encryptDecryptFlag, /*!< [in] A flag specifying which operation the ChaCha-POLY module should perform: encrypt or decrypt. */
+        uint8_t                          *pAddData,          /*!< [in] A pointer to the additional data input buffer to the POLY module.
+                                                                       This pointer does not need to be aligned. Must not be null. */
+        size_t                           addDataSize,        /*!< [in] The size of the input data. Must not be zero. */
+        uint8_t                          *pDataIn,           /*!< [in] A pointer to the input-data buffer to the ChaCha engine.
+                                                                       This pointer does not need to be aligned. Must not be null. */
+        size_t                           dataInSize,         /*!< [in] The size of the input data. Must not be zero. */
+        uint8_t                          *pDataOut,          /*!< [out] A pointer to the output-data buffer from the ChaCha engine.
+                                                                        This pointer does not need to be aligned. Must not be null. */
+        mbedtls_poly_mac                 macRes              /*!< [in/out] A pointer to the MAC result buffer.*/
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _MBEDTLS_CC_CHACHA_POLY_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_poly_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_poly_error.h
new file mode 100644
index 0000000..d174de2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_chacha_poly_error.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains the errors definitions of the CryptoCell ChaCha-POLY APIs.
+ */
+
+/*!
+ @defgroup cc_chacha_poly_error Specific errors of the CryptoCell ChaCha-POLY APIs
+ @brief Contains the CryptoCell ChaCha-POLY-API errors definitions. See mbedtls_cc_chacha_poly_error.h.
+ @{
+ @ingroup cc_chacha_poly
+ @}
+ */
+
+
+#ifndef _MBEDTLS_CC_CHACHA_POLY_ERROR_H
+#define _MBEDTLS_CC_CHACHA_POLY_ERROR_H
+
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* The base address of errors for the ChaCha-POLY module - 0x00F02400. */
+/*! Invalid additional data. */
+#define CC_CHACHA_POLY_ADATA_INVALID_ERROR                      (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x01UL)
+/*! Invalid input data. */
+#define CC_CHACHA_POLY_DATA_INVALID_ERROR                   (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal encryption mode. */
+#define CC_CHACHA_POLY_ENC_MODE_INVALID_ERROR               (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x03UL)
+/*! Illegal data size. */
+#define CC_CHACHA_POLY_DATA_SIZE_INVALID_ERROR              (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x04UL)
+/*! Key-generation error. */
+#define CC_CHACHA_POLY_GEN_KEY_ERROR                    (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x05UL)
+/*! ChaCha key-generation error. */
+#define CC_CHACHA_POLY_ENCRYPTION_ERROR                 (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x06UL)
+/*! Authentication error. */
+#define CC_CHACHA_POLY_AUTH_ERROR                   (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x07UL)
+/*! MAC comparison error. */
+#define CC_CHACHA_POLY_MAC_ERROR                                (CC_CHACHA_POLY_MODULE_ERROR_BASE + 0x08UL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_MBEDTLS_CC_CHACHA_POLY_ERROR_H
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ec_mont_edw_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ec_mont_edw_error.h
new file mode 100644
index 0000000..bc86295
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ec_mont_edw_error.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _MBEDTLS_CC_EC_MONT_EDW_ERROR_H
+#define _MBEDTLS_CC_EC_MONT_EDW_ERROR_H
+
+
+/*!
+@file
+@brief This file contains the definitions of the CryptoCell ECC-25519 errors.
+@defgroup cc_ecmontedw_error CryptoCell ECC-25519 errors
+@{
+@ingroup cryptocell_api
+*/
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/**********************************************************************************************************
+ * CryptoCell ECC-25519 MODULE ERRORS    base address - 0x00F02100                *
+ **********************************************************************************************************/
+/*! Illegal input pointer */
+#define CC_EC_EDW_INVALID_INPUT_POINTER_ERROR                 (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x00UL)
+/*! Illegal input size */
+#define CC_EC_EDW_INVALID_INPUT_SIZE_ERROR                (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal scalar size */
+#define CC_EC_EDW_INVALID_SCALAR_SIZE_ERROR               (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal scalar data */
+#define CC_EC_EDW_INVALID_SCALAR_DATA_ERROR               (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x03UL)
+/*! Invalid RND context pointer */
+#define CC_EC_EDW_RND_CONTEXT_PTR_INVALID_ERROR              (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x04UL)
+/*! Invalid RND generate vector functions pointer */
+#define CC_EC_EDW_RND_GEN_VECTOR_FUNC_ERROR               (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x05UL)
+/*! Signing or verification operation failed */
+#define CC_EC_EDW_SIGN_VERIFY_FAILED_ERROR                (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x20UL)
+/*! Illegal input pointer */
+#define CC_EC_MONT_INVALID_INPUT_POINTER_ERROR              (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x30UL)
+/*! Illegal input size */
+#define CC_EC_MONT_INVALID_INPUT_SIZE_ERROR                 (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x31UL)
+/*! Illegal domain id */
+#define CC_EC_MONT_INVALID_DOMAIN_ID_ERROR                  (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x32UL)
+/*! Internal PKI error */
+#define CC_ECEDW_INTERNAL_ERROR                             (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x33UL)
+/*! Internal PKI error */
+#define CC_ECMONT_INTERNAL_ERROR                            (CC_EC_MONT_EDW_MODULE_ERROR_BASE + 0x34UL)
+
+
+/************************************************************************************************************
+ *    NOT SUPPORTED MODULES ERROR IDs                                                                       *
+ ************************************************************************************************************/
+/*! EC montgomery is not supported */
+#define CC_EC_MONT_IS_NOT_SUPPORTED                         (CC_ECPKI_MODULE_ERROR_BASE + 0xFEUL)
+/*! EC edwards is not supported */
+#define CC_EC_EDW_IS_NOT_SUPPORTED                          (CC_ECPKI_MODULE_ERROR_BASE + 0xFFUL)
+
+
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+*/
+#endif//_MBEDTLS_CC_EC_MONT_EDW_ERROR_H
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecdh_edwards.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecdh_edwards.h
new file mode 100644
index 0000000..c183d1f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecdh_edwards.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup ecdh_edwards
+ @}
+ */
+
+/*!
+ @file
+
+ @brief This file contains the CryptoCell ECDH Edwards curve APIs.
+ */
+
+#ifndef ECDH_EDWARDS_H
+#define ECDH_EDWARDS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "mbedtls/ecp.h"
+
+/*************************** Defines *****************************************/
+
+/*************************** Typedefs  ***************************************/
+
+/*************************** Enums *******************************************/
+
+/*************************** Structs  ****************************************/
+
+/*************************** context Structs  ********************************/
+
+/*!
+   @brief   This function generates a public key and a TLS ServerKeyExchange
+   payload.
+
+   This is the first function used by a TLS server for ECDHE ciphersuites.
+
+   @note    This function can be used only for curve 25519.
+
+   @note    This function assumes that the ECP group (\c grp) of the
+            \p ctx context has already been properly set,
+            for example, using mbedtls_ecp_group_load().
+
+   @see     ecp.h
+
+   @return  \c 0 on success.
+   @return  An \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ */
+
+int mbedtls_ecdh_make_params_edwards(
+        /*! The ECDH context. */
+        mbedtls_ecdh_context *ctx,
+        /*! The number of characters written. */
+        size_t *olen,
+        /*! The destination buffer. */
+        unsigned char *buf,
+        /*! The length of the destination buffer. */
+        size_t blen,
+        /*! The RNG function. */
+        int (*f_rng)(void *, unsigned char *, size_t),
+        /*! The RNG context. */
+        void *p_rng
+                      );
+
+/*!
+   @brief   This function parses and processes a TLS ServerKeyExhange
+            payload.
+
+            This is the first function used by a TLS client for ECDHE ciphersuites.
+
+   @note    This function can be used only for curve 25519.
+
+   @see     ecp.h
+
+   @return  \c 0 on success.
+   @return  An \c MBEDTLS_ERR_ECP_XXX error code on failure.
+ */
+int mbedtls_ecdh_read_params_edwards(
+        /*! The ECDH context. */
+        mbedtls_ecdh_context *ctx,
+        /*! The pointer to the start of the input buffer. */
+        const unsigned char **buf,
+        /*! The address for one byte past the end of the buffer. */
+        const unsigned char *end
+        );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+@}
+*/
+#endif  /* MBEDTLS_ECDH_EDWARDS */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecdsa_edwards.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecdsa_edwards.h
new file mode 100644
index 0000000..bb118ca
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecdsa_edwards.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup eddsa
+ @{
+ */
+
+/*!
+ @file
+
+ @brief This file contains the CryptoCell EDDSA Edwards curve APIs.
+
+ This API supports EDDSA Edwards for generating, signing and verifying keys.
+ This is implemented based on <em>Ed25519: High-speed high-security
+ signatures</em>.
+ */
+
+#ifndef _MBEDTLS_ECDSA_EDWARDS_H
+#define _MBEDTLS_ECDSA_EDWARDS_H
+
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*************************** Defines *****************************************/
+
+/*************************** Typedefs  ***************************************/
+
+/*************************** Enums *******************************************/
+
+/*************************** Structs  ****************************************/
+
+/*************************** context Structs  ********************************/
+
+/*!
+ @brief This function generates an EDDSA keypair on the Edwards 25519 curve.
+
+ @return    \c 0 on success.
+ @return    An \c MBEDTLS_ERR_ECP_XXX code on failure.
+ */
+int mbedtls_ecdsa_genkey_edwards(
+        /*! The EDDSA context to store the keypair in. */
+        mbedtls_ecdsa_context *ctx,
+        /*! The elliptic curve to use. Currently only 25519 curve is
+        supported. */
+        mbedtls_ecp_group_id gid,
+        /*! The RNG function. */
+        int (*f_rng)(void *, unsigned char *, size_t),
+        /*! The RNG context. */
+        void *p_rng
+        );
+
+/*!
+   @brief           This function computes the EDDSA signature of a
+                    previously-hashed message.
+
+   @note            If the bitlength of the message hash is larger than the
+                    bitlength of the group order, then the hash is truncated
+                    as defined in <em>Standards for Efficient Cryptography Group
+                    (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+                    4.1.3, step 5.
+
+   @return          \c 0 on success.
+   @return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX error code
+                    on failure.
+ */
+int mbedtls_ecdsa_sign_edwards(
+            /*! The ECP group. */
+            mbedtls_ecp_group *grp,
+            /*! The first output integer. */
+            mbedtls_mpi *r,
+            /*! The second output integer. */
+            mbedtls_mpi *s,
+            /*! The private signing key. */
+            const mbedtls_mpi *d,
+            /*! The message hash. */
+            const unsigned char *buf,
+            /*! The length of \p buf. */
+            size_t blen
+            );
+
+
+/*!
+   @brief           This function verifies the EDDSA signature of a
+                    previously-hashed message.
+
+   @note            If the bitlength of the message hash is larger than the
+                    bitlength of the group order, then the hash is truncated as
+                    defined in <em>Standards for Efficient Cryptography Group
+                    (SECG): SEC1 Elliptic Curve Cryptography</em>, section
+                    4.1.4, step 3.
+
+   @return          \c 0 on success.
+   @return          \c MBEDTLS_ERR_ECP_BAD_INPUT_DATA if signature is invalid.
+   @return          An \c MBEDTLS_ERR_ECP_XXX or \c MBEDTLS_MPI_XXX
+                    error code on failure for any other reason.
+  */
+int mbedtls_ecdsa_verify_edwards(
+            /*! The ECP group. */
+            mbedtls_ecp_group *grp,
+            /*!The message hash . */
+            const unsigned char *buf,
+            /*! The length of \p buf. */
+            size_t blen,
+            /*! The public key to use for verification. */
+            const mbedtls_ecp_point *Q,
+            /*! The first integer of the signature. */
+            const mbedtls_mpi *r,
+            /*! The second integer of the signature. */
+            const mbedtls_mpi *s
+            );
+
+/**
+   @brief           This function imports an EC Edwards public key.
+
+   @return          \c 0 on success.
+   @return          \c MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+                    or \c MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE on failure.
+ */
+int mbedtls_ecdsa_public_key_read_edwards(
+            /*! [out] The public key to import. */
+            mbedtls_ecp_point *Q,
+            /*! [in] The buffer to read the public key from. */
+            unsigned char *buf,
+            /*! [in] The length of the buffer in bytes. */
+            size_t blen
+            );
+
+/**
+   @brief           This function exports an EC Edwards public key.
+
+   @return          \c 0 on success.
+   @return          \c MBEDTLS_ERR_ECP_BAD_INPUT_DATA
+                    or \c MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL on failure.
+ */
+int mbedtls_ecdsa_public_key_write_edwards(
+            /*! [in] The public key to export. */
+            const mbedtls_ecp_point *Q,
+            /*! [out] The length of the data written in bytes. */
+            size_t *olen,
+            /*! [out] The buffer to write the public key to. */
+            unsigned char *buf,
+            /*! [in] The length of the buffer in bytes. */
+            size_t blen
+            );
+
+
+ #ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /* _MBEDTLS_ECDSA_EDWARDS_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecies.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecies.h
new file mode 100644
index 0000000..e364309
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_ecies.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_ecies
+ @{
+*/
+
+/*!
+ @file mbedtls_cc_ecies.h
+
+ @brief This file contains the CryptoCell Elliptic Curve Integrated Encryption Scheme (ECIES) APIs.
+ */
+
+#ifndef _MBEDTLS_CC_ECIES_H
+#define _MBEDTLS_CC_ECIES_H
+
+
+#include "cc_ecpki_types.h"
+#include "cc_pal_types_plat.h"
+#include "cc_kdf.h"
+#include "mbedtls_cc_hkdf.h"
+#include "mbedtls/ecp.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*! The maximal length of the ECIES cipher in bytes. */
+#define MBEDTLS_ECIES_MAX_CIPHER_LEN_BYTES  ((2*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1) * sizeof(int))
+/*! The minimal length of the ECIES buffer in bytes. */
+#define MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES    (sizeof(CCEciesTempData_t))
+
+/*!
+  @brief A macro for creating and encrypting a secret key.
+
+  For a description of the parameters see ::mbedtls_ecies_kem_encrypt_full.
+ */
+#define  mbedtls_ecies_kem_encrypt(pGrp, pRecipPublKey, kdfDerivMode, kdfHashMode, \
+                   isSingleHashMode, pSecrKey, secrKeySize, \
+                   pCipherData, pCipherDataSize, pBuff, buffLen, \
+                   f_rng, p_rng) \
+     mbedtls_ecies_kem_encrypt_full((pGrp), (pRecipPublKey), (kdfDerivMode), (kdfHashMode), \
+                    (isSingleHashMode), NULL, NULL, (pSecrKey), (secrKeySize), \
+                    (pCipherData), (pCipherDataSize), (pBuff), (buffLen), \
+                    f_rng, p_rng)
+
+/*!
+  @brief This function creates and encrypts (encapsulates) the secret key of
+  required size, according to <em>ISO/IEC 18033-2:2006: Information technology
+  -- Security techniques -- Encryption algorithms -- Part 2: Asymmetric
+  ciphers</em>, ECIES-KEM Encryption.
+
+  To call this function in applications, the ::mbedtls_ecies_kem_encrypt macro
+  definition must be used. The function itself has the additional input of the
+  external ephemeral key pair, used only for testing purposes.
+
+  @note Use KDF2 function mode for compliance with <em>X9.63-2011: Public Key
+  Cryptography for the Financial Services Industry – Key Agreement and Key
+  Transport Using Elliptic Curve Cryptography</em>. \par
+
+  @note The term "sender" indicates an entity that creates and
+  encapsulates the secret key using this function. The term "recipient"
+  indicates another entity which receives and decrypts the secret key. \par
+
+  @note All public and private keys that are used must relate to the same EC
+  Domain. \par
+
+  @note The user must verify that the public key of the recipient is
+  on the elliptic curve before it is used in this function.
+
+  @return CCError_t \c 0 on success.
+ */
+CCError_t mbedtls_ecies_kem_encrypt_full(
+    /*! [in] The ECP group to use. */
+    mbedtls_ecp_group *pGrp,
+    /*! [in] A pointer to the public key of the recipient. */
+    mbedtls_ecp_point *pRecipUzPublKey,
+    /*! [in] The KDF function mode to use: KDF1 or KDF2. For more
+    information, see CCKdfDerivFuncMode_t() in cc_kdf.h. */
+    CCKdfDerivFuncMode_t kdfDerivMode,
+    /*! [in] The used hash function. */
+    mbedtls_hkdf_hashmode_t kdfHashMode,
+    /*! [in] The specific ECIES mode, according to <em>ISO/IEC 18033-2:2006:
+    Information technology -- Security techniques -- Encryption algorithms
+    -- Part 2: Asymmetric ciphers</em> - section 10.2: 0: Not-single hash,
+    or 1: Single hash. */
+    uint32_t isSingleHashMode,
+    /*! [in] A pointer to the ephemeral public key related to the private
+    key. Must be set to NULL if \p pExtEphUzPrivateKey = NULL. */
+    mbedtls_ecp_point *pExtEphUzPublicKey,
+    /*! [in] The pointer to the external ephemeral private key. This key
+    is used only for testing the function. In regular use, the pointer
+    should be set to NULL and then the random key-pair should be generated
+    internally. */
+    mbedtls_mpi *pExtEphUzPrivateKey,
+    /*! [in] A pointer to the buffer for the secret-key data to be
+    generated. */
+    uint8_t *pSecrKey,
+    /*! [in] The size of the secret-key data in bytes. */
+    size_t secrKeySize,
+    /*! [in] A pointer to the encrypted cipher text. */
+    uint8_t *pCipherData,
+    /*! [in/out] In: A pointer to the size of the buffer for CipherData
+    output, or Out: The size of the buffer for CipherData output in
+    bytes. */
+    size_t *pCipherDataSize,
+    /*! [in] A pointer to the temporary buffer. */
+    void *pBuff,
+    /*! [in] The size of the buffer pointed by \p pBuff. Must not be less
+    than #MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES. */
+    size_t buffLen,
+    /*! [in] The RNG function required for generating a key pair when
+    \p pExtEphUzPublicKey and \p pExtEphUzPrivateKey are NULL */
+    int (*f_rng)(void *, unsigned char *, size_t),
+    /*! [in] The RNG parameter. */
+    void *p_rng
+    );
+
+/*!
+  @brief This function decrypts the encapsulated secret key passed by the
+  sender, according to <em>ISO/IEC 18033-2:2006: Information technology --
+  Security techniques -- Encryption algorithms -- Part 2: Asymmetric
+  ciphers</em>, sec. 10.2.4 - ECIES-KEM Decryption.
+
+  @note The KDF2 function mode must be used for compliance with <em>X9.63-2011:
+  Public Key Cryptography for the Financial Services Industry – Key Agreement
+  and Key Transport Using Elliptic Curve Cryptograph</em>. \par
+
+  @note The term "sender" indicates an entity that creates and
+  encapsulates the secret key using this function. The term "recipient"
+  indicates another entity which receives and decrypts the secret key. \par
+
+  @note All public and private keys that are used must relate to the same EC
+  Domain. \par
+
+  @return CCError_t \c 0 on success.
+ */
+CCError_t mbedtls_ecies_kem_decrypt(
+    /*! [in] The ECP group to use. */
+    mbedtls_ecp_group *pGrp,
+    /*! [in] A pointer to the private key of the recipient. */
+    mbedtls_mpi *pRecipUzPrivKey,
+    /*! [in] The KDF function mode to use: KDF1 or KDF2. For more
+    information, see CCKdfDerivFuncMode_t() in cc_kdf.h. */
+    CCKdfDerivFuncMode_t kdfDerivMode,
+    /*! [in] The used hash function. */
+    mbedtls_hkdf_hashmode_t kdfHashMode,
+    /*! [in] The specific ECIES mode definition: 0,1, according to
+    <em>ISO/IEC 18033-2:2006: Information technology -- Security techniques
+    -- Encryption algorithms -- Part 2: Asymmetric ciphers</em> -
+    section 10.2. */
+    uint32_t isSingleHashMode,
+    /*! [in] A pointer to the received encrypted cipher data. */
+    uint8_t *pCipherData,
+    /*! [in] The size of the cipher data in bytes. */
+    size_t cipherDataSize,
+    /*! [in] A pointer to the buffer for the secret-key data to be
+    generated. */
+    uint8_t *pSecrKey,
+    /*! [in] The size of the secret-key data in bytes. */
+    size_t secrKeySize,
+    /*! [in] A pointer to the temporary buffer. */
+    void *pBuff,
+    /*! [in] The size of the buffer pointed by \p pBuff. Must not be
+    less than #MBEDTLS_ECIES_MIN_BUFF_LEN_BYTES. */
+    size_t buffLen
+    );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_hkdf.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_hkdf.h
new file mode 100644
index 0000000..56d9e90
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_hkdf.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains the CryptoCell HKDF key-derivation function API.
+
+ This function is as defined in
+ <em>RFC-5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</em>.
+ */
+
+/*!
+ @defgroup cc_hkdf CryptoCell HKDF key-derivation function API
+ @brief Contains the CryptoCell HMAC key-derivation function API. See mbedtls_cc_hkdf.h.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_HKDF_H
+#define _MBEDTLS_CC_HKDF_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+
+/*! The maximal size of the HKDF key in words. */
+#define CC_HKDF_MAX_HASH_KEY_SIZE_IN_BYTES        512
+
+/*! The maximal size of the HKDF hash-digest in Bytes. */
+#define CC_HKDF_MAX_HASH_DIGEST_SIZE_IN_BYTES     CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES
+
+/************************ Defines ******************************/
+
+/************************ Enums ********************************/
+/*! Supported HKDF hash modes. */
+typedef enum
+{
+    /*! SHA-1 mode. */
+    CC_HKDF_HASH_SHA1_mode      = 0,
+    /*! SHA-224 mode. */
+    CC_HKDF_HASH_SHA224_mode  = 1,
+    /*! SHA-256 mode. */
+    CC_HKDF_HASH_SHA256_mode  = 2,
+    /*! SHA-384 mode. */
+    CC_HKDF_HASH_SHA384_mode  = 3,
+    /*! SHA-512 mode. */
+    CC_HKDF_HASH_SHA512_mode  = 4,
+    /*! The maximal number of hash modes. */
+    CC_HKDF_HASH_NumOfModes,
+    /*! Reserved. */
+    CC_HKDF_HASH_OpModeLast    = 0x7FFFFFFF,
+
+}mbedtls_hkdf_hashmode_t;
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+/****************************************************************/
+
+
+/*********************************************************************************************************/
+/*!
+  @brief mbedtls_hkdf_key_derivation() performs the HMAC-based key derivation, as define by
+  <em>RFC-5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</em>.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure as defined in cc_kdf_error.h, or in md.h.
+*/
+CCError_t  mbedtls_hkdf_key_derivation(
+            mbedtls_hkdf_hashmode_t    HKDFhashMode,   /*!< [in] The HKDF identifier of the hash function to be used. */
+            uint8_t*                   Salt_ptr,       /*!< [in] A pointer to a non-secret random value. Can be NULL. */
+            size_t                     SaltLen,        /*!< [in] The size of the \p Salt_ptr. */
+            uint8_t*                   Ikm_ptr,        /*!< [in] A pointer to an input key message. */
+            uint32_t                   IkmLen,         /*!< [in] The size of the input key message */
+            uint8_t*                   Info,           /*!< [in] A pointer to an optional context and application-specific information. Can be NULL */
+            uint32_t                   InfoLen,        /*!< [in] The size of the application-specific information. */
+            uint8_t*                   Okm,            /*!< [in] A pointer to an output key material. */
+            uint32_t                   OkmLen,         /*!< [in] The size of the output key material. */
+            CCBool                     IsStrongKey     /*!< [in] If TRUE, no need to perform the extraction phase. */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_hkdf_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_hkdf_error.h
new file mode 100644
index 0000000..3649fda
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_hkdf_error.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains the error definitions of the CryptoCell HKDF APIs.
+ */
+
+/*!
+ @defgroup cc_hkdf_error Specific errors of the HKDF key-derivation APIs
+ @brief Contains the CryptoCell HKDF-API error definitions. See mbedtls_cc_hkdf_error.h.
+ @{
+ @ingroup cc_hkdf
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_HKDF_ERROR_H
+#define _MBEDTLS_CC_HKDF_ERROR_H
+
+#include "cc_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines *******************************/
+
+/* The base address for the CryptoCell HKDF module errors - 0x00F01100. */
+/*! Invalid argument. */
+#define CC_HKDF_INVALID_ARGUMENT_POINTER_ERROR      (CC_HKDF_MODULE_ERROR_BASE + 0x0UL)
+/*! Invalid argument size. */
+#define CC_HKDF_INVALID_ARGUMENT_SIZE_ERROR         (CC_HKDF_MODULE_ERROR_BASE + 0x1UL)
+/*! Illegal hash mode. */
+#define CC_HKDF_INVALID_ARGUMENT_HASH_MODE_ERROR        (CC_HKDF_MODULE_ERROR_BASE + 0x3UL)
+/*! HKDF not supported. */
+#define CC_HKDF_IS_NOT_SUPPORTED                              (CC_HKDF_MODULE_ERROR_BASE + 0xFFUL)
+
+/************************ Enums *********************************/
+
+/************************ Typedefs  *****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_MBEDTLS_CC_HKDF_ERROR_H
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_poly.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_poly.h
new file mode 100644
index 0000000..f43d41f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_poly.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains all of the CryptoCell POLY APIs, their enums and definitions.
+ */
+
+ /*!
+ @defgroup cc_poly CryptoCell POLY APIs
+ @brief Contains all CryptoCell POLY APIs. See mbedtls_cc_poly.h.
+
+ @{
+ @ingroup cryptocell_api
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_POLY_H
+#define _MBEDTLS_CC_POLY_H
+
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+/*! The size of the POLY key in words. */
+#define CC_POLY_KEY_SIZE_IN_WORDS       8
+/*! The size of the POLY key in Bytes. */
+#define CC_POLY_KEY_SIZE_IN_BYTES       (CC_POLY_KEY_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE)
+/*! The size of the POLY MAC in words. */
+#define CC_POLY_MAC_SIZE_IN_WORDS       4
+/*! The size of the POLY MAC in Bytes. */
+#define CC_POLY_MAC_SIZE_IN_BYTES       (CC_POLY_MAC_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE)
+
+/************************ Typedefs  ****************************/
+
+/*! The definition of the ChaCha-MAC buffer. */
+typedef uint32_t mbedtls_poly_mac[CC_POLY_MAC_SIZE_IN_WORDS];
+
+/*! The definition of the ChaCha-key buffer. */
+typedef uint32_t mbedtls_poly_key[CC_POLY_KEY_SIZE_IN_WORDS];
+
+/************************ Public Functions **********************/
+
+/****************************************************************************************************/
+/*!
+  @brief This function performs the POLY MAC Calculation.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure, as defined in mbedtls_cc_poly_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_poly(
+        mbedtls_poly_key     pKey,         /*!< [in] A pointer to the key buffer of the user. */
+        uint8_t              *pDataIn,     /*!< [in] A pointer to the buffer of the input data to the ChaCha. Must not be null. */
+        size_t               dataInSize,   /*!< [in] The size of the input data. Must not be zero. */
+        mbedtls_poly_mac     macRes        /*!< [in/out] A pointer to the MAC-result buffer.*/
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _MBEDTLS_CC_POLY_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_poly_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_poly_error.h
new file mode 100644
index 0000000..1044da4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_poly_error.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @file
+ @brief This file contains the error definitions of the CryptoCell POLY APIs.
+
+ @defgroup cc_poly_errors Specific errors of the CryptoCell POLY APIs
+ @brief Contains the CryptoCell POLY-API error definitions. See mbedtls_cc_poly_error.h.
+ @{
+ @ingroup cc_poly
+ @}
+ */
+
+#ifndef _MBEDTLS_CC_POLY_ERROR_H
+#define _MBEDTLS_CC_POLY_ERROR_H
+
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/* The base address of errors for the CryptoCell POLY module - 0x00F02500 */
+/*! Invalid key. */
+#define CC_POLY_KEY_INVALID_ERROR               (CC_POLY_MODULE_ERROR_BASE + 0x01UL)
+/*! Invalid input data. */
+#define CC_POLY_DATA_INVALID_ERROR              (CC_POLY_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal input data size. */
+#define CC_POLY_DATA_SIZE_INVALID_ERROR         (CC_POLY_MODULE_ERROR_BASE + 0x03UL)
+/*! MAC calculation error. */
+#define CC_POLY_RESOURCES_ERROR                 (CC_POLY_MODULE_ERROR_BASE + 0x04UL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_MBEDTLS_CC_POLY_ERROR_H
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_sha512_t.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_sha512_t.h
new file mode 100644
index 0000000..64ccaf8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_sha512_t.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_sha512_t_h
+ @{
+ */
+
+
+/*!
+ @file
+ @brief This file contains all of the CryptoCell SHA-512 truncated APIs, their
+ enums and definitions.
+ */
+
+#ifndef _MBEDTLS_CC_SHA512_T_H
+#define _MBEDTLS_CC_SHA512_T_H
+
+#include <sha512.h>
+
+/*!
+   @brief This function initializes the SHA-512_t context.
+ */
+void mbedtls_sha512_t_init(
+    /*! The SHA-512_t context to initialize. */
+    mbedtls_sha512_context *ctx
+      );
+
+/*!
+   @brief This function clears the SHA-512_t context.
+ */
+void mbedtls_sha512_t_free(
+    /*! The SHA-512_t context to clear. */
+    mbedtls_sha512_context *ctx
+       );
+
+/*!
+   @brief This function starts a SHA-512_t checksum calculation.
+ */
+void mbedtls_sha512_t_starts(
+    /*! The SHA-512_t context to initialize. */
+    mbedtls_sha512_context *ctx,
+    /*! Determines which function to use: 0: Use SHA-512/256, or 1:
+    Use SHA-512/224. */
+    int is224
+        );
+
+/*!
+   @brief This function feeds an input buffer into an ongoing SHA-512_t
+   checksum calculation.
+ */
+void mbedtls_sha512_t_update(
+    /*! The SHA-512_t context. */
+    mbedtls_sha512_context *ctx,
+    /*! The buffer holding the input data. */
+    const unsigned char *input,
+    /*! The length of the input data. */
+    size_t ilen
+          );
+
+/*!
+   @brief   This function finishes the SHA-512_t operation, and writes
+    the result to the output buffer.
+
+    <ul><li>For SHA512/224, the output buffer will include
+    the 28 leftmost bytes of the SHA-512 digest.</li>
+    <li>For SHA512/256, the output buffer will include
+    the 32 leftmost bytes of the SHA-512 digest.</li></ul>
+    */
+void mbedtls_sha512_t_finish(
+    /*! The SHA-512_t context. */
+    mbedtls_sha512_context *ctx,
+    /*! The SHA-512/256 or SHA-512/224 checksum result. */
+    unsigned char output[32],
+    /*! Determines which function to use: 0: Use SHA-512/256, or 1:
+    Use SHA-512/224. */
+    int is224
+          );
+
+/*!
+   @brief      This function calculates the SHA-512 checksum of a buffer.
+
+    The function performs the following operations:
+    <ul><li>Allocates the context.<li><li>Calculates
+    the checksum.</li><li>Frees the context.</li></ul>
+    The SHA-512 result is calculated as
+    output = SHA-512(input buffer).
+*/
+void mbedtls_sha512_t(
+    /*! The buffer holding the input data. */
+    const unsigned char *input,
+    /*! The length of the input data. */
+    size_t ilen,
+    /*! The SHA-512/256 or SHA-512/224 checksum result. */
+    unsigned char output[32],
+    /*! Determines which function to use: 0: Use SHA-512/256, or 1:
+    Use SHA-512/224. */
+    int is224
+      );
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_srp.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_srp.h
new file mode 100644
index 0000000..7282e17
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_srp.h
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ /*!
+ @addtogroup cc_srp
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all of the CryptoCell SRP APIs, their enums and
+ definitions.
+ */
+
+#ifndef _MBEDTLS_CC_SRP_H
+#define _MBEDTLS_CC_SRP_H
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+#include "cc_pka_defs_hw.h"
+#include "cc_hash_defs.h"
+#include "cc_rnd_common.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!\internal The following describes the SRP APIs usage for the Device and the Accessory :*
+
+        Device (User)                       Accessory (Host)
+*      --------------                       -----------------
+
+  1.    CC_SRP_HK_INIT(CC_SRP_USER, .......)        CC_SRP_HK_INIT(CC_SRP_HOST, .....)
+
+  2.                                CC_SrpPwdVerCreate(..)
+
+  3.    CC_SrpUserPubKeyCreate(..)              CC_SrpHostPubKeyCreate(..)
+
+  4.    CC_SrpUserProofCalc(..)
+
+  5.                                CC_SrpHostProofVerifyAndCalc(..)
+
+  6.    CC_SrpUserProofVerify(..)
+
+  7.    CC_SrpClear(..)                 CC_SrpClear(..)
+
+ */
+
+/************************ Defines ******************************/
+/* The SRP modulus sizes. */
+/*! SRP modulus size of 1024 bits. */
+#define CC_SRP_MODULUS_SIZE_1024_BITS   1024
+/*! SRP modulus size of 1536 bits. */
+#define CC_SRP_MODULUS_SIZE_1536_BITS   1536
+/*! SRP modulus size of 2048 bits. */
+#define CC_SRP_MODULUS_SIZE_2048_BITS   2048
+/*! SRP modulus size of 3072 bits. */
+#define CC_SRP_MODULUS_SIZE_3072_BITS   3072
+
+/*! The maximal size of the SRP modulus in bits. */
+#define CC_SRP_MAX_MODULUS_IN_BITS      CC_SRP_MODULUS_SIZE_3072_BITS
+/*! The maximal size of the SRP modulus in bytes. */
+#define CC_SRP_MAX_MODULUS          (CC_SRP_MAX_MODULUS_IN_BITS/CC_BITS_IN_BYTE)
+/*! The maximal size of the SRP modulus in words. */
+#define CC_SRP_MAX_MODULUS_IN_WORDS         (CC_SRP_MAX_MODULUS_IN_BITS/CC_BITS_IN_32BIT_WORD)
+
+/* SRP private number size range. */
+/*! The minimal size of the SRP private number in bits. */
+#define CC_SRP_PRIV_NUM_MIN_SIZE_IN_BITS        (256)
+/*! The minimal size of the SRP private number in bytes. */
+#define CC_SRP_PRIV_NUM_MIN_SIZE            (CC_SRP_PRIV_NUM_MIN_SIZE_IN_BITS/CC_BITS_IN_BYTE)
+/*! The minimal size of the SRP private number in words. */
+#define CC_SRP_PRIV_NUM_MIN_SIZE_IN_WORDS       (CC_SRP_PRIV_NUM_MIN_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD)
+/*! The maximal size of the SRP private number in bits. */
+#define CC_SRP_PRIV_NUM_MAX_SIZE_IN_BITS        (CC_SRP_MAX_MODULUS_IN_BITS)
+/*! The maximal size of the SRP private number in bytes. */
+#define CC_SRP_PRIV_NUM_MAX_SIZE            (CC_SRP_PRIV_NUM_MAX_SIZE_IN_BITS/CC_BITS_IN_BYTE)
+/*! The maximal size of the SRP private number in words. */
+#define CC_SRP_PRIV_NUM_MAX_SIZE_IN_WORDS       (CC_SRP_PRIV_NUM_MAX_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD)
+
+/*! The maximal size of the SRP hash digest in words. */
+#define CC_SRP_MAX_DIGEST_IN_WORDS      CC_HASH_RESULT_SIZE_IN_WORDS
+/*! The maximal size of the SRP hash digest in bytes. */
+#define CC_SRP_MAX_DIGEST           (CC_SRP_MAX_DIGEST_IN_WORDS*CC_32BIT_WORD_SIZE)
+
+/*! The minimal size of the salt in bytes. */
+#define CC_SRP_MIN_SALT_SIZE            (8)
+/*! The minimal size of the salt in words. */
+#define CC_SRP_MIN_SALT_SIZE_IN_WORDS       (CC_SRP_MIN_SALT_SIZE/CC_32BIT_WORD_SIZE)
+/*! The maximal size of the salt in bytes. */
+#define CC_SRP_MAX_SALT_SIZE            (64)
+/*! The maximal size of the salt in words. */
+#define CC_SRP_MAX_SALT_SIZE_IN_WORDS       (CC_SRP_MAX_SALT_SIZE/CC_32BIT_WORD_SIZE)
+
+/************************ Typedefs  ****************************/
+/*! The definition of the SRP modulus buffer. */
+typedef uint8_t mbedtls_srp_modulus[CC_SRP_MAX_MODULUS];
+
+/*! The definition of the SRP digest buffer. */
+typedef uint8_t mbedtls_srp_digest[CC_SRP_MAX_DIGEST];
+
+/*! The definition of the SRP session key. */
+typedef uint8_t mbedtls_srp_sessionKey[2*CC_SRP_MAX_DIGEST];
+
+/************************ Enums ********************************/
+
+/*! Supported SRP versions. */
+typedef enum {
+    /*! SRP version 3. */
+    CC_SRP_VER_3    = 0,
+    /*! SRP version 6. */
+    CC_SRP_VER_6   = 1,
+    /*! SRP version 6A. */
+    CC_SRP_VER_6A  = 2,
+    /*! SRP version HK. */
+    CC_SRP_VER_HK  = 3,
+/*! The maximal number of supported versions. */
+    CC_SRP_NumOfVersions,
+    /*! Reserved.*/
+    CC_SRP_VersionLast= 0x7FFFFFFF,
+}mbedtls_srp_version_t;
+
+/*! SRP entity types. */
+typedef enum {
+    /*! The host entity, also known as server, verifier, or accessory. */
+    CC_SRP_HOST = 1,
+    /*! The user entity, also known as client, or device. */
+    CC_SRP_USER   = 2,
+    /*! The maximal number of entities types. */
+    CC_SRP_NumOfEntityType,
+    /*! Reserved. */
+    CC_SRP_EntityLast= 0x7FFFFFFF,
+}mbedtls_srp_entity_t;
+
+/************************ Structs  ******************************/
+
+/*!
+ @brief Group parameters for the SRP.
+
+ Defines the modulus and the generator used.
+ */
+typedef struct mbedtls_srp_group_param {
+    /*! The SRP modulus. */
+    mbedtls_srp_modulus modulus;
+    /*! The SRP generator. */
+    uint8_t         gen;
+    /*! The size of the SRP modulus in bits. */
+    size_t          modSizeInBits;
+    /*! The valid SRP Np. */
+    uint32_t        validNp;
+    /*! The SRP Np buffer. */
+    uint32_t        Np[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+}mbedtls_srp_group_param;
+
+/************************ context Structs  ******************************/
+/*! The SRP context prototype */
+typedef struct mbedtls_srp_context {
+    /*! The SRP entitiy type. */
+    mbedtls_srp_entity_t            srpType;
+    /*! The SRP version. */
+    mbedtls_srp_version_t   srpVer;
+    /*! The group parameter including the modulus information. */// N, g, Np
+    mbedtls_srp_group_param     groupParam;
+    /*! The hash mode. */
+    CCHashOperationMode_t   hashMode;
+    /*! The hash digest size. */
+    size_t          hashDigestSize;
+    /*! The session key size. */
+    size_t          sessionKeySize;
+    /*! A pointer to the RND context. */
+    CCRndContext_t      *pRndCtx;
+    /*! The modulus. */ // a or b
+    mbedtls_srp_modulus     ephemPriv;
+    /*! The modulus size. */
+    size_t          ephemPrivSize;
+    /*! The user-name digest. */// M
+    mbedtls_srp_digest      userNameDigest;
+    /*! The cred digest. */ // p
+    mbedtls_srp_digest      credDigest;
+    /*! The SRP K multiplier. */      // k multiplier
+    mbedtls_srp_digest      kMult;
+}mbedtls_srp_context;
+
+
+/************************ SRP common Functions **********************/
+/*****************************************************************************/
+/*!
+ @brief This function initiates the SRP context.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure as defined in mbedtls_cc_srp_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_init(
+        /*! [in] The SRP entity type. */
+        mbedtls_srp_entity_t    srpType,
+        /*! [in] The SRP version. */
+        mbedtls_srp_version_t   srpVer,
+        /*! [in] A pointer to the SRP modulus, BE Byte buffer. */
+        mbedtls_srp_modulus     srpModulus,
+        /*! [in] The SRP generator param. */
+        uint8_t                 srpGen,
+        /*! [in] The size of the SRP modulus in bits. Valid values are: 1024
+        bits, 1536 bits, 2048 bits, or 3072 bits. */
+        size_t                  modSizeInBits,
+        /*! [in] The hash mode. */
+        CCHashOperationMode_t   hashMode,
+        /*! [in] A pointer to the username. */
+        uint8_t                 *pUserName,
+        /*! [in] The size of the username buffer. Must be larger than 0. */
+        size_t                  userNameSize,
+        /*! [in] A pointer to the user password. */
+        uint8_t                 *pPwd,
+        /*! [in] The size of the user-password buffer. Must be larger than 0
+        if \p pPwd is valid. */
+        size_t                  pwdSize,
+        /*! [in] A pointer to the RND context. */
+        CCRndContext_t          *pRndCtx,
+        /*! [out] A pointer to the SRP host context. */
+        mbedtls_srp_context     *pCtx
+);
+
+/*! Macro definition for a specific SRP-initialization function. */
+#define CC_SRP_HK_INIT(srpType, srpModulus, srpGen, modSizeInBits, pUserName, userNameSize, pPwd, pwdSize, pRndCtx, pCtx) \
+        mbedtls_srp_init(srpType, CC_SRP_VER_HK, srpModulus, srpGen, modSizeInBits, CC_HASH_SHA512_mode, pUserName, userNameSize, pPwd, pwdSize, pRndCtx, pCtx)
+
+
+/*****************************************************************************/
+/*!
+ @brief This function calculates \p pSalt and \p pwdVerifier.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_srp_error.h,
+ cc_rnd_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_pwd_ver_create(
+        /*! [in] The size of the random salt to generate. The range is between
+        #CC_SRP_MIN_SALT_SIZE and #CC_SRP_MAX_SALT_SIZE. */
+        size_t                  saltSize,
+        /*! [out] A pointer to the \p pSalt number (s). */
+        uint8_t         *pSalt,
+        /*! [out] A pointer to the password verifier (v). */
+        mbedtls_srp_modulus         pwdVerifier,
+        /*! [out] A pointer to the SRP context. */
+        mbedtls_srp_context *pCtx
+);
+
+
+/*****************************************************************************/
+/*!
+ @brief This function clears the SRP context.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_srp_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_clear(
+        /*! [in/out] A pointer to the SRP context. */
+        mbedtls_srp_context *pCtx
+);
+
+
+/************************ SRP Host Functions **********************/
+/*****************************************************************************/
+/*!
+ @brief This function generates the public and private host ephemeral keys,
+ known as B and b in <em>RFC 5054 Using the Secure Remote Password (SRP)
+ Protocol for TLS Authentication</em>.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_srp_error.h or
+ cc_rnd_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_host_pub_key_create(
+        /*! [in] The size of the generated ephemeral private key (b). The range
+        is between #CC_SRP_PRIV_NUM_MIN_SIZE and #CC_SRP_PRIV_NUM_MAX_SIZE */
+        size_t                  ephemPrivSize,
+        /*! [in] A pointer to the verifier (v). */
+        mbedtls_srp_modulus     pwdVerifier,
+        /*! [out] A pointer to the host ephemeral public key (B). */
+        mbedtls_srp_modulus     hostPubKeyB,
+        /*! [in/out] A pointer to the SRP context. */
+        mbedtls_srp_context     *pCtx
+);
+
+
+/*!
+ @brief This function verifies the user proof, and calculates the host-message
+ proof.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_srp_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_host_proof_verify_and_calc(
+        /*! [in] The size of the random salt. The range is between
+        #CC_SRP_MIN_SALT_SIZE and #CC_SRP_MAX_SALT_SIZE. */
+        size_t                  saltSize,
+        /*! [in] A pointer to the pSalt number. */
+        uint8_t                 *pSalt,
+        /*! [in] A pointer to the password verifier (v). */
+        mbedtls_srp_modulus     pwdVerifier,
+        /*! [in] A pointer to the ephemeral public key of the user (A). */
+        mbedtls_srp_modulus     userPubKeyA,
+        /*! [in] A pointer to the ephemeral public key of the host (B). */
+        mbedtls_srp_modulus     hostPubKeyB,
+        /*! [in] A pointer to the SRP user-proof buffer (M1). */
+        mbedtls_srp_digest      userProof,
+        /*! [out] A pointer to the SRP host-proof buffer (M2). */
+        mbedtls_srp_digest      hostProof,
+        /*! [out] A pointer to the SRP session key (K). */
+        mbedtls_srp_sessionKey   sessionKey,
+        /*! [in] A pointer to the SRP context. */
+        mbedtls_srp_context     *pCtx
+);
+
+
+
+/************************ SRP User Functions **********************/
+/*****************************************************************************/
+/*!
+ @brief This function generates public and private user ephemeral keys, known
+ as A and a in <em>RFC 5054 Using the Secure Remote Password (SRP) Protocol
+ for TLS Authentication</em>.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_srp_error.h or
+ cc_rnd_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_user_pub_key_create(
+        /*! [in] The size of the generated ephemeral private key (a). The range
+        is between #CC_SRP_PRIV_NUM_MIN_SIZE and #CC_SRP_PRIV_NUM_MAX_SIZE.
+        The size must be 32 bit aligned */
+        size_t                  ephemPrivSize,
+        /*! [out] A pointer to the user ephemeral public key (A). */
+        mbedtls_srp_modulus     userPubKeyA,
+        /*! [in/out] A pointer to the SRP context. */
+        mbedtls_srp_context     *pCtx
+);
+
+
+/*****************************************************************************/
+/*!
+ @brief This function calculates the user proof.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_srp_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_user_proof_calc(
+        /*! [in] The size of the random salt. The range is between
+        #CC_SRP_MIN_SALT_SIZE and #CC_SRP_MAX_SALT_SIZE. */
+        size_t                  saltSize,
+        /*! [in] A pointer to the pSalt number. */
+        uint8_t                 *pSalt,
+        /*! [in] A pointer to the public ephmeral key of the user (A). */
+        mbedtls_srp_modulus     userPubKeyA,
+        /*! [in] A pointer to the public ephmeral key of the host (B). */
+        mbedtls_srp_modulus     hostPubKeyB,
+        /*! [out] A pointer to the SRP user proof buffer (M1). */
+        mbedtls_srp_digest      userProof,
+        /*! [out] A pointer to the SRP session key (K). */
+        mbedtls_srp_sessionKey      sessionKey,
+        /*! [out] A pointer to the SRP context. */
+        mbedtls_srp_context     *pCtx
+);
+
+/*****************************************************************************/
+/*!
+ @brief This function verifies the host proof.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure, as defined in mbedtls_cc_srp_error.h.
+ */
+CIMPORT_C CCError_t  mbedtls_srp_user_proof_verify(
+        /*! [in] A pointer to the SRP session key (K). */
+        mbedtls_srp_sessionKey    sessionKey,
+        /*! [in] A pointer to the public ephmeral key of the user (A). */
+        mbedtls_srp_modulus   userPubKeyA,
+        /*! [in] A pointer to the SRP user proof buffer (M1). */
+        mbedtls_srp_digest    userProof,
+        /*! [in] A pointer to the SRP host proof buffer (M2). */
+        mbedtls_srp_digest    hostProof,
+        /*! [out] A pointer to the SRP user context. */
+        mbedtls_srp_context   *pCtx
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /* #ifndef _MBEDTLS_CC_SRP_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_srp_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_srp_error.h
new file mode 100644
index 0000000..fd13351
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_cc_srp_error.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_srp_errors
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the error definitions of the CryptoCell SRP APIs.
+ */
+
+
+#ifndef _MBEDTLS_CC_SRP_ERROR_H
+#define _MBEDTLS_CC_SRP_ERROR_H
+
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/* The base address errors of the CryptoCell SRP module - 0x00F02600 */
+/*! Illegal parameter. */
+#define CC_SRP_PARAM_INVALID_ERROR           (CC_SRP_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal modulus size. */
+#define CC_SRP_MOD_SIZE_INVALID_ERROR        (CC_SRP_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal state (uninitialized) . */
+#define CC_SRP_STATE_UNINITIALIZED_ERROR     (CC_SRP_MODULE_ERROR_BASE + 0x03UL)
+/*! Result validation error. */
+#define CC_SRP_RESULT_ERROR                  (CC_SRP_MODULE_ERROR_BASE + 0x04UL)
+/*! Invalid parameter. */
+#define CC_SRP_PARAM_ERROR                   (CC_SRP_MODULE_ERROR_BASE + 0x05UL)
+/*! Internal PKI error. */
+#define CC_SRP_INTERNAL_ERROR                (CC_SRP_MODULE_ERROR_BASE + 0x06UL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif //_MBEDTLS_CC_SRP_ERROR_H
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_chacha_ext_dma.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_chacha_ext_dma.h
new file mode 100644
index 0000000..598f858
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_chacha_ext_dma.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup chacha_ext_dma
+
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all the CryptoCell ChaCha external DMA APIs, their
+ enums and definitions.
+ */
+
+#ifndef _MBEDTLS_CHACHA_EXT_DMA_H
+#define _MBEDTLS_CHACHA_EXT_DMA_H
+
+#include "cc_pal_types.h"
+#include "mbedtls_cc_chacha.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+  @brief This function initializes the external DMA control.
+
+  It configures the ChaCha mode, the initial hash value, and other
+  configurations in the ChaCha engine.
+
+  @return \c 0 on success.
+  @return A non-zero value from mbedtls_ext_dma_error.h on failure.
+ */
+int mbedtls_ext_dma_chacha_init(
+            /*! [in] The nonce buffer.  */
+            uint8_t *  pNonce,
+            /*! [in] The nonce size flag.  */
+            mbedtls_chacha_nonce_size_t         nonceSizeFlag,
+            /*! [in] The key buffer.  */
+            uint8_t *  pKey,
+            /*! [in] The size of the key buffer. Must be 32 bytes.  */
+            uint32_t    keySizeBytes,
+            /*! [in] Initial counter value.  */
+            uint32_t    initialCounter,
+            /*! [in] The ChaCha operation: Encrypt or Decrypt. */
+            mbedtls_chacha_encrypt_mode_t  EncryptDecryptFlag,
+            /*! [in] Input data length in bytes */
+            uint32_t    dataSize
+            );
+
+
+/*!
+  @brief This function frees used resources.
+
+  @return \c CC_OK on success.
+  @return A non-zero value from mbedtls_ext_dma_error.h on failure.
+ */
+int mbedtls_chacha_ext_dma_finish(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /* #ifndef _MBEDTLS_CHACHA_EXT_DMA_H */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_ext_dma_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_ext_dma_error.h
new file mode 100644
index 0000000..dfe6f01
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_ext_dma_error.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup ext_dma_errors
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the error definitions of the CryptoCell external
+ DMA APIs.
+ */
+
+#ifndef _MBEDTLS_EXT_DMA_ERROR_H
+#define _MBEDTLS_EXT_DMA_ERROR_H
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/* The base address for errors of the CryptoCell external DMA. CC_EXT_DMA_MODULE_ERROR_BASE = 0x00F02D00 */
+/* AES errors */
+/*! Illegal mode. */
+#define EXT_DMA_AES_ILLEGAL_OPERATION_MODE_ERROR        (CC_EXT_DMA_MODULE_ERROR_BASE + 0x00UL)
+/*! Illegal encryption mode. */
+#define EXT_DMA_AES_INVALID_ENCRYPT_MODE_ERROR      (CC_EXT_DMA_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal decryption mode. */
+#define EXT_DMA_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE             (CC_EXT_DMA_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal key size. */
+#define EXT_DMA_AES_ILLEGAL_KEY_SIZE_ERROR              (CC_EXT_DMA_MODULE_ERROR_BASE + 0x03UL)
+/*! Illegal IV. */
+#define EXT_DMA_AES_INVALID_IV_OR_TWEAK_PTR_ERROR       (CC_EXT_DMA_MODULE_ERROR_BASE + 0x04UL)
+
+/* Hash errors */
+/*! Illegal hash operation mode. */
+#define EXT_DMA_HASH_ILLEGAL_OPERATION_MODE_ERROR   (CC_EXT_DMA_MODULE_ERROR_BASE + 0x05UL)
+/*! Illegal result buffer. */
+#define EXT_DMA_HASH_INVALID_RESULT_BUFFER_POINTER_ERROR    (CC_EXT_DMA_MODULE_ERROR_BASE + 0x06UL)
+/*! Illegal parameters. */
+#define EXT_DMA_HASH_ILLEGAL_PARAMS_ERROR   (CC_EXT_DMA_MODULE_ERROR_BASE + 0x07UL)
+
+/* Chacha errors */
+/*! Invalid nonce. */
+#define EXT_DMA_CHACHA_INVALID_NONCE_PTR_ERROR          (CC_EXT_DMA_MODULE_ERROR_BASE + 0x08UL)
+/*! Invalid encrypt or decrypt mode. */
+#define EXT_DMA_CHACHA_INVALID_ENCRYPT_MODE_ERROR       (CC_EXT_DMA_MODULE_ERROR_BASE + 0x09UL)
+/*! Invalid key pointer. */
+#define EXT_DMA_CHACHA_INVALID_KEY_POINTER_ERROR        (CC_EXT_DMA_MODULE_ERROR_BASE + 0xAUL)
+/*! Invalid key size. */
+#define EXT_DMA_CHACHA_ILLEGAL_KEY_SIZE_ERROR           (CC_EXT_DMA_MODULE_ERROR_BASE + 0xBUL)
+/*! Invalid nonce size flag. */
+#define EXT_DMA_CHACHA_INVALID_NONCE_ERROR              (CC_EXT_DMA_MODULE_ERROR_BASE + 0xCUL)
+/*! Illegal input size. */
+#define EXT_DMA_CHACHA_ILLEGAL_INPUT_SIZE_ERROR         (CC_EXT_DMA_MODULE_ERROR_BASE + 0xDUL)
+
+/* External DMA modules errors */
+/*! Illegal input size. */
+#define EXT_DMA_ILLEGAL_INPUT_SIZE_ERROR                (CC_EXT_DMA_MODULE_ERROR_BASE + 0xF0UL)
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif // _MBEDTLS_EXT_DMA_ERROR_H
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_hash_ext_dma.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_hash_ext_dma.h
new file mode 100644
index 0000000..90c417e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc3x/mbedtls_hash_ext_dma.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*!
+ @addtogroup hash_ext_dma
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all the CryptoCell hash external DMA APIs, their
+ enums and definitions.
+ */
+
+#ifndef _MBEDTLS_HASH_EXT_DMA_H
+#define _MBEDTLS_HASH_EXT_DMA_H
+
+#include "cc_pal_types.h"
+#include "cc_hash_defs.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+ @brief This function initializes the External DMA Control.
+
+ It configures the hash mode, the initial hash value, and other configurations.
+
+ @return \c CC_OK on success.
+ @return A non-zero value on failure.
+ */
+int mbedtls_hash_ext_dma_init(
+    /*! [in] The hash mode. Supported modes are: SHA1, SHA224 or SHA256. */
+    CCHashOperationMode_t  operationMode,
+    /*! [in] Input data size in bytes. */
+    uint32_t                dataSize
+    );
+
+/*!
+  @brief This function returns the digest after the hash operation, and frees
+  used resources.
+
+  @return \c CC_OK on success.
+  @return A non-zero value on failure.
+ */
+int mbedtls_hash_ext_dma_finish(
+    /*! [in] The hash mode. Supported modes are: SHA1, SHA224 or SHA256. */
+    CCHashOperationMode_t  operationMode,
+    /*! [in] The size of the hash digest in bytes. */
+    uint32_t digestBufferSize,
+    /*! [out] The output digest buffer. */
+    uint32_t *digestBuffer
+    );
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /* #ifndef MBEDTLS_HASH_EXT_DMA_H_ */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aes_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aes_defs.h
new file mode 100644
index 0000000..b9d6689
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aes_defs.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ /*!
+ @addtogroup cc_aes_defs
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the type definitions that are used by the CryptoCell
+ AES APIs.
+ */
+
+
+#ifndef CC_AES_DEFS_H
+#define CC_AES_DEFS_H
+
+#include "cc_pal_types.h"
+#include "cc_aes_defs_proj.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines  ******************************/
+/*! The size of the AES block in words. */
+#define CC_AES_CRYPTO_BLOCK_SIZE_IN_WORDS 4
+/*! The size of the AES block in bytes. */
+#define CC_AES_BLOCK_SIZE_IN_BYTES  (CC_AES_CRYPTO_BLOCK_SIZE_IN_WORDS * sizeof(uint32_t))
+
+/*! The size of the IV buffer in words. */
+#define CC_AES_IV_SIZE_IN_WORDS   CC_AES_CRYPTO_BLOCK_SIZE_IN_WORDS
+/*! The size of the IV buffer in bytes. */
+#define CC_AES_IV_SIZE_IN_BYTES  (CC_AES_IV_SIZE_IN_WORDS * sizeof(uint32_t))
+
+
+/************************ Enums ********************************/
+/*! The AES operation:<ul><li>Encrypt</li><li>Decrypt</li></ul>. */
+typedef enum {
+    /*! An AES encrypt operation. */
+    CC_AES_ENCRYPT = 0,
+    /*! An AES decrypt operation. */
+    CC_AES_DECRYPT = 1,
+    /*! The maximal number of operations. */
+    CC_AES_NUM_OF_ENCRYPT_MODES,
+    /*! Reserved. */
+    CC_AES_ENCRYPT_MODE_LAST = 0x7FFFFFFF
+}CCAesEncryptMode_t;
+
+/*! The AES operation mode. */
+typedef enum {
+    /*! ECB mode. */
+    CC_AES_MODE_ECB          = 0,
+    /*! CBC mode. */
+    CC_AES_MODE_CBC          = 1,
+    /*! CBC-MAC mode. */
+    CC_AES_MODE_CBC_MAC      = 2,
+    /*! CTR mode. */
+    CC_AES_MODE_CTR          = 3,
+    /*! XCBC-MAC mode. */
+    CC_AES_MODE_XCBC_MAC     = 4,
+    /*! CMAC mode. */
+    CC_AES_MODE_CMAC         = 5,
+    /*! XTS mode. */
+    CC_AES_MODE_XTS          = 6,
+    /*! CBC-CTS mode. */
+    CC_AES_MODE_CBC_CTS      = 7,
+    /*! OFB mode. */
+    CC_AES_MODE_OFB          = 8,
+
+    /*! The maximal number of AES modes. */
+    CC_AES_NUM_OF_OPERATION_MODES,
+    /*! Reserved. */
+    CC_AES_OPERATION_MODE_LAST = 0x7FFFFFFF
+}CCAesOperationMode_t;
+
+/*! The AES padding type. */
+typedef enum {
+       /*! No padding. */
+       CC_AES_PADDING_NONE  = 0,
+       /*! PKCS7 padding. */
+       CC_AES_PADDING_PKCS7 = 1,
+       /*! The maximal number of AES padding modes. */
+       CC_AES_NUM_OF_PADDING_TYPES,
+       /*! Reserved. */
+       CC_AES_PADDING_TYPE_LAST = 0x7FFFFFFF
+}CCAesPaddingType_t;
+
+/*! The AES key type. */
+typedef enum {
+    /*! The user key. */
+    CC_AES_USER_KEY          = 0,
+    /*! The Kplt hardware key. */
+    CC_AES_PLATFORM_KEY      = 1,
+    /*! The Kcst hardware key. */
+    CC_AES_CUSTOMER_KEY      = 2,
+    /*! The maximal number of AES key types. */
+    CC_AES_NUM_OF_KEY_TYPES,
+    /*! Reserved. */
+    CC_AES_KEY_TYPE_LAST = 0x7FFFFFFF
+}CCAesKeyType_t;
+
+/************************ Typedefs  ****************************/
+
+/*! Defines the IV buffer. A 16-byte array. */
+typedef uint8_t CCAesIv_t[CC_AES_IV_SIZE_IN_BYTES];
+
+/*! Defines the AES key data buffer. */
+typedef uint8_t CCAesKeyBuffer_t[CC_AES_KEY_MAX_SIZE_IN_BYTES];
+
+/************************ Structs  ******************************/
+
+/*!
+ The context prototype of the user.
+
+ The argument type that is passed by the user to the AES APIs. The context
+ saves the state of the operation, and must be saved by the user until
+ the end of the API flow.
+ */
+typedef struct CCAesUserContext_t {
+    /*! The context buffer for internal usage. */
+    uint32_t buff[CC_AES_USER_CTX_SIZE_IN_WORDS] ;
+}CCAesUserContext_t;
+
+
+/*! The AES key data of the user. */
+typedef struct CCAesUserKeyData_t {
+    /*! A pointer to the key. */
+    uint8_t * pKey;
+    /*! The size of the key in bytes. Valid values for XTS mode, if supported:
+    32 bytes or 64 bytes, indicating the full size of the double key (2x128 or
+    2x256 bit). Valid values for XCBC-MAC mode: 16 bytes, as limited by the
+    standard. Valid values for all other modes: 16 bytes, 24 bytes, or
+    32 bytes. */
+    size_t    keySize;
+}CCAesUserKeyData_t;
+
+/*! The AES HW key Data. */
+typedef struct CCAesHwKeyData_t {
+    /*! Slot number. */
+    size_t slotNumber;
+}CCAesHwKeyData_t;
+
+#endif /* CC_AES_DEFS_H */
+
+#ifdef __cplusplus
+}
+
+#endif
+
+/*!
+ @}
+*/
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aes_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aes_error.h
new file mode 100644
index 0000000..cd662f9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aes_error.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+@file
+@brief This file contains the definitions of the CryptoCell AES errors.
+@defgroup cc_aes_error CryptoCell AES specific errors
+@{
+@ingroup cc_aes
+*/
+
+#ifndef CC_AES_ERROR_H
+#define CC_AES_ERROR_H
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/*! CC_AES_MODULE_ERROR_BASE - 0x00F00000 */
+/*! Illegal user context. */
+#define CC_AES_INVALID_USER_CONTEXT_POINTER_ERROR     (CC_AES_MODULE_ERROR_BASE + 0x00UL)
+/*! Illegal IV or tweak pointer. */
+#define CC_AES_INVALID_IV_OR_TWEAK_PTR_ERROR          (CC_AES_MODULE_ERROR_BASE + 0x01UL)
+/*! Illegal operation. */
+#define CC_AES_ILLEGAL_OPERATION_MODE_ERROR           (CC_AES_MODULE_ERROR_BASE + 0x02UL)
+/*! Illegal key size. */
+#define CC_AES_ILLEGAL_KEY_SIZE_ERROR                 (CC_AES_MODULE_ERROR_BASE + 0x03UL)
+/*! Illegal key pointer. */
+#define CC_AES_INVALID_KEY_POINTER_ERROR              (CC_AES_MODULE_ERROR_BASE + 0x04UL)
+/*! Unsupported key type. */
+#define CC_AES_KEY_TYPE_NOT_SUPPORTED_ERROR           (CC_AES_MODULE_ERROR_BASE + 0x05UL)
+/*! Illegal operation. */
+#define CC_AES_INVALID_ENCRYPT_MODE_ERROR             (CC_AES_MODULE_ERROR_BASE + 0x06UL)
+/*! User context corrupted. */
+#define CC_AES_USER_CONTEXT_CORRUPTED_ERROR           (CC_AES_MODULE_ERROR_BASE + 0x07UL)
+/*! Illegal data in pointer. */
+#define CC_AES_DATA_IN_POINTER_INVALID_ERROR          (CC_AES_MODULE_ERROR_BASE + 0x08UL)
+/*! Illegal data out pointer. */
+#define CC_AES_DATA_OUT_POINTER_INVALID_ERROR         (CC_AES_MODULE_ERROR_BASE + 0x09UL)
+/*! Illegal data in size. */
+#define CC_AES_DATA_IN_SIZE_ILLEGAL                   (CC_AES_MODULE_ERROR_BASE + 0x0AUL)
+/*! Illegal data out address. */
+#define CC_AES_DATA_OUT_DATA_IN_OVERLAP_ERROR         (CC_AES_MODULE_ERROR_BASE + 0x0BUL)
+/*! Illegal data in buffer size. */
+#define CC_AES_DATA_IN_BUFFER_SIZE_ERROR              (CC_AES_MODULE_ERROR_BASE + 0x0CUL)
+/*! Illegal data out buffer size. */
+#define CC_AES_DATA_OUT_BUFFER_SIZE_ERROR             (CC_AES_MODULE_ERROR_BASE + 0x0DUL)
+/*! Illegal padding type. */
+#define CC_AES_ILLEGAL_PADDING_TYPE_ERROR             (CC_AES_MODULE_ERROR_BASE + 0x0EUL)
+/*! Incorrect padding. */
+#define CC_AES_INCORRECT_PADDING_ERROR                (CC_AES_MODULE_ERROR_BASE + 0x0FUL)
+/*! Output is corrupted. */
+#define CC_AES_CORRUPTED_OUTPUT_ERROR                 (CC_AES_MODULE_ERROR_BASE + 0x10UL)
+/*! Illegal output size. */
+#define CC_AES_DATA_OUT_SIZE_POINTER_INVALID_ERROR    (CC_AES_MODULE_ERROR_BASE + 0x11UL)
+/*! Decryption operation is not permitted in this mode. */
+#define CC_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE    (CC_AES_MODULE_ERROR_BASE + 0x12UL)
+/*! Additional block operation is not permitted. */
+#define CC_AES_ADDITIONAL_BLOCK_NOT_PERMITTED_ERROR   (CC_AES_MODULE_ERROR_BASE + 0x15UL)
+/*! Illegal context size. */
+#define CC_AES_CTX_SIZES_ERROR                      (CC_AES_MODULE_ERROR_BASE + 0x16UL)
+/*! Illegal parameters. */
+#define CC_AES_ILLEGAL_PARAMS_ERROR               (CC_AES_MODULE_ERROR_BASE + 0x60UL)
+/*! Illegal CTR block offset. */
+#define CC_AES_CTR_ILLEGAL_BLOCK_OFFSET_ERROR     (CC_AES_MODULE_ERROR_BASE + 0x70UL)
+/*! Illegal counter (in CTR mode). */
+#define CC_AES_CTR_ILLEGAL_COUNTER_ERROR          (CC_AES_MODULE_ERROR_BASE + 0x71UL)
+/*! AES is not supported. */
+#define CC_AES_IS_NOT_SUPPORTED                   (CC_AES_MODULE_ERROR_BASE + 0xFFUL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+
+#endif /* #ifndef CC_AES_ERROR_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aesccm_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aesccm_error.h
new file mode 100644
index 0000000..2f19d83
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_aesccm_error.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_AESCCM_ERROR_H
+#define _CC_AESCCM_ERROR_H
+
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file contains the definitions of the CryptoCell AESCCM errors.
+@defgroup cc_aesccm_error CryptoCell AES-CCM specific errors
+@{
+@ingroup cc_aesccm
+
+*/
+
+/************************ Defines ******************************/
+
+/*! CryptoCell AESCCM module errors. CC_AESCCM_MODULE_ERROR_BASE = 0x00F01500 */
+/*! Invalid context pointer. */
+#define CC_AESCCM_INVALID_USER_CONTEXT_POINTER_ERROR     (CC_AESCCM_MODULE_ERROR_BASE + 0x00UL)
+/*! Illegal key size. */
+#define CC_AESCCM_ILLEGAL_KEY_SIZE_ERROR                 (CC_AESCCM_MODULE_ERROR_BASE + 0x01UL)
+/*! Invalid key pointer. */
+#define CC_AESCCM_INVALID_KEY_POINTER_ERROR              (CC_AESCCM_MODULE_ERROR_BASE + 0x02UL)
+/*! Invalid encryption mode. */
+#define CC_AESCCM_INVALID_ENCRYPT_MODE_ERROR             (CC_AESCCM_MODULE_ERROR_BASE + 0x03UL)
+/*! Context is corrupted. */
+#define CC_AESCCM_USER_CONTEXT_CORRUPTED_ERROR           (CC_AESCCM_MODULE_ERROR_BASE + 0x04UL)
+/*! Invalid data in pointer. */
+#define CC_AESCCM_DATA_IN_POINTER_INVALID_ERROR          (CC_AESCCM_MODULE_ERROR_BASE + 0x05UL)
+/*! Invalid data out pointer. */
+#define CC_AESCCM_DATA_OUT_POINTER_INVALID_ERROR         (CC_AESCCM_MODULE_ERROR_BASE + 0x06UL)
+/*! Illegal data in size. */
+#define CC_AESCCM_DATA_IN_SIZE_ILLEGAL                   (CC_AESCCM_MODULE_ERROR_BASE + 0x07UL)
+/*! Illegal data in or data out address. */
+#define CC_AESCCM_DATA_OUT_DATA_IN_OVERLAP_ERROR         (CC_AESCCM_MODULE_ERROR_BASE + 0x08UL)
+/*! Illegal data out size. */
+#define CC_AESCCM_DATA_OUT_SIZE_INVALID_ERROR            (CC_AESCCM_MODULE_ERROR_BASE + 0x09UL)
+/*! Illegal call to process additional data. */
+#define CC_AESCCM_ADDITIONAL_BLOCK_NOT_PERMITTED_ERROR   (CC_AESCCM_MODULE_ERROR_BASE + 0x0AUL)
+/*! Illegal dma buffer type. */
+#define CC_AESCCM_ILLEGAL_DMA_BUFF_TYPE_ERROR            (CC_AESCCM_MODULE_ERROR_BASE + 0x0BUL)
+/*! Illegal parameter size. */
+#define CC_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR           (CC_AESCCM_MODULE_ERROR_BASE + 0x0CUL)
+/*! Invalid parameter pointer. */
+#define CC_AESCCM_ILLEGAL_PARAMETER_PTR_ERROR            (CC_AESCCM_MODULE_ERROR_BASE + 0x0DUL)
+/*! Invalid data type. */
+#define CC_AESCCM_ILLEGAL_DATA_TYPE_ERROR                (CC_AESCCM_MODULE_ERROR_BASE + 0x0EUL)
+/*! CCM MAC compare failure. */
+#define CC_AESCCM_CCM_MAC_INVALID_ERROR                  (CC_AESCCM_MODULE_ERROR_BASE + 0x0FUL)
+/*! Illegal operation. */
+#define CC_AESCCM_LAST_BLOCK_NOT_PERMITTED_ERROR         (CC_AESCCM_MODULE_ERROR_BASE + 0x10UL)
+/*! Illegal parameter. */
+#define CC_AESCCM_ILLEGAL_PARAMETER_ERROR                (CC_AESCCM_MODULE_ERROR_BASE + 0x11UL)
+/*! Additional data input size is incorrect. */
+#define CC_AESCCM_NOT_ALL_ADATA_WAS_PROCESSED_ERROR      (CC_AESCCM_MODULE_ERROR_BASE + 0x13UL)
+/*! Text data input size is incorrect. */
+#define CC_AESCCM_NOT_ALL_DATA_WAS_PROCESSED_ERROR       (CC_AESCCM_MODULE_ERROR_BASE + 0x14UL)
+/*! Additional data was already processed (must be processed only once). */
+#define CC_AESCCM_ADATA_WAS_PROCESSED_ERROR          (CC_AESCCM_MODULE_ERROR_BASE + 0x15UL)
+/*! Illegal Nonce size. */
+#define CC_AESCCM_ILLEGAL_NONCE_SIZE_ERROR       (CC_AESCCM_MODULE_ERROR_BASE + 0x16UL)
+/*! Illegal tag (MAC) size. */
+#define CC_AESCCM_ILLEGAL_TAG_SIZE_ERROR         (CC_AESCCM_MODULE_ERROR_BASE + 0x17UL)
+/*! Illegal context size. */
+#define CC_AESCCM_CTX_SIZES_ERROR            (CC_AESCCM_MODULE_ERROR_BASE + 0x28UL)
+/*! Illegal parameters. */
+#define CC_AESCCM_ILLEGAL_PARAMS_ERROR           (CC_AESCCM_MODULE_ERROR_BASE + 0x29UL)
+/*! AESCCM is not supported. */
+#define CC_AESCCM_IS_NOT_SUPPORTED                       (CC_AESCCM_MODULE_ERROR_BASE + 0xFFUL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  *****************************/
+
+/************************ Public Variables *********************/
+
+/************************ Public Functions *********************/
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+
+
+#endif /* _CC_AESCCM_ERROR_H */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_build.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_build.h
new file mode 100644
index 0000000..15cda09
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_build.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_ECPKI_BUILD_H
+#define _CC_ECPKI_BUILD_H
+
+/*!
+@file
+@brief This file defines functions for building key structures used in Elliptic Curves Cryptography (ECC).
+@defgroup cryptocell_ecpki CryptoCell ECC APIs
+@{
+@ingroup cryptocell_api
+
+*/
+
+
+#include "cc_error.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**********************************************************************************
+ *                    CC_EcpkiPrivKeyBuild function                            *
+ **********************************************************************************/
+/*!
+@brief Builds (imports) the user private key structure from an existing private key so
+that this structure can be used by other EC primitives.
+This function should be called before using of the private key. Input
+domain structure must be initialized by EC parameters and auxiliary
+values, using CC_EcpkiGetDomain or CC_EcpkiSetDomain functions.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h.
+*/
+CIMPORT_C CCError_t CC_EcpkiPrivKeyBuild(
+                     const CCEcpkiDomain_t *pDomain,            /*!< [in] The EC domain (curve). */
+                     const uint8_t         *pPrivKeyIn,         /*!< [in] Pointer to private key data. */
+                     size_t                 PrivKeySizeInBytes, /*!< [in] Size of private key data (in bytes). */
+                     CCEcpkiUserPrivKey_t  *pUserPrivKey        /*!< [out] Pointer to the private key structure.
+                                                   This structure is used as input to the ECPKI cryptographic primitives. */
+                     );
+
+/**********************************************************************************
+ *                CC_EcpkiPublKeyBuildAndCheck function                             *
+ **********************************************************************************/
+/*!
+@brief Builds a user public key structure from an imported public key,
+so it can be used by other EC primitives.
+When operating the EC cryptographic algorithms with imported EC public
+key, this function should be called before using of the public key.
+
+\note The Incoming public key PublKeyIn structure is big endian bytes array, containing
+concatenation of PC||X||Y. \par
+\note PC - point control single byte, defining the type of point: 0x4 - uncompressed,
+06,07 - hybrid, 2,3 - compressed. \par
+\note X,Y - EC point coordinates of public key (y is omitted in compressed form),
+size of X and Y must be equal to size of EC modulus.
+
+The user may call this function by appropriate macros, according to the necessary validation level in section SEC1. ECC standard: 3.2 of Standards for
+Efficient Cryptography Group (SECG): SEC1 Elliptic Curve Cryptography and ANSI X9.62-2005: Public Key Cryptography for the Financial Services Industry,
+The Elliptic Curve Digital Signature Algorithm (ECDSA):
+<ul><li>Checking the input pointers and sizes only - ::CC_EcpkiPubKeyBuild.</li>
+<li>Partially checking of public key - ::CC_EcpkiPubKeyBuildAndPartlyCheck. </li>
+<li>Full checking of public key - ::CC_EcpkiPubKeyBuildAndFullCheck. </li></ul>
+
+\note Full check mode takes long time and should be used only when it is actually needed.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h.
+*/
+/*
+The function performs the following operations:
+- Checks validity of incoming variables and pointers;
+- Converts incoming key data from big endian into little endian;
+- If public key is given in compressed form (i.e. byte[0] = 2 or 3 and
+  coordinate Y is omitted), then the function uncompress it;
+- Performs checking of input key according to CheckMode parameter.
+- Initializes variables and structures.
+*/
+CIMPORT_C CCError_t CC_EcpkiPublKeyBuildAndCheck(
+            const CCEcpkiDomain_t       *pDomain,               /*!< [in]  The EC domain (curve). */
+            uint8_t                     *pPubKeyIn,         /*!< [in]  Pointer to the input public key data, in compressed or
+                                           uncompressed or hybrid form:
+                                           [PC||X||Y] Big-Endian representation, structured according to
+                                           [IEEE1363], where:
+                                           <ul><li>X and Y are the public key's EC point coordinates.
+                                           In compressed form, Y is omitted.</li>
+                                           <li> The sizes of X and Y are equal to the size of the EC modulus.</li>
+                                           <li> PC is a one-byte point control that defines the type of point
+                                           compression. </li></ul>*/
+            size_t                      PublKeySizeInBytes,    /*!< [in]  The size of public key data (in bytes). */
+            ECPublKeyCheckMode_t        CheckMode,             /*!< [in]  The required level of public key verification
+                                    (higher verification level means longer verification time):
+                                    <ul><li> 0 = preliminary validation. </li>
+                                    <li> 1 = partial validation. </li>
+                                    <li> 2 = full validation. </li></ul>*/
+            CCEcpkiUserPublKey_t        *pUserPublKey,          /*!< [out] Pointer to the output public key structure.
+                                        This structure is used as input to the ECPKI cryptographic primitives. */
+            CCEcpkiBuildTempData_t      *pTempBuff              /*!< [in]  Pointer for a temporary buffer required for the build function. */
+            );
+
+
+/**********************************************************************************
+ *                 CC_EcpkiPubKeyBuild macro                              *
+ **********************************************************************************/
+/*!
+@brief This macro calls CC_EcpkiPublKeyBuildAndCheck function for building the public key
+while checking input pointers and sizes. For a description of the parameters see ::CC_EcpkiPublKeyBuildAndCheck.
+*/
+#define  CC_EcpkiPubKeyBuild(pDomain, pPubKeyIn, PublKeySizeInBytes, pUserPublKey) \
+         CC_EcpkiPublKeyBuildAndCheck((pDomain), (pPubKeyIn), (PublKeySizeInBytes), CheckPointersAndSizesOnly, (pUserPublKey), NULL)
+
+
+/**********************************************************************************
+ *                 CC_EcpkiPubKeyBuildAndPartlyCheck macro                         *
+ **********************************************************************************/
+/*!
+@brief This macro calls CC_EcpkiPublKeyBuildAndCheck function for building the public key with partial validation of the key [SEC1] - 3.2.3.
+For a description of the parameters see ::CC_EcpkiPublKeyBuildAndCheck.
+*/
+#define  CC_EcpkiPubKeyBuildAndPartlyCheck(pDomain, pPubKeyIn, PublKeySizeInBytes, pUserPublKey, pTempBuff) \
+         CC_EcpkiPublKeyBuildAndCheck((pDomain), (pPubKeyIn), (PublKeySizeInBytes), ECpublKeyPartlyCheck, (pUserPublKey), (pTempBuff))
+
+
+/**********************************************************************************
+ *                 CC_EcpkiPubKeyBuildAndFullCheck macro                     *
+ **********************************************************************************/
+/*!
+@brief This macro calls CC_EcpkiPublKeyBuildAndCheck function for building the public key with full validation of the key [SEC1] - 3.2.2.
+For a description of the parameters and return values see CC_EcpkiPublKeyBuildAndCheck.
+*/
+#define  CC_EcpkiPubKeyBuildAndFullCheck(pDomain, pPubKeyIn, PublKeySizeInBytes, pUserPublKey,  pTempBuff) \
+     CC_EcpkiPublKeyBuildAndCheck((pDomain), (pPubKeyIn), (PublKeySizeInBytes), (ECpublKeyFullCheck), (pUserPublKey),  (pTempBuff))
+
+
+/***********************************************************************************
+ *                     CC_EcpkiPubKeyExport function                           *
+ ***********************************************************************************/
+/*!
+@brief Converts an existing public key from internal representation to Big-Endian export representation.
+The function converts the X,Y coordinates of public key EC point to big endianness,
+and sets the public key as follows:
+<ul><li>In case "Uncompressed" point:  PubKey = PC||X||Y, PC = 0x4 - single byte;</li>
+<li>In case of "Hybrid" key PC = 0x6.</li>
+<li>In case of "Compressed" key PC = 0x2.</li></ul>
+\note Size of output X and Y coordinates is equal to ModSizeInBytes.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h.
+*/
+CIMPORT_C CCError_t CC_EcpkiPubKeyExport(
+                  CCEcpkiUserPublKey_t           *pUserPublKey,        /*!< [in]  Pointer to the input public key structure (in Little-Endian form). */
+                  CCEcpkiPointCompression_t      compression,         /*!< [in]  Compression mode: Compressed, Uncompressed or Hybrid. */
+                  uint8_t                        *pExternPublKey,      /*!< [out] Pointer to the exported public key array, in compressed or uncompressed
+                                               or hybrid form:
+                                            [PC||X||Y] Big-Endian representation, structured according to [IEEE1363].
+                                            In compressed form, Y is omitted. */
+                  size_t                         *pPublKeySizeBytes    /*!< [in/out] Pointer used for the input of the user public key buffer size
+                                               (in bytes), and the output of the size of the converted public key in bytes. */
+                  );
+
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_dh.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_dh.h
new file mode 100644
index 0000000..fac3085
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_dh.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_ECPKI_DH_H
+#define _CC_ECPKI_DH_H
+
+/*! @file
+@brief This file defines the API that supports EC Diffie-Hellman shared secret value derivation primitives.
+@defgroup cc_ecpki_dh CryptoCell ECC Diffie-Hellman APIs
+@{
+@ingroup cryptocell_ecpki
+
+*/
+
+
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/***********************************************************************
+ *               CC_EcdhSvdpDh function                    *
+ ***********************************************************************/
+/*!
+@brief Creates the shared secret value according to IEEE 1363-2000: IEEE Standard for Standard Specifications for Public-Key Cryptography standard
+and ANSI X9.63-2011: Public Key Cryptography for the Financial Services Industry - Key Agreement and Key Transport Using
+Elliptic Curve Cryptography standard:
+<ol><li> Checks input-parameter pointers and EC Domain in public and private
+keys.</li>
+<li> Derives the partner public key and calls the EcWrstDhDeriveSharedSecret
+function, which performs EC SVDP operations.</li></ol>
+\note The term "User"
+refers to any party that calculates a shared secret value using this primitive.
+The term "Partner" refers to any other party of shared secret value calculation.
+Partner's public key shall be validated before using in this primitive.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h.
+*/
+CIMPORT_C CCError_t CC_EcdhSvdpDh(
+                        CCEcpkiUserPublKey_t *PartnerPublKey_ptr,           /*!< [in]  Pointer to a partner public key. */
+                        CCEcpkiUserPrivKey_t *UserPrivKey_ptr,              /*!< [in]  Pointer to a user private key. */
+                        uint8_t              *SharedSecretValue_ptr,    /*!< [out] Pointer to an output buffer that contains the shared
+                                               secret value. */
+                        size_t                   *SharedSecrValSize_ptr,    /*!< [in/out] Pointer to the size of user-passed buffer (in) and
+                                                                                          actual size of output of calculated shared secret value
+                                              (out). */
+                        CCEcdhTempData_t     *TempBuff_ptr              /*!< [in]  Pointer to a temporary buffer. */);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_ecdsa.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_ecdsa.h
new file mode 100644
index 0000000..09e4390
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_ecdsa.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_ECPKI_ECDSA_H
+#define _CC_ECPKI_ECDSA_H
+
+/*!
+@file
+@brief This file defines the APIs that support the ECDSA functions.
+@defgroup cc_ecpki_ecdsa CryptoCell ECDSA APIs
+@{
+@ingroup cryptocell_ecpki
+
+*/
+
+#include "cc_error.h"
+#include "cc_ecpki_types.h"
+#include "cc_hash_defs.h"
+#include "cc_rnd_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+/**************************************************************************
+ *                CC_EcdsaSign - integrated function
+ **************************************************************************/
+/*!
+@brief This function performs an ECDSA sign operation in integrated form.
+
+\note Using of HASH functions with HASH size greater than EC modulus size, is not recommended!.
+Algorithm according to the ANSI X9.62-2005: Public Key Cryptography for the Financial Services Industry, The Elliptic
+Curve Digital Signature Algorithm (ECDSA) standard.
+
+The message data may be either a non-hashed data or a digest of a hash function.
+For a non-hashed data, the message data will be hashed using the hash function indicated by ::CCEcpkiHashOpMode_t.
+For a digest, ::CCEcpkiHashOpMode_t should indicate the hash function that the message data was created by, and it will not be hashed.
+
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h, cc_hash_error.h or cc_rnd_error.h.
+**/
+CIMPORT_C CCError_t CC_EcdsaSign(
+                     CCRndContext_t         *pRndContext,            /*!< [in/out] Pointer to the RND context buffer. */
+                     CCEcdsaSignUserContext_t   *pSignUserContext,   /*!< [in/out] Pointer to the user buffer for signing the database. */
+                     CCEcpkiUserPrivKey_t       *pSignerPrivKey,     /*!< [in]  A pointer to a user private key structure. */
+                     CCEcpkiHashOpMode_t        hashMode,            /*!< [in]  One of the supported SHA-x HASH modes, as defined in
+                                                   ::CCEcpkiHashOpMode_t.
+                                                   \note MD5 is not supported. */
+                     uint8_t                    *pMessageDataIn,     /*!< [in] Pointer to the input data to be signed.
+                                                   The size of the scatter/gather list representing the data buffer
+                                                   is limited to 128 entries, and the size of each entry is limited
+                                                   to 64KB (fragments larger than 64KB are broken into
+                                                   fragments <= 64KB). */
+                     size_t                     messageSizeInBytes,  /*!< [in]  Size of message data in bytes. */
+                     uint8_t                    *pSignatureOut,      /*!< [in]  Pointer to a buffer for output of signature. */
+                     size_t                     *pSignatureOutSize   /*!< [in/out] Pointer to the signature size. Used to pass the size of
+                                                       the SignatureOut buffer (in), which must be >=
+                                                       2 * OrderSizeInBytes. When the API returns,
+                                                       it is replaced with the size of the actual signature (out). */
+                     );
+
+
+
+/**************************************************************************
+ *                CC_EcdsaVerify integrated function
+ **************************************************************************/
+/*!
+@brief This function performs an ECDSA verify operation in integrated form.
+Algorithm according to the ANSI X9.62-2005: Public Key Cryptography for the Financial Services Industry,
+The Elliptic Curve Digital Signature Algorithm (ECDSA) standard.
+
+The message data may be either a non-hashed data or a digest of a hash function.
+For a non-hashed data, the message data will be hashed using the hash function indicated by ::CCEcpkiHashOpMode_t.
+For a digest, ::CCEcpkiHashOpMode_t should indicate the hash function that the message data was created by, and it will not be hashed.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h or cc_hash_error.h.
+*/
+CIMPORT_C CCError_t CC_EcdsaVerify (
+                    CCEcdsaVerifyUserContext_t *pVerifyUserContext, /*!< [in] Pointer to the user buffer for signing the database. */
+                    CCEcpkiUserPublKey_t       *pUserPublKey,       /*!< [in] Pointer to a user public key structure. */
+                    CCEcpkiHashOpMode_t         hashMode,           /*!< [in] One of the supported SHA-x HASH modes, as defined in
+                                                  ::CCEcpkiHashOpMode_t.
+                                                  \note MD5 is not supported. */
+                    uint8_t                     *pSignatureIn,       /*!< [in] Pointer to the signature to be verified. */
+                    size_t                      SignatureSizeBytes,  /*!< [in] Size of the signature (in bytes).  */
+                    uint8_t                     *pMessageDataIn,     /*!< [in] Pointer to the input data that was signed (same as given to
+                                                      the signing function). The size of the scatter/gather list representing
+                                                      the data buffer is limited to 128 entries, and the size of each entry is
+                                                      limited to 64KB (fragments larger than 64KB are broken into fragments <= 64KB). */
+                    size_t                      messageSizeInBytes   /*!< [in] Size of the input data (in bytes). */
+                    );
+
+
+/**********************************************************************************************************/
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_error.h
new file mode 100644
index 0000000..c9a3beb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_error.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_ECPKI_ERROR_H
+#define _CC_ECPKI_ERROR_H
+
+
+/*!
+@file
+@brief This file contains the definitions of the CryptoCell ECPKI errors.
+@defgroup cc_ecpki_error CryptoCell ECC specific errors
+@{
+@ingroup cryptocell_ecpki
+
+*/
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* CC_ECPKI_MODULE_ERROR_BASE = 0x00F00800  */
+
+/*********************************************************************************************
+ * CryptoCell ECPKI MODULE ERRORS                                                                  *
+ *********************************************************************************************/
+/*! Illegal domain ID. */
+#define CC_ECPKI_ILLEGAL_DOMAIN_ID_ERROR                    (CC_ECPKI_MODULE_ERROR_BASE + 0x1UL)
+/*! Illegal domain pointer. */
+#define CC_ECPKI_DOMAIN_PTR_ERROR               (CC_ECPKI_MODULE_ERROR_BASE + 0x2UL)
+/* The CryptoCell ECPKI GEN KEY PAIR module errors */
+/*! Illegal private key pointer. */
+#define CC_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0x3UL)
+/*! Illegal public key pointer. */
+#define CC_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0x4UL)
+/*! Illegal temporary buffer pointer. */
+#define CC_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR            (CC_ECPKI_MODULE_ERROR_BASE + 0x5UL)
+/*! Illegal RND context pointer. */
+#define CC_ECPKI_RND_CONTEXT_PTR_ERROR              (CC_ECPKI_MODULE_ERROR_BASE + 0x6UL)
+
+/************************************************************************************************************
+* The CryptoCell ECPKI BUILD KEYS MODULE ERRORS                                                                   *
+*************************************************************************************************************/
+/*! Illegal compression mode. */
+#define CC_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR     (CC_ECPKI_MODULE_ERROR_BASE + 0x07UL)
+/*! Illegal domain ID. */
+#define CC_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR            (CC_ECPKI_MODULE_ERROR_BASE + 0x08UL)
+/*! Illegal private key pointer. */
+#define CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR      (CC_ECPKI_MODULE_ERROR_BASE + 0x09UL)
+/*! Illegal private key structure pointer. */
+#define CC_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR    (CC_ECPKI_MODULE_ERROR_BASE + 0x0AUL)
+/*! Illegal private key size. */
+#define CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x0BUL)
+/*! Illegal private key data. */
+#define CC_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x0CUL)
+/*! Illegal public key pointer. */
+#define CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR      (CC_ECPKI_MODULE_ERROR_BASE + 0x0DUL)
+/*! Illegal public key structure pointer. */
+#define CC_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR    (CC_ECPKI_MODULE_ERROR_BASE + 0x0EUL)
+/*! Illegal public key size. */
+#define CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x0FUL)
+/*! Illegal public key data. */
+#define CC_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x10UL)
+/*! Illegal EC build check mode option. */
+#define CC_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0x11UL)
+/*! Illegal temporary buffer pointer. */
+#define CC_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x12UL)
+
+
+
+/* The CryptoCell ECPKI EXPORT PUBLIC KEY MODULE ERRORS */
+/*! Illegal public key structure pointer. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR      (CC_ECPKI_MODULE_ERROR_BASE + 0x14UL)
+/*! Illegal public key compression mode. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR       (CC_ECPKI_MODULE_ERROR_BASE + 0x15UL)
+/*! Illegal output public key pointer. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR    (CC_ECPKI_MODULE_ERROR_BASE + 0x16UL)
+/*! Illegal output public key size pointer. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR      (CC_ECPKI_MODULE_ERROR_BASE + 0x17UL)
+/*! Illegal output public key size. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0x18UL)
+/*! Illegal domain ID. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR              (CC_ECPKI_MODULE_ERROR_BASE + 0x19UL)
+/*! Validation of public key failed. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_VALIDATION_TAG_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0x1AUL)
+/*! Validation of public key failed. */
+#define CC_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0x1BUL)
+
+/* The CryptoCell ECPKI BUILD ECC DOMAIN ERRORS */
+/*! Illegal domain ID. */
+#define CC_ECPKI_BUILD_DOMAIN_ID_IS_NOT_VALID_ERROR               (CC_ECPKI_MODULE_ERROR_BASE + 0x20UL)
+/*! Illegal domain ID pointer. */
+#define CC_ECPKI_BUILD_DOMAIN_DOMAIN_PTR_ERROR                        (CC_ECPKI_MODULE_ERROR_BASE + 0x21UL)
+/*! Illegal domain parameter pointer. */
+#define CC_ECPKI_BUILD_DOMAIN_EC_PARAMETR_PTR_ERROR                   (CC_ECPKI_MODULE_ERROR_BASE + 0x22UL)
+/*! Illegal domain parameter size. */
+#define CC_ECPKI_BUILD_DOMAIN_EC_PARAMETR_SIZE_ERROR                  (CC_ECPKI_MODULE_ERROR_BASE + 0x23UL)
+/*! Illegal domain cofactor parameters. */
+#define CC_ECPKI_BUILD_DOMAIN_COFACTOR_PARAMS_ERROR                   (CC_ECPKI_MODULE_ERROR_BASE + 0x24UL)
+/*! Insufficient strength. */
+#define CC_ECPKI_BUILD_DOMAIN_SECURITY_STRENGTH_ERROR                 (CC_ECPKI_MODULE_ERROR_BASE + 0x25UL)
+/*! SCA resistance error. */
+#define CC_ECPKI_BUILD_SCA_RESIST_ILLEGAL_MODE_ERROR                  (CC_ECPKI_MODULE_ERROR_BASE + 0x26UL)
+
+
+/*! Internal error */
+#define CC_ECPKI_INTERNAL_ERROR                                       (CC_ECPKI_MODULE_ERROR_BASE + 0x30UL)
+/************************************************************************************************************
+ * CryptoCell EC DIFFIE-HELLMAN MODULE ERRORS
+*************************************************************************************************************/
+/* The CryptoCell EC SVDP_DH Function errors */
+/*! Illegal partner's public key pointer. */
+#define CC_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR                (CC_ECPKI_MODULE_ERROR_BASE + 0x31UL)
+/*! Partner's public key validation failed. */
+#define CC_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR                  (CC_ECPKI_MODULE_ERROR_BASE + 0x32UL)
+/*! Illegal user private key pointer. */
+#define CC_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR                   (CC_ECPKI_MODULE_ERROR_BASE + 0x33UL)
+/*! Private key validation failed. */
+#define CC_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR                     (CC_ECPKI_MODULE_ERROR_BASE + 0x34UL)
+/*! Illegal shared secret pointer. */
+#define CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR                 (CC_ECPKI_MODULE_ERROR_BASE + 0x35UL)
+/*! Illegal temporary buffer pointer. */
+#define CC_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR                           (CC_ECPKI_MODULE_ERROR_BASE + 0x36UL)
+/*! Illegal shared secret size pointer. */
+#define CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR            (CC_ECPKI_MODULE_ERROR_BASE + 0x37UL)
+/*! Illegal shared secret size. */
+#define CC_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR                (CC_ECPKI_MODULE_ERROR_BASE + 0x38UL)
+/*! Illegal domain ID. */
+#define CC_ECDH_SVDP_DH_ILLEGAL_DOMAIN_ID_ERROR                               (CC_ECPKI_MODULE_ERROR_BASE + 0x39UL)
+/*! Illegal private and public domain ID are different. */
+#define CC_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR             (CC_ECPKI_MODULE_ERROR_BASE + 0x3AUL)
+
+
+/************************************************************************************************************
+ * CryptoCell ECDSA  MODULE ERRORS
+ ************************************************************************************************************/
+/* The CryptoCell ECDSA Signing  errors */
+/*! Illegal domain ID. */
+#define CC_ECDSA_SIGN_INVALID_DOMAIN_ID_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0x50UL)
+/*! Illegal context pointer. */
+#define CC_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR            (CC_ECPKI_MODULE_ERROR_BASE + 0x51UL)
+/*! Illegal private key pointer. */
+#define CC_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0x52UL)
+/*! Illegal hash operation mode. */
+#define CC_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR                (CC_ECPKI_MODULE_ERROR_BASE + 0x53UL)
+/*! Illegal data in pointer. */
+#define CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0x54UL)
+/*! Illegal data in size. */
+#define CC_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x55UL)
+/*! Context validation failed. */
+#define CC_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0x57UL)
+/*! User's private key validation failed. */
+#define CC_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x58UL)
+/*! Illegal signature pointer. */
+#define CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0x60UL)
+/*! Illegal signature size pointer. */
+#define CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR      (CC_ECPKI_MODULE_ERROR_BASE + 0x61UL)
+/*! Illegal signature size. */
+#define CC_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0x62UL)
+/*! Ephemeral key error. */
+#define CC_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR     (CC_ECPKI_MODULE_ERROR_BASE + 0x63UL)
+/*! Illegal ephemeral key pointer. */
+#define CC_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0x64UL)
+/*! Illegal RND context pointer. */
+#define CC_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR             (CC_ECPKI_MODULE_ERROR_BASE + 0x65UL)
+/*! Illegal RND function pointer. */
+#define CC_ECDSA_SIGN_INVALID_RND_FUNCTION_PTR_ERROR            (CC_ECPKI_MODULE_ERROR_BASE + 0x66UL)
+/*! Signature calculation failed. */
+#define CC_ECDSA_SIGN_SIGNING_ERROR                             (CC_ECPKI_MODULE_ERROR_BASE + 0x67UL)
+
+/* The CryptoCell ECDSA Verifying  errors */
+/*! Illegal domain ID. */
+#define CC_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0x70UL)
+/*! Illegal user's context pointer. */
+#define CC_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR      (CC_ECPKI_MODULE_ERROR_BASE + 0x71UL)
+/*! Illegal public key pointer. */
+#define CC_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR       (CC_ECPKI_MODULE_ERROR_BASE + 0x72UL)
+/*! Illegal hash operation mode. */
+#define CC_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR              (CC_ECPKI_MODULE_ERROR_BASE + 0x73UL)
+/*! Illegal signature pointer. */
+#define CC_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0x76UL)
+/*! Illegal signature size. */
+#define CC_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR        (CC_ECPKI_MODULE_ERROR_BASE + 0x77UL)
+/*! Illegal data in pointer. */
+#define CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR       (CC_ECPKI_MODULE_ERROR_BASE + 0x80UL)
+/*! Illegal data in size. */
+#define CC_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR      (CC_ECPKI_MODULE_ERROR_BASE + 0x81UL)
+/*! Context validation failed. */
+#define CC_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR       (CC_ECPKI_MODULE_ERROR_BASE + 0x82UL)
+/*! public key validation failed. */
+#define CC_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR    (CC_ECPKI_MODULE_ERROR_BASE + 0x83UL)
+/*! Verification failed. */
+#define CC_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR               (CC_ECPKI_MODULE_ERROR_BASE + 0x84UL)
+
+
+
+/*! Illegal hash mode. */
+#define CC_ECC_ILLEGAL_HASH_MODE_ERROR                         (CC_ECPKI_MODULE_ERROR_BASE + 0x85UL)
+
+
+/************************************************************************************************************
+ * CryptoCell ECPKI MODULE  COMMON ERRORS
+*************************************************************************************************************/
+/*! Illegal RND function pointer. */
+#define CC_ECPKI_INVALID_RND_FUNC_PTR_ERROR                   (CC_ECPKI_MODULE_ERROR_BASE + 0x90UL)
+/*! Illegal RND context pointer. */
+#define CC_ECPKI_INVALID_RND_CTX_PTR_ERROR                    (CC_ECPKI_MODULE_ERROR_BASE + 0x91UL)
+/*! Illegal domain ID. */
+#define CC_ECPKI_INVALID_DOMAIN_ID_ERROR                      (CC_ECPKI_MODULE_ERROR_BASE + 0x92UL)
+/*! Private key validation failed. */
+#define CC_ECPKI_INVALID_PRIV_KEY_TAG_ERROR                   (CC_ECPKI_MODULE_ERROR_BASE + 0x93UL)
+/*! Public key validation failed. */
+#define CC_ECPKI_INVALID_PUBL_KEY_TAG_ERROR                   (CC_ECPKI_MODULE_ERROR_BASE + 0x94UL)
+/*! Illegal data in. */
+#define CC_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0x95UL)
+/*! Illegal Base point pointer. */
+#define CC_ECPKI_INVALID_BASE_POINT_PTR_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0x96UL)
+
+/************************************************************************************************************
+ * CryptoCell ECIES MODULE ERRORS
+*************************************************************************************************************/
+/*! Illegal public key pointer. */
+#define CC_ECIES_INVALID_PUBL_KEY_PTR_ERROR                     (CC_ECPKI_MODULE_ERROR_BASE + 0xE0UL)
+/*! Public key validation failed. */
+#define CC_ECIES_INVALID_PUBL_KEY_TAG_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0xE1UL)
+/*! Illegal private key pointer. */
+#define CC_ECIES_INVALID_PRIV_KEY_PTR_ERROR                     (CC_ECPKI_MODULE_ERROR_BASE + 0xE2UL)
+/*! Private key validation failed. */
+#define CC_ECIES_INVALID_PRIV_KEY_TAG_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0xE3UL)
+/*! Illegal private key value. */
+#define CC_ECIES_INVALID_PRIV_KEY_VALUE_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0xE4UL)
+/*! Illegal KDF derivation mode. */
+#define CC_ECIES_INVALID_KDF_DERIV_MODE_ERROR               (CC_ECPKI_MODULE_ERROR_BASE + 0xE5UL)
+/*! Illegal KDF hash mode. */
+#define CC_ECIES_INVALID_KDF_HASH_MODE_ERROR            (CC_ECPKI_MODULE_ERROR_BASE + 0xE6UL)
+/*! Illegal secret key pointer. */
+#define CC_ECIES_INVALID_SECRET_KEY_PTR_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0xE7UL)
+/*! Illegal secret key size. */
+#define CC_ECIES_INVALID_SECRET_KEY_SIZE_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0xE8UL)
+/*! Illegal cipher data pointer. */
+#define CC_ECIES_INVALID_CIPHER_DATA_PTR_ERROR          (CC_ECPKI_MODULE_ERROR_BASE + 0xE9UL)
+/*! Illegal cipher data size pointer. */
+#define CC_ECIES_INVALID_CIPHER_DATA_SIZE_PTR_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0xEAUL)
+/*! Illegal cipher data size. */
+#define CC_ECIES_INVALID_CIPHER_DATA_SIZE_ERROR         (CC_ECPKI_MODULE_ERROR_BASE + 0xEBUL)
+/*! Illegal temporary buffer pointer. */
+#define CC_ECIES_INVALID_TEMP_DATA_PTR_ERROR            (CC_ECPKI_MODULE_ERROR_BASE + 0xECUL)
+/*! Illegal temporary buffe size */
+#define CC_ECIES_INVALID_TEMP_DATA_SIZE_ERROR           (CC_ECPKI_MODULE_ERROR_BASE + 0xEDUL)
+/*! Illegal ephemeral key pointer */
+#define CC_ECIES_INVALID_EPHEM_KEY_PAIR_PTR_ERROR               (CC_ECPKI_MODULE_ERROR_BASE + 0xEEUL)
+/*! NULL ptr */
+#define CC_ECIES_INVALID_PTR                                   (CC_ECPKI_MODULE_ERROR_BASE + 0xEFUL)
+
+/************************ Enums ********************************/
+
+/************************ Typedefs  ****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_kg.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_kg.h
new file mode 100644
index 0000000..ede7bb3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_kg.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_ECPKI_KG_H
+#define _CC_ECPKI_KG_H
+
+/*! @file
+@brief This file defines the API for generation of ECC private and public keys.
+@defgroup cc_ecpki_kg CryptoCell ECC Key Generation APIs
+@{
+@ingroup cryptocell_ecpki
+
+*/
+
+
+#include "cc_error.h"
+#include "cc_rnd_common.h"
+#include "cc_ecpki_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*****************  CC_EcpkiKeyPairGenerate function   **********************/
+/*!
+@brief Generates a pair of private and public keys in internal representation according to ANSI X9.62-2005: Public Key Cryptography for the
+Financial Services Industry, The Elliptic Curve Digital Signature Algorithm (ECDSA) standard.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h or cc_rnd_error.h
+*/
+CIMPORT_C CCError_t CC_EcpkiKeyPairGenerate(
+                        CCRndContext_t         *pRndContext,      /*!< [in/out] Pointer to the RND context buffer. */
+                        const CCEcpkiDomain_t  *pDomain,          /*!< [in]  Pointer to EC domain (curve). */
+                        CCEcpkiUserPrivKey_t   *pUserPrivKey,     /*!< [out] Pointer to the private key structure. This structure is used as input to the
+                                         ECPKI cryptographic primitives. */
+                        CCEcpkiUserPublKey_t   *pUserPublKey,     /*!< [out] Pointer to the public key structure. This structure is used as input to the
+                                         ECPKI cryptographic primitives. */
+            CCEcpkiKgTempData_t   *pTempData,        /*!< [in] Temporary buffers for internal use, defined in ::CCEcpkiKgTempData_t. */
+                        CCEcpkiKgFipsContext_t   *pFipsCtx       /*!< [in] Pointer to temporary buffer used in case FIPS certification if required
+                                       (may be NULL for all other cases). */
+);
+
+/*****************  CC_EcpkiKeyPairGenerateBase function   **********************/
+/*!
+@brief Generates a pair of private and public keys using a configurable base point
+in internal representation according to ANSI X9.62-2005: Public Key Cryptography for the
+Financial Services Industry, The Elliptic Curve Digital Signature Algorithm (ECDSA) standard.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ecpki_error.h or cc_rnd_error.h
+*/
+CIMPORT_C CCError_t CC_EcpkiKeyPairGenerateBase(
+                        CCRndContext_t         *pRndContext, /*!< [in/out] Pointer to RND context. */
+                        const CCEcpkiDomain_t  *pDomain,          /*!< [in]  Pointer to EC domain (curve). */
+                        const uint32_t         *ecX_ptr, /*!< [in]  The X cordinate of the base point. */
+                        const uint32_t         *ecY_ptr, /*!< [in]  The Y cordinate of the base point. */
+                        CCEcpkiUserPrivKey_t   *pUserPrivKey,     /*!< [out] Pointer to the private key structure. This structure is used as input to the
+                                         ECPKI cryptographic primitives. */
+                        CCEcpkiUserPublKey_t   *pUserPublKey,     /*!< [out] Pointer to the public key structure. This structure is used as input to the
+                                         ECPKI cryptographic primitives. */
+                        CCEcpkiKgTempData_t    *pTempData,        /*!< [in] Temporary buffers for internal use, defined in ::CCEcpkiKgTempData_t. */
+                        CCEcpkiKgFipsContext_t *pFipsCtx       /*!< [in] Pointer to temporary buffer used in case FIPS certification if required
+                                       (may be NULL for all other cases). */
+);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_types.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_types.h
new file mode 100644
index 0000000..92ad69d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ecpki_types.h
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_ecpki_types
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains all the type definitions that are used for the
+ CryptoCell ECPKI APIs.
+ */
+
+#ifndef _CC_ECPKI_TYPES_H
+#define _CC_ECPKI_TYPES_H
+
+
+#include "cc_bitops.h"
+#include "cc_pal_types_plat.h"
+#include "cc_hash_defs.h"
+#include "cc_pka_defs_hw.h"
+#include "cc_pal_compiler.h"
+#ifdef USE_MBEDTLS_CRYPTOCELL
+#include "mbedtls/md.h"
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+/*! The size of the internal buffer in words. */
+#define CC_PKA_DOMAIN_LLF_BUFF_SIZE_IN_WORDS (10 + 3*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS)
+
+/**************************************************************************************
+ *                Enumerators
+ ***************************************************************************************/
+
+/*------------------------------------------------------------------*/
+/*! @brief EC domain idetifiers.
+
+   For more information, see <em>Standards for Efficient Cryptography Group
+   (SECG): SEC2 Recommended Elliptic Curve Domain Parameters, Version 1.0</em>.
+*/
+typedef enum
+{
+    /* For prime field */
+    /*! EC secp192k1. */
+    CC_ECPKI_DomainID_secp192k1,
+    /*! EC secp192r1. */
+    CC_ECPKI_DomainID_secp192r1,
+    /*! EC secp224k1. */
+    CC_ECPKI_DomainID_secp224k1,
+    /*! EC secp224r1. */
+    CC_ECPKI_DomainID_secp224r1,
+    /*! EC secp256k1. */
+    CC_ECPKI_DomainID_secp256k1,
+    /*! EC secp256r1. */
+    CC_ECPKI_DomainID_secp256r1,
+    /*! EC secp384r1. */
+    CC_ECPKI_DomainID_secp384r1,
+    /*! EC secp521r1. */
+    CC_ECPKI_DomainID_secp521r1,
+    /*! Reserved.*/
+    CC_ECPKI_DomainID_OffMode,
+    /*! Reserved.*/
+    CC_ECPKI_DomainIDLast      = 0x7FFFFFFF,
+
+}CCEcpkiDomainID_t;
+
+
+/*------------------------------------------------------------------*/
+/*!
+  @brief Hash operation mode.
+
+  Defines hash modes according to <em>IEEE 1363-2000: IEEE Standard for
+  Standard Specifications for Public-Key Cryptography</em>.
+ */
+typedef enum
+{
+    /*! The message data will be hashed with SHA-1. */
+    CC_ECPKI_HASH_SHA1_mode    = 0,
+    /*! The message data will be hashed with SHA-224. */
+    CC_ECPKI_HASH_SHA224_mode  = 1,
+    /*! The message data will be hashed with SHA-256. */
+    CC_ECPKI_HASH_SHA256_mode  = 2,
+    /*! The message data will be hashed with SHA-384. */
+    CC_ECPKI_HASH_SHA384_mode  = 3,
+    /*! The message data will be hashed with SHA-512. */
+    CC_ECPKI_HASH_SHA512_mode  = 4,
+    /*! The message data is a digest of SHA-1 and will not be hashed. */
+    CC_ECPKI_AFTER_HASH_SHA1_mode    = 5,
+    /*! The message data is a digest of SHA-224 and will not be hashed. */
+    CC_ECPKI_AFTER_HASH_SHA224_mode  = 6,
+    /*! The message data is a digest of SHA-256 and will not be hashed. */
+    CC_ECPKI_AFTER_HASH_SHA256_mode  = 7,
+    /*! The message data is a digest of SHA-384 and will not be hashed. */
+    CC_ECPKI_AFTER_HASH_SHA384_mode  = 8,
+    /*! The message data is a digest of SHA-512 and will not be hashed. */
+    CC_ECPKI_AFTER_HASH_SHA512_mode  = 9,
+    /*! The maximal number of hash modes. */
+    CC_ECPKI_HASH_NumOfModes,
+    /*! Reserved. */
+    CC_ECPKI_HASH_OpModeLast        = 0x7FFFFFFF,
+
+}CCEcpkiHashOpMode_t;
+
+
+/*---------------------------------------------------*/
+/*! EC point-compression identifiers.
+*/
+typedef enum
+{
+    /*! A compressed point. */
+    CC_EC_PointCompressed     = 2,
+    /*! An uncompressed point. */
+    CC_EC_PointUncompressed   = 4,
+    /*! An incorrect point-control value. */
+    CC_EC_PointContWrong      = 5,
+    /*! A hybrid point. */
+    CC_EC_PointHybrid         = 6,
+    /*! Reserved. */
+    CC_EC_PointCompresOffMode = 8,
+    /*! Reserved. */
+    CC_ECPKI_PointCompressionLast= 0x7FFFFFFF,
+}CCEcpkiPointCompression_t;
+
+/*----------------------------------------------------*/
+/*! EC key checks. */
+typedef enum {
+    /*! Check only preliminary input parameters. */
+    CheckPointersAndSizesOnly = 0,
+    /*! Check preliminary input parameters and verify that the EC public-key
+    point is on the curve. */
+    ECpublKeyPartlyCheck      = 1,
+    /*! Check preliminary input parameters, verify that the EC public-key
+    point is on the curve, and verify that \c EC_GeneratorOrder*PubKey = 0 */
+    ECpublKeyFullCheck        = 2,
+    /*! Reserved. */
+    PublKeyChecingOffMode,
+    /*! Reserved. */
+    EC_PublKeyCheckModeLast  = 0x7FFFFFFF,
+}ECPublKeyCheckMode_t;
+
+/*----------------------------------------------------*/
+/*! SW SCA protection type. */
+typedef enum {
+    /*! SCA protection inactive. */
+    SCAP_Inactive,
+    /*! SCA protection active. */
+    SCAP_Active,
+    /*! Reserved. */
+    SCAP_OFF_MODE,
+    /*! Reserved. */
+    SCAP_LAST = 0x7FFFFFFF
+}CCEcpkiScaProtection_t;
+
+/**************************************************************************************
+ *               EC Domain structure definition
+ ***************************************************************************************/
+
+/*!
+ @brief The structure containing the EC domain parameters in little-endian
+ form.
+
+ EC equation: \c Y^2 = \c X^3 + \c A*X + \c B over prime field \p GFp.
+ */
+typedef  struct {
+    /*! EC modulus: P. */
+    uint32_t    ecP [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! EC equation parameter A. */
+    uint32_t    ecA [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! EC equation parameter B. */
+    uint32_t    ecB [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! Order of generator. */
+    uint32_t    ecR [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    /*! EC cofactor EC_Cofactor_K. The coordinates of the EC base point
+    generator in projective form. */
+    uint32_t    ecGx [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! EC cofactor EC_Cofactor_K. The coordinates of the EC base point
+    generator in projective form. */
+    uint32_t    ecGy [CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! EC cofactor EC_Cofactor_K. The coordinates of the EC base point
+    generator in projective form. */
+    uint32_t    ecH;
+    /*! Specific fields that are used by the low-level functions.*/
+    uint32_t      llfBuff[CC_PKA_DOMAIN_LLF_BUFF_SIZE_IN_WORDS];
+    /*! The size of fields in bits. */
+    uint32_t    modSizeInBits;
+    /*! The size of the order in bits. */
+    uint32_t    ordSizeInBits;
+    /*! The size of each inserted Barret tag in words. Zero if not inserted.*/
+    uint32_t    barrTagSizeInWords;
+    /*! The EC Domain identifier. */
+    CCEcpkiDomainID_t   DomainID;
+    /*! Internal buffer. */
+    int8_t name[20];
+}CCEcpkiDomain_t;
+
+
+
+/**************************************************************************************
+ *               EC  point structures definitions
+ ***************************************************************************************/
+
+/*! The structure containing the EC point in affine coordinates
+   and little endian form. */
+typedef  struct
+{
+    /*! The X coordinate of the point. */
+    uint32_t x[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! The Y coordinate of the point. */
+    uint32_t y[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+
+}CCEcpkiPointAffine_t;
+
+
+/**************************************************************************************
+ *                ECPKI public and private key  Structures
+ ***************************************************************************************/
+
+/* --------------------------------------------------------------------- */
+/* .................. The public key structures definitions ............ */
+/* --------------------------------------------------------------------- */
+
+/*! The structure containing the public key in affine coordinates.*/
+typedef  struct
+{
+    /*! The X coordinate of the public key.*/
+    uint32_t x[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! The Y coordinate of the public key.*/
+    uint32_t y[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS];
+    /*! The EC Domain.*/
+    CCEcpkiDomain_t  domain;
+    /*! The point type.*/
+    uint32_t pointType;
+} CCEcpkiPublKey_t;
+
+
+/*!
+@brief The user structure prototype of the EC public key.
+
+This structure must be saved by the user. It is used as input to ECC functions,
+for example, CC_EcdsaVerify().
+*/
+typedef struct   CCEcpkiUserPublKey_t
+{
+    /*! The validation tag. */
+    uint32_t    valid_tag;
+    /*! The data of the public key. */
+    uint32_t    PublKeyDbBuff[(sizeof(CCEcpkiPublKey_t)+3)/4];
+} CCEcpkiUserPublKey_t;
+
+
+/* --------------------------------------------------------------------- */
+/* .................. The private key structures definitions ........... */
+/* --------------------------------------------------------------------- */
+
+/*! The structure containing the data of the private key. */
+typedef  struct
+{
+    /*! The data of the private key. */
+    uint32_t  PrivKey[CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    /*! The EC domain. */
+    CCEcpkiDomain_t  domain;
+    /*! The SCA protection mode. */
+    CCEcpkiScaProtection_t  scaProtection;
+}CCEcpkiPrivKey_t;
+
+
+/*!
+ @brief The user structure prototype of the EC private key.
+
+ This structure must be saved by the user. It is used as input to ECC functions,
+ for example, CC_EcdsaSign().
+ */
+typedef struct   CCEcpkiUserPrivKey_t
+{
+    /*! The validation tag. */
+    uint32_t    valid_tag;
+    /*! The data of the private key. */
+    uint32_t    PrivKeyDbBuff[(sizeof(CCEcpkiPrivKey_t)+3)/4];
+}  CCEcpkiUserPrivKey_t;
+
+/*! The type of the ECDH temporary data. */
+typedef struct CCEcdhTempData_t
+{
+    /*! Temporary buffers. */
+    uint32_t ccEcdhIntBuff[CC_PKA_ECDH_BUFF_MAX_LENGTH_IN_WORDS];
+}CCEcdhTempData_t;
+
+/*! EC build temporary data. */
+typedef struct CCEcpkiBuildTempData_t
+{
+    /*! Temporary buffers. */
+    uint32_t  ccBuildTmpIntBuff[CC_PKA_ECPKI_BUILD_TMP_BUFF_MAX_LENGTH_IN_WORDS];
+}CCEcpkiBuildTempData_t;
+
+
+
+/**************************************************************************
+ *                CryptoCell ECDSA context structures
+ **************************************************************************/
+
+/* --------------------------------------------------------------------- */
+/*                CryptoCell ECDSA Signing context structure                   */
+/* --------------------------------------------------------------------- */
+/*! The internal buffer used in the signing process. */
+typedef uint32_t CCEcdsaSignIntBuff_t[CC_PKA_ECDSA_SIGN_BUFF_MAX_LENGTH_IN_WORDS];
+
+/*! The context definition for the signing operation. */
+typedef  struct
+{
+    /*! The data of the private key. */
+    CCEcpkiUserPrivKey_t     ECDSA_SignerPrivKey;
+
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    /*! The hash context. */
+    mbedtls_md_context_t     hash_ctx;
+#else
+    /*! The hash context. */
+    CCHashUserContext_t      hashUserCtxBuff;
+#endif
+    /*! The hash result buffer. */
+    CCHashResultBuf_t        hashResult;
+    /*! The size of the hash result in words. */
+    uint32_t                 hashResultSizeWords;
+    /*! The hash mode. */
+    CCEcpkiHashOpMode_t  hashMode;
+    /*! Internal buffer. */
+    CCEcdsaSignIntBuff_t     ecdsaSignIntBuff;
+}EcdsaSignContext_t;
+
+
+/* --------------------------------------------------------------------- */
+/*                ECDSA  Signing User context database              */
+/* --------------------------------------------------------------------- */
+
+/*!
+ @brief The context definition of the user for the signing operation.
+
+ This context saves the state of the operation, and must be saved by the user
+ until the end of the API flow.
+ */
+typedef struct  CCEcdsaSignUserContext_t
+{
+    /*! The data of the signing process. */
+    uint32_t  context_buff [(sizeof(EcdsaSignContext_t)+3)/4];
+    /*! The validation tag. */
+    uint32_t  valid_tag;
+} CCEcdsaSignUserContext_t;
+
+
+
+/****************************************************************************/
+
+/* --------------------------------------------------------------------- */
+/*                ECDSA Verifying context structure                 */
+/* --------------------------------------------------------------------- */
+/*! The internal buffer used in the verification process. */
+typedef uint32_t CCEcdsaVerifyIntBuff_t[CC_PKA_ECDSA_VERIFY_BUFF_MAX_LENGTH_IN_WORDS];
+
+/*! The context definition for verification operation. */
+typedef  struct
+{
+    /*! The data of the public key. */
+    CCEcpkiUserPublKey_t        ECDSA_SignerPublKey;
+
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    /*! The hash context. */
+    mbedtls_md_context_t        hash_ctx;
+#else
+    /*! The hash context. */
+    CCHashUserContext_t         hashUserCtxBuff;
+#endif
+    /*! The hash result. */
+    CCHashResultBuf_t           hashResult;
+    /*! The size of the hash result in words. */
+    uint32_t                    hashResultSizeWords;
+    /*! The hash mode. */
+    CCEcpkiHashOpMode_t         hashMode;
+    /*! Internal buffer. */
+    CCEcdsaVerifyIntBuff_t      ccEcdsaVerIntBuff;
+}EcdsaVerifyContext_t;
+
+
+/* --------------------------------------------------------------------- */
+/*                ECDSA Verifying User context database             */
+/* --------------------------------------------------------------------- */
+/*!
+ @brief The context definition of the user for the verification operation.
+
+ The context saves the state of the operation, and must be saved by the user
+ until the end of the API flow.
+ */
+typedef struct  CCEcdsaVerifyUserContext_t
+{
+    /*! The data of the verification process. */
+    uint32_t    context_buff[(sizeof(EcdsaVerifyContext_t)+3)/4];
+    /*! The validation tag. */
+    uint32_t    valid_tag;
+}CCEcdsaVerifyUserContext_t;
+
+
+/* --------------------------------------------------------------------- */
+/* .................. key generation temp buffer   ........... */
+/* --------------------------------------------------------------------- */
+
+/*! The temporary data type of the ECPKI KG. */
+typedef struct CCEcpkiKgTempData_t
+{
+    /*! Internal buffer. */
+    uint32_t ccKGIntBuff[CC_PKA_KG_BUFF_MAX_LENGTH_IN_WORDS];
+}CCEcpkiKgTempData_t;
+
+/*! The temporary data definition of the ECIES. */
+typedef struct CCEciesTempData_t {
+    /*! The data of the private key. */
+    CCEcpkiUserPrivKey_t   PrivKey;
+    /*! The data of the public key. */
+    CCEcpkiUserPublKey_t   PublKey;
+    /*! The public-key data used by conversion from Mbed TLS to CryptoCell. */
+    CCEcpkiUserPublKey_t   ConvPublKey;
+    /*! Internal buffer. */
+    uint32_t  zz[3*CC_ECPKI_MODUL_MAX_LENGTH_IN_WORDS + 1];
+    /*! Internal buffers. */
+    union {
+        CCEcpkiBuildTempData_t buildTempbuff;
+        CCEcpkiKgTempData_t    KgTempBuff;
+        CCEcdhTempData_t       DhTempBuff;
+    } tmp;
+}CCEciesTempData_t;
+
+
+/* --------------------------------------------------------------------- */
+/* .................. defines for FIPS      ........... */
+/* --------------------------------------------------------------------- */
+
+/*! The order length for FIPS ECC tests. */
+#define CC_ECPKI_FIPS_ORDER_LENGTH (256/CC_BITS_IN_BYTE)  // the order of secp256r1 in bytes
+
+/*! ECPKI data structures for FIPS certification. */
+typedef struct CCEcpkiKgFipsContext_t
+{
+    /*! Signing and verification data. */
+    union {
+        CCEcdsaSignUserContext_t    signCtx;
+        CCEcdsaVerifyUserContext_t  verifyCtx;
+    }operationCtx;
+    /*! Internal buffer. */
+    uint32_t    signBuff[2*CC_ECPKI_ORDER_MAX_LENGTH_IN_WORDS] ;
+}CCEcpkiKgFipsContext_t;
+
+/*! ECDSA KAT data structures for FIPS certification.
+    The ECDSA KAT tests are defined for domain 256r1.     */
+typedef struct CCEcdsaFipsKatContext_t{
+    /*! The key data. */
+    union {
+        /*! The private key data. */
+        struct {
+            CCEcpkiUserPrivKey_t    PrivKey;
+            CCEcdsaSignUserContext_t    signCtx;
+        }userSignData;
+        /*! The public key data. */
+        struct {
+            CCEcpkiUserPublKey_t    PublKey;
+            union {
+                CCEcdsaVerifyUserContext_t  verifyCtx;
+                CCEcpkiBuildTempData_t  tempData;
+            }buildOrVerify;
+        }userVerifyData;
+    }keyContextData;
+    /*! Internal buffer. */
+    uint8_t         signBuff[2*CC_ECPKI_FIPS_ORDER_LENGTH];
+}CCEcdsaFipsKatContext_t;
+
+/*! ECDH KAT data structures for FIPS certification. */
+typedef struct CCEcdhFipsKatContext_t{
+    /*! The public key data. */
+    CCEcpkiUserPublKey_t  pubKey;
+    /*! The private key data. */
+    CCEcpkiUserPrivKey_t  privKey;
+    /*! Internal buffers. */
+    union {
+        CCEcpkiBuildTempData_t  ecpkiTempData;
+        CCEcdhTempData_t      ecdhTempBuff;
+    }tmpData;
+    /*! The buffer for the secret key. */
+    uint8_t secretBuff[CC_ECPKI_FIPS_ORDER_LENGTH];
+}CCEcdhFipsKatContext_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_error.h
new file mode 100644
index 0000000..fc24358
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_error.h
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+/*!
+ @addtogroup cc_error
+ @{
+ */
+
+/*!
+ @file
+ @brief This file defines the error return code types and the numbering spaces
+        for each module of the layers listed.
+*/
+
+
+#ifndef _CC_ERROR_H
+#define _CC_ERROR_H
+
+#include "cc_pal_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! The definitions of the error number-space used for the different modules */
+
+/* ........... Error base numeric mapping definitions ................... */
+/* ----------------------------------------------------------------------- */
+
+ /*! The error base number for CryptoCell. */
+#define CC_ERROR_BASE          0x00F00000UL
+
+/*! The error range number assigned for each layer. */
+#define CC_ERROR_LAYER_RANGE   0x00010000UL
+
+/*! The error range number assigned to each module on its specified layer. */
+#define CC_ERROR_MODULE_RANGE  0x00000100UL
+
+/* Defines the layer index for the error mapping. */
+/*! The CryptoCell error-layer index. */
+#define CC_LAYER_ERROR_IDX     0x00UL
+/*! The error-layer index for low-level functions. */
+#define LLF_LAYER_ERROR_IDX      0x01UL
+/*! The generic error-layer index. */
+#define GENERIC_ERROR_IDX        0x05UL
+
+/* Defines the module index for error mapping */
+/*! The AES error index.*/
+#define AES_ERROR_IDX            0x00UL
+/*! The DES error index.*/
+#define DES_ERROR_IDX            0x01UL
+/*! The hash error index.*/
+#define HASH_ERROR_IDX           0x02UL
+/*! The HMAC error index.*/
+#define HMAC_ERROR_IDX           0x03UL
+/*! The RSA error index.*/
+#define RSA_ERROR_IDX            0x04UL
+/*! The DH error index.*/
+#define DH_ERROR_IDX             0x05UL
+/*! The ECPKI error index.*/
+#define ECPKI_ERROR_IDX          0x08UL
+/*! The RND error index.*/
+#define RND_ERROR_IDX            0x0CUL
+/*! The Common error index.*/
+#define COMMON_ERROR_IDX         0x0DUL
+/*! The KDF error index.*/
+#define KDF_ERROR_IDX            0x11UL
+/*! The HKDF error index.*/
+#define HKDF_ERROR_IDX           0x12UL
+/*! The AESCCM error index.*/
+#define AESCCM_ERROR_IDX         0x15UL
+/*! The FIPS error index.*/
+#define FIPS_ERROR_IDX           0x17UL
+/*! The PKA error index.*/
+
+#define PKA_MODULE_ERROR_IDX     0x21UL
+/*! The ChaCha error index.*/
+#define CHACHA_ERROR_IDX         0x22UL
+/*! The EC Montgomery and Edwards error index.*/
+#define EC_MONT_EDW_ERROR_IDX    0x23UL
+/*! The ChaCha-POLY error index.*/
+#define CHACHA_POLY_ERROR_IDX    0x24UL
+/*! The POLY error index.*/
+#define POLY_ERROR_IDX           0x25UL
+/*! The SRP error index.*/
+#define SRP_ERROR_IDX            0x26UL
+
+
+/*! The AESGCM error index.*/
+#define AESGCM_ERROR_IDX         0x27UL
+
+/*! The AES key-wrap error index.*/
+#define AES_KEYWRAP_ERROR_IDX    0x28UL
+
+/*! Management error index.*/
+#define MNG_ERROR_IDX            0x29UL
+
+/*! Production error index.*/
+#define PROD_ERROR_IDX           0x2AUL
+
+/*! The FFCDH error index. */
+#define FFCDH_ERROR_IDX          0x2BUL
+/*! The FFC domain error index. */
+#define FFC_DOMAIN_ERROR_IDX     0x2CUL
+
+/*! Do not change! Error definition, reserved for Secure Boot ECDSA */
+#define SB_ECC_ERROR_IDX_        0x2DUL
+/*! External DMA error index. */
+#define EXT_DMA_ERROR_IDX        0x2EUL
+
+
+
+/* .......... defining the error spaces for each module on each layer ........... */
+/* ------------------------------------------------------------------------------ */
+
+/*! The error base address of the AES module - 0x00F00000. */
+#define CC_AES_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * AES_ERROR_IDX ) )
+
+/*! The error base address of the DES module - 0x00F00100. */
+#define CC_DES_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * DES_ERROR_IDX ) )
+
+/*! The error base address of the hash module - 0x00F00200. */
+#define CC_HASH_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * HASH_ERROR_IDX ) )
+
+/*! The error base address of the HMAC module - 0x00F00300. */
+#define CC_HMAC_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * HMAC_ERROR_IDX ) )
+
+/*! The error base address of the RSA module - 0x00F00400. */
+#define CC_RSA_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                   (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                   (CC_ERROR_MODULE_RANGE * RSA_ERROR_IDX ) )
+
+/*! The error base address of the DH module - 0x00F00500. */
+#define CC_DH_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                   (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                   (CC_ERROR_MODULE_RANGE * DH_ERROR_IDX ) )
+
+/*! The error base address of the ECPKI module - 0x00F00800. */
+#define CC_ECPKI_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * ECPKI_ERROR_IDX ) )
+
+/*! The error base address of the low-level ECPKI module -  0x00F10800. */
+#define LLF_ECPKI_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * LLF_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * ECPKI_ERROR_IDX ) )
+
+/*! The error base address of the RND module - 0x00F00C00. */
+#define CC_RND_MODULE_ERROR_BASE   (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * RND_ERROR_IDX ) )
+
+/*! The error base address of the low-level RND module -  0x00F10C00. */
+#define LLF_RND_MODULE_ERROR_BASE    (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * LLF_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * RND_ERROR_IDX ) )
+
+/*! The error base address of the common module - 0x00F00D00. */
+#define CC_COMMON_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * COMMON_ERROR_IDX ) )
+
+/*! The error base address of the KDF module - 0x00F01100. */
+#define CC_KDF_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                  (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                  (CC_ERROR_MODULE_RANGE * KDF_ERROR_IDX ) )
+
+/*! The error base address of the HKDF module - 0x00F01100. */
+#define CC_HKDF_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                  (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                  (CC_ERROR_MODULE_RANGE * HKDF_ERROR_IDX ) )
+
+/*! The error base address of the AESCCM module - 0x00F01500. */
+#define CC_AESCCM_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                       (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                       (CC_ERROR_MODULE_RANGE * AESCCM_ERROR_IDX ) )
+
+/*! The error base address of the FIPS module - 0x00F01700. */
+#define CC_FIPS_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                       (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                       (CC_ERROR_MODULE_RANGE * FIPS_ERROR_IDX ) )
+
+/*! The error base address of the PKA module - 0x00F02100. */
+#define PKA_MODULE_ERROR_BASE             (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * PKA_MODULE_ERROR_IDX ) )
+
+/*! The error base address of the ChaCha module - 0x00F02200. */
+#define CC_CHACHA_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * CHACHA_ERROR_IDX ) )
+/*! The error base address of the EC MONT_EDW module - 0x00F02300.  */
+#define CC_EC_MONT_EDW_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * EC_MONT_EDW_ERROR_IDX ) )
+
+/*! The error base address of the Chacha-POLY module - 0x00F02400. */
+#define CC_CHACHA_POLY_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * CHACHA_POLY_ERROR_IDX ) )
+/*! The error base address of the POLY module - 0x00F02500. */
+#define CC_POLY_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * POLY_ERROR_IDX ) )
+
+/*! The error base address of the SRP module - 0x00F02600. */
+#define CC_SRP_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * SRP_ERROR_IDX ) )
+
+/*! The error base address of the AESGCM module - 0x00F02700. */
+#define CC_AESGCM_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                       (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                       (CC_ERROR_MODULE_RANGE * AESGCM_ERROR_IDX ) )
+
+/*! The error base address of the AES key-wrap module - 0x00F02800. */
+#define CC_AES_KEYWRAP_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                          (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                          (CC_ERROR_MODULE_RANGE * AES_KEYWRAP_ERROR_IDX ) )
+
+/*! The error base address of the Management module - 0x00F02900. */
+#define CC_MNG_MODULE_ERROR_BASE      (CC_ERROR_BASE + \
+                        (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                        (CC_ERROR_MODULE_RANGE * MNG_ERROR_IDX ) )
+
+/*! The error base address of the production library - 0x00F02A00 */
+#define CC_PROD_MODULE_ERROR_BASE  (CC_ERROR_BASE + \
+                                     (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                     (CC_ERROR_MODULE_RANGE * PROD_ERROR_IDX ) )
+
+/*! The error base address of the FFCDH module - 0x00F02B00. */
+#define CC_FFCDH_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * FFCDH_ERROR_IDX ) )
+
+/*! The error base address of the FFCDH module - 0x00F02B00. */
+#define CC_FFC_DOMAIN_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * FFC_DOMAIN_ERROR_IDX ) )
+
+/*! The error base address of the External DMA module - 0x00F02B00. */
+#define CC_EXT_DMA_MODULE_ERROR_BASE (CC_ERROR_BASE + \
+                                           (CC_ERROR_LAYER_RANGE * CC_LAYER_ERROR_IDX) + \
+                                           (CC_ERROR_MODULE_RANGE * EXT_DMA_ERROR_IDX ) )
+
+/*! The generic error base address of the user - 0x00F50000 */
+#define GENERIC_ERROR_BASE ( CC_ERROR_BASE + (CC_ERROR_LAYER_RANGE * GENERIC_ERROR_IDX) )
+/*! CryptoCell fatal error. */
+#define CC_FATAL_ERROR          (GENERIC_ERROR_BASE + 0x00UL)
+/*! CryptoCell out of resources error. */
+#define CC_OUT_OF_RESOURCE_ERROR        (GENERIC_ERROR_BASE + 0x01UL)
+/*! CryptoCell illegal resource value error. */
+#define CC_ILLEGAL_RESOURCE_VAL_ERROR       (GENERIC_ERROR_BASE + 0x02UL)
+
+
+
+/* ............ The OK (success) definition ....................... */
+
+/*! A macro that defines the CryptoCell return value. */
+#define CC_CRYPTO_RETURN_ERROR(retCode, retcodeInfo, funcHandler) \
+    ((retCode) == 0 ? CC_OK : funcHandler(retCode, retcodeInfo))
+
+/************************ Enums ********************************/
+
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+
+
+/************************ Public Variables **********************/
+
+
+/************************ Public Functions **********************/
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+@}
+ */
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffc_domain.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffc_domain.h
new file mode 100644
index 0000000..fc8e8b2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffc_domain.h
@@ -0,0 +1,399 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_FFC_DOMAIN_H
+#define _CC_FFC_DOMAIN_H
+
+#include "cc_pka_defs_hw.h"
+#include "cc_pal_types.h"
+#include "cc_pal_compiler.h"
+#include "cc_hash_defs.h"
+#include "cc_rnd_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file defines the API that supports FFC Domain generation domain.
+@defgroup cc_ffcdh_domain CryptoCell FFC Domain Generation APIs
+@{
+@ingroup cc_ffc_domain
+
+*/
+
+/************************ Defines ******************************/
+
+/*! Maximal prime P (modulus) size .*/
+#define CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_BITS    2048  /* 3072 - for FFC DSA FIPS 186-4 sec. 4.2 . */
+#define CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_BYTES   (CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_BITS / CC_BITS_IN_BYTE)
+#define CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_WORDS   (CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_BYTES/CC_32BIT_WORD_SIZE)
+/*! Minimal valid key size in bits.*/
+#define CC_FFC_DOMAIN_MIN_VALID_MOD_SIZE_VALUE_IN_BITS  1024 /*!< Size limitation according the same standard */
+
+/*! Prime P (modulus) buffer size in words.*/
+#define CC_FFC_DOMAIN_MAX_MOD_BUFFER_SIZE_IN_WORDS   (CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_WORDS + 2)
+#define CC_FFC_DOMAIN_MAX_MOD_BUFFER_SIZE_IN_BYTES   (CC_FFC_DOMAIN_MAX_MOD_BUFFER_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE)
+
+/*! Maximal FFC subgroup order size. */
+#define CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_BITS   256
+#define CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_BYTES  (CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_BITS / CC_BITS_IN_BYTE)
+#define CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_WORDS  (CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_BITS / CC_BITS_IN_32BIT_WORD)
+/*!< Maximal size of buffer for generator order (added 2 words for internal using) */
+#define CC_FFC_DOMAIN_MAX_GENER_ORDER_BUFF_SIZE_IN_WORDS (CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_WORDS + 2)
+
+/*! Minimal and maximal sizes of FFC Seed in bytes. */
+#define CC_FFC_DOMAIN_SEED_MIN_SIZE_IN_BYTES    CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES
+#define CC_FFC_DOMAIN_SEED_MAX_SIZE_IN_BYTES    CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES
+/*! Minimal size of FFC seed in bits. */
+#define CC_FFC_DOMAIN_SEED_MIN_SIZE_IN_BITS     (CC_FFC_DOMAIN_SEED_MIN_SIZE_IN_BYTES * 8)
+
+/*! The size of the buffer for User ID */
+//#define CC_FFCDH_USER_ID_SIZE_IN_BYTES  8
+/*! Buffer for Barrett Tag - special value, used in modular multiplication */
+#define CC_FFC_DOMAIN_BARRETT_TAG_MAX_SIZE_IN_WORDS  5
+#define CC_FFC_DOMAIN_BARRETT_TAG_MAX_SIZE_IN_BYTES  (CC_FFC_DOMAIN_BARRETT_TAG_MAX_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE)
+
+
+/* Macros for checking and return errors */
+#define CHECK_ERROR(err)  if((err)) goto End
+#define CHECK_AND_SET_ERROR(expr, errMsg)  if((expr)) {err = (errMsg); goto End;}
+#define CHECK_AND_RETURN_ERROR(expr, errMsg)  if((expr)) {err = (errMsg); return err;}
+
+/* check that ptr != NULL and outSize <= buffSize */
+#define CHECK_PTR_AND_SIZE(pOut, outSize, buffSize) { \
+    if((pOut == NULL) err = CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR; goto End; \
+    if((outSize > buffSize) err = CC_FFCDH_INVALID_ARGUMENT_SIZE_ERROR; goto End; \
+}
+
+/* primality testing definitions */
+#define CC_FFC_PRIME_TEST_MODE CC_DH_PRIME_TEST_MODE
+#define CCFfcPrimeTestMode_t CCRsaDhPrimeTestMode_t
+
+/*!< the DH Domain user validity TAG */
+#define CC_FFC_DOMAIN_VALIDATION_TAG   0xFFCD8000
+
+#define CC_FFC_DOMAIN_TMP_BUFF_SIZE_IN_WORDS  \
+    (5*CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_WORDS + 3*CC_FFC_DOMAIN_MAX_MOD_BUFFER_SIZE_IN_WORDS + 3)
+
+
+/************************ Enums ********************************/
+/*! HASH operation modes. */
+typedef enum
+{
+    CC_FFC_HASH_SHA1_MODE    = 0,
+    CC_FFC_HASH_SHA224_MODE  = 1,
+    CC_FFC_HASH_SHA256_MODE  = 2,
+    CC_FFC_HASH_SHA384_MODE  = 3,
+    CC_FFC_HASH_SHA512_MODE  = 4,
+    CC_FFC_HASH_NUM_OFF_MODE,
+    CC_FFC_HASH_OP_MODE_LAST = 0x7FFFFFFF
+}CCFfcHashOpMode_t;
+
+
+/*! FFC DH Domain validation mode definitions:
+    NIST SP 56A Rev. 2, */
+typedef enum {
+    CC_FFC_DOMAIN_VALIDAT_FULL_MODE,    /*!< full validation */
+    CC_FFC_DOMAIN_TRUSTED_DATA_MODE,    /*!< minimal checking: sizes and pointers;
+                                                   this mode may be used on user's responsibility and
+                                                   only when he obtains full assurance about Domain data */
+        CC_FFC_DOMAIN_VALIDAT_NUM_OFF_MODE, /*!< not allowed value */
+        CC_FFC_DOMAIN_VALIDAT_MODE_LAST = 0x7FFFFFFF
+} CCFfcDomainValidMode_t;
+
+/*! FFC DH Domain parameters sets definition: NIST SP 56A Rev. 2, sec. 5.8.1, tab.6. */
+typedef enum
+{
+    /* domain sets according to SP 800-56A rev.2. */
+        CC_FFC_PARAMS_SET_FA,  /*!< FA - min. parameters sizes and security strength */
+        CC_FFC_PARAMS_SET_FB,  /*!< FB - middle 1 */
+        CC_FFC_PARAMS_SET_FC,  /*!< FC - middle 2 (max.sizes allowed for FFC-DH) */
+        /*!< DSA - added for FFC-DSA allowed sizes according to FIPS 186-4 sec.4.2, */
+        CC_FFC_PARAMS_ADD_SET_DSA, /*!< max sizes (allowed for FFC-DSA, not standard for FFC-DH) */
+        CC_FFC_PARAMS_SET_NUM_OFF_MODE,  /*!< not allowed value */
+        CC_FFC_PARAMS_SET_LAST = 0x7FFFFFFF
+} CCFfcParamSetId_t;
+
+/*! FFC DH Domain parameters sets definition: NIST SP 56A Rev. 2, sec. 5.8.1, tab.6. */
+typedef enum
+{
+    /* domain sets according to SP 800-56A rev.2. */
+        CC_FFC_USE_GIVEN_SEED,    /*!< generate domain from given Seed */
+        CC_FFC_GENERATE_NEW_SEED, /*!< generate new seed and Domain */
+        CC_FFC_SEED_NOT_USED,     /*!< seed not used in appropriate function. */
+        CC_FFC_GEN_SEED_NUM_OFF_MODE,  /*!< not allowed value */
+        CC_FFC_GEN_SEED_NUM_LAST = 0x7FFFFFFF
+} CCFfcGenerateSeed_t;
+
+
+/************************ Typedefs  ****************************/
+
+/* temp buffers, used in different DH KG functions */
+
+/*! Temporary data buffer structure for domain parameters generation in DH. */
+typedef struct CCFfcDomainTmpBuff_t
+{
+    /* The aligned input and output temp buffers */
+    /*! Temporary buffer. */
+    uint32_t TmpBuff[CC_FFC_DOMAIN_TMP_BUFF_SIZE_IN_WORDS];
+}CCFfcDomainTmpBuff_t;
+
+
+/**************************************************************/
+/*! FFC Domain parameters structure (p,q,g,{seed,genCounter}.
+ *  NIST SP 800-56A sec.5.5.1.1. Max. size of structure:
+ *  2*(MaxModSize + MaxOrderSize) + 5w*4 + 40bytes = 636 bytes */
+typedef struct CCFfcDomain_t {
+
+    uint32_t prime[CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_WORDS]; /*!< prime modulus. */
+    uint32_t modLenWords;  /*!< prime modulus size in bytes  */
+    uint32_t genG[CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_WORDS];  /*!< FFC sub-group generator */
+    uint32_t order[CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_WORDS]; /*!< order of FFC sub-group */
+    uint32_t ordLenWords;  /*!< group order size in bytes */
+    uint8_t  seed[CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_BYTES]; /*!< seed for domain generation and validation */
+    uint32_t seedSizeBytes; /*!< seed size in bytes */
+    uint32_t barrettTag[CC_FFC_DOMAIN_BARRETT_TAG_MAX_SIZE_IN_WORDS]; /*!< buffer for Barrett Tag - special value, used in
+                                                                      modular reduction and multiplication. */
+    uint32_t genCounter;             /*!< count of iterations, needed for successful domain generation */
+    CCFfcParamSetId_t ffcParamSetId; /*!< enumerator, defining the set of FFC domain parameters
+                                          according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+    CCFfcHashOpMode_t ffcHashMode;   /*!< enumerator ID of HASH mode, chosen for domain generation.
+                      Note: HASH SHA1 function allowed only for SA set of domain parameters. */
+    uint32_t hashDigestSize;         /*!< size in bytes of HASH digest for chosen mode. */
+    uint32_t hashBlockSize;          /*!< size in bytes of HASH block for chosen mode. */
+    uint32_t indexOfGenerator;       /*!< index, of currently created FFC Generator (allows create different
+                                          Generators for existed prime P, Order Q, and Seed). */
+    uint32_t validTag;  /*!< validation tag.*/
+}CCFfcDomain_t;
+
+#define FFC_DOMAIN_SIZE_BYTES  ((2*CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_WORDS + 2*CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_WORDS + \
+        CC_FFC_DOMAIN_BARRETT_TAG_MAX_SIZE_IN_WORDS + 10) * CC_32BIT_WORD_SIZE)
+
+/***************************************************************************/
+/*!< Set of FFC Domain parameters size approved by NIST SP 800-56A rev.2. tab.6,8
+ *   and FIPS 186-4
+     Intended for initialisation of array of structures of following type.
+     Note: Bit-size of each parameters = 8*ByteSize.
+ */
+typedef struct CCFfcDomainParamSizes_t
+{
+    uint32_t maxSecurStrength;  /*!< Maximum security strength supported, in bytes. */
+    uint32_t primeSize;         /*!< Field (prime P) size in bytes. */
+    uint32_t orderSize;         /*!< Subgroup order Q size in bytes. */
+    uint32_t minHashLen;        /*!< Minimum length of HASH output in bytes. */
+} CCFfcDomainParamSizes_t;
+
+
+/*!< Set of DH FFC parameters sizes, approved by NIST SP 800-56A rev.2: sec. 5.8.1, 5.9.3.
+     Intended for initialization of array of structures of type CCFfcDhFfcDomainParamSizes_t.
+     All sizes are given in bytes (see CCFfcDomainParamSizes_t struct).
+     \note Index of array is given according to CCFfcDhFfcParamsSetId_t enumerator:
+         {CC_FFCDH_PARAMS_SET_FA, CC_FFCDH_PARAMS_SET_FB, CC_FFCDH_PARAMS_SET_FC} = {0,1,2}.
+*/
+#define CC_FFC_DOMAIN_PARAM_SIZES_SET  {{80,1024,160,80},{112,2048,224,112},{112,2048,256,112}}
+/*! Define and init parameters array */
+//CCFfcDomainParamSizes_t ffcDomainParamSizes[(uint32_t)CC_FFC_DOMAIN_PARAMS_SET_NUM_OFF_MODE] = CC_FFC_DOMAIN_PARAM_SIZES_SET;
+
+/*! Array of allowed HASH SHA-x block and digest sizes for all SHA modes (size in bytes).
+   \note Index of array is according to CCFfcDhParamsSetId_t enumerator: {CC_HASH_SHA1_mode, CC_HASH_SHA224_mode, CC_HASH_SHA256_mode,
+   CC_HASH_SHA384_mode, CC_HASH_SHA512_mode} = {0,1,2,3,4}.
+ */
+#define CC_FFC_SHA_PARAMETERS_SIZES_IN_BYTES {{64,20},{64,28},{64,32},{128,48},{128,64}}
+
+/*! Define and initialize HASH parameters array */
+//CCFfcDhHashBlockAndDigestSizes_t DhHashBlockAndDigestSizes[(uint32_t)CC_FFCDH_HASH_NUM_OFF_MODE] =
+//                           CC_FFC_SHA_PARAMETERS_SIZES_IN_BYTES;
+
+//
+///*! Temporary buffer structure . */
+//typedef struct CCFfcDhKgCheckTemp_t
+//{
+//  /*! Temporary buffer. */
+//  uint32_t   checkTempBuff[3*CC_FFC_DOMAIN_MAX_MOD_SIZE_IN_WORDS];
+//  /*! Temporary buffer. */
+//  CCFfcDomainTmpBuff_t    domainBuff;
+//}CCFfcDomainCheckTemp_t;
+
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+/*******************************************************************************************/
+/*!
+@brief This function generates FFC domain parameters according to NIST SP 56A rev.2, referring to FIPS 184-4 standard.
+\par<ol><li>
+<li> The function generates FFC Domain from given Seed and iterations count and sets them into Domain structure.
+If actual count of iterations is not equalled to given value, then the function returns an error. </li>
+<li> The function calculates prime modulus P, subgroup generator G with order Q using Seed and given Generator
+index, allowing to generate different FFC generators with same P and Q, according to SP 56A rev.2 sec.5.5.1.1
+and FIPS 184-4 A.1.1.2, A.2.3. </li>
+<li> The function allows generation domains only for approved set of parameters sizes (SP 56A rev.2 5.5.1.1),
+given by enumerator ID of type CCFfcDhParamSetId_t. </li></ol>
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_ffc_domain_error.h.
+
+*/
+CIMPORT_C CCError_t CC_FfcGenerateDomainFromSeed(
+                CCFfcDomain_t *pDomain,        /*!< [out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,   /*!< [in] random generation function context. */
+                size_t primeSizeBits,          /*!< [in] size of domain's prime modulus in bits (see requirements above). */
+                size_t orderSizeBits,          /*!< [in] size of domain's sub-group order in bits (see requirements above). */
+                uint8_t  *pSeed,               /*!< [in] pointer to the seed for domain generation and validation; */
+                size_t   seedSizeBytes,        /*!< [in] seed size in bytes */
+                uint32_t genCounter,           /*!< [in] exact value of count of main loop iterations, required for generation
+                                     FFC Domain from given Seed. If actual count is not equal to given,
+                                     then the function returns an error. */
+                CCFfcParamSetId_t ffcParamSetId,/*!< [in] enumerator, defining the set of FFC domain parameters
+                                     according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t ffcHashMode, /*!< [in] enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode may be
+                                     used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint8_t generIndex,            /*!< [in] an index of FFC Generator,  allowing to generate different FFC generators with
+                                    the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainTmpBuff_t *pTmpBuff /*!< [in] pointer to FFC Domain temp buffer structure. */
+);
+
+/*******************************************************************************************/
+/*!
+@brief This function generates FFC Domain parameters including new Seed Seed according to
+ NIST SP 56A rev.2 with referring to FIPS 184-4 standard.
+\par<ol><li>
+<li> The function generates a new Seed, calculates FFC Domain parameters and sets them into Domain. </li>
+<li> The function calculates prime modulus P, subgroup generator G with order Q using Seed and given Generator
+index, allowing to generate different FFC generators with same P and Q, according to SP 56A rev.2 sec.5.5.1.1
+and FIPS 184-4 A.1.1.2, A.2.3. </li>
+<li> The function allows generation Domain only for approved set of parameters sizes (SP 56A rev.2 5.5.1.1),
+given by enumerator ID of type CCFfcDhParamSetId_t. </li></ol>
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+ */
+CIMPORT_C CCError_t CC_FfcGenerateDomainAndSeed(
+                CCFfcDomain_t *pDomain,         /*!< [out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,    /*!< [in] random generation function context. */
+                size_t primeSizeBits,           /*!< [in] size of domain's prime modulus in bits (see requirements above). */
+                size_t orderSizeBits,           /*!< [in] size of domain's sub-group order in bits (see requirements above). */
+                size_t seedSizeBytes,           /*!< [in] required size of the seed in bytes; it must be not less than
+                                                     HASH security strength, defined in given ffcParamsSet. */
+                CCFfcParamSetId_t ffcParamSetId,/*!< [in] enumerator, defining the set of FFC domain parameters
+                                                     according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t ffcHashMode,  /*!< [in] enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode may be
+                                                     used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint8_t generIndex,             /*!< [in] an index of FFC Generator, allowing to generate different FFC generators with
+                                                     the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainTmpBuff_t *pTmpBuff  /*!< [in] pointer to FFC Domain temp buffer structure. */
+);
+
+
+/*******************************************************************************************/
+/*!
+@brief The function validates received FFC domain parameters and sets them into Domain structure.
+<ol><li> Validation of performed according to NIST SP 56A rev.2, sec. 5.5.2 and to FIPS 184-4 standard. </li>
+</li> If optional parameters (Seed and pgenCounter) are given, then the function performs full validation by generation
+primes P,Q from the given Seed and compares calculated and received parameters according to the FIPS 184-4, A.1.1.3. </li>
+</li> Generator G is validated according to sec. A.2.3. </li>
+</li> If optional parameters pSeed, seedSize, pgenCounter are zero, and the user explicitly sets validation mode to
+"Trusted Data", then the function performs only checking of pointers, sizes and some relations between parameters. <li>.
+</li> All  input byte-arrays should be set with big endianness order of bytes, i.e. MS Byte is a leftmost one. </li></ol>
+@return CC_OK on success.
+@return A non-zero value on failure, as defined in cc_dh_error.h, cc_rnd_error.h.
+ */
+CIMPORT_C CCError_t CC_FfcValidateAndImportDomain(
+                CCFfcDomain_t *pDomain,          /*!< [out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,     /*!< [in] optional (used on Full Validation mode only), random generation
+                                                           function context. */
+                uint8_t *pPrime,                 /*!< [in] pointer to prime modulus of the finite field (P). */
+                size_t  primeSizeBits,           /*!< [in] prime P size in bits. */
+                uint8_t *pOrder,                 /*!< [in] pointer to the order Q of the generator. */
+                size_t  orderSizeBits,           /*!< [in] order size in bits. */
+                uint8_t *pGenerator,             /*!< [in] pointer to generator G of subgroup of FFC. */
+                size_t  generSizeBytes,          /*!< [in] generator G size in bytes (see note bellow). */
+                uint8_t *pSeed,                  /*!< [in] optional (used on Full Validation mode only), pointer to the Seed,
+                                                           if the Seed is not given, then should be set to NULL. */
+                size_t  seedSizeBytes,           /*!< [in] optional size of Seed in bytes; if Seed not given, then
+                                                      should be set to 0. */
+                CCFfcParamSetId_t ffcParamSetId, /*!< [in] enumerator, defining the set of FFC domain parameters
+                                                      according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t ffcHashMode,   /*!< [in] enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode may be
+                                                      used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint32_t genCounter,             /*!< [in] optional, counter of main iterations loop, performed during
+                                                      domain generation with Seed. */
+                    uint8_t generIndex,          /*!< [in] an index of FFC Generator, allowing to generate different FFC generators with
+                                                          the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainValidMode_t validMode,/*!< [in] enumerator, defining validation mode of of domain parameters:
+                                                     "full" (approved by FIPS standard), "partial"
+                                                      and "trusted" (validated previously); using of both second
+                                                      modes is not approved by standards and is fully on the user
+                                                      responsibility. */
+                CCFfcDomainTmpBuff_t *pTmpBuff   /*!< [in] optional pointer to FFC Domain temp buffer structure. Used only
+                                                       on Full validation mode, on Trusted mode may be set to NULL. */
+);
+
+
+/*******************************************************************************************/
+/*!
+@brief This function extracts FFC domain parameters from Domain structure for external using.
+<ol><li> Assumed, that FFC domain is properly generated by CC_FfcGenerateDomain or other function
+according to the FIPS 184-4, A.1.1.2 standard. </li>
+<li> The function checks input/output pointers and buffers sizes, converts the DH Domain parameters
+to big endianness output arrays (with leading zeros if exists). </li>
+<li> Note: Sizes of parameters are given by pointers, were [in/out] values are: in - buffer size,
+out - actual size. </li></ol>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcExportDomain(
+                CCFfcDomain_t *pDomain,          /*!< [in] pointer to FFC Domain to be exported. */
+                uint8_t *pPrime,                 /*!< [out] pointer to prime modulus of the finite field (P). */
+                size_t  *pPrimeSize,             /*!< [in/out] pointer to prime P size in bytes. */
+                uint8_t *pGenerator,             /*!< [out] pointer to generator of subgroup (G). */
+                size_t  *pGeneratorSize,         /*!< [in/out] pointer to generator G size in bytes. */
+                uint8_t *pOrder,                 /*!< [out] pointer to the order of the generator G. */
+                size_t  *pOrderSize,             /*!< [in/out] pointer to order of generator Q size in bytes. */
+                uint8_t *pSeed,                  /*!< [out] optional, pointer to the Seed, used for Domain generation;
+                                                      if Seed is not required, then the pointer and size should be NULL. */
+                size_t  *pSeedSize,              /*!< [in/out] optional, size of the Seed in bytes - if the Seed not exist,
+                                                      in the Domain, the function sets the size = 0. */
+                CCFfcParamSetId_t *pFfcParamSetId, /*!< [in] pointer to enumerator ID, defining the set of FFC domain parameters
+                                                       parameters according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+                CCFfcHashOpMode_t *pFfcHashMode,  /*!< [in] pointer to enumerator ID of SHAx HASH mode. Note: HASH SHA1 mode
+                                                       may be used only with SA set of domain parameters (sec. 5.8.1, tab.6). */
+                uint32_t *pGenCounter,            /*!< [out] pointer to count of iterations, which were performed
+                                                       during Domain generation. */
+                uint8_t  *pIndexOfGenerator       /*!< pointer to index, of  FFC Generator existed in the Domain. */
+);
+
+
+/*******************************************************************************************/
+/*!
+@brief The function creates a new FFC subgroup Generator for existed FFC Domain.
+<ol><li> Assumed, that FFC domain is properly generated or imported previously and meets
+to the FIPS 184-4, sec. A.1.1.2 standard. </li>
+<li> The function checks input/output pointers and buffers sizes and creates new Generator
+according to sec. A.2.3. and sets it into Domain structure. </li></ol>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcCreateNewGenerator(
+                CCFfcDomain_t *pDomain,        /*!< [in/out] pointer to  FFC Domain structure. */
+                CCRndContext_t *pRndContext,   /*!< [in] random generation function context. */
+                uint8_t index,                 /*!< [in] index allowing to generate some FFC generators with
+                                                    the same FFC parameters prime P and Order Q, existed in the domain. */
+                CCFfcDomainTmpBuff_t *pTmpBuff /*!< [in] pointer to FFC Domain temp buffer structure. */
+);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffc_domain_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffc_domain_error.h
new file mode 100644
index 0000000..b48e276
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffc_domain_error.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_FFC_DOMAIN_ERROR_H
+#define _CC_FFC_DOMAIN_ERROR_H
+
+
+#include "cc_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file contains error codes definitions for CryptoCell FFC_DOMAIN module.
+@defgroup ffccc_dh_error CryptoCell FFC_DOMAIN specific errors
+@{
+@ingroup cc_ffc_domain
+*/
+/************************ Defines ******************************/
+
+/* FFC_DOMAIN module on the CryptoCell layer base address - 0x00F02C00 */
+
+/*! Invalid input pointer.*/
+#define CC_FFC_DOMAIN_INVALID_ARGUMENT_PTR_ERROR        (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x00UL)
+/*! Invalid input size.*/
+#define CC_FFC_DOMAIN_INVALID_ARGUMENT_SIZE_ERROR       (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x01UL)
+/*! A pointer and size of optional parameter not meets one to other: one is zero, but other - not. */
+#define CC_FFC_DOMAIN_INVALID_OPTIONAL_PARAM_ERROR              (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x02UL)
+/*! Invalid pointer to domain structure. */
+#define CC_FFC_DOMAIN_INVALID_DOMAIN_PTR_ERROR                  (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x03UL)
+/*! Invalid pointer to random function Context. */
+#define CC_FFC_DOMAIN_INVALID_RND_CTX_PTR_ERROR                 (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x04UL)
+/*! Invalid pointer to random function inside the Context. */
+#define CC_FFC_DOMAIN_INVALID_RND_FUNCTION_PTR_ERROR            (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x05UL)
+/*! Invalid Domain validation Tag. */
+#define CC_FFC_DOMAIN_VALIDATION_TAG_ERROR                      (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x06UL)
+/*! Invalid enumerator of FFC sizes standard set ID. */
+#define CC_FFC_DOMAIN_INVALID_SIZES_SET_ID_ERROR        (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x07UL)
+/*! Invalid enumerator of hash mode. */
+#define CC_FFC_DOMAIN_INVALID_HASH_MODE_ERROR               (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x08UL)
+/*! Invalid enumerator of seed generation mode. */
+#define CC_FFC_DOMAIN_INVALID_SEED_GENERATION_MODE_ERROR    (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x09UL)
+/*! Invalid enumerator of Domain validation mode. */
+#define CC_FFC_DOMAIN_INVALID_VALIDAT_MODE_ERROR                (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x0AUL)
+/*! Invalid Hash mode: size of Hash too low for required security. */
+#define CC_FFC_DOMAIN_INVALID_LOW_HASH_SIZE_ERROR               (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x0BUL)
+/*! Invalid prime modulus size. */
+#define CC_FFC_DOMAIN_INVALID_PRIME_SIZE_ERROR              (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x10UL)
+/*! Invalid FFC sub-group Order size. */
+#define CC_FFC_DOMAIN_INVALID_ORDER_SIZE_ERROR          (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x11UL)
+/*! Invalid Domain generation Seed pointer. */
+#define CC_FFC_DOMAIN_INVALID_SEED_PTR_ERROR                    (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x12UL)
+/*! Invalid Domain generation Seed size. */
+#define CC_FFC_DOMAIN_INVALID_SEED_SIZE_ERROR           (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x13UL)
+/*! Invalid FFC Domain Prime value. */
+#define CC_FFC_DOMAIN_PRIME_NOT_VALID_ERROR                     (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x14UL)
+/*! Invalid FFC Domain Order value. */
+#define CC_FFC_DOMAIN_ORDER_NOT_VALID_ERROR                 (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x15UL)
+/*! Invalid FFC Domain sub-group Generator. */
+#define CC_FFC_DOMAIN_GENERATOR_NOT_VALID_ERROR                 (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x16UL)
+/*! Invalid FFC Domain generation Counter. */
+#define CC_FFC_DOMAIN_GEN_COUNTER_NOT_VALID_ERROR               (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x17UL)
+/*! Seed is not required by given DH Scheme. */
+#define CC_FFC_DOMAIN_SEED_IS_NOT_REQUIRED_ERROR                (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x18UL)
+/*! Domain generation is failed. */
+#define CC_FFC_DOMAIN_GENERATION_FAILURE_ERROR                  (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0x19UL)
+
+#define CC_FFC_DOMAIN_IS_NOT_SUPPORTED              (CC_FFC_DOMAIN_MODULE_ERROR_BASE + 0xFFUL)
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffcdh.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffcdh.h
new file mode 100644
index 0000000..85139be
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffcdh.h
@@ -0,0 +1,883 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_FFCDH_H
+#define _CC_FFCDH_H
+
+#include "cc_pal_types.h"
+#include "cc_pka_defs_hw.h"
+#include "cc_pal_types.h"
+#include "cc_pal_compiler.h"
+#include "cc_hash_defs.h"
+#include "mbedtls_cc_hkdf.h"
+#include "cc_ffc_domain.h"
+#include "cc_rnd_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*!
+@file
+@brief This file defines the API that supports FFC Diffie-Hellman key exchange, as defined in NIST SP 56A rev.2 standard.
+@defgroup cc_ffcdh CryptoCell FFCDH APIs
+@{
+@ingroup cryptocell_api
+
+*/
+
+
+/************************ Defines ******************************/
+
+/*! Definition for DH public key.*/
+
+/*!< Size limitation according to NIST SP 56A ver.2 standard */
+#define CC_FFCDH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS  2048 /*! Maximal valid key size in bits.*/
+/*! Minimal valid key size in bits.*/
+#define CC_FFCDH_MIN_VALID_KEY_SIZE_VALUE_IN_BITS  1024 /*!< Size limitation according to NSI standard */
+/*! Maximal prime P (modulus) size in bytes.*/
+#define CC_FFCDH_MAX_MOD_SIZE_IN_BYTES   (CC_FFCDH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / CC_BITS_IN_BYTE)
+/*! Maximal prime P (modulus) size in words.*/
+#define CC_FFCDH_MAX_MOD_SIZE_IN_WORDS   (CC_FFCDH_MAX_MOD_SIZE_IN_BYTES / CC_32BIT_WORD_SIZE)
+/*! Prime P (modulus) buffer size in words.*/
+#define CC_FFCDH_MAX_MOD_BUFFER_SIZE_IN_WORDS   (CC_FFCDH_MAX_MOD_SIZE_IN_WORDS + 2)
+#define CC_FFCDH_MAX_MOD_BUFFER_SIZE_IN_BYTES   (CC_FFCDH_MAX_MOD_BUFFER_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE)
+
+/*! Maximal FFC subgroup order size. */
+#define CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BITS   CC_FFC_DOMAIN_MAX_GENER_ORDER_SIZE_IN_BITS
+#define CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BYTES  (CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BITS / CC_BITS_IN_BYTE)
+#define CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_WORDS  (CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BITS / CC_BITS_IN_32BIT_WORD)
+/*!< Maximal size of buffer for Generator order (added 2 words for internal using) */
+#define CC_FFCDH_MAX_GENER_ORDER_BUFF_SIZE_IN_WORDS (CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_WORDS + 2)
+
+/* Size in bytes of Length-counter (used for TLS data transfer etc. in form Len||Data) */
+#define CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES 2
+#define CC_FFCDH_KDF_COUNTER_SIZE_IN_BYTES 4  /* counter used in some KDF functions and concatenated
+                                                 with OtherInfo */
+#define CC_FFCDH_PUBL_KEY_TMP_BUFF_IN_WORDS  CC_FFCDH_MAX_MOD_SIZE_IN_WORDS
+#define CC_FFCDH_PRIV_KEY_TMP_BUFF_IN_WORDS  (CC_FFCDH_MAX_GENER_ORDER_BUFF_SIZE_IN_WORDS)
+
+/*! Number of other info entries */
+#define CC_FFCDH_COUNT_OF_OTHER_INFO_ENTRIES  13
+
+#define CC_FFCDH_MAX_SIZE_OF_ALG_ID_ENTRY_BYTES  32 /*!< Algorithm ID in bytes.*/
+
+/*! Maximal size of supplied Private or Public data entry. */
+#define CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES  64 /*!< Size is in bytes */
+#define CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES  32 /*!< implementation limit, in bytes. */
+
+/*! Size of Nonce for Key Confirmation (if it is used) should be equal to FFC sub-group order size (meets to SP 800-56Arev.2, sec. 5.4) */
+#define CC_FFCDH_MAX_SIZE_OF_NONCE_SUB_ENTRY_BYTES CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BYTES
+#define CC_FFCDH_MAX_SIZE_OF_PUBL_KEY_DATA_BYTES  CC_FFCDH_MAX_MOD_SIZE_IN_BYTES /*!< Party Public Key max. size in bytes. */
+#define CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_OTHER_DATA_BYTES  64 /*!< Party Public Keys Info max. size in bytes.*/
+/*!< Count of concatenated sub-entries of Party (U or V) Info  */
+#define CC_FFCDH_COUNT_OF_PARTY_INFO_ENTRIES 5
+/*! Maximal size of PartyInfo (U or V). Note: Buffers for Nonce and Ephemeral key
+ *  are joined, because only one of them is used actually  */
+#define CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES  (CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES  + 2*CC_FFCDH_MAX_SIZE_OF_PUBL_KEY_DATA_BYTES + \
+        CC_FFCDH_MAX_SIZE_OF_NONCE_SUB_ENTRY_BYTES + CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_OTHER_DATA_BYTES + \
+        CC_FFCDH_COUNT_OF_PARTY_INFO_ENTRIES * CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES)
+
+/*! Maximal size of OtherInfo buffer, including KDF Counter and all entries of actual OtherInfo data */
+#define CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_DATA_BYTES  (CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES + CC_FFCDH_MAX_SIZE_OF_ALG_ID_ENTRY_BYTES + \
+        2 * (CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES + CC_FFCDH_LENGTH_COUNTER_SIZE_IN_BYTES + CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES))
+/*! Extended KDF data buffer: containing: Counter||SharedSecretZZ||OtherInfo */
+#define CC_FFCDH_MAX_SIZE_OF_KDF_DATA_BUFFER_BYTES  (CC_FFCDH_KDF_COUNTER_SIZE_IN_BYTES + 2*CC_FFCDH_MAX_MOD_SIZE_IN_BYTES/*ZZ size*/ + \
+CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_DATA_BYTES)
+#define CC_FFCDH_MAX_SIZE_OF_KDF_DATA_BUFFER_WORDS  (CC_FFCDH_MAX_SIZE_OF_KDF_DATA_BUFFER_BYTES / CC_32BIT_WORD_SIZE)
+
+#define CC_FFCDH_MAX_SIZE_OF_KEYING_MATERIAL_BYTES  1024 /*!< Size is in bytes*/
+
+/*! Maximal size of Confirmation MacData in bytes.
+ * msg_str || IDp || IDr || EphemDataP || EphemDataR {|| TextP}
+ * (Max.size 614 bytes */
+#define CC_FFCDH_SIZE_OF_CONFIRM_MSG_STRING_BYTES      6 /*!< standard confirmation message string size in bytes. */
+#define CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES  32 /*!< party supplied confirmation text size in bytes. */
+#define CC_FFCDH_MAX_SIZE_OF_CONFIRM_MAC_DATA_BYTES  (CC_FFCDH_SIZE_OF_CONFIRM_MSG_STRING_BYTES + 2*(CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES + \
+        CC_FFCDH_MAX_MOD_SIZE_IN_BYTES) + CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES)
+/*! Maximal size of Confirmation MacTag (according max. HASH output size) */
+#define CC_FFCDH_MAX_SIZE_OF_CONFIRM_MAC_TAG_BYTES  CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES
+/*! Minimal size in bytes of Confirmation MacTag (sec 5.9.3, tab.8) */
+#define CC_FFCDH_MIN_SIZE_OF_CONFIRM_MAC_TAG_BYTES  8
+#define CC_FFCDH_MAX_SIZE_OF_HMAC_SALT_BUFF_BYTES   CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES
+
+/*! Constant size in bytes of Confirmation MacTag defined in this implementation;
+ *  note: minimal size according to standards is 6 bytes (112 bit - sec 5.9.3, tab.8) */
+#define CC_FFCDH_SIZE_OF_CONFIRM_MAC_KEY_IN_BYTES  8
+
+/*! The size of the buffer for User ID */
+//#define CC_FFCDH_USER_ID_SIZE_IN_BYTES  8
+/*! Buffer for Barrett Tag - special value, used in modular multiplication */
+#define CC_FFCDH_BARRETT_TAG_MAX_SIZE_IN_WORDS  CC_FFC_DOMAIN_BARRETT_TAG_MAX_SIZE_IN_WORDS
+#define CC_FFCDH_BARRETT_TAG_MAX_SIZE_IN_BYTES  (CC_FFCDH_BARRETT_TAG_MAX_SIZE_IN_WORDS * CC_32BIT_WORD_SIZE)
+
+/*! Size (in 32-bit words) of additional buffer used in random generation of vector
+in range according to FIPS 186-4 sec. B.1.1 */
+#define FFCDH_RND_ADDING_SIZE_WORDS 2
+#define FFCDH_RND_ADDING_SIZE_BYTES (FFCDH_RND_ADDING_SIZE_WORDS * CC_32BIT_WORD_SIZE)
+
+/*! Max. size of DH Context temp buffer in words */
+#define CC_FFCDH_CTX_TMP_BUFF_MAX_SIZE_IN_WORDS  (CC_FFCDH_MAX_MOD_SIZE_IN_WORDS + CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_WORDS)
+/* Size of FFCDH Context internal buffer */
+#define CC_FFCDH_CONTEXT_BUFF_SIZE_IN_BYTES  \
+        ROUNDUP_BYTES_TO_32BIT_WORD((FFC_DOMAIN_SIZE_BYTES + 32/*schemeInfo*/ + CC_FFCDH_MAX_SIZE_OF_HMAC_SALT_BUFF_BYTES + \
+        CC_FFCDH_MAX_SIZE_OF_KEYING_MATERIAL_BYTES + 4*CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_BYTES + 2*CC_FFCDH_MAX_SIZE_OF_PARTY_ID_BYTES + \
+        4*CC_FFCDH_MAX_MOD_SIZE_IN_BYTES + CC_FFCDH_MAX_SIZE_OF_KDF_DATA_BUFFER_BYTES + 2*CC_HASH_RESULT_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE/*MacTags*/ + \
+        84/*dataOffsets*/ + 2*CC_FFCDH_MAX_SIZE_OF_CONFIRM_TEXT_DATA_BYTES + 26*CC_32BIT_WORD_SIZE/*separ.words*/ + \
+        CC_FFCDH_CTX_TMP_BUFF_MAX_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE))
+#define CC_FFCDH_CONTEXT_BUFF_SIZE_IN_WORDS  (CC_FFCDH_CONTEXT_BUFF_SIZE_IN_BYTES / CC_32BIT_WORD_SIZE)
+
+#define CC_FFCDH_CALC_USER_MAC_TAG   FALSE
+#define CC_FFCDH_CALC_PARTN_MAC_TAG  TRUE
+
+/*! Key size used for FIPS tests.*/
+#define CC_FFCDH_FIPS_PRIME_SIZE_VALUE_IN_BITS    2048
+#define CC_FFCDH_FIPS_PRIME_SIZE_VALUE_IN_WORDS   (CC_FFCDH_FIPS_PRIME_SIZE_VALUE_IN_BITS / CC_BITS_IN_32BIT_WORD)
+#define CC_FFCDH_FIPS_ORDER_SIZE_VALUE_IN_WORDS   32
+
+
+
+/************************ Enums ********************************/
+
+/*! Key derivation modes according NIST SP 800-56A ver.2 sec. 5.8.2 with reference to
+ *  SP 800-56C sec. 4, SP 800-108 and RFC 5869. */
+typedef enum
+{
+    CC_FFCDH_KDF_HMAC_RFC5869_MODE,  /*!< extraction-then-expansion KDF(RFC 5869), based on HMAC function;
+                                          note: input salt assumed to be NULL. */
+        CC_FFCDH_KDF_NUM_OFF_MODE, /*!< not allowed value */
+    CC_FFCDH_KDF_MODE_LAST = 0x7FFFFFFF
+} CCFfcDhKdfModeSp56A_t;
+
+
+/*! FFC DH key Agreement Schemes enumeration according to
+    NIST SP 56A Rev. 2, Section 6, tab. 10-12. */
+typedef enum
+{
+    CC_FFCDH_SCHEM_HYBRID1,          /*!< dhHybrid1 C(2e, 2s, FFC DH) */
+    CC_FFCDH_SCHEM_HYBRID_ONE_FLOW,  /*!< dhHybridOneFlow C(1e, 2s, FFC DH) */
+    CC_FFCDH_SCHEM_EPHEM,            /*!< dhEphem C(2e, 0s, FFC DH) */
+    CC_FFCDH_SCHEM_ONE_FLOW,         /*!< dhOneFlow C(1e, 1s, FFC DH) */
+    CC_FFCDH_SCHEM_STATIC,           /*!< dhStatic C(0e, 2s, FFC DH) */
+    CC_FFCDH_SCHEM_NUM_OFF_MODE,     /*!< not allowed value */
+    CC_FFCDH_SCHEM_LAST = 0x7FFFFFFF
+} CCFfcDhSchemeId_t;
+
+/*! An enumeration ID, defining user role in DH Agreement, represented as U, V
+   in NIST SP 56A Rev. 2, Sections 3.1, 5.8.1.2, 5.9.1, 6 */
+typedef enum
+{
+        CC_FFCDH_PARTY_U,             /*!< party U of Key Agreement */
+        CC_FFCDH_PARTY_V,             /*!< party V of Key Agreement */
+        CC_FFCDH_PARTY_NUM_OFF_MODE,  /*!< not allowed value */
+        CC_FFCDH_PARTY_LAST = 0x7FFFFFFF
+} CCFfcDhUserPartyIs_t;
+
+/*! DH Agreement Confirmation mode: which parts is provider or/and receiver.
+  NIST SP 56A Rev. 2, Sections 5.9, 6.1, 6.2, 6.3 */
+typedef enum
+{
+    CC_FFCDH_CONFIRM_U_TO_V,          /*!< only party U provides MacTag to V. */
+    CC_FFCDH_CONFIRM_V_TO_U,          /*!< only party V provides MacTag to U. */
+    CC_FFCDH_CONFIRM_BILATERAL,       /*!< each party provides MacTag to other. */
+    CC_FFCDH_CONFIRM_NOT_USED,        /*!< the confirmation is not performed by the scheme */
+    CC_FFCDH_CONFIRM_NUM_OFF_MODE,    /*!< not allowed value */
+    CC_FFCDH_CONFIRM_MODE_LAST = 0x7FFFFFFF
+}CCFfcDhUserConfirmMode_t;
+
+
+/*! DH key status according to its life time (or purpose): static/ephemeral */
+typedef enum
+{
+    CC_FFCDH_KEY_STATIC,     /*!< static (long term) key  */
+    CC_FFCDH_KEY_EPHEMER,    /*!< ephemeral (one-time) key */
+    CC_FFCDH_KEY_STATUS_NUM_OFF_MODE, /*!< not allowed value */
+    CC_FFCDH_KEY_STATUS_LAST = 0x7FFFFFFF
+} CCFfcDhKeyStatus_t;
+
+
+/*! FFC DH Public Key validation mode definitions :
+    (such enumerator mode should be given for each key separately). */
+typedef enum {
+    CC_FFCDH_KEY_VALIDAT_FULL_MODE,    /*!< full validation (NIST SP 56A Rev. 2) */
+    CC_FFCDH_KEY_VALIDAT_PARTIAL_MODE, /*!< checking of sizes, pointers and ranges;
+                                                this mode may be used on user's responsibility
+                                                when he has assurance about received data */
+        CC_FFCDH_KEY_VALIDAT_NUM_OFF_MODE, /*!< not allowed value */
+        CC_FFCDH_KEY_VALIDAT_MODE_LAST = 0x7FFFFFFF
+} CCFfcDhKeyValidMode_t;
+
+/*! FFC DH both PartyInfo (Public Keys) validation mode definitions (NIST SP 56A Rev. 2).
+    Such enumerator mode might be applied to all existed Public keys, belonging to the party,
+     namely: static and ephemeral keys. If full mode for any existed key is not defined,
+     then it will be validated partially (checking of sizes, pointers and ranges). */
+typedef enum {
+    CC_FFCDH_STAT_KEY_FULL_VALIDAT_MODE,    /*!< full validation of static key only */
+    CC_FFCDH_EPHEM_KEY_FULL_VALIDAT_MODE,   /*!< full validation of ephemeral key only */
+    CC_FFCDH_BOTH_KEYS_FULL_VALIDAT_MODE,   /*!< full validation of both keys */
+    CC_FFCDH_NO_FULL_VALIDAT_MODE,          /*!< only partial validation of existed keys */
+        CC_FFCDH_KEYS_VALIDAT_NUM_OFF_MODE,     /*!< not allowed value */
+        CC_FFCDH_KEYS_VALIDAT_MODE_LAST = 0x7FFFFFFF
+} CCFfcDhPartyInfoValidMode_t;
+
+
+/************************ Structures  ***********************************/
+
+/*! FFC Domain parameters structure (p,q,g,{seed,genCounter}. */
+//#define CCFfcDhDomain_t  CCFfcDomain_t
+
+/*! FFC DH Domain parameters sets definition: NIST SP 56A Rev. 2, sec. 5.8.1, tab.6,
+ *  Note: modulus (prime) size 3072 is not allowed in FFC DH. */
+//#define CCFfcDhParamSetId_t  CCFfcParamSetId_t
+
+/**************************************************************/
+/*! Definition of PartyInfo entry structure.
+The structure (buffer) containing data, which should be supplied, to the key agreement
+by any Party (partyU or partyV) and used for derivation of Shared Secret Keying Data. \par
+The data should be constructed according to concatenation method, described in
+NIST SP 56A rev.2 standard sec. 5.8.1, and the following requirements:
+
+<ul><li> PartyInfo = PartyInfoLen||PartyId||PartyNonce{||PartyOtherData}, where
+each sub-entry is formatted as follows: </li>
+<li> - entries in {} parenthesis are optional. </li>
+<li> - each sub-entry is formatted as length (Len), followed by the data: Len||Data; </li>
+<li> - length (Len) is a 2-bytes big endianness counter; </li>
+<li> - actual length of PartyInfo shall be not great than CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_ENTRY bytes. </li>
+<li> - if any explicitly defined there optionally entry or sub-entry is omitted, then its length
+should be set zero and data is empty string. </li></ul>
+\note Said requirements are mandatory and should be agreed by both parties as a part of Key
+Establishment Agreement protocol.
+*/
+typedef struct CCFfcDhPartyInfo_t{
+        uint8_t data[CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES];
+}CCFfcDhPartyInfo_t;
+
+/**************************************************************/
+/*! Definition of OtherInfo structure.
+This structure containing "other data", shared by both key agreement parties
+and used for derivation of Shared Secret Keying Data. \par
+The data should be constructed according to concatenation method, described in
+NIST SP 56A rev.2 standard sec. 5.8.1, and the following requirements:
+
+<ul><li>  OtherInfo data should be concatenated according to the roles, performed by each
+party in the Key Agreement (partyU or partyV), and include the following entries: </li>
+<li>  AlgorithmId||PartyUInfo||PartyVInfo {||SuppPubInfo}{||SuppPrivInfo}, where each entry
+is formatted as follows: </li>
+<li> - entries in {} parenthesis are optional. </li>
+<li> - each entry could include some sub-entries, which are formatted as length (Len), followed
+by the data of said length: Len||Data; </li>
+<li> - length (Len) of the data is formatted as 2-bytes big endianness counter; </li>
+<li> - numerical parameters, such as size of HMAC-Key etc., are considered as separate sub-entry
+and formatted accordingly;
+<li> - actual length of OtherInfo shall be not great than CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_DATA_BYTES bytes. </li>
+<li> - if any explicitly defined optionally entry or sub-entry is omitted, then its length
+should be zero and data array remained empty. </li></ul>
+<ul><li> Formatting of separate entries is described below (each sub-entry includes Len||Data): </li>
+<li> - AlgorithmId entry includes information how the extracted keying material should be parsed between
+HMAC Key (used for internal calculation of Confirmation MacTag) and between Key for External Algorithm,
+i.e. output SecretKeyingData. This entry also includes ID of algorithms, for which these keys are intended:
+  AlgorithmId = HmacKeySize||InternalAlgorithmId||ExternalAlgorithmKeySize||ExternalAlgorithmId, where
+first two sub-entries will be set by CC functions as array: 0x00||0x02||0x00||0x04||"HMAC" and
+sub-entries, related to ExternalAlgorithm, should be given by the user as input to appropriate CC functions. </li>
+<li> - PartyUInfo and PartyVInfo should be constructed as described in CCFfcDhPartyInfo_t structure. </li>
+<li> - Optional SuppPubInfo and SuppPrivInfo entries and their sub-entries should be defined in the Key
+Agreement protocol. </li></ul>
+\note Said requirements are mandatory and should be agreed by both parties as a part of Key Establishment
+Agreement protocol.
+*/
+typedef struct CCFfcDhOtherInfo_t{
+        uint8_t data[CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_DATA_BYTES/*884 bytes ???*/];
+}CCFfcDhOtherInfo_t;
+
+/**************************************************************/
+/*! Definition of MAC Data structure, containing data, known to both key agreement
+parties and used for key confirmation. \par
+The data should be constructed according to NIST SP 56A rev.2 standard,
+sec. 5.9, 5.9.1.1 and the following requirements:
+<ul><li> MacData should be concatenated according to the role, performed by the user
+in the Key Agreement: is he partyU or partyV and is he confirmation provider (P)
+or recipient (R): </li>
+<li>  MacDataP = messageStringP||IDP||IDR{||EphemDataP}||EphemDataR{||TextP},
+where each entry is formatted as follows: </li>
+<li> - actually, instead letters "P" and "R" must be set "U" or "V" according to parties roles in DH Scheme; </li>
+<li> - EphemData is an EphemeralPublicKey or Nonce, contributed by the party to the Agreement; </li>
+<li> - messageStringP is a 6-byte string, defined in the sec.5.9.1, 5.9.2 according to used DH Scheme; <li>
+<li> - TextP is an optional bit-string about Confirmation, known to both parties; </li>
+<li> - each entry is formatted as length, followed by bytes-array of data: Len||Data; </li>
+<li> - length (Len) of the data is formatted as 2-bytes big endianness counter; </li>
+<li> - if any explicitly defined there optionally sub-entry is omitted, then its length should be
+zero and data array remained empty. </li></ul>
+<li> - total length of MacDataP shall be not great than CC_FFCDH_MAX_SIZE_OF_MAC_DATA bytes. </li></ul>
+\note Confirmation is possible (effective) only if Confirmation Receiver contribute an EphemeralKey or Nonce
+to the Key Agreement.
+\note Said requirements are mandatory and should be agreed by both parties as a part of Key Establishment
+Agreement protocol.
+*/
+typedef struct CCFfcDhConfirmMacData_t{
+        uint32_t sizeInBytes; /*!< actual size of data in the MacData buffer, in bytes */
+        uint8_t macData[CC_FFCDH_MAX_SIZE_OF_CONFIRM_MAC_DATA_BYTES];
+} CCFfcDhConfirmMacData_t;
+
+
+/**************************************************************/
+/*! DH Key Agreement Confirmation MacTag, calculated as HMAC of MacData.
+    See NIST SP 56A rev.2 standard, sec. 5.9. Optionally MacTag may be
+    truncated (sec. 5.9.3) */
+typedef struct CCFfcDhConfirmMacTag_t{
+        uint32_t sizeInBytes;
+        uint8_t macTag[CC_FFCDH_MAX_SIZE_OF_CONFIRM_MAC_TAG_BYTES];
+}CCFfcDhConfirmMacTag_t;
+
+
+typedef struct CCFfcDhHashBlockAndDigestSizes_t{
+        uint32_t blockSizeInBytes;  /*!< HASH function block size in bytes */
+        uint32_t digestSizeInBytes; /*!< HASH function digest (output) size in bytes */
+} CCFfcDhHashBlockAndDigestSizes_t;
+
+
+/**************************************************************/
+/*! The structure containing the FFC DH Public Key parameters. */
+typedef  struct  CCFfcDhPublKey_t
+{
+        size_t   keySizeBits;
+    uint32_t pubKey[CC_FFCDH_MAX_MOD_SIZE_IN_WORDS]; /*!< Public Key .*/
+        CCFfcDhKeyStatus_t status; /*! enumerator, defining the key status according to its lifetime
+                                    or purpose: static/ephemeral/nonce */
+}CCFfcDhPublKey_t;
+
+
+/**************************************************************/
+/*! The FFC DH public key's user structure prototype. This structure must be saved by the user,
+and is used as input to the DH functions (such as ::CC_FfcDhGeneratePubPrv etc.). */
+typedef struct   CCFfcDhUserPubKey_t
+{
+    uint32_t validTag; /*!< Validation tag.*/
+    uint32_t publKeyDbBuff[CALC_32BIT_WORDS_FROM_BYTES(sizeof(CCFfcDhPublKey_t))]; /*!< Public key data. */
+}CCFfcDhUserPubKey_t;
+
+#ifdef FFC_FURTHER_USING
+/**************************************************************/
+/*! The structure containing the FFC DH Public Keys parameters. */
+typedef  struct  CCFfcDhCtxPublKeys_t
+{
+    uint32_t statKeySizeBytes;
+    uint8_t statPublKey[CC_FFCDH_MAX_MOD_SIZE_IN_WORDS];
+    uint32_t ephemKeySizeBytes;
+    uint32_t ephemPublKey[CC_FFCDH_MAX_MOD_SIZE_IN_WORDS];
+        uint32_t nonceSizeBytes;
+        uint32_t userNonce[CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_WORDS];
+}CCFfcDhCtxPublKeys_t;
+
+
+/**************************************************************/
+/*! The structure containing the FFC DH Private Key parameters.
+\note The maximal bit length of private key must be 160, 224 or 256
+according to NIST SP 56A rev.2, sec.5.5.1.1 */
+typedef  struct  CCFfcDhPrivKey_t
+{
+    /*! Private Key exponent.*/
+        size_t   keySizeBits;
+    uint32_t key[CC_FFCDH_MAX_GENER_ORDER_SIZE_IN_WORDS + FFCDH_RND_ADDING_SIZE_BYTES];
+        CCFfcDhKeyStatus_t status; /*! enumerator, defining the key status according to its lifetime
+                                    or purpose: static/ephemeral/nonce */
+}CCFfcDhPrivKey_t;
+
+
+/**************************************************************/
+/*! The FFC DH public key's user structure prototype. This structure must be saved by the user
+as secret, and is used as input to the DH functions (such as ::CC_FfcDhGeneratePubPrv etc.). */
+typedef struct   CCFfcDhUserPrivKey_t
+{
+    uint32_t validTag; /*!< key validation tag. */
+    uint32_t privKeyDbBuff[CALC_32BIT_WORDS_FROM_BYTES(sizeof(CCFfcDhPrivKey_t))]; /*!< Private key data. */
+}CCFfcDhUserPrivKey_t;
+
+
+/**************************************************************/
+/*! The structure defines context temp buffer, used for internal calculations.
+\note The maximal bit length of private key must be 160, 224 or 256
+according to NIST SP 56A rev.2, sec.5.5.1.1 */
+typedef  struct  CCFfcDhCtxTempBuff_t
+{
+    uint32_t key[CC_FFCDH_CTX_TMP_BUFF_MAX_SIZE_IN_WORDS];
+}CCFfcDhCtxTempBuff_t;
+
+#endif
+
+/* temp buffer structure, used for DH functions  */
+typedef struct CCFfcDhTemp_t
+{
+    uint32_t TempBuff[CC_FFCDH_CTX_TMP_BUFF_MAX_SIZE_IN_WORDS];
+} CCFfcDhTemp_t;
+
+
+/* Definition of name of function that translates the FCC Domain and DH Hash modes into
+ * HASH, KDF-Hash modes and gives HASH block and digest sizes (in bytes). Note: the function
+ * sets on output only required parameters, which pointers are not NULL.
+ * */
+#define FfcDhGetHashMode  FfcDomainGetHashMode
+
+/***************************************************************************/
+/*!< Set of DH FFC parameters size approved by NIST SP 800-56A rev.2. tab.6,8
+     Intended for initialisation of array of structures of following type.
+*/
+#define  CCFfcDhDomainParamSizes_t  CCFfcDomainParamSizes_t
+
+/**************************************************************/
+/*! DH Key Agreement user context structure is passed by the user to the DH APIs.
+   The context saves the state of the operations and must be saved by the user
+   till the end of the APIs flow. */
+typedef struct CCFfcDhUserContext_t
+{
+    /*! Validation tag. */
+    uint32_t validTag;
+    /*! Private data context buffer. */
+        uint32_t  contextBuff[CC_FFCDH_CONTEXT_BUFF_SIZE_IN_WORDS];
+//        uint32_t  contextBuff[(sizeof(DhContext_t)+3)/4];
+} CCFfcDhUserContext_t;
+
+
+
+/***************************************************************************/
+/*! Definition of FFC-DH buffer used for FIPS Known Answer Tests. */
+typedef struct
+{
+    /* FFC Domain parameters */
+    uint32_t prime[CC_FFCDH_FIPS_PRIME_SIZE_VALUE_IN_WORDS];     /*!< prime modulus - in KAT used 2048 bit size. */
+        uint32_t generator[CC_FFCDH_FIPS_PRIME_SIZE_VALUE_IN_WORDS]; /*!< FFC sub-group generator */
+        uint32_t order[CC_FFCDH_FIPS_ORDER_SIZE_VALUE_IN_WORDS];     /*!< order of FFC sub-group - in KAT used 256 bit size*/
+        uint32_t privKey[CC_FFCDH_FIPS_ORDER_SIZE_VALUE_IN_WORDS];   /*!< private key */
+        uint32_t pubKey[CC_FFCDH_FIPS_PRIME_SIZE_VALUE_IN_WORDS];    /*!< public key */
+    CCFfcDhTemp_t tmpBuff;                                       /*!< temporary buffer */
+} CCFfcDhFipsKat_t;
+
+
+/************************ Public Variables ******************************/
+/*!< Set of DH FFC parameters sizes, approved by NIST SP 800-56A rev.2: sec. 5.8.1, 5.9.3.
+     Intended for initialization of array of structures of type CCFfcDhFfcDomainParamSizes_t.
+     All sizes are given in bytes.
+     \note Index of array is given according to CCFfcDhFfcParamsSetId_t enumerator:
+         {CC_FFCDH_PARAMS_SET_FA, CC_FFCDH_PARAMS_SET_FB, CC_FFCDH_PARAMS_SET_FC} = {0,1,2}.
+*/
+#define CC_FFCDH_DOMAIN_PARAM_SIZES_SET CC_FFC_DOMAIN_PARAM_SIZES_SET
+//{{80,1024,160,80},{112,2048,224,112},{112,2048,256,112}}
+/*! Define and init parameters array */
+//CCFfcDhDomainParamSizes_t ffcDomainParamSizes[(uint32_t)CC_FFCDH_PARAMS_SET_NUM_OFF_MODE] = FFCDH_DOMAIN_PARAM_SIZES_SET;
+
+/*! Array of allowed HASH SHA-x block and digest sizes for all SHA modes (size in bytes).
+   \note Index of array is according to CCFfcDhParamsSetId_t enumerator: {CC_HASH_SHA1_mode, CC_HASH_SHA224_mode, CC_HASH_SHA256_mode,
+   CC_HASH_SHA384_mode, CC_HASH_SHA512_mode} = {0,1,2,3,4}. */
+#define CC_DH_SHA_PARAMETERS_SIZES_IN_BYTES CC_FFC_SHA_PARAMETERS_SIZES_IN_BYTES
+//{{64,20},{64,28},{64,32},{128,48},{128,64}}
+/*! Define and initialize HASH parameters array */
+//CCFfcDhHashBlockAndDigestSizes_t DhHashBlockAndDigestSizes[(uint32_t)CC_FFCDH_HASH_NUM_OFF_MODE] =
+//                           DH_SHA_PARAMETERS_SIZES_IN_BYTES;
+
+
+/************************ Public Functions ******************************/
+
+/*******************************************************************************************/
+/*! The functions initializes the DH Context structure:
+<li> zeroes context buffers, initializes 3 MS bytes of validation tag by context ID and sets LS byte
+to zero to prepare it for further indications of setting appropriate parts of data into context
+*/
+CIMPORT_C CCError_t  CC_FfcDhInitCtx( CCFfcDhUserContext_t *pDhUserCtx);
+
+
+/*******************************************************************************************/
+/*! The functions destroys (zeroes) the DH Context structure.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+
+*/
+CIMPORT_C CCError_t  CC_FfcDhFreeCtx( CCFfcDhUserContext_t *pDhUserCtx);
+
+
+/*******************************************************************************************/
+/*! The function sets into DH context FFCDH Scheme agreed parameters: SchemeId, User role, Confirmation mode etc.
+\note The context is used in DH Agreement functions, implementing NIST SP 800-56A rev.2 standard.
+\note Assumed, that input FFC Domain is properly generated or imported and validated according to
+NIST SP 800-56A and FIPS 186-4 standards.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CEXPORT_C CCError_t  CC_FfcDhCtxSetSchemeParams(
+                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to context structure, containing all parameters and data,
+                                                                    defining DH Key Agreement Scheme */
+            CCFfcDomain_t *pDomain,           /*!< [in] pointer to DH FFC Domain structure. */
+            uint8_t *pAlgId,                  /*!< [in] pointer to Algorithm ID agreed by both parties and indicates how the derived
+                                                        secret keying material will be parsed and for which algorithms (sec.5.8.1.2).
+                                                        In partial, Algorithm ID should indicate also how much bits are intended for
+                                                        internal confirmation MAC algorithm and how much remaining bits will be
+                                                        returned to the user for external applications/algorithms (the total size should
+                                                        be equal to chosen secretKeyDataSize). */
+            size_t algIdSize,                 /*!< [in] size of Algorithm ID in bytes, should be less than
+                                        CC_FFCDH_MAX_SIZE_OF_ALG_ID_SUB_ENTRY. */
+            size_t secretKeyingDataSize,      /*!< [in] size in bytes of shared secret keying data, which will be extracted and in
+                                                                    the next steps and passed to the user for using in  external algorithm(s).
+                                                                    It is used for calculation of Derived Keying material size =
+                                                                    key size of the used HMAC function + secretKeyingDataSize. */
+                        uint8_t *pUserId,                 /*!< [in] pointer to the user ID - a distinct identifier of the user. */
+                        size_t userIdSize,                /*!< [in] size of the user ID in bytes. */
+                        uint8_t *pPartnId,                /*!< [in] pointer to the partner ID - a distinct identifier of the party. */
+                        size_t partnIdSize,               /*!< [in] size of the partner ID in bytes. */
+                        CCFfcDhUserPartyIs_t userParty,   /*!< [in] enumerator, defining role of the user (function's caller) in the
+                                                                    DH Agreement Scheme: partyU or partyV. */
+            CCFfcDhSchemeId_t dhSchemeId,     /*!< [in] enumerator ID of used FFC DH Key Agreement Scheme, as defined
+                                                in sec. 6, tab. 12. */
+            CCFfcParamSetId_t ffcParamSetId,  /*!< [in] enumerator, defining the set of FFC domain parameters
+                                                                    according to SP 56A rev.2 section 5.5.1.1, tab.1. */
+            CCFfcDhKdfModeSp56A_t kdfMode,    /*!< [in] enumerator ID of used KDF function, based on HASH or HMAC algorithms. In current
+                                                        implementation is allowed only KDF HMAC_RFC5869 mode, according to KDF_HMAC_RFC-5869. */
+                        CCFfcHashOpMode_t ffcHashMode,    /*!< [in] enumerator ID of used SHAXXX HASH mode, supported by the product.
+                                                                    Note: HASH SHA1 function may be used only with SA set of domain parameters
+                                                                    (sec. 5.8.1, tab.6); with other sets the function returns an error. */
+                        CCFfcDhUserConfirmMode_t confirmMode, /*!< enumerator, defining confirmation mode of each party: provider
+                                                                    or/and recipient, according to sec. 5.9. */
+                        uint8_t *pHmacSalt,               /*!< [in] optional, pointer to the Salt, used as key in HMAC-KDF function on appropriate modes.
+                                                                    If HMAC-KDF mode is set, and the pointer and size are zero, then the Salt is
+                                                                    treated as full-zero bytes array of size equalled to block-size of used HMAC function.
+                                                                    If HMAC-KDF mode is HMAC_RFC5869_MODE, then the Salt is treated as HMAC Key.
+                                                                    If only one of parameters (pointer and size) is zero, but other not, then the
+                                                                    function returns an error. */
+                        size_t  hmacSaltSize,             /*!< [in] optional, size of Salt in bytes, should be equalled to the HMAC block size if
+                                                                    salt is used. */
+                        size_t  macTagSize                /*!< [in] optional, size in bytes ofof confirmation MacTag. Should be in range:
+                                                                    [CC_FFCDH_MIN_SIZE_OF_CONFIRM_MAC_TAG_BYTES, CC_FFCDH_MAX_SIZE_OF_CONFIRM_MAC_TAG_BYTES]. */
+);
+
+
+
+/*******************************************************************************************/
+/*!
+@brief The function generates FFC DH key pairs according to DH Scheme and NIST SP 800-56A rev.2 standard:
+<ol><li> - count of required key pairs (one or two is dependent on DH Scheme and user Party (U or V),
+inserted into Context. For each of key pair the function performs the following steps: </li>
+<li> - randomly generates the private key X according to section 5.6.1.1 and FIPS 184-4, B.1.1; </li>
+<li> - the sizes of primes P,Q should be taken from DH FFC sizes set previously inserted into Context;  </li>
+<li> - calculates the associated public key  Y = G^X mod P; </li>
+<li> - sets private and public keys in appropriate place in the Context according to user party (U,V) and keys
+status (static, ephemeral); </li>
+<li> - exports the public key as big endianness order of bytes. </li></ol>
+\note Before calling of this function, DH context should be initialized, DH Scheme parameters and
+DH Domain are inserted by calling appropriate functions, else the function returns an error.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h, cc_rnd_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhGeneratePublPrivKeys(
+                                CCFfcDhUserContext_t *pDhUserCtx,/*!< [in/out] pointer to DH FFC User Context structure. */
+                                CCRndContext_t *pRndContext      /*!< [in] random generation function context. */
+);
+
+/*******************************************************************************************/
+/*!
+@brief This function validates the FFC DH public key according to NIST SP 800-56A rev.2,
+       sec.5.6.2.3.1 and checking mode:
+
+<ul><li> - on "partial" mode - checks the pointers and high/low limits of key value;</li>
+<li> - on "full" mode - checks also that the the key belongs to the FFC subgroup; </li></ul>
+\note Before calling of this function, appropriate FFC Domain parameters should be obtained and validated,
+else the function returns an error.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhValidatePublKey(
+            CCFfcDomain_t *pFfcDomain,         /*!< [in/out] pointer to DH FFC Context structure. */
+            uint8_t *pPublKeyData,             /*!< [in] pointer to given DH FFC public key formatted as big endianness array;
+                                     it should be in range [2, P-2], where P is the Domain Prime P. */
+            size_t publKeyDataSize,            /*!< [in] pointer to public key size, in bytes: should be not great than Prime size. */
+
+            CCFfcDhKeyValidMode_t validatMode, /*!< [in] enumerator ID defining the validation mode:
+                                     CC_FFCDH_CHECK_FULL_MODE - full validation (sec. 5.6.2.3.1);
+                                     CC_FFCDH_CHECK_PARTIAL_MODE - check pointers, sizes and range of values. */
+            uint32_t *pTmpBuff);               /*!< [in] temporary buffer of size not less 2*Prime size. ??? */
+
+
+
+/*******************************************************************************************/
+/*!
+@brief The function checks and sets the FFC DH partner's public key into DH Context
+according to NIST SP 800-56A rev.2 sec.5.6.2.3.1 and checking mode:
+
+<ul><li> - if the key belongs to user's party, then the function returns an error, meaning
+that the user should use other function to import both public and private keys together;</li>.
+<li> - on "partial" mode - checks the pointers and high/low limits of key value;</li>
+<li> - on "full" mode - checks also that the the key belongs to the FFC subgroup; </li>
+<li> - sets the key data into DH Context according to party's role and key status. </li></ul>
+\note Before calling of this function, DH context should be initialized and Scheme and FFC Domain
+parameters are inserted by calling appropriate functions, else the function returns an error.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhValidateAndImportPublKey(
+                                CCFfcDhUserContext_t *pDhUserCtx,  /*!< [in/out] pointer to DH FFC Context structure. */
+                                uint8_t *pPublKeyData,             /*!< [in] pointer to given DH FFC public key or Nonce in big endianness;
+                                                                          it should be in range [2, P-2], where P is the Domain Prime. */
+                                size_t publKeyDataSize,            /*!< [in] public key size, in bytes: should be not great than Domain Prime size. */
+                                CCFfcDhKeyValidMode_t validatMode, /*!< [in] enumerator ID defining the validation mode:
+                                                                           CC_FFCDH_CHECK_FULL_MODE - full validation (sec. 5.6.2.3.1);
+                                                                           CC_FFCDH_CHECK_PARTIAL_MODE - check pointers, sizes and range of values;
+                                                                           Note: for Nonce only size and range checking is performed. */
+                                CCFfcDhKeyStatus_t keyStatus       /*!< [in] enumerator, defining the key status according to its life time
+                                                                          or purpose: static/ephemeral/nonce */
+);
+
+
+
+
+/*******************************************************************************************/
+/*!
+@brief The function checks and sets the FFC DH user's private/public key pair into DH Context
+according to NIST SP 800-56A rev.2 sec.5.6.2.3.1 and checking mode:
+
+<ul><li> - if the key belongs to partner's party, then the function returns an error, meaning
+that the user should use other function to import only public key;</li>.
+<li> - on "partial" mode - checks the pointers and high/low limits of key value;</li>
+<li> - on "full" mode - checks also that the the public key meets to private key; </li>
+<li> - sets the key data into DH Context according to party's role and key status. </li></ul>
+\note Before calling of this function, DH context should be initialized and Scheme and FFC Domain
+parameters are inserted by calling appropriate functions, else the function returns an error.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhValidateAndImportKeyPair(
+                                CCFfcDhUserContext_t *pDhUserCtx,  /*!< [in/out] pointer to DH FFC Context structure. */
+                                uint8_t *pPrivKeyData,             /*!< [in] pointer to given DH FFC private key in big endianness;
+                                                                             it should be in range [1, n-1], where n is the Domain generator order. */
+                                size_t privKeyDataSize,            /*!< [in] private key size, in bytes: should be equaled Domain
+                                                                             generator order size. */
+                                uint8_t *pPublKeyData,             /*!< [in] pointer to given DH FFC public key in big endianness;
+                                                                          it should be in range [2, P-2], where P is the Domain Prime. */
+                                size_t publKeyDataSize,            /*!< [in] public key size, in bytes: should be equaled to Domain Prime size,
+                                                                             including leading zeros. */
+                                CCFfcDhKeyValidMode_t validatMode, /*!< [in] enumerator ID defining the validation mode:
+                                                                             CC_FFCDH_CHECK_FULL_MODE - full validation (sec. 5.6.2.3.1);
+                                                                             CC_FFCDH_CHECK_PARTIAL_MODE - check pointers, sizes and range of values. */
+                                CCFfcDhKeyStatus_t keyStatus       /*!< [in] enumerator, defining the key status according to its life time
+                                                                             or purpose: static/ephemeral/nonce */
+);
+
+/*******************************************************************************************/
+/*!
+@brief This function generates random Nonce, used in appropriate DH Schemes (NIST SP 56A rev.2 sec.5.9, 6).
+<li> The function generates random vector of given size, sets it into DH context according. </li>
+\note Before calling of this function, DH context should be initialized and Scheme parameters and
+DH Domain are inserted by calling appropriate functions, else the function returns an error.
+\note The Nonce should be generated and the function called only if it is required by DH scheme, and
+the Nonce is not inserted previously, else the function returns an error.
+\note The function is used when the user not generates an ephemeral key, but requires key confirmation and
+therefore Nonce generation.
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhGenerateRandomNonce(
+                                CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to DH FFC Context structure. */
+                                CCRndContext_t *pRndContext);     /*!< [in] random generation function context. */
+
+
+
+/*******************************************************************************************/
+/*!
+@brief This function formats the UserInfo according to the user role (PartyU or PartyV) and NIST SP 56A rev.2,
+       sec. 5.8.1.2, 5.8.1.2.1.
+
+<ul><li>  Input and previously inserted data is concatenated as defined in the CCFfcDhPartyInfo_t structure and
+ sets it into the Context:  UserInfo = UserId||UserStatPublKey||UserStatPublKey||UserNonce}{||UserOtherData}, where: </li>
+<li> - UserInfo and each its sub-entry are formatted as length (Len) and then appropriate data: Len||Data,
+where each length is a 2-bytes big endianness counter; </li>
+<li> - If any sub-entry is not used in chosen DH Scheme, than its lengths should be set 0 and the data is empty. </li>
+<li> - total size of PartyInfo, including said lengths, should be not great, than the size of CCDhPartyInfo_t. </li></ul>
+\note Before calling of this function the User should initialize DH Context, insert FFC Domain, DH Scheme parameters and
+all his Private/Public Keys (or Nonce) using appropriate CC functions.
+\note The output from this function will be exported to the other party of the Agreement and vice versa, UserInfo, received
+from other party, will be used as input to DhCtxSetSchemeData() function.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhCreateUserInfo(
+                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to context structure, containing all data,
+                                                               used in DH Key Agreement Scheme. */
+                        uint8_t *pUserOtherData,          /*!< [in] optional, pointer to other data, which the user will
+                                                                    insert in addition to its ID, keys and Nonce. */
+                        size_t userOtherDataSize,         /*!< [in] optional, size of additional data (in bytes), which the
+                                                                    user will include into the UserInfo. */
+                        uint8_t *pUserConfirmText,        /*!< [in] optional, pointer to confirmation Text of the User. */
+                        size_t  userConfirmTextSize,      /*!< [in] optional size of Text data of partyU, in bytes. */
+                        CCFfcDhPartyInfo_t *pUserInfo,    /*!< [out] pointer to the concatenated UserInfo (i.e. PartyU or PartyV Info). */
+                        size_t *pUserInfoSize             /*!< [in/out] pointer to the size of UserInfo, in bytes:
+                                                                in -  given buffer size (should be not less than CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_ENTRY;
+                                                                out - actual size of UserInfo, including length counters */
+);
+
+
+/*******************************************************************************************/
+/*!
+@brief This function checks and sets given "OtherInfo" entries, calculates shared secret value and
+       derives the "secret keying material".
+       The function's implementation meets to NIST SP 56A rev.2 standard requirements.
+\note Before calling of this function, DH Context should be initialized, DH Scheme, Domain parameters and all
+required user's Private, Public keys or nonces are inserted by calling appropriate CC functions.
+<ul><li>  The function sets input data into the Context to form the "OtherInfo" (sec. 5.8.1) according to
+said standard and the implementation requirements:
+<li>  - OtherInfo = AlgorithmId||PartyUInfo||PartyVInfo {||SuppPubInfo}{||SuppPrivInfo}, where each PartyInfo is
+formatted as : </li>
+<li>  - Remark: AlgorithmId includes information about length in bits of derived Keying Material and its
+ parsing between internal using for confirmation HMAC algorithm and output Secret Keying Data
+ and algorithm, which it is intended for. </li>
+<li>  - PartyInfo = PartyId||PartyStatPublKey||PartyEphemKey||PartyNonce{||PartyOtherData}. </li>
+<li>  - for detailed description of "OtherInfo" construction and concatenation its sub-entries, see
+CCFfcDhOtherInfo_t structure definition; </li></ul>
+\note - the function performs the following calculations:
+<ul><li> - calculates shared secret value according to DH Scheme:
+   -  SharedSecretVal = (PublKey1 ^ PrivKey1)  modulo Prime  or
+   -  SharedSecretVal = (PartnPublKey1 ^ UserPrivKey1) || (PartnPublKey2 ^ UserPrivKey2)  modulo Prime; </li>
+<li> - derives the secret keying material of required size from the shared secret value by calling KDF function
+with shared OtherInfo data: DerivedKeyingMaterial = KDF(ZZ, OtherInfo, keyingMaterialSize); </li></ul>
+<ul><li> - If DH Scheme includes Key Confirmation, then the function calculates confirmation HMAC MacTag, which is
+intended to be provided to the partner (sec. 5.2, 5.9, 6); in this case the secret keying material is parsed to MacKey
+of size, equaled to HMAC key size. </li>
+<li> - in our implementation HMAC key size is defined to be equaled to FFC sub-group order (meets to sec.5.9.3). </li>
+<li> - if in the chosen DH Scheme the user is not a Confirmation Provider, then both the pointer and the size of
+appropriate MacTag should be set to NULL. </li>
+<li>  - for detailed description of Confirmation "MacData" see CCFfcDhConfirmMacData_t structure definition. </li></ul>
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_dh_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhSetAndCalculateSchemeData(
+                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in/out] pointer to context structure, containing all data, used in DH Key
+                                                                Agreement Scheme, required for implementation of said standard. */
+                        /*! Partner's Data to be included into OtherInfo entry. Detailed description see in CCFfcDhOtherInfo_t. */
+                        uint8_t *pPartnerInfo,            /*!< [in] pointer to the concatenated PartnerInfo. Detailed description see in CCFfcDhOtherInfo_t. */
+                        size_t sizeOfPartnerInfo,         /*!< [in] size of PartnerInfo, in bytes, should be <= CC_FFCDH_MAX_SIZE_OF_PARTY_INFO_BYTES. */
+                        CCFfcDhPartyInfoValidMode_t partnInfoValidMode, /*!< enumerator, defining which of public keys (static, ephemeral),
+                                                                included in the PartnerInfo, should be full validated and which partial only. */
+                        uint8_t *pSuppPubInfo,            /*!< [in] pointer to optional shared public data to be included into SuppPubInfo entry */
+                        size_t suppPubInfoSize,           /*!< [in] size of SuppPubInfo data, in bytes. */
+                        uint8_t *pSuppPrivInfo,           /*!< [in] pointer to optional shared private data to be included into SuppPrivInfo entry */
+                        size_t suppPrivInfoSize,          /*!< [in] size of other SuppPrivInfo data, in bytes (should be not great than
+                                                                    CC_FFCDH_MAX_SIZE_OF_OTHER_INFO_SUPPL_ENTRY_BYTES */
+                        uint8_t *pUserMacTag,             /*!< [out] optional, pointer to the user-provider confirmation MacTag depending
+                                                                   on used Key Agreement Scheme. The tag is calculated by HMAC with given
+                                                                   hashMode, as described in SP800-56A sec. 5.9. */
+                        size_t  macTagSize                /*!< [in] optional, required size in bytes of confirmation MacTag. */
+);
+
+
+///******************************************************************************************/
+///*!
+//@brief The function calculates user's confirmation MacTags for FFC DH Schemes according to NIST SP 56A rev.2 standard.
+//
+//\note Before calling of this function the user should obtain assurance of used FFC Domain and public, private keys,
+//involved in the key agreement, using one of the methods, described in sec. 5.6.2 of above named standard.
+//<ul><li> - depending on DH Scheme, calculates confirmation HMAC MacTag, which is intended to be provided to the partner
+//(sec. 5.2, 5.9, 6); in this case the secret keying material is parsed to MacKey of size, equaled to HMAC key size. </li>
+//<li> - in our implementation HMAC key size defined equal to FFC sub-group order (meets to sec.5.9.3). </li>
+//<li> - if in the chosen DH Scheme the user is not Confirmation provider, then both the pointer and the size of
+//appropriate MacTag should be set to NULL. </li>
+//<li>  - for detailed description of Confirmation "MacData" see CCFfcDhConfirmMacData_t structure definition. </li></ul>
+//
+//@return CC_OK on success.
+//@return A non-zero value on failure as defined in cc_dh_error.h, cc_kdf_error.h or cc_hash_error.h.
+//*/
+//CIMPORT_C CCError_t CC_FfcDhCalcConfirmMacTags(
+//                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in] pointer to the user's DH context structure, containing all data, defining
+//                                                                   DH Key Agreement Scheme. The context shall be initialized for user's roles
+//                                                                   (U or V; Provider or Receiver) using CC_FfcDhSetCtx function. */
+//                        uint8_t *pUserMacTag,             /*!< [out] optional, pointer to the user (provider) confirmation MacTag depending
+//                                                                   on used Key Agreement Scheme. The tag is calculated by HMAC with given
+//                                                                   hashMode, as described in section 5.9. */
+//                        size_t *pMacTagSize,              /*!< [in/out] optional, required size of MacTag, in bytes; maximal allowed size is the
+//                                                                   HMAC output size; minimal size is 8 bytes according to tab. 8 of said standard. */
+//                        uint8_t *pUserConfirmText,        /*!< [in] optional, pointer to confirmation Text of the User. */
+//                        uint8_t  userConfirmTextSize,     /*!< [in] optional size of Text data of partyU, in bytes. */
+//                        uint8_t *pPartnerConfirmText,     /*!< [in] optional, pointer to confirmation Text of the Partner. */
+//                        uint8_t  partnerConfirmTextSize   /*!< [in] optional, size of Text data of partyV, in bytes. */
+//);
+
+
+/*******************************************************************************************/
+/*!
+@brief This function performs DH Key Agreement Confirmation and, on success, outputs the shared keying data.
+The function calculates expected partner's confirmation MacTag' and compares it to value,
+received from the partner.
+<li> If the tags are not equaled, then the function returns an error and zeroes the secure
+sensitive data. </li>
+<li> If no errors, the function puts the derived secret keying data into output buffer. </li>
+\note Assumed, that the user yet have obtained assurance of public and private keys,
+involved in the key agreement.
+\note Before calling this function the user should perform all required DH Key Agreement
+operations, including calculation of shared secret keying material by calling
+CC_FfcDhCalcUserConfirmMacTag function.
+\note If according to chosen Scheme the user is not a Confirmation Recipient,
+then all, the pointer and the size of MacTag should be
+set to zero, else the function returns an error.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined in cc_dh_error.h
+*/
+CIMPORT_C CCError_t CC_FfcDhGetSharedSecretKeyingData(
+                        CCFfcDhUserContext_t *pDhUserCtx, /*!< [in] pointer to the user's DH context structure, containing all data,
+                                                               defining DH Key Agreement Scheme and its results.  */
+                        uint8_t *pSecretKeyData,          /*!< [out] pointer to the shared secret keying data, extracted
+                                                                from keying material after parsing to . */
+                        size_t  *pSecretKeyDataSize,      /*!< [in/out] the pointer to the size of shared secret key data:
+                                                               in - size of the given output buffer, out - actual size of extracted
+                                                               key data */
+                        uint8_t *pPartnerMacTag,          /*!< [in] optional, pointer to the confirmation MacTag, provided by the partner */
+                        size_t macTagSize                 /*!< [in] optional, size of partner's MacTag, in bytes */
+);
+
+
+
+/*******************************************************************************************/
+/*!
+@brief This function implements FFC DH primitive according to section 5.7.1.1 of NIST SP 56A rev.2 standard.
+       The function computes the shared secret value:  SharedSecretVal = partnerPublKey ^ userPrivKey modulo Prime.
+\note Before calling of this function the user should obtain assurance of FFC Domain, public and private keys, involved in the key
+agreement, using one of methods, described in section 5.6.2 of above named standard.
+\note For assurance of keys validity the user can use appropriate APIs for generating or building and validation,
+of keys, described in cc_ffcdh.h file.
+\note The function intended of-first for internal using in Keying Material derivation inside CC DH functions.
+@return CC_OK on success.
+@return A non-zero value on failure as defined in cc_dh_error.h or cc_rnd_error.h.
+*/
+CIMPORT_C CCError_t CC_FfcDhGetSharedSecretVal(
+            CCFfcDomain_t *pDomain,         /*!< [in/out] pointer to DH FFC Context structure. */
+                        uint8_t *pSharedSecretVal,      /*!< [out] pointer to the shared secret value in big endianness order
+                                                                  of bytes in the array (MS-byte is a most left one). This
+                                                                  buffer should be at least of prime (modulus) size in bytes. */
+                        size_t *pSharedSecretValSize,   /*!< [in/out] pointer to the shared secret value size:
+                                                                  input - size of the given buffer, it should be at least
+                                                                  prime (modulus) size bytes; output - actual size. */
+                        uint8_t *pPrivKeyData,          /*!< [in] pointer to given DH FFC private key in big endianness;
+                                                                  the Key should be in range [1, n-1], where n is the Domain
+                                                                  generator order. */
+                        size_t privKeyDataSize,         /*!< [in] private key size, in bytes: should be not great than Domain
+                                                                  generator order size. */
+                        uint8_t *pPublKeyData,          /*!< [in] pointer to given DH FFC public key in big endianness;
+                                                                  the key should be in range [2, P-2], where P is the Domain Prime. */
+                        size_t publKeyDataSize,         /*!< [in] public key size, in bytes: should be not great than Domain Prime size. */
+                        uint32_t *pTmpBuff              /*!< [in] pointer to temp buffer of size */
+);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffcdh_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffcdh_error.h
new file mode 100644
index 0000000..c7ea678
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_ffcdh_error.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_FFCDH_ERROR_H
+#define _CC_FFCDH_ERROR_H
+
+
+#include "cc_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file contains error codes definitions for CryptoCell FFCDH module.
+@defgroup ffccc_dh_error CryptoCell FFCDH specific errors
+@{
+@ingroup cc_ffcdh
+*/
+/************************ Defines ******************************/
+
+/* FFCDH module on the CryptoCell layer base address - 0x00F02700 */
+
+/*! The CryptoCell FFCDH module errors */
+
+/*! Invalid input argument pointer. */
+#define CC_FFCDH_INVALID_ARGUMENT_POINTER_ERROR         (CC_FFCDH_MODULE_ERROR_BASE + 0x00UL)
+/*! Invalid input argument size. */
+#define CC_FFCDH_INVALID_ARGUMENT_SIZE_ERROR            (CC_FFCDH_MODULE_ERROR_BASE + 0x01UL)
+/*! Invalid pointer to DH Context structure. */
+#define CC_FFCDH_INVALID_CONTEXT_PTR_ERROR          (CC_FFCDH_MODULE_ERROR_BASE + 0x02UL)
+/*! Invalid DH Context validation Tag.*/
+#define CC_FFCDH_CONTEXT_VALIDATION_TAG_ERROR                   (CC_FFCDH_MODULE_ERROR_BASE + 0x03UL)
+/*! Invalid FFCDH Scheme ID. */
+#define CC_FFCDH_INVALID_SCHEM_ID_ERROR                         (CC_FFCDH_MODULE_ERROR_BASE + 0x04UL)
+/*! Invalid FFCDH parameters set ID. */
+#define CC_FFCDH_INVALID_DOMAIN_SIZES_SET_ID_ERROR      (CC_FFCDH_MODULE_ERROR_BASE + 0x05UL)
+/*! Invalid FFCDH Key confirmation mode. */
+#define CC_FFCDH_INVALID_CONFIRM_MODE_ERROR             (CC_FFCDH_MODULE_ERROR_BASE + 0x06UL)
+/*! Invalid FFCDH User party ID. */
+#define CC_FFCDH_INVALID_USER_PARTY_ID_ERROR                    (CC_FFCDH_MODULE_ERROR_BASE + 0x07UL)
+/*! Invalid FFCDH key derivation function mode. */
+#define CC_FFCDH_INVALID_KDF_MODE_ERROR                         (CC_FFCDH_MODULE_ERROR_BASE + 0x08UL)
+/*! Invalid FFCDH Key validation mode. */
+#define CC_FFCDH_INVALID_VALIDAT_MODE_ERROR                     (CC_FFCDH_MODULE_ERROR_BASE + 0x09UL)
+/*! Invalid HASH operation mode.*/
+#define CC_FFCDH_INVALID_HASH_MODE_ERROR                (CC_FFCDH_MODULE_ERROR_BASE + 0x0AUL)
+/*! Invalid HASH operation digest size is too low.*/
+#define CC_FFCDH_INVALID_LOW_HASH_SIZE_ERROR                    (CC_FFCDH_MODULE_ERROR_BASE + 0x0BUL)
+/*! Invalid HMAC result size is too low.*/
+#define CC_FFCDH_INVALID_HMAC_SALT_PARAMS_ERROR             (CC_FFCDH_MODULE_ERROR_BASE + 0x0CUL)
+/*! Invalid private key size. */
+#define CC_FFCDH_INVALID_PRIVATE_KEY_SIZE_ERROR                 (CC_FFCDH_MODULE_ERROR_BASE + 0x10UL)
+/*! Invalid private key value. */
+#define CC_FFCDH_INVALID_PRIVATE_KEY_VALUE_ERROR                (CC_FFCDH_MODULE_ERROR_BASE + 0x11UL)
+/*! Invalid public key size. */
+#define CC_FFCDH_INVALID_PUBLIC_KEY_SIZE_ERROR                  (CC_FFCDH_MODULE_ERROR_BASE + 0x12UL)
+/*! Invalid public key value. */
+#define CC_FFCDH_INVALID_PUBLIC_KEY_VALUE_ERROR                 (CC_FFCDH_MODULE_ERROR_BASE + 0x13UL)
+/*! Invalid key status mode: static or ephemeral. */
+#define CC_FFCDH_INVALID_KEY_STATUS_ERROR           (CC_FFCDH_MODULE_ERROR_BASE + 0x14UL)
+/*! Invalid rewriting of previously inserted parameter. */
+#define CC_FFCDH_ILLEGAL_TRY_REWRITE_PARAM_ERROR                (CC_FFCDH_MODULE_ERROR_BASE + 0x15UL)
+/*! Invalid optional data parameters (pointer, size). */
+#define CC_FFCDH_OPTIONAL_DATA_ERROR                            (CC_FFCDH_MODULE_ERROR_BASE + 0x16UL)
+/*! Invalid parameters of Algorithm ID data  (pointer, size). */
+#define CC_FFCDH_ALGORITHM_ID_ERROR                             (CC_FFCDH_MODULE_ERROR_BASE + 0x17UL)
+/*! Invalid size of any Party Info entry (too great). */
+#define CC_FFCDH_PARTY_INFO_SUB_ENTRY_SIZE_ERROR                (CC_FFCDH_MODULE_ERROR_BASE + 0x18UL)
+/*! The User tries to pass Nonce, not required by DH Scheme. */
+#define CC_FFCDH_NONCE_IS_NOT_REQUIRED_ERROR                    (CC_FFCDH_MODULE_ERROR_BASE + 0x19UL)
+/*! The User tries to pass some Key, not required by DH Scheme. */
+#define CC_FFCDH_THE_KEY_IS_NOT_REQUIRED_ERROR                  (CC_FFCDH_MODULE_ERROR_BASE + 0x1AUL)
+/*! The output buffer is too low */
+#define CC_FFCDH_LOW_OUTPUT_BUFF_SIZE_ERROR                     (CC_FFCDH_MODULE_ERROR_BASE + 0x1BUL)
+/*! Invalid size of Partner Info entry. */
+#define CC_FFCDH_PARTN_INFO_PARSING_SIZE_ERROR                  (CC_FFCDH_MODULE_ERROR_BASE + 0x20UL)
+/*! Error on parsing and comparing of Partner Info data . */
+#define CC_FFCDH_PARTN_INFO_PARSING_DATA_ERROR                  (CC_FFCDH_MODULE_ERROR_BASE + 0x21UL)
+/*! Invalid output pointer to Keying Data. */
+#define CC_FFCDH_KEYING_DATA_PTR_INVALID_ERROR          (CC_FFCDH_MODULE_ERROR_BASE + 0x22UL)
+/*! Invalid pointer to Keying Data size. */
+#define CC_FFCDH_KEYING_DATA_SIZE_PTR_INVALID_ERROR     (CC_FFCDH_MODULE_ERROR_BASE + 0x23UL)
+/*! Invalid size of output Keying Data buffer given by the user. */
+#define CC_FFCDH_KEYING_DATA_SIZE_INVALID_ERROR         (CC_FFCDH_MODULE_ERROR_BASE + 0x24UL)
+/*! Invalid pointer to MacTag output buffer. */
+#define CC_FFCDH_MAC_TAG_PTR_INVALID_ERROR          (CC_FFCDH_MODULE_ERROR_BASE + 0x25UL)
+/*! Invalid size of MacTag output buffer. */
+#define CC_FFCDH_MAC_TAG_SIZE_INVALID_ERROR         (CC_FFCDH_MODULE_ERROR_BASE + 0x26UL)
+/*! Calculated MacTag not matches to value, provided by the partner. */
+#define CC_FFCDH_MAC_TAG_DATA_INVALID_ERROR         (CC_FFCDH_MODULE_ERROR_BASE + 0x27UL)
+/* Invalid FFC DH Domain pointer. */
+#define CC_FFCDH_INVALID_DOMAIN_PTR_ERROR                       (CC_FFCDH_MODULE_ERROR_BASE + 0x30UL)
+/*! Invalid validation Tag of user passed FFC Domain. */
+#define CC_FFCDH_INVALID_DOMAIN_VALIDAT_TAG_ERROR               (CC_FFCDH_MODULE_ERROR_BASE + 0x31UL)
+/*! FFC Domain parameters not meet to required by input FFC sizes set ID or HASH mode. */
+#define CC_FFCDH_INVALID_DOMAIN_DATA_ERROR                      (CC_FFCDH_MODULE_ERROR_BASE + 0x32UL)
+/*! Invalid pointer to FFC DH Shared Secret Value. */
+#define CC_FFCDH_INVALID_SHARED_SECR_VAL_PTR_ERROR              (CC_FFCDH_MODULE_ERROR_BASE + 0x33UL)
+/*! Invalid private key data  pointer. */
+#define CC_FFCDH_INVALID_PRIV_KEY_PTR_ERROR                     (CC_FFCDH_MODULE_ERROR_BASE + 0x34UL)
+/*! invalid public key size. */
+#define CC_FFCDH_INVALID_PUBL_KEY_PTR_ERROR                     (CC_FFCDH_MODULE_ERROR_BASE + 0x35UL)
+
+/*! FFC DH is not supported */
+#define CC_FFCDH_IS_NOT_SUPPORTED               (CC_FFCDH_MODULE_ERROR_BASE + 0xFFUL)
+
+
+/************************ Enums ********************************/
+
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+
+
+/************************ Public Variables **********************/
+
+
+/************************ Public Functions **********************/
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_hash_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_hash_defs.h
new file mode 100644
index 0000000..9a4e4c7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_hash_defs.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*!
+ @addtogroup cc_hash_defs
+ @{
+*/
+
+/*!
+ @file
+ @brief This file contains definitions of the CryptoCell hash APIs.
+ */
+
+#ifndef CC_HASH_DEFS_H
+#define CC_HASH_DEFS_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "cc_error.h"
+#include "cc_hash_defs_proj.h"
+
+/************************ Defines ******************************/
+
+/*! The size of the hash result in words. The maximal size for SHA-512 is
+512 bits. */
+#define CC_HASH_RESULT_SIZE_IN_WORDS    16
+
+/*! The size of the MD5 digest result in bytes. */
+#define CC_HASH_MD5_DIGEST_SIZE_IN_BYTES 16
+
+/*! The size of the MD5 digest result in words. */
+#define CC_HASH_MD5_DIGEST_SIZE_IN_WORDS 4
+
+/*! The size of the SHA-1 digest result in bytes. */
+#define CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES 20
+
+/*! The size of the SHA-1 digest result in words. */
+#define CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS 5
+
+/*! The size of the SHA-224 digest result in words. */
+#define CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS 7
+
+/*! The size of the SHA-256 digest result in words. */
+#define CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS 8
+
+/*! The size of the SHA-384 digest result in words. */
+#define CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS 12
+
+/*! The size of the SHA-512 digest result in words. */
+#define CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS 16
+
+/*! The size of the SHA-256 digest result in bytes. */
+#define CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES 28
+
+/*! The size of the SHA-256 digest result in bytes. */
+#define CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES 32
+
+/*! The size of the SHA-384 digest result in bytes. */
+#define CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES 48
+
+/*! The size of the SHA-512 digest result in bytes. */
+#define CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES 64
+
+/*! The size of the SHA-1 hash block in words. */
+#define CC_HASH_BLOCK_SIZE_IN_WORDS 16
+
+/*! The size of the SHA-1 hash block in bytes. */
+#define CC_HASH_BLOCK_SIZE_IN_BYTES 64
+
+/*! The size of the SHA-2 hash block in words. */
+#define CC_HASH_SHA512_BLOCK_SIZE_IN_WORDS  32
+
+/*! The size of the SHA-2 hash block in bytes. */
+#define CC_HASH_SHA512_BLOCK_SIZE_IN_BYTES  128
+
+/*! The maximal data size for the update operation. */
+#define CC_HASH_UPDATE_DATA_MAX_SIZE_IN_BYTES (1 << 29)
+
+
+/************************ Enums ********************************/
+
+/*! The hash operation mode. */
+typedef enum {
+    /*! SHA-1. */
+    CC_HASH_SHA1_mode          = 0,
+    /*! SHA-224. */
+    CC_HASH_SHA224_mode        = 1,
+    /*! SHA-256. */
+    CC_HASH_SHA256_mode        = 2,
+    /*! SHA-384. */
+    CC_HASH_SHA384_mode        = 3,
+    /*! SHA-512. */
+    CC_HASH_SHA512_mode        = 4,
+    /*! MD5. */
+    CC_HASH_MD5_mode           = 5,
+    /*! The number of hash modes. */
+    CC_HASH_NumOfModes,
+    /*! Reserved. */
+    CC_HASH_OperationModeLast= 0x7FFFFFFF,
+
+}CCHashOperationMode_t;
+
+/************************ Typedefs  *****************************/
+
+/*! The hash result buffer. */
+typedef uint32_t CCHashResultBuf_t[CC_HASH_RESULT_SIZE_IN_WORDS];
+
+/************************ Structs  ******************************/
+/*!
+ The context prototype of the user.
+ The argument type that is passed by the user to the hash APIs.
+ The context saves the state of the operation, and must be saved by the user
+ until the end of the API flow.
+*/
+typedef struct CCHashUserContext_t {
+    /*! The internal buffer. */
+    uint32_t buff[CC_HASH_USER_CTX_SIZE_IN_WORDS];
+}CCHashUserContext_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /* #ifndef CC_HASH_DEFS_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_kdf.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_kdf.h
new file mode 100644
index 0000000..10eecf6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_kdf.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_KDF_H
+#define _CC_KDF_H
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file defines the API that supports Key derivation function in modes
+       as defined in Public-Key Cryptography Standards (PKCS) #3: Diffie-Hellman Key Agreement Standard,
+       ANSI X9.42-2003: Public Key Cryptography for the Financial Services Industry: Agreement of Symmetric Keys Using Discrete Logarithm Cryptography,
+       and ANSI X9.63-2011: Public Key Cryptography for the Financial Services Industry - Key Agreement and Key Transport Using Elliptic Curve
+       Cryptography.
+@defgroup cc_kdf CryptoCell Key Derivation APIs
+@{
+@ingroup cryptocell_api
+
+*/
+
+#include "cc_hash_defs.h"
+
+/************************ Defines ******************************/
+
+/*! Shared secret value max size in bytes */
+#define  CC_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE  1024
+
+/* Count and max. sizeof OtherInfo entries (pointers to data buffers) */
+/*! Number of other info entries. */
+#define  CC_KDF_COUNT_OF_OTHER_INFO_ENTRIES   5
+
+/*! Maximal size of keying data in bytes. */
+#define  CC_KDF_MAX_SIZE_OF_KEYING_DATA  2048
+/*! Size of KDF counter in bytes */
+#define CC_KDF_COUNTER_SIZE_IN_BYTES  4
+
+/************************ Enums ********************************/
+
+/*! HASH operation modes */
+typedef enum
+{
+    /*! SHA1 mode.*/
+    CC_KDF_HASH_SHA1_mode    = 0,
+    /*! SHA224 mode.*/
+    CC_KDF_HASH_SHA224_mode  = 1,
+    /*! SHA256 mode.*/
+    CC_KDF_HASH_SHA256_mode  = 2,
+    /*! SHA384 mode.*/
+    CC_KDF_HASH_SHA384_mode  = 3,
+    /*! SHA512 mode.*/
+    CC_KDF_HASH_SHA512_mode  = 4,
+    /*! Maximal number of HASH modes. */
+    CC_KDF_HASH_NumOfModes,
+    /*! Reserved.*/
+    CC_KDF_HASH_OpModeLast = 0x7FFFFFFF,
+
+}CCKdfHashOpMode_t;
+
+/*! Key derivation modes. */
+typedef enum
+{
+    /*! ASN1 key derivation mode.*/
+    CC_KDF_ASN1_DerivMode    = 0,
+    /*! Concatination key derivation mode.*/
+    CC_KDF_ConcatDerivMode   = 1,
+    /*! X963 key derivation mode.*/
+    CC_KDF_X963_DerivMode    = CC_KDF_ConcatDerivMode,
+    /*! ISO 18033 KDF1 key derivation mode.*/
+    CC_KDF_ISO18033_KDF1_DerivMode = 3,
+    /*! ISO 18033 KDF2 key derivation mode.*/
+    CC_KDF_ISO18033_KDF2_DerivMode = 4,
+    /*! Maximal number of key derivation modes. */
+    CC_KDF_DerivFunc_NumOfModes = 5,
+    /*! Reserved.*/
+    CC_KDF_DerivFuncModeLast= 0x7FFFFFFF,
+
+}CCKdfDerivFuncMode_t;
+
+/*! Enumerator for the additional information given to the KDF. */
+typedef enum
+{
+    CC_KDF_ALGORITHM_ID     = 0, /*! An identifier (OID), indicating algorithm for which the keying data is used. */
+    CC_KDF_PARTY_U_INFO     = 1, /*! Optional data of party U .*/
+    CC_KDF_PARTY_V_INFO     = 2, /*! Optional data of party V. */
+    CC_KDF_SUPP_PRIV_INFO   = 3, /*! Optional supplied private shared data. */
+    CC_KDF_SUPP_PUB_INFO    = 4, /*! Optional supplied public shared data. */
+
+    CC_KDF_MAX_COUNT_OF_ENTRIES,  /*! Maximal allowed number of entries in Other Info structure. */
+    /*! Reserved.*/
+    CC_KDF_ENTRYS_MAX_VAL  = 0x7FFFFFFF,
+
+}CCKdfOtherInfoEntries_t;
+/************************ Typedefs  ****************************/
+
+/*! KDF structure, containing pointers to OtherInfo data entries and sizes.
+
+   The structure contains two arrays: one for data pointers and one for sizes, placed according
+   to the order given in the the ANSI X9.42-2003: Public Key Cryptography for the Financial Services
+   Industry: Agreement of Symmetric Keys Using Discrete Logarithm Cryptography standard
+   and defined in CCKdfOtherInfoEntries_t enumerator.
+   On KDF ASN1 mode this order is mandatory. On other KDF modes the user may insert
+   optional OtherInfo simply in one (preferably the first) or in some entries.
+   If any data entry is not used, then the pointer value and the size must be set to NULL. */
+typedef struct
+{
+        /*! Pointers to data entries. */
+        uint8_t  *dataPointers[CC_KDF_MAX_COUNT_OF_ENTRIES];
+        /*! Sizes of data entries. */
+        uint32_t  dataSizes[CC_KDF_MAX_COUNT_OF_ENTRIES];
+}CCKdfOtherInfo_t;
+
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+/****************************************************************/
+
+/*********************************************************************************************************/
+/*!
+ @brief CC_KdfKeyDerivFunc performs key derivation according to one of the modes defined in standards:
+    ANSI X9.42-2003: Public Key Cryptography for the Financial Services Industry: Agreement of Symmetric Keys Using Discrete Logarithm Cryptography,
+    ANSI X9.63-2011: Public Key Cryptography for the Financial Services Industry - Key Agreement and Key Transport Using Elliptic Curve Cryptography,
+    ISO/IEC 18033-2:2006: Information technology -- Security techniques -- Encryption algorithms -- Part 2: Asymmetric ciphers.
+
+The present implementation of the function allows the following operation modes:
+<ul><li> CC_KDF_ASN1_DerivMode - mode based on  ASN.1 DER encoding; </li>
+<li> CC_KDF_ConcatDerivMode - mode based on concatenation;</li>
+<li> CC_KDF_X963_DerivMode = CC_KDF_ConcatDerivMode;</li>
+<li> CC_KDF_ISO18033_KDF1_DerivMode, CC_KDF_ISO18033_KDF2_DerivMode - specific modes according to
+ISO/IEC 18033-2 standard.</li></ul>
+
+The purpose of this function is to derive a keying data from the shared secret value and some
+other optional shared information, included in OtherInfo (SharedInfo).
+
+\note All buffers arguments are represented in Big-Endian format.
+
+@return CC_OK on success.
+@return A non-zero value on failure as defined cc_kdf_error.h or cc_hash_error.h.
+*/
+CCError_t  CC_KdfKeyDerivFunc(
+                    uint8_t              *pZzSecret,            /*!< [in]  A pointer to shared secret value octet string. */
+                    size_t                zzSecretSize,         /*!< [in]  The size of the shared secret value in bytes.
+                                                                           The maximal size is defined as: ::CC_KDF_MAX_SIZE_OF_SHARED_SECRET_VALUE. */
+                    CCKdfOtherInfo_t     *pOtherInfo,           /*!< [in]  A pointer to the structure, containing pointers to the data, shared by
+                                       two entities of agreement, depending on KDF mode:
+                                                                           <ul><li> In KDF ASN1 mode OtherInfo includes ASN1 DER encoding of AlgorithmID (mandatory),
+                                                                             and some optional data entries as described in section 7.7.1 of the ANSI X9.42-2003:
+                                         Public Key Cryptography for the Financial Services Industry: Agreement of Symmetric Keys Using
+                                         Discrete Logarithm Cryptography standard.</li>
+                                                                           <li> In both ISO/IEC 18033-2:2006: Information technology -- Security techniques -- Encryption algorithms -- Part 2:
+                                        Asymmetric ciphers standard: KDF1 and KDF2 modes this parameter is ignored and may be set to NULL. </li>
+                                                                           <li> In other modes it is optional and may be set to NULL. </li></ul>*/
+                    CCKdfHashOpMode_t     kdfHashMode,          /*!< [in]  The KDF identifier of hash function to be used. The hash function output
+                                       must be at least 160 bits. */
+                    CCKdfDerivFuncMode_t  derivMode,            /*!< [in]  The enum value, specifies one of above described derivation modes. */
+                    uint8_t              *pKeyingData,          /*!< [out] A pointer to the buffer for derived keying data. */
+                    size_t                keyingDataSize        /*!< [in]  The size in bytes of the keying data to be derived.
+                                                                           The maximal size is defined as :: CC_KDF_MAX_SIZE_OF_KEYING_DATA. */ );
+
+/*********************************************************************************************************/
+/*!
+ CC_KdfAsn1KeyDerivFunc is a macro that performs key derivation according to ASN1 DER encoding method defined
+ in section 7.2.1 of ANSI X9.42-2003: Public Key Cryptography for the Financial Services Industry: Agreement of Symmetric Keys Using Discrete Logarithm Cryptography standard.
+ For a description of the parameters see ::CC_KdfKeyDerivFunc.
+*/
+#define CC_KdfAsn1KeyDerivFunc(ZZSecret_ptr,ZZSecretSize,OtherInfo_ptr,kdfHashMode,KeyingData_ptr,KeyLenInBytes)\
+        CC_KdfKeyDerivFunc((ZZSecret_ptr),(ZZSecretSize),(OtherInfo_ptr),(kdfHashMode),CC_KDF_ASN1_DerivMode,(KeyingData_ptr),(KeyLenInBytes))
+
+
+/*********************************************************************************************************/
+/*!
+ CC_KdfConcatKeyDerivFunc is a macro that performs key derivation according to concatenation mode defined
+ in section 7.2.2 of ANSI X9.42-2003: Public Key Cryptography for the Financial Services Industry: Agreement of Symmetric Keys Using Discrete Logarithm Cryptography
+ standard and also meets ANSI X9.63-2011: Public Key Cryptography for the Financial Services Industry - Key Agreement and Key Transport Using Elliptic Curve
+ Cryptography standard. For a description of the parameters see ::CC_KdfKeyDerivFunc.
+*/
+#define CC_KdfConcatKeyDerivFunc(ZZSecret_ptr,ZZSecretSize,OtherInfo_ptr,kdfHashMode,KeyingData_ptr,KeyLenInBytes)\
+        CC_KdfKeyDerivFunc((ZZSecret_ptr),(ZZSecretSize),(OtherInfo_ptr),(kdfHashMode),CC_KDF_ConcatDerivMode,(KeyingData_ptr),(KeyLenInBytes))
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_kdf_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_kdf_error.h
new file mode 100644
index 0000000..5099381
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_kdf_error.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_KDF_ERROR_H
+#define _CC_KDF_ERROR_H
+
+#include "cc_error.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file contains the definitions of the CryptoCell KDF errors.
+@defgroup cc_kdf_error CryptoCell Key Derivation specific errors
+@{
+@ingroup cc_kdf
+
+ */
+
+
+/************************ Defines *******************************/
+
+/*! The CryptoCell KDF module errors / base address - 0x00F01100*/
+/*! Illegal input pointer. */
+#define CC_KDF_INVALID_ARGUMENT_POINTER_ERROR           (CC_KDF_MODULE_ERROR_BASE + 0x0UL)
+/*! Illegal input size. */
+#define CC_KDF_INVALID_ARGUMENT_SIZE_ERROR          (CC_KDF_MODULE_ERROR_BASE + 0x1UL)
+/*! Illegal operation mode. */
+#define CC_KDF_INVALID_ARGUMENT_OPERATION_MODE_ERROR        (CC_KDF_MODULE_ERROR_BASE + 0x2UL)
+/*! Illegal hash mode. */
+#define CC_KDF_INVALID_ARGUMENT_HASH_MODE_ERROR         (CC_KDF_MODULE_ERROR_BASE + 0x3UL)
+/*! Illegal key derivation mode. */
+#define CC_KDF_INVALID_KEY_DERIVATION_MODE_ERROR                (CC_KDF_MODULE_ERROR_BASE + 0x4UL)
+/*! Illegal shared secret value size. */
+#define CC_KDF_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR           (CC_KDF_MODULE_ERROR_BASE + 0x5UL)
+/*! Illegal otherInfo size. */
+#define CC_KDF_INVALID_OTHER_INFO_SIZE_ERROR                    (CC_KDF_MODULE_ERROR_BASE + 0x6UL)
+/*! Illegal key data size. */
+#define CC_KDF_INVALID_KEYING_DATA_SIZE_ERROR                   (CC_KDF_MODULE_ERROR_BASE + 0x7UL)
+/*! Illegal algorithm ID pointer. */
+#define CC_KDF_INVALID_ALGORITHM_ID_POINTER_ERROR               (CC_KDF_MODULE_ERROR_BASE + 0x8UL)
+/*! Illegal algorithm ID size. */
+#define CC_KDF_INVALID_ALGORITHM_ID_SIZE_ERROR                  (CC_KDF_MODULE_ERROR_BASE + 0x9UL)
+/*! KDF is not supproted. */
+#define CC_KDF_IS_NOT_SUPPORTED                                 (CC_KDF_MODULE_ERROR_BASE + 0xFFUL)
+
+/************************ Enums *********************************/
+
+/************************ Typedefs  *****************************/
+
+/************************ Structs  ******************************/
+
+/************************ Public Variables **********************/
+
+/************************ Public Functions **********************/
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rnd_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rnd_error.h
new file mode 100644
index 0000000..3a6f455
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rnd_error.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_RND_ERROR_H
+#define _CC_RND_ERROR_H
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*!
+@file
+@brief This file contains the definitions of the CryptoCell RND errors.
+@defgroup cc_rnd_error CryptoCell RND specific errors
+@{
+@ingroup cc_rnd
+*/
+
+
+/************************ Defines ******************************/
+/*! RND module on the CryptoCell layer base address - 0x00F00C00 */
+/*! Illegal output pointer.*/
+#define CC_RND_DATA_OUT_POINTER_INVALID_ERROR           (CC_RND_MODULE_ERROR_BASE + 0x0UL)
+/*! Random generation in range failed .*/
+#define CC_RND_CAN_NOT_GENERATE_RAND_IN_RANGE           (CC_RND_MODULE_ERROR_BASE + 0x1UL)
+/*! CPRNGT test failed.*/
+#define CC_RND_CPRNG_TEST_FAIL_ERROR                (CC_RND_MODULE_ERROR_BASE + 0x2UL)
+/*! Illegal additional data buffer. */
+#define CC_RND_ADDITIONAL_INPUT_BUFFER_NULL         (CC_RND_MODULE_ERROR_BASE + 0x3UL)
+/*! Illegal additional data size. */
+#define CC_RND_ADDITIONAL_INPUT_SIZE_ERROR          (CC_RND_MODULE_ERROR_BASE + 0x4UL)
+/*! Data size overflow. */
+#define CC_RND_DATA_SIZE_OVERFLOW_ERROR             (CC_RND_MODULE_ERROR_BASE + 0x5UL)
+/*! Illegal vector size. */
+#define CC_RND_VECTOR_SIZE_ERROR            (CC_RND_MODULE_ERROR_BASE + 0x6UL)
+/*! Reseed counter overflow - in case this error was returned instantiation or reseeding operation must be called. */
+#define CC_RND_RESEED_COUNTER_OVERFLOW_ERROR        (CC_RND_MODULE_ERROR_BASE + 0x7UL)
+/*! Instantiation was not yet called. */
+#define CC_RND_INSTANTIATION_NOT_DONE_ERROR     (CC_RND_MODULE_ERROR_BASE + 0x8UL)
+/*! TRNG loss of samples. */
+#define CC_RND_TRNG_LOSS_SAMPLES_ERROR                  (CC_RND_MODULE_ERROR_BASE + 0x9UL)
+/*! TRNG Time exceeded limitations. */
+#define CC_RND_TRNG_TIME_EXCEED_ERROR               (CC_RND_MODULE_ERROR_BASE + 0xAUL)
+/*! TRNG loss of samples and time exceeded limitations. */
+#define CC_RND_TRNG_LOSS_SAMPLES_AND_TIME_EXCEED_ERROR  (CC_RND_MODULE_ERROR_BASE + 0xBUL)
+/*! RND is in Known Answer Test mode. */
+#define CC_RND_IS_KAT_MODE_ERROR                        (CC_RND_MODULE_ERROR_BASE + 0xCUL)
+/*! RND operation not supported. */
+#define CC_RND_OPERATION_IS_NOT_SUPPORTED_ERROR         (CC_RND_MODULE_ERROR_BASE + 0xDUL)
+/*! RND validity check failed. */
+#define CC_RND_STATE_VALIDATION_TAG_ERROR               (CC_RND_MODULE_ERROR_BASE + 0xEUL)
+/*! RND is not supported. */
+#define CC_RND_IS_NOT_SUPPORTED                         (CC_RND_MODULE_ERROR_BASE + 0xFUL)
+
+/*! Illegal generate vector function pointer. */
+#define CC_RND_GEN_VECTOR_FUNC_ERROR                (CC_RND_MODULE_ERROR_BASE + 0x14UL)
+
+/*! Illegal work buffer pointer. */
+#define CC_RND_WORK_BUFFER_PTR_INVALID_ERROR            (CC_RND_MODULE_ERROR_BASE + 0x20UL)
+/*! Illegal AES key size. */
+#define CC_RND_ILLEGAL_AES_KEY_SIZE_ERROR               (CC_RND_MODULE_ERROR_BASE + 0x21UL)
+/*! Illegal data pointer. */
+#define CC_RND_ILLEGAL_DATA_PTR_ERROR                   (CC_RND_MODULE_ERROR_BASE + 0x22UL)
+/*! Illegal data size. */
+#define CC_RND_ILLEGAL_DATA_SIZE_ERROR                  (CC_RND_MODULE_ERROR_BASE + 0x23UL)
+/*! Illegal parameter. */
+#define CC_RND_ILLEGAL_PARAMETER_ERROR                  (CC_RND_MODULE_ERROR_BASE + 0x24UL)
+/*! Illegal RND state pointer. */
+#define CC_RND_STATE_PTR_INVALID_ERROR                  (CC_RND_MODULE_ERROR_BASE + 0x25UL)
+/*! TRNG errors. */
+#define CC_RND_TRNG_ERRORS_ERROR                        (CC_RND_MODULE_ERROR_BASE + 0x26UL)
+/*! Illegal context pointer. */
+#define CC_RND_CONTEXT_PTR_INVALID_ERROR                (CC_RND_MODULE_ERROR_BASE + 0x27UL)
+/*! Illegal output vector pointer. */
+#define CC_RND_VECTOR_OUT_PTR_ERROR                     (CC_RND_MODULE_ERROR_BASE + 0x30UL)
+/*! Illegal output vector size. */
+#define CC_RND_VECTOR_OUT_SIZE_ERROR            (CC_RND_MODULE_ERROR_BASE + 0x31UL)
+/*! Maximal vector size is too small. */
+#define CC_RND_MAX_VECTOR_IS_TOO_SMALL_ERROR        (CC_RND_MODULE_ERROR_BASE + 0x32UL)
+/*! Illegal Known Answer Tests parameters. */
+#define CC_RND_KAT_DATA_PARAMS_ERROR                    (CC_RND_MODULE_ERROR_BASE + 0x33UL)
+/*! TRNG Known Answer Test not supported. */
+#define CC_RND_TRNG_KAT_NOT_SUPPORTED_ERROR             (CC_RND_MODULE_ERROR_BASE + 0x34UL)
+/*! SRAM memory is not defined. */
+#define CC_RND_SRAM_NOT_SUPPORTED_ERROR                 (CC_RND_MODULE_ERROR_BASE + 0x35UL)
+/*! AES operation failure. */
+#define CC_RND_AES_ERROR                                (CC_RND_MODULE_ERROR_BASE + 0x36UL)
+/*! TRNG mode mismatch between PAL and lib */
+#define CC_RND_MODE_MISMATCH_ERROR                      (CC_RND_MODULE_ERROR_BASE + 0x37UL)
+
+
+/************************ Enums ********************************/
+
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+
+
+/************************ Public Variables **********************/
+
+
+/************************ Public Functions **********************/
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_build.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_build.h
new file mode 100644
index 0000000..0a93f62
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_build.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_RSA_BUILD_H
+#define _CC_RSA_BUILD_H
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_error.h"
+#include "cc_rsa_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file defines some utility functions for working with RSA cryptography.
+@defgroup cc_rsa_build CryptoCell RSA Utility APIs
+@{
+@ingroup cc_rsa
+*/
+
+/******************************************************************************************/
+/*!
+@brief Builds a ::CCRsaUserPubKey_t public key structure with the provided modulus and exponent.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RsaPubKeyBuild(
+                                    CCRsaUserPubKey_t *UserPubKey_ptr,   /*!< [out] Pointer to the public key structure. */
+                                    uint8_t *Exponent_ptr,                  /*!< [in]  Pointer to the exponent stream of bytes (Big-Endian format). */
+                                    size_t   ExponentSize,                  /*!< [in]  The size of the exponent (in bytes). */
+                                    uint8_t *Modulus_ptr,                   /*!< [in]  Pointer to the modulus stream of bytes (Big-Endian format).
+                                               The most significant bit (MSB) must be set to '1'. */
+                                    size_t   ModulusSize                    /*!< [in]  The modulus size in bytes. Supported sizes are 256, 384 and 512 bytes. */
+);
+
+
+/******************************************************************************************/
+/*!
+@brief Builds a ::CCRsaUserPrivKey_t private-key structure with the provided modulus and exponent, marking the key as a non-CRT key.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RsaPrivKeyBuild(
+                                    CCRsaUserPrivKey_t   *UserPrivKey_ptr,     /*!< [out] Pointer to the public key structure.*/
+                                    uint8_t                 *PrivExponent_ptr,    /*!< [in]  Pointer to the private exponent stream of bytes (Big-Endian format). */
+                                    size_t                   PrivExponentSize,    /*!< [in]  The size of the private exponent (in bytes). */
+                                    uint8_t                 *PubExponent_ptr,     /*!< [in]  Pointer to the public exponent stream of bytes (Big-Endian format). */
+                                    size_t                   PubExponentSize,     /*!< [in]  The size of the public exponent (in bytes). */
+                                    uint8_t                 *Modulus_ptr,         /*!< [in]  Pointer to the modulus stream of bytes (Big-Endian format).
+                                               The most significant bit must be set to '1'. */
+                                    size_t                   ModulusSize          /*!< [in]  The modulus size in bytes. Supported sizes are 256, 384 and 512. */
+);
+
+/******************************************************************************************/
+/*!
+@brief Builds a ::CCRsaUserPrivKey_t private-key structure with the provided parameters, marking the key as a CRT key.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RsaPrivKeyCrtBuild(
+                                      CCRsaUserPrivKey_t *UserPrivKey_ptr,   /*!< [out] Pointer to the public key structure. */
+                                      uint8_t *P_ptr,                           /*!< [in]  Pointer to the first factor stream of bytes (Big-Endian format). */
+                                      size_t   PSize,                           /*!< [in]  The size of the first factor (in bytes). */
+                                      uint8_t *Q_ptr,                           /*!< [in]  Pointer to the second factor stream of bytes (Big-Endian format). */
+                                      size_t   QSize,                           /*!< [in]  The size of the second factor (in bytes). */
+                                      uint8_t *dP_ptr,                          /*!< [in]  Pointer to the first factor's CRT exponent stream of bytes
+                                               (Big-Endian format). */
+                                      size_t   dPSize,                          /*!< [in]  The size of the first factor's CRT exponent (in bytes). */
+                                      uint8_t *dQ_ptr,                          /*!< [in]  Pointer to the second factor's CRT exponent stream of bytes
+                                               (Big-Endian format). */
+                                      size_t   dQSize,                          /*!< [in]  The size of the second factor's CRT exponent (in bytes). */
+                                      uint8_t *qInv_ptr,                        /*!< [in]  Pointer to the first CRT coefficient stream of bytes (Big-Endian format). */
+                                      size_t   qInvSize                         /*!< [in]  The size of the first CRT coefficient (in bytes). */
+);
+
+
+/******************************************************************************************/
+/*!
+@brief The function gets the e,n public key parameters from the input
+CCRsaUserPubKey_t structure. The function can also be used to retrieve the
+modulus and exponent sizes only (Exponent_ptr AND Modulus_ptr must be set to
+NULL).
+
+\note All members of input UserPubKey_ptr structure must be initialized.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RsaPubKeyGet(
+                                CCRsaUserPubKey_t *UserPubKey_ptr,   /*!< [in] A pointer to the public key structure. */
+                                uint8_t  *Exponent_ptr,                 /*!< [out] A pointer to the exponent stream of bytes (Big-Endian format). */
+                                size_t   *ExponentSize_ptr,             /*!< [in/out] the size of the exponent buffer in bytes,
+                                              it is updated to the actual size of the exponent, in bytes. */
+                                uint8_t  *Modulus_ptr,                  /*!< [out] A pointer to the modulus stream of bytes (Big-Endian format).
+                                           The MS (most significant) bit must be set to '1'. */
+                                size_t   *ModulusSize_ptr               /*!< [in/out] the size of the modulus buffer in bytes, it is updated to the actual
+                                              size of the modulus, in bytes. */
+);
+
+/******************************************************************************************/
+/*!
+@brief The function gets the d,n and e - private key parameters (non CRT mode) from the input
+CCRsaUserPrivKey_t structure.
+
+\note All members of input UserPrivKey_ptr structure must be initialized. All output pointers must be allocated.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+*/
+CEXPORT_C CCError_t CC_RsaGetPrivKey(CCRsaUserPrivKey_t *UserPrivKey_ptr        /*!< [in] A pointer to the private key structure.*/,
+                     uint8_t             *PrivExponent_ptr      /*!< [out] A pointer to the exponent stream of bytes (Big-Endian format).*/,
+                     uint16_t            *PrivExponentSize_ptr  /*!< [in,out] The size of the private exponent buffer in bytes , it is updated to the
+                                                 actual size of the private exponent, in bytes*/,
+                     uint8_t             *PubExponent_ptr       /*!< [out] A pointer to the public exponent stream of bytes ( Big endian ).*/,
+                     uint16_t            *PubExponentSize_ptr,  /*!< [in,out] The size of the exponent buffer in bytes , it is updated to the
+                                                 actual size of the exponent, in bytes*/
+                     uint8_t             *Modulus_ptr,          /*!< [out] A pointer to the modulus stream of bytes (Big-Endian format).
+                                                 The MS (most significant) bit must be set to '1'.*/
+                     uint16_t            *ModulusSize_ptr       /*!< [in,out] The size of the modulus buffer in bytes , it is updated to the
+                                                 actual size of the modulus, in bytes*/
+);
+
+
+/******************************************************************************************/
+/*!
+@brief The function gets the P, Q, dP, dQ and QInv - private key parameters (CRT mode) from the input
+CCRsaUserPrivKey_t structure.
+
+\note All members of input UserPrivKey_ptr structure must be initialized. All output pointers must be allocated.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+*/
+CEXPORT_C CCError_t CC_RsaGetPrivKeyCRT(CCRsaUserPrivKey_t *UserPrivKey_ptr /*!< [in] A pointer to the private key structure.*/,
+                    uint8_t *P_ptr              /*!< [out] A pointer to the first factor stream of bytes ( Big endian ).*/,
+                    uint16_t *PSize_ptr,            /*!< [in,out] The size of the first factor buffer in bytes , updated to the actual size of the
+                                             first factor, in bytes.*/
+                    uint8_t *Q_ptr,             /*!< [out] A pointer to the second factor stream of bytes ( Big endian ).*/
+                    uint16_t *QSize_ptr,            /*!< [in,out] The size of the second factor buffer in bytes , updated to the
+                                             actual size of the second factor, in bytes.*/
+                    uint8_t *dP_ptr,            /*!< [out] A pointer to the first factors CRT exponent stream of bytes ( Big endian ).*/
+                    uint16_t *dPSize_ptr,           /*!< [in,out] The size of the first factor exponent buffer in bytes , updated to the
+                                             actual size of the first factor exponent, in bytes.*/
+                    uint8_t *dQ_ptr,            /*!< [out] A pointer to the second factors CRT exponent stream of bytes ( Big endian ).*/
+                    uint16_t *dQSize_ptr,           /*!< [in,out] The size of the second factors CRT exponent buffer in bytes , updated to the
+                                             actual size of the second factors CRT exponent, in bytes.*/
+                    uint8_t *qInv_ptr,          /*!< [out] A pointer to the first CRT coefficient stream of bytes ( Big endian ).*/
+                    uint16_t *qInvSize_ptr          /*!< [in,out] The size of the first CRT coefficient buffer in bytes , updated to the
+                                             actual size of the first CRT coefficient, in bytes.*/
+);
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+#endif /* _CC_RSA_BUILD_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_error.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_error.h
new file mode 100644
index 0000000..9257675
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_error.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_RSA_ERROR_H
+#define _CC_RSA_ERROR_H
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_error.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! @file
+@brief This file contains the definitions of the CryptoCell RSA errors.
+@defgroup cc_rsa_error CryptoCell RSA specific errors
+@{
+@ingroup cc_rsa
+
+*/
+
+/************************ Defines ******************************/
+
+/* PKI RSA module on the CryptoCell layer base address - 0x00F00400 */
+
+/*! CryptoCell RSA module errors */
+/*! Illegal modulus size. */
+#define CC_RSA_INVALID_MODULUS_SIZE                        (CC_RSA_MODULE_ERROR_BASE + 0x0UL)
+/*! Illegal modulus pointer. */
+#define CC_RSA_INVALID_MODULUS_POINTER_ERROR               (CC_RSA_MODULE_ERROR_BASE + 0x1UL)
+/*! Illegal exponent pointer. */
+#define CC_RSA_INVALID_EXPONENT_POINTER_ERROR              (CC_RSA_MODULE_ERROR_BASE + 0x2UL)
+/*! Illegal public key structure pointer. */
+#define CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR        (CC_RSA_MODULE_ERROR_BASE + 0x3UL)
+/*! Illegal private key structure pointer. */
+#define CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR       (CC_RSA_MODULE_ERROR_BASE + 0x4UL)
+/*! Illegal exponent value. */
+#define CC_RSA_INVALID_EXPONENT_VAL                        (CC_RSA_MODULE_ERROR_BASE + 0x5UL)
+/*! Illegal exponent size. */
+#define CC_RSA_INVALID_EXPONENT_SIZE                       (CC_RSA_MODULE_ERROR_BASE + 0x6UL)
+/*! Illegal CRT first factor pointer (P_ptr) . */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR      (CC_RSA_MODULE_ERROR_BASE + 0x7UL)
+/*! Illegal CRT second factor pointer (Q_ptr) . */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR     (CC_RSA_MODULE_ERROR_BASE + 0x8UL)
+/*! Illegal CRT first exponent factor pointer (dP_ptr) . */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR      (CC_RSA_MODULE_ERROR_BASE + 0x9UL)
+/*! Illegal CRT second exponent factor pointer (dQ_ptr) . */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR     (CC_RSA_MODULE_ERROR_BASE + 0xAUL)
+/*! Illegal CRT coefficient pointer (qInv_ptr) . */
+#define CC_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR           (CC_RSA_MODULE_ERROR_BASE + 0xBUL)
+/*! Illegal CRT first factor size (Psize). */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE               (CC_RSA_MODULE_ERROR_BASE + 0xCUL)
+/*! Illegal CRT second factor size (Qsize). */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE              (CC_RSA_MODULE_ERROR_BASE + 0xDUL)
+/*! Illegal CRT first and second factor size (Psize + Qsize). */
+#define CC_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE    (CC_RSA_MODULE_ERROR_BASE + 0xEUL)
+/*! Illegal CRT first factor exponent value (dP). */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL       (CC_RSA_MODULE_ERROR_BASE + 0xFUL)
+/*! Illegal CRT first factor exponent value (dQ). */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL      (CC_RSA_MODULE_ERROR_BASE + 0x10UL)
+/*! Illegal CRT coefficient value (qInv). */
+#define CC_RSA_INVALID_CRT_COEFF_VAL                       (CC_RSA_MODULE_ERROR_BASE + 0x11UL)
+/*! Illegal data in. */
+#define CC_RSA_DATA_POINTER_INVALID_ERROR                  (CC_RSA_MODULE_ERROR_BASE + 0x12UL)
+/*! Illegal message data size. */
+#define CC_RSA_INVALID_MESSAGE_DATA_SIZE                   (CC_RSA_MODULE_ERROR_BASE + 0x13UL)
+/*! Illegal message value. */
+#define CC_RSA_INVALID_MESSAGE_VAL                         (CC_RSA_MODULE_ERROR_BASE + 0x14UL)
+/*! Modulus even error. */
+#define CC_RSA_MODULUS_EVEN_ERROR                          (CC_RSA_MODULE_ERROR_BASE + 0x15UL)
+/*! Illegal context pointer. */
+#define CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR          (CC_RSA_MODULE_ERROR_BASE + 0x16UL)
+/*! Illegal hash operation mode. */
+#define CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR           (CC_RSA_MODULE_ERROR_BASE + 0x17UL)
+/*! Illegal MGF value. */
+#define CC_RSA_MGF_ILLEGAL_ARG_ERROR                       (CC_RSA_MODULE_ERROR_BASE + 0x18UL)
+/*! Illegal PKCS1 version. */
+#define CC_RSA_PKCS1_VER_ARG_ERROR                         (CC_RSA_MODULE_ERROR_BASE + 0x19UL)
+/*! Invalid private key. */
+#define CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR               (CC_RSA_MODULE_ERROR_BASE + 0x1AUL)
+/*! Invalid public key. */
+#define CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR                (CC_RSA_MODULE_ERROR_BASE + 0x1BUL)
+/*! Invalid context. */
+#define CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR           (CC_RSA_MODULE_ERROR_BASE + 0x1CUL)
+/*! Illegal output pointer. */
+#define CC_RSA_INVALID_OUTPUT_POINTER_ERROR                (CC_RSA_MODULE_ERROR_BASE + 0x1DUL)
+/*! Illegal output size pointer. */
+#define CC_RSA_INVALID_OUTPUT_SIZE_POINTER_ERROR           (CC_RSA_MODULE_ERROR_BASE + 0x1FUL)
+/*! Illegal temporary buffer pointer. */
+#define CC_RSA_CONV_TO_CRT_INVALID_TEMP_BUFF_POINTER_ERROR (CC_RSA_MODULE_ERROR_BASE + 0x20UL)
+/*! OAEP encode parameter string is too long. */
+#define CC_RSA_BASE_OAEP_ENCODE_PARAMETER_STRING_TOO_LONG  (CC_RSA_MODULE_ERROR_BASE + 0x22UL)
+/*! OAEP decode parameter string is too long. */
+#define CC_RSA_BASE_OAEP_DECODE_PARAMETER_STRING_TOO_LONG  (CC_RSA_MODULE_ERROR_BASE + 0x23UL)
+/*! OAEP encode message is too long. */
+#define CC_RSA_BASE_OAEP_ENCODE_MESSAGE_TOO_LONG           (CC_RSA_MODULE_ERROR_BASE + 0x24UL)
+/*! OAEP decode message is too long. */
+#define CC_RSA_BASE_OAEP_DECODE_MESSAGE_TOO_LONG           (CC_RSA_MODULE_ERROR_BASE + 0x25UL)
+/*! Illegal key generation data struct pointer. */
+#define CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID         (CC_RSA_MODULE_ERROR_BASE + 0x26UL)
+/*! Illegal PRIM data struct pointer. */
+#define CC_RSA_PRIM_DATA_STRUCT_POINTER_INVALID            (CC_RSA_MODULE_ERROR_BASE + 0x27UL)
+/*! Illegal message buffer size. */
+#define CC_RSA_INVALID_MESSAGE_BUFFER_SIZE                 (CC_RSA_MODULE_ERROR_BASE + 0x28UL)
+/*! Illegal signature buffer size. */
+#define CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE               (CC_RSA_MODULE_ERROR_BASE + 0x29UL)
+/*! Illegal modulus size pointer. */
+#define CC_RSA_INVALID_MOD_BUFFER_SIZE_POINTER             (CC_RSA_MODULE_ERROR_BASE + 0x2AUL)
+/*! Illegal exponent size pointer. */
+#define CC_RSA_INVALID_EXP_BUFFER_SIZE_POINTER             (CC_RSA_MODULE_ERROR_BASE + 0x2BUL)
+/*! Illegal signature pointer. */
+#define CC_RSA_INVALID_SIGNATURE_BUFFER_POINTER            (CC_RSA_MODULE_ERROR_BASE + 0x2CUL)
+/*! Wrong private key type. */
+#define CC_RSA_WRONG_PRIVATE_KEY_TYPE                      (CC_RSA_MODULE_ERROR_BASE + 0x2DUL)
+/*! Illegal CRT first factor size pointer (Psize) . */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_POINTER_ERROR (CC_RSA_MODULE_ERROR_BASE + 0x2EUL)
+/*! Illegal CRT second factor size pointer (Qsize) . */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_POINTER_ERROR (CC_RSA_MODULE_ERROR_BASE + 0x2FUL)
+/*! Illegal CRT first factor exponent size pointer (dPsize) . */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_PTR_ERROR (CC_RSA_MODULE_ERROR_BASE + 0x30UL)
+/*! Illegal CRT second factor exponent size pointer (dQsize) . */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_PTR_ERROR (CC_RSA_MODULE_ERROR_BASE + 0x31UL)
+/*! Illegal CRT coefficient size pointer (qInvsize) . */
+#define CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_PTR_ERROR        (CC_RSA_MODULE_ERROR_BASE + 0x32UL)
+/*! Illegal CRT first factor size (Psize) . */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_ERROR         (CC_RSA_MODULE_ERROR_BASE + 0x33UL)
+/*! Illegal CRT second factor size (Qsize) . */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_ERROR        (CC_RSA_MODULE_ERROR_BASE + 0x34UL)
+/*! Illegal CRT first factor exponent size (dPsize) . */
+#define CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_ERROR     (CC_RSA_MODULE_ERROR_BASE + 0x35UL)
+/*! Illegal CRT second factor exponent size (dQsize) . */
+#define CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_ERROR    (CC_RSA_MODULE_ERROR_BASE + 0x36UL)
+/*! Illegal CRT coefficient size (qInvsize) . */
+#define CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_ERROR            (CC_RSA_MODULE_ERROR_BASE + 0x37UL)
+/*! Key generation conditional test failed. */
+#define CC_RSA_KEY_GEN_CONDITIONAL_TEST_FAIL_ERROR       (CC_RSA_MODULE_ERROR_BASE + 0x38UL)
+/*! Random generation in range failed. */
+#define CC_RSA_CAN_NOT_GENERATE_RAND_IN_RANGE            (CC_RSA_MODULE_ERROR_BASE + 0x39UL)
+/*! Illegal CRT parameter size. */
+#define CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR             (CC_RSA_MODULE_ERROR_BASE + 0x3AUL)
+/*! Illegal modulus. */
+#define CC_RSA_INVALID_MODULUS_ERROR                       (CC_RSA_MODULE_ERROR_BASE + 0x40UL)
+/*! Illegal pointer. */
+#define CC_RSA_INVALID_PTR_ERROR                           (CC_RSA_MODULE_ERROR_BASE + 0x41UL)
+/*! Illegal decryption mode. */
+#define CC_RSA_INVALID_DECRYPRION_MODE_ERROR               (CC_RSA_MODULE_ERROR_BASE + 0x42UL)
+/*! Illegal generated private key. */
+#define CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW               (CC_RSA_MODULE_ERROR_BASE + 0x43UL)
+/*! Key generation error. */
+#define CC_RSA_KEY_GENERATION_FAILURE_ERROR                (CC_RSA_MODULE_ERROR_BASE + 0x44UL)
+#define CC_RSA_INTERNAL_ERROR                              (CC_RSA_MODULE_ERROR_BASE + 0x45UL)
+
+
+/****************************************************************************************
+ * PKCS#1 VERSION 1.5 ERRORS
+ ****************************************************************************************/
+/*! BER encoding passed. */
+#define CC_RSA_BER_ENCODING_OK                            CC_OK
+/*! Error in BER parsing. */
+#define CC_RSA_ERROR_BER_PARSING                         (CC_RSA_MODULE_ERROR_BASE+0x51UL)
+/*! Error in PKCS15 message. */
+#define CC_RSA_ENCODE_15_MSG_OUT_OF_RANGE                (CC_RSA_MODULE_ERROR_BASE+0x52UL)
+/*! Error in PKCS15 PS. */
+#define CC_RSA_ENCODE_15_PS_TOO_SHORT                    (CC_RSA_MODULE_ERROR_BASE+0x53UL)
+/*! PKCS15 block type is not supported. */
+#define CC_RSA_PKCS1_15_BLOCK_TYPE_NOT_SUPPORTED         (CC_RSA_MODULE_ERROR_BASE+0x54UL)
+/*! Error in PKCS15 decrypted block parsing. */
+#define CC_RSA_15_ERROR_IN_DECRYPTED_BLOCK_PARSING       (CC_RSA_MODULE_ERROR_BASE+0x55UL)
+/*! Error in random operation. */
+#define CC_RSA_ERROR_IN_RANDOM_OPERATION_FOR_ENCODE      (CC_RSA_MODULE_ERROR_BASE+0x56UL)
+/*! PKCS15 verification failed. */
+#define CC_RSA_ERROR_VER15_INCONSISTENT_VERIFY           (CC_RSA_MODULE_ERROR_BASE+0x57UL)
+/*! Illegal message size (in no hash operation case). */
+#define CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_NO_HASH_CASE (CC_RSA_MODULE_ERROR_BASE+0x58UL)
+/*! Illegal message size. */
+#define CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE       (CC_RSA_MODULE_ERROR_BASE+0x59UL)
+/*! PKCS#1 Ver 1.5 verify hash input inconsistent with hash mode derived from signature. */
+#define CC_RSA_PKCS15_VERIFY_BER_ENCODING_HASH_TYPE    (CC_RSA_MODULE_ERROR_BASE+0x60UL)  /*!< \internal PKCS#1 Ver 1.5 verify hash input inconsistent with hash mode derived from signature*/
+/*! Illegal DER hash mode */
+#define CC_RSA_GET_DER_HASH_MODE_ILLEGAL                 (CC_RSA_MODULE_ERROR_BASE+0x61UL)
+
+/****************************************************************************************
+ * PKCS#1 VERSION 2.1 ERRORS
+ ****************************************************************************************/
+ /*! Illegal salt length. */
+#define CC_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR  (CC_RSA_MODULE_ERROR_BASE+0x80UL)
+/*! Illegal MGF mask. */
+#define CC_RSA_BASE_MGF_MASK_TOO_LONG                   (CC_RSA_MODULE_ERROR_BASE+0x81UL)
+/*! PSS verification failed. */
+#define CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY            (CC_RSA_MODULE_ERROR_BASE+0x82UL)
+/*! OAEP message too long. */
+#define CC_RSA_OAEP_VER21_MESSAGE_TOO_LONG              (CC_RSA_MODULE_ERROR_BASE+0x83UL)
+/*! OAEP error in decrypted block parsing. */
+#define CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING         (CC_RSA_MODULE_ERROR_BASE+0x84UL)
+/*! OAEP decoding error. */
+#define CC_RSA_OAEP_DECODE_ERROR                        (CC_RSA_MODULE_ERROR_BASE+0x85UL)
+/*! Error in decrypted data size. */
+#define CC_RSA_15_ERROR_IN_DECRYPTED_DATA_SIZE          (CC_RSA_MODULE_ERROR_BASE+0x86UL)
+/*! Error in decrypted data. */
+#define CC_RSA_15_ERROR_IN_DECRYPTED_DATA               (CC_RSA_MODULE_ERROR_BASE+0x87UL)
+/*! Illegal L pointer. */
+#define CC_RSA_OAEP_L_POINTER_ERROR                     (CC_RSA_MODULE_ERROR_BASE+0x88UL)
+/*! Illegal output size. */
+#define CC_RSA_DECRYPT_INVALID_OUTPUT_SIZE              (CC_RSA_MODULE_ERROR_BASE+0x89UL)
+/*! Illegal output size pointer. */
+#define CC_RSA_DECRYPT_OUTPUT_SIZE_POINTER_ERROR        (CC_RSA_MODULE_ERROR_BASE+0x8AUL)
+/*! Illegal parameters. */
+#define CC_RSA_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR   (CC_RSA_MODULE_ERROR_BASE + 0x93UL)
+/*! RSA is not supported. */
+#define CC_RSA_IS_NOT_SUPPORTED                         (CC_RSA_MODULE_ERROR_BASE+0xFFUL)
+
+
+/************************ Enums ********************************/
+
+
+/************************ Typedefs  ****************************/
+
+
+/************************ Structs  ******************************/
+
+
+/************************ Public Variables **********************/
+
+
+/************************ Public Functions **********************/
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+#endif /* _CC_RSA_ERROR_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_kg.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_kg.h
new file mode 100644
index 0000000..71804bd
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_kg.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_RSA_KG_H
+#define _CC_RSA_KG_H
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_rsa_types.h"
+#include "cc_rnd_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief Generates a RSA pair of public and private keys.
+@defgroup cc_rsa_kg CryptoCell RSA key generation APIs
+@{
+@ingroup cc_rsa
+*/
+
+/************************ Defines ******************************/
+
+/* Max allowed size and values of public exponent for key generation in CryptoCell*/
+/*! Maximal public exponent size in bits. */
+#define CC_RSA_KG_PUB_EXP_MAX_SIZE_BITS    17
+/*! Definition of public exponent value. */
+#define CC_RSA_KG_PUB_EXP_ALLOW_VAL_1      0x000003
+/*! Definition of public exponent value. */
+#define CC_RSA_KG_PUB_EXP_ALLOW_VAL_2      0x000011
+/*! Definition of public exponent value. */
+#define CC_RSA_KG_PUB_EXP_ALLOW_VAL_3      0x010001
+
+
+
+
+/***********************************************************************************************/
+
+/*!
+@brief CC_RsaKgKeyPairGenerate generates a Pair of public and private keys on non CRT mode according to ANSI X9.31-1988: Public Key
+Cryptography Using Reversible Algorithms for the Financial Services Industry (rDSA).
+
+\note   To be FIPS Publication 186-4: Digital Signature Standard (DSS) [5.1] compliant use only the following:
+    key sizes (in bits): 2048, 3072, 4096 and public exponent value 0x10001.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h or cc_rnd_error.h on failure.
+
+*/
+CIMPORT_C CCError_t CC_RsaKgKeyPairGenerate(
+                                        CCRndContext_t *rndContext_ptr,          /*!< [in/out] Pointer to the RND context buffer. */
+                                        uint8_t             *pubExp_ptr,            /*!< [in]  The pointer to the public exponent (public key). */
+                                        size_t               pubExpSizeInBytes,     /*!< [in]  The public exponent size in bytes. */
+                                        size_t               keySize,               /*!< [in]  The size of the key, in bits. Supported sizes are
+                                                   2048, 3072 and 4096 bit. */
+                                        CCRsaUserPrivKey_t *userPrivKey_ptr,     /*!< [out] Pointer to the private-key structure. */
+                                        CCRsaUserPubKey_t  *userPubKey_ptr,      /*!< [out] Pointer to the public-key structure. */
+                    CCRsaKgData_t      *keyGenData_ptr,      /*!< [in]  Pointer to a temporary structure required for the KeyGen operation. */
+                                        CCRsaKgFipsContext_t    *pFipsCtx        /*!< [in]  Pointer to temporary buffer used in case FIPS certification if required
+                                                (may be NULL for all other cases). */
+);
+
+/***********************************************************************************************/
+/*!
+@brief Generates a pair of public and private keys on CRT mode according to ANSI X9.31-1988: Public Key
+Cryptography Using Reversible Algorithms for the Financial Services Industry (rDSA).
+
+\note To be FIPS Publication 186-4: Digital Signature Standard (DSS) compliant use only the following key sizes (in bits): 2048, 3072 and 4096.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h or cc_rnd_error.h on failure.
+*/
+
+CIMPORT_C CCError_t CC_RsaKgKeyPairCrtGenerate(
+                                        CCRndContext_t *rndContext_ptr,         /*!< [in/out] Pointer to the RND context buffer. */
+                                        uint8_t             *pubExp_ptr,           /*!< [in]  The pointer to the public exponent (public key). */
+                                        size_t               pubExpSizeInBytes,    /*!< [in]  The public exponent size in bytes. */
+                                        size_t               keySize,              /*!< [in]  The size of the key, in bits. Supported sizes are
+                                                                                              2048, 3072 and 4096 bit. */
+                                        CCRsaUserPrivKey_t *userPrivKey_ptr,    /*!< [out] Pointer to the private-key structure. */
+                                        CCRsaUserPubKey_t  *userPubKey_ptr,     /*!< [out] Pointer to the public-key structure. */
+                                        CCRsaKgData_t      *keyGenData_ptr,     /*!< [in] Pointer to a temporary structure required for the KeyGen operation. */
+                                        CCRsaKgFipsContext_t    *pFipsCtx       /*!< [in] Pointer to temporary buffer used in case FIPS certification if required
+                                              (may be NULL for all other cases). */
+);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+#endif /* _CC_RSA_KG_H */
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_prim.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_prim.h
new file mode 100644
index 0000000..34fe96d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_prim.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_RSA_PRIM_H
+#define _CC_RSA_PRIM_H
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_rsa_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file defines the API that implements the Public-Key Cryptography Standards (PKCS) #1
+RSA Cryptography Specifications Version 2.1 primitive functions.
+@defgroup cc_rsa_prim CryptoCell RSA primitive APIs
+@{
+@ingroup cc_rsa
+
+
+\note Direct use of primitive functions, rather than schemes to protect data, is strongly discouraged as primitive functions are
+susceptible to well-known attacks.
+*/
+
+
+
+/**********************************************************************************/
+/*!
+@brief Implements the RSAEP algorithm, as defined in section 6.1.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography
+Specifications Version 2.1.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+ */
+CIMPORT_C CCError_t CC_RsaPrimEncrypt(
+                                CCRsaUserPubKey_t *UserPubKey_ptr,       /*!< [in]  Pointer to the public-key data structure. */
+                                CCRsaPrimeData_t  *PrimeData_ptr,        /*!< [in]  Pointer to a temporary structure containing internal buffers. */
+                                uint8_t              *Data_ptr,          /*!< [in]  Pointer to the data to encrypt. */
+                                size_t                DataSize,          /*!< [in]  The size (in bytes) of the data to encrypt. Data size must be &le; Modulus size.
+                                            It can be smaller than the modulus size but it is not recommended.
+                                                                                    If smaller, the data is zero-padded up to the modulus size.
+                                                                                    Since the result of decryption is always the size of the modulus,
+                                                                                    this causes the size of the decrypted data to be larger than the
+                                            originally encrypted data. */
+                                uint8_t              *Output_ptr         /*!< [out] Pointer to the encrypted data. The buffer size must be &ge; the modulus size. */
+);
+
+
+/**********************************************************************************/
+/*!
+@brief Implements the RSADP algorithm, as defined in section 6.1.2 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography
+Specifications Version 2.1.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h on failure.
+
+*/
+CIMPORT_C CCError_t CC_RsaPrimDecrypt(
+                            CCRsaUserPrivKey_t *UserPrivKey_ptr,     /*!< [in]  Pointer to the private-key data structure.
+                                                                                    The representation (pair or quintuple) and hence the algorithm (CRT or not-CRT)
+                                                                                    is determined by the Private Key data structure - using
+                                            ::CC_RsaPrivKeyBuild or ::CC_RsaPrivKeyCrtBuild
+                                                                                    to determine which algorithm is used.*/
+                            CCRsaPrimeData_t   *PrimeData_ptr,       /*!< [in]  Pointer to a temporary structure containing internal buffers required for
+                                        the RSA operation. */
+                            uint8_t     *Data_ptr,                   /*!< [in]  Pointer to the data to be decrypted. */
+                            size_t       DataSize,                   /*!< [in]  The size (in bytes) of the data to decrypt. Must be equal to the modulus size. */
+                            uint8_t     *Output_ptr                  /*!< [out] Pointer to the decrypted data. The buffer size must be &le; the modulus size. */
+);
+
+
+/*!
+@brief Implements the RSASP1 algorithm, as defined in [PKCS1_2.1] - 6.2.1, as a call to ::CC_RsaPrimDecrypt,
+since the signature primitive is identical to the decryption primitive.
+*/
+#define CC_RsaPrimSign CC_RsaPrimDecrypt
+
+/*!
+@brief Implements the RSAVP1 algorithm, as defined in [PKCS1_2.1] - 6.2.2, as a call to ::CC_RsaPrimEncrypt.
+*/
+#define CC_RsaPrimVerify CC_RsaPrimEncrypt
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+#endif /* _CC_RSA_PRIM_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_schemes.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_schemes.h
new file mode 100644
index 0000000..48bf7e6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_schemes.h
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_RSA_SCHEMES_H
+#define _CC_RSA_SCHEMES_H
+
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_error.h"
+#include "cc_rsa_types.h"
+#include "cc_rnd_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+@file
+@brief This file defines APIs that support Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5
+and Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1 encryption and signature schemes.
+@defgroup cc_rsa_schemes CryptoCell RSA encryption and signature schemes
+@{
+@ingroup cc_rsa
+*/
+
+/**********************************************************************************************************/
+/*!
+@brief This function implements the Encrypt algorithm, as defined in Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+Version 2.1 and Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5.
+
+It should not be called directly. Instead, use macros ::CC_RsaOaepEncrypt or ::CC_RsaPkcs1V15Encrypt.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h, cc_rnd_error.h or cc_hash_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RsaSchemesEncrypt(
+                        CCRndContext_t *rndContext_ptr,         /*!< [in/out] Pointer to the RND context buffer. */
+                        CCRsaUserPubKey_t  *UserPubKey_ptr,     /*!< [in]  Pointer to the public key data structure. */
+                        CCRsaPrimeData_t   *PrimeData_ptr,      /*!< [in]  Pointer to a temporary structure that is internally used as workspace for the
+                                           Encryption operation. */
+                        CCRsaHashOpMode_t hashFunc,             /*!< [in]  The HASH function to be used. One of the supported SHA-x HASH modes, as defined
+                                           in ::CCRsaHashOpMode_t (MD5 is not supported).*/
+                        uint8_t  *L,                            /*!< [in]  The label input pointer. Relevant for Public-Key Cryptography Standards (PKCS) #1 RSA
+                                       Cryptography Specifications Version 2.1 only. NULL by default.
+                                           NULL for Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5. */
+                        size_t    Llen,                         /*!< [in]  The label length. Relevant for Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography
+                                       Specifications Version 2.1 only. Zero by default. Must be <=2048. Zero for Public-Key Cryptography
+                                       Standards (PKCS) #1: RSA Encryption Standard Version 1.5. */
+                        CCPkcs1Mgf_t MGF,                       /*!< [in]  The mask generation function. [PKCS1_2.1] defines MGF1, so the only value
+                                       allowed here is CC_PKCS1_MGF1. */
+                        uint8_t   *DataIn_ptr,                  /*!< [in]  Pointer to the data to encrypt. */
+                        size_t     DataInSize,                  /*!< [in]  The size (in bytes) of the data to encrypt. The data size must be:
+                                                                           <ul><li>For Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+                                           Version 2.1, DataSize <= modulus size - 2*HashLen - 2.</li>
+                                                                           <li>For Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5,
+                                           DataSize <= modulus size - 11.</li></ul> */
+                        uint8_t   *Output_ptr,                  /*!< [out] Pointer to the encrypted data. The buffer must be at least modulus size bytes long. */
+                        CCPkcs1Version_t  PKCS1_ver             /*!< [in] Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5 or
+                                      Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1,
+                                      according to the functionality required. */
+);
+
+/*!
+   @brief CC_RsaOaepEncrypt implements the RSAES-OAEP algorithm
+   as defined in section 8.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1.
+
+   \note It is not recommended to use hash MD5 in Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography
+     Specifications Version 2.1, therefore it is not supported.
+
+   This function combines the RSA encryption primitive and the
+   EME-OAEP encoding method, to provide an RSA-based encryption
+   method that is semantically secure against adaptive
+   chosen-ciphertext attacks. For additional details, see Public-Key Cryptography Standards
+   (PKCS) #1 RSA Cryptography Specifications Version 2.1.
+*/
+#define CC_RsaOaepEncrypt(rndContext_ptr, UserPubKey_ptr,PrimeData_ptr,HashMode,L,Llen,MGF,Data_ptr,DataSize,Output_ptr)\
+    CC_RsaSchemesEncrypt(rndContext_ptr, UserPubKey_ptr,PrimeData_ptr,HashMode,L,Llen,MGF,Data_ptr,DataSize,Output_ptr,CC_PKCS1_VER21)
+
+/*!
+   @brief
+   CC_RsaPkcs1V15Encrypt implements the RSAES-PKCS1v15 algorithm
+   as defined in section 8.2 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1.
+*/
+#define CC_RsaPkcs1V15Encrypt(rndContext_ptr, UserPubKey_ptr,PrimeData_ptr,DataIn_ptr,DataInSize,Output_ptr)\
+    CC_RsaSchemesEncrypt(rndContext_ptr, UserPubKey_ptr,PrimeData_ptr,CC_RSA_HASH_NO_HASH_mode,NULL,0,CC_PKCS1_NO_MGF,DataIn_ptr,DataInSize, Output_ptr,CC_PKCS1_VER15)
+
+
+/**********************************************************************************************************/
+/*!
+@brief This function implements the Decrypt algorithm, as defined in Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1 and
+Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5.
+
+It should not be called directly. Instead, use macros ::CC_RsaOaepDecrypt or ::CC_RsaPkcs1V15Decrypt.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h or cc_hash_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RsaSchemesDecrypt(
+                                CCRsaUserPrivKey_t  *UserPrivKey_ptr,    /*!< [in]  Pointer to the private-key data structure of the user. */
+                                CCRsaPrimeData_t    *PrimeData_ptr,      /*!< [in]  Pointer to a temporary structure that is internally used as workspace
+                                            for the decryption operation. */
+                                CCRsaHashOpMode_t  hashFunc,             /*!< [in]  The HASH function to be used. One of the supported SHA-x HASH modes,
+                                            as defined in ::CCRsaHashOpMode_t (MD5 is not supported). */
+                                uint8_t                 *L,              /*!< [in]  The label input pointer. Relevant for Public-Key Cryptography Standards (PKCS) #1
+                                            RSA Cryptography Specifications Version 2.1 only. NULL by default.
+                                            NULL for Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard
+                                            Version 1.5. */
+                                size_t                  Llen,            /*!< [in]  The label length. Relevant for Public-Key Cryptography Standards (PKCS) #1 RSA
+                                            Cryptography Specifications Version 2.1 only. Zero by default.
+                                            Zero for Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard
+                                            Version 1.5. */
+                                CCPkcs1Mgf_t        MGF,                 /*!< [in]  The mask generation function. Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography
+                                            Specifications Version 2.1 defines MGF1, so the only
+                                            value allowed here is CC_PKCS1_MGF1. */
+                                uint8_t                 *DataIn_ptr,     /*!< [in]  Pointer to the data to decrypt. */
+                                size_t                  DataInSize,      /*!< [in]  The size (in bytes) of the data to decrypt. DataSize must be &le;
+                                            the modulus size. */
+                                uint8_t                 *Output_ptr,     /*!< [in]  Pointer to the decrypted data. The buffer must be at least
+                                            PrivKey_ptr->N.len bytes long (i.e. the modulus size in bytes). */
+                                size_t                  *OutputSize_ptr, /*!< [in]  Pointer to the byte size of the buffer pointed to by Output_buffer.
+                                            The size must be:
+                                                                                    <ul><li> For Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+                                                 Version 2.1: Modulus size > OutputSize >= (modulus size - 2*HashLen - 2).</li>
+                                                                                    <li> For Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5:
+                                             Modulus size > OutputSize >= (modulus size - 11).
+                                                                                         The value pointed by OutputSize_ptr is updated after decryption with
+                                             the actual number of bytes that are loaded to Output_ptr.</li></ul> */
+                                CCPkcs1Version_t      PKCS1_ver          /*!< [in] Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5 or
+                                           Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1,
+                                           according to the functionality required. */
+);
+
+/**********************************************************************************************************/
+/**
+   @brief CC_RsaOaepDecrypt implements the RSAES-OAEP algorithm
+   as section 8.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1.
+
+   \note It is not recommended to use hash MD5 in Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography
+   Specifications Version 2.1, therefore it is not supported.
+
+   This function combines the RSA decryption primitive and the
+   EME-OAEP encoding method, to provide an RSA-based decryption
+   method that is semantically secure against adaptive
+   chosen-ciphertext attacks. For more details, see Public-Key Cryptography Standards
+   (PKCS) #1 RSA Cryptography Specifications Version 2.1.
+
+*/
+#define CC_RsaOaepDecrypt(UserPrivKey_ptr,PrimeData_ptr,HashMode,L,Llen,MGF,Data_ptr,DataSize,Output_ptr,OutputSize_ptr)\
+    CC_RsaSchemesDecrypt(UserPrivKey_ptr,PrimeData_ptr,HashMode,L,Llen,MGF,Data_ptr,DataSize,Output_ptr,OutputSize_ptr,CC_PKCS1_VER21)
+
+
+/**
+   @brief CC_RsaPkcs1V15Decrypt implements the RSAES-PKCS1v15 algorithm as defined
+   in PKCS#1 v2.1 8.2.
+*/
+#define CC_RsaPkcs1V15Decrypt(UserPrivKey_ptr,PrimeData_ptr,DataIn_ptr,DataInSize,Output_ptr,OutputSize_ptr)\
+    CC_RsaSchemesDecrypt(UserPrivKey_ptr,PrimeData_ptr,CC_RSA_HASH_NO_HASH_mode,NULL,0,CC_PKCS1_NO_MGF,DataIn_ptr,DataInSize,Output_ptr,OutputSize_ptr,CC_PKCS1_VER15)
+
+/**********************************************************************************************************/
+/*!
+@brief Implements the Signing algorithm, as defined in Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5
+or Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1, using a single function.
+
+The input data may be either a non-hashed data or a digest of a hash function.
+For a non-hashed data, the input data will be hashed using the hash function indicated by ::CCRsaHashOpMode_t.
+For a digest, ::CCRsaHashOpMode_t should indicate the hash function that the input data was created by, and it will not be hashed.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h, cc_rnd_error.h or cc_hash_error.h on failure.
+*/
+CIMPORT_C CCError_t CC_RsaSign(
+                   CCRndContext_t *rndContext_ptr,               /*!< [in/out] Pointer to the RND context buffer. */
+                   CCRsaPrivUserContext_t *UserContext_ptr,   /*!< [in]  Pointer to a temporary context for internal use. */
+                   CCRsaUserPrivKey_t *UserPrivKey_ptr,          /*!< [in]  Pointer to the private-key data structure of the user.
+                                                                            The representation (pair or quintuple) and hence the algorithm (CRT or not CRT)
+                                        is determined by the Private Key build function -
+                                                                            ::CC_RsaPrivKeyBuild or ::CC_RsaPrivKeyCrtBuild. */
+                   CCRsaHashOpMode_t rsaHashMode,                /*!< [in]  One of the supported SHA-x HASH modes, as defined in ::CCRsaHashOpMode_t.
+                                        (MD5 is not supported). */
+                   CCPkcs1Mgf_t MGF,                             /*!< [in]  The mask generation function. Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+                                        Version 2.1 defines only MGF1, so the only value allowed for it is CC_PKCS1_MGF1. */
+                   size_t       SaltLen,                         /*!< [in]  The Length of the Salt buffer (relevant for Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography
+                                        Specifications Version 2.1 only, typically lengths is 0 or hash Len).
+                                                                            FIPS Publication 186-4: Digital Signature Standard (DSS) requires, that SaltLen <= hash len.
+                                        If SaltLen > KeySize - hash Len - 2, the function returns an error.  */
+                   uint8_t     *DataIn_ptr,                      /*!< [in]  Pointer to the input data to be signed.
+                                                                            The size of the scatter/gather list representing the data buffer is limited to 128
+                                        entries, and the size of each entry is limited to 64KB (fragments larger than
+                                        64KB are broken into fragments <= 64KB). */
+                   size_t      DataInSize,                       /*!< [in]  The size (in bytes) of the data to sign. */
+                   uint8_t     *Output_ptr,                      /*!< [out] Pointer to the signature. The buffer must be at least PrivKey_ptr->N.len bytes
+                                        long (i.e. the modulus size in bytes). */
+                   size_t      *OutputSize_ptr,                  /*!< [in/out] Pointer to the signature size value - the input value is the signature
+                                           buffer size allocated, the output value is the signature size used.
+                                                                               he buffer must be equal to PrivKey_ptr->N.len bytes long
+                                           (i.e. the modulus size in bytes). */
+                   CCPkcs1Version_t PKCS1_ver                    /*!< [in]  Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5 or Public-Key Cryptography
+                                        Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1, according to the functionality required. */
+);
+
+
+/*!
+@brief CC_RsaPkcs1V15Sign implements the RSASSA-PKCS1v15 algorithm as defined in Public-Key Cryptography Standards (PKCS) #1:
+RSA Encryption Standard Version 1.5.
+
+This function combines the RSASP1 signature primitive and the EMSA-PKCS1v15 encoding method, to provide an RSA-based signature scheme.
+For more details, see Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5.
+ */
+
+#define CC_RsaPkcs1V15Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,hashFunc,DataIn_ptr,DataInSize,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, (UserContext_ptr),(UserPrivKey_ptr),(hashFunc),(CC_PKCS1_NO_MGF),0,(DataIn_ptr),(DataInSize),(Output_ptr),(OutputSize_ptr),CC_PKCS1_VER15)
+
+
+/*!
+@brief CC_RsaPkcs1V15Sha1Sign implements the RSASSA-PKCS1v15 algorithm as defined in Public-Key Cryptography Standards
+(PKCS) #1: RSA Encryption Standard Version 1.5, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-1.
+
+\note The data_in size is already known after the Hash.
+*/
+#define CC_RsaPkcs1V15Sha1Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, (UserContext_ptr),(UserPrivKey_ptr),(CC_RSA_After_SHA1_mode),(CC_PKCS1_NO_MGF),0,(DataIn_ptr),CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES,(Output_ptr),(OutputSize_ptr),CC_PKCS1_VER15)
+
+/*!
+@brief CC_RsaPkcs1V15Md5Sign implements the RSASSA-PKCS1v15 algorithm as defined in Public-Key Cryptography Standards (PKCS) #1:
+RSA Encryption Standard Version 1.5, but without performing a HASH function - it assumes that the data in has already been
+hashed using MD5.
+
+\note The data_in size is already known after the Hash.
+*/
+
+#define CC_RsaPkcs1V15Md5Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, (UserContext_ptr),(UserPrivKey_ptr),CC_RSA_After_MD5_mode,CC_PKCS1_NO_MGF,0,(DataIn_ptr),CC_HASH_MD5_DIGEST_SIZE_IN_BYTES,(Output_ptr),(OutputSize_ptr),CC_PKCS1_VER15)
+
+
+/*!
+@brief CC_RsaPkcs1V15Sha224Sign implements the RSASSA-PKCS1v15 algorithm as defined in Public-Key Cryptography Standards (PKCS) #1: RSA Encryption
+Standard Version 1.5, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-224.
+
+\note The data_in size is already known after the Hash.
+*/
+#define CC_RsaPkcs1V15Sha224Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, (UserContext_ptr),(UserPrivKey_ptr),(CC_RSA_After_SHA224_mode),(CC_PKCS1_NO_MGF),0,(DataIn_ptr),CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES,(Output_ptr),(OutputSize_ptr),CC_PKCS1_VER15)
+
+
+/*!
+@brief CC_RsaPkcs1V15Sha256Sign implements the RSASSA-PKCS1v15 algorithm as defined in Public-Key Cryptography Standards (PKCS) #1: RSA Encryption
+Standard Version 1.5, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-256.
+
+\note The data_in size is already known after the Hash.
+*/
+#define CC_RsaPkcs1V15Sha256Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, (UserContext_ptr),(UserPrivKey_ptr),(CC_RSA_After_SHA256_mode),(CC_PKCS1_NO_MGF),0,(DataIn_ptr),CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES,(Output_ptr),(OutputSize_ptr),CC_PKCS1_VER15)
+
+/*!
+@brief CC_RsaPkcs1V15Sha1Sign implements the RSASSA-PKCS1v15 algorithm as defined in Public-Key Cryptography Standards (PKCS) #1: RSA Encryption
+Standard Version 1.5, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-384.
+
+\note The data_in size is already known after the Hash.
+*/
+#define CC_RsaPkcs1V15Sha384Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, (UserContext_ptr),(UserPrivKey_ptr),(CC_RSA_After_SHA384_mode),(CC_PKCS1_NO_MGF),0,(DataIn_ptr),CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES,(Output_ptr),(OutputSize_ptr),CC_PKCS1_VER15)
+
+
+/*!
+@brief CC_RsaPkcs1V15Sha512Sign implements the RSASSA-PKCS1v15 algorithm  as defined in Public-Key Cryptography Standards (PKCS) #1: RSA Encryption
+Standard Version 1.5, but without performing a HASH function - it assumes that the data in has already been hashed using SHA-512.
+
+\note The data_in size is already known after the Hash.
+*/
+#define CC_RsaPkcs1V15Sha512Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, (UserContext_ptr),(UserPrivKey_ptr),(CC_RSA_After_SHA512_mode),(CC_PKCS1_NO_MGF),0,(DataIn_ptr),CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES,(Output_ptr),(OutputSize_ptr),CC_PKCS1_VER15)
+
+
+
+/*!
+@brief CC_RsaPssSign implements the RSASSA-PSS algorithm as defined in section 9.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+Version 2.1, in a single function call.
+
+\note According to the Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1 it is not recommended to use MD5 Hash,
+therefore it is not supported.
+
+The actual macro that is used by the user is ::CC_RsaPssSign.
+*/
+
+#define CC_RsaPssSign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,hashFunc,MGF,SaltLen,DataIn_ptr,DataInSize,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,hashFunc,MGF,SaltLen,DataIn_ptr,DataInSize,Output_ptr,OutputSize_ptr,CC_PKCS1_VER21)
+
+
+/*!
+@brief CC_RsaPssSha1Sign implements the RSASSA-PSS algorithm as defined in section 9.1 of Public-Key Cryptography Standards (PKCS) #1
+RSA Cryptography Specifications Version 2.1 in a single function call, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-1.
+
+\note The data_in size is already known after the Hash.
+
+The actual macro that is used by the users is ::CC_RsaPssSha1Sign.
+*/
+
+#define CC_RsaPssSha1Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,MGF,SaltLen,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,CC_RSA_After_SHA1_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES,Output_ptr,OutputSize_ptr,CC_PKCS1_VER21)
+
+
+/*!
+@brief CC_RsaPssSha224Sign implements the RSASSA-PSS algorithm as defined in section 9.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+Version 2.1 in a single function call, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-224.
+
+\note The data_in size is already known after the Hash.
+
+The actual macro that is used by the users is ::CC_RsaPssSha224Sign.
+*/
+
+#define CC_RsaPssSha224Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,MGF,SaltLen,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,CC_RSA_After_SHA224_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES,Output_ptr,OutputSize_ptr,CC_PKCS1_VER21)
+
+
+/*!
+@brief CC_RsaPssSha256Sign implements the RSASSA-PSS algorithm as defined in section 9.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+Version 2.1 in a single function call, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-256.
+
+\note The data_in size is already known after the Hash.
+
+The actual macro that is used by the users is ::CC_RsaPssSha256Sign.
+*/
+
+#define CC_RsaPssSha256Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,MGF,SaltLen,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,CC_RSA_After_SHA256_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES,Output_ptr,OutputSize_ptr,CC_PKCS1_VER21)
+
+
+/*!
+@brief CC_RsaPssSha384Sign implements the RSASSA-PSS algorithm as defined in section 9.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+Version 2.1 in a single function call, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-384.
+
+\note The data_in size is already known after the Hash.
+
+The actual macro that is used by the users is ::CC_RsaPssSha384Sign.
+*/
+
+#define CC_RsaPssSha384Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,MGF,SaltLen,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,CC_RSA_After_SHA384_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES,Output_ptr,OutputSize_ptr,CC_PKCS1_VER21)
+
+
+/*!
+@brief CC_RsaPssSha512Sign implements the RSASSA-PSS algorithm as defined in section 9.1 of Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications
+Version 2.1 in a single function call, but without performing a HASH function -
+it assumes that the data in has already been hashed using SHA-512.
+
+\note The data_in size is already known after the Hash.
+
+The actual macro that is used by the users is ::CC_RsaPssSha512Sign.
+*/
+
+#define CC_RsaPssSha512Sign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,MGF,SaltLen,DataIn_ptr,Output_ptr,OutputSize_ptr)\
+    CC_RsaSign(rndContext_ptr, UserContext_ptr,UserPrivKey_ptr,CC_RSA_After_SHA512_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES,Output_ptr,OutputSize_ptr,CC_PKCS1_VER21)
+
+
+/**********************************************************************************************************/
+/*!
+@brief Implements the RSA signature verification algorithms, in a single function call, as defined in Public-Key Cryptography Standards (PKCS) #1: RSA Encryption
+Standard Version 1.5 and in Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 2.1.
+
+The input data may be either a non-hashed data or a digest of a hash function.
+For a non-hashed data, the input data will be hashed using the hash function indicated by ::CCRsaHashOpMode_t.
+For a digest, ::CCRsaHashOpMode_t should indicate the hash function that the input data was created by, and it will not be hashed.
+
+@return CC_OK on success.
+@return A non-zero value from cc_rsa_error.h or cc_hash_error.h on failure.
+*/
+
+CIMPORT_C CCError_t CC_RsaVerify(
+                            CCRsaPubUserContext_t *UserContext_ptr,   /*!< [in]  Pointer to a temporary context for internal use. */
+                            CCRsaUserPubKey_t *UserPubKey_ptr,           /*!< [in]  Pointer to the public key data structure of the user. */
+                            CCRsaHashOpMode_t rsaHashMode,               /*!< [in]  One of the supported SHA-x HASH modes, as defined in ::CCRsaHashOpMode_t.
+                                            (MD5 is not supported). */
+                            CCPkcs1Mgf_t MGF,                            /*!< [in]  The mask generation function. Public-Key Cryptography Standards (PKCS) #1 RSA
+                                                Cryptography Specifications Version 2.1 defines only MGF1, so the only
+                                            value allowed for it is CC_PKCS1_MGF1. */
+                            size_t      SaltLen,                         /*!< [in]  The Length of the Salt buffer. Relevant only for Public-Key Cryptography Standards
+                                            (PKCS) #1 RSA Cryptography Specifications Version 2.1.
+                                            Typical lengths are 0 or hash Len (20 for SHA-1).
+                                                                                    The maximum length allowed is [modulus size - hash Len - 2]. */
+                            uint8_t     *DataIn_ptr,                     /*!< [in]  Pointer to the input data to be verified.
+                                                                                    The size of the scatter/gather list representing the data buffer is
+                                            limited to 128 entries, and the size of each entry is limited to 64KB
+                                                (fragments larger than 64KB are broken into fragments <= 64KB). */
+                            size_t      DataInSize,                      /*!< [in]  The size (in bytes) of the data whose signature is to be verified. */
+                            uint8_t     *Sig_ptr,                        /*!< [in]  Pointer to the signature to be verified.
+                                                                                    The length of the signature is PubKey_ptr->N.len bytes
+                                            (i.e. the modulus size in bytes). */
+                            CCPkcs1Version_t PKCS1_ver                   /*!< [in]  Public-Key Cryptography Standards (PKCS) #1: RSA Encryption Standard Version 1.5 or
+                                            Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version
+                                            2.1, according to the functionality required. */
+);
+/*!
+@brief CRYS_RSA_PKCS1v15_Verify implements the Public-Key Cryptography Standards (PKCS) #1: RSA Encryption
+Standard Version 1.5 Verify algorithm.
+*/
+#define CC_RsaPkcs1V15Verify(UserContext_ptr,UserPubKey_ptr,hashFunc,DataIn_ptr,DataInSize,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,hashFunc,CC_PKCS1_NO_MGF,0,DataIn_ptr,DataInSize,Sig_ptr,CC_PKCS1_VER15)
+
+
+/*!
+@brief CC_RsaPkcs1V15Md5Verify implements the RSASSA-PKCS1v15 Verify algorithm as defined in PKCS#1 v1.5, but without operating the HASH function -
+it assumes the DataIn_ptr data has already been hashed using MD5.
+*/
+
+#define CC_RsaPkcs1V15Md5Verify(UserContext_ptr,UserPubKey_ptr,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_MD5_mode,CC_PKCS1_NO_MGF,0,DataIn_ptr,CC_HASH_MD5_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER15)
+
+
+/*!
+@brief CC_RsaPkcs1V15Sha1Verify implements the RSASSA-PKCS1v15 Verify algorithm as defined in PKCS#1 v1.5, but without operating the HASH function -
+it assumes that the DataIn_ptr data has already been hashed using SHA1.
+
+*/
+#define CC_RsaPkcs1V15Sha1Verify(UserContext_ptr,UserPubKey_ptr,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA1_mode,CC_PKCS1_NO_MGF,0,DataIn_ptr,CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER15)
+
+/*!
+@brief CC_RsaPkcs1V15Sha224Verify implements the RSASSA-PKCS1v15 Verify algorithm as defined in PKCS#1 v1.5, but without operating the HASH function -
+it assumes that the DataIn_ptr data has already been hashed using SHA224.
+
+*/
+#define CC_RsaPkcs1V15Sha224Verify(UserContext_ptr,UserPubKey_ptr,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA224_mode,CC_PKCS1_NO_MGF,0,DataIn_ptr,CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER15)
+
+/*!
+@brief CC_RsaPkcs1V15Sha256Verify implements the RSASSA-PKCS1v15 Verify algorithm as defined in PKCS#1 v1.5, but without operating the HASH function -
+it assumes that the DataIn_ptr data has already been hashed using SHA256.
+
+*/
+#define CC_RsaPkcs1V15Sha256Verify(UserContext_ptr,UserPubKey_ptr,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA256_mode,CC_PKCS1_NO_MGF,0,DataIn_ptr,CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER15)
+
+/*!
+@brief CC_RsaPkcs1V15Sha384Verify implements the RSASSA-PKCS1v15 Verify algorithm as defined in PKCS#1 v1.5, but without operating the HASH function -
+it assumes that the DataIn_ptr data has already been hashed using SHA384.
+
+*/
+#define CC_RsaPkcs1V15Sha384Verify(UserContext_ptr,UserPubKey_ptr,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA384_mode,CC_PKCS1_NO_MGF,0,DataIn_ptr,CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER15)
+
+/*!
+@brief CC_RsaPkcs1V15Sha512Verify implements the RSASSA-PKCS1v15 Verify algorithm as defined in PKCS#1 v1.5, but without operating the HASH function -
+it assumes that the DataIn_ptr data has already been hashed using SHA512.
+
+*/
+#define CC_RsaPkcs1V15Sha512Verify(UserContext_ptr,UserPubKey_ptr,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA512_mode,CC_PKCS1_NO_MGF,0,DataIn_ptr,CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER15)
+
+/*!
+@brief CC_RsaPssVerify implements the RSASSA-PKCS1v21 Verify algorithm as defined in PKCS#1 v2.1.
+*/
+
+#define CC_RsaPssVerify(UserContext_ptr,UserPubKey_ptr,hashFunc,MGF,SaltLen,DataIn_ptr,DataInSize,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,hashFunc,MGF,SaltLen,DataIn_ptr,DataInSize,Sig_ptr,CC_PKCS1_VER21)
+
+/*!
+@brief CC_RsaPssSha1Verify implements the PKCS1v21 Verify algorithm as defined in PKCS#1 v2.1, but without operating the HASH function -
+it assumes the DataIn_ptr has already been hashed using SHA1.
+*/
+
+#define CC_RsaPssSha1Verify(UserContext_ptr,UserPubKey_ptr,MGF,SaltLen,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA1_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER21)
+/*!
+@brief CC_RsaPssSha224Verify implements the PKCS1v21 Verify algorithm as defined in PKCS#1 v2.1, but without operating the HASH function -
+it assumes the DataIn_ptr has already been hashed using SHA224.
+*/
+
+#define CC_RsaPssSha224Verify(UserContext_ptr,UserPubKey_ptr,MGF,SaltLen,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA224_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER21)
+
+/*!
+@brief CC_RsaPssSha256Verify implements the PKCS1v21 Verify algorithm as defined in PKCS#1 v2.1, but without operating the HASH function -
+it assumes the DataIn_ptr has already been hashed using SHA256.
+*/
+
+#define CC_RsaPssSha256Verify(UserContext_ptr,UserPubKey_ptr,MGF,SaltLen,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA256_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER21)
+
+
+/*!
+@brief CC_RsaPssSha384Verify implements the PKCS1v21 Verify algorithm as defined in PKCS#1 v2.1, but without operating the HASH function -
+it assumes the DataIn_ptr has already been hashed using SHA384.
+
+*/
+
+#define CC_RsaPssSha384Verify(UserContext_ptr,UserPubKey_ptr,MGF,SaltLen,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA384_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER21)
+
+
+/*!
+@brief CC_RsaPssSha512Verify implements the PKCS1v21 Verify algorithm as defined in PKCS#1 v2.1, but without operating the HASH function -
+it assumes the DataIn_ptr has already been hashed using SHA512.
+*/
+
+#define CC_RsaPssSha512Verify(UserContext_ptr,UserPubKey_ptr,MGF,SaltLen,DataIn_ptr,Sig_ptr)\
+    CC_RsaVerify(UserContext_ptr,UserPubKey_ptr,CC_RSA_After_SHA512_mode,MGF,SaltLen,DataIn_ptr,CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES,Sig_ptr,CC_PKCS1_VER21)
+
+/**********************************************************************************************************/
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
+#endif /* _CC_RSA_SCHEMES_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_types.h b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_types.h
new file mode 100644
index 0000000..f40c0a8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/crypto_api/cc_rsa_types.h
@@ -0,0 +1,573 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_RSA_TYPES_H
+#define _CC_RSA_TYPES_H
+
+#include "cc_hash_defs.h"
+#include "cc_bitops.h"
+#include "cc_pka_defs_hw.h"
+#include "cc_pal_types.h"
+#include "cc_pal_compiler.h"
+
+#ifdef CC_SOFT_KEYGEN
+#include "ccsw_rsa_shared_types.h"
+#endif
+#ifdef USE_MBEDTLS_CRYPTOCELL
+#include "md.h"
+#else
+#include "cc_hash.h"
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/*!
+@file
+@@brief This file contains all the enums and definitions that are used for the CryptoCell RSA APIs.
+@defgroup cc_rsa_types CryptoCell RSA used definitions and enums
+@{
+@ingroup cc_rsa
+*/
+
+/************************ Defines ******************************/
+
+/*! Definition of HASH context size. */
+#define CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS CC_HASH_USER_CTX_SIZE_IN_WORDS
+
+/*! Maximal key size in bytes. */
+#define CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES    (CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / CC_BITS_IN_BYTE)
+
+/*! Minimal key size in bits. */
+#define CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS              512
+/*! Valid key size multiplications in RSA. */
+#define CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS         256
+
+/*! Maximal RSA generated key size in bits. */
+#define CC_RSA_MAX_KEY_GENERATION_SIZE_BITS   CC_RSA_MAX_KEY_GENERATION_HW_SIZE_BITS
+
+/* FIPS 184-4 definitions for allowed RSA and FFC DH key sizes */
+/*! FIPS 184-4 allowed key size - 1024 bits. */
+#define CC_RSA_FIPS_KEY_SIZE_1024_BITS   1024
+/*! FIPS 184-4 allowed key size - 2048 bits. */
+#define CC_RSA_FIPS_KEY_SIZE_2048_BITS   2048
+/*! FIPS 184-4 allowed key size - 3072 bits. */
+#define CC_RSA_FIPS_KEY_SIZE_3072_BITS   3072
+/*! FIPS 184-4 allowed modulus size in bits. */
+#define CC_RSA_FIPS_MODULUS_SIZE_BITS    CC_RSA_FIPS_KEY_SIZE_2048_BITS
+
+/*! FIPS 184-4 DH key size - 1024 bits. */
+#define CC_DH_FIPS_KEY_SIZE_1024_BITS    1024
+/*! FIPS 184-4 DH key size - 2048 bits. */
+#define CC_DH_FIPS_KEY_SIZE_2048_BITS    2048
+
+
+/*! Salt length definition - if the salt length is not available in verify operation, the user can use this define and the algorithm will
+    calculate the salt length alone*/
+/*!\note Security wise: it is not recommended to use this flag.*/
+#define CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN                     0xFFFF
+
+/*! Minimal public exponent value */
+#define CC_RSA_MIN_PUB_EXP_VALUE  3
+/*! Minimal private exponent value */
+#define CC_RSA_MIN_PRIV_EXP_VALUE 1
+
+/* The maximum buffer size for the 'H' value */
+/*! Temporary buffer size definition.*/
+#define CC_RSA_TMP_BUFF_SIZE (CC_RSA_OAEP_ENCODE_MAX_MASKDB_SIZE + CC_RSA_OAEP_ENCODE_MAX_SEEDMASK_SIZE + CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS*sizeof(uint32_t) + sizeof(CCHashResultBuf_t))
+
+/*! Hash structure definition.*/
+#define CCPkcs1HashFunc_t CCHashOperationMode_t
+
+/*! OAEP maximal H length.*/
+#define CC_RSA_OAEP_MAX_HLEN                            CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES
+
+/*! MGF1 definitions */
+#define CC_RSA_MGF_2_POWER_32                       65535 /*!< \internal 0xFFFF This is the 2^32 of the 2^32*hLen boundary check */
+/*! MGF1 definitions */
+#define CC_RSA_SIZE_OF_T_STRING_BYTES                   (CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS*sizeof(uint32_t))
+
+/***********************************************************
+ *
+ * RSA PKCS#1 v2.1 DEFINES
+ *
+ ***********************************************************/
+ /*! Size of OEAP seed. */
+#define CC_RSA_OAEP_ENCODE_MAX_SEEDMASK_SIZE            CC_RSA_OAEP_MAX_HLEN
+/*! Maximal PSS salt size. */
+#define CC_RSA_PSS_SALT_LENGTH                  CC_RSA_OAEP_MAX_HLEN
+/*! PSS padding length. */
+#define CC_RSA_PSS_PAD1_LEN                 8
+/*! OAEP encode mask size. */
+#define CC_RSA_OAEP_ENCODE_MAX_MASKDB_SIZE              (CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS*sizeof(uint32_t)) /*!< \internal For OAEP Encode; the max size is emLen */
+/*! OAEP decode mask size. */
+#define CC_RSA_OAEP_DECODE_MAX_DBMASK_SIZE              (CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS*sizeof(uint32_t)) /*!< \internal For OAEP Decode; the max size is emLen */
+
+/************************ Enums ********************************/
+
+/*! Defines the enum for the HASH operation mode. */
+typedef enum
+{
+    CC_RSA_HASH_MD5_mode  = 0,  /*!< For Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 1.5 only.
+                         The input data will be hashed with MD5 */
+    CC_RSA_HASH_SHA1_mode = 1,  /*!< The input data will be hashed with SHA1. */
+    CC_RSA_HASH_SHA224_mode = 2,  /*!< The input data will be hashed with SHA224. */
+    CC_RSA_HASH_SHA256_mode = 3,  /*!< The input data will be hashed with SHA256. */
+    CC_RSA_HASH_SHA384_mode = 4,  /*!< The input data will be hashed with SHA384. */
+    CC_RSA_HASH_SHA512_mode = 5,    /*!< The input data will be hashed with SHA512. */
+    CC_RSA_After_MD5_mode = 6,      /*!< For PKCS1 v1.5 only. The input data is a digest of MD5 and will not be hashed. */
+    CC_RSA_After_SHA1_mode = 7, /*!< The input data is a digest of SHA1 and will not be hashed. */
+    CC_RSA_After_SHA224_mode = 8,   /*!< The input data is a digest of SHA224 and will not be hashed. */
+    CC_RSA_After_SHA256_mode = 9,   /*!< The input data is a digest of SHA256 and will not be hashed. */
+    CC_RSA_After_SHA384_mode = 10,  /*!< The input data is a digest of SHA384 and will not be hashed. */
+    CC_RSA_After_SHA512_mode = 11,  /*!< The input data is a digest of SHA512 and will not be hashed. */
+    CC_RSA_After_HASH_NOT_KNOWN_mode = 12,    /*!< \internal used only for Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 1.5 -
+                            possible to perform verify operation without hash mode input,
+                        the hash mode is derived from the signature.*/
+    CC_RSA_HASH_NO_HASH_mode = 13,  /*!< Used for Public-Key Cryptography Standards (PKCS) #1 RSA Cryptography Specifications Version 1.5 Encrypt and Decrypt.*/
+    CC_RSA_HASH_NumOfModes,     /*!< Maximal number of hash operations modes. */
+
+    CC_RSA_HASH_OpModeLast  = 0x7FFFFFFF, /*! Reserved.*/
+
+}CCRsaHashOpMode_t;
+
+
+/*! Defines the enum of the RSA decryption mode. */
+typedef enum
+{
+    CC_RSA_NoCrt = 10, /*!< Decryption no CRT mode.*/
+    CC_RSA_Crt   = 11, /*!< Decryption CRT mode.*/
+
+    CC_RSADecryptionNumOfOptions, /*! Reserved.*/
+
+    CC_RSA_DecryptionModeLast= 0x7FFFFFFF, /*! Reserved.*/
+
+}CCRsaDecryptionMode_t;
+
+/*! RSA Key source definition. */
+typedef enum
+{
+    CC_RSA_ExternalKey = 1, /*!< External key.*/
+    CC_RSA_InternalKey = 2, /*!< Internal key.*/
+
+    CC_RSA_KeySourceLast= 0x7FFFFFFF, /*!< Reserved. */
+
+}CCRsaKeySource_t;
+
+/*! MGF values. */
+typedef enum
+{
+    CC_PKCS1_MGF1 = 0,   /*! MGF1. */
+    CC_PKCS1_NO_MGF = 1, /*! No MGF. */
+    CC_RSA_NumOfMGFFunctions, /*! Maximal number of MGF options. */
+
+    CC_PKCS1_MGFLast= 0x7FFFFFFF, /*! Reserved.*/
+
+}CCPkcs1Mgf_t;
+
+/*! Defines the enum of the various PKCS1 versions. */
+typedef enum
+{
+    CC_PKCS1_VER15 = 0, /*! PKCS1 version 15. */
+    CC_PKCS1_VER21 = 1, /*! PKCS1 version 21. */
+
+    CC_RSA_NumOf_PKCS1_versions, /*! Maximal number of PKCS versions. */
+
+    CC_PKCS1_versionLast= 0x7FFFFFFF, /*! Reserved.*/
+
+}CCPkcs1Version_t;
+
+
+/*! Enum defining primality testing mode in Rabin-Miller
+   and Lucas-Lehmer tests (internal tests). */
+typedef enum
+{
+        /* P and Q primes */
+    CC_RSA_PRIME_TEST_MODE     = 0, /*!< PRIME test. */
+
+        /* FFC (DH, DSA) primes */
+    CC_DH_PRIME_TEST_MODE      = 1, /*!< DH Prime test. */
+
+    CC_RSA_DH_PRIME_TEST_OFF_MODE /*!< Reserved.*/
+
+}CCRsaDhPrimeTestMode_t;
+
+/************************ Public and private key database Structs ******************************/
+
+/* .................. The public key definitions ...................... */
+/* --------------------------------------------------------------------- */
+
+/*! Public key data structure (used internally). */
+typedef struct
+{
+    /*! RSA modulus buffer. */
+    uint32_t n[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! RSA modulus size in bits. */
+    uint32_t nSizeInBits;
+
+    /*! RSA public exponent buffer. */
+    uint32_t e[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! RSA public exponent buffer. */
+    uint32_t eSizeInBits;
+
+    /*! Buffer for internal usage.*/
+    uint32_t ccRSAIntBuff[CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS];
+
+}CCRsaPubKey_t;
+
+/*! The public key's user structure prototype. This structure must be saved by the user, and is used as input to the RSA functions
+(such as ::CC_RsaSchemesEncrypt etc.) */
+typedef struct CCRsaUserPubKey_t
+{
+    /*! Validation tag. */
+    uint32_t valid_tag;
+    /*! Public key data. */
+    uint32_t  PublicKeyDbBuff[ sizeof(CCRsaPubKey_t)/sizeof(uint32_t) + 1 ];
+
+
+}CCRsaUserPubKey_t;
+
+/* .................. The private key definitions ...................... */
+/* --------------------------------------------------------------------- */
+
+/*! Private key on non-CRT mode data structure (used internally). */
+typedef struct
+{
+    /*! RSA private exponent buffer. */
+    uint32_t d[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! RSA private exponent size in bits. */
+    uint32_t dSizeInBits;
+
+    /*! RSA public exponent buffer. */
+    uint32_t e[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! RSA public exponent size in bits. */
+    uint32_t eSizeInBits;
+
+}CCRsaPrivNonCrtKey_t;
+
+/*! Private key on CRT mode data structure (used internally). */
+/* use small CRT buffers */
+typedef struct
+{
+    /*! First factor buffer. */
+    uint32_t P[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    /*! First factor size in bits. */
+    uint32_t PSizeInBits;
+
+    /*! Second factor buffer. */
+    uint32_t Q[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    /*! Second factor size in bits. */
+    uint32_t QSizeInBits;
+
+    /*! First CRT exponent buffer. */
+    uint32_t dP[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    /*! First CRT exponent size in bits. */
+    uint32_t dPSizeInBits;
+
+    /*! Second CRT exponent buffer. */
+    uint32_t dQ[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    /*! Second CRT exponent size in bits. */
+    uint32_t dQSizeInBits;
+
+    /*! First CRT coefficient buffer. */
+    uint32_t qInv[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS/2];
+    /*! First CRT coefficient size in bits. */
+    uint32_t qInvSizeInBits;
+
+}CCRsaPrivCrtKey_t;
+
+
+/*! Private key data structure (used internally). */
+typedef struct
+{
+    /*! RSA modulus buffer. */
+    uint32_t n[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! RSA modulus size in bits. */
+    uint32_t nSizeInBits;
+
+    /*! Decryption operation mode. */
+    CCRsaDecryptionMode_t OperationMode;
+
+    /*! Key source ( internal or external ). */
+    CCRsaKeySource_t KeySource;
+
+
+    /*! Union between the CRT and non-CRT data structures. */
+    union
+    {
+        CCRsaPrivNonCrtKey_t NonCrt; /*!< Non CRT data structure. */
+        CCRsaPrivCrtKey_t    Crt;    /*!< CRT data structure. */
+    }PriveKeyDb;
+
+    /*! Internal buffer. */
+    uint32_t ccRSAPrivKeyIntBuff[CC_PKA_PRIV_KEY_BUFF_SIZE_IN_WORDS];
+
+}CCRsaPrivKey_t;
+
+/*! The private key's user structure prototype. This structure must be saved by the user, and is used as input to the RSA functions
+(such as ::CC_RsaSchemesDecrypt etc.). */
+typedef struct CCRsaUserPrivKey_t
+{
+    /*! Validation tag.*/
+    uint32_t valid_tag;
+    /*! Private key data. */
+    uint32_t  PrivateKeyDbBuff[ sizeof(CCRsaPrivKey_t)/sizeof(uint32_t) + 1 ] ;
+
+}CCRsaUserPrivKey_t;
+
+/*! Temporary buffers for RSA usage. */
+typedef struct CCRsaPrimeData_t
+{
+   /* The aligned input and output data buffers */
+    uint32_t DataIn[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];   /*!< Temporary buffer for data in.*/
+    uint32_t DataOut[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];  /*!< Temporary buffer for data out.*/
+    /*! Temporary buffer for internal data.*/
+    uint8_t  InternalBuff[CC_RSA_TMP_BUFF_SIZE] CC_PAL_COMPILER_ALIGN (4);
+
+}CCRsaPrimeData_t;
+
+/*! KG data type. */
+typedef union CCRsaKgData_t
+{
+    /*! RSA Key Generation buffers definitions. */
+    struct
+    {
+        /* The aligned input and output data buffers */
+        /*! First factor buffer. */
+        uint32_t p[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS / 2];
+        /*! Second factor buffer. */
+        uint32_t q[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS / 2];
+        union {
+            /*! Internal buffer. */
+            uint32_t ccRSAKGDataIntBuff[CC_PKA_KGDATA_BUFF_SIZE_IN_WORDS];
+            #ifdef CC_SOFT_KEYGEN
+            /* # added for compatibility with size of KGData SW type */
+            uint32_t TempbuffExp[PKI_KEY_GEN_TEMP_BUFF_SIZE_WORDS];
+            #endif
+        }kg_buf;
+    }KGData;
+
+    /*! Buffers for internal usage. */
+    union {
+        /*! Internally used buffer.*/
+            struct {
+            CCRsaPrimeData_t    PrimData;
+        }primExt;
+        #ifdef CC_SOFT_KEYGEN
+        /* # added for compatibility with size of SW CCRsaPrivKey_t type */
+            SwSharedRSAPrimeData_t SW_Shared_PrimData;
+        #endif
+    }prim;
+}CCRsaKgData_t;
+
+ /*************
+ *  RSA contexts
+ **************/
+/************************ CryptoCell RSA struct for Private Key ******************************/
+
+
+/*! Context definition for operations that use the RSA private key. */
+typedef struct
+{
+
+    /*! Private key data.  */
+    CCRsaUserPrivKey_t PrivUserKey;
+
+    /*! RSA PKCS#1 Version 1.5 or 2.1 */
+    uint8_t   PKCS1_Version;
+
+    /*! MGF to be used for the PKCS1 Ver 2.1 sign or verify operations. */
+    uint8_t MGF_2use;
+
+    /*! Salt random length for PKCS#1 PSS Ver 2.1*/
+    uint16_t SaltLen;
+
+    /*! Internal buffer. */
+    CCRsaPrimeData_t  PrimeData;
+
+    /*! HASH context buffer. */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    mbedtls_md_context_t RsaHashCtx;
+#else
+    uint32_t RsaHashCtxBuff[CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS];
+#endif
+
+    /*! HASH result buffer. */
+    CCHashResultBuf_t        HASH_Result;
+    /*! HASH result size in words. */
+    uint16_t                  HASH_Result_Size;
+    /*! RSA HASH operation mode (all modes RSA supports).*/
+    CCRsaHashOpMode_t    RsaHashOperationMode;
+    /*! HASH operation mode.*/
+    CCHashOperationMode_t HashOperationMode;
+    /*! HASH block size (in words).*/
+    uint16_t                  HashBlockSize;
+    /*! HASH flag. */
+    bool doHash;
+
+    /* Used for sensitive data manipulation in the context space, which is safer and which saves stack space */
+    /*! Internal buffer.*/
+    uint32_t EBD[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! Internal bufffer used size in bits. */
+    uint32_t EBDSizeInBits;
+
+    /* Used for sensitive data manipulation in the context space, which is safer and which saves stack space */
+    /*! Internal buffer.*/
+    uint8_t  T_Buf[CC_RSA_SIZE_OF_T_STRING_BYTES];
+    /*! Internal buffer used size.*/
+    uint16_t T_BufSize;
+
+    /*! Buffer for the use of the Ber encoder in the case of PKCS#1 Ver 1.5. */
+    uint32_t  BER[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! Ber encoder buffer size.*/
+    uint16_t  BERSize;
+
+    /*! Internal buffer.*/
+    uint8_t DummyBufAESBlockSize[16];
+
+}RSAPrivContext_t;
+
+/*! The user's context prototype - the argument type that is passed by the user
+   to the RSA APIs. The context saves the state of the operation and must be saved by the user
+   till the end of the APIs flow . */
+typedef struct CCRsaPrivUserContext_t
+{
+    /*! Validation tag. */
+    uint32_t valid_tag;
+    /*! Internally used value.*/
+    uint32_t AES_iv;
+    /*! Private data context buffer. */
+    uint8_t  context_buff[ sizeof(RSAPrivContext_t) + sizeof(uint32_t)] CC_PAL_COMPILER_ALIGN (4);  /* must be aligned to 4 */
+
+}CCRsaPrivUserContext_t;
+
+
+/************************ CryptoCell RSA struct for Public Key ******************************/
+
+/*! Context definition for operations that use the RSA public key. */
+typedef struct
+{
+
+    /*! RSA public key structure. */
+    CCRsaUserPubKey_t PubUserKey;
+
+    /*! Public key size in bytes */
+    uint32_t nSizeInBytes;
+
+    /*! RSA PKCS#1 Version 1.5 or 2.1 */
+    uint8_t   PKCS1_Version;
+
+    /*! MGF to be used for the PKCS1 Ver 2.1 Sign or Verify operations */
+    uint8_t MGF_2use;
+
+    /*! Salt random length for PKCS#1 PSS Ver 2.1*/
+    uint16_t SaltLen;
+
+    /*! Internal buffer. */
+    CCRsaPrimeData_t  PrimeData;
+
+    /*! HASH context. */
+#ifdef USE_MBEDTLS_CRYPTOCELL
+    mbedtls_md_context_t RsaHashCtx;
+#else
+    uint32_t RsaHashCtxBuff[CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS];
+#endif
+    /*! HASH result buffer. */
+    CCHashResultBuf_t        HASH_Result;
+    /*! HASH result size. */
+    uint16_t                  HASH_Result_Size; /* denotes the length, in words, of the hash function output */
+    /*! RSA HASH operation mode (all modes RSA supports). */
+    CCRsaHashOpMode_t    RsaHashOperationMode;
+    /*! HASH operation mode. */
+    CCHashOperationMode_t HashOperationMode;
+    /*! HASH block size. */
+    uint16_t                  HashBlockSize; /*in words*/
+    /*! HASH flag.*/
+    bool doHash;
+
+    /* Used for sensitive data manipulation in the context space, which is safer and which saves stack space */
+    /*! Internal buffer.*/
+    uint32_t EBD[CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS];
+    /*! Internal bufffer used size in bits. */
+    uint32_t EBDSizeInBits;
+
+    /* Used for sensitive data manipulation in the context space, which is safer and which saves stack space */
+    /*! Internal buffer.*/
+    uint8_t T_Buf[CC_RSA_SIZE_OF_T_STRING_BYTES];
+    /*! Internal buffer used size.*/
+    uint16_t T_BufSize;
+
+    /*! Internal buffer.*/
+    uint8_t DummyBufAESBlockSize[16];
+
+}RSAPubContext_t;
+
+
+/*! Temporary buffers for the RSA usage. */
+typedef struct CCRsaPubUserContext_t
+{
+    /*! Validation tag. */
+    uint32_t valid_tag;
+    /*! Internally used value.*/
+    uint32_t AES_iv;
+    /*! Public data context buffer. */
+    uint32_t  context_buff[ sizeof(RSAPubContext_t)/sizeof(uint32_t) + 1] ;
+
+}CCRsaPubUserContext_t;
+
+
+
+/*! Required for internal FIPS verification for RSA key generation. */
+typedef struct CCRsaKgFipsContext_t{
+    /*! Internal buffer. */
+    CCRsaPrimeData_t    primData;
+    /*! Buffer used for decryption. */
+    uint8_t         decBuff[((CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS/CC_BITS_IN_BYTE) - 2*(CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES) -2)];
+    /*! Buffer used for encryption. */
+    uint8_t         encBuff[CC_RSA_FIPS_MODULUS_SIZE_BITS/CC_BITS_IN_BYTE];
+}CCRsaKgFipsContext_t;
+
+/*! Required for internal FIPS verification for RSA KAT. The RSA KAT tests are defined for Public-Key Cryptography Standards (PKCS) #1 RSA*
+    Cryptography Specifications Version 2.1 with modulus key size of 2048.      */
+typedef struct CCRsaFipsKatContext_t{
+    /*! RSA user's key (either public or private).*/
+    union {
+        /*! RSA user's public key. */
+        CCRsaUserPubKey_t   userPubKey;     // used for RsaEnc and RsaVerify
+        /*! RSA user's private key. */
+        CCRsaUserPrivKey_t   userPrivKey;  // used for RsaDec and RsaSign
+    }userKey;
+    /*! RSA user's context (either public or private).*/
+    union {
+        /*! RSA user's private context. */
+        CCRsaPrivUserContext_t userPrivContext;  // used for RsaSign
+        /*! RSA public user's context. */
+        CCRsaPubUserContext_t userPubContext;  // used for RsaVerify
+        /*! Internal buffers. */
+        CCRsaPrimeData_t    primData;  // used for RsaEnc and RsaDec
+    }userContext;
+    /*! RSA user's data. */
+    union {
+        struct {   // used for RsaEnc and RsaDec
+            /*! Buffer for encrypted data. */
+            uint8_t     encBuff[CC_RSA_FIPS_MODULUS_SIZE_BITS/CC_BITS_IN_BYTE];
+            /*! Buffer for decrypted data. */
+            uint8_t     decBuff[((CC_RSA_FIPS_MODULUS_SIZE_BITS/CC_BITS_IN_BYTE) - 2*(CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES) -2)];
+        }userOaepData;
+        /*! Buffer for Signed data. */
+        uint8_t         signBuff[CC_RSA_FIPS_MODULUS_SIZE_BITS/CC_BITS_IN_BYTE]; // used for RsaSign and RsaVerify
+    }userData;
+}CCRsaFipsKatContext_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/aes_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/aes_alt.h
new file mode 100644
index 0000000..5323543
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/aes_alt.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_AES_ALT_H
+#define MBEDTLS_AES_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* padlock.c and aesni.c rely on these values! */
+#define MBEDTLS_AES_ENCRYPT     1 /**< AES encryption. */
+#define MBEDTLS_AES_DECRYPT     0 /**< AES decryption. */
+
+/* Error codes in range 0x0020-0x0022 */
+#define MBEDTLS_ERR_AES_INVALID_KEY_LENGTH                -0x0020  /**< Invalid key length. */
+#define MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH              -0x0022  /**< Invalid data input length. */
+
+/* Error codes in range 0x0023-0x0025 */
+#define MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE               -0x0023  /**< Feature not available. For example, an unsupported AES key size. */
+#define MBEDTLS_ERR_AES_HW_ACCEL_FAILED                   -0x0025  /**< AES hardware accelerator failed. */
+
+
+// hide internal implementation of the struct. Allocate enough space for it.
+#define MBEDTLS_AES_CONTEXT_SIZE_IN_WORDS 24
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          AES context structure
+ *
+ * \note           Max len of key - 256.
+ */
+typedef struct
+{
+    uint32_t buf[MBEDTLS_AES_CONTEXT_SIZE_IN_WORDS];
+} mbedtls_aes_context;
+
+
+#if defined(MBEDTLS_CIPHER_MODE_XTS)
+/**
+ * \brief The AES XTS context-type definition.
+ */
+typedef struct mbedtls_aes_xts_context
+{
+    mbedtls_aes_context crypt; /*!< The AES context to use for AES block
+                                        encryption or decryption. */
+    mbedtls_aes_context tweak; /*!< The AES context used for tweak
+                                        computation. */
+} mbedtls_aes_xts_context;
+#endif /* MBEDTLS_CIPHER_MODE_XTS */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* aes_alt.h */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/cc_ecc_internal.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/cc_ecc_internal.h
new file mode 100644
index 0000000..a11c622
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/cc_ecc_internal.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_CC_ECC_INTERNAL_H
+#define MBEDTLS_CC_ECC_INTERNAL_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#if defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) || defined(MBEDTLS_ECDSA_GENKEY_ALT)
+/*
+ * Generate a keypair with configurable base point
+ */
+int cc_ecp_gen_keypair_base( mbedtls_ecp_group *grp,
+                             const mbedtls_ecp_point *G,
+                             mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng );
+
+/*
+ * Generate key pair, wrapper for conventional base point
+ */
+int cc_ecp_gen_keypair( mbedtls_ecp_group *grp,
+                             mbedtls_mpi *d, mbedtls_ecp_point *Q,
+                             int (*f_rng)(void *, unsigned char *, size_t),
+                             void *p_rng );
+
+#endif /* MBEDTLS_ECDH_GEN_PUBLIC_ALT || MBEDTLS_ECDSA_GENKEY_ALT*/
+
+#if defined(MBEDTLS_ECDH_COMPUTE_SHARED_ALT)
+/*
+ * Multiplication R = m * P
+ */
+int cc_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
+             const mbedtls_mpi *m, const mbedtls_ecp_point *P,
+             int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
+
+#endif /* MBEDTLS_ECDH_COMPUTE_SHARED_ALT */
+
+#endif //MBEDTLS_CC_ECC_INTERNAL_H
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/ccm_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/ccm_alt.h
new file mode 100644
index 0000000..32d7ed6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/ccm_alt.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_CCM_ALT_H
+#define MBEDTLS_CCM_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+#include <stdint.h>
+#include "mbedtls/cipher.h"
+
+
+#define MBEDTLS_ERR_CCM_BAD_INPUT      -0x000D /**< Bad input parameters to function. */
+#define MBEDTLS_ERR_CCM_AUTH_FAILED    -0x000F /**< Authenticated decryption failed. */
+
+/* hide internal implementation of the struct. Allocate enough space for it.*/
+#define MBEDTLS_CCM_CONTEXT_SIZE_IN_WORDS 264
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          The CCM context-type definition. The CCM context is passed
+ *                 to the APIs called.
+ */
+typedef struct {
+    uint32_t buf[MBEDTLS_CCM_CONTEXT_SIZE_IN_WORDS];
+}
+mbedtls_ccm_context;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CCM_ALT_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/chacha20_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/chacha20_alt.h
new file mode 100644
index 0000000..b473b9e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/chacha20_alt.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_CHACHA20_ALT_H
+#define MBEDTLS_CHACHA20_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#include <stddef.h>
+#include <stdint.h>
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+/*! The size of the ChaCha user-context in words. */
+#define MBEDTLS_CHACHA_USER_CTX_SIZE_IN_WORDS         17
+/*! The size of the ChaCha block in Bytes. */
+#define MBEDTLS_CHACHA_BLOCK_SIZE_BYTES               64
+/*! The size of the ChaCha block in Bytes. As defined in rfc7539 */
+#define MBEDTLS_CHACHA_NONCE_SIZE_BYTES                12
+/*! The size of the ChaCha key in Bytes. */
+#define MBEDTLS_CHACHA_KEY_SIZE_BYTES                 32
+/*! Internal type to identify 12 byte nonce */
+#define MBEDTLS_CHACHA_NONCE_SIZE_12BYTE_TYPE         1
+
+/*! The definition of the 12-Byte array of the nonce buffer. */
+typedef uint8_t mbedtls_chacha_nonce[MBEDTLS_CHACHA_NONCE_SIZE_BYTES];
+
+/*! The definition of the key buffer of the ChaCha engine. */
+typedef uint8_t mbedtls_chacha_key[MBEDTLS_CHACHA_KEY_SIZE_BYTES];
+
+#if defined(MBEDTLS_CHACHA20_ALT)
+
+typedef struct
+{
+    uint32_t buf[MBEDTLS_CHACHA_USER_CTX_SIZE_IN_WORDS];
+}
+mbedtls_chacha20_context;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* chacha20_alt.h */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/chachapoly_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/chachapoly_alt.h
new file mode 100644
index 0000000..83be138
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/chachapoly_alt.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _MBEDTLS_CHACHAPOLY_ALT_H
+#define _MBEDTLS_CHACHAPOLY_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/************************ Defines ******************************/
+
+#if defined(MBEDTLS_CHACHAPOLY_ALT)
+
+
+#define MBEDTLS_CHACHAPOLY_KEY_SIZE_BYTES 32
+
+
+typedef struct mbedtls_chachapoly_context
+{
+    unsigned char key[MBEDTLS_CHACHAPOLY_KEY_SIZE_BYTES];
+}
+mbedtls_chachapoly_context;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* chachapoly_alt.h */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/cmac_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/cmac_alt.h
new file mode 100644
index 0000000..cac7a8a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/cmac_alt.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_CMAC_ALT_H
+#define MBEDTLS_CMAC_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+
+#include <stddef.h>
+#include <stdint.h>
+
+
+/* hide internal implementation of the struct. Allocate enough space for it.*/
+#define MBEDTLS_CMAC_CONTEXT_SIZE_IN_WORDS          33
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          CMAC cipher context structure
+ */
+struct mbedtls_cmac_context_t{
+    /*! Internal buffer */
+    uint32_t buf[MBEDTLS_CMAC_CONTEXT_SIZE_IN_WORDS];
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_CMAC_ALT_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-mps2-freertos.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-mps2-freertos.h
new file mode 100644
index 0000000..bef1d5e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-mps2-freertos.h
@@ -0,0 +1,3273 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ *      library/aria.c
+ *      library/timing.c
+ *      include/mbedtls/bn_mul.h
+ *
+ * Required by:
+ *      MBEDTLS_AESNI_C
+ *      MBEDTLS_PADLOCK_C
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define MBEDTLS_HAVE_ASM
+
+/**
+ * \def MBEDTLS_NO_UDBL_DIVISION
+ *
+ * The platform lacks support for double-width integer division (64-bit
+ * division on a 32-bit platform, 128-bit division on a 64-bit platform).
+ *
+ * Used in:
+ *      include/mbedtls/bignum.h
+ *      library/bignum.c
+ *
+ * The bignum code uses double-width division to speed up some operations.
+ * Double-width division is often implemented in software that needs to
+ * be linked with the program. The presence of a double-width integer
+ * type is usually detected automatically through preprocessor macros,
+ * but the automatic detection cannot know whether the code needs to
+ * and can be linked with an implementation of division for that type.
+ * By default division is assumed to be usable if the type is present.
+ * Uncomment this option to prevent the use of double-width division.
+ *
+ * Note that division for the native integer type is always required.
+ * Furthermore, a 64-bit type is always required even on a 32-bit
+ * platform, but it need not support multiplication or division. In some
+ * cases it is also desirable to disable some double-width operations. For
+ * example, if double-width division is implemented in software, disabling
+ * it can reduce code size in some embedded targets.
+ */
+//#define MBEDTLS_NO_UDBL_DIVISION
+
+/**
+ * \def MBEDTLS_NO_64BIT_MULTIPLICATION
+ *
+ * The platform lacks support for 32x32 -> 64-bit multiplication.
+ *
+ * Used in:
+ *      library/poly1305.c
+ *
+ * Some parts of the library may use multiplication of two unsigned 32-bit
+ * operands with a 64-bit result in order to speed up computations. On some
+ * platforms, this is not available in hardware and has to be implemented in
+ * software, usually in a library provided by the toolchain.
+ *
+ * Sometimes it is not desirable to have to link to that library. This option
+ * removes the dependency of that library on platforms that lack a hardware
+ * 64-bit multiplier by embedding a software implementation in Mbed TLS.
+ *
+ * Note that depending on the compiler, this may decrease performance compared
+ * to using the library function provided by the toolchain.
+ */
+//#define MBEDTLS_NO_64BIT_MULTIPLICATION
+
+/**
+ * \def MBEDTLS_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define MBEDTLS_HAVE_SSE2
+
+/**
+ * \def MBEDTLS_HAVE_TIME
+ *
+ * System has time.h and time().
+ * The time does not need to be correct, only time differences are used,
+ * by contrast with MBEDTLS_HAVE_TIME_DATE
+ *
+ * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT,
+ * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and
+ * MBEDTLS_PLATFORM_STD_TIME.
+ *
+ * Comment if your system does not support time functions
+ */
+#define MBEDTLS_HAVE_TIME
+
+/**
+ * \def MBEDTLS_HAVE_TIME_DATE
+ *
+ * System has time.h, time(), and an implementation for
+ * mbedtls_platform_gmtime_r() (see below).
+ * The time needs to be correct (not necesarily very accurate, but at least
+ * the date should be correct). This is used to verify the validity period of
+ * X.509 certificates.
+ *
+ * Comment if your system does not have a correct clock.
+ *
+ * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
+ * behaves similarly to the gmtime_r() function from the C standard. Refer to
+ * the documentation for mbedtls_platform_gmtime_r() for more information.
+ *
+ * \note It is possible to configure an implementation for
+ * mbedtls_platform_gmtime_r() at compile-time by using the macro
+ * MBEDTLS_PLATFORM_GMTIME_R_ALT.
+ */
+#define MBEDTLS_HAVE_TIME_DATE
+
+/**
+ * \def MBEDTLS_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default mbed TLS uses the system-provided calloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY without the
+ * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
+ * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
+ * free() function pointer at runtime.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
+ * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
+ * alternate function at compile time.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+#define MBEDTLS_PLATFORM_MEMORY
+
+/**
+ * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. calloc() to
+ * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a
+ * MBEDTLS_PLATFORM_XXX_MACRO.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def MBEDTLS_PLATFORM_EXIT_ALT
+ *
+ * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the
+ * function in the platform abstraction layer.
+ *
+ * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will
+ * provide a function "mbedtls_platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require MBEDTLS_PLATFORM_C to be defined!
+ *
+ * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows;
+ * it will be enabled automatically by check_config.h
+ *
+ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * MBEDTLS_PLATFORM_XXX_MACRO!
+ *
+ * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define MBEDTLS_PLATFORM_EXIT_ALT
+//#define MBEDTLS_PLATFORM_TIME_ALT
+//#define MBEDTLS_PLATFORM_FPRINTF_ALT
+//#define MBEDTLS_PLATFORM_PRINTF_ALT
+//#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
+//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
+
+/**
+ * \def MBEDTLS_DEPRECATED_WARNING
+ *
+ * Mark deprecated functions so that they generate a warning if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * This only works with GCC and Clang. With other compilers, you may want to
+ * use MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Uncomment to get warnings on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_WARNING
+
+/**
+ * \def MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Remove deprecated functions so that they generate an error if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * Uncomment to get errors on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_REMOVED
+
+/**
+ * \def MBEDTLS_CHECK_PARAMS
+ *
+ * This configuration option controls whether the library validates more of
+ * the parameters passed to it.
+ *
+ * When this flag is not defined, the library only attempts to validate an
+ * input parameter if: (1) they may come from the outside world (such as the
+ * network, the filesystem, etc.) or (2) not validating them could result in
+ * internal memory errors such as overflowing a buffer controlled by the
+ * library. On the other hand, it doesn't attempt to validate parameters whose
+ * values are fully controlled by the application (such as pointers).
+ *
+ * When this flag is defined, the library additionally attempts to validate
+ * parameters that are fully controlled by the application, and should always
+ * be valid if the application code is fully correct and trusted.
+ *
+ * For example, when a function accepts as input a pointer to a buffer that may
+ * contain untrusted data, and its documentation mentions that this pointer
+ * must not be NULL:
+ * - the pointer is checked to be non-NULL only if this option is enabled
+ * - the content of the buffer is always validated
+ *
+ * When this flag is defined, if a library function receives a parameter that
+ * is invalid, it will:
+ * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
+ *   call to the function mbedtls_param_failed()
+ * - immediately return (with a specific error code unless the function
+ *   returns void and can't communicate an error).
+ *
+ * When defining this flag, you also need to:
+ * - either provide a definition of the function mbedtls_param_failed() in
+ *   your application (see platform_util.h for its prototype) as the library
+ *   calls that function, but does not provide a default definition for it,
+ * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
+ *   below if the above mechanism is not flexible enough to suit your needs.
+ *   See the documentation of this macro later in this file.
+ *
+ * Uncomment to enable validation of application-controlled parameters.
+ */
+//#define MBEDTLS_CHECK_PARAMS
+
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: mbed TLS feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_TIMING_ALT
+ *
+ * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(),
+ * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay()
+ *
+ * Only works if you have MBEDTLS_TIMING_C enabled.
+ *
+ * You will need to provide a header "timing_alt.h" and an implementation at
+ * compile time.
+ */
+//#define MBEDTLS_TIMING_ALT
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternate core implementation of a symmetric crypto, an arithmetic or hash
+ * module (e.g. platform specific assembly optimized implementations). Keep
+ * in mind that the function prototypes should remain the same.
+ *
+ * This replaces the whole module. If you only want to replace one of the
+ * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer
+ * provide the "struct mbedtls_aes_context" definition and omit the base
+ * function declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * module.
+ *
+ * \warning   MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ *            use constitutes a security risk. If possible, we recommend
+ *            avoiding dependencies on them, and considering stronger message
+ *            digests and ciphers instead.
+ *
+ */
+#define MBEDTLS_AES_ALT
+//#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_ARIA_ALT
+//#define MBEDTLS_BLOWFISH_ALT
+//#define MBEDTLS_CAMELLIA_ALT
+#define MBEDTLS_CCM_ALT
+#define MBEDTLS_CHACHA20_ALT
+#define MBEDTLS_CHACHAPOLY_ALT
+#define MBEDTLS_CMAC_ALT
+//#define MBEDTLS_DES_ALT
+#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_ECJPAKE_ALT
+#define MBEDTLS_GCM_ALT
+//#define MBEDTLS_NIST_KW_ALT
+//#define MBEDTLS_MD2_ALT
+//#define MBEDTLS_MD4_ALT
+//#define MBEDTLS_MD5_ALT
+#define MBEDTLS_POLY1305_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+#define MBEDTLS_RSA_ALT
+#define MBEDTLS_SHA1_ALT
+#define MBEDTLS_SHA256_ALT
+//#define MBEDTLS_SHA512_ALT
+//#define MBEDTLS_XTEA_ALT
+
+/*
+ * When replacing the elliptic curve module, pleace consider, that it is
+ * implemented with two .c files:
+ *      - ecp.c
+ *      - ecp_curves.c
+ * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT
+ * macros as described above. The only difference is that you have to make sure
+ * that you provide functionality for both .c files.
+ */
+//#define MBEDTLS_ECP_ALT
+
+/**
+ * \def MBEDTLS_MD2_PROCESS_ALT
+ *
+ * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
+ * alternate core implementation of symmetric crypto or hash function. Keep in
+ * mind that function prototypes should remain the same.
+ *
+ * This replaces only one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
+ * no longer provide the mbedtls_sha1_process() function, but it will still provide
+ * the other function (using your mbedtls_sha1_process() function) and the definition
+ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
+ * with this definition.
+ *
+ * \note Because of a signature change, the core AES encryption and decryption routines are
+ *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
+ *       respectively. When setting up alternative implementations, these functions should
+ *       be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ *       must stay untouched.
+ *
+ * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ *       MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
+ *       tables.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ *
+ * \warning   MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ *            constitutes a security risk. If possible, we recommend avoiding
+ *            dependencies on them, and considering stronger message digests
+ *            and ciphers instead.
+ *
+ */
+//#define MBEDTLS_MD2_PROCESS_ALT
+//#define MBEDTLS_MD4_PROCESS_ALT
+//#define MBEDTLS_MD5_PROCESS_ALT
+//#define MBEDTLS_RIPEMD160_PROCESS_ALT
+//#define MBEDTLS_SHA1_PROCESS_ALT
+//#define MBEDTLS_SHA256_PROCESS_ALT
+//#define MBEDTLS_SHA512_PROCESS_ALT
+//#define MBEDTLS_DES_SETKEY_ALT
+//#define MBEDTLS_DES_CRYPT_ECB_ALT
+//#define MBEDTLS_DES3_CRYPT_ECB_ALT
+//#define MBEDTLS_AES_SETKEY_ENC_ALT
+//#define MBEDTLS_AES_SETKEY_DEC_ALT
+//#define MBEDTLS_AES_ENCRYPT_ALT
+//#define MBEDTLS_AES_DECRYPT_ALT
+#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+#define MBEDTLS_ECDSA_VERIFY_ALT
+#define MBEDTLS_ECDSA_SIGN_ALT
+#define MBEDTLS_ECDSA_GENKEY_ALT
+
+/**
+ * \def MBEDTLS_ECP_INTERNAL_ALT
+ *
+ * Expose a part of the internal interface of the Elliptic Curve Point module.
+ *
+ * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternative core implementation of elliptic curve arithmetic. Keep in mind
+ * that function prototypes should remain the same.
+ *
+ * This partially replaces one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation
+ * is still present and it is used for group structures not supported by the
+ * alternative.
+ *
+ * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT
+ * and implementing the following functions:
+ *      unsigned char mbedtls_internal_ecp_grp_capable(
+ *          const mbedtls_ecp_group *grp )
+ *      int  mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
+ *      void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp )
+ * The mbedtls_internal_ecp_grp_capable function should return 1 if the
+ * replacement functions implement arithmetic for the given group and 0
+ * otherwise.
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are
+ * called before and after each point operation and provide an opportunity to
+ * implement optimized set up and tear down instructions.
+ *
+ * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and
+ * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac
+ * function, but will use your mbedtls_internal_ecp_double_jac if the group is
+ * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when
+ * receives it as an argument). If the group is not supported then the original
+ * implementation is used. The other functions and the definition of
+ * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your
+ * implementation of mbedtls_internal_ecp_double_jac and
+ * mbedtls_internal_ecp_grp_capable must be compatible with this definition.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ */
+/* Required for all the functions in this section */
+//#define MBEDTLS_ECP_INTERNAL_ALT
+/* Support for Weierstrass curves with Jacobi representation */
+//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
+//#define MBEDTLS_ECP_ADD_MIXED_ALT
+//#define MBEDTLS_ECP_DOUBLE_JAC_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
+/* Support for curves with Montgomery arithmetic */
+//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT
+//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
+//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
+
+/**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ *
+ * Uncomment this macro to let mbed TLS use your own implementation of a
+ * hardware entropy collector.
+ *
+ * Your function must be called \c mbedtls_hardware_poll(), have the same
+ * prototype as declared in entropy_poll.h, and accept NULL as first argument.
+ *
+ * Uncomment to use your own hardware entropy collector.
+ */
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+
+/**
+ * \def MBEDTLS_AES_ROM_TABLES
+ *
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_ROM_TABLES
+
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
+/**
+ * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define MBEDTLS_CAMELLIA_SMALL_MEMORY
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CBC
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+//#define MBEDTLS_CIPHER_MODE_CFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CTR
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback mode (OFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_XTS
+ *
+ * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES.
+ */
+//#define MBEDTLS_CIPHER_MODE_XTS
+
+/**
+ * \def MBEDTLS_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+ */
+//#define MBEDTLS_CIPHER_NULL_CIPHER
+
+/**
+ * \def MBEDTLS_CIPHER_PADDING_PKCS7
+ *
+ * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+//#define MBEDTLS_CIPHER_PADDING_PKCS7
+//#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+//#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+//#define MBEDTLS_CIPHER_PADDING_ZEROS
+
+/**
+ * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels with virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ *      MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+//#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module.  By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+
+#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+/* CryptoCell only supports BP256R1 brainpool curve at this stage */
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+//#define MBEDTLS_ECP_DP_CURVE448_ENABLED
+
+/**
+ * \def MBEDTLS_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#define MBEDTLS_ECP_NIST_OPTIM
+
+/**
+ * \def MBEDTLS_ECP_RESTARTABLE
+ *
+ * Enable "non-blocking" ECC operations that can return early and be resumed.
+ *
+ * This allows various functions to pause by returning
+ * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
+ * order to further progress and eventually complete their operation. This is
+ * controlled through mbedtls_ecp_set_max_ops() which limits the maximum
+ * number of ECC operations a function may perform before pausing; see
+ * mbedtls_ecp_set_max_ops() for more information.
+ *
+ * This is useful in non-threaded environments if you want to avoid blocking
+ * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
+ *
+ * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
+ */
+//#define MBEDTLS_ECP_RESTARTABLE
+
+/**
+ * \def MBEDTLS_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDTLS_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define MBEDTLS_ECDSA_DETERMINISTIC
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+ *
+ * Enable the PSK based ciphersuite modes in SSL / TLS.
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+ *
+ * Enable the DHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+ *
+ * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+ *
+ * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+ *
+ * Enable the RSA-only based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+ *
+ * Enable the DHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+ *
+ * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+ *
+ * Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Requires: MBEDTLS_ECJPAKE_C
+ *           MBEDTLS_SHA256_C
+ *           MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+/**
+ * \def MBEDTLS_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+//#define MBEDTLS_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def MBEDTLS_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of mbedtls_strerror() in
+ * third party libraries easier when MBEDTLS_ERROR_C is disabled
+ * (no effect when MBEDTLS_ERROR_C is enabled).
+ *
+ * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
+ * not using mbedtls_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * mbedtls_strerror()
+ */
+#define MBEDTLS_ERROR_STRERROR_DUMMY
+
+/**
+ * \def MBEDTLS_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: MBEDTLS_BIGNUM_C
+ */
+#define MBEDTLS_GENPRIME
+
+/**
+ * \def MBEDTLS_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+//#define MBEDTLS_FS_IO
+
+/**
+ * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * mbedtls_timing_hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def MBEDTLS_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: MBEDTLS_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both MBEDTLS_SHA256_C and
+ * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define MBEDTLS_ENTROPY_FORCE_SHA256
+
+/**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ *       determined in the platform layer, and can be modified at runtime and/or
+ *       compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ *       with regular fopen(), please make sure you make a seedfile with the
+ *       proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ *       least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ *       and written to or you will get an entropy source error! The default
+ *       implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ *       bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ *       given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/**
+ * \def MBEDTLS_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define MBEDTLS_MEMORY_DEBUG
+
+/**
+ * \def MBEDTLS_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *           GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define MBEDTLS_MEMORY_BACKTRACE
+
+/**
+ * \def MBEDTLS_PK_RSA_ALT_SUPPORT
+ *
+ * Support external private RSA keys (eg from a HSM) in the PK layer.
+ *
+ * Comment this macro to disable support for external private RSA keys.
+ */
+//#define MBEDTLS_PK_RSA_ALT_SUPPORT
+
+/**
+ * \def MBEDTLS_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDTLS_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#define MBEDTLS_PKCS1_V15
+
+/**
+ * \def MBEDTLS_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#define MBEDTLS_PKCS1_V21
+
+/**
+ * \def MBEDTLS_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem
+ * for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define MBEDTLS_RSA_NO_CRT
+
+/**
+ * \def MBEDTLS_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+#define MBEDTLS_SELF_TEST
+
+/**
+ * \def MBEDTLS_SHA256_SMALLER
+ *
+ * Enable an implementation of SHA-256 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * The default implementation is meant to be a reasonnable compromise between
+ * performance and size. This version optimizes more aggressively for size at
+ * the expense of performance. Eg on Cortex-M4 it reduces the size of
+ * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
+ * 30%.
+ *
+ * Uncomment to enable the smaller implementation of SHA256.
+ */
+//#define MBEDTLS_SHA256_SMALLER
+
+/**
+ * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, mbed TLS can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+//#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+
+/**
+ * \def MBEDTLS_SSL_ASYNC_PRIVATE
+ *
+ * Enable asynchronous external private key operations in SSL. This allows
+ * you to configure an SSL connection to call an external cryptographic
+ * module to perform private key operations instead of performing the
+ * operation inside the library.
+ *
+ */
+//#define MBEDTLS_SSL_ASYNC_PRIVATE
+
+/**
+ * \def MBEDTLS_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+ */
+//#define MBEDTLS_SSL_DEBUG_ALL
+
+/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
+ *
+ * Enable support for Encrypt-then-MAC, RFC 7366.
+ *
+ * This allows peers that both support it to use a more robust protection for
+ * ciphersuites using CBC, providing deep resistance against timing attacks
+ * on the padding or underlying cipher.
+ *
+ * This only affects CBC ciphersuites, and is useless if none is defined.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Encrypt-then-MAC
+ */
+//#define MBEDTLS_SSL_ENCRYPT_THEN_MAC
+
+/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+ *
+ * Enable support for Extended Master Secret, aka Session Hash
+ * (draft-ietf-tls-session-hash-02).
+ *
+ * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * attacks, but it is recommended to always use it (even if you disable
+ * renegotiation), since it actually fixes a more fundamental issue in the
+ * original SSL/TLS design, and has implications beyond Triple Handshake.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Extended Master Secret.
+ */
+//#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+
+/**
+ * \def MBEDTLS_SSL_FALLBACK_SCSV
+ *
+ * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00).
+ *
+ * For servers, it is recommended to always enable this, unless you support
+ * only one version of TLS, or know for sure that none of your clients
+ * implements a fallback strategy.
+ *
+ * For clients, you only need this if you're using a fallback strategy, which
+ * is not recommended in the first place, unless you absolutely need it to
+ * interoperate with buggy (version-intolerant) servers.
+ *
+ * Comment this macro to disable support for FALLBACK_SCSV
+ */
+//#define MBEDTLS_SSL_FALLBACK_SCSV
+
+/**
+ * \def MBEDTLS_SSL_HW_RECORD_ACCEL
+ *
+ * Enable hooking functions in SSL module for hardware acceleration of
+ * individual records.
+ *
+ * Uncomment this macro to enable hooking functions.
+ */
+//#define MBEDTLS_SSL_HW_RECORD_ACCEL
+
+/**
+ * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING
+ *
+ * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0.
+ *
+ * This is a countermeasure to the BEAST attack, which also minimizes the risk
+ * of interoperability issues compared to sending 0-length records.
+ *
+ * Comment this macro to disable 1/n-1 record splitting.
+ */
+//#define MBEDTLS_SSL_CBC_RECORD_SPLITTING
+
+/**
+ * \def MBEDTLS_SSL_RENEGOTIATION
+ *
+ * Disable support for TLS renegotiation.
+ *
+ * The two main uses of renegotiation are (1) refresh keys on long-lived
+ * connections and (2) client authentication after the initial handshake.
+ * If you don't need renegotiation, it's probably better to disable it, since
+ * it has been associated with security issues in the past and is easy to
+ * misuse/misunderstand.
+ *
+ * Comment this to disable support for renegotiation.
+ *
+ * \note   Even if this option is disabled, both client and server are aware
+ *         of the Renegotiation Indication Extension (RFC 5746) used to
+ *         prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ *         (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ *          configuration of this extension).
+ *
+ */
+//#define MBEDTLS_SSL_RENEGOTIATION
+
+/**
+ * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to enable support for SSLv2 Client Hello messages.
+ */
+//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
+ * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+ *
+ * Pick the ciphersuite according to the client's preferences rather than ours
+ * in the SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to respect client's ciphersuite order
+ */
+//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+/**
+ * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+//#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+
+/**
+ * \def MBEDTLS_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+//#define MBEDTLS_SSL_PROTO_SSL3
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1 / DTLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
+ *           (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2 / DTLS 1.2
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_2
+
+/**
+ * \def MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Enable support for DTLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_1
+ *        or MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for DTLS
+ */
+//#define MBEDTLS_SSL_PROTO_DTLS
+
+/**
+ * \def MBEDTLS_SSL_ALPN
+ *
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+//#define MBEDTLS_SSL_ALPN
+
+/**
+ * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY
+ *
+ * Enable support for the anti-replay mechanism in DTLS.
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *           MBEDTLS_SSL_PROTO_DTLS
+ *
+ * \warning Disabling this is often a security risk!
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
+ *
+ * Comment this to disable anti-replay in DTLS.
+ */
+//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Enable support for HelloVerifyRequest on DTLS servers.
+ *
+ * This feature is highly recommended to prevent DTLS servers being used as
+ * amplifiers in DoS attacks against other hosts. It should always be enabled
+ * unless you know for sure amplification cannot be a problem in the
+ * environment in which your server operates.
+ *
+ * \warning Disabling this can ba a security risk! (see above)
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for HelloVerifyRequest.
+ */
+//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+ *
+ * Enable server-side support for clients that reconnect from the same port.
+ *
+ * Some clients unexpectedly close the connection and try to reconnect using the
+ * same source port. This needs special support from the server to handle the
+ * new connection securely, as described in section 4.2.8 of RFC 6347. This
+ * flag enables that support.
+ *
+ * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Comment this to disable support for clients reusing the source port.
+ */
+//#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+
+/**
+ * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+ *
+ * Enable support for a limit of records with bad MAC.
+ *
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+
+/**
+ * \def MBEDTLS_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ * Client-side, provides full support for session tickets (maintainance of a
+ * session store remains the responsibility of the application, though).
+ * Server-side, you also need to provide callbacks for writing and parsing
+ * tickets, including authenticated encryption and key management. Example
+ * callbacks are provided by MBEDTLS_SSL_TICKET_C.
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+//#define MBEDTLS_SSL_SESSION_TICKETS
+
+/**
+ * \def MBEDTLS_SSL_EXPORT_KEYS
+ *
+ * Enable support for exporting key block and master secret.
+ * This is required for certain users of TLS, e.g. EAP-TLS.
+ *
+ * Comment this macro to disable support for key export
+ */
+//#define MBEDTLS_SSL_EXPORT_KEYS
+
+/**
+ * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+//#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+ *
+ * Fallback to old (pre-2.7), non-conforming implementation of the truncated
+ * HMAC extension which also truncates the HMAC key. Note that this option is
+ * only meant for a transitory upgrade period and is likely to be removed in
+ * a future version of the library.
+ *
+ * \warning The old implementation is non-compliant and has a security weakness
+ *          (2^80 brute force attack on the HMAC key used for a single,
+ *          uninterrupted connection). This should only be enabled temporarily
+ *          when (1) the use of truncated HMAC is essential in order to save
+ *          bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
+ *          the fixed implementation yet (pre-2.7).
+ *
+ * \deprecated This option is deprecated and will likely be removed in a
+ *             future version of Mbed TLS.
+ *
+ * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
+ *
+ * Requires: MBEDTLS_SSL_TRUNCATED_HMAC
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+
+/**
+ * \def MBEDTLS_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define MBEDTLS_THREADING_ALT
+
+/**
+ * \def MBEDTLS_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+//#define MBEDTLS_THREADING_PTHREAD
+
+/**
+ * \def MBEDTLS_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via mbedtls_version_check_feature().
+ *
+ * Requires: MBEDTLS_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define MBEDTLS_VERSION_FEATURES
+
+/**
+ * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an extension in a v1 or v2 certificate.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+
+/**
+ * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an unknown critical extension.
+ *
+ * \warning Depending on your PKI use, enabling this can be a security risk!
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+
+/**
+ * \def MBEDTLS_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+//#define MBEDTLS_X509_CHECK_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+//#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT
+ *
+ * Enable parsing and verification of X.509 certificates, CRLs and CSRS
+ * signed with RSASSA-PSS (aka PKCS#1 v2.1).
+ *
+ * Comment this macro to disallow using RSASSA-PSS in certificates.
+ */
+//#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+
+/**
+ * \def MBEDTLS_ZLIB_SUPPORT
+ *
+ * If set, the SSL/TLS module uses ZLIB to support compression and
+ * decompression of packet data.
+ *
+ * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
+ * CRIME attack. Before enabling this option, you should examine with care if
+ * CRIME or similar exploits may be a applicable to your use case.
+ *
+ * \note Currently compression can't be used with DTLS.
+ *
+ * \deprecated This feature is deprecated and will be removed
+ *             in the next major revision of the library.
+ *
+ * Used in: library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This feature requires zlib library and headers to be present.
+ *
+ * Uncomment to enable use of ZLIB
+ */
+//#define MBEDTLS_ZLIB_SUPPORT
+/* \} name SECTION: mbed TLS feature support */
+
+/**
+ * \name SECTION: mbed TLS modules
+ *
+ * This section enables or disables entire modules in mbed TLS
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module:  library/aesni.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+//#define MBEDTLS_AESNI_C
+
+/**
+ * \def MBEDTLS_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module:  library/aes.c
+ * Caller:  library/cipher.c
+ *          library/pem.c
+ *          library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define MBEDTLS_AES_C
+
+/**
+ * \def MBEDTLS_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module:  library/arc4.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. If possible, we recommend avoidng dependencies on
+ *            it, and considering stronger ciphers instead.
+ *
+ */
+//#define MBEDTLS_ARC4_C
+
+/**
+ * \def MBEDTLS_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module:  library/asn1.c
+ * Caller:  library/x509.c
+ *          library/dhm.c
+ *          library/pkcs12.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ */
+#define MBEDTLS_ASN1_PARSE_C
+
+/**
+ * \def MBEDTLS_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module:  library/asn1write.c
+ * Caller:  library/ecdsa.c
+ *          library/pkwrite.c
+ *          library/x509_create.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ */
+#define MBEDTLS_ASN1_WRITE_C
+
+/**
+ * \def MBEDTLS_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module:  library/base64.c
+ * Caller:  library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define MBEDTLS_BASE64_C
+
+/**
+ * \def MBEDTLS_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module:  library/bignum.c
+ * Caller:  library/dhm.c
+ *          library/ecp.c
+ *          library/ecdsa.c
+ *          library/rsa.c
+ *          library/rsa_internal.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define MBEDTLS_BIGNUM_C
+
+/**
+ * \def MBEDTLS_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module:  library/blowfish.c
+ */
+//#define MBEDTLS_BLOWFISH_C
+
+/**
+ * \def MBEDTLS_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module:  library/camellia.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+//#define MBEDTLS_CAMELLIA_C
+
+/**
+ * \def MBEDTLS_ARIA_C
+ *
+ * Enable the ARIA block cipher.
+ *
+ * Module:  library/aria.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
+ */
+//#define MBEDTLS_ARIA_C
+
+/**
+ * \def MBEDTLS_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module:  library/ccm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#define MBEDTLS_CCM_C
+
+/**
+ * \def MBEDTLS_CERTS_C
+ *
+ * Enable the test certificates.
+ *
+ * Module:  library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+//#define MBEDTLS_CERTS_C
+
+/**
+ * \def MBEDTLS_CHACHA20_C
+ *
+ * Enable the ChaCha20 stream cipher.
+ *
+ * Module:  library/chacha20.c
+ */
+#define MBEDTLS_CHACHA20_C
+
+/**
+ * \def MBEDTLS_CHACHAPOLY_C
+ *
+ * Enable the ChaCha20-Poly1305 AEAD algorithm.
+ *
+ * Module:  library/chachapoly.c
+ *
+ * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
+ */
+#define MBEDTLS_CHACHAPOLY_C
+
+/**
+ * \def MBEDTLS_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module:  library/cipher.c
+ * Caller:  library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define MBEDTLS_CIPHER_C
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module:  library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+#define MBEDTLS_CMAC_C
+
+/**
+ * \def MBEDTLS_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-256-based random generator.
+ *
+ * Module:  library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_AES_C
+ *
+ * This module provides the CTR_DRBG AES-256 random number generator.
+ */
+#define MBEDTLS_CTR_DRBG_C
+
+/**
+ * \def MBEDTLS_DEBUG_C
+ *
+ * Enable the debug functions.
+ *
+ * Module:  library/debug.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+//#define MBEDTLS_DEBUG_C
+
+/**
+ * \def MBEDTLS_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module:  library/des.c
+ * Caller:  library/pem.c
+ *          library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_DES_C
+
+/**
+ * \def MBEDTLS_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module:  library/dhm.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      DHE-RSA, DHE-PSK
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+#define MBEDTLS_DHM_C
+
+/**
+ * \def MBEDTLS_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module:  library/ecdh.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDTLS_ECP_C
+ */
+#define MBEDTLS_ECDH_C
+
+/**
+ * \def MBEDTLS_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module:  library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
+ */
+#define MBEDTLS_ECDSA_C
+
+/**
+ * \def MBEDTLS_ECJPAKE_C
+ *
+ * Enable the elliptic curve J-PAKE library.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Module:  library/ecjpake.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECJPAKE
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
+ */
+//#define MBEDTLS_ECJPAKE_C
+
+/**
+ * \def MBEDTLS_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module:  library/ecp.c
+ * Caller:  library/ecdh.c
+ *          library/ecdsa.c
+ *          library/ecjpake.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
+ */
+#define MBEDTLS_ECP_C
+
+/**
+ * \def MBEDTLS_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module:  library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define MBEDTLS_ENTROPY_C
+
+/**
+ * \def MBEDTLS_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module:  library/error.c
+ * Caller:
+ *
+ * This module enables mbedtls_strerror().
+ */
+//#define MBEDTLS_ERROR_C
+
+/**
+ * \def MBEDTLS_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module:  library/gcm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define MBEDTLS_GCM_C
+
+/**
+ * \def MBEDTLS_HAVEGE_C
+ *
+ * Enable the HAVEGE random generator.
+ *
+ * Warning: the HAVEGE random generator is not suitable for virtualized
+ *          environments
+ *
+ * Warning: the HAVEGE random generator is dependent on timing and specific
+ *          processor traits. It is therefore not advised to use HAVEGE as
+ *          your applications primary random generator or primary entropy pool
+ *          input. As a secondary input to your entropy pool, it IS able add
+ *          the (limited) extra entropy it provides.
+ *
+ * Module:  library/havege.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_TIMING_C
+ *
+ * Uncomment to enable the HAVEGE random generator.
+ */
+//#define MBEDTLS_HAVEGE_C
+
+/**
+ * \def MBEDTLS_HKDF_C
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Module:  library/hkdf.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the Hashed Message Authentication Code
+ * (HMAC)-based key derivation function (HKDF).
+ */
+#define MBEDTLS_HKDF_C
+
+/**
+ * \def MBEDTLS_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module:  library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define MBEDTLS_HMAC_DRBG_C
+
+/**
+ * \def MBEDTLS_NIST_KW_C
+ *
+ * Enable the Key Wrapping mode for 128-bit block ciphers,
+ * as defined in NIST SP 800-38F. Only KW and KWP modes
+ * are supported. At the moment, only AES is approved by NIST.
+ *
+ * Module:  library/nist_kw.c
+ *
+ * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C
+ */
+#define MBEDTLS_NIST_KW_C
+
+/**
+ * \def MBEDTLS_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module:  library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define MBEDTLS_MD_C
+
+/**
+ * \def MBEDTLS_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module:  library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning   MD2 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD2_C
+
+/**
+ * \def MBEDTLS_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module:  library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning   MD4 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD4_C
+
+/**
+ * \def MBEDTLS_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module:  library/md5.c
+ * Caller:  library/md.c
+ *          library/pem.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD5_C
+
+/**
+ * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
+ * calls)
+ *
+ * Module:  library/memory_buffer_alloc.c
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *           MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def MBEDTLS_NET_C
+ *
+ * Enable the TCP and UDP over IPv6/IPv4 networking routines.
+ *
+ * \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
+ * and Windows. For other platforms, you'll want to disable it, and write your
+ * own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/net_sockets.c
+ *
+ * This module provides networking routines.
+ */
+//#define MBEDTLS_NET_C
+
+/**
+ * \def MBEDTLS_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module:  library/oid.c
+ * Caller:  library/asn1write.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ *          library/pkwrite.c
+ *          library/rsa.c
+ *          library/x509.c
+ *          library/x509_create.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#define MBEDTLS_OID_C
+
+/**
+ * \def MBEDTLS_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module:  library/padlock.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+//#define MBEDTLS_PADLOCK_C
+
+/**
+ * \def MBEDTLS_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/dhm.c
+ *          library/pkparse.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+#define MBEDTLS_PEM_PARSE_C
+
+/**
+ * \def MBEDTLS_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/pkwrite.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+#define MBEDTLS_PEM_WRITE_C
+
+/**
+ * \def MBEDTLS_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module:  library/pk.c
+ * Caller:  library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#define MBEDTLS_PK_C
+
+/**
+ * \def MBEDTLS_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module:  library/pkparse.c
+ * Caller:  library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#define MBEDTLS_PK_PARSE_C
+
+/**
+ * \def MBEDTLS_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module:  library/pkwrite.c
+ * Caller:  library/x509write.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#define MBEDTLS_PK_WRITE_C
+
+/**
+ * \def MBEDTLS_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module:  library/pkcs5.c
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+#define MBEDTLS_PKCS5_C
+
+/**
+ * \def MBEDTLS_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support.
+ *
+ * Module:  library/pkcs11.c
+ * Caller:  library/pk.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define MBEDTLS_PKCS11_C
+
+/**
+ * \def MBEDTLS_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module:  library/pkcs12.c
+ * Caller:  library/pkparse.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * Can use:  MBEDTLS_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+//#define MBEDTLS_PKCS12_C
+
+/**
+ * \def MBEDTLS_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
+ * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module:  library/platform.c
+ * Caller:  Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#define MBEDTLS_PLATFORM_C
+
+/**
+ * \def MBEDTLS_POLY1305_C
+ *
+ * Enable the Poly1305 MAC algorithm.
+ *
+ * Module:  library/poly1305.c
+ * Caller:  library/chachapoly.c
+ */
+#define MBEDTLS_POLY1305_C
+
+/**
+ * \def MBEDTLS_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module:  library/ripemd160.c
+ * Caller:  library/md.c
+ *
+ */
+//#define MBEDTLS_RIPEMD160_C
+
+/**
+ * \def MBEDTLS_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module:  library/rsa.c
+ *          library/rsa_internal.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ *      RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C
+ */
+#define MBEDTLS_RSA_C
+
+/**
+ * \def MBEDTLS_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module:  library/sha1.c
+ * Caller:  library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
+ * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_SHA1_C
+
+/**
+ * \def MBEDTLS_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module:  library/sha256.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define MBEDTLS_SHA256_C
+
+/**
+ * \def MBEDTLS_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ *
+ * Module:  library/sha512.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define MBEDTLS_SHA512_C
+
+/**
+ * \def MBEDTLS_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module:  library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_CACHE_C
+ */
+//#define MBEDTLS_SSL_CACHE_C
+
+/**
+ * \def MBEDTLS_SSL_COOKIE_C
+ *
+ * Enable basic implementation of DTLS cookies for hello verification.
+ *
+ * Module:  library/ssl_cookie.c
+ * Caller:
+ */
+//#define MBEDTLS_SSL_COOKIE_C
+
+/**
+ * \def MBEDTLS_SSL_TICKET_C
+ *
+ * Enable an implementation of TLS server-side callbacks for session tickets.
+ *
+ * Module:  library/ssl_ticket.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_CIPHER_C
+ */
+//#define MBEDTLS_SSL_TICKET_C
+
+/**
+ * \def MBEDTLS_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module:  library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+//#define MBEDTLS_SSL_CLI_C
+
+/**
+ * \def MBEDTLS_SSL_SRV_C
+ *
+ * Enable the SSL/TLS server code.
+ *
+ * Module:  library/ssl_srv.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS server support.
+ */
+//#define MBEDTLS_SSL_SRV_C
+
+/**
+ * \def MBEDTLS_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module:  library/ssl_tls.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ *           and at least one of the MBEDTLS_SSL_PROTO_XXX defines
+ *
+ * This module is required for SSL/TLS.
+ */
+//#define MBEDTLS_SSL_TLS_C
+
+/**
+ * \def MBEDTLS_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default mbed TLS assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
+ *
+ * Module:  library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either MBEDTLS_THREADING_ALT or
+ * MBEDTLS_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within mbed TLS
+ */
+//#define MBEDTLS_THREADING_C
+
+/**
+ * \def MBEDTLS_TIMING_C
+ *
+ * Enable the semi-portable timing interface.
+ *
+ * \note The provided implementation only works on POSIX/Unix (including Linux,
+ * BSD and OS X) and Windows. On other platforms, you can either disable that
+ * module and provide your own implementations of the callbacks needed by
+ * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide
+ * your own implementation of the whole module by setting
+ * \c MBEDTLS_TIMING_ALT in the current file.
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/timing.c
+ * Caller:  library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+//#define MBEDTLS_TIMING_C
+
+/**
+ * \def MBEDTLS_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module:  library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define MBEDTLS_VERSION_C
+
+/**
+ * \def MBEDTLS_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module:  library/x509.c
+ * Caller:  library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C,
+ *           MBEDTLS_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+//#define MBEDTLS_X509_USE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module:  library/x509_crt.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+//#define MBEDTLS_X509_CRT_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module:  library/x509_crl.c
+ * Caller:  library/x509_crt.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+//#define MBEDTLS_X509_CRL_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module:  library/x509_csr.c
+ * Caller:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+//#define MBEDTLS_X509_CSR_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module:  library/x509_create.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+//#define MBEDTLS_X509_CREATE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_WRITE_C
+ *
+ * Enable creating X.509 certificates.
+ *
+ * Module:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate creation.
+ */
+//#define MBEDTLS_X509_CRT_WRITE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module:  library/x509_csr_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+//#define MBEDTLS_X509_CSR_WRITE_C
+
+/**
+ * \def MBEDTLS_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module:  library/xtea.c
+ * Caller:
+ */
+//#define MBEDTLS_XTEA_C
+
+/* \} name SECTION: mbed TLS modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define MBEDTLS_MPI_WINDOW_SIZE            6 /**< Maximum windows size used. */
+//#define MBEDTLS_MPI_MAX_SIZE            1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN               48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+/*!  Maximal reseed counter - indicates maximal number of
+requests allowed between reseeds; according to NIST 800-90
+it is (2^48 - 1), our restriction is :  (int - 0xFFFF - 0xF ).*/
+#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL            0xFFF0 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_CTR_DRBG_MAX_INPUT                256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_CTR_DRBG_MAX_REQUEST             1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT           384 /**< Maximum size of (re)seed buffer */
+//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY              /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */
+
+/* HMAC_DRBG options */
+//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_HMAC_DRBG_MAX_INPUT           256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST        1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT      384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define MBEDTLS_ECP_MAX_BITS             521 /**< Maximum bit size of groups */
+//#define MBEDTLS_ECP_WINDOW_SIZE            6 /**< Maximum window size used */
+//#define MBEDTLS_ECP_FIXED_POINT_OPTIM      1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define MBEDTLS_ENTROPY_MAX_SOURCES                20 /**< Maximum number of sources supported */
+#define MBEDTLS_ENTROPY_MAX_GATHER                144 /**< Maximum amount requested from entropy sources */
+//#define MBEDTLS_ENTROPY_MIN_HARDWARE               32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */
+
+/* Memory buffer allocator options */
+//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE      4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define MBEDTLS_PLATFORM_STD_MEM_HDR   <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define MBEDTLS_PLATFORM_STD_CALLOC        calloc /**< Default allocator to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_FREE            free /**< Default free to use, can be undefined */
+#define MBEDTLS_PLATFORM_STD_CALLOC        pvPortCalloc /**< Default allocator to use, can be undefined */
+#define MBEDTLS_PLATFORM_STD_FREE            vPortFree /**< Default free to use, can be undefined */
+
+//#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
+
+/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
+/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
+//#define MBEDTLS_PLATFORM_CALLOC_MACRO          calloc /**< Default allocator macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_MACRO            time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+
+/**
+ * \brief       This macro is invoked by the library when an invalid parameter
+ *              is detected that is only checked with MBEDTLS_CHECK_PARAMS
+ *              (see the documentation of that option for context).
+ *
+ *              When you leave this undefined here, a default definition is
+ *              provided that invokes the function mbedtls_param_failed(),
+ *              which is declared in platform_util.h for the benefit of the
+ *              library, but that you need to define in your application.
+ *
+ *              When you define this here, this replaces the default
+ *              definition in platform_util.h (which no longer declares the
+ *              function mbedtls_param_failed()) and it is your responsibility
+ *              to make sure this macro expands to something suitable (in
+ *              particular, that all the necessary declarations are visible
+ *              from within the library - you can ensure that by providing
+ *              them in this file next to the macro definition).
+ *
+ *              Note that you may define this macro to expand to nothing, in
+ *              which case you don't have to worry about declarations or
+ *              definitions. However, you will then be notified about invalid
+ *              parameters only in non-void functions, and void function will
+ *              just silently return early on invalid parameters, which
+ *              partially negates the benefits of enabling
+ *              #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
+ *
+ * \param cond  The expression that should evaluate to true, but doesn't.
+ */
+//#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
+
+/* SSL Cache options */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
+
+/* SSL options */
+
+/** \def MBEDTLS_SSL_MAX_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming and outgoing plaintext fragments.
+ *
+ * This determines the size of both the incoming and outgoing TLS I/O buffers
+ * in such a way that both are capable of holding the specified amount of
+ * plaintext data, regardless of the protection mechanism used.
+ *
+ * To configure incoming and outgoing I/O buffers separately, use
+ * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN,
+ * which overwrite the value set by this option.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of both
+ * incoming and outgoing I/O buffers.
+ */
+//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_IN_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming plaintext fragments.
+ *
+ * This determines the size of the incoming TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option is undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of the incoming I/O buffer
+ * independently of the outgoing I/O buffer.
+ */
+//#define MBEDTLS_SSL_IN_CONTENT_LEN              16384
+
+/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of outgoing plaintext fragments.
+ *
+ * This determines the size of the outgoing TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * It is possible to save RAM by setting a smaller outward buffer, while keeping
+ * the default inward 16384 byte buffer to conform to the TLS specification.
+ *
+ * The minimum required outward buffer size is determined by the handshake
+ * protocol's usage. Handshaking will fail if the outward buffer is too small.
+ * The specific size requirement depends on the configured ciphers and any
+ * certificate data which is sent during the handshake.
+ *
+ * Uncomment to set the maximum plaintext size of the outgoing I/O buffer
+ * independently of the incoming I/O buffer.
+ */
+//#define MBEDTLS_SSL_OUT_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING
+ *
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ *
+ * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * to account for a reassembled handshake message of maximum size,
+ * together with its reassembly bitmap.
+ *
+ * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default)
+ * should be sufficient for all practical situations as it allows
+ * to reassembly a large handshake message (such as a certificate)
+ * while buffering multiple smaller handshake messages.
+ *
+ */
+//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING             32768
+
+//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
+//#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
+//#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+/* X509 options */
+//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
+//#define MBEDTLS_X509_MAX_FILE_PATH_LEN     512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
+
+/**
+ * Allow SHA-1 in the default TLS configuration for certificate signing.
+ * Without this build-time option, SHA-1 support must be activated explicitly
+ * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
+ * recommended because of it is possible to generate SHA-1 collisions, however
+ * this may be safe for legacy infrastructure where additional controls apply.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+
+/**
+ * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
+ * signature and ciphersuite selection. Without this build-time option, SHA-1
+ * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes.
+ * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
+ * default. At the time of writing, there is no practical attack on the use
+ * of SHA-1 in handshake signatures, hence this option is turned on by default
+ * to preserve compatibility with existing peers, but the general
+ * warning applies nonetheless:
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
+
+/**
+ * Uncomment the macro to let mbed TLS use your alternate implementation of
+ * mbedtls_platform_zeroize(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * mbedtls_platform_zeroize() is a widely used function across the library to
+ * zero a block of memory. The implementation is expected to be secure in the
+ * sense that it has been written to prevent the compiler from removing calls
+ * to mbedtls_platform_zeroize() as part of redundant code elimination
+ * optimizations. However, it is difficult to guarantee that calls to
+ * mbedtls_platform_zeroize() will not be optimized by the compiler as older
+ * versions of the C language standards do not provide a secure implementation
+ * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to
+ * configure their own implementation of mbedtls_platform_zeroize(), for
+ * example by using directives specific to their compiler, features from newer
+ * C standards (e.g using memset_s() in C11) or calling a secure memset() from
+ * their system (e.g explicit_bzero() in BSD).
+ */
+//#define MBEDTLS_PLATFORM_ZEROIZE_ALT
+
+/**
+ * Uncomment the macro to let Mbed TLS use your alternate implementation of
+ * mbedtls_platform_gmtime_r(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * gmtime() is not a thread-safe function as defined in the C standard. The
+ * library will try to use safer implementations of this function, such as
+ * gmtime_r() when available. However, if Mbed TLS cannot identify the target
+ * system, the implementation of mbedtls_platform_gmtime_r() will default to
+ * using the standard gmtime(). In this case, calls from the library to
+ * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
+ * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
+ * library are also guarded with this mutex to avoid race conditions. However,
+ * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
+ * unconditionally use the implementation for mbedtls_platform_gmtime_r()
+ * supplied at compile time.
+ */
+//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
+
+/* \} name SECTION: Customisation configuration options */
+
+/* Target and application specific configurations */
+//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h"
+
+#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE
+#endif
+
+/*
+ * Allow user to override any previous default.
+ *
+ * Use two macro names for that, as:
+ * - with yotta the prefix YOTTA_CFG_ is forced
+ * - without yotta is looks weird to have a YOTTA prefix.
+ */
+#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
+#elif defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#include "mbedtls/check_config.h"
+
+/* Allow compilation of FreeRTOS only in mbedtls library and not in ccproductionLib*/
+#if !defined(DX_PLAT_MPS2_PLUS)
+#include "FreeRTOS.h"
+#endif
+
+#endif /* MBEDTLS_CONFIG_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-mps2-no-os.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-mps2-no-os.h
new file mode 100644
index 0000000..017c9ec
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-mps2-no-os.h
@@ -0,0 +1,3266 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ *      library/aria.c
+ *      library/timing.c
+ *      include/mbedtls/bn_mul.h
+ *
+ * Required by:
+ *      MBEDTLS_AESNI_C
+ *      MBEDTLS_PADLOCK_C
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define MBEDTLS_HAVE_ASM
+
+/**
+ * \def MBEDTLS_NO_UDBL_DIVISION
+ *
+ * The platform lacks support for double-width integer division (64-bit
+ * division on a 32-bit platform, 128-bit division on a 64-bit platform).
+ *
+ * Used in:
+ *      include/mbedtls/bignum.h
+ *      library/bignum.c
+ *
+ * The bignum code uses double-width division to speed up some operations.
+ * Double-width division is often implemented in software that needs to
+ * be linked with the program. The presence of a double-width integer
+ * type is usually detected automatically through preprocessor macros,
+ * but the automatic detection cannot know whether the code needs to
+ * and can be linked with an implementation of division for that type.
+ * By default division is assumed to be usable if the type is present.
+ * Uncomment this option to prevent the use of double-width division.
+ *
+ * Note that division for the native integer type is always required.
+ * Furthermore, a 64-bit type is always required even on a 32-bit
+ * platform, but it need not support multiplication or division. In some
+ * cases it is also desirable to disable some double-width operations. For
+ * example, if double-width division is implemented in software, disabling
+ * it can reduce code size in some embedded targets.
+ */
+//#define MBEDTLS_NO_UDBL_DIVISION
+
+/**
+ * \def MBEDTLS_NO_64BIT_MULTIPLICATION
+ *
+ * The platform lacks support for 32x32 -> 64-bit multiplication.
+ *
+ * Used in:
+ *      library/poly1305.c
+ *
+ * Some parts of the library may use multiplication of two unsigned 32-bit
+ * operands with a 64-bit result in order to speed up computations. On some
+ * platforms, this is not available in hardware and has to be implemented in
+ * software, usually in a library provided by the toolchain.
+ *
+ * Sometimes it is not desirable to have to link to that library. This option
+ * removes the dependency of that library on platforms that lack a hardware
+ * 64-bit multiplier by embedding a software implementation in Mbed TLS.
+ *
+ * Note that depending on the compiler, this may decrease performance compared
+ * to using the library function provided by the toolchain.
+ */
+//#define MBEDTLS_NO_64BIT_MULTIPLICATION
+
+/**
+ * \def MBEDTLS_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define MBEDTLS_HAVE_SSE2
+
+/**
+ * \def MBEDTLS_HAVE_TIME
+ *
+ * System has time.h and time().
+ * The time does not need to be correct, only time differences are used,
+ * by contrast with MBEDTLS_HAVE_TIME_DATE
+ *
+ * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT,
+ * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and
+ * MBEDTLS_PLATFORM_STD_TIME.
+ *
+ * Comment if your system does not support time functions
+ */
+#define MBEDTLS_HAVE_TIME
+
+/**
+ * \def MBEDTLS_HAVE_TIME_DATE
+ *
+ * System has time.h, time(), and an implementation for
+ * mbedtls_platform_gmtime_r() (see below).
+ * The time needs to be correct (not necesarily very accurate, but at least
+ * the date should be correct). This is used to verify the validity period of
+ * X.509 certificates.
+ *
+ * Comment if your system does not have a correct clock.
+ *
+ * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
+ * behaves similarly to the gmtime_r() function from the C standard. Refer to
+ * the documentation for mbedtls_platform_gmtime_r() for more information.
+ *
+ * \note It is possible to configure an implementation for
+ * mbedtls_platform_gmtime_r() at compile-time by using the macro
+ * MBEDTLS_PLATFORM_GMTIME_R_ALT.
+ */
+#define MBEDTLS_HAVE_TIME_DATE
+
+/**
+ * \def MBEDTLS_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default mbed TLS uses the system-provided calloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY without the
+ * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
+ * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
+ * free() function pointer at runtime.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
+ * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
+ * alternate function at compile time.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+#define MBEDTLS_PLATFORM_MEMORY
+
+/**
+ * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. calloc() to
+ * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a
+ * MBEDTLS_PLATFORM_XXX_MACRO.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def MBEDTLS_PLATFORM_EXIT_ALT
+ *
+ * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the
+ * function in the platform abstraction layer.
+ *
+ * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will
+ * provide a function "mbedtls_platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require MBEDTLS_PLATFORM_C to be defined!
+ *
+ * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows;
+ * it will be enabled automatically by check_config.h
+ *
+ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * MBEDTLS_PLATFORM_XXX_MACRO!
+ *
+ * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define MBEDTLS_PLATFORM_EXIT_ALT
+//#define MBEDTLS_PLATFORM_TIME_ALT
+//#define MBEDTLS_PLATFORM_FPRINTF_ALT
+//#define MBEDTLS_PLATFORM_PRINTF_ALT
+//#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
+//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
+
+/**
+ * \def MBEDTLS_DEPRECATED_WARNING
+ *
+ * Mark deprecated functions so that they generate a warning if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * This only works with GCC and Clang. With other compilers, you may want to
+ * use MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Uncomment to get warnings on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_WARNING
+
+/**
+ * \def MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Remove deprecated functions so that they generate an error if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * Uncomment to get errors on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_REMOVED
+
+/**
+ * \def MBEDTLS_CHECK_PARAMS
+ *
+ * This configuration option controls whether the library validates more of
+ * the parameters passed to it.
+ *
+ * When this flag is not defined, the library only attempts to validate an
+ * input parameter if: (1) they may come from the outside world (such as the
+ * network, the filesystem, etc.) or (2) not validating them could result in
+ * internal memory errors such as overflowing a buffer controlled by the
+ * library. On the other hand, it doesn't attempt to validate parameters whose
+ * values are fully controlled by the application (such as pointers).
+ *
+ * When this flag is defined, the library additionally attempts to validate
+ * parameters that are fully controlled by the application, and should always
+ * be valid if the application code is fully correct and trusted.
+ *
+ * For example, when a function accepts as input a pointer to a buffer that may
+ * contain untrusted data, and its documentation mentions that this pointer
+ * must not be NULL:
+ * - the pointer is checked to be non-NULL only if this option is enabled
+ * - the content of the buffer is always validated
+ *
+ * When this flag is defined, if a library function receives a parameter that
+ * is invalid, it will:
+ * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
+ *   call to the function mbedtls_param_failed()
+ * - immediately return (with a specific error code unless the function
+ *   returns void and can't communicate an error).
+ *
+ * When defining this flag, you also need to:
+ * - either provide a definition of the function mbedtls_param_failed() in
+ *   your application (see platform_util.h for its prototype) as the library
+ *   calls that function, but does not provide a default definition for it,
+ * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
+ *   below if the above mechanism is not flexible enough to suit your needs.
+ *   See the documentation of this macro later in this file.
+ *
+ * Uncomment to enable validation of application-controlled parameters.
+ */
+//#define MBEDTLS_CHECK_PARAMS
+
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: mbed TLS feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_TIMING_ALT
+ *
+ * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(),
+ * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay()
+ *
+ * Only works if you have MBEDTLS_TIMING_C enabled.
+ *
+ * You will need to provide a header "timing_alt.h" and an implementation at
+ * compile time.
+ */
+//#define MBEDTLS_TIMING_ALT
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternate core implementation of a symmetric crypto, an arithmetic or hash
+ * module (e.g. platform specific assembly optimized implementations). Keep
+ * in mind that the function prototypes should remain the same.
+ *
+ * This replaces the whole module. If you only want to replace one of the
+ * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer
+ * provide the "struct mbedtls_aes_context" definition and omit the base function
+ * declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * module.
+ *
+ * \warning   MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ *            use constitutes a security risk. If possible, we recommend
+ *            avoiding dependencies on them, and considering stronger message
+ *            digests and ciphers instead.
+ *
+ */
+#define MBEDTLS_AES_ALT
+//#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_ARIA_ALT
+//#define MBEDTLS_BLOWFISH_ALT
+//#define MBEDTLS_CAMELLIA_ALT
+#define MBEDTLS_CCM_ALT
+#define MBEDTLS_GCM_ALT
+#define MBEDTLS_CHACHA20_ALT
+#define MBEDTLS_CHACHAPOLY_ALT
+#define MBEDTLS_CMAC_ALT
+//#define MBEDTLS_DES_ALT
+//#define MBEDTLS_ECJPAKE_ALT
+//#define MBEDTLS_XTEA_ALT
+//#define MBEDTLS_NIST_KW_ALT
+//#define MBEDTLS_MD2_ALT
+//#define MBEDTLS_MD4_ALT
+//#define MBEDTLS_MD5_ALT
+#define MBEDTLS_POLY1305_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+#define MBEDTLS_SHA1_ALT
+#define MBEDTLS_SHA256_ALT
+//#define MBEDTLS_SHA512_ALT
+#define MBEDTLS_RSA_ALT
+#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_XTEA_ALT
+
+/*
+ * When replacing the elliptic curve module, pleace consider, that it is
+ * implemented with two .c files:
+ *      - ecp.c
+ *      - ecp_curves.c
+ * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT
+ * macros as described above. The only difference is that you have to make sure
+ * that you provide functionality for both .c files.
+ */
+//#define MBEDTLS_ECP_ALT
+
+
+/**
+ * \def MBEDTLS_MD2_PROCESS_ALT
+ *
+ * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
+ * alternate core implementation of symmetric crypto or hash function. Keep in
+ * mind that function prototypes should remain the same.
+ *
+ * This replaces only one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
+ * no longer provide the mbedtls_sha1_process() function, but it will still provide
+ * the other function (using your mbedtls_sha1_process() function) and the definition
+ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
+ * with this definition.
+ *
+ * \note Because of a signature change, the core AES encryption and decryption routines are
+ *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
+ *       respectively. When setting up alternative implementations, these functions should
+ *       be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ *       must stay untouched.
+ *
+ * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ *       MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
+ *       tables.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ *
+ * \warning   MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ *            constitutes a security risk. If possible, we recommend avoiding
+ *            dependencies on them, and considering stronger message digests
+ *            and ciphers instead.
+ *
+ */
+//#define MBEDTLS_MD2_PROCESS_ALT
+//#define MBEDTLS_MD4_PROCESS_ALT
+//#define MBEDTLS_MD5_PROCESS_ALT
+//#define MBEDTLS_RIPEMD160_PROCESS_ALT
+//#define MBEDTLS_SHA1_PROCESS_ALT
+//#define MBEDTLS_SHA256_PROCESS_ALT
+//#define MBEDTLS_SHA512_PROCESS_ALT
+//#define MBEDTLS_DES_SETKEY_ALT
+//#define MBEDTLS_DES_CRYPT_ECB_ALT
+//#define MBEDTLS_DES3_CRYPT_ECB_ALT
+//#define MBEDTLS_AES_SETKEY_ENC_ALT
+//#define MBEDTLS_AES_SETKEY_DEC_ALT
+//#define MBEDTLS_AES_ENCRYPT_ALT
+//#define MBEDTLS_AES_DECRYPT_ALT
+#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+#define MBEDTLS_ECDSA_VERIFY_ALT
+#define MBEDTLS_ECDSA_SIGN_ALT
+#define MBEDTLS_ECDSA_GENKEY_ALT
+/**
+ * \def MBEDTLS_ECP_INTERNAL_ALT
+ *
+ * Expose a part of the internal interface of the Elliptic Curve Point module.
+ *
+ * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternative core implementation of elliptic curve arithmetic. Keep in mind
+ * that function prototypes should remain the same.
+ *
+ * This partially replaces one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation
+ * is still present and it is used for group structures not supported by the
+ * alternative.
+ *
+ * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT
+ * and implementing the following functions:
+ *      unsigned char mbedtls_internal_ecp_grp_capable(
+ *          const mbedtls_ecp_group *grp )
+ *      int  mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
+ *      void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp )
+ * The mbedtls_internal_ecp_grp_capable function should return 1 if the
+ * replacement functions implement arithmetic for the given group and 0
+ * otherwise.
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are
+ * called before and after each point operation and provide an opportunity to
+ * implement optimized set up and tear down instructions.
+ *
+ * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and
+ * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac
+ * function, but will use your mbedtls_internal_ecp_double_jac if the group is
+ * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when
+ * receives it as an argument). If the group is not supported then the original
+ * implementation is used. The other functions and the definition of
+ * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your
+ * implementation of mbedtls_internal_ecp_double_jac and
+ * mbedtls_internal_ecp_grp_capable must be compatible with this definition.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ */
+/* Required for all the functions in this section */
+//#define MBEDTLS_ECP_INTERNAL_ALT
+/* Support for Weierstrass curves with Jacobi representation */
+//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
+//#define MBEDTLS_ECP_ADD_MIXED_ALT
+//#define MBEDTLS_ECP_DOUBLE_JAC_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
+/* Support for curves with Montgomery arithmetic */
+//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT
+//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
+//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
+
+/**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ *
+ * Uncomment this macro to let mbed TLS use your own implementation of a
+ * hardware entropy collector.
+ *
+ * Your function must be called \c mbedtls_hardware_poll(), have the same
+ * prototype as declared in entropy_poll.h, and accept NULL as first argument.
+ *
+ * Uncomment to use your own hardware entropy collector.
+ */
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+
+/**
+ * \def MBEDTLS_AES_ROM_TABLES
+ *
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_ROM_TABLES
+
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
+/**
+ * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define MBEDTLS_CAMELLIA_SMALL_MEMORY
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CBC
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+//#define MBEDTLS_CIPHER_MODE_CFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CTR
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback mode (OFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_XTS
+ *
+ * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES.
+ */
+//#define MBEDTLS_CIPHER_MODE_XTS
+
+/**
+ * \def MBEDTLS_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+ */
+//#define MBEDTLS_CIPHER_NULL_CIPHER
+
+/**
+ * \def MBEDTLS_CIPHER_PADDING_PKCS7
+ *
+ * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+//#define MBEDTLS_CIPHER_PADDING_PKCS7
+//#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+//#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+//#define MBEDTLS_CIPHER_PADDING_ZEROS
+
+/**
+ * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels with virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ *      MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+//#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module.  By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+/* CryptoCell only supports BP256R1 at this stage */
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+//#define MBEDTLS_ECP_DP_CURVE448_ENABLED
+
+/**
+ * \def MBEDTLS_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#define MBEDTLS_ECP_NIST_OPTIM
+
+/**
+ * \def MBEDTLS_ECP_RESTARTABLE
+ *
+ * Enable "non-blocking" ECC operations that can return early and be resumed.
+ *
+ * This allows various functions to pause by returning
+ * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
+ * order to further progress and eventually complete their operation. This is
+ * controlled through mbedtls_ecp_set_max_ops() which limits the maximum
+ * number of ECC operations a function may perform before pausing; see
+ * mbedtls_ecp_set_max_ops() for more information.
+ *
+ * This is useful in non-threaded environments if you want to avoid blocking
+ * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
+ *
+ * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
+ */
+//#define MBEDTLS_ECP_RESTARTABLE
+
+/**
+ * \def MBEDTLS_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDTLS_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define MBEDTLS_ECDSA_DETERMINISTIC
+
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+ *
+ * Enable the PSK based ciphersuite modes in SSL / TLS.
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+ *
+ * Enable the DHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+ *
+ * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+ *
+ * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+ *
+ * Enable the RSA-only based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+ *
+ * Enable the DHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+ *
+ * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+ *
+ * Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Requires: MBEDTLS_ECJPAKE_C
+ *           MBEDTLS_SHA256_C
+ *           MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+/**
+ * \def MBEDTLS_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+//#define MBEDTLS_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def MBEDTLS_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of mbedtls_strerror() in
+ * third party libraries easier when MBEDTLS_ERROR_C is disabled
+ * (no effect when MBEDTLS_ERROR_C is enabled).
+ *
+ * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
+ * not using mbedtls_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * mbedtls_strerror()
+ */
+#define MBEDTLS_ERROR_STRERROR_DUMMY
+
+/**
+ * \def MBEDTLS_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: MBEDTLS_BIGNUM_C
+ */
+#define MBEDTLS_GENPRIME
+
+/**
+ * \def MBEDTLS_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+//#define MBEDTLS_FS_IO
+
+/**
+ * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * mbedtls_timing_hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def MBEDTLS_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: MBEDTLS_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both MBEDTLS_SHA256_C and
+ * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define MBEDTLS_ENTROPY_FORCE_SHA256
+
+/**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ *       determined in the platform layer, and can be modified at runtime and/or
+ *       compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ *       with regular fopen(), please make sure you make a seedfile with the
+ *       proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ *       least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ *       and written to or you will get an entropy source error! The default
+ *       implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ *       bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ *       given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/**
+ * \def MBEDTLS_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define MBEDTLS_MEMORY_DEBUG
+
+/**
+ * \def MBEDTLS_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *           GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define MBEDTLS_MEMORY_BACKTRACE
+
+/**
+ * \def MBEDTLS_PK_RSA_ALT_SUPPORT
+ *
+ * Support external private RSA keys (eg from a HSM) in the PK layer.
+ *
+ * Comment this macro to disable support for external private RSA keys.
+ */
+//#define MBEDTLS_PK_RSA_ALT_SUPPORT
+
+/**
+ * \def MBEDTLS_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDTLS_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#define MBEDTLS_PKCS1_V15
+
+/**
+ * \def MBEDTLS_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#define MBEDTLS_PKCS1_V21
+
+/**
+ * \def MBEDTLS_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define MBEDTLS_RSA_NO_CRT
+
+/**
+ * \def MBEDTLS_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+#define MBEDTLS_SELF_TEST
+
+/**
+ * \def MBEDTLS_SHA256_SMALLER
+ *
+ * Enable an implementation of SHA-256 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * The default implementation is meant to be a reasonnable compromise between
+ * performance and size. This version optimizes more aggressively for size at
+ * the expense of performance. Eg on Cortex-M4 it reduces the size of
+ * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
+ * 30%.
+ *
+ * Uncomment to enable the smaller implementation of SHA256.
+ */
+//#define MBEDTLS_SHA256_SMALLER
+
+/**
+ * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, mbed TLS can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+//#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+/**
+ * \def MBEDTLS_SSL_ASYNC_PRIVATE
+ *
+ * Enable asynchronous external private key operations in SSL. This allows
+ * you to configure an SSL connection to call an external cryptographic
+ * module to perform private key operations instead of performing the
+ * operation inside the library.
+ *
+ */
+//#define MBEDTLS_SSL_ASYNC_PRIVATE
+
+/**
+ * \def MBEDTLS_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+ */
+//#define MBEDTLS_SSL_DEBUG_ALL
+
+/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
+ *
+ * Enable support for Encrypt-then-MAC, RFC 7366.
+ *
+ * This allows peers that both support it to use a more robust protection for
+ * ciphersuites using CBC, providing deep resistance against timing attacks
+ * on the padding or underlying cipher.
+ *
+ * This only affects CBC ciphersuites, and is useless if none is defined.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Encrypt-then-MAC
+ */
+//#define MBEDTLS_SSL_ENCRYPT_THEN_MAC
+
+/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+ *
+ * Enable support for Extended Master Secret, aka Session Hash
+ * (draft-ietf-tls-session-hash-02).
+ *
+ * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * attacks, but it is recommended to always use it (even if you disable
+ * renegotiation), since it actually fixes a more fundamental issue in the
+ * original SSL/TLS design, and has implications beyond Triple Handshake.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Extended Master Secret.
+ */
+//#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+
+/**
+ * \def MBEDTLS_SSL_FALLBACK_SCSV
+ *
+ * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00).
+ *
+ * For servers, it is recommended to always enable this, unless you support
+ * only one version of TLS, or know for sure that none of your clients
+ * implements a fallback strategy.
+ *
+ * For clients, you only need this if you're using a fallback strategy, which
+ * is not recommended in the first place, unless you absolutely need it to
+ * interoperate with buggy (version-intolerant) servers.
+ *
+ * Comment this macro to disable support for FALLBACK_SCSV
+ */
+//#define MBEDTLS_SSL_FALLBACK_SCSV
+
+/**
+ * \def MBEDTLS_SSL_HW_RECORD_ACCEL
+ *
+ * Enable hooking functions in SSL module for hardware acceleration of
+ * individual records.
+ *
+ * Uncomment this macro to enable hooking functions.
+ */
+//#define MBEDTLS_SSL_HW_RECORD_ACCEL
+
+/**
+ * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING
+ *
+ * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0.
+ *
+ * This is a countermeasure to the BEAST attack, which also minimizes the risk
+ * of interoperability issues compared to sending 0-length records.
+ *
+ * Comment this macro to disable 1/n-1 record splitting.
+ */
+//#define MBEDTLS_SSL_CBC_RECORD_SPLITTING
+
+/**
+ * \def MBEDTLS_SSL_RENEGOTIATION
+ *
+ * Enable support for TLS renegotiation.
+ *
+ * The two main uses of renegotiation are (1) refresh keys on long-lived
+ * connections and (2) client authentication after the initial handshake.
+ * If you don't need renegotiation, it's probably better to disable it, since
+ * it has been associated with security issues in the past and is easy to
+ * misuse/misunderstand.
+ *
+ * Comment this to disable support for renegotiation.
+ *
+ * \note   Even if this option is disabled, both client and server are aware
+ *         of the Renegotiation Indication Extension (RFC 5746) used to
+ *         prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ *         (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ *          configuration of this extension).
+ *
+ */
+//#define MBEDTLS_SSL_RENEGOTIATION
+
+/**
+ * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to enable support for SSLv2 Client Hello messages.
+ */
+//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
+ * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+ *
+ * Pick the ciphersuite according to the client's preferences rather than ours
+ * in the SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to respect client's ciphersuite order
+ */
+//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+/**
+ * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+//#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+
+/**
+ * \def MBEDTLS_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+//#define MBEDTLS_SSL_PROTO_SSL3
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1 / DTLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
+ *           (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2 / DTLS 1.2
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_2
+
+/**
+ * \def MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Enable support for DTLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_1
+ *        or MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for DTLS
+ */
+//#define MBEDTLS_SSL_PROTO_DTLS
+
+/**
+ * \def MBEDTLS_SSL_ALPN
+ *
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+//#define MBEDTLS_SSL_ALPN
+
+/**
+ * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY
+ *
+ * Enable support for the anti-replay mechanism in DTLS.
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *           MBEDTLS_SSL_PROTO_DTLS
+ *
+ * \warning Disabling this is often a security risk!
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
+ *
+ * Comment this to disable anti-replay in DTLS.
+ */
+//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Enable support for HelloVerifyRequest on DTLS servers.
+ *
+ * This feature is highly recommended to prevent DTLS servers being used as
+ * amplifiers in DoS attacks against other hosts. It should always be enabled
+ * unless you know for sure amplification cannot be a problem in the
+ * environment in which your server operates.
+ *
+ * \warning Disabling this can ba a security risk! (see above)
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for HelloVerifyRequest.
+ */
+//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+ *
+ * Enable server-side support for clients that reconnect from the same port.
+ *
+ * Some clients unexpectedly close the connection and try to reconnect using the
+ * same source port. This needs special support from the server to handle the
+ * new connection securely, as described in section 4.2.8 of RFC 6347. This
+ * flag enables that support.
+ *
+ * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Comment this to disable support for clients reusing the source port.
+ */
+//#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+
+/**
+ * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+ *
+ * Enable support for a limit of records with bad MAC.
+ *
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+
+/**
+ * \def MBEDTLS_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ * Client-side, provides full support for session tickets (maintainance of a
+ * session store remains the responsibility of the application, though).
+ * Server-side, you also need to provide callbacks for writing and parsing
+ * tickets, including authenticated encryption and key management. Example
+ * callbacks are provided by MBEDTLS_SSL_TICKET_C.
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+//#define MBEDTLS_SSL_SESSION_TICKETS
+
+/**
+ * \def MBEDTLS_SSL_EXPORT_KEYS
+ *
+ * Enable support for exporting key block and master secret.
+ * This is required for certain users of TLS, e.g. EAP-TLS.
+ *
+ * Comment this macro to disable support for key export
+ */
+//#define MBEDTLS_SSL_EXPORT_KEYS
+
+/**
+ * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+//#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+ *
+ * Fallback to old (pre-2.7), non-conforming implementation of the truncated
+ * HMAC extension which also truncates the HMAC key. Note that this option is
+ * only meant for a transitory upgrade period and is likely to be removed in
+ * a future version of the library.
+ *
+ * \warning The old implementation is non-compliant and has a security weakness
+ *          (2^80 brute force attack on the HMAC key used for a single,
+ *          uninterrupted connection). This should only be enabled temporarily
+ *          when (1) the use of truncated HMAC is essential in order to save
+ *          bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
+ *          the fixed implementation yet (pre-2.7).
+ *
+ * \deprecated This option is deprecated and will likely be removed in a
+ *             future version of Mbed TLS.
+ *
+ * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
+ *
+ * Requires: MBEDTLS_SSL_TRUNCATED_HMAC
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+
+/**
+ * \def MBEDTLS_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define MBEDTLS_THREADING_ALT
+
+/**
+ * \def MBEDTLS_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+//#define MBEDTLS_THREADING_PTHREAD
+
+/**
+ * \def MBEDTLS_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via mbedtls_version_check_feature().
+ *
+ * Requires: MBEDTLS_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define MBEDTLS_VERSION_FEATURES
+
+/**
+ * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an extension in a v1 or v2 certificate.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+
+/**
+ * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an unknown critical extension.
+ *
+ * \warning Depending on your PKI use, enabling this can be a security risk!
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+
+/**
+ * \def MBEDTLS_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+//#define MBEDTLS_X509_CHECK_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+//#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT
+ *
+ * Enable parsing and verification of X.509 certificates, CRLs and CSRS
+ * signed with RSASSA-PSS (aka PKCS#1 v2.1).
+ *
+ * Comment this macro to disallow using RSASSA-PSS in certificates.
+ */
+//#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+
+/**
+ * \def MBEDTLS_ZLIB_SUPPORT
+ *
+ * If set, the SSL/TLS module uses ZLIB to support compression and
+ * decompression of packet data.
+ *
+ * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
+ * CRIME attack. Before enabling this option, you should examine with care if
+ * CRIME or similar exploits may be a applicable to your use case.
+ *
+ * \note Currently compression can't be used with DTLS.
+ *
+ * \deprecated This feature is deprecated and will be removed
+ *             in the next major revision of the library.
+ *
+ * Used in: library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This feature requires zlib library and headers to be present.
+ *
+ * Uncomment to enable use of ZLIB
+ */
+//#define MBEDTLS_ZLIB_SUPPORT
+/* \} name SECTION: mbed TLS feature support */
+
+/**
+ * \name SECTION: mbed TLS modules
+ *
+ * This section enables or disables entire modules in mbed TLS
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module:  library/aesni.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+//#define MBEDTLS_AESNI_C
+
+/**
+ * \def MBEDTLS_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module:  library/aes.c
+ * Caller:  library/cipher.c
+ *          library/pem.c
+ *          library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define MBEDTLS_AES_C
+
+/**
+ * \def MBEDTLS_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module:  library/arc4.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. If possible, we recommend avoidng dependencies on
+ *            it, and considering stronger ciphers instead.
+ *
+ */
+//#define MBEDTLS_ARC4_C
+
+/**
+ * \def MBEDTLS_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module:  library/asn1.c
+ * Caller:  library/x509.c
+ *          library/dhm.c
+ *          library/pkcs12.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ */
+#define MBEDTLS_ASN1_PARSE_C
+
+/**
+ * \def MBEDTLS_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module:  library/asn1write.c
+ * Caller:  library/ecdsa.c
+ *          library/pkwrite.c
+ *          library/x509_create.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ */
+#define MBEDTLS_ASN1_WRITE_C
+
+/**
+ * \def MBEDTLS_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module:  library/base64.c
+ * Caller:  library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define MBEDTLS_BASE64_C
+
+/**
+ * \def MBEDTLS_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module:  library/bignum.c
+ * Caller:  library/dhm.c
+ *          library/ecp.c
+ *          library/ecdsa.c
+ *          library/rsa.c
+ *          library/rsa_internal.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define MBEDTLS_BIGNUM_C
+
+/**
+ * \def MBEDTLS_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module:  library/blowfish.c
+ */
+//#define MBEDTLS_BLOWFISH_C
+
+/**
+ * \def MBEDTLS_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module:  library/camellia.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+//#define MBEDTLS_CAMELLIA_C
+
+/**
+ * \def MBEDTLS_ARIA_C
+ *
+ * Enable the ARIA block cipher.
+ *
+ * Module:  library/aria.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
+ */
+//#define MBEDTLS_ARIA_C
+
+/**
+ * \def MBEDTLS_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module:  library/ccm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#define MBEDTLS_CCM_C
+
+/**
+ * \def MBEDTLS_CERTS_C
+ *
+ * Enable the test certificates.
+ *
+ * Module:  library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+//#define MBEDTLS_CERTS_C
+
+/**
+ * \def MBEDTLS_CHACHA20_C
+ *
+ * Enable the ChaCha20 stream cipher.
+ *
+ * Module:  library/chacha20.c
+ */
+#define MBEDTLS_CHACHA20_C
+
+/**
+ * \def MBEDTLS_CHACHAPOLY_C
+ *
+ * Enable the ChaCha20-Poly1305 AEAD algorithm.
+ *
+ * Module:  library/chachapoly.c
+ *
+ * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
+ */
+#define MBEDTLS_CHACHAPOLY_C
+
+/**
+ * \def MBEDTLS_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module:  library/cipher.c
+ * Caller:  library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define MBEDTLS_CIPHER_C
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module:  library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+#define MBEDTLS_CMAC_C
+
+/**
+ * \def MBEDTLS_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-based random generator.
+ * The CTR_DRBG generator uses AES-256 by default.
+ * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
+ *
+ * Module:  library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_AES_C
+ *
+ * This module provides the CTR_DRBG AES random number generator.
+ */
+#define MBEDTLS_CTR_DRBG_C
+
+/**
+ * \def MBEDTLS_DEBUG_C
+ *
+ * Enable the debug functions.
+ *
+ * Module:  library/debug.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+//#define MBEDTLS_DEBUG_C
+
+/**
+ * \def MBEDTLS_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module:  library/des.c
+ * Caller:  library/pem.c
+ *          library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_DES_C
+
+/**
+ * \def MBEDTLS_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module:  library/dhm.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      DHE-RSA, DHE-PSK
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+#define MBEDTLS_DHM_C
+
+/**
+ * \def MBEDTLS_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module:  library/ecdh.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDTLS_ECP_C
+ */
+#define MBEDTLS_ECDH_C
+
+/**
+ * \def MBEDTLS_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module:  library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
+ */
+#define MBEDTLS_ECDSA_C
+
+/**
+ * \def MBEDTLS_ECJPAKE_C
+ *
+ * Enable the elliptic curve J-PAKE library.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Module:  library/ecjpake.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECJPAKE
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
+ */
+//#define MBEDTLS_ECJPAKE_C
+
+/**
+ * \def MBEDTLS_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module:  library/ecp.c
+ * Caller:  library/ecdh.c
+ *          library/ecdsa.c
+ *          library/ecjpake.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
+ */
+#define MBEDTLS_ECP_C
+
+/**
+ * \def MBEDTLS_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module:  library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define MBEDTLS_ENTROPY_C
+
+/**
+ * \def MBEDTLS_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module:  library/error.c
+ * Caller:
+ *
+ * This module enables mbedtls_strerror().
+ */
+//#define MBEDTLS_ERROR_C
+
+/**
+ * \def MBEDTLS_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module:  library/gcm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define MBEDTLS_GCM_C
+
+/**
+ * \def MBEDTLS_HAVEGE_C
+ *
+ * Enable the HAVEGE random generator.
+ *
+ * Warning: the HAVEGE random generator is not suitable for virtualized
+ *          environments
+ *
+ * Warning: the HAVEGE random generator is dependent on timing and specific
+ *          processor traits. It is therefore not advised to use HAVEGE as
+ *          your applications primary random generator or primary entropy pool
+ *          input. As a secondary input to your entropy pool, it IS able add
+ *          the (limited) extra entropy it provides.
+ *
+ * Module:  library/havege.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_TIMING_C
+ *
+ * Uncomment to enable the HAVEGE random generator.
+ */
+//#define MBEDTLS_HAVEGE_C
+
+/**
+ * \def MBEDTLS_HKDF_C
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Module:  library/hkdf.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the Hashed Message Authentication Code
+ * (HMAC)-based key derivation function (HKDF).
+ */
+#define MBEDTLS_HKDF_C
+
+/**
+ * \def MBEDTLS_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module:  library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define MBEDTLS_HMAC_DRBG_C
+
+/**
+ * \def MBEDTLS_NIST_KW_C
+ *
+ * Enable the Key Wrapping mode for 128-bit block ciphers,
+ * as defined in NIST SP 800-38F. Only KW and KWP modes
+ * are supported. At the moment, only AES is approved by NIST.
+ *
+ * Module:  library/nist_kw.c
+ *
+ * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C
+ */
+#define MBEDTLS_NIST_KW_C
+
+/**
+ * \def MBEDTLS_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module:  library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define MBEDTLS_MD_C
+
+/**
+ * \def MBEDTLS_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module:  library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning   MD2 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD2_C
+
+/**
+ * \def MBEDTLS_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module:  library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning   MD4 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD4_C
+
+/**
+ * \def MBEDTLS_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module:  library/md5.c
+ * Caller:  library/md.c
+ *          library/pem.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD5_C
+
+/**
+ * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
+ * calls)
+ *
+ * Module:  library/memory_buffer_alloc.c
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *           MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def MBEDTLS_NET_C
+ *
+ * Enable the TCP and UDP over IPv6/IPv4 networking routines.
+ *
+ * \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
+ * and Windows. For other platforms, you'll want to disable it, and write your
+ * own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/net_sockets.c
+ *
+ * This module provides networking routines.
+ */
+//#define MBEDTLS_NET_C
+
+/**
+ * \def MBEDTLS_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module:  library/oid.c
+ * Caller:  library/asn1write.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ *          library/pkwrite.c
+ *          library/rsa.c
+ *          library/x509.c
+ *          library/x509_create.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#define MBEDTLS_OID_C
+
+/**
+ * \def MBEDTLS_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module:  library/padlock.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+//#define MBEDTLS_PADLOCK_C
+
+/**
+ * \def MBEDTLS_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/dhm.c
+ *          library/pkparse.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+#define MBEDTLS_PEM_PARSE_C
+
+/**
+ * \def MBEDTLS_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/pkwrite.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+#define MBEDTLS_PEM_WRITE_C
+
+/**
+ * \def MBEDTLS_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module:  library/pk.c
+ * Caller:  library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#define MBEDTLS_PK_C
+
+/**
+ * \def MBEDTLS_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module:  library/pkparse.c
+ * Caller:  library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#define MBEDTLS_PK_PARSE_C
+
+/**
+ * \def MBEDTLS_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module:  library/pkwrite.c
+ * Caller:  library/x509write.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#define MBEDTLS_PK_WRITE_C
+
+/**
+ * \def MBEDTLS_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module:  library/pkcs5.c
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+#define MBEDTLS_PKCS5_C
+
+/**
+ * \def MBEDTLS_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support.
+ *
+ * Module:  library/pkcs11.c
+ * Caller:  library/pk.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define MBEDTLS_PKCS11_C
+
+/**
+ * \def MBEDTLS_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module:  library/pkcs12.c
+ * Caller:  library/pkparse.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * Can use:  MBEDTLS_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+//#define MBEDTLS_PKCS12_C
+
+/**
+ * \def MBEDTLS_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
+ * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module:  library/platform.c
+ * Caller:  Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#define MBEDTLS_PLATFORM_C
+
+/**
+ * \def MBEDTLS_POLY1305_C
+ *
+ * Enable the Poly1305 MAC algorithm.
+ *
+ * Module:  library/poly1305.c
+ * Caller:  library/chachapoly.c
+ */
+#define MBEDTLS_POLY1305_C
+
+/**
+ * \def MBEDTLS_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module:  library/ripemd160.c
+ * Caller:  library/md.c
+ *
+ */
+//#define MBEDTLS_RIPEMD160_C
+
+/**
+ * \def MBEDTLS_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module:  library/rsa.c
+ *          library/rsa_internal.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ *      RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C
+ */
+#define MBEDTLS_RSA_C
+
+/**
+ * \def MBEDTLS_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module:  library/sha1.c
+ * Caller:  library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
+ * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_SHA1_C
+
+/**
+ * \def MBEDTLS_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module:  library/sha256.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define MBEDTLS_SHA256_C
+
+/**
+ * \def MBEDTLS_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ *
+ * Module:  library/sha512.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define MBEDTLS_SHA512_C
+
+/**
+ * \def MBEDTLS_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module:  library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_CACHE_C
+ */
+//#define MBEDTLS_SSL_CACHE_C
+
+/**
+ * \def MBEDTLS_SSL_COOKIE_C
+ *
+ * Enable basic implementation of DTLS cookies for hello verification.
+ *
+ * Module:  library/ssl_cookie.c
+ * Caller:
+ */
+//#define MBEDTLS_SSL_COOKIE_C
+
+/**
+ * \def MBEDTLS_SSL_TICKET_C
+ *
+ * Enable an implementation of TLS server-side callbacks for session tickets.
+ *
+ * Module:  library/ssl_ticket.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_CIPHER_C
+ */
+//#define MBEDTLS_SSL_TICKET_C
+
+/**
+ * \def MBEDTLS_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module:  library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+//#define MBEDTLS_SSL_CLI_C
+
+/**
+ * \def MBEDTLS_SSL_SRV_C
+ *
+ * Enable the SSL/TLS server code.
+ *
+ * Module:  library/ssl_srv.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS server support.
+ */
+//#define MBEDTLS_SSL_SRV_C
+
+/**
+ * \def MBEDTLS_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module:  library/ssl_tls.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ *           and at least one of the MBEDTLS_SSL_PROTO_XXX defines
+ *
+ * This module is required for SSL/TLS.
+ */
+//#define MBEDTLS_SSL_TLS_C
+
+/**
+ * \def MBEDTLS_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default mbed TLS assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
+ *
+ * Module:  library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either MBEDTLS_THREADING_ALT or
+ * MBEDTLS_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within mbed TLS
+ */
+//#define MBEDTLS_THREADING_C
+
+/**
+ * \def MBEDTLS_TIMING_C
+ *
+ * Enable the semi-portable timing interface.
+ *
+ * \note The provided implementation only works on POSIX/Unix (including Linux,
+ * BSD and OS X) and Windows. On other platforms, you can either disable that
+ * module and provide your own implementations of the callbacks needed by
+ * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide
+ * your own implementation of the whole module by setting
+ * \c MBEDTLS_TIMING_ALT in the current file.
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/timing.c
+ * Caller:  library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+//#define MBEDTLS_TIMING_C
+
+/**
+ * \def MBEDTLS_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module:  library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define MBEDTLS_VERSION_C
+
+/**
+ * \def MBEDTLS_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module:  library/x509.c
+ * Caller:  library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C,
+ *           MBEDTLS_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+//#define MBEDTLS_X509_USE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module:  library/x509_crt.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+//#define MBEDTLS_X509_CRT_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module:  library/x509_crl.c
+ * Caller:  library/x509_crt.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+//#define MBEDTLS_X509_CRL_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module:  library/x509_csr.c
+ * Caller:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+//#define MBEDTLS_X509_CSR_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module:  library/x509_create.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+//#define MBEDTLS_X509_CREATE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_WRITE_C
+ *
+ * Enable creating X.509 certificates.
+ *
+ * Module:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate creation.
+ */
+//#define MBEDTLS_X509_CRT_WRITE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module:  library/x509_csr_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+//#define MBEDTLS_X509_CSR_WRITE_C
+
+/**
+ * \def MBEDTLS_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module:  library/xtea.c
+ * Caller:
+ */
+//#define MBEDTLS_XTEA_C
+
+/* \} name SECTION: mbed TLS modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define MBEDTLS_MPI_WINDOW_SIZE            6 /**< Maximum windows size used. */
+//#define MBEDTLS_MPI_MAX_SIZE            1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN               48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+/*!  Maximal reseed counter - indicates maximal number of
+requests allowed between reseeds; according to NIST 800-90
+it is (2^48 - 1), our restriction is :  (int - 0xFFFF - 0xF ).*/
+#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL            0xFFF0 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_CTR_DRBG_MAX_INPUT                256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_CTR_DRBG_MAX_REQUEST             1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT           384 /**< Maximum size of (re)seed buffer */
+//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY              /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */
+
+/* HMAC_DRBG options */
+//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_HMAC_DRBG_MAX_INPUT           256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST        1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT      384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define MBEDTLS_ECP_MAX_BITS             521 /**< Maximum bit size of groups */
+//#define MBEDTLS_ECP_WINDOW_SIZE            6 /**< Maximum window size used */
+//#define MBEDTLS_ECP_FIXED_POINT_OPTIM      1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define MBEDTLS_ENTROPY_MAX_SOURCES                20 /**< Maximum number of sources supported */
+#define MBEDTLS_ENTROPY_MAX_GATHER                   144 /**< Maximum amount requested from entropy sources */
+//#define MBEDTLS_ENTROPY_MIN_HARDWARE               32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */
+
+/* Memory buffer allocator options */
+//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE      4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define MBEDTLS_PLATFORM_STD_MEM_HDR   <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define MBEDTLS_PLATFORM_STD_CALLOC        calloc /**< Default allocator to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_FREE            free /**< Default free to use, can be undefined */
+
+//#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
+
+/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
+/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
+//#define MBEDTLS_PLATFORM_CALLOC_MACRO          calloc /**< Default allocator macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined */
+#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_MACRO            time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
+#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+
+/**
+ * \brief       This macro is invoked by the library when an invalid parameter
+ *              is detected that is only checked with MBEDTLS_CHECK_PARAMS
+ *              (see the documentation of that option for context).
+ *
+ *              When you leave this undefined here, a default definition is
+ *              provided that invokes the function mbedtls_param_failed(),
+ *              which is declared in platform_util.h for the benefit of the
+ *              library, but that you need to define in your application.
+ *
+ *              When you define this here, this replaces the default
+ *              definition in platform_util.h (which no longer declares the
+ *              function mbedtls_param_failed()) and it is your responsibility
+ *              to make sure this macro expands to something suitable (in
+ *              particular, that all the necessary declarations are visible
+ *              from within the library - you can ensure that by providing
+ *              them in this file next to the macro definition).
+ *
+ *              Note that you may define this macro to expand to nothing, in
+ *              which case you don't have to worry about declarations or
+ *              definitions. However, you will then be notified about invalid
+ *              parameters only in non-void functions, and void function will
+ *              just silently return early on invalid parameters, which
+ *              partially negates the benefits of enabling
+ *              #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
+ *
+ * \param cond  The expression that should evaluate to true, but doesn't.
+ */
+//#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
+
+/* SSL Cache options */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
+
+/* SSL options */
+
+/** \def MBEDTLS_SSL_MAX_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming and outgoing plaintext fragments.
+ *
+ * This determines the size of both the incoming and outgoing TLS I/O buffers
+ * in such a way that both are capable of holding the specified amount of
+ * plaintext data, regardless of the protection mechanism used.
+ *
+ * To configure incoming and outgoing I/O buffers separately, use
+ * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN,
+ * which overwrite the value set by this option.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of both
+ * incoming and outgoing I/O buffers.
+ */
+//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_IN_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming plaintext fragments.
+ *
+ * This determines the size of the incoming TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option is undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of the incoming I/O buffer
+ * independently of the outgoing I/O buffer.
+ */
+//#define MBEDTLS_SSL_IN_CONTENT_LEN              16384
+
+/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of outgoing plaintext fragments.
+ *
+ * This determines the size of the outgoing TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * It is possible to save RAM by setting a smaller outward buffer, while keeping
+ * the default inward 16384 byte buffer to conform to the TLS specification.
+ *
+ * The minimum required outward buffer size is determined by the handshake
+ * protocol's usage. Handshaking will fail if the outward buffer is too small.
+ * The specific size requirement depends on the configured ciphers and any
+ * certificate data which is sent during the handshake.
+ *
+ * Uncomment to set the maximum plaintext size of the outgoing I/O buffer
+ * independently of the incoming I/O buffer.
+ */
+//#define MBEDTLS_SSL_OUT_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING
+ *
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ *
+ * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * to account for a reassembled handshake message of maximum size,
+ * together with its reassembly bitmap.
+ *
+ * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default)
+ * should be sufficient for all practical situations as it allows
+ * to reassembly a large handshake message (such as a certificate)
+ * while buffering multiple smaller handshake messages.
+ *
+ */
+//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING             32768
+
+//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
+//#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
+//#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+/* X509 options */
+//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
+//#define MBEDTLS_X509_MAX_FILE_PATH_LEN     512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
+
+/**
+ * Allow SHA-1 in the default TLS configuration for certificate signing.
+ * Without this build-time option, SHA-1 support must be activated explicitly
+ * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
+ * recommended because of it is possible to generate SHA-1 collisions, however
+ * this may be safe for legacy infrastructure where additional controls apply.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+
+/**
+ * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
+ * signature and ciphersuite selection. Without this build-time option, SHA-1
+ * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes.
+ * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
+ * default. At the time of writing, there is no practical attack on the use
+ * of SHA-1 in handshake signatures, hence this option is turned on by default
+ * to preserve compatibility with existing peers, but the general
+ * warning applies nonetheless:
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
+
+/**
+ * Uncomment the macro to let mbed TLS use your alternate implementation of
+ * mbedtls_platform_zeroize(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * mbedtls_platform_zeroize() is a widely used function across the library to
+ * zero a block of memory. The implementation is expected to be secure in the
+ * sense that it has been written to prevent the compiler from removing calls
+ * to mbedtls_platform_zeroize() as part of redundant code elimination
+ * optimizations. However, it is difficult to guarantee that calls to
+ * mbedtls_platform_zeroize() will not be optimized by the compiler as older
+ * versions of the C language standards do not provide a secure implementation
+ * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to
+ * configure their own implementation of mbedtls_platform_zeroize(), for
+ * example by using directives specific to their compiler, features from newer
+ * C standards (e.g using memset_s() in C11) or calling a secure memset() from
+ * their system (e.g explicit_bzero() in BSD).
+ */
+//#define MBEDTLS_PLATFORM_ZEROIZE_ALT
+
+/**
+ * Uncomment the macro to let Mbed TLS use your alternate implementation of
+ * mbedtls_platform_gmtime_r(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * gmtime() is not a thread-safe function as defined in the C standard. The
+ * library will try to use safer implementations of this function, such as
+ * gmtime_r() when available. However, if Mbed TLS cannot identify the target
+ * system, the implementation of mbedtls_platform_gmtime_r() will default to
+ * using the standard gmtime(). In this case, calls from the library to
+ * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
+ * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
+ * library are also guarded with this mutex to avoid race conditions. However,
+ * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
+ * unconditionally use the implementation for mbedtls_platform_gmtime_r()
+ * supplied at compile time.
+ */
+//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
+
+/* \} name SECTION: Customisation configuration options */
+
+/*
+ * Allow user to override any previous default.
+ *
+ * Use two macro names for that, as:
+ * - with yotta the prefix YOTTA_CFG_ is forced
+ * - without yotta is looks weird to have a YOTTA prefix.
+ */
+#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
+#elif defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#include "mbedtls/check_config.h"
+
+/* define memory related functions */
+#if !defined(DX_PLAT_MPS2_PLUS)
+//#include "no_os.h"
+#endif
+
+#endif /* MBEDTLS_CONFIG_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-musca_b1-no-os.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-musca_b1-no-os.h
new file mode 100644
index 0000000..a02b2dd
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312-musca_b1-no-os.h
@@ -0,0 +1,3360 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ *      library/aria.c
+ *      library/timing.c
+ *      include/mbedtls/bn_mul.h
+ *
+ * Required by:
+ *      MBEDTLS_AESNI_C
+ *      MBEDTLS_PADLOCK_C
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define MBEDTLS_HAVE_ASM
+
+/**
+ * \def MBEDTLS_NO_UDBL_DIVISION
+ *
+ * The platform lacks support for double-width integer division (64-bit
+ * division on a 32-bit platform, 128-bit division on a 64-bit platform).
+ *
+ * Used in:
+ *      include/mbedtls/bignum.h
+ *      library/bignum.c
+ *
+ * The bignum code uses double-width division to speed up some operations.
+ * Double-width division is often implemented in software that needs to
+ * be linked with the program. The presence of a double-width integer
+ * type is usually detected automatically through preprocessor macros,
+ * but the automatic detection cannot know whether the code needs to
+ * and can be linked with an implementation of division for that type.
+ * By default division is assumed to be usable if the type is present.
+ * Uncomment this option to prevent the use of double-width division.
+ *
+ * Note that division for the native integer type is always required.
+ * Furthermore, a 64-bit type is always required even on a 32-bit
+ * platform, but it need not support multiplication or division. In some
+ * cases it is also desirable to disable some double-width operations. For
+ * example, if double-width division is implemented in software, disabling
+ * it can reduce code size in some embedded targets.
+ */
+//#define MBEDTLS_NO_UDBL_DIVISION
+
+/**
+ * \def MBEDTLS_NO_64BIT_MULTIPLICATION
+ *
+ * The platform lacks support for 32x32 -> 64-bit multiplication.
+ *
+ * Used in:
+ *      library/poly1305.c
+ *
+ * Some parts of the library may use multiplication of two unsigned 32-bit
+ * operands with a 64-bit result in order to speed up computations. On some
+ * platforms, this is not available in hardware and has to be implemented in
+ * software, usually in a library provided by the toolchain.
+ *
+ * Sometimes it is not desirable to have to link to that library. This option
+ * removes the dependency of that library on platforms that lack a hardware
+ * 64-bit multiplier by embedding a software implementation in Mbed TLS.
+ *
+ * Note that depending on the compiler, this may decrease performance compared
+ * to using the library function provided by the toolchain.
+ */
+//#define MBEDTLS_NO_64BIT_MULTIPLICATION
+
+/**
+ * \def MBEDTLS_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define MBEDTLS_HAVE_SSE2
+
+/**
+ * \def MBEDTLS_HAVE_TIME
+ *
+ * System has time.h and time().
+ * The time does not need to be correct, only time differences are used,
+ * by contrast with MBEDTLS_HAVE_TIME_DATE
+ *
+ * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT,
+ * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and
+ * MBEDTLS_PLATFORM_STD_TIME.
+ *
+ * Comment if your system does not support time functions
+ */
+#define MBEDTLS_HAVE_TIME
+
+/**
+ * \def MBEDTLS_HAVE_TIME_DATE
+ *
+ * System has time.h, time(), and an implementation for
+ * mbedtls_platform_gmtime_r() (see below).
+ * The time needs to be correct (not necesarily very accurate, but at least
+ * the date should be correct). This is used to verify the validity period of
+ * X.509 certificates.
+ *
+ * Comment if your system does not have a correct clock.
+ *
+ * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
+ * behaves similarly to the gmtime_r() function from the C standard. Refer to
+ * the documentation for mbedtls_platform_gmtime_r() for more information.
+ *
+ * \note It is possible to configure an implementation for
+ * mbedtls_platform_gmtime_r() at compile-time by using the macro
+ * MBEDTLS_PLATFORM_GMTIME_R_ALT.
+ */
+#define MBEDTLS_HAVE_TIME_DATE
+
+/**
+ * \def MBEDTLS_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default mbed TLS uses the system-provided calloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY without the
+ * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
+ * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
+ * free() function pointer at runtime.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
+ * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
+ * alternate function at compile time.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+#define MBEDTLS_PLATFORM_MEMORY
+
+/**
+ * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. calloc() to
+ * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a
+ * MBEDTLS_PLATFORM_XXX_MACRO.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def MBEDTLS_PLATFORM_EXIT_ALT
+ *
+ * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the
+ * function in the platform abstraction layer.
+ *
+ * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will
+ * provide a function "mbedtls_platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require MBEDTLS_PLATFORM_C to be defined!
+ *
+ * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows;
+ * it will be enabled automatically by check_config.h
+ *
+ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * MBEDTLS_PLATFORM_XXX_MACRO!
+ *
+ * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define MBEDTLS_PLATFORM_EXIT_ALT
+//#define MBEDTLS_PLATFORM_TIME_ALT
+//#define MBEDTLS_PLATFORM_FPRINTF_ALT
+//#define MBEDTLS_PLATFORM_PRINTF_ALT
+//#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
+//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
+
+/**
+ * \def MBEDTLS_DEPRECATED_WARNING
+ *
+ * Mark deprecated functions so that they generate a warning if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * This only works with GCC and Clang. With other compilers, you may want to
+ * use MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Uncomment to get warnings on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_WARNING
+
+/**
+ * \def MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Remove deprecated functions so that they generate an error if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * Uncomment to get errors on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_REMOVED
+
+/**
+ * \def MBEDTLS_CHECK_PARAMS
+ *
+ * This configuration option controls whether the library validates more of
+ * the parameters passed to it.
+ *
+ * When this flag is not defined, the library only attempts to validate an
+ * input parameter if: (1) they may come from the outside world (such as the
+ * network, the filesystem, etc.) or (2) not validating them could result in
+ * internal memory errors such as overflowing a buffer controlled by the
+ * library. On the other hand, it doesn't attempt to validate parameters whose
+ * values are fully controlled by the application (such as pointers).
+ *
+ * When this flag is defined, the library additionally attempts to validate
+ * parameters that are fully controlled by the application, and should always
+ * be valid if the application code is fully correct and trusted.
+ *
+ * For example, when a function accepts as input a pointer to a buffer that may
+ * contain untrusted data, and its documentation mentions that this pointer
+ * must not be NULL:
+ * - the pointer is checked to be non-NULL only if this option is enabled
+ * - the content of the buffer is always validated
+ *
+ * When this flag is defined, if a library function receives a parameter that
+ * is invalid, it will:
+ * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
+ *   call to the function mbedtls_param_failed()
+ * - immediately return (with a specific error code unless the function
+ *   returns void and can't communicate an error).
+ *
+ * When defining this flag, you also need to:
+ * - either provide a definition of the function mbedtls_param_failed() in
+ *   your application (see platform_util.h for its prototype) as the library
+ *   calls that function, but does not provide a default definition for it,
+ * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
+ *   below if the above mechanism is not flexible enough to suit your needs.
+ *   See the documentation of this macro later in this file.
+ *
+ * Uncomment to enable validation of application-controlled parameters.
+ */
+//#define MBEDTLS_CHECK_PARAMS
+
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: mbed TLS feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_TIMING_ALT
+ *
+ * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(),
+ * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay()
+ *
+ * Only works if you have MBEDTLS_TIMING_C enabled.
+ *
+ * You will need to provide a header "timing_alt.h" and an implementation at
+ * compile time.
+ */
+//#define MBEDTLS_TIMING_ALT
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternate core implementation of a symmetric crypto, an arithmetic or hash
+ * module (e.g. platform specific assembly optimized implementations). Keep
+ * in mind that the function prototypes should remain the same.
+ *
+ * This replaces the whole module. If you only want to replace one of the
+ * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer
+ * provide the "struct mbedtls_aes_context" definition and omit the base function
+ * declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * module.
+ *
+ * \warning   MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ *            use constitutes a security risk. If possible, we recommend
+ *            avoiding dependencies on them, and considering stronger message
+ *            digests and ciphers instead.
+ *
+ */
+#define MBEDTLS_AES_ALT
+//#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_ARIA_ALT
+//#define MBEDTLS_BLOWFISH_ALT
+//#define MBEDTLS_CAMELLIA_ALT
+#define MBEDTLS_CCM_ALT
+#define MBEDTLS_GCM_ALT
+#define MBEDTLS_CHACHA20_ALT
+#define MBEDTLS_CHACHAPOLY_ALT
+#define MBEDTLS_CMAC_ALT
+//#define MBEDTLS_DES_ALT
+//#define MBEDTLS_ECJPAKE_ALT
+//#define MBEDTLS_XTEA_ALT
+//#define MBEDTLS_NIST_KW_ALT
+//#define MBEDTLS_MD2_ALT
+//#define MBEDTLS_MD4_ALT
+//#define MBEDTLS_MD5_ALT
+#define MBEDTLS_POLY1305_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+#define MBEDTLS_SHA1_ALT
+#define MBEDTLS_SHA256_ALT
+//#define MBEDTLS_SHA512_ALT
+#define MBEDTLS_RSA_ALT
+#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_XTEA_ALT
+
+/*
+ * When replacing the elliptic curve module, pleace consider, that it is
+ * implemented with two .c files:
+ *      - ecp.c
+ *      - ecp_curves.c
+ * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT
+ * macros as described above. The only difference is that you have to make sure
+ * that you provide functionality for both .c files.
+ */
+//#define MBEDTLS_ECP_ALT
+
+
+/**
+ * \def MBEDTLS_MD2_PROCESS_ALT
+ *
+ * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
+ * alternate core implementation of symmetric crypto or hash function. Keep in
+ * mind that function prototypes should remain the same.
+ *
+ * This replaces only one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
+ * no longer provide the mbedtls_sha1_process() function, but it will still provide
+ * the other function (using your mbedtls_sha1_process() function) and the definition
+ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
+ * with this definition.
+ *
+ * \note Because of a signature change, the core AES encryption and decryption routines are
+ *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
+ *       respectively. When setting up alternative implementations, these functions should
+ *       be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ *       must stay untouched.
+ *
+ * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ *       MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
+ *       tables.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ *
+ * \warning   MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ *            constitutes a security risk. If possible, we recommend avoiding
+ *            dependencies on them, and considering stronger message digests
+ *            and ciphers instead.
+ *
+ */
+//#define MBEDTLS_MD2_PROCESS_ALT
+//#define MBEDTLS_MD4_PROCESS_ALT
+//#define MBEDTLS_MD5_PROCESS_ALT
+//#define MBEDTLS_RIPEMD160_PROCESS_ALT
+//#define MBEDTLS_SHA1_PROCESS_ALT
+//#define MBEDTLS_SHA256_PROCESS_ALT
+//#define MBEDTLS_SHA512_PROCESS_ALT
+//#define MBEDTLS_DES_SETKEY_ALT
+//#define MBEDTLS_DES_CRYPT_ECB_ALT
+//#define MBEDTLS_DES3_CRYPT_ECB_ALT
+//#define MBEDTLS_AES_SETKEY_ENC_ALT
+//#define MBEDTLS_AES_SETKEY_DEC_ALT
+//#define MBEDTLS_AES_ENCRYPT_ALT
+//#define MBEDTLS_AES_DECRYPT_ALT
+#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+#define MBEDTLS_ECDSA_VERIFY_ALT
+#define MBEDTLS_ECDSA_SIGN_ALT
+#define MBEDTLS_ECDSA_GENKEY_ALT
+/**
+ * \def MBEDTLS_ECP_INTERNAL_ALT
+ *
+ * Expose a part of the internal interface of the Elliptic Curve Point module.
+ *
+ * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternative core implementation of elliptic curve arithmetic. Keep in mind
+ * that function prototypes should remain the same.
+ *
+ * This partially replaces one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation
+ * is still present and it is used for group structures not supported by the
+ * alternative.
+ *
+ * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT
+ * and implementing the following functions:
+ *      unsigned char mbedtls_internal_ecp_grp_capable(
+ *          const mbedtls_ecp_group *grp )
+ *      int  mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
+ *      void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp )
+ * The mbedtls_internal_ecp_grp_capable function should return 1 if the
+ * replacement functions implement arithmetic for the given group and 0
+ * otherwise.
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are
+ * called before and after each point operation and provide an opportunity to
+ * implement optimized set up and tear down instructions.
+ *
+ * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and
+ * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac
+ * function, but will use your mbedtls_internal_ecp_double_jac if the group is
+ * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when
+ * receives it as an argument). If the group is not supported then the original
+ * implementation is used. The other functions and the definition of
+ * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your
+ * implementation of mbedtls_internal_ecp_double_jac and
+ * mbedtls_internal_ecp_grp_capable must be compatible with this definition.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ */
+/* Required for all the functions in this section */
+//#define MBEDTLS_ECP_INTERNAL_ALT
+/* Support for Weierstrass curves with Jacobi representation */
+//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
+//#define MBEDTLS_ECP_ADD_MIXED_ALT
+//#define MBEDTLS_ECP_DOUBLE_JAC_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
+/* Support for curves with Montgomery arithmetic */
+//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT
+//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
+//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
+
+/**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ *
+ * Uncomment this macro to let mbed TLS use your own implementation of a
+ * hardware entropy collector.
+ *
+ * Your function must be called \c mbedtls_hardware_poll(), have the same
+ * prototype as declared in entropy_poll.h, and accept NULL as first argument.
+ *
+ * Uncomment to use your own hardware entropy collector.
+ */
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+
+/**
+ * \def MBEDTLS_AES_ROM_TABLES
+ *
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_ROM_TABLES
+
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
+/**
+ * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define MBEDTLS_CAMELLIA_SMALL_MEMORY
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CBC
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CTR
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback mode (OFB) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_XTS
+ *
+ * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES.
+ */
+//#define MBEDTLS_CIPHER_MODE_XTS
+
+/**
+ * \def MBEDTLS_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+ */
+//#define MBEDTLS_CIPHER_NULL_CIPHER
+
+/**
+ * \def MBEDTLS_CIPHER_PADDING_PKCS7
+ *
+ * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+#define MBEDTLS_CIPHER_PADDING_PKCS7
+#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+#define MBEDTLS_CIPHER_PADDING_ZEROS
+
+/**
+ * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels with virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ *      MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+//#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module.  By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+/* CryptoCell only supports BP256R1 at this stage */
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+//#define MBEDTLS_ECP_DP_CURVE448_ENABLED
+
+/**
+ * \def MBEDTLS_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#define MBEDTLS_ECP_NIST_OPTIM
+
+/**
+ * \def MBEDTLS_ECP_RESTARTABLE
+ *
+ * Enable "non-blocking" ECC operations that can return early and be resumed.
+ *
+ * This allows various functions to pause by returning
+ * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
+ * order to further progress and eventually complete their operation. This is
+ * controlled through mbedtls_ecp_set_max_ops() which limits the maximum
+ * number of ECC operations a function may perform before pausing; see
+ * mbedtls_ecp_set_max_ops() for more information.
+ *
+ * This is useful in non-threaded environments if you want to avoid blocking
+ * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
+ *
+ * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
+ */
+//#define MBEDTLS_ECP_RESTARTABLE
+
+/**
+ * \def MBEDTLS_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDTLS_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define MBEDTLS_ECDSA_DETERMINISTIC
+
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+ *
+ * Enable the PSK based ciphersuite modes in SSL / TLS.
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+ *
+ * Enable the DHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+ *
+ * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+ *
+ * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+ *
+ * Enable the RSA-only based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+ *
+ * Enable the DHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+ *
+ * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+ *
+ * Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Requires: MBEDTLS_ECJPAKE_C
+ *           MBEDTLS_SHA256_C
+ *           MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+/**
+ * \def MBEDTLS_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+//#define MBEDTLS_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def MBEDTLS_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of mbedtls_strerror() in
+ * third party libraries easier when MBEDTLS_ERROR_C is disabled
+ * (no effect when MBEDTLS_ERROR_C is enabled).
+ *
+ * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
+ * not using mbedtls_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * mbedtls_strerror()
+ */
+#define MBEDTLS_ERROR_STRERROR_DUMMY
+
+/**
+ * \def MBEDTLS_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: MBEDTLS_BIGNUM_C
+ */
+#define MBEDTLS_GENPRIME
+
+/**
+ * \def MBEDTLS_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+//#define MBEDTLS_FS_IO
+
+/**
+ * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * mbedtls_timing_hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def MBEDTLS_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: MBEDTLS_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both MBEDTLS_SHA256_C and
+ * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define MBEDTLS_ENTROPY_FORCE_SHA256
+
+/**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ *       determined in the platform layer, and can be modified at runtime and/or
+ *       compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ *       with regular fopen(), please make sure you make a seedfile with the
+ *       proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ *       least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ *       and written to or you will get an entropy source error! The default
+ *       implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ *       bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ *       given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/**
+ * \def MBEDTLS_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define MBEDTLS_MEMORY_DEBUG
+
+/**
+ * \def MBEDTLS_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *           GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define MBEDTLS_MEMORY_BACKTRACE
+
+/**
+ * \def MBEDTLS_PK_RSA_ALT_SUPPORT
+ *
+ * Support external private RSA keys (eg from a HSM) in the PK layer.
+ *
+ * Comment this macro to disable support for external private RSA keys.
+ */
+//#define MBEDTLS_PK_RSA_ALT_SUPPORT
+
+/**
+ * \def MBEDTLS_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDTLS_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#define MBEDTLS_PKCS1_V15
+
+/**
+ * \def MBEDTLS_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#define MBEDTLS_PKCS1_V21
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_SPM
+ *
+ * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure
+ * Partition Manager) integration which separates the code into two parts: a
+ * NSPE (Non-Secure Process Environment) and an SPE (Secure Process
+ * Environment).
+ *
+ * Module:  library/psa_crypto.c
+ * Requires: MBEDTLS_PSA_CRYPTO_C
+ *
+ */
+#define MBEDTLS_PSA_CRYPTO_SPM
+
+/**
+ * \def MBEDTLS_PSA_HAS_ITS_IO
+ *
+ * Enable the non-volatile secure storage usage.
+ *
+ * This is crucial on systems that do not have a HW TRNG support.
+ *
+ */
+//#define MBEDTLS_PSA_HAS_ITS_IO
+
+/**
+ * \def MBEDTLS_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define MBEDTLS_RSA_NO_CRT
+
+/**
+ * \def MBEDTLS_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+#define MBEDTLS_SELF_TEST
+
+/**
+ * \def MBEDTLS_SHA256_SMALLER
+ *
+ * Enable an implementation of SHA-256 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * The default implementation is meant to be a reasonnable compromise between
+ * performance and size. This version optimizes more aggressively for size at
+ * the expense of performance. Eg on Cortex-M4 it reduces the size of
+ * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
+ * 30%.
+ *
+ * Uncomment to enable the smaller implementation of SHA256.
+ */
+//#define MBEDTLS_SHA256_SMALLER
+
+/**
+ * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, mbed TLS can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+//#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+/**
+ * \def MBEDTLS_SSL_ASYNC_PRIVATE
+ *
+ * Enable asynchronous external private key operations in SSL. This allows
+ * you to configure an SSL connection to call an external cryptographic
+ * module to perform private key operations instead of performing the
+ * operation inside the library.
+ *
+ */
+//#define MBEDTLS_SSL_ASYNC_PRIVATE
+
+/**
+ * \def MBEDTLS_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+ */
+//#define MBEDTLS_SSL_DEBUG_ALL
+
+/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
+ *
+ * Enable support for Encrypt-then-MAC, RFC 7366.
+ *
+ * This allows peers that both support it to use a more robust protection for
+ * ciphersuites using CBC, providing deep resistance against timing attacks
+ * on the padding or underlying cipher.
+ *
+ * This only affects CBC ciphersuites, and is useless if none is defined.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Encrypt-then-MAC
+ */
+//#define MBEDTLS_SSL_ENCRYPT_THEN_MAC
+
+/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+ *
+ * Enable support for Extended Master Secret, aka Session Hash
+ * (draft-ietf-tls-session-hash-02).
+ *
+ * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * attacks, but it is recommended to always use it (even if you disable
+ * renegotiation), since it actually fixes a more fundamental issue in the
+ * original SSL/TLS design, and has implications beyond Triple Handshake.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Extended Master Secret.
+ */
+//#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+
+/**
+ * \def MBEDTLS_SSL_FALLBACK_SCSV
+ *
+ * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00).
+ *
+ * For servers, it is recommended to always enable this, unless you support
+ * only one version of TLS, or know for sure that none of your clients
+ * implements a fallback strategy.
+ *
+ * For clients, you only need this if you're using a fallback strategy, which
+ * is not recommended in the first place, unless you absolutely need it to
+ * interoperate with buggy (version-intolerant) servers.
+ *
+ * Comment this macro to disable support for FALLBACK_SCSV
+ */
+//#define MBEDTLS_SSL_FALLBACK_SCSV
+
+/**
+ * \def MBEDTLS_SSL_HW_RECORD_ACCEL
+ *
+ * Enable hooking functions in SSL module for hardware acceleration of
+ * individual records.
+ *
+ * Uncomment this macro to enable hooking functions.
+ */
+//#define MBEDTLS_SSL_HW_RECORD_ACCEL
+
+/**
+ * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING
+ *
+ * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0.
+ *
+ * This is a countermeasure to the BEAST attack, which also minimizes the risk
+ * of interoperability issues compared to sending 0-length records.
+ *
+ * Comment this macro to disable 1/n-1 record splitting.
+ */
+//#define MBEDTLS_SSL_CBC_RECORD_SPLITTING
+
+/**
+ * \def MBEDTLS_SSL_RENEGOTIATION
+ *
+ * Enable support for TLS renegotiation.
+ *
+ * The two main uses of renegotiation are (1) refresh keys on long-lived
+ * connections and (2) client authentication after the initial handshake.
+ * If you don't need renegotiation, it's probably better to disable it, since
+ * it has been associated with security issues in the past and is easy to
+ * misuse/misunderstand.
+ *
+ * Comment this to disable support for renegotiation.
+ *
+ * \note   Even if this option is disabled, both client and server are aware
+ *         of the Renegotiation Indication Extension (RFC 5746) used to
+ *         prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ *         (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ *          configuration of this extension).
+ *
+ */
+//#define MBEDTLS_SSL_RENEGOTIATION
+
+/**
+ * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to enable support for SSLv2 Client Hello messages.
+ */
+//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
+ * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+ *
+ * Pick the ciphersuite according to the client's preferences rather than ours
+ * in the SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to respect client's ciphersuite order
+ */
+//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+/**
+ * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+//#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+
+/**
+ * \def MBEDTLS_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+//#define MBEDTLS_SSL_PROTO_SSL3
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1 / DTLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
+ *           (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2 / DTLS 1.2
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_2
+
+/**
+ * \def MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Enable support for DTLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_1
+ *        or MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for DTLS
+ */
+//#define MBEDTLS_SSL_PROTO_DTLS
+
+/**
+ * \def MBEDTLS_SSL_ALPN
+ *
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+//#define MBEDTLS_SSL_ALPN
+
+/**
+ * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY
+ *
+ * Enable support for the anti-replay mechanism in DTLS.
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *           MBEDTLS_SSL_PROTO_DTLS
+ *
+ * \warning Disabling this is often a security risk!
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
+ *
+ * Comment this to disable anti-replay in DTLS.
+ */
+//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Enable support for HelloVerifyRequest on DTLS servers.
+ *
+ * This feature is highly recommended to prevent DTLS servers being used as
+ * amplifiers in DoS attacks against other hosts. It should always be enabled
+ * unless you know for sure amplification cannot be a problem in the
+ * environment in which your server operates.
+ *
+ * \warning Disabling this can ba a security risk! (see above)
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for HelloVerifyRequest.
+ */
+//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+ *
+ * Enable server-side support for clients that reconnect from the same port.
+ *
+ * Some clients unexpectedly close the connection and try to reconnect using the
+ * same source port. This needs special support from the server to handle the
+ * new connection securely, as described in section 4.2.8 of RFC 6347. This
+ * flag enables that support.
+ *
+ * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Comment this to disable support for clients reusing the source port.
+ */
+//#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+
+/**
+ * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+ *
+ * Enable support for a limit of records with bad MAC.
+ *
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+
+/**
+ * \def MBEDTLS_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ * Client-side, provides full support for session tickets (maintainance of a
+ * session store remains the responsibility of the application, though).
+ * Server-side, you also need to provide callbacks for writing and parsing
+ * tickets, including authenticated encryption and key management. Example
+ * callbacks are provided by MBEDTLS_SSL_TICKET_C.
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+//#define MBEDTLS_SSL_SESSION_TICKETS
+
+/**
+ * \def MBEDTLS_SSL_EXPORT_KEYS
+ *
+ * Enable support for exporting key block and master secret.
+ * This is required for certain users of TLS, e.g. EAP-TLS.
+ *
+ * Comment this macro to disable support for key export
+ */
+//#define MBEDTLS_SSL_EXPORT_KEYS
+
+/**
+ * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+//#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+ *
+ * Fallback to old (pre-2.7), non-conforming implementation of the truncated
+ * HMAC extension which also truncates the HMAC key. Note that this option is
+ * only meant for a transitory upgrade period and is likely to be removed in
+ * a future version of the library.
+ *
+ * \warning The old implementation is non-compliant and has a security weakness
+ *          (2^80 brute force attack on the HMAC key used for a single,
+ *          uninterrupted connection). This should only be enabled temporarily
+ *          when (1) the use of truncated HMAC is essential in order to save
+ *          bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
+ *          the fixed implementation yet (pre-2.7).
+ *
+ * \deprecated This option is deprecated and will likely be removed in a
+ *             future version of Mbed TLS.
+ *
+ * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
+ *
+ * Requires: MBEDTLS_SSL_TRUNCATED_HMAC
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+
+/**
+ * \def MBEDTLS_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define MBEDTLS_THREADING_ALT
+
+/**
+ * \def MBEDTLS_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+//#define MBEDTLS_THREADING_PTHREAD
+
+/**
+ * \def MBEDTLS_USE_PSA_CRYPTO
+ *
+ * Make the X.509 and TLS library use PSA for cryptographic operations, see
+ * #MBEDTLS_PSA_CRYPTO_C.
+ *
+ * Note: this option is still in progress, the full X.509 and TLS modules are
+ * not covered yet, but parts that are not ported to PSA yet will still work
+ * as usual, so enabling this option should not break backwards compatibility.
+ *
+ * \warning  Support for PSA is still an experimental feature.
+ *           Any public API that depends on this option may change
+ *           at any time until this warning is removed.
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C.
+ */
+//#define MBEDTLS_USE_PSA_CRYPTO
+
+/**
+ * \def MBEDTLS_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via mbedtls_version_check_feature().
+ *
+ * Requires: MBEDTLS_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define MBEDTLS_VERSION_FEATURES
+
+/**
+ * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an extension in a v1 or v2 certificate.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+
+/**
+ * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an unknown critical extension.
+ *
+ * \warning Depending on your PKI use, enabling this can be a security risk!
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+
+/**
+ * \def MBEDTLS_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+//#define MBEDTLS_X509_CHECK_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+//#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT
+ *
+ * Enable parsing and verification of X.509 certificates, CRLs and CSRS
+ * signed with RSASSA-PSS (aka PKCS#1 v2.1).
+ *
+ * Comment this macro to disallow using RSASSA-PSS in certificates.
+ */
+//#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+
+/**
+ * \def MBEDTLS_ZLIB_SUPPORT
+ *
+ * If set, the SSL/TLS module uses ZLIB to support compression and
+ * decompression of packet data.
+ *
+ * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
+ * CRIME attack. Before enabling this option, you should examine with care if
+ * CRIME or similar exploits may be a applicable to your use case.
+ *
+ * \note Currently compression can't be used with DTLS.
+ *
+ * \deprecated This feature is deprecated and will be removed
+ *             in the next major revision of the library.
+ *
+ * Used in: library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This feature requires zlib library and headers to be present.
+ *
+ * Uncomment to enable use of ZLIB
+ */
+//#define MBEDTLS_ZLIB_SUPPORT
+/* \} name SECTION: mbed TLS feature support */
+
+/**
+ * \name SECTION: mbed TLS modules
+ *
+ * This section enables or disables entire modules in mbed TLS
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module:  library/aesni.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+//#define MBEDTLS_AESNI_C
+
+/**
+ * \def MBEDTLS_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module:  library/aes.c
+ * Caller:  library/cipher.c
+ *          library/pem.c
+ *          library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define MBEDTLS_AES_C
+
+/**
+ * \def MBEDTLS_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module:  library/arc4.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. If possible, we recommend avoidng dependencies on
+ *            it, and considering stronger ciphers instead.
+ *
+ */
+//#define MBEDTLS_ARC4_C
+
+/**
+ * \def MBEDTLS_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module:  library/asn1.c
+ * Caller:  library/x509.c
+ *          library/dhm.c
+ *          library/pkcs12.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ */
+#define MBEDTLS_ASN1_PARSE_C
+
+/**
+ * \def MBEDTLS_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module:  library/asn1write.c
+ * Caller:  library/ecdsa.c
+ *          library/pkwrite.c
+ *          library/x509_create.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ */
+#define MBEDTLS_ASN1_WRITE_C
+
+/**
+ * \def MBEDTLS_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module:  library/base64.c
+ * Caller:  library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define MBEDTLS_BASE64_C
+
+/**
+ * \def MBEDTLS_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module:  library/bignum.c
+ * Caller:  library/dhm.c
+ *          library/ecp.c
+ *          library/ecdsa.c
+ *          library/rsa.c
+ *          library/rsa_internal.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define MBEDTLS_BIGNUM_C
+
+/**
+ * \def MBEDTLS_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module:  library/blowfish.c
+ */
+//#define MBEDTLS_BLOWFISH_C
+
+/**
+ * \def MBEDTLS_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module:  library/camellia.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+//#define MBEDTLS_CAMELLIA_C
+
+/**
+ * \def MBEDTLS_ARIA_C
+ *
+ * Enable the ARIA block cipher.
+ *
+ * Module:  library/aria.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
+ */
+//#define MBEDTLS_ARIA_C
+
+/**
+ * \def MBEDTLS_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module:  library/ccm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#define MBEDTLS_CCM_C
+
+/**
+ * \def MBEDTLS_CERTS_C
+ *
+ * Enable the test certificates.
+ *
+ * Module:  library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+//#define MBEDTLS_CERTS_C
+
+/**
+ * \def MBEDTLS_CHACHA20_C
+ *
+ * Enable the ChaCha20 stream cipher.
+ *
+ * Module:  library/chacha20.c
+ */
+#define MBEDTLS_CHACHA20_C
+
+/**
+ * \def MBEDTLS_CHACHAPOLY_C
+ *
+ * Enable the ChaCha20-Poly1305 AEAD algorithm.
+ *
+ * Module:  library/chachapoly.c
+ *
+ * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
+ */
+#define MBEDTLS_CHACHAPOLY_C
+
+/**
+ * \def MBEDTLS_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module:  library/cipher.c
+ * Caller:  library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define MBEDTLS_CIPHER_C
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module:  library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+#define MBEDTLS_CMAC_C
+
+/**
+ * \def MBEDTLS_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-based random generator.
+ * The CTR_DRBG generator uses AES-256 by default.
+ * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
+ *
+ * Module:  library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_AES_C
+ *
+ * This module provides the CTR_DRBG AES random number generator.
+ */
+#define MBEDTLS_CTR_DRBG_C
+
+/**
+ * \def MBEDTLS_DEBUG_C
+ *
+ * Enable the debug functions.
+ *
+ * Module:  library/debug.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+//#define MBEDTLS_DEBUG_C
+
+/**
+ * \def MBEDTLS_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module:  library/des.c
+ * Caller:  library/pem.c
+ *          library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_DES_C
+
+/**
+ * \def MBEDTLS_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module:  library/dhm.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      DHE-RSA, DHE-PSK
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+#define MBEDTLS_DHM_C
+
+/**
+ * \def MBEDTLS_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module:  library/ecdh.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDTLS_ECP_C
+ */
+#define MBEDTLS_ECDH_C
+
+/**
+ * \def MBEDTLS_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module:  library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
+ */
+#define MBEDTLS_ECDSA_C
+
+/**
+ * \def MBEDTLS_ECJPAKE_C
+ *
+ * Enable the elliptic curve J-PAKE library.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Module:  library/ecjpake.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECJPAKE
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
+ */
+//#define MBEDTLS_ECJPAKE_C
+
+/**
+ * \def MBEDTLS_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module:  library/ecp.c
+ * Caller:  library/ecdh.c
+ *          library/ecdsa.c
+ *          library/ecjpake.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
+ */
+#define MBEDTLS_ECP_C
+
+/**
+ * \def MBEDTLS_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module:  library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define MBEDTLS_ENTROPY_C
+
+/**
+ * \def MBEDTLS_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module:  library/error.c
+ * Caller:
+ *
+ * This module enables mbedtls_strerror().
+ */
+//#define MBEDTLS_ERROR_C
+
+/**
+ * \def MBEDTLS_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module:  library/gcm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define MBEDTLS_GCM_C
+
+/**
+ * \def MBEDTLS_HAVEGE_C
+ *
+ * Enable the HAVEGE random generator.
+ *
+ * Warning: the HAVEGE random generator is not suitable for virtualized
+ *          environments
+ *
+ * Warning: the HAVEGE random generator is dependent on timing and specific
+ *          processor traits. It is therefore not advised to use HAVEGE as
+ *          your applications primary random generator or primary entropy pool
+ *          input. As a secondary input to your entropy pool, it IS able add
+ *          the (limited) extra entropy it provides.
+ *
+ * Module:  library/havege.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_TIMING_C
+ *
+ * Uncomment to enable the HAVEGE random generator.
+ */
+//#define MBEDTLS_HAVEGE_C
+
+/**
+ * \def MBEDTLS_HKDF_C
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Module:  library/hkdf.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the Hashed Message Authentication Code
+ * (HMAC)-based key derivation function (HKDF).
+ */
+#define MBEDTLS_HKDF_C
+
+/**
+ * \def MBEDTLS_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module:  library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define MBEDTLS_HMAC_DRBG_C
+
+/**
+ * \def MBEDTLS_NIST_KW_C
+ *
+ * Enable the Key Wrapping mode for 128-bit block ciphers,
+ * as defined in NIST SP 800-38F. Only KW and KWP modes
+ * are supported. At the moment, only AES is approved by NIST.
+ *
+ * Module:  library/nist_kw.c
+ *
+ * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C
+ */
+#define MBEDTLS_NIST_KW_C
+
+/**
+ * \def MBEDTLS_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module:  library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define MBEDTLS_MD_C
+
+/**
+ * \def MBEDTLS_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module:  library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning   MD2 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD2_C
+
+/**
+ * \def MBEDTLS_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module:  library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning   MD4 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD4_C
+
+/**
+ * \def MBEDTLS_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module:  library/md5.c
+ * Caller:  library/md.c
+ *          library/pem.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD5_C
+
+/**
+ * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
+ * calls)
+ *
+ * Module:  library/memory_buffer_alloc.c
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *           MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def MBEDTLS_NET_C
+ *
+ * Enable the TCP and UDP over IPv6/IPv4 networking routines.
+ *
+ * \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
+ * and Windows. For other platforms, you'll want to disable it, and write your
+ * own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/net_sockets.c
+ *
+ * This module provides networking routines.
+ */
+//#define MBEDTLS_NET_C
+
+/**
+ * \def MBEDTLS_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module:  library/oid.c
+ * Caller:  library/asn1write.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ *          library/pkwrite.c
+ *          library/rsa.c
+ *          library/x509.c
+ *          library/x509_create.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#define MBEDTLS_OID_C
+
+/**
+ * \def MBEDTLS_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module:  library/padlock.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+//#define MBEDTLS_PADLOCK_C
+
+/**
+ * \def MBEDTLS_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/dhm.c
+ *          library/pkparse.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+#define MBEDTLS_PEM_PARSE_C
+
+/**
+ * \def MBEDTLS_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/pkwrite.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+#define MBEDTLS_PEM_WRITE_C
+
+/**
+ * \def MBEDTLS_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module:  library/pk.c
+ * Caller:  library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#define MBEDTLS_PK_C
+
+/**
+ * \def MBEDTLS_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module:  library/pkparse.c
+ * Caller:  library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#define MBEDTLS_PK_PARSE_C
+
+/**
+ * \def MBEDTLS_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module:  library/pkwrite.c
+ * Caller:  library/x509write.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#define MBEDTLS_PK_WRITE_C
+
+/**
+ * \def MBEDTLS_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module:  library/pkcs5.c
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+#define MBEDTLS_PKCS5_C
+
+/**
+ * \def MBEDTLS_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support.
+ *
+ * Module:  library/pkcs11.c
+ * Caller:  library/pk.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define MBEDTLS_PKCS11_C
+
+/**
+ * \def MBEDTLS_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module:  library/pkcs12.c
+ * Caller:  library/pkparse.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * Can use:  MBEDTLS_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+//#define MBEDTLS_PKCS12_C
+
+/**
+ * \def MBEDTLS_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
+ * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module:  library/platform.c
+ * Caller:  Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#define MBEDTLS_PLATFORM_C
+
+/**
+ * \def MBEDTLS_POLY1305_C
+ *
+ * Enable the Poly1305 MAC algorithm.
+ *
+ * Module:  library/poly1305.c
+ * Caller:  library/chachapoly.c
+ */
+#define MBEDTLS_POLY1305_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_C
+ *
+ * Enable the Platform Security Architecture cryptography API.
+ *
+ * Module:  library/psa_crypto.c
+ *
+ * Requires: MBEDTLS_CTR_DRBG_C, MBEDTLS_ENTROPY_C
+ *
+ */
+#define MBEDTLS_PSA_CRYPTO_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_STORAGE_C
+ *
+ * Enable the Platform Security Architecture persistent key storage.
+ *
+ * Module:  library/psa_crypto_storage.c
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C and one of either
+ * MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C or MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
+ * (but not both)
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_STORAGE_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C
+ *
+ * Enable persistent key storage over files for the
+ * Platform Security Architecture cryptography API.
+ *
+ * Module:  library/psa_crypto_storage_file.c
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_FS_IO
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_STORAGE_FILE_C
+
+/**
+ * \def MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
+ *
+ * Enable persistent key storage over PSA ITS for the
+ * Platform Security Architecture cryptography API.
+ *
+ * Module:  library/psa_crypto_storage_its.c
+ *
+ * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_HAS_ITS_IO
+ *
+ */
+//#define MBEDTLS_PSA_CRYPTO_STORAGE_ITS_C
+
+/**
+ * \def MBEDTLS_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module:  library/ripemd160.c
+ * Caller:  library/md.c
+ *
+ */
+//#define MBEDTLS_RIPEMD160_C
+
+/**
+ * \def MBEDTLS_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module:  library/rsa.c
+ *          library/rsa_internal.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ *      RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C
+ */
+#define MBEDTLS_RSA_C
+
+/**
+ * \def MBEDTLS_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module:  library/sha1.c
+ * Caller:  library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
+ * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_SHA1_C
+
+/**
+ * \def MBEDTLS_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module:  library/sha256.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define MBEDTLS_SHA256_C
+
+/**
+ * \def MBEDTLS_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ *
+ * Module:  library/sha512.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define MBEDTLS_SHA512_C
+
+/**
+ * \def MBEDTLS_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module:  library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_CACHE_C
+ */
+//#define MBEDTLS_SSL_CACHE_C
+
+/**
+ * \def MBEDTLS_SSL_COOKIE_C
+ *
+ * Enable basic implementation of DTLS cookies for hello verification.
+ *
+ * Module:  library/ssl_cookie.c
+ * Caller:
+ */
+//#define MBEDTLS_SSL_COOKIE_C
+
+/**
+ * \def MBEDTLS_SSL_TICKET_C
+ *
+ * Enable an implementation of TLS server-side callbacks for session tickets.
+ *
+ * Module:  library/ssl_ticket.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_CIPHER_C
+ */
+//#define MBEDTLS_SSL_TICKET_C
+
+/**
+ * \def MBEDTLS_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module:  library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+//#define MBEDTLS_SSL_CLI_C
+
+/**
+ * \def MBEDTLS_SSL_SRV_C
+ *
+ * Enable the SSL/TLS server code.
+ *
+ * Module:  library/ssl_srv.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS server support.
+ */
+//#define MBEDTLS_SSL_SRV_C
+
+/**
+ * \def MBEDTLS_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module:  library/ssl_tls.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ *           and at least one of the MBEDTLS_SSL_PROTO_XXX defines
+ *
+ * This module is required for SSL/TLS.
+ */
+//#define MBEDTLS_SSL_TLS_C
+
+/**
+ * \def MBEDTLS_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default mbed TLS assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
+ *
+ * Module:  library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either MBEDTLS_THREADING_ALT or
+ * MBEDTLS_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within mbed TLS
+ */
+//#define MBEDTLS_THREADING_C
+
+/**
+ * \def MBEDTLS_TIMING_C
+ *
+ * Enable the semi-portable timing interface.
+ *
+ * \note The provided implementation only works on POSIX/Unix (including Linux,
+ * BSD and OS X) and Windows. On other platforms, you can either disable that
+ * module and provide your own implementations of the callbacks needed by
+ * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide
+ * your own implementation of the whole module by setting
+ * \c MBEDTLS_TIMING_ALT in the current file.
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/timing.c
+ * Caller:  library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+//#define MBEDTLS_TIMING_C
+
+/**
+ * \def MBEDTLS_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module:  library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define MBEDTLS_VERSION_C
+
+/**
+ * \def MBEDTLS_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module:  library/x509.c
+ * Caller:  library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C,
+ *           MBEDTLS_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+//#define MBEDTLS_X509_USE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module:  library/x509_crt.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+//#define MBEDTLS_X509_CRT_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module:  library/x509_crl.c
+ * Caller:  library/x509_crt.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+//#define MBEDTLS_X509_CRL_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module:  library/x509_csr.c
+ * Caller:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+//#define MBEDTLS_X509_CSR_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module:  library/x509_create.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+//#define MBEDTLS_X509_CREATE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_WRITE_C
+ *
+ * Enable creating X.509 certificates.
+ *
+ * Module:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate creation.
+ */
+//#define MBEDTLS_X509_CRT_WRITE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module:  library/x509_csr_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+//#define MBEDTLS_X509_CSR_WRITE_C
+
+/**
+ * \def MBEDTLS_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module:  library/xtea.c
+ * Caller:
+ */
+//#define MBEDTLS_XTEA_C
+
+/* \} name SECTION: mbed TLS modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define MBEDTLS_MPI_WINDOW_SIZE            6 /**< Maximum windows size used. */
+//#define MBEDTLS_MPI_MAX_SIZE            1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN               48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+/*!  Maximal reseed counter - indicates maximal number of
+requests allowed between reseeds; according to NIST 800-90
+it is (2^48 - 1), our restriction is :  (int - 0xFFFF - 0xF ).*/
+#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL            0xFFF0 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_CTR_DRBG_MAX_INPUT                256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_CTR_DRBG_MAX_REQUEST             1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT           384 /**< Maximum size of (re)seed buffer */
+//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY              /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */
+
+/* HMAC_DRBG options */
+//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_HMAC_DRBG_MAX_INPUT           256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST        1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT      384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define MBEDTLS_ECP_MAX_BITS             521 /**< Maximum bit size of groups */
+//#define MBEDTLS_ECP_WINDOW_SIZE            6 /**< Maximum window size used */
+//#define MBEDTLS_ECP_FIXED_POINT_OPTIM      1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define MBEDTLS_ENTROPY_MAX_SOURCES                20 /**< Maximum number of sources supported */
+#define MBEDTLS_ENTROPY_MAX_GATHER                   144 /**< Maximum amount requested from entropy sources */
+//#define MBEDTLS_ENTROPY_MIN_HARDWARE               32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */
+
+/* Memory buffer allocator options */
+//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE      4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define MBEDTLS_PLATFORM_STD_MEM_HDR   <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define MBEDTLS_PLATFORM_STD_CALLOC        calloc /**< Default allocator to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_FREE            free /**< Default free to use, can be undefined */
+
+//#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
+
+/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
+/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
+//#define MBEDTLS_PLATFORM_CALLOC_MACRO          calloc /**< Default allocator macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined */
+#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_MACRO            time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
+#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+
+/**
+ * \brief       This macro is invoked by the library when an invalid parameter
+ *              is detected that is only checked with MBEDTLS_CHECK_PARAMS
+ *              (see the documentation of that option for context).
+ *
+ *              When you leave this undefined here, a default definition is
+ *              provided that invokes the function mbedtls_param_failed(),
+ *              which is declared in platform_util.h for the benefit of the
+ *              library, but that you need to define in your application.
+ *
+ *              When you define this here, this replaces the default
+ *              definition in platform_util.h (which no longer declares the
+ *              function mbedtls_param_failed()) and it is your responsibility
+ *              to make sure this macro expands to something suitable (in
+ *              particular, that all the necessary declarations are visible
+ *              from within the library - you can ensure that by providing
+ *              them in this file next to the macro definition).
+ *
+ *              Note that you may define this macro to expand to nothing, in
+ *              which case you don't have to worry about declarations or
+ *              definitions. However, you will then be notified about invalid
+ *              parameters only in non-void functions, and void function will
+ *              just silently return early on invalid parameters, which
+ *              partially negates the benefits of enabling
+ *              #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
+ *
+ * \param cond  The expression that should evaluate to true, but doesn't.
+ */
+//#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
+
+/* SSL Cache options */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
+
+/* SSL options */
+
+/** \def MBEDTLS_SSL_MAX_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming and outgoing plaintext fragments.
+ *
+ * This determines the size of both the incoming and outgoing TLS I/O buffers
+ * in such a way that both are capable of holding the specified amount of
+ * plaintext data, regardless of the protection mechanism used.
+ *
+ * To configure incoming and outgoing I/O buffers separately, use
+ * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN,
+ * which overwrite the value set by this option.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of both
+ * incoming and outgoing I/O buffers.
+ */
+//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_IN_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming plaintext fragments.
+ *
+ * This determines the size of the incoming TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option is undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of the incoming I/O buffer
+ * independently of the outgoing I/O buffer.
+ */
+//#define MBEDTLS_SSL_IN_CONTENT_LEN              16384
+
+/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of outgoing plaintext fragments.
+ *
+ * This determines the size of the outgoing TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * It is possible to save RAM by setting a smaller outward buffer, while keeping
+ * the default inward 16384 byte buffer to conform to the TLS specification.
+ *
+ * The minimum required outward buffer size is determined by the handshake
+ * protocol's usage. Handshaking will fail if the outward buffer is too small.
+ * The specific size requirement depends on the configured ciphers and any
+ * certificate data which is sent during the handshake.
+ *
+ * Uncomment to set the maximum plaintext size of the outgoing I/O buffer
+ * independently of the incoming I/O buffer.
+ */
+//#define MBEDTLS_SSL_OUT_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING
+ *
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ *
+ * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * to account for a reassembled handshake message of maximum size,
+ * together with its reassembly bitmap.
+ *
+ * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default)
+ * should be sufficient for all practical situations as it allows
+ * to reassembly a large handshake message (such as a certificate)
+ * while buffering multiple smaller handshake messages.
+ *
+ */
+//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING             32768
+
+//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
+//#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
+//#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+/* X509 options */
+//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
+//#define MBEDTLS_X509_MAX_FILE_PATH_LEN     512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
+
+/**
+ * Allow SHA-1 in the default TLS configuration for certificate signing.
+ * Without this build-time option, SHA-1 support must be activated explicitly
+ * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
+ * recommended because of it is possible to generate SHA-1 collisions, however
+ * this may be safe for legacy infrastructure where additional controls apply.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+
+/**
+ * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
+ * signature and ciphersuite selection. Without this build-time option, SHA-1
+ * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes.
+ * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
+ * default. At the time of writing, there is no practical attack on the use
+ * of SHA-1 in handshake signatures, hence this option is turned on by default
+ * to preserve compatibility with existing peers, but the general
+ * warning applies nonetheless:
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
+
+/**
+ * Uncomment the macro to let mbed TLS use your alternate implementation of
+ * mbedtls_platform_zeroize(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * mbedtls_platform_zeroize() is a widely used function across the library to
+ * zero a block of memory. The implementation is expected to be secure in the
+ * sense that it has been written to prevent the compiler from removing calls
+ * to mbedtls_platform_zeroize() as part of redundant code elimination
+ * optimizations. However, it is difficult to guarantee that calls to
+ * mbedtls_platform_zeroize() will not be optimized by the compiler as older
+ * versions of the C language standards do not provide a secure implementation
+ * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to
+ * configure their own implementation of mbedtls_platform_zeroize(), for
+ * example by using directives specific to their compiler, features from newer
+ * C standards (e.g using memset_s() in C11) or calling a secure memset() from
+ * their system (e.g explicit_bzero() in BSD).
+ */
+//#define MBEDTLS_PLATFORM_ZEROIZE_ALT
+
+/**
+ * Uncomment the macro to let Mbed TLS use your alternate implementation of
+ * mbedtls_platform_gmtime_r(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * gmtime() is not a thread-safe function as defined in the C standard. The
+ * library will try to use safer implementations of this function, such as
+ * gmtime_r() when available. However, if Mbed TLS cannot identify the target
+ * system, the implementation of mbedtls_platform_gmtime_r() will default to
+ * using the standard gmtime(). In this case, calls from the library to
+ * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
+ * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
+ * library are also guarded with this mutex to avoid race conditions. However,
+ * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
+ * unconditionally use the implementation for mbedtls_platform_gmtime_r()
+ * supplied at compile time.
+ */
+//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
+
+/* \} name SECTION: Customisation configuration options */
+
+/*
+ * Allow user to override any previous default.
+ *
+ * Use two macro names for that, as:
+ * - with yotta the prefix YOTTA_CFG_ is forced
+ * - without yotta is looks weird to have a YOTTA prefix.
+ */
+#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
+#elif defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#include "mbedtls/check_config.h"
+
+/* define memory related functions */
+#if !defined(DX_PLAT_MUSCA_B1)
+//#include "region_defs.h"
+#endif
+
+#endif /* MBEDTLS_CONFIG_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312.h
new file mode 100644
index 0000000..0dfa27e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/config-cc312.h
@@ -0,0 +1,3270 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_CONFIG_H
+#define MBEDTLS_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ *      library/aria.c
+ *      library/timing.c
+ *      include/mbedtls/bn_mul.h
+ *
+ * Required by:
+ *      MBEDTLS_AESNI_C
+ *      MBEDTLS_PADLOCK_C
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define MBEDTLS_HAVE_ASM
+
+/**
+ * \def MBEDTLS_NO_UDBL_DIVISION
+ *
+ * The platform lacks support for double-width integer division (64-bit
+ * division on a 32-bit platform, 128-bit division on a 64-bit platform).
+ *
+ * Used in:
+ *      include/mbedtls/bignum.h
+ *      library/bignum.c
+ *
+ * The bignum code uses double-width division to speed up some operations.
+ * Double-width division is often implemented in software that needs to
+ * be linked with the program. The presence of a double-width integer
+ * type is usually detected automatically through preprocessor macros,
+ * but the automatic detection cannot know whether the code needs to
+ * and can be linked with an implementation of division for that type.
+ * By default division is assumed to be usable if the type is present.
+ * Uncomment this option to prevent the use of double-width division.
+ *
+ * Note that division for the native integer type is always required.
+ * Furthermore, a 64-bit type is always required even on a 32-bit
+ * platform, but it need not support multiplication or division. In some
+ * cases it is also desirable to disable some double-width operations. For
+ * example, if double-width division is implemented in software, disabling
+ * it can reduce code size in some embedded targets.
+ */
+//#define MBEDTLS_NO_UDBL_DIVISION
+
+/**
+ * \def MBEDTLS_NO_64BIT_MULTIPLICATION
+ *
+ * The platform lacks support for 32x32 -> 64-bit multiplication.
+ *
+ * Used in:
+ *      library/poly1305.c
+ *
+ * Some parts of the library may use multiplication of two unsigned 32-bit
+ * operands with a 64-bit result in order to speed up computations. On some
+ * platforms, this is not available in hardware and has to be implemented in
+ * software, usually in a library provided by the toolchain.
+ *
+ * Sometimes it is not desirable to have to link to that library. This option
+ * removes the dependency of that library on platforms that lack a hardware
+ * 64-bit multiplier by embedding a software implementation in Mbed TLS.
+ *
+ * Note that depending on the compiler, this may decrease performance compared
+ * to using the library function provided by the toolchain.
+ */
+//#define MBEDTLS_NO_64BIT_MULTIPLICATION
+
+/**
+ * \def MBEDTLS_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define MBEDTLS_HAVE_SSE2
+
+/**
+ * \def MBEDTLS_HAVE_TIME
+ *
+ * System has time.h and time().
+ * The time does not need to be correct, only time differences are used,
+ * by contrast with MBEDTLS_HAVE_TIME_DATE
+ *
+ * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT,
+ * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and
+ * MBEDTLS_PLATFORM_STD_TIME.
+ *
+ * Comment if your system does not support time functions
+ */
+#define MBEDTLS_HAVE_TIME
+
+/**
+ * \def MBEDTLS_HAVE_TIME_DATE
+ *
+ * System has time.h, time(), and an implementation for
+ * mbedtls_platform_gmtime_r() (see below).
+ * The time needs to be correct (not necesarily very accurate, but at least
+ * the date should be correct). This is used to verify the validity period of
+ * X.509 certificates.
+ *
+ * Comment if your system does not have a correct clock.
+ *
+ * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that
+ * behaves similarly to the gmtime_r() function from the C standard. Refer to
+ * the documentation for mbedtls_platform_gmtime_r() for more information.
+ *
+ * \note It is possible to configure an implementation for
+ * mbedtls_platform_gmtime_r() at compile-time by using the macro
+ * MBEDTLS_PLATFORM_GMTIME_R_ALT.
+ */
+#define MBEDTLS_HAVE_TIME_DATE
+
+/**
+ * \def MBEDTLS_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default mbed TLS uses the system-provided calloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY without the
+ * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide
+ * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and
+ * free() function pointer at runtime.
+ *
+ * Enabling MBEDTLS_PLATFORM_MEMORY and specifying
+ * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the
+ * alternate function at compile time.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+#define MBEDTLS_PLATFORM_MEMORY
+
+/**
+ * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. calloc() to
+ * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a
+ * MBEDTLS_PLATFORM_XXX_MACRO.
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def MBEDTLS_PLATFORM_EXIT_ALT
+ *
+ * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the
+ * function in the platform abstraction layer.
+ *
+ * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will
+ * provide a function "mbedtls_platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require MBEDTLS_PLATFORM_C to be defined!
+ *
+ * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows;
+ * it will be enabled automatically by check_config.h
+ *
+ * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as
+ * MBEDTLS_PLATFORM_XXX_MACRO!
+ *
+ * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define MBEDTLS_PLATFORM_EXIT_ALT
+//#define MBEDTLS_PLATFORM_TIME_ALT
+//#define MBEDTLS_PLATFORM_FPRINTF_ALT
+//#define MBEDTLS_PLATFORM_PRINTF_ALT
+//#define MBEDTLS_PLATFORM_SNPRINTF_ALT
+//#define MBEDTLS_PLATFORM_NV_SEED_ALT
+//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT
+
+/**
+ * \def MBEDTLS_DEPRECATED_WARNING
+ *
+ * Mark deprecated functions so that they generate a warning if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * This only works with GCC and Clang. With other compilers, you may want to
+ * use MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Uncomment to get warnings on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_WARNING
+
+/**
+ * \def MBEDTLS_DEPRECATED_REMOVED
+ *
+ * Remove deprecated functions so that they generate an error if used.
+ * Functions deprecated in one version will usually be removed in the next
+ * version. You can enable this to help you prepare the transition to a new
+ * major version by making sure your code is not using these functions.
+ *
+ * Uncomment to get errors on using deprecated functions.
+ */
+//#define MBEDTLS_DEPRECATED_REMOVED
+
+/**
+ * \def MBEDTLS_CHECK_PARAMS
+ *
+ * This configuration option controls whether the library validates more of
+ * the parameters passed to it.
+ *
+ * When this flag is not defined, the library only attempts to validate an
+ * input parameter if: (1) they may come from the outside world (such as the
+ * network, the filesystem, etc.) or (2) not validating them could result in
+ * internal memory errors such as overflowing a buffer controlled by the
+ * library. On the other hand, it doesn't attempt to validate parameters whose
+ * values are fully controlled by the application (such as pointers).
+ *
+ * When this flag is defined, the library additionally attempts to validate
+ * parameters that are fully controlled by the application, and should always
+ * be valid if the application code is fully correct and trusted.
+ *
+ * For example, when a function accepts as input a pointer to a buffer that may
+ * contain untrusted data, and its documentation mentions that this pointer
+ * must not be NULL:
+ * - the pointer is checked to be non-NULL only if this option is enabled
+ * - the content of the buffer is always validated
+ *
+ * When this flag is defined, if a library function receives a parameter that
+ * is invalid, it will:
+ * - invoke the macro MBEDTLS_PARAM_FAILED() which by default expands to a
+ *   call to the function mbedtls_param_failed()
+ * - immediately return (with a specific error code unless the function
+ *   returns void and can't communicate an error).
+ *
+ * When defining this flag, you also need to:
+ * - either provide a definition of the function mbedtls_param_failed() in
+ *   your application (see platform_util.h for its prototype) as the library
+ *   calls that function, but does not provide a default definition for it,
+ * - or provide a different definition of the macro MBEDTLS_PARAM_FAILED()
+ *   below if the above mechanism is not flexible enough to suit your needs.
+ *   See the documentation of this macro later in this file.
+ *
+ * Uncomment to enable validation of application-controlled parameters.
+ */
+//#define MBEDTLS_CHECK_PARAMS
+
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: mbed TLS feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_TIMING_ALT
+ *
+ * Uncomment to provide your own alternate implementation for mbedtls_timing_hardclock(),
+ * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay()
+ *
+ * Only works if you have MBEDTLS_TIMING_C enabled.
+ *
+ * You will need to provide a header "timing_alt.h" and an implementation at
+ * compile time.
+ */
+//#define MBEDTLS_TIMING_ALT
+
+/**
+ * \def MBEDTLS_AES_ALT
+ *
+ * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternate core implementation of a symmetric crypto, an arithmetic or hash
+ * module (e.g. platform specific assembly optimized implementations). Keep
+ * in mind that the function prototypes should remain the same.
+ *
+ * This replaces the whole module. If you only want to replace one of the
+ * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer
+ * provide the "struct mbedtls_aes_context" definition and omit the base
+ * function declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * module.
+ *
+ * \warning   MD2, MD4, MD5, ARC4, DES and SHA-1 are considered weak and their
+ *            use constitutes a security risk. If possible, we recommend
+ *            avoiding dependencies on them, and considering stronger message
+ *            digests and ciphers instead.
+ *
+ */
+#define MBEDTLS_AES_ALT
+//#define MBEDTLS_ARC4_ALT
+//#define MBEDTLS_ARIA_ALT
+//#define MBEDTLS_BLOWFISH_ALT
+//#define MBEDTLS_CAMELLIA_ALT
+#define MBEDTLS_CCM_ALT
+#define MBEDTLS_CHACHA20_ALT
+#define MBEDTLS_CHACHAPOLY_ALT
+#define MBEDTLS_CMAC_ALT
+//#define MBEDTLS_DES_ALT
+#define MBEDTLS_DHM_ALT
+//#define MBEDTLS_ECJPAKE_ALT
+#define MBEDTLS_GCM_ALT
+//#define MBEDTLS_NIST_KW_ALT
+//#define MBEDTLS_MD2_ALT
+//#define MBEDTLS_MD4_ALT
+//#define MBEDTLS_MD5_ALT
+#define MBEDTLS_POLY1305_ALT
+//#define MBEDTLS_RIPEMD160_ALT
+//#define MBEDTLS_XTEA_ALT
+#define MBEDTLS_SHA1_ALT
+#define MBEDTLS_SHA256_ALT
+//#define MBEDTLS_SHA512_ALT
+#define MBEDTLS_RSA_ALT
+
+
+/*
+ * When replacing the elliptic curve module, pleace consider, that it is
+ * implemented with two .c files:
+ *      - ecp.c
+ *      - ecp_curves.c
+ * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT
+ * macros as described above. The only difference is that you have to make sure
+ * that you provide functionality for both .c files.
+ */
+//#define MBEDTLS_ECP_ALT
+
+/**
+ * \def MBEDTLS_MD2_PROCESS_ALT
+ *
+ * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you
+ * alternate core implementation of symmetric crypto or hash function. Keep in
+ * mind that function prototypes should remain the same.
+ *
+ * This replaces only one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags.
+ *
+ * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will
+ * no longer provide the mbedtls_sha1_process() function, but it will still provide
+ * the other function (using your mbedtls_sha1_process() function) and the definition
+ * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible
+ * with this definition.
+ *
+ * \note Because of a signature change, the core AES encryption and decryption routines are
+ *       currently named mbedtls_aes_internal_encrypt and mbedtls_aes_internal_decrypt,
+ *       respectively. When setting up alternative implementations, these functions should
+ *       be overriden, but the wrapper functions mbedtls_aes_decrypt and mbedtls_aes_encrypt
+ *       must stay untouched.
+ *
+ * \note If you use the AES_xxx_ALT macros, then is is recommended to also set
+ *       MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES
+ *       tables.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ *
+ * \warning   MD2, MD4, MD5, DES and SHA-1 are considered weak and their use
+ *            constitutes a security risk. If possible, we recommend avoiding
+ *            dependencies on them, and considering stronger message digests
+ *            and ciphers instead.
+ *
+ */
+//#define MBEDTLS_MD2_PROCESS_ALT
+//#define MBEDTLS_MD4_PROCESS_ALT
+//#define MBEDTLS_MD5_PROCESS_ALT
+//#define MBEDTLS_RIPEMD160_PROCESS_ALT
+//#define MBEDTLS_SHA1_PROCESS_ALT
+//#define MBEDTLS_SHA256_PROCESS_ALT
+//#define MBEDTLS_SHA512_PROCESS_ALT
+//#define MBEDTLS_DES_SETKEY_ALT
+//#define MBEDTLS_DES_CRYPT_ECB_ALT
+//#define MBEDTLS_DES3_CRYPT_ECB_ALT
+//#define MBEDTLS_AES_SETKEY_ENC_ALT
+//#define MBEDTLS_AES_SETKEY_DEC_ALT
+//#define MBEDTLS_AES_ENCRYPT_ALT
+//#define MBEDTLS_AES_DECRYPT_ALT
+#define MBEDTLS_ECDH_GEN_PUBLIC_ALT
+#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT
+#define MBEDTLS_ECDSA_VERIFY_ALT
+#define MBEDTLS_ECDSA_SIGN_ALT
+#define MBEDTLS_ECDSA_GENKEY_ALT
+
+/**
+ * \def MBEDTLS_ECP_INTERNAL_ALT
+ *
+ * Expose a part of the internal interface of the Elliptic Curve Point module.
+ *
+ * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your
+ * alternative core implementation of elliptic curve arithmetic. Keep in mind
+ * that function prototypes should remain the same.
+ *
+ * This partially replaces one function. The header file from mbed TLS is still
+ * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation
+ * is still present and it is used for group structures not supported by the
+ * alternative.
+ *
+ * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT
+ * and implementing the following functions:
+ *      unsigned char mbedtls_internal_ecp_grp_capable(
+ *          const mbedtls_ecp_group *grp )
+ *      int  mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp )
+ *      void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp )
+ * The mbedtls_internal_ecp_grp_capable function should return 1 if the
+ * replacement functions implement arithmetic for the given group and 0
+ * otherwise.
+ * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are
+ * called before and after each point operation and provide an opportunity to
+ * implement optimized set up and tear down instructions.
+ *
+ * Example: In case you uncomment MBEDTLS_ECP_INTERNAL_ALT and
+ * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac
+ * function, but will use your mbedtls_internal_ecp_double_jac if the group is
+ * supported (your mbedtls_internal_ecp_grp_capable function returns 1 when
+ * receives it as an argument). If the group is not supported then the original
+ * implementation is used. The other functions and the definition of
+ * mbedtls_ecp_group and mbedtls_ecp_point will not change, so your
+ * implementation of mbedtls_internal_ecp_double_jac and
+ * mbedtls_internal_ecp_grp_capable must be compatible with this definition.
+ *
+ * Uncomment a macro to enable alternate implementation of the corresponding
+ * function.
+ */
+/* Required for all the functions in this section */
+//#define MBEDTLS_ECP_INTERNAL_ALT
+/* Support for Weierstrass curves with Jacobi representation */
+//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
+//#define MBEDTLS_ECP_ADD_MIXED_ALT
+//#define MBEDTLS_ECP_DOUBLE_JAC_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
+//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
+/* Support for curves with Montgomery arithmetic */
+//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT
+//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT
+//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT
+
+/**
+ * \def MBEDTLS_TEST_NULL_ENTROPY
+ *
+ * Enables testing and use of mbed TLS without any configured entropy sources.
+ * This permits use of the library on platforms before an entropy source has
+ * been integrated (see for example the MBEDTLS_ENTROPY_HARDWARE_ALT or the
+ * MBEDTLS_ENTROPY_NV_SEED switches).
+ *
+ * WARNING! This switch MUST be disabled in production builds, and is suitable
+ * only for development.
+ * Enabling the switch negates any security provided by the library.
+ *
+ * Requires MBEDTLS_ENTROPY_C, MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ */
+//#define MBEDTLS_TEST_NULL_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_HARDWARE_ALT
+ *
+ * Uncomment this macro to let mbed TLS use your own implementation of a
+ * hardware entropy collector.
+ *
+ * Your function must be called \c mbedtls_hardware_poll(), have the same
+ * prototype as declared in entropy_poll.h, and accept NULL as first argument.
+ *
+ * Uncomment to use your own hardware entropy collector.
+ */
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+
+/**
+ * \def MBEDTLS_AES_ROM_TABLES
+ *
+ * Use precomputed AES tables stored in ROM.
+ *
+ * Uncomment this macro to use precomputed AES tables stored in ROM.
+ * Comment this macro to generate AES tables in RAM at runtime.
+ *
+ * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb
+ * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the
+ * initialization time before the first AES operation can be performed.
+ * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c
+ * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded
+ * performance if ROM access is slower than RAM access.
+ *
+ * This option is independent of \c MBEDTLS_AES_FEWER_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_ROM_TABLES
+
+/**
+ * \def MBEDTLS_AES_FEWER_TABLES
+ *
+ * Use less ROM/RAM for AES tables.
+ *
+ * Uncommenting this macro omits 75% of the AES tables from
+ * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES)
+ * by computing their values on the fly during operations
+ * (the tables are entry-wise rotations of one another).
+ *
+ * Tradeoff: Uncommenting this reduces the RAM / ROM footprint
+ * by ~6kb but at the cost of more arithmetic operations during
+ * runtime. Specifically, one has to compare 4 accesses within
+ * different tables to 4 accesses with additional arithmetic
+ * operations within the same table. The performance gain/loss
+ * depends on the system and memory details.
+ *
+ * This option is independent of \c MBEDTLS_AES_ROM_TABLES.
+ *
+ */
+//#define MBEDTLS_AES_FEWER_TABLES
+
+/**
+ * \def MBEDTLS_CAMELLIA_SMALL_MEMORY
+ *
+ * Use less ROM for the Camellia implementation (saves about 768 bytes).
+ *
+ * Uncomment this macro to use less memory for Camellia.
+ */
+//#define MBEDTLS_CAMELLIA_SMALL_MEMORY
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_XTS
+ *
+ * Enable Cipher Block XTS for symmetric ciphers.
+ */
+//#define MBEDTLS_CIPHER_MODE_XTS
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CBC
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+//#define MBEDTLS_CIPHER_MODE_CFB
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_CTR
+
+/**
+ * \def MBEDTLS_CIPHER_MODE_OFB
+ *
+ * Enable Output Feedback Cipher mode (OFB) for symmetric
+ * ciphers.
+ */
+#define MBEDTLS_CIPHER_MODE_OFB
+
+/**
+ * \def MBEDTLS_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires MBEDTLS_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_NULL_SHA
+ *      MBEDTLS_TLS_RSA_WITH_NULL_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_NULL_SHA
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+ */
+//#define MBEDTLS_CIPHER_NULL_CIPHER
+
+/**
+ * \def MBEDTLS_CIPHER_PADDING_PKCS7
+ *
+ * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for
+ * specific padding modes in the cipher layer with cipher modes that support
+ * padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+//#define MBEDTLS_CIPHER_PADDING_PKCS7
+//#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS
+//#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN
+//#define MBEDTLS_CIPHER_PADDING_ZEROS
+
+/**
+ * \def MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels with virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ *      MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_ENABLE_WEAK_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+//#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
+
+/**
+ * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED
+ *
+ * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve
+ * module.  By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+
+#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
+#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
+#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
+/* CryptoCell only supports BP256R1 brainpool curve at this stage */
+#define MBEDTLS_ECP_DP_BP256R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP384R1_ENABLED
+//#define MBEDTLS_ECP_DP_BP512R1_ENABLED
+#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
+//#define MBEDTLS_ECP_DP_CURVE448_ENABLED
+
+/**
+ * \def MBEDTLS_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimization.
+ */
+#define MBEDTLS_ECP_NIST_OPTIM
+
+/**
+ * \def MBEDTLS_ECP_RESTARTABLE
+ *
+ * Enable "non-blocking" ECC operations that can return early and be resumed.
+ *
+ * This allows various functions to pause by returning
+ * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module,
+ * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in
+ * order to further progress and eventually complete their operation. This is
+ * controlled through mbedtls_ecp_set_max_ops() which limits the maximum
+ * number of ECC operations a function may perform before pausing; see
+ * mbedtls_ecp_set_max_ops() for more information.
+ *
+ * This is useful in non-threaded environments if you want to avoid blocking
+ * for too long on ECC (and, hence, X.509 or SSL/TLS) operations.
+ *
+ * Uncomment this macro to enable restartable ECC computations.
+ *
+ * \note  This option only works with the default software implementation of
+ *        elliptic curve functionality. It is incompatible with
+ *        MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT and MBEDTLS_ECDSA_XXX_ALT.
+ */
+//#define MBEDTLS_ECP_RESTARTABLE
+
+/**
+ * \def MBEDTLS_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: MBEDTLS_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define MBEDTLS_ECDSA_DETERMINISTIC
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+ *
+ * Enable the PSK based ciphersuite modes in SSL / TLS.
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+ *
+ * Enable the DHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+ *
+ * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+ *
+ * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+ *
+ * Enable the RSA-only based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ */
+//#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+ *
+ * Enable the DHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+//#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+ *
+ * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15,
+ *           MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
+ * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+ *
+ * Enable the ECJPAKE based ciphersuite modes in SSL / TLS.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Requires: MBEDTLS_ECJPAKE_C
+ *           MBEDTLS_SHA256_C
+ *           MBEDTLS_ECP_DP_SECP256R1_ENABLED
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8
+ */
+//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED
+
+/**
+ * \def MBEDTLS_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+//#define MBEDTLS_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def MBEDTLS_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of mbedtls_strerror() in
+ * third party libraries easier when MBEDTLS_ERROR_C is disabled
+ * (no effect when MBEDTLS_ERROR_C is enabled).
+ *
+ * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're
+ * not using mbedtls_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * mbedtls_strerror()
+ */
+#define MBEDTLS_ERROR_STRERROR_DUMMY
+
+/**
+ * \def MBEDTLS_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: MBEDTLS_BIGNUM_C
+ */
+#define MBEDTLS_GENPRIME
+
+/**
+ * \def MBEDTLS_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+//#define MBEDTLS_FS_IO
+
+/**
+ * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * mbedtls_timing_hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def MBEDTLS_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+//#define MBEDTLS_NO_PLATFORM_ENTROPY
+
+/**
+ * \def MBEDTLS_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: MBEDTLS_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both MBEDTLS_SHA256_C and
+ * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define MBEDTLS_ENTROPY_FORCE_SHA256
+
+/**
+ * \def MBEDTLS_ENTROPY_NV_SEED
+ *
+ * Enable the non-volatile (NV) seed file-based entropy source.
+ * (Also enables the NV seed read/write functions in the platform layer)
+ *
+ * This is crucial (if not required) on systems that do not have a
+ * cryptographic entropy source (in hardware or kernel) available.
+ *
+ * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C
+ *
+ * \note The read/write functions that are used by the entropy source are
+ *       determined in the platform layer, and can be modified at runtime and/or
+ *       compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used.
+ *
+ * \note If you use the default implementation functions that read a seedfile
+ *       with regular fopen(), please make sure you make a seedfile with the
+ *       proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at
+ *       least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from
+ *       and written to or you will get an entropy source error! The default
+ *       implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE
+ *       bytes from the file.
+ *
+ * \note The entropy collector will write to the seed file before entropy is
+ *       given to an external source, to update it.
+ */
+//#define MBEDTLS_ENTROPY_NV_SEED
+
+/**
+ * \def MBEDTLS_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define MBEDTLS_MEMORY_DEBUG
+
+/**
+ * \def MBEDTLS_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *           GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define MBEDTLS_MEMORY_BACKTRACE
+
+/**
+ * \def MBEDTLS_PK_RSA_ALT_SUPPORT
+ *
+ * Support external private RSA keys (eg from a HSM) in the PK layer.
+ *
+ * Comment this macro to disable support for external private RSA keys.
+ */
+//#define MBEDTLS_PK_RSA_ALT_SUPPORT
+
+/**
+ * \def MBEDTLS_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: MBEDTLS_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#define MBEDTLS_PKCS1_V15
+
+/**
+ * \def MBEDTLS_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#define MBEDTLS_PKCS1_V21
+
+/**
+ * \def MBEDTLS_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem
+ * for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define MBEDTLS_RSA_NO_CRT
+
+/**
+ * \def MBEDTLS_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+//#define MBEDTLS_SELF_TEST
+
+/**
+ * \def MBEDTLS_SHA256_SMALLER
+ *
+ * Enable an implementation of SHA-256 that has lower ROM footprint but also
+ * lower performance.
+ *
+ * The default implementation is meant to be a reasonnable compromise between
+ * performance and size. This version optimizes more aggressively for size at
+ * the expense of performance. Eg on Cortex-M4 it reduces the size of
+ * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about
+ * 30%.
+ *
+ * Uncomment to enable the smaller implementation of SHA256.
+ */
+//#define MBEDTLS_SHA256_SMALLER
+
+/**
+ * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, mbed TLS can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+//#define MBEDTLS_SSL_ALL_ALERT_MESSAGES
+
+/**
+ * \def MBEDTLS_SSL_ASYNC_PRIVATE
+ *
+ * Enable asynchronous external private key operations in SSL. This allows
+ * you to configure an SSL connection to call an external cryptographic
+ * module to perform private key operations instead of performing the
+ * operation inside the library.
+ *
+ */
+//#define MBEDTLS_SSL_ASYNC_PRIVATE
+
+/**
+ * \def MBEDTLS_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+ */
+//#define MBEDTLS_SSL_DEBUG_ALL
+
+/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC
+ *
+ * Enable support for Encrypt-then-MAC, RFC 7366.
+ *
+ * This allows peers that both support it to use a more robust protection for
+ * ciphersuites using CBC, providing deep resistance against timing attacks
+ * on the padding or underlying cipher.
+ *
+ * This only affects CBC ciphersuites, and is useless if none is defined.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Encrypt-then-MAC
+ */
+//#define MBEDTLS_SSL_ENCRYPT_THEN_MAC
+
+/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+ *
+ * Enable support for Extended Master Secret, aka Session Hash
+ * (draft-ietf-tls-session-hash-02).
+ *
+ * This was introduced as "the proper fix" to the Triple Handshake familiy of
+ * attacks, but it is recommended to always use it (even if you disable
+ * renegotiation), since it actually fixes a more fundamental issue in the
+ * original SSL/TLS design, and has implications beyond Triple Handshake.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1    or
+ *           MBEDTLS_SSL_PROTO_TLS1_1  or
+ *           MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for Extended Master Secret.
+ */
+//#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET
+
+/**
+ * \def MBEDTLS_SSL_FALLBACK_SCSV
+ *
+ * Enable support for FALLBACK_SCSV (draft-ietf-tls-downgrade-scsv-00).
+ *
+ * For servers, it is recommended to always enable this, unless you support
+ * only one version of TLS, or know for sure that none of your clients
+ * implements a fallback strategy.
+ *
+ * For clients, you only need this if you're using a fallback strategy, which
+ * is not recommended in the first place, unless you absolutely need it to
+ * interoperate with buggy (version-intolerant) servers.
+ *
+ * Comment this macro to disable support for FALLBACK_SCSV
+ */
+//#define MBEDTLS_SSL_FALLBACK_SCSV
+
+/**
+ * \def MBEDTLS_SSL_HW_RECORD_ACCEL
+ *
+ * Enable hooking functions in SSL module for hardware acceleration of
+ * individual records.
+ *
+ * Uncomment this macro to enable hooking functions.
+ */
+//#define MBEDTLS_SSL_HW_RECORD_ACCEL
+
+/**
+ * \def MBEDTLS_SSL_CBC_RECORD_SPLITTING
+ *
+ * Enable 1/n-1 record splitting for CBC mode in SSLv3 and TLS 1.0.
+ *
+ * This is a countermeasure to the BEAST attack, which also minimizes the risk
+ * of interoperability issues compared to sending 0-length records.
+ *
+ * Comment this macro to disable 1/n-1 record splitting.
+ */
+//#define MBEDTLS_SSL_CBC_RECORD_SPLITTING
+
+/**
+ * \def MBEDTLS_SSL_RENEGOTIATION
+ *
+ * Disable support for TLS renegotiation.
+ *
+ * The two main uses of renegotiation are (1) refresh keys on long-lived
+ * connections and (2) client authentication after the initial handshake.
+ * If you don't need renegotiation, it's probably better to disable it, since
+ * it has been associated with security issues in the past and is easy to
+ * misuse/misunderstand.
+ *
+ * Comment this to disable support for renegotiation.
+ *
+ * \note   Even if this option is disabled, both client and server are aware
+ *         of the Renegotiation Indication Extension (RFC 5746) used to
+ *         prevent the SSL renegotiation attack (see RFC 5746 Sect. 1).
+ *         (See \c mbedtls_ssl_conf_legacy_renegotiation for the
+ *          configuration of this extension).
+ *
+ */
+//#define MBEDTLS_SSL_RENEGOTIATION
+
+/**
+ * \def MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to enable support for SSLv2 Client Hello messages.
+ */
+//#define MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
+ * \def MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+ *
+ * Pick the ciphersuite according to the client's preferences rather than ours
+ * in the SSL Server module (MBEDTLS_SSL_SRV_C).
+ *
+ * Uncomment this macro to respect client's ciphersuite order
+ */
+//#define MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+/**
+ * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+//#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH
+
+/**
+ * \def MBEDTLS_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+//#define MBEDTLS_SSL_PROTO_SSL3
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0.
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1 (and DTLS 1.0 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_MD5_C
+ *           MBEDTLS_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1 / DTLS 1.0
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_1
+
+/**
+ * \def MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled).
+ *
+ * Requires: MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C
+ *           (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2 / DTLS 1.2
+ */
+//#define MBEDTLS_SSL_PROTO_TLS1_2
+
+/**
+ * \def MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Enable support for DTLS (all available versions).
+ *
+ * Enable this and MBEDTLS_SSL_PROTO_TLS1_1 to enable DTLS 1.0,
+ * and/or this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2.
+ *
+ * Requires: MBEDTLS_SSL_PROTO_TLS1_1
+ *        or MBEDTLS_SSL_PROTO_TLS1_2
+ *
+ * Comment this macro to disable support for DTLS
+ */
+//#define MBEDTLS_SSL_PROTO_DTLS
+
+/**
+ * \def MBEDTLS_SSL_ALPN
+ *
+ * Enable support for RFC 7301 Application Layer Protocol Negotiation.
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+//#define MBEDTLS_SSL_ALPN
+
+/**
+ * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY
+ *
+ * Enable support for the anti-replay mechanism in DTLS.
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *           MBEDTLS_SSL_PROTO_DTLS
+ *
+ * \warning Disabling this is often a security risk!
+ * See mbedtls_ssl_conf_dtls_anti_replay() for details.
+ *
+ * Comment this to disable anti-replay in DTLS.
+ */
+//#define MBEDTLS_SSL_DTLS_ANTI_REPLAY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Enable support for HelloVerifyRequest on DTLS servers.
+ *
+ * This feature is highly recommended to prevent DTLS servers being used as
+ * amplifiers in DoS attacks against other hosts. It should always be enabled
+ * unless you know for sure amplification cannot be a problem in the
+ * environment in which your server operates.
+ *
+ * \warning Disabling this can ba a security risk! (see above)
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ *
+ * Comment this to disable support for HelloVerifyRequest.
+ */
+//#define MBEDTLS_SSL_DTLS_HELLO_VERIFY
+
+/**
+ * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+ *
+ * Enable server-side support for clients that reconnect from the same port.
+ *
+ * Some clients unexpectedly close the connection and try to reconnect using the
+ * same source port. This needs special support from the server to handle the
+ * new connection securely, as described in section 4.2.8 of RFC 6347. This
+ * flag enables that support.
+ *
+ * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY
+ *
+ * Comment this to disable support for clients reusing the source port.
+ */
+//#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE
+
+/**
+ * \def MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+ *
+ * Enable support for a limit of records with bad MAC.
+ *
+ * See mbedtls_ssl_conf_dtls_badmac_limit().
+ *
+ * Requires: MBEDTLS_SSL_PROTO_DTLS
+ */
+//#define MBEDTLS_SSL_DTLS_BADMAC_LIMIT
+
+/**
+ * \def MBEDTLS_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ * Client-side, provides full support for session tickets (maintainance of a
+ * session store remains the responsibility of the application, though).
+ * Server-side, you also need to provide callbacks for writing and parsing
+ * tickets, including authenticated encryption and key management. Example
+ * callbacks are provided by MBEDTLS_SSL_TICKET_C.
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+//#define MBEDTLS_SSL_SESSION_TICKETS
+
+/**
+ * \def MBEDTLS_SSL_EXPORT_KEYS
+ *
+ * Enable support for exporting key block and master secret.
+ * This is required for certain users of TLS, e.g. EAP-TLS.
+ *
+ * Comment this macro to disable support for key export
+ */
+//#define MBEDTLS_SSL_EXPORT_KEYS
+
+/**
+ * \def MBEDTLS_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Requires: MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+//#define MBEDTLS_SSL_SERVER_NAME_INDICATION
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC
+
+/**
+ * \def MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+ *
+ * Fallback to old (pre-2.7), non-conforming implementation of the truncated
+ * HMAC extension which also truncates the HMAC key. Note that this option is
+ * only meant for a transitory upgrade period and is likely to be removed in
+ * a future version of the library.
+ *
+ * \warning The old implementation is non-compliant and has a security weakness
+ *          (2^80 brute force attack on the HMAC key used for a single,
+ *          uninterrupted connection). This should only be enabled temporarily
+ *          when (1) the use of truncated HMAC is essential in order to save
+ *          bandwidth, and (2) the peer is an Mbed TLS stack that doesn't use
+ *          the fixed implementation yet (pre-2.7).
+ *
+ * \deprecated This option is deprecated and will likely be removed in a
+ *             future version of Mbed TLS.
+ *
+ * Uncomment to fallback to old, non-compliant truncated HMAC implementation.
+ *
+ * Requires: MBEDTLS_SSL_TRUNCATED_HMAC
+ */
+//#define MBEDTLS_SSL_TRUNCATED_HMAC_COMPAT
+
+/**
+ * \def MBEDTLS_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define MBEDTLS_THREADING_ALT
+
+/**
+ * \def MBEDTLS_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: MBEDTLS_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+#define MBEDTLS_THREADING_PTHREAD
+
+/**
+ * \def MBEDTLS_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via mbedtls_version_check_feature().
+ *
+ * Requires: MBEDTLS_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define MBEDTLS_VERSION_FEATURES
+
+/**
+ * \def MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an extension in a v1 or v2 certificate.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3
+
+/**
+ * \def MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an unknown critical extension.
+ *
+ * \warning Depending on your PKI use, enabling this can be a security risk!
+ *
+ * Uncomment to prevent an error.
+ */
+//#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+
+/**
+ * \def MBEDTLS_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+//#define MBEDTLS_X509_CHECK_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+//#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE
+
+/**
+ * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT
+ *
+ * Enable parsing and verification of X.509 certificates, CRLs and CSRS
+ * signed with RSASSA-PSS (aka PKCS#1 v2.1).
+ *
+ * Comment this macro to disallow using RSASSA-PSS in certificates.
+ */
+//#define MBEDTLS_X509_RSASSA_PSS_SUPPORT
+
+/**
+ * \def MBEDTLS_ZLIB_SUPPORT
+ *
+ * If set, the SSL/TLS module uses ZLIB to support compression and
+ * decompression of packet data.
+ *
+ * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
+ * CRIME attack. Before enabling this option, you should examine with care if
+ * CRIME or similar exploits may be a applicable to your use case.
+ *
+ * \note Currently compression can't be used with DTLS.
+ *
+ * \deprecated This feature is deprecated and will be removed
+ *             in the next major revision of the library.
+ *
+ * Used in: library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This feature requires zlib library and headers to be present.
+ *
+ * Uncomment to enable use of ZLIB
+ */
+//#define MBEDTLS_ZLIB_SUPPORT
+/* \} name SECTION: mbed TLS feature support */
+
+/**
+ * \name SECTION: mbed TLS modules
+ *
+ * This section enables or disables entire modules in mbed TLS
+ * \{
+ */
+
+/**
+ * \def MBEDTLS_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module:  library/aesni.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+//#define MBEDTLS_AESNI_C
+
+/**
+ * \def MBEDTLS_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module:  library/aes.c
+ * Caller:  library/cipher.c
+ *          library/pem.c
+ *          library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define MBEDTLS_AES_C
+
+/**
+ * \def MBEDTLS_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module:  library/arc4.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_RSA_WITH_RC4_128_MD5
+ *      MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA
+ *      MBEDTLS_TLS_PSK_WITH_RC4_128_SHA
+ *
+ * \warning   ARC4 is considered a weak cipher and its use constitutes a
+ *            security risk. If possible, we recommend avoidng dependencies on
+ *            it, and considering stronger ciphers instead.
+ *
+ */
+//#define MBEDTLS_ARC4_C
+
+/**
+ * \def MBEDTLS_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module:  library/asn1.c
+ * Caller:  library/x509.c
+ *          library/dhm.c
+ *          library/pkcs12.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ */
+#define MBEDTLS_ASN1_PARSE_C
+
+/**
+ * \def MBEDTLS_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module:  library/asn1write.c
+ * Caller:  library/ecdsa.c
+ *          library/pkwrite.c
+ *          library/x509_create.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ */
+#define MBEDTLS_ASN1_WRITE_C
+
+/**
+ * \def MBEDTLS_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module:  library/base64.c
+ * Caller:  library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define MBEDTLS_BASE64_C
+
+/**
+ * \def MBEDTLS_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module:  library/bignum.c
+ * Caller:  library/dhm.c
+ *          library/ecp.c
+ *          library/ecdsa.c
+ *          library/rsa.c
+ *          library/rsa_internal.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define MBEDTLS_BIGNUM_C
+
+/**
+ * \def MBEDTLS_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module:  library/blowfish.c
+ */
+//#define MBEDTLS_BLOWFISH_C
+
+/**
+ * \def MBEDTLS_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module:  library/camellia.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+//#define MBEDTLS_CAMELLIA_C
+
+/**
+ * \def MBEDTLS_ARIA_C
+ *
+ * Enable the ARIA block cipher.
+ *
+ * Module:  library/aria.c
+ * Caller:  library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256
+ *      MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384
+ */
+//#define MBEDTLS_ARIA_C
+
+/**
+ * \def MBEDTLS_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module:  library/ccm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#define MBEDTLS_CCM_C
+
+/**
+ * \def MBEDTLS_CERTS_C
+ *
+ * Enable the test certificates.
+ *
+ * Module:  library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+//#define MBEDTLS_CERTS_C
+
+/**
+ * \def MBEDTLS_CHACHA20_C
+ *
+ * Enable the ChaCha20 stream cipher.
+ *
+ * Module:  library/chacha20.c
+ */
+#define MBEDTLS_CHACHA20_C
+
+/**
+ * \def MBEDTLS_CHACHAPOLY_C
+ *
+ * Enable the ChaCha20-Poly1305 AEAD algorithm.
+ *
+ * Module:  library/chachapoly.c
+ *
+ * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C
+ */
+#define MBEDTLS_CHACHAPOLY_C
+
+/**
+ * \def MBEDTLS_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module:  library/cipher.c
+ * Caller:  library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define MBEDTLS_CIPHER_C
+
+/**
+ * \def MBEDTLS_CMAC_C
+ *
+ * Enable the CMAC (Cipher-based Message Authentication Code) mode for block
+ * ciphers.
+ *
+ * Module:  library/cmac.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_DES_C
+ *
+ */
+#define MBEDTLS_CMAC_C
+
+/**
+ * \def MBEDTLS_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-based random generator.
+ * The CTR_DRBG generator uses AES-256 by default.
+ * To use AES-128 instead, enable MBEDTLS_CTR_DRBG_USE_128_BIT_KEY below.
+ *
+ * Module:  library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_AES_C
+ *
+ * This module provides the CTR_DRBG AES-256 random number generator.
+ */
+#define MBEDTLS_CTR_DRBG_C
+
+/**
+ * \def MBEDTLS_DEBUG_C
+ *
+ * Enable the debug functions.
+ *
+ * Module:  library/debug.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+//#define MBEDTLS_DEBUG_C
+
+/**
+ * \def MBEDTLS_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module:  library/des.c
+ * Caller:  library/pem.c
+ *          library/cipher.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ *      MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ *      MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ *
+ * \warning   DES is considered a weak cipher and its use constitutes a
+ *            security risk. We recommend considering stronger ciphers instead.
+ */
+//#define MBEDTLS_DES_C
+
+/**
+ * \def MBEDTLS_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module:  library/dhm.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      DHE-RSA, DHE-PSK
+ *
+ * \warning    Using DHE constitutes a security risk as it
+ *             is not possible to validate custom DH parameters.
+ *             If possible, it is recommended users should consider
+ *             preferring other methods of key exchange.
+ *             See dhm.h for more details.
+ *
+ */
+#define MBEDTLS_DHM_C
+
+/**
+ * \def MBEDTLS_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module:  library/ecdh.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: MBEDTLS_ECP_C
+ */
+#define MBEDTLS_ECDH_C
+
+/**
+ * \def MBEDTLS_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module:  library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECDHE-ECDSA
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C
+ */
+#define MBEDTLS_ECDSA_C
+
+/**
+ * \def MBEDTLS_ECJPAKE_C
+ *
+ * Enable the elliptic curve J-PAKE library.
+ *
+ * \warning This is currently experimental. EC J-PAKE support is based on the
+ * Thread v1.0.0 specification; incompatible changes to the specification
+ * might still happen. For this reason, this is disabled by default.
+ *
+ * Module:  library/ecjpake.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ *      ECJPAKE
+ *
+ * Requires: MBEDTLS_ECP_C, MBEDTLS_MD_C
+ */
+//#define MBEDTLS_ECJPAKE_C
+
+/**
+ * \def MBEDTLS_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module:  library/ecp.c
+ * Caller:  library/ecdh.c
+ *          library/ecdsa.c
+ *          library/ecjpake.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED
+ */
+#define MBEDTLS_ECP_C
+
+/**
+ * \def MBEDTLS_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module:  library/entropy.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define MBEDTLS_ENTROPY_C
+
+/**
+ * \def MBEDTLS_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module:  library/error.c
+ * Caller:
+ *
+ * This module enables mbedtls_strerror().
+ */
+//#define MBEDTLS_ERROR_C
+
+/**
+ * \def MBEDTLS_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module:  library/gcm.c
+ *
+ * Requires: MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define MBEDTLS_GCM_C
+
+/**
+ * \def MBEDTLS_HAVEGE_C
+ *
+ * Enable the HAVEGE random generator.
+ *
+ * Warning: the HAVEGE random generator is not suitable for virtualized
+ *          environments
+ *
+ * Warning: the HAVEGE random generator is dependent on timing and specific
+ *          processor traits. It is therefore not advised to use HAVEGE as
+ *          your applications primary random generator or primary entropy pool
+ *          input. As a secondary input to your entropy pool, it IS able add
+ *          the (limited) extra entropy it provides.
+ *
+ * Module:  library/havege.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_TIMING_C
+ *
+ * Uncomment to enable the HAVEGE random generator.
+ */
+//#define MBEDTLS_HAVEGE_C
+
+/**
+ * \def MBEDTLS_HKDF_C
+ *
+ * Enable the HKDF algorithm (RFC 5869).
+ *
+ * Module:  library/hkdf.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the Hashed Message Authentication Code
+ * (HMAC)-based key derivation function (HKDF).
+ */
+#define MBEDTLS_HKDF_C
+
+/**
+ * \def MBEDTLS_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module:  library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define MBEDTLS_HMAC_DRBG_C
+
+/**
+ * \def MBEDTLS_NIST_KW_C
+ *
+ * Enable the Key Wrapping mode for 128-bit block ciphers,
+ * as defined in NIST SP 800-38F. Only KW and KWP modes
+ * are supported. At the moment, only AES is approved by NIST.
+ *
+ * Module:  library/nist_kw.c
+ *
+ * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C
+ */
+#define MBEDTLS_NIST_KW_C
+
+/**
+ * \def MBEDTLS_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module:  library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define MBEDTLS_MD_C
+
+/**
+ * \def MBEDTLS_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module:  library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+ * \warning   MD2 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD2_C
+
+/**
+ * \def MBEDTLS_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module:  library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+ * \warning   MD4 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD4_C
+
+/**
+ * \def MBEDTLS_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module:  library/md5.c
+ * Caller:  library/md.c
+ *          library/pem.c
+ *          library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, and for TLS 1.2
+ * depending on the handshake parameters. Further, it is used for checking
+ * MD5-signed certificates, and for PBKDF1 when decrypting PEM-encoded
+ * encrypted keys.
+ *
+ * \warning   MD5 is considered a weak message digest and its use constitutes a
+ *            security risk. If possible, we recommend avoiding dependencies on
+ *            it, and considering stronger message digests instead.
+ *
+ */
+//#define MBEDTLS_MD5_C
+
+/**
+ * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces calloc() and free()
+ * calls)
+ *
+ * Module:  library/memory_buffer_alloc.c
+ *
+ * Requires: MBEDTLS_PLATFORM_C
+ *           MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def MBEDTLS_NET_C
+ *
+ * Enable the TCP and UDP over IPv6/IPv4 networking routines.
+ *
+ * \note This module only works on POSIX/Unix (including Linux, BSD and OS X)
+ * and Windows. For other platforms, you'll want to disable it, and write your
+ * own networking callbacks to be passed to \c mbedtls_ssl_set_bio().
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/net_sockets.c
+ *
+ * This module provides networking routines.
+ */
+//#define MBEDTLS_NET_C
+
+/**
+ * \def MBEDTLS_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module:  library/oid.c
+ * Caller:  library/asn1write.c
+ *          library/pkcs5.c
+ *          library/pkparse.c
+ *          library/pkwrite.c
+ *          library/rsa.c
+ *          library/x509.c
+ *          library/x509_create.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#define MBEDTLS_OID_C
+
+/**
+ * \def MBEDTLS_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module:  library/padlock.c
+ * Caller:  library/aes.c
+ *
+ * Requires: MBEDTLS_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+//#define MBEDTLS_PADLOCK_C
+
+/**
+ * \def MBEDTLS_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/dhm.c
+ *          library/pkparse.c
+ *          library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+#define MBEDTLS_PEM_PARSE_C
+
+/**
+ * \def MBEDTLS_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module:  library/pem.c
+ * Caller:  library/pkwrite.c
+ *          library/x509write_crt.c
+ *          library/x509write_csr.c
+ *
+ * Requires: MBEDTLS_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+#define MBEDTLS_PEM_WRITE_C
+
+/**
+ * \def MBEDTLS_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module:  library/pk.c
+ * Caller:  library/ssl_tls.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_RSA_C or MBEDTLS_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#define MBEDTLS_PK_C
+
+/**
+ * \def MBEDTLS_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module:  library/pkparse.c
+ * Caller:  library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#define MBEDTLS_PK_PARSE_C
+
+/**
+ * \def MBEDTLS_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module:  library/pkwrite.c
+ * Caller:  library/x509write.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#define MBEDTLS_PK_WRITE_C
+
+/**
+ * \def MBEDTLS_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module:  library/pkcs5.c
+ *
+ * Requires: MBEDTLS_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+#define MBEDTLS_PKCS5_C
+
+/**
+ * \def MBEDTLS_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support.
+ *
+ * Module:  library/pkcs11.c
+ * Caller:  library/pk.c
+ *
+ * Requires: MBEDTLS_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define MBEDTLS_PKCS11_C
+
+/**
+ * \def MBEDTLS_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module:  library/pkcs12.c
+ * Caller:  library/pkparse.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ * Can use:  MBEDTLS_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+//#define MBEDTLS_PKCS12_C
+
+/**
+ * \def MBEDTLS_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit().
+ *
+ * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT
+ * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned
+ * above to be specified at runtime or compile time respectively.
+ *
+ * \note This abstraction layer must be enabled on Windows (including MSYS2)
+ * as other module rely on it for a fixed snprintf implementation.
+ *
+ * Module:  library/platform.c
+ * Caller:  Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+#define MBEDTLS_PLATFORM_C
+
+/**
+ * \def MBEDTLS_POLY1305_C
+ *
+ * Enable the Poly1305 MAC algorithm.
+ *
+ * Module:  library/poly1305.c
+ * Caller:  library/chachapoly.c
+ */
+#define MBEDTLS_POLY1305_C
+
+/**
+ * \def MBEDTLS_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module:  library/ripemd160.c
+ * Caller:  library/md.c
+ *
+ */
+//#define MBEDTLS_RIPEMD160_C
+
+/**
+ * \def MBEDTLS_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module:  library/rsa.c
+ *          library/rsa_internal.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ *      RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C
+ */
+#define MBEDTLS_RSA_C
+
+/**
+ * \def MBEDTLS_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module:  library/sha1.c
+ * Caller:  library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *          library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS up to version 1.1, for TLS 1.2
+ * depending on the handshake parameters, and for SHA1-signed certificates.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_SHA1_C
+
+/**
+ * \def MBEDTLS_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ *
+ * Module:  library/sha256.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define MBEDTLS_SHA256_C
+
+/**
+ * \def MBEDTLS_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ *
+ * Module:  library/sha512.c
+ * Caller:  library/entropy.c
+ *          library/md.c
+ *          library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define MBEDTLS_SHA512_C
+
+/**
+ * \def MBEDTLS_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module:  library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_CACHE_C
+ */
+//#define MBEDTLS_SSL_CACHE_C
+
+/**
+ * \def MBEDTLS_SSL_COOKIE_C
+ *
+ * Enable basic implementation of DTLS cookies for hello verification.
+ *
+ * Module:  library/ssl_cookie.c
+ * Caller:
+ */
+//#define MBEDTLS_SSL_COOKIE_C
+
+/**
+ * \def MBEDTLS_SSL_TICKET_C
+ *
+ * Enable an implementation of TLS server-side callbacks for session tickets.
+ *
+ * Module:  library/ssl_ticket.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_CIPHER_C
+ */
+//#define MBEDTLS_SSL_TICKET_C
+
+/**
+ * \def MBEDTLS_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module:  library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+//#define MBEDTLS_SSL_CLI_C
+
+/**
+ * \def MBEDTLS_SSL_SRV_C
+ *
+ * Enable the SSL/TLS server code.
+ *
+ * Module:  library/ssl_srv.c
+ * Caller:
+ *
+ * Requires: MBEDTLS_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS server support.
+ */
+//#define MBEDTLS_SSL_SRV_C
+
+/**
+ * \def MBEDTLS_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module:  library/ssl_tls.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *
+ * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C
+ *           and at least one of the MBEDTLS_SSL_PROTO_XXX defines
+ *
+ * This module is required for SSL/TLS.
+ */
+//#define MBEDTLS_SSL_TLS_C
+
+/**
+ * \def MBEDTLS_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default mbed TLS assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions. See also our Knowledge Base article about threading:
+ * https://tls.mbed.org/kb/development/thread-safety-and-multi-threading
+ *
+ * Module:  library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either MBEDTLS_THREADING_ALT or
+ * MBEDTLS_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within mbed TLS
+ */
+#define MBEDTLS_THREADING_C
+
+/**
+ * \def MBEDTLS_TIMING_C
+ *
+ * Enable the semi-portable timing interface.
+ *
+ * \note The provided implementation only works on POSIX/Unix (including Linux,
+ * BSD and OS X) and Windows. On other platforms, you can either disable that
+ * module and provide your own implementations of the callbacks needed by
+ * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide
+ * your own implementation of the whole module by setting
+ * \c MBEDTLS_TIMING_ALT in the current file.
+ *
+ * \note See also our Knowledge Base article about porting to a new
+ * environment:
+ * https://tls.mbed.org/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS
+ *
+ * Module:  library/timing.c
+ * Caller:  library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+#define MBEDTLS_TIMING_C
+
+/**
+ * \def MBEDTLS_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module:  library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define MBEDTLS_VERSION_C
+
+/**
+ * \def MBEDTLS_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module:  library/x509.c
+ * Caller:  library/x509_crl.c
+ *          library/x509_crt.c
+ *          library/x509_csr.c
+ *
+ * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C,
+ *           MBEDTLS_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+//#define MBEDTLS_X509_USE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module:  library/x509_crt.c
+ * Caller:  library/ssl_cli.c
+ *          library/ssl_srv.c
+ *          library/ssl_tls.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+//#define MBEDTLS_X509_CRT_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module:  library/x509_crl.c
+ * Caller:  library/x509_crt.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+//#define MBEDTLS_X509_CRL_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module:  library/x509_csr.c
+ * Caller:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+//#define MBEDTLS_X509_CSR_PARSE_C
+
+/**
+ * \def MBEDTLS_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module:  library/x509_create.c
+ *
+ * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+//#define MBEDTLS_X509_CREATE_C
+
+/**
+ * \def MBEDTLS_X509_CRT_WRITE_C
+ *
+ * Enable creating X.509 certificates.
+ *
+ * Module:  library/x509_crt_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate creation.
+ */
+//#define MBEDTLS_X509_CRT_WRITE_C
+
+/**
+ * \def MBEDTLS_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module:  library/x509_csr_write.c
+ *
+ * Requires: MBEDTLS_X509_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+//#define MBEDTLS_X509_CSR_WRITE_C
+
+/**
+ * \def MBEDTLS_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module:  library/xtea.c
+ * Caller:
+ */
+//#define MBEDTLS_XTEA_C
+
+/* \} name SECTION: mbed TLS modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define MBEDTLS_MPI_WINDOW_SIZE            6 /**< Maximum windows size used. */
+//#define MBEDTLS_MPI_MAX_SIZE            1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN               48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+/*!  Maximal reseed counter - indicates maximal number of
+requests allowed between reseeds; according to NIST 800-90
+it is (2^48 - 1), our restriction is :  (int - 0xFFFF - 0xF).*/
+#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL            0xFFF0 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_CTR_DRBG_MAX_INPUT                256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_CTR_DRBG_MAX_REQUEST             1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT           384 /**< Maximum size of (re)seed buffer */
+//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY              /**< Use 128-bit key for CTR_DRBG - may reduce security (see ctr_drbg.h) */
+
+/* HMAC_DRBG options */
+//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL   10000 /**< Interval before reseed is performed by default */
+//#define MBEDTLS_HMAC_DRBG_MAX_INPUT           256 /**< Maximum number of additional input bytes */
+//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST        1024 /**< Maximum number of requested bytes per call */
+//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT      384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define MBEDTLS_ECP_MAX_BITS             521 /**< Maximum bit size of groups */
+//#define MBEDTLS_ECP_WINDOW_SIZE            6 /**< Maximum window size used */
+//#define MBEDTLS_ECP_FIXED_POINT_OPTIM      1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define MBEDTLS_ENTROPY_MAX_SOURCES                20 /**< Maximum number of sources supported */
+#define MBEDTLS_ENTROPY_MAX_GATHER                144 /**< Maximum amount requested from entropy sources */
+//#define MBEDTLS_ENTROPY_MIN_HARDWARE               32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */
+
+/* Memory buffer allocator options */
+//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE      4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define MBEDTLS_PLATFORM_STD_MEM_HDR   <stdlib.h> /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define MBEDTLS_PLATFORM_STD_CALLOC        calloc /**< Default allocator to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_FREE            free /**< Default free to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT            exit /**< Default exit to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_TIME            time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_STD_FPRINTF      fprintf /**< Default fprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_PRINTF        printf /**< Default printf to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_STD_SNPRINTF    snprintf /**< Default snprintf to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS       0 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE       1 /**< Default exit value to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE  "seedfile" /**< Seed file to read/write with default implementation */
+
+/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */
+/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */
+//#define MBEDTLS_PLATFORM_CALLOC_MACRO        calloc /**< Default allocator macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_FREE_MACRO            free /**< Default free macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_EXIT_MACRO            exit /**< Default exit macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_TIME_MACRO            time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO       time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */
+//#define MBEDTLS_PLATFORM_FPRINTF_MACRO      fprintf /**< Default fprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_PRINTF_MACRO        printf /**< Default printf macro to use, can be undefined */
+/* Note: your snprintf must correclty zero-terminate the buffer! */
+//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO    snprintf /**< Default snprintf macro to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO   mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */
+//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO  mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */
+
+/**
+ * \brief       This macro is invoked by the library when an invalid parameter
+ *              is detected that is only checked with MBEDTLS_CHECK_PARAMS
+ *              (see the documentation of that option for context).
+ *
+ *              When you leave this undefined here, a default definition is
+ *              provided that invokes the function mbedtls_param_failed(),
+ *              which is declared in platform_util.h for the benefit of the
+ *              library, but that you need to define in your application.
+ *
+ *              When you define this here, this replaces the default
+ *              definition in platform_util.h (which no longer declares the
+ *              function mbedtls_param_failed()) and it is your responsibility
+ *              to make sure this macro expands to something suitable (in
+ *              particular, that all the necessary declarations are visible
+ *              from within the library - you can ensure that by providing
+ *              them in this file next to the macro definition).
+ *
+ *              Note that you may define this macro to expand to nothing, in
+ *              which case you don't have to worry about declarations or
+ *              definitions. However, you will then be notified about invalid
+ *              parameters only in non-void functions, and void function will
+ *              just silently return early on invalid parameters, which
+ *              partially negates the benefits of enabling
+ *              #MBEDTLS_CHECK_PARAMS in the first place, so is discouraged.
+ *
+ * \param cond  The expression that should evaluate to true, but doesn't.
+ */
+//#define MBEDTLS_PARAM_FAILED( cond )               assert( cond )
+
+/* SSL Cache options */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT       86400 /**< 1 day  */
+//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES      50 /**< Maximum entries in cache */
+
+/* SSL options */
+
+/** \def MBEDTLS_SSL_MAX_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming and outgoing plaintext fragments.
+ *
+ * This determines the size of both the incoming and outgoing TLS I/O buffers
+ * in such a way that both are capable of holding the specified amount of
+ * plaintext data, regardless of the protection mechanism used.
+ *
+ * To configure incoming and outgoing I/O buffers separately, use
+ * #MBEDTLS_SSL_IN_CONTENT_LEN and #MBEDTLS_SSL_OUT_CONTENT_LEN,
+ * which overwrite the value set by this option.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of both
+ * incoming and outgoing I/O buffers.
+ */
+//#define MBEDTLS_SSL_MAX_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_IN_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of incoming plaintext fragments.
+ *
+ * This determines the size of the incoming TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option is undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * \note When using a value less than the default of 16KB on the client, it is
+ *       recommended to use the Maximum Fragment Length (MFL) extension to
+ *       inform the server about this limitation. On the server, there
+ *       is no supported, standardized way of informing the client about
+ *       restriction on the maximum size of incoming messages, and unless
+ *       the limitation has been communicated by other means, it is recommended
+ *       to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN
+ *       while keeping the default value of 16KB for the incoming buffer.
+ *
+ * Uncomment to set the maximum plaintext size of the incoming I/O buffer
+ * independently of the outgoing I/O buffer.
+ */
+//#define MBEDTLS_SSL_IN_CONTENT_LEN              16384
+
+/** \def MBEDTLS_SSL_OUT_CONTENT_LEN
+ *
+ * Maximum length (in bytes) of outgoing plaintext fragments.
+ *
+ * This determines the size of the outgoing TLS I/O buffer in such a way
+ * that it is capable of holding the specified amount of plaintext data,
+ * regardless of the protection mechanism used.
+ *
+ * If this option undefined, it inherits its value from
+ * #MBEDTLS_SSL_MAX_CONTENT_LEN.
+ *
+ * It is possible to save RAM by setting a smaller outward buffer, while keeping
+ * the default inward 16384 byte buffer to conform to the TLS specification.
+ *
+ * The minimum required outward buffer size is determined by the handshake
+ * protocol's usage. Handshaking will fail if the outward buffer is too small.
+ * The specific size requirement depends on the configured ciphers and any
+ * certificate data which is sent during the handshake.
+ *
+ * Uncomment to set the maximum plaintext size of the outgoing I/O buffer
+ * independently of the incoming I/O buffer.
+ */
+//#define MBEDTLS_SSL_OUT_CONTENT_LEN             16384
+
+/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING
+ *
+ * Maximum number of heap-allocated bytes for the purpose of
+ * DTLS handshake message reassembly and future message buffering.
+ *
+ * This should be at least 9/8 * MBEDTLSSL_IN_CONTENT_LEN
+ * to account for a reassembled handshake message of maximum size,
+ * together with its reassembly bitmap.
+ *
+ * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default)
+ * should be sufficient for all practical situations as it allows
+ * to reassembly a large handshake message (such as a certificate)
+ * while buffering multiple smaller handshake messages.
+ *
+ */
+//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING             32768
+
+//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME     86400 /**< Lifetime of session tickets (if enabled) */
+//#define MBEDTLS_PSK_MAX_LEN               32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
+//#define MBEDTLS_SSL_COOKIE_TIMEOUT        60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+/* X509 options */
+//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA   8   /**< Maximum number of intermediate CAs in a verification chain. */
+//#define MBEDTLS_X509_MAX_FILE_PATH_LEN     512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */
+
+/**
+ * Allow SHA-1 in the default TLS configuration for certificate signing.
+ * Without this build-time option, SHA-1 support must be activated explicitly
+ * through mbedtls_ssl_conf_cert_profile. Turning on this option is not
+ * recommended because of it is possible to generate SHA-1 collisions, however
+ * this may be safe for legacy infrastructure where additional controls apply.
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+// #define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_CERTIFICATES
+
+/**
+ * Allow SHA-1 in the default TLS configuration for TLS 1.2 handshake
+ * signature and ciphersuite selection. Without this build-time option, SHA-1
+ * support must be activated explicitly through mbedtls_ssl_conf_sig_hashes.
+ * The use of SHA-1 in TLS <= 1.1 and in HMAC-SHA-1 is always allowed by
+ * default. At the time of writing, there is no practical attack on the use
+ * of SHA-1 in handshake signatures, hence this option is turned on by default
+ * to preserve compatibility with existing peers, but the general
+ * warning applies nonetheless:
+ *
+ * \warning   SHA-1 is considered a weak message digest and its use constitutes
+ *            a security risk. If possible, we recommend avoiding dependencies
+ *            on it, and considering stronger message digests instead.
+ *
+ */
+#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE
+
+/**
+ * Uncomment the macro to let mbed TLS use your alternate implementation of
+ * mbedtls_platform_zeroize(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * mbedtls_platform_zeroize() is a widely used function across the library to
+ * zero a block of memory. The implementation is expected to be secure in the
+ * sense that it has been written to prevent the compiler from removing calls
+ * to mbedtls_platform_zeroize() as part of redundant code elimination
+ * optimizations. However, it is difficult to guarantee that calls to
+ * mbedtls_platform_zeroize() will not be optimized by the compiler as older
+ * versions of the C language standards do not provide a secure implementation
+ * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to
+ * configure their own implementation of mbedtls_platform_zeroize(), for
+ * example by using directives specific to their compiler, features from newer
+ * C standards (e.g using memset_s() in C11) or calling a secure memset() from
+ * their system (e.g explicit_bzero() in BSD).
+ */
+//#define MBEDTLS_PLATFORM_ZEROIZE_ALT
+
+/**
+ * Uncomment the macro to let Mbed TLS use your alternate implementation of
+ * mbedtls_platform_gmtime_r(). This replaces the default implementation in
+ * platform_util.c.
+ *
+ * gmtime() is not a thread-safe function as defined in the C standard. The
+ * library will try to use safer implementations of this function, such as
+ * gmtime_r() when available. However, if Mbed TLS cannot identify the target
+ * system, the implementation of mbedtls_platform_gmtime_r() will default to
+ * using the standard gmtime(). In this case, calls from the library to
+ * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex
+ * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the
+ * library are also guarded with this mutex to avoid race conditions. However,
+ * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will
+ * unconditionally use the implementation for mbedtls_platform_gmtime_r()
+ * supplied at compile time.
+ */
+//#define MBEDTLS_PLATFORM_GMTIME_R_ALT
+
+/* \} name SECTION: Customisation configuration options */
+
+/* Target and application specific configurations */
+//#define YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE "mbedtls/target_config.h"
+
+#if defined(TARGET_LIKE_MBED) && defined(YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_TARGET_CONFIG_FILE
+#endif
+
+/*
+ * Allow user to override any previous default.
+ *
+ * Use two macro names for that, as:
+ * - with yotta the prefix YOTTA_CFG_ is forced
+ * - without yotta is looks weird to have a YOTTA prefix.
+ */
+#if defined(YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE)
+#include YOTTA_CFG_MBEDTLS_USER_CONFIG_FILE
+#elif defined(MBEDTLS_USER_CONFIG_FILE)
+#include MBEDTLS_USER_CONFIG_FILE
+#endif
+
+#include "mbedtls/check_config.h"
+
+#endif /* MBEDTLS_CONFIG_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/dhm_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/dhm_alt.h
new file mode 100644
index 0000000..9a0382d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/dhm_alt.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_DHM_ALT_H
+#define MBEDTLS_DHM_ALT_H
+
+
+#if defined(MBEDTLS_DHM_ALT)
+
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include <stddef.h>
+
+/*
+ * DHM Error codes
+ */
+#define MBEDTLS_ERR_DHM_BAD_INPUT_DATA                    -0x3080  /**< Bad input parameters. */
+#define MBEDTLS_ERR_DHM_READ_PARAMS_FAILED                -0x3100  /**< Reading of the DHM parameters failed. */
+#define MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED                -0x3180  /**< Making of the DHM parameters failed. */
+#define MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED                -0x3200  /**< Reading of the public values failed. */
+#define MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED                -0x3280  /**< Making of the public value failed. */
+#define MBEDTLS_ERR_DHM_CALC_SECRET_FAILED                -0x3300  /**< Calculation of the DHM secret failed. */
+#define MBEDTLS_ERR_DHM_INVALID_FORMAT                    -0x3380  /**< The ASN.1 data is not formatted correctly. */
+#define MBEDTLS_ERR_DHM_ALLOC_FAILED                      -0x3400  /**< Allocation of memory failed. */
+#define MBEDTLS_ERR_DHM_FILE_IO_ERROR                     -0x3480  /**< Read or write of file failed. */
+#define MBEDTLS_ERR_DHM_HW_ACCEL_FAILED                   -0x3500  /**< DHM hardware accelerator failed. */
+#define MBEDTLS_ERR_DHM_SET_GROUP_FAILED                  -0x3580  /**< Setting the modulus and generator failed. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          The DHM context structure.
+ */
+typedef struct
+{
+    size_t len;         /*!<  The size of \p P in Bytes. */
+    mbedtls_mpi P;      /*!<  The prime modulus. */
+    mbedtls_mpi G;      /*!<  The generator. */
+    mbedtls_mpi X;      /*!<  Our secret value. */
+    mbedtls_mpi GX;     /*!<  Our public key = \c G^X mod \c P. */
+    mbedtls_mpi GY;     /*!<  The public key of the peer = \c G^Y mod \c P. */
+    mbedtls_mpi K;      /*!<  The shared secret = \c G^(XY) mod \c P. */
+    mbedtls_mpi RP;     /*!<  The cached value = \c R^2 mod \c P. */
+    mbedtls_mpi Vi;     /*!<  The blinding value. */
+    mbedtls_mpi Vf;     /*!<  The unblinding value. */
+    mbedtls_mpi pX;     /*!<  The previous \c X. */
+}
+mbedtls_dhm_context;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* MBEDTLS_DHM_ALT  - use alternative code */
+#endif  /* MBEDTLS_DHM_ALT_H  - include only once  */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/gcm_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/gcm_alt.h
new file mode 100644
index 0000000..239a714
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/gcm_alt.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_GCM_ALT_H
+#define MBEDTLS_GCM_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined(MBEDTLS_GCM_C)
+
+#include <stddef.h>
+#include <stdint.h>
+#include "mbedtls/cipher.h"
+
+#define MBEDTLS_GCM_ENCRYPT     1
+#define MBEDTLS_GCM_DECRYPT     0
+
+#define MBEDTLS_ERR_GCM_AUTH_FAILED             -0x0012  /**< Authenticated decryption failed. */
+#define MBEDTLS_ERR_GCM_BAD_INPUT               -0x0014  /**< Bad input parameters to function. */
+
+/* hide internal implementation of the struct. Allocate enough space for it.*/
+#define MBEDTLS_GCM_CONTEXT_SIZE_IN_WORDS   40
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          GCM context structure
+ */
+typedef struct {
+    uint32_t buf[MBEDTLS_GCM_CONTEXT_SIZE_IN_WORDS];
+}
+mbedtls_gcm_context;
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* MBEDTLS_GCM_C */
+#endif /* MBEDTLS_GCM_ALT_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/poly1305_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/poly1305_alt.h
new file mode 100644
index 0000000..e70ce59
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/poly1305_alt.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _MBEDTLS_POLY1305_ALT_H
+#define _MBEDTLS_POLY1305_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if defined(MBEDTLS_POLY1305_ALT)
+
+/************************ defines  ****************************/
+/*! The size of the POLY key in words. */
+#define MBEDTLS_POLY_KEY_SIZE_WORDS       8
+
+/*! The size of the POLY key in bytes. */
+#define MBEDTLS_POLY_KEY_SIZE_BYTES       32
+
+/*! The size of the POLY MAC in words. */
+#define MBEDTLS_POLY_MAC_SIZE_WORDS       4
+
+/*! The size of the POLY MAC in bytes. */
+#define MBEDTLS_POLY_MAC_SIZE_BYTES       16
+
+/************************ Typedefs  ****************************/
+/*! The definition of the ChaCha-MAC buffer. */
+typedef uint32_t mbedtls_poly_mac[MBEDTLS_POLY_MAC_SIZE_WORDS];
+
+/*! The definition of the ChaCha-key buffer. */
+typedef uint32_t mbedtls_poly_key[MBEDTLS_POLY_KEY_SIZE_WORDS];
+
+typedef struct mbedtls_poly1305_context
+{
+    uint32_t r[4];      /** The value for 'r' (low 128 bits of the key). */
+    uint32_t s[4];      /** The value for 's' (high 128 bits of the key). */
+    uint32_t acc[5];    /** The accumulator number. */
+    uint8_t queue[16];  /** The current partial block of data. */
+    size_t queue_len;   /** The number of bytes stored in 'queue'. */
+}
+mbedtls_poly1305_context;
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* poly1305_alt.h */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/rsa_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/rsa_alt.h
new file mode 100644
index 0000000..2eef069
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/rsa_alt.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_RSA_ALT_H
+#define MBEDTLS_RSA_ALT_H
+
+#if defined(MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#if defined (MBEDTLS_RSA_ALT)
+
+// Regular implementation
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief   The RSA context structure.
+ *
+ * \note    Direct manipulation of the members of this structure
+ *          is deprecated. All manipulation should instead be done through
+ *          the public interface functions.
+ */
+typedef struct
+{
+    int ver;                    /*!<  always 0          */
+    size_t len;                 /*!<  size(N) in chars  */
+
+    mbedtls_mpi N;                      /*!<  public modulus    */
+    mbedtls_mpi E;                      /*!<  public exponent   */
+
+    mbedtls_mpi D;                      /*!<  private exponent  */
+    mbedtls_mpi P;                      /*!<  1st prime factor  */
+    mbedtls_mpi Q;                      /*!<  2nd prime factor  */
+
+    mbedtls_mpi DP;                     /*!<  D % (P - 1)       */
+    mbedtls_mpi DQ;                     /*!<  D % (Q - 1)       */
+    mbedtls_mpi QP;                     /*!<  1 / (Q % P)       */
+
+    mbedtls_mpi RN;                     /*!<  cached R^2 mod N  */
+
+    mbedtls_mpi RP;                     /*!<  cached R^2 mod P  */
+    mbedtls_mpi RQ;                     /*!<  cached R^2 mod Q  */
+
+    mbedtls_mpi Vi;                     /*!<  cached blinding value     */
+    mbedtls_mpi Vf;                     /*!<  cached un-blinding value  */
+
+    mbedtls_mpi NP;                     /*!< Barrett mod N tag NP for N-modulus */
+    mbedtls_mpi BQP;                    /*!< Barrett mod Q tag QP for Q-factor  */
+    mbedtls_mpi BPP;                    /*!< Barrett mod P tag PP for P-factor  */
+
+    int padding;                /*!<  MBEDTLS_RSA_PKCS_V15 for 1.5 padding and
+                                      MBEDTLS_RSA_PKCS_v21 for OAEP/PSS         */
+    int hash_id;                /*!<  Hash identifier of mbedtls_md_type_t as
+                                      specified in the mbedtls_md.h header file
+                                      for the EME-OAEP and EMSA-PSS
+                                      encoding                          */
+#if defined(MBEDTLS_THREADING_C)
+    mbedtls_threading_mutex_t mutex;    /*!<  Thread-safety mutex       */
+#endif
+}
+mbedtls_rsa_context;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  MBEDTLS_RSA_ALT  */
+
+#endif /*  MBEDTLS_RSA_ALT_H  */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/sha1_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/sha1_alt.h
new file mode 100644
index 0000000..62b8694
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/sha1_alt.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_SHA1_ALT_H
+#define MBEDTLS_SHA1_ALT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "cc_hash_defs_proj.h"
+#if defined (MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#define MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED                  -0x0035  /**< SHA-1 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          SHA-1 context structure
+ */
+typedef struct mbedtls_sha1_context {
+        /*! Internal buffer */
+        uint32_t buff[CC_HASH_USER_CTX_SIZE_IN_WORDS]; // defined in cc_hash_defs_proj.h
+} mbedtls_sha1_context;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_SHA1_ALT_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/sha256_alt.h b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/sha256_alt.h
new file mode 100644
index 0000000..20d08d4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/mbedtls/sha256_alt.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_SHA256_ALT_H
+#define MBEDTLS_SHA256_ALT_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "cc_hash_defs_proj.h"
+#if defined (MBEDTLS_CONFIG_FILE)
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+
+#define MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED                -0x0037  /**< SHA-256 hardware accelerator failed */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief          SHA-256 context structure
+ */
+typedef struct mbedtls_sha256_context {
+        /*! Internal buffer */
+        uint32_t buff[CC_HASH_USER_CTX_SIZE_IN_WORDS]; // defined in cc_hash_defs.h
+} mbedtls_sha256_context;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_SHA256_ALT_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_log_mask.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_log_mask.h
new file mode 100644
index 0000000..234ebd9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_log_mask.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_LOG_MASK_H_
+#define _CC_LOG_MASK_H_
+
+#define CC_LOG_MASK_CCLIB                   (1<<1)
+#define CC_LOG_MASK_SECURE_BOOT             (1<<2)
+#define CC_LOG_MASK_CMPU                    (1<<3)
+#define CC_LOG_MASK_DMPU                    (1<<4)
+#define CC_LOG_MASK_CC_API                  (1<<5)
+#define CC_LOG_MASK_CC_SYM_DRIVER           (1<<6)
+#define CC_LOG_MASK_MLLI                    (1<<7)
+#define CC_LOG_MASK_HW_QUEUE                (1<<8)
+#define CC_LOG_MASK_COMPLETION              (1<<9)
+#define CC_LOG_MASK_INFRA                   (1<<10)
+#define CC_LOG_MASK_LLF                     (1<<13)
+#define CC_LOG_MASK_ASYM_ECC                (1<<14)
+#define CC_LOG_MASK_ASYM_RSA_DH             (1<<15)
+#define CC_LOG_MASK_ASYM_KDF                (1<<16)
+#define CC_LOG_MASK_ASYM_LLF                (1<<17)
+#define CC_LOG_MASK_ASYM_RND                (1<<18)
+#define CC_LOG_MASK_UTILS                   (1<<19)
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_abort.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_abort.h
new file mode 100644
index 0000000..a46d034
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_abort.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+ /*!
+ @addtogroup cc_pal_abort
+ @{
+ */
+
+/*!
+ @file
+ @brief This file includes all PAL APIs.
+ */
+
+#ifndef _CC_PAL_ABORT_H
+#define _CC_PAL_ABORT_H
+
+
+#include "cc_pal_abort_plat.h"
+
+
+/*!
+  @brief This function performs the "Abort" operation.
+
+  Must be implemented according to platform and OS.
+*/
+void CC_PalAbort(
+    /*! [in] An optional parameter for a string of chars to indicate the abort
+    operation. */
+    const char * exp
+);
+
+/*!
+ @}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_apbc.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_apbc.h
new file mode 100644
index 0000000..b0b0c7e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_apbc.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_apbc
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the definitions and APIs for APB-C implementation.
+
+ This is a placeholder for platform-specific APB-C implementation.
+*/
+
+#ifndef _CC_PAL_APBC_H
+#define _CC_PAL_APBC_H
+
+/*!
+ @brief This function initiates an atomic counter.
+
+ @return Void.
+ */
+void CC_PalApbcCntrInit(void);
+
+/*!
+ @brief This function returns the number of APB-C access operations.
+
+ @return The value of the atomic counter.
+ */
+int32_t CC_PalApbcCntrValue(void);
+
+/*!
+ @brief This function updates the atomic counter on each call to APB-C access.
+
+ On each call to APB-C access, the counter is increased. At the end of each
+ operation, the counter is decreased.
+
+ @return \c 0 on success.
+ @return A non-zero value on failure.
+ */
+CCError_t CC_PalApbcModeSelect(
+               /*! [in] Determines the APB-C mode: TRUE (APB-C start access).
+               FALSE (APB-C finish access). */
+               CCBool isApbcInc
+               );
+
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_barrier.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_barrier.h
new file mode 100644
index 0000000..014206a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_barrier.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_barrier
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the definitions and APIs for memory-barrier
+ implementation.
+
+ This is a placeholder for platform-specific memory barrier implementation.
+ The secure core driver should include a memory barrier, before and after
+ the last word of the descriptor, to allow correct order between the words
+ and different descriptors.
+ */
+
+
+#ifndef _CC_PAL_BARRIER_H
+#define _CC_PAL_BARRIER_H
+
+
+/*!
+  This macro puts the memory barrier after the write operation.
+
+  @return None
+ */
+
+void CC_PalWmb(void);
+
+/*!
+  This macro puts the memory barrier before the read operation.
+
+  @return None
+ */
+void CC_PalRmb(void);
+
+/*!
+ @}
+*/
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_buff_attr.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_buff_attr.h
new file mode 100644
index 0000000..be590da
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_buff_attr.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _CC_PAL_BUFF_ATTR_H
+#define _CC_PAL_BUFF_ATTR_H
+
+/*!
+@file
+@brief This file contains the definitions and APIs to get inout data buffer attributes.
+       This is a place holder for platform specific inout data attributes functions implementation
+       The module should be updated whether data buffer is secure or non-secure,
+       in order to notify the low level driver how to configure the HW accordigly.
+@defgroup cc_pal_buff_attr CryptoCell PAL Data Buffer Attributes APIs
+@{
+@ingroup cc_pal
+
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+
+/******************************************************************************
+*               Buffer Information
+******************************************************************************/
+
+/*! User buffer attribute (secure / non-secure). */
+#define DATA_BUFFER_IS_NONSECURE    1
+#define DATA_BUFFER_IS_SECURE       0
+/*! Buffer attribute (secure / non-secure) as used by arm_cmse.h . */
+#define CMSE_NONSECURE              0
+#define CMSE_SECURE                 1
+
+/******************************************************************************
+*               Functions
+******************************************************************************/
+
+/**
+ * @brief This function purpose is to verify the buffer's attributes according to address, size, and type (in/out).
+ * The function returns whether the buffer is secure or non-secure.
+ * In any case of invalid memory, the function shall return an error (i.e.mixed regions of secured and non-secure memory).
+ *
+ * @return Zero on success.
+ * @return A non-zero value in case of failure.
+ */
+CCError_t CC_PalDataBufferAttrGet(const unsigned char *pDataBuffer, /*!< [in] Address of data buffer. */
+                                  size_t   buffSize,                /*!< [in] Buffer size in bytes. */
+                                  uint8_t  buffType,                /* ! [in] Input for read / output for write */
+                                  uint8_t  *pBuffNs                 /*!< [out] HNONSEC buffer attribute (0 for secure, 1 for non-secure) */
+                                  );
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_compiler.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_compiler.h
new file mode 100644
index 0000000..6e38712
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_compiler.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_compiler
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains CryptoCell PAL platform-dependent compiler-related
+ definitions.
+ */
+
+
+#ifndef __CC_PAL_COMPILER_H__
+#define __CC_PAL_COMPILER_H__
+
+#ifdef __GNUC__
+
+/* *********************** Defines ******************************/
+
+/*! Associate a symbol with a link section. */
+#define CC_PAL_COMPILER_SECTION(sectionName)  __attribute__((section(sectionName)))
+
+/*! Mark symbol as used, that is, prevent the garbage collector from
+dropping it. */
+#define CC_PAL_COMPILER_KEEP_SYMBOL __attribute__((used))
+
+/*! Align a given data item in bytes. */
+#define CC_PAL_COMPILER_ALIGN(alignement)  __attribute__((aligned(alignement)))
+
+/*! Mark a function that never returns. */
+#define CC_PAL_COMPILER_FUNC_NEVER_RETURNS __attribute__((noreturn))
+
+/*! Prevent a function from being inlined. */
+#define CC_PAL_COMPILER_FUNC_DONT_INLINE __attribute__((noinline))
+
+/*! Given data type might serve as an alias for another data-type pointer. */
+/* (this is used for "superclass" struct casting)             */
+#define CC_PAL_COMPILER_TYPE_MAY_ALIAS __attribute__((__may_alias__))
+
+/*! Get the size of a structure-type member. */
+#define CC_PAL_COMPILER_SIZEOF_STRUCT_MEMBER(type_name, member_name) \
+    sizeof(((type_name *)0)->member_name)
+
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT_(a, b) a##b
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT(a, b) CC_ASSERT_CONCAT_(a, b)
+/*! Definition of assertion. */
+#define CC_PAL_COMPILER_ASSERT(cond, message) \
+    enum { CC_ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(cond)) }
+
+#elif defined(__ARM_DSM__)
+#define inline
+
+/*! Associate a symbol with a link section. */
+#define CC_PAL_COMPILER_SECTION(sectionName)  __attribute__((section(sectionName)))
+
+/*! Mark a symbol as used, that is, prevent garbage collector from
+dropping it. */
+#define CC_PAL_COMPILER_KEEP_SYMBOL __attribute__((used))
+
+/*! Align a given data item in bytes. */
+#define CC_PAL_COMPILER_ALIGN(alignement)  __attribute__((aligned(alignement)))
+
+/*! Mark a function that never returns. */
+#define CC_PAL_COMPILER_FUNC_NEVER_RETURNS __attribute__((noreturn))
+
+/*! Prevent a function from being inlined. */
+#define CC_PAL_COMPILER_FUNC_DONT_INLINE __attribute__((noinline))
+
+/*! Given data type might serve as an alias for another data-type pointer. */
+/* (this is used for "superclass" struct casting)             */
+#define CC_PAL_COMPILER_TYPE_MAY_ALIAS __attribute__((__may_alias__))
+
+/*! Get the size of a structure-type member. */
+#define CC_PAL_COMPILER_SIZEOF_STRUCT_MEMBER(type_name, member_name) \
+    sizeof(((type_name *)0)->member_name)
+
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT_(a, b) a##b
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT(a, b) CC_ASSERT_CONCAT_(a, b)
+/*! Definition of assertion. */
+#define CC_PAL_COMPILER_ASSERT(cond, message) \
+    enum { CC_ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(cond)) }
+
+
+#elif defined(__ARM_DS__)
+#define inline
+
+/*! Associate a symbol with a link section. */
+#define CC_PAL_COMPILER_SECTION(sectionName)  __attribute__((section(sectionName)))
+
+/*! Mark a symbol as used, that is, prevent garbage collector from
+dropping it. */
+#define CC_PAL_COMPILER_KEEP_SYMBOL __attribute__((used))
+
+/*! Align a given data item in bytes. */
+#define CC_PAL_COMPILER_ALIGN(alignement)  __attribute__((aligned(alignement)))
+
+/*! Mark a function that never returns. */
+#define CC_PAL_COMPILER_FUNC_NEVER_RETURNS __attribute__((noreturn))
+
+/*! Prevent a function from being inlined. */
+#define CC_PAL_COMPILER_FUNC_DONT_INLINE __attribute__((noinline))
+
+/*! Given data type might serve as an alias for another data-type pointer. */
+/* (this is used for "superclass" struct casting)             */
+#define CC_PAL_COMPILER_TYPE_MAY_ALIAS
+
+/*! Get the size of a structure-type member. */
+#define CC_PAL_COMPILER_SIZEOF_STRUCT_MEMBER(type_name, member_name) \
+    sizeof(((type_name *)0)->member_name)
+
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT_(a, b) a##b
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT(a, b) CC_ASSERT_CONCAT_(a, b)
+/*! Definition of assertion. */
+#define CC_PAL_COMPILER_ASSERT(cond, message) \
+    enum { CC_ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(cond)) }
+
+
+#elif defined(__ARM_DS5__)
+#define inline __inline
+
+
+/*! Associate a symbol with a link section. */
+#define CC_PAL_COMPILER_SECTION(sectionName)  __attribute__((section(sectionName)))
+
+/*! Mark a symbol as used, that is, prevent garbage collector from
+dropping it. */
+#define CC_PAL_COMPILER_KEEP_SYMBOL __attribute__((used))
+
+/*! Align a given data item in bytes. */
+#define CC_PAL_COMPILER_ALIGN(alignement)  __attribute__((aligned(alignement)))
+
+/*! Mark a function that never returns. */
+#define CC_PAL_COMPILER_FUNC_NEVER_RETURNS __attribute__((noreturn))
+
+/*! Prevent a function from being inlined. */
+#define CC_PAL_COMPILER_FUNC_DONT_INLINE __attribute__((noinline))
+
+/*! Given data type might serve as an alias for another data-type pointer. */
+/* (this is used for "superclass" struct casting)             */
+#define CC_PAL_COMPILER_TYPE_MAY_ALIAS
+
+/*! Get the size of a structure-type member. */
+#define CC_PAL_COMPILER_SIZEOF_STRUCT_MEMBER(type_name, member_name) \
+    sizeof(((type_name *)0)->member_name)
+
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT_(a, b) a##b
+/*! Definition of assertion. */
+#define CC_ASSERT_CONCAT(a, b) CC_ASSERT_CONCAT_(a, b)
+/*! Definition of assertion. */
+#define CC_PAL_COMPILER_ASSERT(cond, message) \
+    enum { CC_ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(cond)) }
+
+#else
+#error Unsupported compiler.
+#endif
+
+/*!
+ @}
+ */
+
+#endif /*__CC_PAL_COMPILER_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_dma.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_dma.h
new file mode 100644
index 0000000..a6979f5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_dma.h
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _CC_PAL_DMA_H
+#define _CC_PAL_DMA_H
+
+/*!
+@file
+@brief This file contains definitions that are used for DMA-related APIs. The implementation of these functions
+need to be replaced according to the platform and OS.
+@defgroup ssi_pal_dma CryptoCell PAL DMA related APIs
+@{
+@ingroup ssi_pal
+
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "cc_pal_dma_plat.h"
+#include "cc_pal_dma_defs.h"
+
+/*! User buffer scatter information. */
+typedef struct {
+    CCDmaAddr_t     blockPhysAddr; /*!< The physical address of the user buffer.*/
+    uint32_t        blockSize;     /*!< The block size of the user buffer.*/
+}CCPalDmaBlockInfo_t;
+
+#ifdef BIG__ENDIAN
+/*! Definition for big to little endian. */
+#define  SET_WORD_LE(val) cpu_to_le32(val)
+#else
+/*! Definition for big to little endian. */
+#define  SET_WORD_LE
+#endif
+
+/**
+ * @brief   This function is called by the CryptoCell runtime library before the HW is used.
+ *      It maps a given data buffer (virtual address) for CryptoCell HW DMA use (physical address), and returns the list of
+ *      one or more DMA-able (physical) blocks. Once it is called,
+ *      only CryptoCell HW access to the buffer is allowed, until it is unmapped.
+ *      \note If the data buffer was already mapped by the secure OS prior to calling the CryptoCell runtime library,
+ *      this API does not have to perform any actual mapping operation, but only return the list of DMA-able blocks.
+ *
+ * @return A non-zero value in case of failure.
+ */
+uint32_t CC_PalDmaBufferMap(
+                uint8_t                      *pDataBuffer,     /*!< [in] The address of the buffer to map. */
+                uint32_t                      buffSize,         /*!< [in] The buffer size in Bytes. */
+                CCPalDmaBufferDirection_t     copyDirection,    /*!< [in] The copy direction of the buffer, according to ::CCPalDmaBufferDirection_t:
+                                              <ul><li>TO_DEVICE - the original buffer is the input to the operation,
+                                              and this function should copy it to the temporary buffer,
+                                              prior to the activating the HW on the temporary buffer.</li>
+                                              <li>FROM_DEVICE - not relevant for this API.</li>
+                                              <li>BI_DIRECTION - used when the cryptographic operation is "in-place", that is,
+                                              the result of encryption or decryption is written over the original data
+                                              at the same address. Should be treated by this API same as
+                                              TO_DEVICE. </li></ul> */
+                 uint32_t                     *pNumOfBlocks,    /*!< [in/out] <ul><li> In - The maximal number of blocks to fill.</li><li>Out - the actual number of blocks.</li></ul> */
+                 CCPalDmaBlockInfo_t          *pDmaBlockList,   /*!< [out] The list of DMA-able blocks that the buffer maps to. */
+                 CC_PalDmaBufferHandle         *dmaBuffHandle   /*!< [out] A handle to the private resources of the mapped buffer.*/ );
+
+
+/**
+ * @brief   This function is called by the CryptoCell runtime library after the HW is used.
+ *      It unmaps a given buffer and frees its associated resources, if needed. It may unlock the buffer and flush it for CPU use.
+ *      Once it is called, CryptoCell HW does not require any further access to this buffer.
+ *      \note If the data buffer was already unmapped by the secure OS prior to calling the CryptoCell runtime library,
+ *      this API does not have to perform any unmapping operation, and the actual unmapping can be done by the secure OS
+ *      outside the context of the CryptoCell runtime library.
+ * @return A non-zero value in case of failure.
+ */
+uint32_t CC_PalDmaBufferUnmap(uint8_t                       *pDataBuffer,   /*!< [in] The address of the buffer to unmap. */
+                  uint32_t                       buffSize,      /*!< [in] The buffer size in Bytes. */
+                  CCPalDmaBufferDirection_t      copyDirection, /*!< [in] The copy direction of the buffer, according to ::CCPalDmaBufferDirection_t:
+                                              <ul><li>TO_DEVICE - not relevant for this API. </li>
+                                              <li>FROM_DEVICE - the temporary buffer holds the output of the HW, and this
+                                              API should copy it to the actual output buffer.</li>
+                                              <li>BI_DIRECTION - used when the cryptographic operation is "in-place", that is,
+                                              the result of encryption or decryption is written over the original data
+                                              at the same address. Should be treated by this API same as
+                                              FROM_DEVICE.</li></ul> */
+                  uint32_t                       numOfBlocks,           /*!< [in] The number of DMA-able blocks that the buffer maps to. */
+                  CCPalDmaBlockInfo_t            *pDmaBlockList,    /*!< [in] The list of DMA-able blocks that the buffer maps to. */
+                  CC_PalDmaBufferHandle          dmaBuffHandle  /*!< [in] A handle to the private resources of the mapped buffer. */);
+
+
+/**
+ * @brief Allocates a DMA-contiguous buffer for CPU use, and returns its virtual address.
+ *  Before passing the buffer to the CryptoCell HW, ::CC_PalDmaBufferMap should be called.
+ *  \note The returned address must be aligned to 32bits.
+ *
+ *
+ * @return A non-zero value in case of failure.
+ */
+uint32_t CC_PalDmaContigBufferAllocate(uint32_t          buffSize, /*!< [in] The buffer size in Bytes.*/
+                       uint8_t           **ppVirtBuffAddr /*!< [out]  The virtual address of the allocated buffer.*/);
+
+
+
+/**
+ * @brief Frees resources previously allocated by ::CC_PalDmaContigBufferAllocate.
+ *
+ *
+ * @return A non-zero value in case of failure.
+ */
+uint32_t CC_PalDmaContigBufferFree(uint32_t          buffSize, /*!< [in] The buffer size in Bytes. */
+                   uint8_t           *pVirtBuffAddr /*!< [in] The virtual address of the buffer to free. */);
+
+
+
+/**
+ * @brief Checks whether the buffer is guaranteed to be a single contiguous DMA block.
+ *
+ *
+ * @return TRUE if the buffer is guaranteed to be a single contiguous DMA block.
+ * @return FALSE otherwise.
+ */
+uint32_t CC_PalIsDmaBufferContiguous(uint8_t                     *pDataBuffer, /*!< [in] The address of the user buffer. */
+                     uint32_t                    buffSize   /*!< [in] The size of the user buffer. */);
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_dma_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_dma_defs.h
new file mode 100644
index 0000000..89cd353
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_dma_defs.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*!
+@file
+@brief This file contains the platform-dependent DMA definitions.
+@defgroup ssi_pal_dma_defs CryptoCell PAL DMA specific definitions
+@{
+@ingroup ssi_pal
+*/
+
+#ifndef _CC_PAL_DMA_DEFS_H
+#define _CC_PAL_DMA_DEFS_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! Definition for DMA buffer handle.*/
+typedef void *CC_PalDmaBufferHandle;
+
+/*! DMA directions configuration. */
+typedef enum {
+    CC_PAL_DMA_DIR_NONE = 0, /*!< No direction. */
+    CC_PAL_DMA_DIR_TO_DEVICE = 1,   /*!< The original buffer is the input to the operation. It should be copied or mapped to the temporary buffer prior to activating the HW on it. */
+    CC_PAL_DMA_DIR_FROM_DEVICE = 2, /*!< The temporary buffer holds the output of the HW. This API should copy or map it to the original output buffer.*/
+    CC_PAL_DMA_DIR_BI_DIRECTION = 3, /*!< The result is written over the original data at the same address. Should be treated as \p CC_PAL_DMA_DIR_TO_DEVICE and \p CC_PAL_DMA_DIR_FROM_DEVICE.*/
+    CC_PAL_DMA_DIR_MAX,      /*!< Maximal DMA direction options. */
+    CC_PAL_DMA_DIR_RESERVE32 = 0x7FFFFFFF  /*!< Reserved.*/
+}CCPalDmaBufferDirection_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_error.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_error.h
new file mode 100644
index 0000000..b3d87df
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_error.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_error
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the error definitions of the platform-dependent PAL APIs.
+ */
+
+
+
+#ifndef _CC_PAL_ERROR_H
+#define _CC_PAL_ERROR_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! The PAL error base.*/
+#define CC_PAL_BASE_ERROR                0x0F000000
+
+/* Memory error returns */
+/*! Buffer one is greater than buffer two error.*/
+#define CC_PAL_MEM_BUF1_GREATER          CC_PAL_BASE_ERROR + 0x01UL
+/*! Buffer two is greater than buffer one error.*/
+#define CC_PAL_MEM_BUF2_GREATER          CC_PAL_BASE_ERROR + 0x02UL
+
+/* Semaphore error returns */
+/*! Semaphore creation failed.*/
+#define CC_PAL_SEM_CREATE_FAILED         CC_PAL_BASE_ERROR + 0x03UL
+/*! Semaphore deletion failed.*/
+#define CC_PAL_SEM_DELETE_FAILED         CC_PAL_BASE_ERROR + 0x04UL
+/*! Semaphore reached timeout.*/
+#define CC_PAL_SEM_WAIT_TIMEOUT          CC_PAL_BASE_ERROR + 0x05UL
+/*! Semaphore wait failed.*/
+#define CC_PAL_SEM_WAIT_FAILED           CC_PAL_BASE_ERROR + 0x06UL
+/*! Semaphore release failed.*/
+#define CC_PAL_SEM_RELEASE_FAILED        CC_PAL_BASE_ERROR + 0x07UL
+/*! Illegal PAL address.*/
+#define CC_PAL_ILLEGAL_ADDRESS       CC_PAL_BASE_ERROR + 0x08UL
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_fips.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_fips.h
new file mode 100644
index 0000000..8f21ac2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_fips.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_PAL_FIPS_H
+#define  _CC_PAL_FIPS_H
+
+/*!
+@file
+@brief This file contains definitions that are used by the FIPS related APIs. The implementation of these functions
+need to be replaced according to the Platform and TEE_OS.
+*/
+
+#include "cc_pal_types_plat.h"
+#include "cc_fips.h"
+#include "cc_fips_defs.h"
+
+/**
+ * @brief This function purpose is to get the FIPS state.
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsGetState(CCFipsState_t *pFipsState);
+
+
+/**
+ * @brief This function purpose is to get the FIPS Error.
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsGetError(CCFipsError_t *pFipsError);
+
+
+/**
+ * @brief This function purpose is to get the FIPS trace.
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsGetTrace(CCFipsTrace_t *pFipsTrace);
+
+
+/**
+ * @brief This function purpose is to set the FIPS state.
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsSetState(CCFipsState_t fipsState);
+
+
+/**
+ * @brief This function purpose is to set the FIPS error.
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsSetError(CCFipsError_t fipsError);
+
+
+/**
+ * @brief This function purpose is to set the FIPS trace.
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsSetTrace(CCFipsTrace_t fipsTrace);
+
+
+/**
+ * @brief This function purpose is to wait for FIPS interrupt.
+ *      After GPR0 (==FIPS) interrupt is detected, clear the interrupt in ICR,
+ *      and call CC_FipsIrqHandle
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsWaitForReeStatus(void);
+
+/**
+ * @brief This function purpose is to stop waiting for REE FIPS interrupt.
+ *      since TEE lib is terminating
+ *
+ *
+ * @return Zero on success.
+ * @return A non-zero value on failure.
+ */
+CCError_t CC_PalFipsStopWaitingRee(void);
+
+#endif  // _CC_PAL_FIPS_H
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_init.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_init.h
new file mode 100644
index 0000000..0b052bf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_init.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_init
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the PAL layer entry point.
+
+ It includes the definitions and APIs for PAL initialization and termination.
+ */
+
+#ifndef _CC_PAL_INIT_H
+#define _CC_PAL_INIT_H
+
+#include "cc_pal_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*!
+  @brief This function performs all initializations that may be required by
+  your PAL implementation, specifically by the DMA-able buffer scheme.
+
+  It is called by ::CC_LibInit.
+
+  The existing implementation allocates a contiguous memory pool that is later
+  used by the CryptoCell implementation.
+  If no initializations are needed in your environment, the function can be
+  minimized to return OK.
+
+  @return A non-zero value on failure.
+ */
+int CC_PalInit(void);
+
+
+
+/*!
+  @brief This function terminates the PAL implementation and frees the resources
+  that were allocated by ::CC_PalInit.
+
+  @return Void.
+ */
+void CC_PalTerminate(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_log.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_log.h
new file mode 100644
index 0000000..41d87c5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_log.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_log
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the PAL layer log definitions.
+
+ The log is disabled by default.
+ */
+
+
+#ifndef _CC_PAL_LOG_H_
+#define _CC_PAL_LOG_H_
+
+#include "cc_pal_types.h"
+#include "cc_pal_log_plat.h"
+
+/* PAL log levels (to be used in CC_PAL_logLevel) */
+/*! PAL log level - disabled. */
+#define CC_PAL_LOG_LEVEL_NULL      (-1)
+/*! PAL log level - error. */
+#define CC_PAL_LOG_LEVEL_ERR       0
+/*! PAL log level - warning. */
+#define CC_PAL_LOG_LEVEL_WARN      1
+/*! PAL log level - info. */
+#define CC_PAL_LOG_LEVEL_INFO      2
+/*! PAL log level - debug. */
+#define CC_PAL_LOG_LEVEL_DEBUG     3
+/*! PAL log level - trace. */
+#define CC_PAL_LOG_LEVEL_TRACE     4
+/*! PAL log level - data. */
+#define CC_PAL_LOG_LEVEL_DATA      5
+
+#ifndef CC_PAL_LOG_CUR_COMPONENT
+/* Setting default component mask in case caller did not define */
+/* (a mask that is always on for every log mask value but full masking) */
+/*! Default log debugged component. */
+#define CC_PAL_LOG_CUR_COMPONENT 0xFFFFFFFF
+#endif
+#ifndef CC_PAL_LOG_CUR_COMPONENT_NAME
+/*! Default log debugged component. */
+#define CC_PAL_LOG_CUR_COMPONENT_NAME "CC"
+#endif
+
+/* Select compile time log level (default if not explicitly specified by caller) */
+#ifndef CC_PAL_MAX_LOG_LEVEL /* Can be overriden by external definition of this constant */
+#ifdef DEBUG
+/*! Default debug log level, when debug is set to on. */
+#define CC_PAL_MAX_LOG_LEVEL  CC_PAL_LOG_LEVEL_ERR /*CC_PAL_LOG_LEVEL_DEBUG*/
+#else /* Disable logging */
+/*! Default debug log level, when debug is set to off. */
+#define CC_PAL_MAX_LOG_LEVEL CC_PAL_LOG_LEVEL_NULL
+#endif
+#endif /*CC_PAL_MAX_LOG_LEVEL*/
+/*! Evaluate \p CC_PAL_MAX_LOG_LEVEL in case provided by caller. */
+#define __CC_PAL_LOG_LEVEL_EVAL(level) level
+/*! The maximal log-level definition. */
+#define _CC_PAL_MAX_LOG_LEVEL __CC_PAL_LOG_LEVEL_EVAL(CC_PAL_MAX_LOG_LEVEL)
+
+
+#ifdef __ARM_DS5__
+#define inline __inline
+#endif
+
+#ifdef ARM_DSM
+/*! Log initialization function. */
+#define CC_PalLogInit() do {} while (0)
+/*! Log set-level function - sets the level of logging in case of debug. */
+#define CC_PalLogLevelSet(setLevel) do {} while (0)
+/*! Log set-mask function - sets the component-masking in case of debug. */
+#define CC_PalLogMaskSet(setMask) do {} while (0)
+#else
+#if _CC_PAL_MAX_LOG_LEVEL > CC_PAL_LOG_LEVEL_NULL
+/*! Log initialization function - platform dependent. */
+void CC_PalLogInit(void);
+/*! Log set-level function - sets the level of logging in case of debug. */
+void CC_PalLogLevelSet(int setLevel);
+/*! Log set-mask function - sets the component-masking in case of debug. */
+void CC_PalLogMaskSet(uint32_t setMask);
+/*! Global variable for log level. */
+extern int CC_PAL_logLevel;
+/*! Global variable for log mask. */
+extern uint32_t CC_PAL_logMask;
+#else /* No log - functions are not platform dependent in case of DEBUG=0*/
+/*! Log initialization function. */
+static inline void CC_PalLogInit(void) {}
+/*! Log set-level function - sets the level of logging in case of debug. */
+static inline void CC_PalLogLevelSet(int setLevel) {CC_UNUSED_PARAM(setLevel);}
+/*! Log set-mask function - sets the component-masking in case of debug. */
+static inline void CC_PalLogMaskSet(uint32_t setMask) {CC_UNUSED_PARAM(setMask);}
+#endif
+#endif
+
+/*! Filter logging based on \p logMask, and dispatch to platform-specific
+logging mechanism. */
+#define _CC_PAL_LOG(level, format, ...)  \
+    if (CC_PAL_logMask & CC_PAL_LOG_CUR_COMPONENT) \
+        CC_PalLog(CC_PAL_LOG_LEVEL_ ## level, "%s:%s: " format, CC_PAL_LOG_CUR_COMPONENT_NAME, __func__, ##__VA_ARGS__)
+
+#if (_CC_PAL_MAX_LOG_LEVEL >= CC_PAL_LOG_LEVEL_ERR)
+/*! Log messages according to log level.*/
+#define CC_PAL_LOG_ERR(format, ... ) \
+    _CC_PAL_LOG(ERR, format, ##__VA_ARGS__)
+#else
+/*! Log messages according to log level.*/
+#define CC_PAL_LOG_ERR( ... ) do {} while (0)
+#endif
+
+#if (_CC_PAL_MAX_LOG_LEVEL >= CC_PAL_LOG_LEVEL_WARN)
+/*! Log messages according to log level.*/
+#define CC_PAL_LOG_WARN(format, ... ) \
+    if (CC_PAL_logLevel >= CC_PAL_LOG_LEVEL_WARN) \
+        _CC_PAL_LOG(WARN, format, ##__VA_ARGS__)
+#else
+/*! Log messages according to log level.*/
+#define CC_PAL_LOG_WARN( ... ) do {} while (0)
+#endif
+
+#if (_CC_PAL_MAX_LOG_LEVEL >= CC_PAL_LOG_LEVEL_INFO)
+/*! Log messages according to log level.*/
+#define CC_PAL_LOG_INFO(format, ... ) \
+    if (CC_PAL_logLevel >= CC_PAL_LOG_LEVEL_INFO) \
+        _CC_PAL_LOG(INFO, format, ##__VA_ARGS__)
+#else
+/*! Log messages according to log level.*/
+#define CC_PAL_LOG_INFO( ... ) do {} while (0)
+#endif
+
+#if (_CC_PAL_MAX_LOG_LEVEL >= CC_PAL_LOG_LEVEL_DEBUG)
+/*! Log messages according to log level.*/
+#define CC_PAL_LOG_DEBUG(format, ... ) \
+    if (CC_PAL_logLevel >= CC_PAL_LOG_LEVEL_DEBUG) \
+        _CC_PAL_LOG(DEBUG, format, ##__VA_ARGS__)
+
+/*! Log message buffer.*/
+#define CC_PAL_LOG_DUMP_BUF(msg, buf, size)     \
+    do {                        \
+    int i;                      \
+    uint8_t *pData = (uint8_t*)buf;         \
+                            \
+    PRINTF("%s (%d):\n", msg, size);        \
+    for (i = 0; i < size; i++) {            \
+        PRINTF("0x%02X ", pData[i]);        \
+        if ((i & 0xF) == 0xF) {         \
+            PRINTF("\n");           \
+        }                   \
+    }                       \
+    PRINTF("\n");                   \
+    } while (0)
+#else
+/*! Log debug messages.*/
+#define CC_PAL_LOG_DEBUG( ... ) do {} while (0)
+/*! Log debug buffer.*/
+#define CC_PAL_LOG_DUMP_BUF(msg, buf, size) do {} while (0)
+#endif
+
+#if (_CC_PAL_MAX_LOG_LEVEL >= CC_PAL_LOG_LEVEL_TRACE)
+/*! Log debug trace.*/
+#define CC_PAL_LOG_TRACE(format, ... ) \
+    if (CC_PAL_logLevel >= CC_PAL_LOG_LEVEL_TRACE) \
+        _CC_PAL_LOG(TRACE, format, ##__VA_ARGS__)
+#else
+/*! Log debug trace.*/
+#define CC_PAL_LOG_TRACE(...) do {} while (0)
+#endif
+
+#if (_CC_PAL_MAX_LOG_LEVEL >= CC_PAL_LOG_LEVEL_TRACE)
+/*! Log debug data.*/
+#define CC_PAL_LOG_DATA(format, ...) \
+    if (CC_PAL_logLevel >= CC_PAL_LOG_LEVEL_TRACE) \
+        _CC_PAL_LOG(DATA, format, ##__VA_ARGS__)
+#else
+/*! Log debug data.*/
+#define CC_PAL_LOG_DATA( ...) do {} while (0)
+#endif
+
+/*!
+ @}
+ */
+
+#endif /*_CC_PAL_LOG_H_*/
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_mem.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_mem.h
new file mode 100644
index 0000000..07e4929
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_mem.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_mem
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains functions for memory operations.
+
+ The functions are generally implemented as wrappers to different
+ operating-system calls.
+
+ \note None of the described functions validate the input parameters, so that
+ the behavior of the APIs in case of an illegal parameter is dependent on the
+ behavior of the operating system.
+ */
+
+
+
+#ifndef _CC_PAL_MEM_H
+#define _CC_PAL_MEM_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+#include "cc_pal_mem_plat.h"
+#include "cc_pal_malloc_plat.h"
+#include <stdlib.h>
+#include <string.h>
+
+    /*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+    /**** ----- Memory Operations APIs ----- ****/
+
+/*!
+  @brief This function compares between two given buffers, according to the
+  given size.
+
+  @return The return values are according to operating-system return values.
+ */
+#define CC_PalMemCmp(aTarget, aSource, aSize) CC_PalMemCmpPlat(aTarget, aSource, aSize)
+
+/*!
+  @brief This function copies \p aSize bytes from the source buffer to the
+  destination buffer.
+
+  @return void.
+ */
+#define CC_PalMemCopy(aDestination, aSource, aSize) CC_PalMemCopyPlat(aDestination, aSource, aSize)
+
+/*!
+  @brief This function moves \p aSize bytes from the source buffer to the
+  destination buffer.
+
+  This function supports overlapped buffers.
+
+  @return void.
+ */
+#define CC_PalMemMove(aDestination, aSource, aSize) CC_PalMemMovePlat(aDestination, aSource, aSize)
+
+
+/*!
+  @brief This function sets \p aSize bytes of \p aChar in the given buffer.
+
+  @return void.
+ */
+#define CC_PalMemSet(aTarget, aChar, aSize) CC_PalMemSetPlat(aTarget, aChar, aSize)
+
+
+/*!
+  @brief This function sets \p aSize bytes in the given buffer to zeroes.
+
+  @return void.
+ */
+#define CC_PalMemSetZero(aTarget, aSize) CC_PalMemSetZeroPlat(aTarget, aSize)
+
+
+/*!
+  @brief This function allocates a memory buffer according to \p aSize.
+
+  @return A pointer to the allocated buffer on success.
+  @return NULL on failure.
+ */
+#define CC_PalMemMalloc(aSize) CC_PalMemMallocPlat(aSize)
+
+/*!
+  @brief This function reallocates a memory buffer according to \p aNewSize.
+         The content of the old buffer is moved to the new location.
+
+  @return A pointer to the newly-allocated buffer on success.
+  @return NULL on failure.
+ */
+#define CC_PalMemRealloc(aBuffer, aNewSize) CC_PalMemReallocPlat(aBuffer, aNewSize)
+
+/*!
+  @brief This function frees a previously-allocated buffer.
+
+  @return void.
+ */
+#define CC_PalMemFree(aBuffer) CC_PalMemFreePlat(aBuffer)
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_memmap.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_memmap.h
new file mode 100644
index 0000000..5b2ed63
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_memmap.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_memmap
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains functions for memory mapping.
+
+       \note None of the described functions validate the input parameters, so
+       that the behavior of the APIs in case of an illegal parameter is dependent
+       on the behavior of the operating system.
+ */
+
+#ifndef _CC_PAL_MEMMAP_H
+#define _CC_PAL_MEMMAP_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#include "cc_pal_types.h"
+#include "cc_address_defs.h"
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+  @brief This function returns the base virtual address that maps the base
+  physical address.
+
+  @return \c 0 on success.
+  @return A non-zero value in case of failure.
+ */
+uint32_t CC_PalMemMap(
+        /*! [in] The starting physical address of the I/O range to be mapped. */
+        CCDmaAddr_t physicalAddress,
+        /*! [in] The number of bytes that were mapped. */
+        uint32_t mapSize,
+        /*! [out] A pointer to the base virtual address to which the physical
+        pages were mapped. */
+        uint32_t **ppVirtBuffAddr);
+
+
+/*!
+  @brief This function unmaps a specified address range that was previously
+  mapped by #CC_PalMemMap.
+
+  @return \c 0 on success.
+  @return A non-zero value in case of failure.
+ */
+uint32_t CC_PalMemUnMap(
+        /*! [in] A pointer to the base virtual address to which the physical
+        pages were mapped. */
+        uint32_t *pVirtBuffAddr,
+        /*! [in] The number of bytes that were mapped. */
+        uint32_t mapSize);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_mutex.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_mutex.h
new file mode 100644
index 0000000..de4d94c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_mutex.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_mutex
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains functions for resource management (mutex operations).
+
+ These functions are generally implemented as wrappers to different
+ operating-system calls.
+
+ \note None of the described functions validate the input parameters, so that
+ the behavior of the APIs in case of an illegal parameter is dependent on the
+ behavior of the operating system.
+ */
+
+#ifndef _CC_PAL_MUTEX_H
+#define _CC_PAL_MUTEX_H
+
+#include "cc_pal_mutex_plat.h"
+#include "cc_pal_types_plat.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+  @brief This function creates a mutex.
+
+
+  @return \c 0 on success.
+  @return A non-zero value on failure.
+ */
+CCError_t CC_PalMutexCreate(
+        /*! [out] A pointer to the handle of the created mutex. */
+        CC_PalMutex *pMutexId
+        );
+
+
+/*!
+  @brief This function destroys a mutex.
+
+
+  @return \c 0 on success.
+  @return A non-zero value on failure.
+ */
+CCError_t CC_PalMutexDestroy(
+        /*! [in] A pointer to handle of the mutex to destroy. */
+        CC_PalMutex *pMutexId
+        );
+
+
+/*!
+  @brief This function waits for a mutex with \p aTimeOut.
+
+  \p aTimeOut is specified in milliseconds. A value of \p aTimeOut=CC_INFINITE
+  means that the function will not return.
+
+  @return \c 0 on success.
+  @return A non-zero value on failure.
+ */
+CCError_t CC_PalMutexLock(
+        /*! [in] A pointer to handle of the mutex. */
+        CC_PalMutex *pMutexId,
+        /*! [in] The timeout in mSec, or CC_INFINITE. */
+        uint32_t aTimeOut
+        );
+
+
+/*!
+  @brief This function releases the mutex.
+
+  @return \c 0 on success.
+  @return A non-zero value on failure.
+ */
+CCError_t CC_PalMutexUnlock(
+        /*! [in] A pointer to the handle of the mutex. */
+        CC_PalMutex *pMutexId
+        );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_perf.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_perf.h
new file mode 100644
index 0000000..d980ba0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_perf.h
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_PERF_H_
+#define _CC_PAL_PERF_H_
+
+#include <string.h>
+
+#ifdef LIB_PERF
+#include "cc_pal_perf_plat.h"
+#endif
+
+typedef enum
+{
+    PERF_TEST_TYPE_AES_INIT,
+    PERF_TEST_TYPE_AES_SET_KEY,
+    PERF_TEST_TYPE_AES_BLOCK,
+    PERF_TEST_TYPE_AES_FIN,
+    PERF_TEST_TYPE_CC_AES_INIT,
+    PERF_TEST_TYPE_CC_AES_BLOCK,
+    PERF_TEST_TYPE_CC_AES_FIN,
+    PERF_TEST_TYPE_HW_CMPLT ,
+    PERF_TEST_TYPE_PAL_MAP,
+    PERF_TEST_TYPE_PAL_UNMAP,
+    PERF_TEST_TYPE_MLLI_BUILD,
+    PERF_TEST_TYPE_SYM_DRV_INIT,
+    PERF_TEST_TYPE_SYM_DRV_PROC,
+    PERF_TEST_TYPE_SYM_DRV_FIN,
+    PERF_TEST_TYPE_CC_HASH_INIT,
+    PERF_TEST_TYPE_CC_HASH_UPDATE,
+    PERF_TEST_TYPE_CC_HASH_FIN,
+    PERF_TEST_TYPE_CC_HMAC_INIT,
+    PERF_TEST_TYPE_CC_HMAC_UPDATE,
+    PERF_TEST_TYPE_CC_HMAC_FIN,
+    PERF_TEST_TYPE_CMPLT_SLEEP,
+    PERF_TEST_TYPE_CC_ECDSA_SIGN_INIT,
+    PERF_TEST_TYPE_CC_ECDSA_SIGN_UPDATE,
+    PERF_TEST_TYPE_CC_ECDSA_SIGN_FINISH,
+    PERF_TEST_TYPE_CC_ECDSA_VERIFY_INIT,
+    PERF_TEST_TYPE_CC_ECDSA_VERIFY_UPDATE,
+    PERF_TEST_TYPE_CC_ECDSA_VERIFY_FINISH,
+    PERF_TEST_TYPE_PKA_EC_WRST_SCALAR_MULT,
+    PERF_TEST_TYPE_CALC_SIGNATURE,
+    PERF_TEST_TYPE_PKA_SCALAR_MULT_AFF,
+    PERF_TEST_TYPE_PKA_SCALAR_MULT_SCA,
+    PERF_TEST_TYPE_PKA_ECDSA_VERIFY,
+    PERF_TEST_TYPE_PKA_ModExp = 0x30,
+    PERF_TEST_TYPE_TEST_BASE = 0x100,
+    PERF_TEST_TYPE_MAX,
+    PERF_TEST_TYPE_RESERVE32 = 0x7FFFFFFF
+} CCPalPerfType_t;
+
+#ifdef LIB_PERF
+
+static char* CC_PalPerfTypeStr(CCPalPerfType_t type, char* pStr, uint32_t buffLen)
+{
+    #define CCPalPerfTypeStr_str(a) case a: strncpy(pStr, #a + strlen("PERF_TEST_TYPE_"), buffLen); break;
+
+    switch (type)
+    {
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_AES_INIT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_AES_SET_KEY);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_AES_BLOCK);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_AES_FIN);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_AES_INIT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_AES_BLOCK);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_AES_FIN);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_HW_CMPLT );
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_PAL_MAP);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_PAL_UNMAP);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_MLLI_BUILD);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_SYM_DRV_INIT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_SYM_DRV_PROC);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_SYM_DRV_FIN);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_HASH_INIT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_HASH_UPDATE);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_HASH_FIN);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_HMAC_INIT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_HMAC_UPDATE);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_HMAC_FIN);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CMPLT_SLEEP);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_ECDSA_SIGN_INIT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_ECDSA_SIGN_UPDATE);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_ECDSA_SIGN_FINISH);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_ECDSA_VERIFY_INIT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_ECDSA_VERIFY_UPDATE);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CC_ECDSA_VERIFY_FINISH);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_PKA_EC_WRST_SCALAR_MULT);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_CALC_SIGNATURE);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_PKA_SCALAR_MULT_AFF);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_PKA_SCALAR_MULT_SCA);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_PKA_ECDSA_VERIFY);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_PKA_ModExp);
+        CCPalPerfTypeStr_str(PERF_TEST_TYPE_TEST_BASE);
+        default: strncpy(pStr, "PERF_TEST_TYPE_UNKNOWN", buffLen);
+    }
+
+    return pStr;
+}
+
+#define CC_PAL_PERF_INIT                            CC_PalPerfInit
+#define CC_PAL_PERF_OPEN_NEW_ENTRY(num, type)       num = CC_PalPerfOpenNewEntry(type)
+#define CC_PAL_PERF_CLOSE_ENTRY(num, type)          CC_PalPerfCloseEntry(num, type)
+#define CC_PAL_PERF_DUMP                            CC_PalPerfDump
+#define CC_PAL_PERF_FIN                             CC_PalPerfFin
+
+/**
+ * @brief   initialize performance test mechanism
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfInit(void);
+
+
+/**
+ * @brief   opens new entry in perf buffer to record new entry
+ *
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return A non-zero value in case of failure.
+ */
+CCPalPerfData_t CC_PalPerfOpenNewEntry(CCPalPerfType_t entryType);
+
+
+/**
+ * @brief   closes entry in perf buffer previously opened by CC_PalPerfOpenNewEntry
+ *
+ * @param[in] idx -  index of the entry to be closed, the return value of CC_PalPerfOpenNewEntry
+ * @param[in] entryType -  entry type (defined in cc_pal_perf.h) to be recorded in buffer
+ *
+ * @return A non-zero value in case of failure.
+ */
+void CC_PalPerfCloseEntry(CCPalPerfData_t idx, CCPalPerfType_t entryType);
+
+
+/**
+ * @brief   dumps the performance buffer
+ *
+ * @param[in] None
+ *
+ * @return None
+ */
+void CC_PalPerfDump(void);
+
+
+/**
+ * @brief   terminates resources used for performance tests
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalPerfFin(void);
+
+#else  //LIB_PERF
+#define CC_PAL_PERF_INIT()
+#define CC_PAL_PERF_OPEN_NEW_ENTRY(num, type)  (num=num)
+#define CC_PAL_PERF_CLOSE_ENTRY(num, type)
+#define CC_PAL_PERF_DUMP()
+#define CC_PAL_PERF_FIN()
+
+
+typedef unsigned int CCPalPerfData_t;
+
+#endif  //LIB_PERF
+
+
+#endif /*_CC_PAL_PERF_H__*/
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_pm.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_pm.h
new file mode 100644
index 0000000..2b7d9c2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_pm.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_pm
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the definitions and APIs for power-management
+ implementation.
+
+ This is a placeholder for platform-specific power management implementation.
+ The module should be updated whether CryptoCell is active or not,
+ to notify the external PMU when CryptoCell might be powered down.
+ */
+
+#ifndef _CC_PAL_PM_H
+#define _CC_PAL_PM_H
+
+
+/*
+******** Function pointer definitions **********
+*/
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+ @brief This function initiates an atomic counter.
+
+ @return Void.
+ */
+void CC_PalPowerSaveModeInit(void);
+
+/*!
+ @brief This function returns the number of active registered CryptoCell
+ operations.
+
+ @return The value of the atomic counter.
+ */
+int32_t CC_PalPowerSaveModeStatus(void);
+
+/*!
+ @brief This function updates the atomic counter on each call to CryptoCell.
+
+ On each call to CryptoCell, the counter is increased. At the end of each operation
+ the counter is decreased.
+ Once the counter is zero, an external callback is called.
+
+ @return \c 0 on success.
+ @return A non-zero value on failure.
+ */
+CCError_t CC_PalPowerSaveModeSelect(
+        /*! [in] TRUE: CryptoCell is active. FALSE: CryptoCell is idle. */
+        CCBool isPowerSaveMode
+        );
+
+
+/*!
+ @}
+ */
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_trng.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_trng.h
new file mode 100644
index 0000000..6927366
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_trng.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_trng
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains APIs for retrieving TRNG user parameters.
+ */
+
+#ifndef _CC_PAL_TRNG_H
+#define _CC_PAL_TRNG_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+
+#if (CC_CONFIG_TRNG_MODE==1)
+/*!
+ @brief The random-generator parameters of CryptoCell for TRNG mode.
+
+ This is as defined in <em>NIST SP 90B: Recommendation for
+ the Entropy Sources Used for Random Bit Generation</em>.
+ */
+typedef struct  CC_PalTrngModeParams_t
+{
+    /*! The amount of bytes for the required entropy bits. It is calculated as
+    ROUND_UP(ROUND_UP(((required entropy bits)/(entropy per bit)), 1024),
+    (EHR width in bytes)) / 8.
+    The 1024 bits is the multiple of the window size. The multiple of the EHR
+    width, which is 192 bits. */
+    uint32_t  numOfBytes;
+    /*!  The repetition counter cutoff, as defined in <em>NIST SP 90B:
+    Recommendation for the Entropy Sources Used for Random Bit
+    Generation</em>, section 4.4.1.
+    This is calculated as C = ROUND_UP(1+(-log(W)/H)), W = 2^(-40),
+    H=(entropy per bit). */
+    uint32_t  repetitionCounterCutoff;
+    /*!  The adaptive proportion cutoff, as defined in <em>NIST SP 90B:
+    Recommendation for the Entropy Sources Used for Random Bit
+    Generation</em>, section 4.4.2.
+    This is calculated as C =CRITBINOM(W, power(2,(-H)),1-a), W = 1024,
+    a = 2^(-40), H=(entropy per bit). */
+    uint32_t  adaptiveProportionCutOff;
+
+} CC_PalTrngModeParams_t;
+#endif
+
+/*! Definition for the structure of the random-generator parameters
+    of CryptoCell, containing the user-given parameters. */
+typedef struct  CC_PalTrngParams_t
+{
+    /*! The sampling ratio of ROSC #1.*/
+    uint32_t  SubSamplingRatio1;
+    /*! The sampling ratio of ROSC #2.*/
+    uint32_t  SubSamplingRatio2;
+    /*! The sampling ratio of ROSC #3.*/
+    uint32_t  SubSamplingRatio3;
+    /*! The sampling ratio of ROSC #4.*/
+    uint32_t  SubSamplingRatio4;
+#if (CC_CONFIG_TRNG_MODE==1)
+    /*! Specific parameters of the TRNG mode.*/
+    CC_PalTrngModeParams_t   trngModeParams;
+#endif
+} CC_PalTrngParams_t;
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+  @brief This function returns the TRNG user parameters.
+
+  @return \c 0 on success.
+  @return A non-zero value on failure.
+ */
+CCError_t CC_PalTrngParamGet(
+        /*! [out] A pointer to the TRNG user parameters. */
+        CC_PalTrngParams_t *pTrngParams,
+        /*! [in/out] A pointer to the size of the TRNG-user-parameters
+        structure used. Input: the function must verify its size is the
+        same as #CC_PalTrngParams_t. Output: the function returns the size
+        of #CC_PalTrngParams_t for library-size verification. */
+        size_t *pParamsSize
+                             );
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_types.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_types.h
new file mode 100644
index 0000000..c49563a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/cc_pal_types.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pal_types
+ @{
+*/
+
+/*!
+ @file
+ @brief This file contains definitions and types of CryptoCell PAL platform-dependent APIs.
+ */
+
+#ifndef CC_PAL_TYPES_H
+#define CC_PAL_TYPES_H
+
+#include "cc_pal_types_plat.h"
+
+/*! Boolean types.*/
+typedef enum {
+    /*! Boolean false definition.*/
+    CC_FALSE = 0,
+    /*! Boolean true definition.*/
+    CC_TRUE = 1
+} CCBool;
+
+/*! Success definition. */
+#define CC_SUCCESS              0UL
+/*! Failure definition. */
+#define CC_FAIL         1UL
+
+/*! Success (OK) definition. */
+#define CC_OK   0
+
+/*! Handles unused parameters in the code, to avoid compilation warnings.  */
+#define CC_UNUSED_PARAM(prm)  ((void)prm)
+
+/*! The maximal uint32 value.*/
+#define CC_MAX_UINT32_VAL   (0xFFFFFFFF)
+
+
+/* Minimal and Maximal macros */
+#ifdef  min
+/*! Definition for minimal calculation. */
+#define CC_MIN(a,b) min( a , b )
+#else
+/*! Definition for minimal calculation. */
+#define CC_MIN( a , b ) ( ( (a) < (b) ) ? (a) : (b) )
+#endif
+
+#ifdef max
+/*! Definition for maximal calculation. */
+#define CC_MAX(a,b) max( a , b )
+#else
+/*! Definition for maximal calculation.. */
+#define CC_MAX( a , b ) ( ( (a) > (b) ) ? (a) : (b) )
+#endif
+
+/*! This macro calculates the number of full bytes from bits, where seven bits
+are one byte. */
+#define CALC_FULL_BYTES(numBits)        ((numBits)/CC_BITS_IN_BYTE + (((numBits) & (CC_BITS_IN_BYTE-1)) > 0))
+/*! This macro calculates the number of full 32-bit words from bits, where
+31 bits are one word. */
+#define CALC_FULL_32BIT_WORDS(numBits)      ((numBits)/CC_BITS_IN_32BIT_WORD +  (((numBits) & (CC_BITS_IN_32BIT_WORD-1)) > 0))
+/*! This macro calculates the number of full 32-bit words from bytes, where
+three bytes are one word. */
+#define CALC_32BIT_WORDS_FROM_BYTES(sizeBytes)  ((sizeBytes)/CC_32BIT_WORD_SIZE + (((sizeBytes) & (CC_32BIT_WORD_SIZE-1)) > 0))
+/*! This macro calculates the number of full 32-bit words from 64-bits
+dwords. */
+#define CALC_32BIT_WORDS_FROM_64BIT_DWORD(sizeWords)  (sizeWords * CC_32BIT_WORD_IN_64BIT_DWORD)
+/*! This macro rounds up bits to 32-bit words. */
+#define ROUNDUP_BITS_TO_32BIT_WORD(numBits)     (CALC_FULL_32BIT_WORDS(numBits) * CC_BITS_IN_32BIT_WORD)
+/*! This macro rounds up bits to bytes. */
+#define ROUNDUP_BITS_TO_BYTES(numBits)      (CALC_FULL_BYTES(numBits) * CC_BITS_IN_BYTE)
+/*! This macro rounds up bytes to 32-bit words. */
+#define ROUNDUP_BYTES_TO_32BIT_WORD(sizeBytes)  (CALC_32BIT_WORDS_FROM_BYTES(sizeBytes) * CC_32BIT_WORD_SIZE)
+/*! Definition of 1 KB in bytes. */
+#define CC_1K_SIZE_IN_BYTES 1024
+/*! Definition of number of bits in a byte. */
+#define CC_BITS_IN_BYTE     8
+/*! Definition of number of bits in a 32-bits word. */
+#define CC_BITS_IN_32BIT_WORD   32
+/*! Definition of number of bytes in a 32-bits word. */
+#define CC_32BIT_WORD_SIZE  4
+/*! Definition of number of 32-bits words in a 64-bits dword. */
+#define CC_32BIT_WORD_IN_64BIT_DWORD 2
+
+
+/*!
+ @}
+*/
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_abort_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_abort_plat.h
new file mode 100644
index 0000000..4c6ef6d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_abort_plat.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_ABORT_PLAT_H
+#define _CC_PAL_ABORT_PLAT_H
+
+#include "cc_pal_log.h"
+#include <stdlib.h>
+
+void CC_PalAbort(const char * exp);
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_dma_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_dma_plat.h
new file mode 100644
index 0000000..207b5ff
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_dma_plat.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_DMA_PLAT_H
+#define _CC_PAL_DMA_PLAT_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_address_defs.h"
+
+/**
+ * @brief   stub function, the function should initialize the DMA mapping of the platform (if needed)
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] physBuffAddr - physical start address of the memory to map
+ *
+ * @return Start address of contiguous memory
+ */
+extern uint32_t CC_PalDmaInit(uint32_t  buffSize,    /*!< [in] Buffer size in Bytes. */
+                  CCDmaAddr_t  physBuffAddr /*!< [in] Physical start address of the memory to map. */);
+
+/**
+ * @brief   free system resources created in PD_PAL_DmaInit()
+ *
+ *
+ * @return void
+ */
+extern void CC_PalDmaTerminate(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_interrupt_ctrl_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_interrupt_ctrl_plat.h
new file mode 100644
index 0000000..eb80a2e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_interrupt_ctrl_plat.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_INTERRUPTCTRL_PLAT_H
+#define _CC_PAL_INTERRUPTCTRL_PLAT_H
+
+#include "FreeRTOS.h"
+#include "InterruptCtrl.h"
+
+#ifdef SSE_200
+#define CRYPTOCELL_INTERRUPT 8 /*Connected to HOST_IRR*/
+#else
+#define CRYPTOCELL_INTERRUPT 24 /*Connected to HOST_IRR*/
+#endif
+/**
+ * @brief This function sets one of the handler function pointers that are
+ * in handlerFuncPtrArr, according to given index.
+ *
+ * @param[in]
+ * handlerIndx - Irq index.
+ * funcPtr - Address of the new handler function.
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalRequestIrq(uint32_t irq, IrqHandlerPtr funcPtr,
+            const char *name, uint8_t nameLength, void *args);
+
+/**
+ * @brief This function removes an interrupt handler.
+ *
+ * @param[in]
+ * irq - Irq index.
+ *
+ * @param[out]
+ *
+ * @return
+ */
+void CC_PalFreeIrq(uint32_t irq);
+
+/**
+ * @brief This function enables an IRQ according to given index.
+ *
+ * @param[in]
+ * irq - Irq index.
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalEnableIrq(uint32_t irq);
+
+/**
+ * @brief This function disables an IRQ according to given index.
+ *
+ * @param[in]
+ * irq - Irq index.
+ *
+ * @param[out]
+ *
+ * @return - CC_SUCCESS for success, CC_FAIL for failure.
+ */
+CCError_t CC_PalDisableIrq(uint32_t irq);
+
+/**
+ * @brief This function removes the interrupt handler for
+ * cryptocell interrupts.
+ *
+ */
+void CC_PalFinishIrq(void);
+
+/* @brief
+*
+* @param[in]
+*
+* @param[out]
+*
+* @return - CC_SUCCESS for success, CC_FAIL for failure.
+*/
+CCError_t CC_PalInitIrq(void);
+
+/*!
+ * Busy wait upon Interrupt Request Register (IRR) signals.
+ * This function notifys for any ARM CryptoCell interrupt, it is the caller responsiblity
+ * to verify and prompt the expected case interupt source.
+ *
+ * @param[in] data  - input data for future use
+ * \return  CCError_t   - CC_OK upon success
+ */
+CCError_t CC_PalWaitInterrupt( uint32_t data);
+
+
+#endif /* _CC_PAL_INTERRUPTCTRL_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_log_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_log_plat.h
new file mode 100644
index 0000000..a3f3ef4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_log_plat.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_LOG_PLAT_H_
+#define _CC_PAL_LOG_PLAT_H_
+
+#include "cc_log_mask.h"
+#include <stdio.h>
+
+/************** PRINTF rules ******************/
+#if defined(DEBUG)
+
+void CC_PalLog(int level, const char * format, ...);
+
+#else /* Disable all prints */
+
+#define CC_PalLog(...)  do {} while (0)
+
+#endif
+
+
+#endif /*_CC_PAL_LOG_PLAT_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_malloc_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_malloc_plat.h
new file mode 100644
index 0000000..20f6fa8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_malloc_plat.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_MEMALLOC_INT_H
+#define _CC_PAL_MEMALLOC_INT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include "FreeRTOS.h"
+
+/**
+* @brief File Description:
+*        This file contains wrappers for memory operations APIs.
+*/
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+ * @brief This function purpose is to allocate a memory buffer according to aSize.
+ *
+ *
+ * @return The function returns a pointer to allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemMallocPlat(size_t  aSize /*!< [in] Number of bytes to allocate. */);
+
+/*!
+ * @brief This function purpose is to reallocate a memory buffer according to aNewSize.
+ *        The content of the old buffer is moved to the new location.
+ *
+ * @return The function returns a pointer to the newly allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemReallocPlat(  void* aBuffer,     /*!< [in] Pointer to allocated buffer. */
+                             size_t  aNewSize   /*!< [in] Number of bytes to reallocate. */);
+
+/*!
+ * @brief This function purpose is to free allocated buffer.
+ *
+ *
+ * @return void.
+ */
+void CC_PalMemFreePlat(void* aBuffer /*!< [in] Pointer to allocated buffer.*/);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_mem_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_mem_plat.h
new file mode 100644
index 0000000..f0aa015
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_mem_plat.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MEM_INT_H
+#define _CC_PAL_MEM_INT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cc_pal_compiler.h"
+
+/**
+ * @brief File Description:
+ *        This file contains the implementation for memory operations APIs.
+ *        The functions implementations are generally just wrappers to different operating system calls.
+ */
+
+
+/*----------------------------
+  PUBLIC FUNCTIONS
+-------------------------------*/
+
+
+/*!
+ * @brief This function purpose is to compare between two given buffers according to given size.
+ *
+ * @return The return values is according to operating system return values.
+ */
+int32_t CC_PalMemCmpPlat(  const void* aTarget, /*!< [in] The target buffer to compare. */
+                           const void* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */);
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ *
+ * @return void.
+ */
+void* CC_PalMemCopyPlat(     void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                               const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                               size_t      aSize     /*!< [in] Number of bytes to copy. */ );
+
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ * This function Supports overlapped buffers.
+ *
+ * @return void.
+ */
+void CC_PalMemMovePlat(   void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                          const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                          size_t      aSize     /*!< [in] Number of bytes to copy. */);
+
+
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with aChar.
+ *
+ * @return void.
+ */
+void CC_PalMemSetPlat(   void* aTarget, /*!< [out]  The target buffer to set. */
+                         uint8_t aChar, /*!< [in] The char to set into aTarget. */
+                         size_t        aSize  /*!< [in] Number of bytes to set. */);
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with zeroes.
+ *
+ * @return void.
+ */
+void CC_PalMemSetZeroPlat(    void* aTarget, /*!< [out]  The target buffer to set. */
+                              size_t      aSize    /*!< [in] Number of bytes to set. */);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_mutex_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_mutex_plat.h
new file mode 100644
index 0000000..e5541a7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_mutex_plat.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_MUTEX_PLAT_H
+#define _CC_PAL_MUTEX_PLAT_H
+
+#include "FreeRTOS.h"
+#include "semphr.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/**
+* @brief File Description:
+*        This file contains functions for resource management (semaphor operations).
+*        The functions implementations are generally just wrappers to different operating system calls.
+*        None of the described functions will check the input parameters so the behavior
+*        of the APIs in illegal parameters case is dependent on the operating system behavior.
+*
+*/
+
+typedef SemaphoreHandle_t CC_PalMutex;
+
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_perf_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_perf_plat.h
new file mode 100644
index 0000000..75986dc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_perf_plat.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_PERF_PLAT_H__
+#define _CC_PAL_PERF_PLAT_H__
+
+#include "stdlib.h"
+#include "stdint.h"
+
+typedef unsigned int CCPalPerfData_t;
+
+#endif /*_CC_PAL_PERF_PLAT_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_types_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_types_plat.h
new file mode 100644
index 0000000..c1a066f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/freertos/cc_pal_types_plat.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*! @file
+@brief This file contains basic platform-dependent type definitions.
+*/
+#ifndef _CC_PAL_TYPES_PLAT_H
+#define _CC_PAL_TYPES_PLAT_H
+/* Host specific types for standard (ISO-C99) compilant platforms */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+typedef uintptr_t       CCVirtAddr_t;
+typedef uint32_t            CCBool_t;
+typedef uint32_t            CCStatus;
+
+#define CCError_t           CCStatus
+#define CC_INFINITE         0xFFFFFFFF
+
+#define CEXPORT_C
+#define CIMPORT_C
+
+#endif /*_CC_PAL_TYPES_PLAT_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_abort_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_abort_plat.h
new file mode 100644
index 0000000..bd5a4dc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_abort_plat.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_ABORT_PLAT_H
+#define _CC_PAL_ABORT_PLAT_H
+
+#include "cc_pal_log.h"
+#include "cc_pal_compiler.h"
+#include "stdlib.h"
+
+void _CC_PalAbort(const char * exp);
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_dma_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_dma_plat.h
new file mode 100644
index 0000000..188eef1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_dma_plat.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_DMA_PLAT_H
+#define _CC_PAL_DMA_PLAT_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_address_defs.h"
+
+/**
+ * @brief   Initializes contiguous memory pool required for CC_PalDmaContigBufferAllocate() and CC_PalDmaContigBufferFree(). Our
+ *      example implementation is to mmap 0x30000000 and call to bpool(), for use of bget() in CC_PalDmaContigBufferAllocate(),
+ *          and brel() in CC_PalDmaContigBufferFree().
+ *
+ * @return A non-zero value in case of failure.
+ */
+extern uint32_t CC_PalDmaInit(uint32_t  buffSize,    /*!< [in] Buffer size in Bytes. */
+                  CCDmaAddr_t  physBuffAddr /*!< [in] Physical start address of the memory to map. */);
+
+/**
+ * @brief   free system resources created in CC_PalDmaInit()
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ *
+ * @return void
+ */
+extern void CC_PalDmaTerminate(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_interrupt_ctrl_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_interrupt_ctrl_plat.h
new file mode 100644
index 0000000..43dc04d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_interrupt_ctrl_plat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_INTERRUPTCTRL_PLAT_H
+#define _CC_PAL_INTERRUPTCTRL_PLAT_H
+
+
+
+/**
+ * @brief This function removes the interrupt handler for
+ * cryptocell interrupts.
+ *
+ */
+void CC_PalFinishIrq(void);
+
+/* @brief
+*
+* @param[in]
+*
+* @param[out]
+*
+* @return - CC_SUCCESS for success, CC_FAIL for failure.
+*/
+CCError_t CC_PalInitIrq(void);
+
+/*!
+ * Busy wait upon Interrupt Request Register (IRR) signals.
+ * This function notifys for any ARM CryptoCell interrupt, it is the caller responsiblity
+ * to verify and prompt the expected case interupt source.
+ *
+ * @param[in] data  - input data for future use
+ * \return  CCError_t   - CC_OK upon success
+ */
+CCError_t CC_PalWaitInterrupt( uint32_t data);
+
+
+#endif /* _CC_PAL_INTERRUPTCTRL_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_log_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_log_plat.h
new file mode 100644
index 0000000..5dbc7de
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_log_plat.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_LOG_PLAT_H_
+#define _CC_PAL_LOG_PLAT_H_
+
+#include "cc_log_mask.h"
+#include <syslog.h>
+
+void CC_PalLog(int level, const char * format, ...);
+
+#endif /*_CC_PAL_LOG_PLAT_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_malloc_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_malloc_plat.h
new file mode 100644
index 0000000..fa84651
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_malloc_plat.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MEMALLOC_INT_H
+#define _CC_PAL_MEMALLOC_INT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+/**
+* @brief File Description:
+*        This file contains wrappers for memory operations APIs.
+*/
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+ * @brief This function purpose is to allocate a memory buffer according to aSize.
+ *
+ *
+ * @return The function returns a pointer to allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemMallocPlat(size_t  aSize /*!< [in] Number of bytes to allocate. */);
+
+/*!
+ * @brief This function purpose is to reallocate a memory buffer according to aNewSize.
+ *        The content of the old buffer is moved to the new location.
+ *
+ * @return The function returns a pointer to the newly allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemReallocPlat(  void* aBuffer,     /*!< [in] Pointer to allocated buffer. */
+                             size_t  aNewSize   /*!< [in] Number of bytes to reallocate. */);
+
+/*!
+ * @brief This function purpose is to free allocated buffer.
+ *
+ *
+ * @return void.
+ */
+void CC_PalMemFreePlat(void* aBuffer /*!< [in] Pointer to allocated buffer.*/);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_mem_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_mem_plat.h
new file mode 100644
index 0000000..51ea8e1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_mem_plat.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MEM_PLAT_H
+#define _CC_PAL_MEM_PLAT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+
+/**
+ * @brief File Description:
+ *        This file contains the implementation for memory operations APIs.
+ *        The functions implementations are generally just wrappers to different operating system calls.
+ */
+
+
+/*----------------------------
+  PUBLIC FUNCTIONS
+-------------------------------*/
+
+
+/*!
+ * @brief This function purpose is to compare between two given buffers according to given size.
+ *
+ * @return The return values is according to operating system return values.
+ */
+int32_t CC_PalMemCmpPlat(  const void* aTarget, /*!< [in] The target buffer to compare. */
+                           const void* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */);
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ *
+ * @return void.
+ */
+void* CC_PalMemCopyPlat(     void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                               const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                               size_t      aSize     /*!< [in] Number of bytes to copy. */ );
+
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ * This function Supports overlapped buffers.
+ *
+ * @return void.
+ */
+void CC_PalMemMovePlat(   void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                          const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                          size_t      aSize     /*!< [in] Number of bytes to copy. */);
+
+
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with aChar.
+ *
+ * @return void.
+ */
+void CC_PalMemSetPlat(   void* aTarget, /*!< [out]  The target buffer to set. */
+                         uint8_t aChar, /*!< [in] The char to set into aTarget. */
+                         size_t        aSize  /*!< [in] Number of bytes to set. */);
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with zeroes.
+ *
+ * @return void.
+ */
+void CC_PalMemSetZeroPlat(    void* aTarget, /*!< [out]  The target buffer to set. */
+                              size_t      aSize    /*!< [in] Number of bytes to set. */);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_mutex_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_mutex_plat.h
new file mode 100644
index 0000000..eda3970
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_mutex_plat.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MUTEX_PLAT_H
+#define _CC_PAL_MUTEX_PLAT_H
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <pthread.h>
+
+/**
+* @brief File Description:
+*        This file contains functions for resource management (semaphor operations).
+*        The functions implementations are generally just wrappers to different operating system calls.
+*        None of the described functions will check the input parameters so the behavior
+*        of the APIs in illegal parameters case is dependent on the operating system behavior.
+*
+*/
+
+typedef pthread_mutex_t CC_PalMutex;
+
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_perf_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_perf_plat.h
new file mode 100644
index 0000000..3bfb386
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_perf_plat.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_PERF_PLAT_H__
+#define _CC_PAL_PERF_PLAT_H__
+
+typedef uint32_t CCPalPerfData_t;
+#endif /*_CC_PAL_PERF_PLAT_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_types_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_types_plat.h
new file mode 100644
index 0000000..db23f2c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/linux/cc_pal_types_plat.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_TYPES_PLAT_H
+#define _CC_PAL_TYPES_PLAT_H
+
+/*! @file
+@brief This file contains basic platform-dependent type definitions.
+*/
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+typedef uintptr_t       CCVirtAddr_t;
+typedef uint32_t            CCBool_t;
+typedef uint32_t            CCStatus;
+
+#define CCError_t           CCStatus
+#define CC_INFINITE         0xFFFFFFFF
+
+#define CEXPORT_C
+#define CIMPORT_C
+
+/* Define macros for host to SeP endianess conversion (for host wrappers) */
+#include <endian.h>
+#include <byteswap.h>
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_le16(x) bswap_16(x)
+#define le16_to_cpu(x) bswap_16(x)
+#define cpu_to_le32(x) bswap_32(x)
+#define le32_to_cpu(x) bswap_32(x)
+#else /*__LITTLE_ENDIAN*/
+#define cpu_to_le16(x) x
+#define le16_to_cpu(x) x
+#define cpu_to_le32(x) x
+#define le32_to_cpu(x) x
+#endif /*__BYTE_ORDER*/
+
+#endif /*_CC_PAL_TYPES_PLAT_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_abort_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_abort_plat.h
new file mode 100644
index 0000000..4c6ef6d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_abort_plat.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_ABORT_PLAT_H
+#define _CC_PAL_ABORT_PLAT_H
+
+#include "cc_pal_log.h"
+#include <stdlib.h>
+
+void CC_PalAbort(const char * exp);
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_dma_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_dma_plat.h
new file mode 100644
index 0000000..207b5ff
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_dma_plat.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_DMA_PLAT_H
+#define _CC_PAL_DMA_PLAT_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_address_defs.h"
+
+/**
+ * @brief   stub function, the function should initialize the DMA mapping of the platform (if needed)
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] physBuffAddr - physical start address of the memory to map
+ *
+ * @return Start address of contiguous memory
+ */
+extern uint32_t CC_PalDmaInit(uint32_t  buffSize,    /*!< [in] Buffer size in Bytes. */
+                  CCDmaAddr_t  physBuffAddr /*!< [in] Physical start address of the memory to map. */);
+
+/**
+ * @brief   free system resources created in PD_PAL_DmaInit()
+ *
+ *
+ * @return void
+ */
+extern void CC_PalDmaTerminate(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_interrupt_ctrl_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_interrupt_ctrl_plat.h
new file mode 100644
index 0000000..43dc04d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_interrupt_ctrl_plat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_INTERRUPTCTRL_PLAT_H
+#define _CC_PAL_INTERRUPTCTRL_PLAT_H
+
+
+
+/**
+ * @brief This function removes the interrupt handler for
+ * cryptocell interrupts.
+ *
+ */
+void CC_PalFinishIrq(void);
+
+/* @brief
+*
+* @param[in]
+*
+* @param[out]
+*
+* @return - CC_SUCCESS for success, CC_FAIL for failure.
+*/
+CCError_t CC_PalInitIrq(void);
+
+/*!
+ * Busy wait upon Interrupt Request Register (IRR) signals.
+ * This function notifys for any ARM CryptoCell interrupt, it is the caller responsiblity
+ * to verify and prompt the expected case interupt source.
+ *
+ * @param[in] data  - input data for future use
+ * \return  CCError_t   - CC_OK upon success
+ */
+CCError_t CC_PalWaitInterrupt( uint32_t data);
+
+
+#endif /* _CC_PAL_INTERRUPTCTRL_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_log_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_log_plat.h
new file mode 100644
index 0000000..a3f3ef4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_log_plat.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_LOG_PLAT_H_
+#define _CC_PAL_LOG_PLAT_H_
+
+#include "cc_log_mask.h"
+#include <stdio.h>
+
+/************** PRINTF rules ******************/
+#if defined(DEBUG)
+
+void CC_PalLog(int level, const char * format, ...);
+
+#else /* Disable all prints */
+
+#define CC_PalLog(...)  do {} while (0)
+
+#endif
+
+
+#endif /*_CC_PAL_LOG_PLAT_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_malloc_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_malloc_plat.h
new file mode 100644
index 0000000..6580e32
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_malloc_plat.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_MEMALLOC_INT_H
+#define _CC_PAL_MEMALLOC_INT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+
+/**
+* @brief File Description:
+*        This file contains wrappers for memory operations APIs.
+*/
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+ * @brief This function purpose is to allocate a memory buffer according to aSize.
+ *
+ *
+ * @return The function returns a pointer to allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemMallocPlat(size_t  aSize /*!< [in] Number of bytes to allocate. */);
+
+/*!
+ * @brief This function purpose is to reallocate a memory buffer according to aNewSize.
+ *        The content of the old buffer is moved to the new location.
+ *
+ * @return The function returns a pointer to the newly allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemReallocPlat(  void* aBuffer,     /*!< [in] Pointer to allocated buffer. */
+                             size_t  aNewSize   /*!< [in] Number of bytes to reallocate. */);
+
+/*!
+ * @brief This function purpose is to free allocated buffer.
+ *
+ *
+ * @return void.
+ */
+void CC_PalMemFreePlat(void* aBuffer /*!< [in] Pointer to allocated buffer.*/);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_mem_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_mem_plat.h
new file mode 100644
index 0000000..f0aa015
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_mem_plat.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MEM_INT_H
+#define _CC_PAL_MEM_INT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "cc_pal_compiler.h"
+
+/**
+ * @brief File Description:
+ *        This file contains the implementation for memory operations APIs.
+ *        The functions implementations are generally just wrappers to different operating system calls.
+ */
+
+
+/*----------------------------
+  PUBLIC FUNCTIONS
+-------------------------------*/
+
+
+/*!
+ * @brief This function purpose is to compare between two given buffers according to given size.
+ *
+ * @return The return values is according to operating system return values.
+ */
+int32_t CC_PalMemCmpPlat(  const void* aTarget, /*!< [in] The target buffer to compare. */
+                           const void* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */);
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ *
+ * @return void.
+ */
+void* CC_PalMemCopyPlat(     void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                               const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                               size_t      aSize     /*!< [in] Number of bytes to copy. */ );
+
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ * This function Supports overlapped buffers.
+ *
+ * @return void.
+ */
+void CC_PalMemMovePlat(   void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                          const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                          size_t      aSize     /*!< [in] Number of bytes to copy. */);
+
+
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with aChar.
+ *
+ * @return void.
+ */
+void CC_PalMemSetPlat(   void* aTarget, /*!< [out]  The target buffer to set. */
+                         uint8_t aChar, /*!< [in] The char to set into aTarget. */
+                         size_t        aSize  /*!< [in] Number of bytes to set. */);
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with zeroes.
+ *
+ * @return void.
+ */
+void CC_PalMemSetZeroPlat(    void* aTarget, /*!< [out]  The target buffer to set. */
+                              size_t      aSize    /*!< [in] Number of bytes to set. */);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_mutex_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_mutex_plat.h
new file mode 100644
index 0000000..14826f8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_mutex_plat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_MUTEX_PLAT_H
+#define _CC_PAL_MUTEX_PLAT_H
+
+#include "cmsis_os2.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/**
+* @brief File Description:
+*        This file contains functions for resource management (semaphor operations).
+*        The functions implementations are generally just wrappers to different operating system calls.
+*        None of the described functions will check the input parameters so the behavior
+*        of the APIs in illegal parameters case is dependent on the operating system behavior.
+*
+*/
+
+typedef osMutexId_t CC_PalMutex;
+
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_perf_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_perf_plat.h
new file mode 100644
index 0000000..75986dc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_perf_plat.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PAL_PERF_PLAT_H__
+#define _CC_PAL_PERF_PLAT_H__
+
+#include "stdlib.h"
+#include "stdint.h"
+
+typedef unsigned int CCPalPerfData_t;
+
+#endif /*_CC_PAL_PERF_PLAT_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_types_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_types_plat.h
new file mode 100644
index 0000000..c1a066f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/mbedos/cc_pal_types_plat.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*! @file
+@brief This file contains basic platform-dependent type definitions.
+*/
+#ifndef _CC_PAL_TYPES_PLAT_H
+#define _CC_PAL_TYPES_PLAT_H
+/* Host specific types for standard (ISO-C99) compilant platforms */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+typedef uintptr_t       CCVirtAddr_t;
+typedef uint32_t            CCBool_t;
+typedef uint32_t            CCStatus;
+
+#define CCError_t           CCStatus
+#define CC_INFINITE         0xFFFFFFFF
+
+#define CEXPORT_C
+#define CIMPORT_C
+
+#endif /*_CC_PAL_TYPES_PLAT_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_abort_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_abort_plat.h
new file mode 100644
index 0000000..ea5aff2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_abort_plat.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_ABORT_PLAT_H
+#define _CC_PAL_ABORT_PLAT_H
+
+#include "cc_pal_log.h"
+#include <stdlib.h>
+
+void _CC_PalAbort(const char * exp);
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_dma_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_dma_plat.h
new file mode 100644
index 0000000..be1f464
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_dma_plat.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_DMA_PLAT_H
+#define _CC_PAL_DMA_PLAT_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_address_defs.h"
+
+/**
+ * @brief   stub function, the function should initialize the DMA mapping of the platform (if needed)
+ *
+ * @param[in] buffSize - buffer size in Bytes
+ * @param[in] physBuffAddr - physical start address of the memory to map
+ *
+ * @return Virtual start address of contiguous memory
+ */
+extern uint32_t CC_PalDmaInit(uint32_t  buffSize,    /*!< [in] Buffer size in Bytes. */
+                  CCDmaAddr_t  physBuffAddr /*!< [in] Physical start address of the memory to map. */);
+
+/**
+ * @brief   free system resources created in PD_PAL_DmaInit()
+ *
+ *
+ * @return void
+ */
+extern void CC_PalDmaTerminate(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_interrupt_ctrl_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_interrupt_ctrl_plat.h
new file mode 100644
index 0000000..43dc04d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_interrupt_ctrl_plat.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_INTERRUPTCTRL_PLAT_H
+#define _CC_PAL_INTERRUPTCTRL_PLAT_H
+
+
+
+/**
+ * @brief This function removes the interrupt handler for
+ * cryptocell interrupts.
+ *
+ */
+void CC_PalFinishIrq(void);
+
+/* @brief
+*
+* @param[in]
+*
+* @param[out]
+*
+* @return - CC_SUCCESS for success, CC_FAIL for failure.
+*/
+CCError_t CC_PalInitIrq(void);
+
+/*!
+ * Busy wait upon Interrupt Request Register (IRR) signals.
+ * This function notifys for any ARM CryptoCell interrupt, it is the caller responsiblity
+ * to verify and prompt the expected case interupt source.
+ *
+ * @param[in] data  - input data for future use
+ * \return  CCError_t   - CC_OK upon success
+ */
+CCError_t CC_PalWaitInterrupt( uint32_t data);
+
+
+#endif /* _CC_PAL_INTERRUPTCTRL_H */
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_log_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_log_plat.h
new file mode 100644
index 0000000..2cfbefc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_log_plat.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_LOG_PLAT_H_
+#define _CC_PAL_LOG_PLAT_H_
+
+#include "cc_log_mask.h"
+#include <stdio.h>
+
+
+
+void CC_PalLog(int level, const char * format, ...);
+
+
+
+
+#endif /*_CC_PAL_LOG_PLAT_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_malloc_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_malloc_plat.h
new file mode 100644
index 0000000..00ab33a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_malloc_plat.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MEMALLOC_INT_H
+#define _CC_PAL_MEMALLOC_INT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+/**
+* @brief File Description:
+*        This file contains wrappers for memory operations APIs.
+*/
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+/*!
+ * @brief This function purpose is to allocate a memory buffer according to aSize.
+ *
+ *
+ * @return The function returns a pointer to allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemMallocPlat(size_t  aSize /*!< [in] Number of bytes to allocate. */);
+
+/*!
+ * @brief This function purpose is to reallocate a memory buffer according to aNewSize.
+ *        The content of the old buffer is moved to the new location.
+ *
+ * @return The function returns a pointer to the newly allocated buffer or NULL if allocation failed.
+ */
+void* CC_PalMemReallocPlat(  void* aBuffer,     /*!< [in] Pointer to allocated buffer. */
+                             size_t  aNewSize   /*!< [in] Number of bytes to reallocate. */);
+
+/*!
+ * @brief This function purpose is to free allocated buffer.
+ *
+ *
+ * @return void.
+ */
+void CC_PalMemFreePlat(void* aBuffer /*!< [in] Pointer to allocated buffer.*/);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_mem_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_mem_plat.h
new file mode 100644
index 0000000..ade9712
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_mem_plat.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MEM_PLAT_H
+#define _CC_PAL_MEM_PLAT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+
+
+/**
+ * @brief File Description:
+ *        This file contains the implementation for memory operations APIs.
+ *        The functions implementations are generally just wrappers to different operating system calls.
+ */
+
+
+/*----------------------------
+  PUBLIC FUNCTIONS
+-------------------------------*/
+
+/*!
+ * @brief This function purpose is to compare between two given buffers according to given size.
+ *
+ * @return The return values is according to operating system return values.
+ */
+int32_t CC_PalMemCmpPlat(  const void* aTarget, /*!< [in] The target buffer to compare. */
+                           const void* aSource, /*!< [in] The Source buffer to compare to. */
+                           size_t      aSize    /*!< [in] Number of bytes to compare. */);
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ *
+ * @return void.
+ */
+void* CC_PalMemCopyPlat(     void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                               const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                               size_t      aSize     /*!< [in] Number of bytes to copy. */ );
+
+
+/*!
+ * @brief This function purpose is to copy aSize bytes from source buffer to destination buffer.
+ * This function Supports overlapped buffers.
+ *
+ * @return void.
+ */
+void CC_PalMemMovePlat(   void* aDestination, /*!< [out] The destination buffer to copy bytes to. */
+                          const void* aSource,      /*!< [in] The Source buffer to copy from. */
+                          size_t      aSize     /*!< [in] Number of bytes to copy. */);
+
+
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with aChar.
+ *
+ * @return void.
+ */
+void CC_PalMemSetPlat(   void* aTarget, /*!< [out]  The target buffer to set. */
+                         uint8_t aChar, /*!< [in] The char to set into aTarget. */
+                         size_t        aSize  /*!< [in] Number of bytes to set. */);
+
+/*!
+ * @brief This function purpose is to set aSize bytes in the given buffer with zeroes.
+ *
+ * @return void.
+ */
+void CC_PalMemSetZeroPlat(    void* aTarget, /*!< [out]  The target buffer to set. */
+                              size_t      aSize    /*!< [in] Number of bytes to set. */);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_mutex_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_mutex_plat.h
new file mode 100644
index 0000000..d0dc973
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_mutex_plat.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_MUTEX_PLAT_H
+#define _CC_PAL_MUTEX_PLAT_H
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+/**
+* @brief File Description:
+*        This file contains functions for resource management (semaphor operations).
+*        The functions implementations are generally just wrappers to different operating system calls.
+*        None of the described functions will check the input parameters so the behavior
+*        of the APIs in illegal parameters case is dependent on the operating system behavior.
+*
+*/
+
+typedef uint32_t CC_PalMutex;
+
+
+
+/*----------------------------
+      PUBLIC FUNCTIONS
+-----------------------------------*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_perf_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_perf_plat.h
new file mode 100644
index 0000000..caaa4dc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_perf_plat.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_PAL_PERF_PLAT_H__
+#define _CC_PAL_PERF_PLAT_H__
+
+typedef unsigned int CCPalPerfData_t;
+
+/**
+ * @brief   DSM environment bug - sometimes very long write operation.
+ *     to overcome this bug we added while to make sure write opeartion is completed
+ *
+ * @param[in]
+ * *
+ * @return None
+ */
+void CC_PalDsmWorkarround();
+
+
+#endif /*_CC_PAL_PERF_PLAT_H__*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_types_plat.h b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_types_plat.h
new file mode 100644
index 0000000..2d90da1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/pal/no_os/cc_pal_types_plat.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*! @file
+@brief This file contains basic platform-dependent type definitions.
+*/
+#ifndef _CC_PAL_TYPES_PLAT_H
+#define _CC_PAL_TYPES_PLAT_H
+/* Host specific types for standard (ISO-C99) compliant platforms */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+/*! Type definition for virtual address. */
+typedef uintptr_t       CCVirtAddr_t;
+/*! Type Definition for boolean variable. */
+typedef uint32_t            CCBool_t;
+/*! Type definition for return status. */
+typedef uint32_t            CCStatus;
+
+/*! Type definition for error return. */
+#define CCError_t           CCStatus
+/*! Defines inifinite value, used to define unlimited time frame. */
+#define CC_INFINITE         0xFFFFFFFF
+
+/*! Type definition for C export. */
+#define CEXPORT_C
+/*! Type definition for C import. */
+#define CIMPORT_C
+
+#endif /*_CC_PAL_TYPES_PLAT_H*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_address_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_address_defs.h
new file mode 100644
index 0000000..64789da
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_address_defs.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_general_defs
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains general definitions for CryptoCell APIs.
+ */
+
+
+
+#ifndef _CC_ADDRESS_DEFS_H
+#define _CC_ADDRESS_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Defines ******************************/
+
+/* Address types within CryptoCell. */
+/*! The SRAM address type. */
+typedef uint32_t CCSramAddr_t;
+/*! The DMA address type. */
+typedef uint32_t CCDmaAddr_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+@}
+ */
+
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_crypto_boot_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_crypto_boot_defs.h
new file mode 100644
index 0000000..a2802c0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_crypto_boot_defs.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_CRYPTO_BOOT_DEFS_H
+#define _CC_CRYPTO_BOOT_DEFS_H
+
+/*! @file
+@brief This file contains Secure Boot And Secure Debug definitions.
+*/
+#include "cc_pal_types.h"
+/*! Maximal size of secure boot's nonce. */
+#define CC_SB_MAX_SIZE_NONCE_BYTES      (2*sizeof(uint32_t))
+
+/*! HASH boot key definition. */
+typedef enum {
+    CC_SB_HASH_BOOT_KEY_0_128B  = 0,        /*!< 128-bit truncated SHA256 digest of public key 0. */
+    CC_SB_HASH_BOOT_KEY_1_128B  = 1,        /*!< 128-bit truncated SHA256 digest of public key 1. */
+    CC_SB_HASH_BOOT_KEY_256B    = 2,        /*!< 256-bit SHA256 digest of public key. */
+    CC_SB_HASH_BOOT_NOT_USED    = 0xF,
+    CC_SB_HASH_MAX_NUM          = 0x7FFFFFFF,   /*!\internal use external 128-bit truncated SHA256 digest */
+}CCSbPubKeyIndexType_t;
+
+
+/*! SW image code encryption type definition. */
+typedef enum {
+    CC_SB_NO_IMAGE_ENCRYPTION   = 0,        /*!< Plain SW image. */
+    CC_SB_ICV_CODE_ENCRYPTION   = 1,        /*!< use Kceicv for cipher SW image. */
+    CC_SB_OEM_CODE_ENCRYPTION   = 2,        /*!< use Kce for cipher SW image. */
+    CC_SB_CODE_ENCRYPTION_MAX_NUM   = 0x7FFFFFFF,   /*!\internal NA */
+}CCswCodeEncType_t;
+
+/*! SW image load and verify scheme. */
+typedef enum {
+    CC_SB_LOAD_AND_VERIFY       = 0,        /*!< Load & Verify from flash to memory. */
+    CC_SB_VERIFY_ONLY_IN_FLASH  = 1,        /*!< Verify only in flash. */
+    CC_SB_VERIFY_ONLY_IN_MEM    = 2,        /*!< Verify only in memory. */
+    CC_SB_LOAD_ONLY             = 3,        /*!< Load only from flash to memory. */
+    CC_SB_LOAD_VERIFY_MAX_NUM   = 0x7FFFFFFF,   /*!\internal NA */
+}CCswLoadVerifyScheme_t;
+
+/*! SW image cryptographic type. */
+typedef enum {
+    CC_SB_HASH_ON_DECRYPTED_IMAGE   = 0,        /*!< AES to HASH. */
+    CC_SB_HASH_ON_ENCRYPTED_IMAGE   = 1,        /*!< AES and HASH. */
+    CC_SB_CRYPTO_TYPE_MAX_NUM   = 0x7FFFFFFF,   /*!\internal NA */
+}CCswCryptoType_t;
+
+/*! Table nonce used in composing IV for SW-component decryption. */
+typedef uint8_t CCSbNonce_t[CC_SB_MAX_SIZE_NONCE_BYTES];
+
+/*! SW components data.*/
+typedef struct {
+    /*! Num of SW components. */
+    uint32_t  numOfSwComps;
+
+    /*! SW image code encryption type. */
+    CCswCodeEncType_t swCodeEncType;
+
+    /*! SW image load & verify scheme. */
+    CCswLoadVerifyScheme_t swLoadVerifyScheme;
+
+    /*! SW image crypto type. */
+    CCswCryptoType_t swCryptoType;
+
+    /*! Nonce. */
+    CCSbNonce_t nonce;
+
+    /*! Pointer to start of sw components data. */
+    uint8_t *pSwCompsData;
+
+}CCSbCertParserSwCompsInfo_t;
+
+/*! SW version */
+typedef struct {
+    CCSbPubKeyIndexType_t keyIndex;     /*!< Enumeration defining the key hash to retrieve: 128-bit HBK0, 128-bit HBK1, or 256-bit HBK. */
+    uint32_t swVersion;         /*!< Sw version.*/
+}CCSbSwVersion_t;
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_ecpki_domains_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_ecpki_domains_defs.h
new file mode 100644
index 0000000..6178fe4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_ecpki_domains_defs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/*!
+ @addtogroup cc_ecpki_domains_defs
+
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains CryptoCell ECPKI domains supported by the project.
+ */
+
+#ifndef _CC_ECPKI_DOMAIN_DEFS_H
+#define _CC_ECPKI_DOMAIN_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_ecpki_domain_secp192r1.h"
+#include "cc_ecpki_domain_secp224r1.h"
+#include "cc_ecpki_domain_secp256r1.h"
+#include "cc_ecpki_domain_secp521r1.h"
+#include "cc_ecpki_domain_secp192k1.h"
+#include "cc_ecpki_domain_secp224k1.h"
+#include "cc_ecpki_domain_secp256k1.h"
+#include "cc_ecpki_domain_secp384r1.h"
+
+/*! Definition of the domain-retrieval function. */
+typedef const CCEcpkiDomain_t * (*getDomainFuncP)(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_general_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_general_defs.h
new file mode 100644
index 0000000..1222e21
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_general_defs.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_general_defs
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains general definitions of the CryptoCell runtime SW APIs.
+ */
+
+
+#ifndef _CC_GENERAL_DEFS_H
+#define _CC_GENERAL_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_hash_defs.h"
+
+/************************ Defines ******************************/
+/*! Hash parameters for HMAC operation. */
+typedef struct {
+    /*! The size of the HMAC hash result. */
+    uint16_t hashResultSize;
+    /*! The hash operation mode. */
+    CCHashOperationMode_t hashMode;
+}HmacHash_t;
+
+/*! The maximal size of the hash string. */
+#define CC_HASH_NAME_MAX_SIZE  10
+/*! Hash parameters for HMAC operation. */
+extern const HmacHash_t HmacHashInfo_t[CC_HASH_NumOfModes];
+/*! Supported hash modes. */
+extern const uint8_t HmacSupportedHashModes_t[CC_HASH_NumOfModes];
+/*! Hash string names. */
+extern const char HashAlgMode2mbedtlsString[CC_HASH_NumOfModes][CC_HASH_NAME_MAX_SIZE];
+
+
+/* general definitions */
+/*-------------------------*/
+/*! Maximal size of AES HUK in bytes. */
+#define CC_AES_KDR_MAX_SIZE_BYTES   32
+/*! Maximal size of AES HUK in words. */
+#define CC_AES_KDR_MAX_SIZE_WORDS   (CC_AES_KDR_MAX_SIZE_BYTES/sizeof(uint32_t))
+
+
+/* Life-cycle states. */
+/*! The Chip Manufacturer (CM) LCS value. */
+#define CC_LCS_CHIP_MANUFACTURE_LCS     0x0
+/*! The Secure LCS value. */
+#define CC_LCS_SECURE_LCS               0x5
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_int_general_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_int_general_defs.h
new file mode 100644
index 0000000..20f0099
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_int_general_defs.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_INT_GENERAL_DEFS_H
+#define _CC_INT_GENERAL_DEFS_H
+
+/*!
+@file
+@brief This file contains internal general definitions of the CryptoCell runtime SW APIs.
+@defgroup cc_general_defs CryptoCell general definitions
+@{
+@ingroup cryptocell_api
+
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/************************ Macros ******************************/
+
+/* check if fatal error bit is set to ON */
+#define CC_IS_FATAL_ERR_ON(rc)\
+do {\
+        uint32_t regVal = 0;\
+    regVal = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));\
+            rc = CC_REG_FLD_GET(0, HOST_AO_LOCK_BITS, HOST_FATAL_ERR, regVal);\
+            rc = (rc == 1)?CC_TRUE:CC_FALSE;\
+}while(0)
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_otp_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_otp_defs.h
new file mode 100644
index 0000000..dd3634a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_otp_defs.h
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_OTP_DEFS_H
+#define _CC_OTP_DEFS_H
+
+/*!
+@file
+@brief This file contains general OTP definitions and memory layout.
+*/
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/* NVM definitions */
+#define CC_OTP_BASE_ADDR            0x2000UL
+#define CC_OTP_START_OFFSET         0x00UL
+#define CC_OTP_LAST_OFFSET          0x7FFUL
+
+/* [0x00-0x07] Device root key (HUK) */
+#define CC_OTP_HUK_OFFSET           0x00UL
+#define CC_OTP_HUK_SIZE_IN_WORDS                8
+
+/* [0x08-0x0B] ICV provisioning secret (KPICV) */
+#define CC_OTP_KPICV_OFFSET         0x08UL
+#define CC_OTP_KPICV_SIZE_IN_WORDS              4
+
+/* [0x0C-0x0F] ICV Code encryption key (KCEICV) */
+#define CC_OTP_KCEICV_OFFSET            0x0CUL
+#define CC_OTP_KCEICV_SIZE_IN_WORDS             4
+
+/* [0x10] Manufacturer-programmed flags */
+#define CC_OTP_MANUFACTURE_FLAG_OFFSET      0x10UL
+
+/* [0x11-0x18] Root-of-Trust Public Key.
+* May be used in one of the following configurations:
+* - A single 256-bit SHA256 digest of the Secure Boot public key (HBK).                                        :
+* - Two 128-bit truncated SHA256 digests of Secure Boot public keys 0 and 1 (HBK0, HBK1) */
+#define CC_OTP_HBK_OFFSET           0x11UL
+#define CC_OTP_HBK_SIZE_IN_WORDS            8
+#define CC_OTP_HBK0_OFFSET          0x11UL
+#define CC_OTP_HBK0_SIZE_IN_WORDS           4
+#define CC_OTP_HBK1_OFFSET          0x15UL
+#define CC_OTP_HBK1_SIZE_IN_WORDS           4
+
+/* [0x19-0x1C] OEM provisioning secret (Kcp) */
+#define CC_OTP_KCP_OFFSET           0x19UL
+#define CC_OTP_KCP_SIZE_IN_WORDS                4
+
+/* OEM Code encryption key (KCE) */
+#define CC_OTP_KCE_OFFSET           0x1DUL
+#define CC_OTP_KCE_SIZE_IN_WORDS                4
+
+/* OEM-programmed flags */
+#define CC_OTP_OEM_FLAG_OFFSET          0x21UL
+
+/* HBK Trusted Firmware minimum version (anti-rollback counter) */
+#define CC_OTP_HBK_MIN_VERSION_OFFSET       0x22UL
+#define CC_OTP_HBK_MIN_VERSION_SIZE_IN_WORDS    5
+
+/* HBK0 Trusted Firmware minimum version (anti-rollback counter) */
+#define CC_OTP_HBK0_MIN_VERSION_OFFSET      0x22UL
+#define CC_OTP_HBK0_MIN_VERSION_SIZE_IN_WORDS   2
+
+/* HBK1 Trusted Firmware minimum version (anti-rollback counter) */
+#define CC_OTP_HBK1_MIN_VERSION_OFFSET      0x24UL
+#define CC_OTP_HBK1_MIN_VERSION_SIZE_IN_WORDS   3
+
+/* General purpose configuration flags */
+#define CC_OTP_ICV_GENERAL_PURPOSE_FLAG_OFFSET  0x27UL
+#define CC_OTP_ICV_GENERAL_PURPOSE_FLAG_SIZE_IN_WORDS   1
+
+/* OTP DCU lock mask */
+#define CC_OTP_DCU_OFFSET           0x28UL
+#define CC_OTP_DCU_SIZE_IN_WORDS                4
+
+/* First stage secure boot loader code and data sections (optional) */
+#define CC_OTP_SB_LOADER_CODE_OFFSET        0x2CUL
+
+
+/* Manufacturer-programmed flags */
+
+/* [7:0] Number of "0" bits in HUK */
+#define CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SHIFT        0
+#define CC_OTP_MANUFACTURE_FLAG_HUK_ZERO_BITS_BIT_SIZE         8
+
+/* [14:8] Number of "0" bits in KPICV (128 bit) */
+#define CC_OTP_MANUFACTURE_FLAG_KPICV_ZERO_BITS_BIT_SHIFT      8
+#define CC_OTP_MANUFACTURE_FLAG_KPICV_ZERO_BITS_BIT_SIZE       7
+
+/* [15:15] KPICV "Not In Use" bit */
+#define CC_OTP_MANUFACTURE_FLAG_KPICV_NOT_IN_USE_BIT_SHIFT     15
+#define CC_OTP_MANUFACTURE_FLAG_KPICV_NOT_IN_USE_BIT_SIZE       1
+
+/* [22:16] Number of "0" bits in KCEICV */
+#define CC_OTP_MANUFACTURE_FLAG_KCEICV_ZERO_BITS_BIT_SHIFT     16
+#define CC_OTP_MANUFACTURE_FLAG_KCEICV_ZERO_BITS_BIT_SIZE       7
+
+/* [23:23] KCEICV "Not In Use" bit */
+#define CC_OTP_MANUFACTURE_FLAG_KCEICV_NOT_IN_USE_BIT_SHIFT    23
+#define CC_OTP_MANUFACTURE_FLAG_KCEICV_NOT_IN_USE_BIT_SIZE      1
+
+/* [30:24] Number of "0" bits in HBK0 (in case it is used as 4 words of the ICV) */
+#define CC_OTP_MANUFACTURE_FLAG_HBK0_ZERO_BITS_BIT_SHIFT       24
+#define CC_OTP_MANUFACTURE_FLAG_HBK0_ZERO_BITS_BIT_SIZE         7
+
+/* [31:31] HBK0 "Not In Use" bit */
+#define CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SHIFT      31
+#define CC_OTP_MANUFACTURE_FLAG_HBK0_NOT_IN_USE_BIT_SIZE        1
+
+
+/* OEM-programmed flags */
+
+/* [7:0] Number of "0" bits in HBK1/HBK (128/256 bits public key) */
+#define CC_OTP_OEM_FLAG_HBK_ZERO_BITS_BIT_SHIFT         0
+#define CC_OTP_OEM_FLAG_HBK_ZERO_BITS_BIT_SIZE          8
+#define CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SHIFT        0
+#define CC_OTP_OEM_FLAG_HBK1_ZERO_BITS_BIT_SIZE         8
+
+/* [14:8] Number of "0" bits in KCP (128 bit) */
+#define CC_OTP_OEM_FLAG_KCP_ZERO_BITS_BIT_SHIFT         8
+#define CC_OTP_OEM_FLAG_KCP_ZERO_BITS_BIT_SIZE          7
+
+/* [15:15] KCP "Not In Use" bit */
+#define CC_OTP_OEM_FLAG_KCP_NOT_IN_USE_BIT_SHIFT       15
+#define CC_OTP_OEM_FLAG_KCP_NOT_IN_USE_BIT_SIZE         1
+
+/* [22:16] Number of "0" bits in KCE */
+#define CC_OTP_OEM_FLAG_KCE_ZERO_BITS_BIT_SHIFT        16
+#define CC_OTP_OEM_FLAG_KCE_ZERO_BITS_BIT_SIZE          7
+
+/* [23:23] KCE "Not In Use" bit */
+#define CC_OTP_OEM_FLAG_KCE_NOT_IN_USE_BIT_SHIFT       23
+#define CC_OTP_OEM_FLAG_KCE_NOT_IN_USE_BIT_SIZE         1
+
+/* [29:24] Reserved */
+
+/* [30:30] OEM RMA mode flag */
+#define CC_OTP_OEM_FLAG_OEM_RMA_MODE_BIT_SHIFT         30
+#define CC_OTP_OEM_FLAG_OEM_RMA_MODE_BIT_SIZE           1
+
+/* [31:31] ICV RMA mode flag */
+#define CC_OTP_OEM_FLAG_ICV_RMA_MODE_BIT_SHIFT         31
+#define CC_OTP_OEM_FLAG_ICV_RMA_MODE_BIT_SIZE           1
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_pka_hw_plat_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_pka_hw_plat_defs.h
new file mode 100644
index 0000000..3285a40
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_pka_hw_plat_defs.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_pka_hw_plat_defs
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains the platform-dependent definitions of the CryptoCell PKA APIs.
+ */
+
+#ifndef _CC_PKA_HW_PLAT_DEFS_H
+#define _CC_PKA_HW_PLAT_DEFS_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_types.h"
+
+/*! The size of the PKA engine word. */
+#define CC_PKA_WORD_SIZE_IN_BITS            64
+/*! The maximal supported size of modulus in bits. */
+#define CC_SRP_MAX_MODULUS_SIZE_IN_BITS       3072
+/*! The maximal supported size of modulus in RSA in bits. */
+#define CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS         4096
+/*! The maximal supported size of key-generation in RSA in bits. */
+#define CC_RSA_MAX_KEY_GENERATION_HW_SIZE_BITS         3072
+/*! The maximal supported size of modulus in RSA in words. */
+#define CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_WORDS        CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / CC_BITS_IN_32BIT_WORD
+
+/*! The size of the RSA public modulus key of the Secure Boot or Secure Debug
+certificate in bits. */
+#define SB_CERT_RSA_KEY_SIZE_IN_BITS     3072UL
+/*! The size of the RSA public modulus key of the Secure Boot or Secure Debug
+certificate in bytes. */
+#define SB_CERT_RSA_KEY_SIZE_IN_BYTES    (SB_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_BYTE)
+/*! The size of the RSA public modulus key of the Secure Boot or Secure Debug
+certificate in words. */
+#define SB_CERT_RSA_KEY_SIZE_IN_WORDS    (SB_CERT_RSA_KEY_SIZE_IN_BITS/CC_BITS_IN_32BIT_WORD)
+
+/*! The maximal count of extra bits in PKA operations. */
+#define PKA_EXTRA_BITS  8
+/*! The number of memory registers in PKA operations. */
+#define PKA_MAX_COUNT_OF_PHYS_MEM_REGS  32
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif //_CC_PKA_HW_PLAT_DEFS_H
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_production_asset.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_production_asset.h
new file mode 100644
index 0000000..188e8da
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_production_asset.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_PROD_ASSET_H
+#define  _CC_PROD_ASSET_H
+
+/*!
+@file
+@brief This file contains the functions and definitions for the OEM Asset provisioning.
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "cc_bitops.h"
+#include "cc_prod.h"
+
+#define PROD_ASSET_PROV_TOKEN   0x50726F64UL   // "Prov"
+#define PROD_ASSET_PROV_VERSION     0x10000UL
+
+// parameters for generating the temporary key
+#define PROD_KEY_RTL_KEY_SIZE       16
+#define PROD_KEY_TMP_KEY_SIZE       16
+#define PROD_KEY_TMP_LABEL_SIZE     7
+#define PROD_ICV_KEY_TMP_LABEL      "KEY ICV"
+#define PROD_OEM_KEY_TMP_LABEL       "KEY OEM"
+#define PROD_KEY_TMP_CONTEXT_SIZE   16
+#define PROD_KEY_TMP_CONTEXT_WORD_SIZE  (PROD_KEY_TMP_CONTEXT_SIZE/CC_32BIT_WORD_SIZE)
+
+// parameters for generating the provisioning key
+#define PROD_KPROV_KEY_SIZE     16
+#define PROD_KPROV_LABEL_SIZE       1
+#define PROD_LABEL  "P"
+#define PROD_KPROV_CONTEXT_SIZE     4
+#define PROD_ICV_ENC_CONTEXT    "EICV"
+#define PROD_ICV_PROV_CONTEXT  "PICV"
+#define PROD_OEM_ENC_CONTEXT    "Kce "
+#define PROD_OEM_PROV_CONTEXT  "Kcp "
+
+// production asset patameters
+#define PROD_ASSET_NONCE_SIZE   12
+#define PROD_ASSET_TAG_SIZE     16
+#define PROD_ASSET_RESERVED1_VAL    0x52657631UL  // Rev1
+#define PROD_ASSET_RESERVED2_VAL    0x52657632UL  // Rev2
+#define PROD_ASSET_RESERVED_WORD_SIZE   2
+#define PROD_ASSET_RESERVED_SIZE    (PROD_ASSET_RESERVED_WORD_SIZE*CC_32BIT_WORD_SIZE)
+#define PROD_ASSET_ADATA_SIZE   (3*CC_32BIT_WORD_SIZE+PROD_ASSET_RESERVED_SIZE)  // token||version||size||reserved
+
+typedef enum {
+    PROD_ASSET_ENTITY_TYPE_ICV  = 1,
+    PROD_ASSET_ENTITY_TYPE_OEM  = 2,
+    PROD_ASSET_ENTITY_TYPE_RESERVED     = 0x7FFFFFFF,
+}CCProductionEntityType_t;
+
+typedef enum {
+    PROD_ASSET_TYPE_KCE     = 1,
+    PROD_ASSET_TYPE_KCP     = 2,
+    PROD_ASSET_TYPE_KEY_RESERVED    = 0x7FFFFFFF,
+}CCProductionAssetKeyType_t;
+
+
+typedef struct {
+        uint32_t  token;
+        uint32_t  version;
+        uint32_t  assetSize;
+        uint32_t  reserved[PROD_ASSET_RESERVED_WORD_SIZE];
+        uint8_t   nonce[PROD_ASSET_NONCE_SIZE];
+        uint8_t   encAsset[PROD_ASSET_SIZE+PROD_ASSET_TAG_SIZE];
+}CCProdAssetPkg_t;  // Total size must be PROD_ASSET_PKG_SIZE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_CC_PROD_ASSET_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_sec_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_sec_defs.h
new file mode 100644
index 0000000..bd731a4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_sec_defs.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_SEC_DEFS_H
+#define _CC_SEC_DEFS_H
+
+/*!
+@file
+@brief This file contains general hash definitions and types.
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! The hashblock size in words. */
+#define HASH_BLOCK_SIZE_IN_WORDS                16
+
+/*! SHA256 result size in words. */
+#define HASH_RESULT_SIZE_IN_WORDS               8
+/*! SHA256 result size in Bytes. */
+#define HASH_RESULT_SIZE_IN_BYTES               32
+
+/*! Defines the hash result array. */
+typedef uint32_t CCHashResult_t[HASH_RESULT_SIZE_IN_WORDS];
+
+/*! Definition for converting pointer to address. */
+#define CONVERT_TO_ADDR(ptr)    (unsigned long)ptr
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_sram_map.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_sram_map.h
new file mode 100644
index 0000000..74f8adf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_sram_map.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*!
+ @addtogroup cc_sram_map
+ @{
+ */
+
+/*!
+ @file
+ @brief This file contains internal SRAM mapping definitions.
+ */
+
+#ifndef _CC_SRAM_MAP_H_
+#define _CC_SRAM_MAP_H_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*! The base address of the PKA in the PKA SRAM. */
+#define CC_SRAM_PKA_BASE_ADDRESS                                0x0
+/*! The size of the PKA SRAM in KB. */
+#define CC_PKA_SRAM_SIZE_IN_KBYTES                6
+
+/*! The SRAM address of the RND. */
+#define CC_SRAM_RND_HW_DMA_ADDRESS                              0x0
+/*! Addresses 0K-2KB in SRAM. Reserved for RND operations. */
+#define CC_SRAM_RND_MAX_SIZE                                    0x800
+/*! The maximal size of SRAM. */
+#define CC_SRAM_MAX_SIZE                                        0x1000
+
+#ifdef __cplusplus
+}
+#endif
+
+/*!
+ @}
+ */
+#endif /*_CC_SRAM_MAP_H_*/
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_util_apbc.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_util_apbc.h
new file mode 100644
index 0000000..1a11204
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_util_apbc.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_UTIL_APBC_H_
+#define _CC_UTIL_APBC_H_
+
+/*!
+@file
+@defgroup cc_apbc_defs CryptoCell APBC macros
+@brief This file contains APBC definitions.
+@{
+@ingroup cryptocell_api
+
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_apbc.h"
+
+/*! Get APBC Access counter. Return number of active APBC accesses operations */
+#define CC_APBC_CNTR_GET   CC_PalApbcCntrValue()
+
+/*! Increment APBC access counter. */
+#define CC_APBC_ACCESS_INC  CC_PalApbcModeSelect(CC_TRUE)
+
+/*! Decrement APBC access counter. */
+#define CC_APBC_ACCESS_DEC  CC_PalApbcModeSelect(CC_FALSE)
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /*_CC_UTIL_APBC_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_util_pm.h b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_util_pm.h
new file mode 100644
index 0000000..a5f1408
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/proj/cc3x/cc_util_pm.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _CC_PM_DEFS_H_
+#define _CC_PM_DEFS_H_
+
+/*!
+@file
+@defgroup cc_pm_defs CryptoCell power management macroes
+@brief This file contains power management definitions.
+@{
+@ingroup cryptocell_api
+
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "cc_pal_pm.h"
+
+/*! Get ARM Cerberus status. Return number of active registered CC operations */
+#define CC_STATUS_GET   CC_PalPowerSaveModeStatus()
+
+/*! Notify ARM Cerberus is active. */
+#define CC_IS_WAKE  CC_PalPowerSaveModeSelect(CC_FALSE)
+
+/*! Notify ARM Cerberus is idle. */
+#define CC_IS_IDLE  CC_PalPowerSaveModeSelect(CC_TRUE)
+
+
+#ifdef __cplusplus
+}
+#endif
+/**
+@}
+ */
+#endif /*_CC_PM_DEFS_H_*/
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_asset_prov.h b/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_asset_prov.h
new file mode 100644
index 0000000..28c0f8a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_asset_prov.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_ASSET_PROV_H
+#define  _CC_ASSET_PROV_H
+
+/*!
+@file
+@brief This file contains the functions and definitions for the OEM Asset provisioning.
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "cc_bitops.h"
+
+#define ASSET_PROV_TOKEN    0x41736574UL
+#define ASSET_PROV_VERSION      0x10000UL
+
+#define KPICV_KEY_SIZE      16
+#define KPROV_KEY_SIZE      16
+#define KPROV_DATA_IN_SIZE  8
+#define ASSET_NONCE_SIZE    12
+#define ASSET_RESERVED_SIZE     8
+#define ASSET_RESERVED_WORD_SIZE    (8/CC_32BIT_WORD_SIZE)
+#define ASSET_TAG_SIZE      16
+#define ASSET_BLOCK_SIZE    16
+#define MAX_ASSET_SIZE      512
+#define ASSET_ADATA_SIZE    (3*CC_32BIT_WORD_SIZE+ASSET_RESERVED_SIZE)  // token||version||assetId||reserved
+
+typedef struct {
+        uint32_t  token;
+        uint32_t  version;
+        uint32_t  assetSize;
+        uint32_t  reserved[ASSET_RESERVED_WORD_SIZE];
+        uint8_t   nonce[ASSET_NONCE_SIZE];
+        uint8_t   encAsset[MAX_ASSET_SIZE+ASSET_TAG_SIZE];
+}CCBsvAssetProv_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*_CC_ASSET_PROV_H */
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_crypto_x509_common_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_crypto_x509_common_defs.h
new file mode 100644
index 0000000..7111cb9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_crypto_x509_common_defs.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_CRYPTO_X509_COMMON_DEFS_H
+#define _CC_CRYPTO_X509_COMMON_DEFS_H
+
+/*!
+@file
+@brief This file contains definitions used in the X509 certificates.
+*/
+
+/*!  MAX size of issuer name string. */
+#define X509_ISSUER_NAME_MAX_STRING_SIZE     64
+/*!  MAX size of subject name string. */
+#define X509_SUBJECT_NAME_MAX_STRING_SIZE    64
+/*!  MAX size of  validity period string. */
+#define X509_VALIDITY_PERIOD_MAX_STRING_SIZE  16
+/*! MAX size of a single user's data buffer */
+#define X509_USER_DATA_MAX_SIZE_BYTES         64
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_crypto_x509_defs.h b/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_crypto_x509_defs.h
new file mode 100644
index 0000000..9d91423
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/sbrom/cc_crypto_x509_defs.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_CRYPTO_X509_DEFS_H
+#define _CC_CRYPTO_X509_DEFS_H
+
+#include "stdint.h"
+
+#define CERTIFICATE_VALIDITY_ENDLESS  0
+#define CC_X509_CERT_PKG_TOKEN  0x43504B47
+#define CC_X509_CERT_PKG_VERSION   0x01000000
+#define CC_X509_MAX_CERT_SIZE   0xFFFF
+
+/* CC object Id's */
+/* all object ID's under CC category */
+#define CC_X509_OBJ_ID_DX       0x2
+/* enable user category */
+#define CC_X509_OBJ_ID_ANY      0x14
+/* MAX NONCE size */
+#define CC_X509_MAX_NONCE_SIZE_BYTES    8
+
+
+#define CC_X509_CERT_ISSUER_NAME    "ARM"
+#define CC_X509_CERT_KEY_CERT       "KeyCert"
+#define CC_X509_CERT_CNT_CERT       "CntCert"
+#define CC_X509_CERT_ENABLER_CERT       "EnablerDbg"
+#define CC_X509_CERT_DEVELOPER_CERT     "DeveloperDbg"
+
+/* certificate type category */
+typedef enum {
+    CC_X509_CERT_TYPE_MIN = 0x0,
+    CC_X509_CERT_TYPE_KEY = 0x1,    /* 0x1 */
+    CC_X509_CERT_TYPE_CONTENT,      /* 0x2 */
+    CC_X509_CERT_TYPE_ENABLER_DBG,     /* 0x3 */
+    CC_X509_CERT_TYPE_DEVELOPER_DBG,     /* 0x4 */
+    CC_X509_CERT_TYPE_MAX,
+    CC_X509_CERT_TYPE_RESERVED = 0xFF
+}CCX509CertType_t;
+
+
+/* certificate type category */
+typedef enum {
+    CC_X509_PKG_TYPE_MIN = 0x0,
+    CC_X509_PKG_TYPE_KEY = 0x1, /* 0x1 */
+    CC_X509_PKG_TYPE_CONTENT,       /* 0x2 */
+    CC_X509_PKG_TYPE_ENABLER_DBG,   /* 0x3 */
+    CC_X509_PKG_TYPE_DEVELOPER_DBG, /* 0x4 */
+    CC_X509_PKG_TYPE_MAX,
+    CC_X509_PKG_TYPE_RESERVED = 0xFF
+}CCX509PkgType_t;
+
+#ifdef CC_SB_SUPPORT_IOT
+/* specific certificate extension category */
+typedef enum {
+    CC_X509_ID_EXT_NONE = 0,
+    CC_X509_ID_EXT_PROPRIETARY_HEADER,
+    CC_X509_ID_EXT_PUB_KEY_NP,
+    CC_X509_ID_EXT_KEY_CERT_MAIN_VAL,
+    CC_X509_ID_EXT_CONTENT_CERT_MAIN_VAL,
+    CC_X509_ID_EXT_ENABLER_CERT_MAIN_VAL,
+    CC_X509_ID_EXT_DEVELOPER_CERT_MAIN_VAL,
+    CC_X509_ID_EXT_MAX,
+    CC_X509_ID_EXT_RESERVED = 0xFF
+}CCX509ExtType_t;
+
+#define CC3X_X509_CERT_EXT_NUMBER 3
+#else
+/* specific certificate extension category */
+typedef enum {
+    CC_X509_ID_EXT_NONE = 0,                 /*0x0 */
+    CC_X509_ID_EXT_NV_COUNTER_ID = 0x1,      /*0x1 */
+    CC_X509_ID_EXT_NV_COUNTER_VAL,               /*0x2 */
+    CC_X509_ID_EXT_PUB_KEY_NP,           /*0x3 */
+    CC_X509_ID_EXT_PUB_KEY_HASH,             /*0x4 */
+    CC_X509_ID_EXT_NUM_OF_SW_IMAGES,         /*0x5 */
+    CC_X509_ID_EXT_SW_IMAGE_NONCE,               /*0x6 */
+    CC_X509_ID_EXT_SW_IMAGE_INFO,                /*0x7 */
+    CC_X509_ID_EXT_SOC_SPECIFIC,             /*0x8 */
+    CC_X509_ID_EXT_SOC_ID,                   /*0x9 */
+    CC_X509_ID_EXT_VALID_LCS,            /*0xA */
+    CC_X509_ID_EXT_RMA_MODE,             /*0xB */
+#ifdef CC_SB_CERT_USER_DATA_EXT
+    CC_X509_ID_EXT_USER_DATA,            /*0xC */
+#endif
+    CC_X509_ID_EXT_MAX,
+    CC_X509_ID_EXT_RESERVED = 0xFF
+}CCX509ExtType_t;
+#endif
+
+typedef union {
+        struct {
+               uint32_t      certOffset:16;
+               uint32_t      certSize:16;
+        }certInfoBits;
+        uint32_t      certInfoWord;
+}CCX509CertInfo_t;
+
+typedef union {
+        struct {
+               uint32_t      certType:8;
+               uint32_t      imageEnc:8;
+               uint32_t      hbkType:8;
+               uint32_t      reserved:8;
+        }pkgFlagsBits;
+        uint32_t      pkgFlagsWord;
+}CCX509PkgFlag_t;
+
+typedef struct {
+    uint32_t pkgToken;
+    uint32_t pkgVer;
+    CCX509PkgFlag_t pkgFlags;
+    CCX509CertInfo_t certInfo;
+}CCX509PkgHeader_t;
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/shared/include/trng/cc_config_trng90b.h b/lib/ext/cryptocell-312-runtime/shared/include/trng/cc_config_trng90b.h
new file mode 100644
index 0000000..aae1771
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/include/trng/cc_config_trng90b.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _CC_CONFIG_TRNG90B_H
+#define _CC_CONFIG_TRNG90B_H
+
+/*
+This file should be updated according to the characterization process.
+*/
+
+/*** For Startup Tests ***/
+// amount of bytes for the startup test = 528 (at least 4096 bits (NIST SP 800-90B (2nd Draft) 4.3.12) = 22 EHRs = 4224 bits)
+#define CC_CONFIG_TRNG90B_AMOUNT_OF_BYTES_STARTUP              528
+
+
+
+#endif  // _CC_CONFIG_TRNG90B_H
diff --git a/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_ecpki_info.c b/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_ecpki_info.c
new file mode 100644
index 0000000..3a2ed13
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_ecpki_info.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* this file contains the definitions of the hashes used in the ecpki */
+
+#include "cc_ecpki_local.h"
+#include "cc_hash_defs.h"
+#include "cc_ecpki_types.h"
+#include "cc_ecpki_domains_defs.h"
+#include "cc_ecpki_domain_secp192r1.h"
+#include "cc_ecpki_domain_secp224r1.h"
+#include "cc_ecpki_domain_secp256r1.h"
+#include "cc_ecpki_domain_secp521r1.h"
+#include "cc_ecpki_domain_secp192k1.h"
+#include "cc_ecpki_domain_secp224k1.h"
+#include "cc_ecpki_domain_secp256k1.h"
+#include "cc_ecpki_domain_secp384r1.h"
+
+const CCEcpkiHash_t ecpki_hash_info[CC_ECPKI_HASH_NumOfModes] = {
+        /*CC_ECPKI_HASH_SHA1_mode         */        {CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS, CC_HASH_SHA1_mode},
+        /*CC_ECPKI_HASH_SHA224_mode       */          {CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS, CC_HASH_SHA224_mode},
+        /*CC_ECPKI_HASH_SHA256_mode       */        {CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS, CC_HASH_SHA256_mode},
+        /*CC_ECPKI_HASH_SHA384_mode       */        {CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS, CC_HASH_SHA384_mode},
+        /*CC_ECPKI_HASH_SHA512_mode       */        {CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS, CC_HASH_SHA512_mode},
+        /*CC_ECPKI_AFTER_HASH_SHA1_mode   */        {CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS, CC_HASH_NumOfModes},
+        /*CC_ECPKI_AFTER_HASH_SHA224_mode */        {CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS, CC_HASH_NumOfModes},
+        /*CC_ECPKI_AFTER_HASH_SHA256_mode */        {CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS, CC_HASH_NumOfModes},
+        /*CC_ECPKI_AFTER_HASH_SHA384_mode */        {CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS, CC_HASH_NumOfModes},
+        /*CC_ECPKI_AFTER_HASH_SHA512_mode */        {CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS, CC_HASH_NumOfModes},
+};
+
+const uint8_t ecpki_supported_hash_modes[CC_ECPKI_HASH_NumOfModes] = {
+    /*CC_ECPKI_HASH_SHA1_mode         */ CC_TRUE,
+    /*CC_ECPKI_HASH_SHA224_mode       */ CC_TRUE,
+    /*CC_ECPKI_HASH_SHA256_mode       */ CC_TRUE,
+    /*CC_ECPKI_HASH_SHA384_mode       */ CC_FALSE,
+    /*CC_ECPKI_HASH_SHA512_mode       */ CC_TRUE,
+    /*CC_ECPKI_AFTER_HASH_SHA1_mode   */ CC_TRUE,
+    /*CC_ECPKI_AFTER_HASH_SHA224_mode */ CC_TRUE,
+    /*CC_ECPKI_AFTER_HASH_SHA256_mode */ CC_TRUE,
+    /*CC_ECPKI_AFTER_HASH_SHA384_mode */ CC_TRUE,
+    /*CC_ECPKI_AFTER_HASH_SHA512_mode */ CC_TRUE
+};
+
+
+const getDomainFuncP ecDomainsFuncP[CC_ECPKI_DomainID_OffMode] = {
+            (&CC_EcpkiGetSecp192k1DomainP),
+            (&CC_EcpkiGetSecp192r1DomainP),
+            (&CC_EcpkiGetSecp224k1DomainP),
+            (&CC_EcpkiGetSecp224r1DomainP),
+            (&CC_EcpkiGetSecp256k1DomainP),
+            (&CC_EcpkiGetSecp256r1DomainP),
+            (&CC_EcpkiGetSecp384r1DomainP),
+            (&CC_EcpkiGetSecp521r1DomainP)
+};
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_hash_info.c b/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_hash_info.c
new file mode 100644
index 0000000..d63439d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_hash_info.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* this file contains the definitions of the hashes used in the rsa */
+
+#include "cc_hash_defs.h"
+#include "cc_general_defs.h"
+
+const HmacHash_t HmacHashInfo_t[CC_HASH_NumOfModes] = {
+    /*CC_HASH_SHA1_mode         */        {CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES,   CC_HASH_SHA1_mode},
+    /*CC_HASH_SHA224_mode       */        {CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES, CC_HASH_SHA224_mode},
+    /*CC_HASH_SHA256_mode       */        {CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES, CC_HASH_SHA256_mode},
+    /*CC_HASH_SHA384_mode       */        {CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES, CC_HASH_SHA384_mode},
+    /*CC_HASH_SHA512_mode       */        {CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES, CC_HASH_SHA512_mode},
+    /*CC_HASH_MD5_mode          */        {CC_HASH_MD5_DIGEST_SIZE_IN_BYTES,    CC_HASH_MD5_mode},
+};
+
+const uint8_t HmacSupportedHashModes_t[CC_HASH_NumOfModes] = {
+    /*CC_HASH_SHA1_mode         */ CC_TRUE,
+    /*CC_HASH_SHA224_mode       */ CC_TRUE,
+    /*CC_HASH_SHA256_mode       */ CC_TRUE,
+    /*CC_HASH_SHA384_mode       */ CC_TRUE,
+    /*CC_HASH_SHA512_mode       */ CC_TRUE,
+    /*CC_HASH_MD5_mode          */ CC_FALSE,
+};
+
+const char HashAlgMode2mbedtlsString[CC_HASH_NumOfModes][CC_HASH_NAME_MAX_SIZE] = {
+   "SHA1",
+   "SHA224",
+   "SHA256",
+   "SHA384",
+   "SHA512",
+   "MD5"
+};
+
diff --git a/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_rsa_info.c b/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_rsa_info.c
new file mode 100644
index 0000000..7248421
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/shared/src/proj/cc3x/cc_rsa_info.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/* this file contains the definitions of the hashes used in the rsa */
+#ifdef CC_IOT
+    #if defined(MBEDTLS_CONFIG_FILE)
+    #include MBEDTLS_CONFIG_FILE
+    #endif
+#endif
+
+#if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
+
+#include "cc_rsa_local.h"
+#include "cc_hash_defs.h"
+#include "cc_rsa_types.h"
+
+const RsaHash_t RsaHashInfo_t[CC_RSA_HASH_NumOfModes] = {
+    /*CC_RSA_HASH_MD5_mode          */        {CC_HASH_MD5_DIGEST_SIZE_IN_WORDS,        CC_HASH_MD5_mode},
+    /*CC_RSA_HASH_SHA1_mode         */        {CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS,       CC_HASH_SHA1_mode},
+    /*CC_RSA_HASH_SHA224_mode       */        {CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA224_mode},
+    /*CC_RSA_HASH_SHA256_mode       */        {CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA256_mode},
+    /*CC_RSA_HASH_SHA384_mode       */        {CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA384_mode},
+    /*CC_RSA_HASH_SHA512_mode       */        {CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA512_mode},
+    /*CC_RSA_After_MD5_mode         */        {CC_HASH_MD5_DIGEST_SIZE_IN_WORDS,        CC_HASH_MD5_mode},
+    /*CC_RSA_After_SHA1_mode        */        {CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS,       CC_HASH_SHA1_mode},
+    /*CC_RSA_After_SHA224_mode      */        {CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA224_mode},
+    /*CC_RSA_After_SHA256_mode      */        {CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA256_mode},
+    /*CC_RSA_After_SHA384_mode      */        {CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA384_mode},
+    /*CC_RSA_After_SHA512_mode      */        {CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS,     CC_HASH_SHA512_mode},
+    /*CC_RSA_After_HASH_NOT_KNOWN_mode   */       {0,CC_HASH_NumOfModes},
+    /*CC_RSA_HASH_NO_HASH_mode      */        {0,CC_HASH_NumOfModes},
+};
+
+#ifdef USE_MBEDTLS_CRYPTOCELL
+const mbedtls_md_type_t RsaHash_CC_mbedtls_Info[CC_HASH_NumOfModes] = {
+    /* CC_HASH_SHA1_mode */     MBEDTLS_MD_SHA1,
+    /* CC_HASH_SHA224_mode */   MBEDTLS_MD_SHA224,
+    /* CC_HASH_SHA256_mode */   MBEDTLS_MD_SHA256,
+    /* CC_HASH_SHA384_mode */   MBEDTLS_MD_SHA384,
+    /* CC_HASH_SHA512_mode */   MBEDTLS_MD_SHA512,
+    /* CC_HASH_MD5_mode */      MBEDTLS_MD_MD5
+};
+#endif
+const uint8_t RsaSupportedHashModes_t[CC_RSA_HASH_NumOfModes] = {
+
+        /*CC_RSA_HASH_MD5_mode          */ CC_FALSE,
+        /*CC_RSA_HASH_SHA1_mode         */ CC_TRUE,
+        /*CC_RSA_HASH_SHA224_mode       */ CC_TRUE,
+        /*CC_RSA_HASH_SHA256_mode       */ CC_TRUE,
+        /*CC_RSA_HASH_SHA384_mode       */ CC_TRUE,
+        /*CC_RSA_HASH_SHA512_mode       */ CC_TRUE,
+        /*CC_RSA_After_MD5_mode         */ CC_FALSE,
+        /*CC_RSA_After_SHA1_mode        */ CC_TRUE,
+        /*CC_RSA_After_SHA224_mode      */ CC_TRUE,
+        /*CC_RSA_After_SHA256_mode      */ CC_TRUE,
+        /*CC_RSA_After_SHA384_mode      */ CC_TRUE,
+        /*CC_RSA_After_SHA512_mode      */ CC_TRUE,
+        /*CC_RSA_After_HASH_NOT_KNOWN_mode   */ CC_FALSE,
+        /*CC_RSA_HASH_NO_HASH_mode           */ CC_FALSE,
+};
+
+#endif /* defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/Makefile
new file mode 100644
index 0000000..05f7702
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/Makefile
@@ -0,0 +1,111 @@
+################################################################################
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+################################################################################
+
+# Utils top level Makefile
+
+UTILS_ROOT = $(shell pwd)/..
+
+all:
+
+clean_%:
+	@echo "cleaning" $*
+	@make -C $* clean
+
+distclean: clean clrconfig
+	rm -rf $(UTILS_ROOT)/bin
+	rm -rf $(UTILS_ROOT)/lib
+	rm -rf $(UTILS_ROOT)/include
+	rm -rf $(UTILS_ROOT)/doc
+
+# Generate dependency on existence only (i.e., don't care if newer).
+# To be used primarily for directories creation
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)), $(1))
+
+
+################################################
+### Handle project configuration definitions ###
+################################################
+
+PROJ_CFG_FNAME = proj.cfg
+PROJ_EXT_CFG_FNAME = proj.ext.cfg
+PROJ_CFG_PATH = $(PROJ_CFG_FNAME)
+PROJ_EXT_CFG_PATH = $(UTILS_ROOT)/../$(PROJ_EXT_CFG_FNAME)
+PROJ_CONFIGS_DIR = configs
+
+
+############ Special rules for project configuration selection ##############
+ifneq ($(wildcard $(PROJ_CFG_PATH)),$(PROJ_CFG_PATH)) # No proj.cfg linked
+
+all: # default in case there is no proj.cfg and setconfig_ was not used
+	$(info Invoke 'make setconfig_<config. name>' to select project configuration )
+	$(error 'proj.cfg' not found)
+
+setconfig_%: $(PROJ_CONFIGS_DIR)/proj-%.cfg
+	@$(info [CFG] $(PROJ_CONFIGS_DIR)/proj-$*.cfg --> proj.cfg)
+	@ln -s $(PROJ_CONFIGS_DIR)/proj-$*.cfg $(PROJ_CFG_FNAME)
+
+$(PROJ_CONFIGS_DIR)/proj-%.cfg:
+	@$(error Unknown project configuration. $@ does not exist.)
+
+clrconfig:
+	$(info [CFG-CLN] No active configuration )
+
+.PHONY: all setconfig_% clrconfig
+
+else
+### proj.cfg exists. Include it to get project cofiguration defintions ###
+# The includes order is important here:
+# External configurations in proj.ext.cfg may be overrided by those in host proj.cfg
+include $(PROJ_EXT_CFG_PATH)
+include $(PROJ_CFG_PATH)
+
+
+ifeq ($(CONFIG_SB_SUPPORT_IOT), 1)
+       TARGETS = cc3x_boot_cert icv_asset_prov cc3x_asset_prov_rt cmpu_asset_pkg_util dmpu_asset_pkg_util
+else
+	TARGETS = oem_asset_utils checksum_onec tests
+	ifeq ($(CC_CONFIG_SB_X509_CERT_SUPPORTED), 1)
+	TARGETS += x509_cert_utils
+	else
+	TARGETS +=  secure_boot_utils secure_debug_utils
+	endif
+endif
+
+
+$(info PROJ_NAME=$(PROJ_NAME))
+# Export all definition from proj.cfg to dispatched makefiles
+export
+
+all: $(PROJ_TARGETS)
+
+$(PROJ_TARGETS):
+	@make $(CFLAGS) -C $@
+
+clean: $(foreach target,$(PROJ_TARGETS),clean_$(target))
+
+
+# setconfig_/clrconfig are available only if $(PROJ_CONFIGS_DIR) exists
+# (i.e., eliminated on release trees)
+ifeq ($(wildcard $(PROJ_CONFIGS_DIR)),$(PROJ_CONFIGS_DIR))
+# Configuration rules
+setconfig_%:
+	$(if $(filter $(PROJ_CONFIGS_DIR)/proj-$*.cfg,$(shell readlink $(PROJ_CFG_PATH))),$(info $* configuration is already set.),$(error Before changing configuration invoke 'make clrconfig'))
+
+clrconfig:
+	@echo [CFG-CLN] X $(shell readlink $(PROJ_CFG_PATH))
+	@rm -f $(PROJ_CFG_PATH)
+endif
+
+endif
+
+# Provide lsconfig to list available configurations
+configs_list = $(foreach cfg_file,$(wildcard $(PROJ_CONFIGS_DIR)/proj-*.cfg),$(patsubst $(PROJ_CONFIGS_DIR)/proj-%.cfg,%,$(cfg_file)))
+lsconfig:
+	@$(info Available project configurations:)
+	@$(foreach cfg_file,$(configs_list),$(info $(cfg_file)))
+
+.PHONY: all setconfig_% clrconfig lsconfig clean distclean all clean_% $(TARGETS)
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/Makefile
new file mode 100644
index 0000000..5cda02d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/Makefile
@@ -0,0 +1,47 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for managing build and installation
+
+# shared library to build
+UTIL_ROOT = $(shell pwd)
+UTILS_DIR_ROOT = $(UTIL_ROOT)/../..
+HOST_DIR_ROOT = $(UTIL_ROOT)/../host
+UTILS_LIB_PATH = ./lib
+UTILS_LIB_NAME = libutil_crypto.so
+UTILS_SCRIPTS_DIRNAME = $(UTIL_ROOT)
+
+
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)), $(1))
+
+INSTALL_LIST = install_lib install_scripts
+
+all:   $(INSTALL_LIST)
+
+
+
+install_lib: build_lib $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/lib)
+	@echo Installing util_crypto library
+	@cp $(UTILS_LIB_PATH)/$(UTILS_LIB_NAME) $(UTILS_DIR_ROOT)/lib
+
+build_lib:
+	@make -C $(UTILS_LIB_PATH)
+
+install_scripts: $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin) $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin/example)
+	@echo Installing scripts
+	@cp $(UTIL_ROOT)/*.py $(UTILS_DIR_ROOT)/bin/
+
+$(UTILS_DIR_ROOT)/%:
+	@echo Creating directory $@
+	@mkdir $@
+
+
+clean:
+	@make -C $(UTILS_LIB_PATH) clean
+
+.PHONY: install_lib install_sd_scripts clean
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/asset_provisioning_rt_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/asset_provisioning_rt_util.py
new file mode 100755
index 0000000..7efa589
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/asset_provisioning_rt_util.py
@@ -0,0 +1,146 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# This utility builds asset provisioning BLOB package:
+# the package format is:
+#                       token, version, asset length, user data (20 bytes)
+#                       nonce(12 bytes)
+#                       encrypted asset (up to 512 bytes - multiple of 16 bytes)
+#                       aset tag (16 bytes)
+
+
+# This file contains the general functions that are used in both certificates
+
+CC_ASSET_PROV_MAX_ASSET_SIZE = 4096
+ASSET_BLOCK_SIZE = 16
+
+import sys
+# Definitions for paths
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+import configparser
+from asset_util_rt_helper import *
+import sys
+
+# Parse given test configuration file and return test attributes as dictionary
+def parse_config_file (config, log_file):
+    local_dict = {}
+    section_name = "ASSET-PROV-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None
+
+    local_dict['asset_id'] = int(config.get(section_name, 'asset-id'), 16)
+    log_sync(log_file, "asset_id " + str(local_dict['asset_id']) + "\n")
+
+    local_dict['key_filename'] = config.get(section_name, 'key-filename')
+    log_sync(log_file,"key_filename: " + str(local_dict['key_filename']) + "\n") 
+     
+    if config.has_option(section_name, 'keypwd-filename'): #used for testing
+            local_dict['keypwd_filename'] = str.encode(config.get(section_name, 'keypwd-filename'))
+            log_sync(log_file,"keypwd_filename: " + str(local_dict['keypwd_filename']) + "\n")   
+    else:
+        local_dict['keypwd_filename'] = ''                     
+               
+    local_dict['asset_filename'] = config.get(section_name, 'asset-filename')
+    log_sync(log_file,"asset_filename: " + str(local_dict['asset_filename']) + "\n") 
+      
+    local_dict['asset_pkg'] = str.encode(config.get(section_name, 'asset-pkg'))
+    log_sync(log_file,"asset_pkg: " + str(local_dict['asset_pkg']) + "\n")   
+               
+    return local_dict
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "asset_prov.log"
+    return config_fname, log_fname
+
+
+# close files and exit script
+def exit_main_func(log_file, config_file, rc):
+    log_file.close()
+    config_file.close()
+    sys.exit(rc)
+
+
+def main():        
+
+    config_fname, log_fname = parse_shell_arguments()
+    log_file = create_log_file(log_fname)
+    print_and_log(log_file, str(datetime.now()) + ": Asset provisioning Utility started (Logging to " + log_fname + ")\n")
+
+    DLLHandle = LoadDLLGetHandle()        
+    
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        log_file.close()
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.read(config_fname)
+    data_dict = {}
+
+    data_dict = parse_config_file(config, log_file)
+
+    if (data_dict != None):
+        # Get assets and encrypted key from files
+        asset_size, assetStr = GetDataFromBinFile(log_file, data_dict['asset_filename'])
+        if (asset_size == 0) or (asset_size > CC_ASSET_PROV_MAX_ASSET_SIZE) or (asset_size%ASSET_BLOCK_SIZE != 0):
+                print_and_log(log_file, "invalid asset size " + str(asset_size) + "\n")
+                log_file.close()
+                sys.exit(e.errno)
+
+        key_size, keyStr = GetDataFromBinFile(log_file, data_dict['key_filename'])
+
+        print_and_log(log_file, "**** Generate Asset BLOB ****\n")        
+
+        result = DLLHandle.build_asset_blob(keyStr, key_size,
+                         data_dict['keypwd_filename'],
+                         data_dict['asset_id'],
+                         assetStr, asset_size,
+                         data_dict['asset_pkg'])
+        if result != 0:
+            raise NameError                                
+       
+        print_and_log(log_file, "**** Generate asset BLOB completed successfully ****\n")
+        exit_main_func(log_file, config_file, 0)
+
+    else:
+        print_and_log(log_file, "**** Invalid config file ****\n")
+        exit_main_func(log_file, config_file, 1)
+
+    FreeDLLGetHandle(DLLHandle)
+
+#############################
+if __name__ == "__main__":
+    main()
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/asset_util_rt_helper.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/asset_util_rt_helper.py
new file mode 100755
index 0000000..1d51714
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/asset_util_rt_helper.py
@@ -0,0 +1,98 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+from datetime import datetime
+#
+import sys
+import struct
+from ctypes import *
+
+#so name
+SBU_CRYPTO_LIB_DIR = "lib"
+SBU_CRYPTO_LIB_Name = SBU_CRYPTO_LIB_DIR + "/" + "libutil_crypto.so"
+SBU_OSSL_CRYPTO_LIB_Name = "libcrypto.so.1.0.0"
+SBU_OSSL_LIB_Name = "libssl.so.1.0.0"
+
+
+CURRENT_PATH = sys.path[0]
+
+
+# The function returns the path of the DLL - fixed path (relative to script path)
+def GetDLLPath(FileName):
+
+    path = str()    
+    path = CURRENT_PATH    
+    # split according to dir names
+    if sys.platform != "win32" :
+        path_div = "/"    
+    else : #platform = win32
+        path_div = "\\"
+
+    path_new = path + path_div + ".." + path_div
+
+    path_new = path_new + FileName        
+    return path_new
+# End of GetDLLPath
+
+# 
+# The function loads the crypto DLL and returns its handle
+def LoadDLLGetHandle():
+    # Load the crypto libraries
+    SBU_Crypto = cdll.LoadLibrary(GetDLLPath(SBU_CRYPTO_LIB_Name))
+    return SBU_Crypto
+# End of LoadDLLGetHandle
+
+# The function free the DLL - // not being used in Linux
+def FreeDLLGetHandle(DllHandle):
+    # free the libraries
+    cdll.FreeLibrary(DllHandle)
+    return 0
+# End of FreeDLLGetHandle
+
+
+# Create a log file handle
+def create_log_file (log_file_path):
+    
+    log_file = open(log_file_path, 'w')
+    return log_file;
+
+# Print (stdout) and output also to log file given text
+def print_and_log (log_file, text):
+    print (text)
+    log_file.write(text)
+    sys.stdout.flush()
+    log_file.flush()
+
+
+# Do synchronous print to appear immediately on the console
+def print_sync (text):
+    print (text)
+    sys.stdout.flush()
+
+
+# Do synchronous write to log file
+def log_sync (log_file, text):
+    log_file.write(text)
+    log_file.flush()
+
+
+# The GetDataFromBinFile gets the data from a binary file
+def GetDataFromBinFile(logFile, fileName):
+    binStr = str()
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(fileName, "rb")
+        binStr = FileObj.read()
+        binSize = len(binStr)
+        FileObj.close()
+
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %fileName)
+        sys.exit(1)
+    return binSize, binStr      
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/examples/asset_prov_se_512.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/examples/asset_prov_se_512.cfg
new file mode 100644
index 0000000..f1556ea
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/examples/asset_prov_se_512.cfg
@@ -0,0 +1,21 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for enabler debug certificate generation
+# [ASSET-PROV-CFG]        Mandatory header.
+#key-filename =         File holding the encrypted Kpicv, in binary format.
+#keypwd-filename =      Passphrase for the key file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#asset-id =             The ICV asset ID in 32 bits hex format (e.g. 0x7000000f).
+#asset-filename =       The asset to create the BLOB for
+#asset-pkg =            The asset package, generated by asset_provisioning_util_rt.py.
+[ASSET-PROV-CFG]
+key-filename =  icv_key_enc.bin
+keypwd-filename = icv_key_pwd.txt
+asset-id   = 0x00112233
+asset-filename = asset512_bin.bin
+asset-pkg = asset_pkg_se_512.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/lib/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/lib/Makefile
new file mode 100644
index 0000000..72acdcf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/lib/Makefile
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for building sbu_crypto library
+SH_LIB_NAME = libutil_crypto.so
+
+LIB_SRC_O = main.o common_crypto_asym.o  common_crypto_sym.o common_rsa_keypair_util.o common_rsa_keypair.o common_util_files.o
+
+UTILS_ROOT = $(shell pwd)/../../..
+SHARED_DIR = $(UTILS_ROOT)/../shared
+HOST_DIR = $(UTILS_ROOT)/../host
+UTILS_LIB_PATH = $(UTILS_ROOT)/lib
+UTILS_INC_PATH = $(SHARED_DIR)/include $(SHARED_DIR)/include/proj/$(PROJ_PRD) $(UTILS_ROOT)/include
+UTILS_INC_PATH += $(UTILS_ROOT)/src/common $(SHARED_DIR)/include/pal  $(SHARED_DIR)/include/pal/$(TEE_OS)  $(SHARED_DIR)/include/cc_util
+
+CFLAGS += -fPIC $(foreach incdir,$(UTILS_INC_PATH),-I$(incdir)) -c
+
+all: $(SH_LIB_NAME)
+
+# Compile and link the sbu_crypto library with hard-coded library run path to utils/lib
+# (to assure the private version of openssl libraries are used)
+$(SH_LIB_NAME): $(LIB_SRC_O)
+	gcc -shared -o $(SH_LIB_NAME) $(LIB_SRC_O) -Wl,-rpath,$(UTILS_LIB_PATH) -lcrypto -lssl
+
+vpath %.c $(UTILS_ROOT)/src/common
+
+%.o: %.c
+	gcc $(CFLAGS) $<
+
+clean:
+	rm -f $(SH_LIB_NAME) $(LIB_SRC_O)
+
+.PHONY: clean all
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/lib/main.c b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/lib/main.c
new file mode 100644
index 0000000..0c7f7c6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_asset_prov_rt/lib/main.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_util_log.h"
+#include "common_crypto_asym.h"
+#include "common_crypto_sym.h"
+#include "common_rsa_keypair_util.h"
+#include "common_util_files.h"
+#include "cc_util_asset_prov_int.h"
+
+static uint8_t  isLibOpened = 0;
+
+#define KPICV_KEY_SIZE      16
+#define KPROV_KEY_SIZE      16
+#define KPROV_DATA_IN_SIZE  8
+
+
+/**
+* @brief initialize openSSL library
+*
+* @param[in] None
+* @param[out] None
+*
+*/
+/*********************************************************/
+static void InitOpenSsl(void)
+{
+    if (0 == isLibOpened) {
+          OpenSSL_add_all_algorithms();
+    }
+    isLibOpened++;
+}
+
+
+/**
+* @brief terminates and cleanup openSSL library
+*
+* @param[in]  None
+* @param[out] None
+*
+*/
+/*********************************************************/
+static void CloseOpenSsl(void)
+{
+    isLibOpened--;
+    if (0 == isLibOpened) {
+          EVP_cleanup();
+          //CYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+    }
+}
+
+
+/**
+* @brief performs CMAC key derivation for Kprov using openSSL library
+*
+* @param[in]  pKey & keySize - Kpicv key and its size
+*       lable & pContext & contextSize used to build the dataIn for derivation
+* @param[out] pOutKey - Kprov
+*
+*/
+/*********************************************************/
+static int AesCmacKeyDerivation(char *pKey, uint32_t keySize,
+                char lable,
+                uint8_t *pContext, uint32_t contextSize,
+                char *pOutKey, uint32_t outKeySize)
+{
+    int rc = 0;
+    int i = 0;
+    int8_t dataIn[KPROV_DATA_IN_SIZE] = {0x0};
+
+    /* Create the input to the CMAC derivation */
+    dataIn[i++] = 0x1;
+    dataIn[i++] = lable;
+    dataIn[i++] = 0x0;
+    memcpy(&dataIn[i], pContext, contextSize);
+    i += contextSize;
+    dataIn[i] = outKeySize*CC_BITS_IN_BYTE; // size of the key in bits
+
+    UTIL_LOG_BYTE_BUFF("dataIn", dataIn, sizeof(dataIn));
+    UTIL_LOG_BYTE_BUFF("pKey", pKey, keySize);
+    rc = CC_CommonAesCmacEncrypt(dataIn, sizeof(dataIn),
+                     pKey, keySize, pOutKey);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCmacEncrypt(), rc %d\n", rc);
+        return (-1);
+    }
+    UTIL_LOG_BYTE_BUFF("pOutKey", pOutKey, outKeySize);
+    return rc;
+}
+
+
+/**
+* @brief Build the ICV asset BLOB using openSSL library
+*
+* @param[in]  encKeyBuff & encKeyBuffSize & pKeyPwdFileName - the encryptes Kpicv key
+*           assetId - Asset ID, used for Kprov derivation
+*           asset & assetSize - The Asset to generate the BLOB for
+*           pBlobFileName - OUT - the asset BLOB binary file name
+* @param[out] None
+*
+*/
+/*********************************************************/
+int build_asset_blob(char *encKeyBuff, uint32_t encKeyBuffSize,
+    char *pKeyPwdFileName,
+    uint32_t assetId,
+    uint8_t *asset, uint32_t assetSize,
+    char *pBlobFileName)
+{
+    int rc = 0;
+    uint8_t keyPicv[(KPICV_KEY_SIZE + CC_ASSET_PROV_BLOCK_SIZE)] = {0};
+    uint8_t keyProv[KPROV_KEY_SIZE] = {0};
+    uint8_t i = 0;
+    CCAssetProvPkg_t assetBlob = {0};
+    uint32_t assetBlobSize;
+
+    // Verify Inputs
+    UTIL_LOG_ERR( "encKeyBuffSize %d\n", encKeyBuffSize);
+    if ((encKeyBuff == NULL) ||
+        (encKeyBuffSize != (KPICV_KEY_SIZE + CC_ASSET_PROV_BLOCK_SIZE)) ||
+        (asset == NULL) ||
+        (assetSize > CC_ASSET_PROV_MAX_ASSET_SIZE) || (assetSize % CC_ASSET_PROV_BLOCK_SIZE) ||
+        (pBlobFileName == NULL)) {
+        UTIL_LOG_ERR( "Invalid inputs\n");
+        return (-1);
+    }
+        assetBlobSize = CC_ASSET_PROV_ADATA_SIZE + CC_ASSET_PROV_NONCE_SIZE + assetSize + CC_ASSET_PROV_TAG_SIZE;
+
+    InitOpenSsl();
+
+    // Build the BLOB header
+    assetBlob.token = CC_ASSET_PROV_TOKEN;
+    assetBlob.version = CC_ASSET_PROV_VERSION;
+    assetBlob.assetSize = assetSize;
+    assetBlob.reserved[0] = 0;
+    assetBlob.reserved[1] = 0; // reserved
+    rc = CC_CommonRandBytes(CC_ASSET_PROV_NONCE_SIZE, (uint8_t *)assetBlob.nonce);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonRandBytes() for nonce, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+
+    // Decrypt Kpicv
+    UTIL_LOG_ERR( "calling CC_CommonAesCbcDecrypt() pKeyPwdFileName %s\n", pKeyPwdFileName);
+    rc = CC_CommonAesCbcDecrypt(pKeyPwdFileName, encKeyBuff, encKeyBuffSize, keyPicv);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCbcDecrypt() for Kpicv, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+
+        // Calculate Kprov = cmac(Kpicv, 0x01 || 0x50 || 0x00 || asset id || 0x80)
+    UTIL_LOG_ERR( "calling AesCmacKeyDerivation\n");
+    rc = AesCmacKeyDerivation(keyPicv, KPICV_KEY_SIZE,
+                'P',
+                (uint8_t *)&assetId, sizeof(assetId),
+                keyProv, sizeof(keyProv));
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to AesCmacKeyDerivation() for Kprov, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+    // Encrypt and authenticate the asset
+    UTIL_LOG_ERR( "calling CC_CommonAesCcmEncrypt\n");
+    rc = CC_CommonAesCcmEncrypt(keyProv,
+                (uint8_t *)assetBlob.nonce, CC_ASSET_PROV_NONCE_SIZE,
+                (uint8_t *)&assetBlob, CC_ASSET_PROV_ADATA_SIZE,
+                asset, assetSize,
+                (uint8_t *)assetBlob.encAsset, &assetSize,
+                                ((uint8_t *)assetBlob.encAsset)+assetSize, CC_ASSET_PROV_TAG_SIZE);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCmacEncrypt() for Kprov, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+    UTIL_LOG_BYTE_BUFF("assetBlob", (uint8_t *)&assetBlob, assetBlobSize);
+    // Writing the asset BLOB into bin file
+    rc = CC_CommonUtilCopyBuffToBinFile(pBlobFileName, (uint8_t *)&assetBlob, assetBlobSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonUtilCopyBuffToBinFile(), rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+    rc = 0;
+end_func:
+    CloseOpenSsl();
+    UTIL_LOG_ERR( "End rc %d\n", rc);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/Makefile
new file mode 100755
index 0000000..b221ea3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/Makefile
@@ -0,0 +1,56 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for managing SBU build and installation
+ifeq ($(CC_CONFIG_SB_X509_CERT_SUPPORTED),1)
+	SUB_DIRS_PREFIX = x509cert
+else
+	SUB_DIRS_PREFIX = cert
+endif
+
+$(info $$SUB_DIRS_PREFIX is [${SUB_DIRS_PREFIX}])
+
+# shared library to build
+SBU_ROOT = $(shell pwd)
+UTIL_ROOT = $(SBU_ROOT)/../..
+SBU_CRYP_LIB_PATH = $(SUB_DIRS_PREFIX)_lib
+SBU_CRYP_LIB_NAME = libsbu_crypto.so
+SBU_SCRIPTS_DIRNAME = $(SUB_DIRS_PREFIX)_utils
+SBU_COMMON_SCRIPTS_DIRNAME = common_utils
+
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)), $(1))
+
+INSTALL_LIST = install_lib install_sbu
+
+all:   $(INSTALL_LIST)
+
+install_lib: build_lib $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTIL_ROOT)/lib)
+	@echo Installing sbu_crypto library
+	@cp $(SBU_ROOT)/$(SBU_CRYP_LIB_PATH)/$(SBU_CRYP_LIB_NAME) $(UTIL_ROOT)/lib
+
+build_lib:
+	@make -C $(SBU_ROOT)/$(SBU_CRYP_LIB_PATH)
+
+
+install_sbu: $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTIL_ROOT)/bin) $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTIL_ROOT)/bin/$(SBU_COMMON_SCRIPTS_DIRNAME))
+	@echo Installing SBU scripts
+	@cp $(SBU_ROOT)/$(SBU_SCRIPTS_DIRNAME)/*.py $(UTIL_ROOT)/bin
+	@cp $(SBU_ROOT)/$(SBU_COMMON_SCRIPTS_DIRNAME)/*.py $(UTIL_ROOT)/bin/$(SBU_COMMON_SCRIPTS_DIRNAME)
+
+$(UTIL_ROOT)/%:
+	@echo Creating directory $@
+	@mkdir $@
+
+
+
+
+clean:
+	@make -C $(SBU_CRYP_LIB_PATH) clean
+
+.PHONY: install_lib install_sbu clean
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_lib/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_lib/Makefile
new file mode 100644
index 0000000..68c7282
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_lib/Makefile
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for building sbu_crypto library
+SH_LIB_NAME = libsbu_crypto.so
+
+LIB_SRC_O = main.o common_rsa_keypair.o common_rsa_keypair_util.o common_crypto_sym.o common_util_files.o common_sb_ops.o
+
+UTILS_ROOT = $(shell pwd)/../../..
+SHARED_DIR = $(UTILS_ROOT)/../shared
+UTILS_LIB_PATH = $(UTILS_ROOT)/lib
+UTILS_INC_PATH = $(UTILS_ROOT)/include $(UTILS_ROOT)/src/common  $(SHARED_DIR)/include/proj/$(PROJ_PRD) $(SHARED_DIR)/include
+UTILS_INC_PATH += $(CODESAFE_SRCDIR)/secure_boot_debug/secure_debug/cc3x  $(SHARED_DIR)/include/pal  $(SHARED_DIR)/include/pal/$(TEE_OS)
+CFLAGS += -fPIC $(foreach incdir,$(UTILS_INC_PATH),-I$(incdir)) -c
+
+CFLAGS += -DCC_SB_SUPPORT_IOT
+
+all: $(SH_LIB_NAME)
+
+# Compile and link the sbu_crypto library with hard-coded library run path to utils/lib
+# (to assure the private version of openssl libraries are used)
+$(SH_LIB_NAME): $(LIB_SRC_O)
+	gcc -shared -o $(SH_LIB_NAME) $(LIB_SRC_O) -Wl,-rpath,$(UTILS_LIB_PATH) -lcrypto -lssl
+
+vpath %.c $(UTILS_ROOT)/src/common
+
+%.o: %.c
+	gcc $(CFLAGS) $<
+
+clean:
+	rm -f $(SH_LIB_NAME) $(LIB_SRC_O)
+
+.PHONY: clean all
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_lib/main.c b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_lib/main.c
new file mode 100644
index 0000000..14172c8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_lib/main.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_sb_ops.h"
+#include "common_crypto_asym.h"
+#include "common_util_log.h"
+#include "common_util_files.h"
+#include "cc_crypto_defs.h"
+#include "cc_pka_hw_plat_defs.h"
+
+
+#define HASH_ON_PLAIN_TEXT      0
+#define HASH_ON_CIPHER_TEXT     1
+
+
+/**
+ * @brief The SBU_RSA_Sign generates RSA signature and returns it.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] DataIn_ptr - the data to sign on
+ * @param[in] DataInSize - the data size
+ * @param[in] PemEncryptedFileName_ptr - the private key file
+ * @param[in] pwdFileName - file name of the password
+ * @param[out] Signature_ptr - the RSA signature
+ *
+ */
+ /*********************************************************/
+SBUEXPORT_C int SBU_RSA_Sign(int pkcsVersion,
+                             char* DataIn_ptr,
+                             unsigned int DataInSize,
+                             char* PemEncryptedFileName_ptr,
+                             char* pwdFileName,
+                             char* Signature_ptr)
+{
+    RSA  *pRsaPrivKey = NULL;
+    unsigned char *pwd = NULL;
+    int  ret_code;
+
+    OpenSSL_add_all_algorithms ();
+
+    /* parse the passphrase for a given file */
+    if( strlen(pwdFileName) ) {
+        if(CC_CommonGetPassphrase(pwdFileName, &pwd) != 0){
+            printf("Failed to retrieve pwd\n");
+            if (pwd != NULL)
+                free(pwd);
+            return (-1);
+        }
+    }
+    else {
+        pwd = Nullptr;
+    }
+
+    if (CC_CommonGetKeyPair (&pRsaPrivKey, PemEncryptedFileName_ptr, pwd) < 0)
+    {
+        printf ("\nCC_CommonGetKeyPair Cannot read RSA private key\n");
+        return (-1);
+    }
+
+    if (pkcsVersion == RSA_USE_PKCS_15_VERSION) {
+        ret_code = Sign_v15(pRsaPrivKey, DataIn_ptr, DataInSize, Signature_ptr, pwd);
+    } else {
+        ret_code = Sign_v21(pRsaPrivKey, DataIn_ptr, DataInSize, Signature_ptr);
+    }
+
+    return (ret_code);
+}
+
+
+/**
+* @brief The SBU_AES_CTR_Encrypt encrypts (AES CTR) a given data and returns it.
+* Also, it hash either the plain or the cipher text according to cryptoType.
+*
+* @param[in] pFileName - input plain text
+* @param[in] pOutputFileName - output cipher text
+* @param[in] Key_ptr - the AES key
+* @param[in] KeySize - AES key size (must be one of the allowed AES key sizes)
+* @param[in] IV_ptr - IV (AES IV size is constant)
+* @param[in] Output_ptr - Output hash buffer
+* @param[in] imageSize - size of input data
+* @param[in] cryptoType - 0 - hash the plain text; 1 = hash the cipher text
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_AES_CTR_EncryptFile(char *pFileName,
+                    char *pOutputFileName,
+                    char* Key_ptr, int KeySize,
+                    char* IV_ptr,
+                    char* Output_ptr,
+                    uint32_t *imageSize,
+                    int8_t cryptoType)
+{
+    int rc = 0;
+    FILE *fd = NULL;
+    FILE *encFd = NULL;
+    int actualFileLen = 0;
+    bool encFlag = false;
+    uint32_t totalRead = 0;
+    uint32_t actualRead = 0;
+    unsigned char m_iv[AES_BLOCK_SIZE];
+    unsigned char m_key[AES_BLOCK_SIZE*2];
+    uint8_t origBuff[MAX_IMAGE_CHUNK] = {0};
+    uint8_t encryptedBuff[MAX_IMAGE_CHUNK+AES_BLOCK_SIZE] = {0};
+    uint32_t actualWriten = 0;
+    uint8_t *pBuff2Hash = NULL;
+    uint8_t imageHash[HASH_SHA256_DIGEST_SIZE_IN_BYTES] = {0};
+    EVP_CIPHER_CTX ctrCtx;
+    SHA256_CTX sha256Ctx;
+    uint32_t encryptedBuffSize = 0;
+    uint32_t prevBuffLen = 0;
+
+    if (pFileName == NULL || Output_ptr == NULL || imageSize == NULL){
+        printf("illegal parameters !\n");
+        return 1;
+    }
+    if (IV_ptr != NULL){ /* if there is IV than key is required as well */
+        memcpy (m_iv, IV_ptr, sizeof (m_iv));
+        memcpy (m_key, Key_ptr, KeySize);
+        encFlag = true;
+    }
+
+    /* Open image file for reading */
+    fd = fopen(pFileName, "rb");
+    if (NULL == fd) {
+        printf( "failed to open file %s for reading\n", pFileName);
+        return 1;
+    }
+    /* Get file length */
+    fseek(fd, 0, SEEK_END);
+    actualFileLen=ftell(fd);
+    if (actualFileLen == -1){
+        printf("ftell failed\n");
+        goto END;
+    }
+    fseek(fd, 0, SEEK_SET);
+    // validate size legal and word aligned
+    if ((0 == actualFileLen) ||
+        (actualFileLen % 0x4)) {
+        printf( "ilegal actualFileLen == 0\n");
+        rc = 3;
+        goto END;
+    }
+
+    /* init SHA256 open-ssl context */
+    rc = SHA256_Init(&sha256Ctx);
+    if (rc == 0) {
+        printf( "failed to SHA256_Init 0x%x\n", rc);
+        rc = 1;
+        goto END;
+    }
+
+    /* init variables in case encryption is needed */
+    if (encFlag == true) {
+        /* open encrypted file for writing encrypted image */
+        encFd = fopen(pOutputFileName, "wb");
+        if (NULL == encFd) {
+            printf( "failed to open file %s for writing\n", pOutputFileName);
+            rc = 1;
+            goto END;
+        }
+
+        /* init AES CTR open-ssl context */
+        EVP_CIPHER_CTX_init(&ctrCtx);
+        rc = EVP_EncryptInit(&ctrCtx, EVP_aes_128_ctr(), m_key, m_iv);
+        if (rc == 0) {
+            printf( "failed to EVP_EncryptInit_ex 0x%x\n", rc);
+            rc = 1;
+            goto END;
+        }
+    }
+
+    /* read max 1M bytes from image file,
+      if encryption is required, encrype first and write into pOutputFileName;
+      then perform SHA256. */
+    totalRead = 0;
+    prevBuffLen = 0;
+    encryptedBuffSize = 0;
+
+    while(totalRead < actualFileLen) {
+        /* read file content */
+        actualRead = fread(origBuff, 1, MAX_IMAGE_CHUNK, fd);
+        if (actualRead == 0)
+        {
+            printf( "fread returned 0\n");
+            goto END;
+        }
+        totalRead += actualRead;
+        pBuff2Hash = origBuff;
+        /* handle encryption */
+        if (encFlag == true) {
+            encryptedBuffSize = 0;
+            pBuff2Hash = &encryptedBuff[0];
+            rc = EVP_EncryptUpdate(&ctrCtx, encryptedBuff, &prevBuffLen, origBuff, actualRead);
+            if (rc == 0) {
+                printf( "failed to EVP_EncryptUpdate, rc 0x%x\n", rc);
+                rc = 1;
+                goto END;
+            }
+            /* update total encrypted byte count */
+            encryptedBuffSize += prevBuffLen;
+            if (totalRead >= actualFileLen) {
+                    rc = EVP_EncryptFinal_ex(&ctrCtx, encryptedBuff+encryptedBuffSize, &prevBuffLen);
+                if (rc == 0) {
+                    printf( "failed to EVP_EncryptFinal_ex, rc 0x%x\n", rc);
+                    rc = 1;
+                    goto END;
+                }
+                encryptedBuffSize += prevBuffLen;
+            }
+
+            /* write encrypted data to binary file  */
+            actualWriten = fwrite(pBuff2Hash, 1, actualRead, encFd);
+            if (actualWriten != actualRead) {
+                printf( "failed to write data to file actual written %d, expected %d\n", actualWriten, actualRead);
+                rc = 1;
+                goto END;
+            }
+        }
+
+        /* calculate SHA256 on plain/cipher image */
+        if (cryptoType == HASH_ON_PLAIN_TEXT) {
+            rc = SHA256_Update(&sha256Ctx, origBuff, actualRead);
+        } else {
+            rc = SHA256_Update(&sha256Ctx, encryptedBuff, actualRead);
+        }
+        if (rc == 0) {
+            printf( "failed to SHA256_Update, rc 0x%x\n", rc);
+            rc = 1;
+            goto END;
+        }
+        if (totalRead >= actualFileLen) {
+            rc = SHA256_Final(imageHash, &sha256Ctx);
+            if (rc == 0) {
+                printf( "failed to SHA256_Final, rc 0x%x\n", rc);
+                rc = 1;
+                goto END;
+            }
+            OPENSSL_cleanse(&sha256Ctx,sizeof(sha256Ctx));
+        }
+
+    }
+    // if we reached here rc is OK
+    rc = 0;
+    // copy the output HASH back to the caller
+    memcpy(Output_ptr , imageHash, HASH_SHA256_DIGEST_SIZE_IN_BYTES);
+    *imageSize = actualFileLen;
+
+END:
+    if (fd != NULL) {
+        fclose(fd);
+    }
+    if (encFd != NULL) {
+        fclose(encFd);
+    }
+    EVP_cleanup();
+
+    return rc;
+
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_dbg_developer_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_dbg_developer_util.py
new file mode 100755
index 0000000..2a27d82
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_dbg_developer_util.py
@@ -0,0 +1,164 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+# This utility builds developer debug certifiacte package:
+# the package Header format is:
+#                       enabler certificate
+#                       token, version, length, flags (reserved word)
+#                       certifiacte PubKey (pub key + Np)
+#                       debug Mask(4 words)
+#                       socid
+#                       certSign
+
+import configparser
+import sys
+import os 
+
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+    
+# this is the scripts local path, from where the program was called
+print (CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+from cert_cfg_parser_util import *
+from cert_dbg_util_gen import *
+from global_defines import *
+from cert_dbg_util_data import *
+from cert_basic_utilities import *
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_dbg2_cert.log"
+    return config_fname, log_fname
+
+
+def CreateCertUtility(sysArgsList):        
+    try:          
+
+        config_fname, log_fname = parse_shell_arguments()
+        
+        log_file = create_log_file(log_fname)
+        print_and_log(log_file, str(datetime.now()) + ": Developer Debug Certificate Utility started (Logging to " + log_fname + ")\n")
+    
+        data_dict, config = developer_cert_config_file_parser(config_fname, log_file)
+        if data_dict == None:
+            log_file.close()
+            exit(1) 
+    
+        DLLHandle = LoadDLLGetHandle()        
+        
+        certStrBin = str()
+        dataToSign = str()
+                
+        print_and_log(log_file, "**** Generate debug certificate ****\n")        
+    
+    
+        # read the enabler certificate from file to str to get the enabler cert + get its length       
+        enablerCertBin = GetDataFromBinFile(log_file, data_dict['enabler_cert_pkg'])
+        certStrBin = byte2string(enablerCertBin)
+    
+        # create certificate header , get bin str and the header str
+        # build header  
+        dataToSign = build_certificate_header (DEBUG_DEVELOPER_TOKEN, PrjDefines, LIST_OF_CONF_PARAMS, 0, 0, 0)
+    
+        # get the developer certificate public key + Np
+        developerNPublicKey = GetRSAKeyParams(log_file, data_dict['cert_keypair'], data_dict['cert_keypair_pwd'], DLLHandle)
+        dataToSign = dataToSign + developerNPublicKey.VarsToBinString()        
+    
+        # add mask
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask0']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask1']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask2']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask3']))
+    
+        # add soc_id                
+        socIdBin = GetDataFromBinFile(log_file, data_dict['soc_id'])
+        if (len(socIdBin) != SOC_ID_SIZE_IN_BYTES):
+            print_and_log(log_file, "Illegal soc ID size")
+            raise 
+        
+        dataToSign = dataToSign + byte2string(socIdBin)
+    
+        # Sign on certificate
+        Signature = GetRSASignature(log_file, dataToSign, data_dict['cert_keypair'], data_dict['cert_keypair_pwd'], DLLHandle)
+        certStrBin = certStrBin + dataToSign + Signature.VarsToBinString()
+    
+        # add signature and write to binary file
+        CreateCertBinFile(log_file, certStrBin, data_dict['cert_pkg'])
+
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+      
+        
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print_and_log(log_file, "I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print_and_log(log_file, "Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print_and_log(log_file, "Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_dbg_enabler_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_dbg_enabler_util.py
new file mode 100755
index 0000000..2adafd4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_dbg_enabler_util.py
@@ -0,0 +1,167 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+# This utility builds enabler debug certifiacte package:
+# the package Header format is:
+#                       key certificate, if exists
+#                       token, version, length, flags (hbk,lcs, isRma)
+#                       certifiacte PubKey (pub key + Np)
+#                       debug Mask(4 words)
+#                       debug lock(4 words)
+#                       sha256 of devPubKey 
+#                       certSign
+
+import configparser
+import sys
+import os 
+
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+
+from cert_cfg_parser_util import *
+from cert_dbg_util_gen import *
+from global_defines import *
+from cert_basic_utilities import *
+from cert_dbg_util_data import *
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_dbg1_cert.log"
+    return config_fname, log_fname
+
+def CreateCertUtility(sysArgsList):
+    try:          
+
+        config_fname, log_fname = parse_shell_arguments()
+        log_file = create_log_file(log_fname)
+        print_and_log(log_file, str(datetime.now()) + ": Enabler Debug Certificate Utility started (Logging to " + log_fname + ")\n")
+    
+        
+        data_dict, config = enabler_cert_config_file_parser(config_fname, log_file)
+        if data_dict == None:
+            log_file.close()
+            exit(1) 
+            
+        DLLHandle = LoadDLLGetHandle()        
+    
+        certStrBin = str()
+        dataToSign = str()
+        if data_dict['key_cert_pkg'] != '':
+            isKeyExist = 1
+        else:
+            isKeyExist = 0
+        print_and_log(log_file, "**** Generate debug certificate ****\n")        
+        # if key package exists need to insert it into the enabler certificate 
+        if data_dict['key_cert_pkg'] != "":
+            keyStr = GetDataFromBinFile(log_file, data_dict['key_cert_pkg'])
+            certStrBin = byte2string(keyStr)
+    
+        # create certificate header , get bin str and the header str
+        dataToSign = build_certificate_header (DEBUG_ENABLER_TOKEN, PrjDefines, LIST_OF_CONF_PARAMS, data_dict['rma_mode'], data_dict['hbk_id'], data_dict['lcs'])
+        
+        # get the enabler certificate public key + Np
+        enablerNPublicKey = GetRSAKeyParams(log_file, data_dict['cert_keypair'], data_dict['cert_keypair_pwd'], DLLHandle)
+        dataToSign = dataToSign + enablerNPublicKey.VarsToBinString()        
+    
+        # add mask
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask0']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask1']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask2']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_mask3']))
+    
+        # add lock
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_lock0']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_lock1']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_lock2']))
+        dataToSign = dataToSign + byte2string(struct.pack('<I', data_dict['debug_lock3']))
+    
+        # get developer certificate public key + Np (from public key)
+        HashBootKey = GetPubKeyHash(log_file, data_dict['next_cert_pubkey'], DLLHandle);
+        dataToSign = dataToSign + HashBootKey.VarsToBinString()
+    
+        # Sign on certificate
+        Signature = GetRSASignature(log_file, dataToSign, data_dict['cert_keypair'], data_dict['cert_keypair_pwd'], DLLHandle)
+    
+        certStrBin = certStrBin + dataToSign + Signature.VarsToBinString()
+    
+        # add signature and write to binary file
+        CreateCertBinFile(log_file, certStrBin, data_dict['cert_pkg'])
+    
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+         
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print_and_log(log_file, "I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print_and_log(log_file, "Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print_and_log(log_file, "Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_key_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_key_util.py
new file mode 100755
index 0000000..d32f02e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_key_util.py
@@ -0,0 +1,264 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# secure boot process. 
+# Key certificate structure is :
+#       FIELD NAME                                               SIZE (words)
+#       ----------                                              ------------
+#       Header token                                               1
+#       version number                                             1
+#       size in words (offset to signature)                        1
+#       Flags                                                      1
+#       N Pub key                                                 96
+#       Np                                                         5
+#       active SW version                                          1
+#       public key HASH                                            8
+#       RSA Signature                                             96
+
+
+import sys
+import os 
+import struct
+
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+# Adding the utility python scripts to the python PATH
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+
+    
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+
+from cert_cfg_parser_util import *
+
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+from key_data_structures import *
+import string
+from global_defines import *
+from ctypes import *
+import global_defines
+import configparser
+from cert_basic_utilities import *
+
+####################################################################
+# Filename - sb_key_util.py
+# Description - This file contains the main functionality of the key 
+#               certificate generation.
+####################################################################
+
+
+########### Certificate utility functions ##########################
+
+# The GetSWVersion function returns CertSwVersion object with S/W version value
+def GetSWVersion(logFile, swVersionVal):    
+        
+    CertSwVersionObj = CertSwVersion(swVersionVal)
+
+    return CertSwVersionObj
+# End of GetSWVersion
+
+# The BinStrToList function takes a binary string and returns a list with HEX
+# representation for the bytes
+def BinStrToList(str1):    
+    TempList = list()
+    ConvList = list(str1.encode('iso-8859-1'))
+    for i in range(len(str1)):
+        TempList.append("0x%02x" % ConvList[i])
+        
+    return TempList
+# End of BinStrToList
+
+# The CreateCertBinFile opens a binary and text file and writes the certificate data into it 
+def Create_CertBinFile(logFile, binStr, txtList, certFileName):
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(certFileName, "wb")
+        FileObj.write(bytes(binStr.encode('iso-8859-1')))
+        FileObj.close()
+
+        # Assemble the text file name (cert + number 1 for primary , 2 for secondary + .txt)
+        certFileNameTxt = certFileName[:-4] + '_' + Cert_FileName + Cert_FileExtTxt
+        # Open a text file and write the data into it, in lines of 4 bytes
+        FileObj = open(certFileNameTxt, "w")
+        
+        NumOfChars = len(txtList)
+        FileObj.write("char cert_bin_image[] = {\n")
+        for i in range(NumOfChars):   
+            FileObj.write(txtList[i])
+            if i !=  NumOfChars-1:
+                FileObj.write(',')
+            if (i+1) % 4 == 0:
+                FileObj.write('\n')
+        FileObj.write("}")
+        FileObj.close()    
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %certFileName)
+        sys.exit(1)
+    return       
+# End of CreateCertBinFile	
+
+def CreateWordsListFromBytesList(BytesList):
+    # Create words in reverse order
+    wordsList = list()
+    length = len(BytesList)/4        
+    for i in range(int(length)):
+        tmpStr = str()
+        for j in range(4):                
+            byte = str()
+            byte = BytesList[i*4 + 4 - j - 1]
+            byte = byte[2:]
+            tmpStr = tmpStr + byte
+        tmpStr = '0x' + tmpStr   
+        wordsList.append(tmpStr)
+    return wordsList    
+            
+
+########### certificate creation - Utility functions End ###########
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_key_cert.log"
+    return config_fname, log_fname
+
+
+# The function analyzes the input files and creates a key certificate binary file to be used in the
+# The function does the following steps:
+# 1. Create the certificate header and add to list 
+# 2. Create RSA public key parameters and add to list
+# 3. Create SW version parameters and add to list
+# 4. Add the next public key HASH
+# 5. In a loop create binary string out of the certificate so far (header + public key + sw version + HASH)
+# 6. Do RSA signature over the HASH value of the certificate so far
+# 7. Build the end of the certificate
+# 8. Write the certificate as binary and text string to file
+#
+# In case an error occurs the function throws exception and exits
+#################################################################################
+
+def CreateCertUtility(sysArgsList):        
+    try:          
+        config_fname, log_fname =  parse_shell_arguments()
+             
+        log_file = create_log_file(log_fname)             
+        # Check the input parameters and save it to list
+        ArgsDict, config = key_cert_config_file_parser(config_fname, log_file)
+        if ArgsDict == None:
+               log_file.close()
+               exit(1) 
+
+                
+        print_and_log(log_file, "**** Creating Key certificate Table **** ")
+        # Create the certificate objects and add it to a list
+        CertDataList = list()
+        DLLHandle = LoadDLLGetHandle()        
+        
+        print_and_log(log_file, "\n Prepare certificate header ")
+        # Create the certificate header and add to list -> header includes 
+        CertDataList.append(CertHeader(log_file, ArgsDict['hbk_id'], CERT_TYPE_KEY, 0, 0, 0, 0, PrjDefines))
+
+        print_and_log(log_file, "\n Create RSA public key parameters to insert to the certificate")        
+        # Create RSA key parameters and add to list (according to which Public key derivative is used)               
+        RSAPubKey = GetRSAKeyParams(log_file, ArgsDict['cert_keypair'], ArgsDict['cert_keypair_pwd'], DLLHandle)        
+        
+        CertDataList.append(RSAPubKey)
+
+        print_and_log(log_file, "\n Get SW version parameters")
+        # Create SW version parameters and add to list
+        CertDataList.append(GetSWVersion(log_file, ArgsDict['nvcounter_val']))
+        
+        # Add HASH of next certificate public key 
+        print_and_log(log_file, "\n Create HASH of public key and Np of the next certificate")
+        CertDataList.append(GetPubKeyHash(log_file, ArgsDict['next_cert_pubkey'], DLLHandle))
+        
+        print_and_log(log_file, "\n Create the certificate as binary string and calculate RSA signature on it")
+        # In a loop create binary string out of the certificate so far (header + public key + sw version + pub key HASH)
+        BinStr = str()
+        for obj in CertDataList:                        
+            BinStr = BinStr + obj.VarsToBinString()
+
+        # Do RSA signature  
+        Signature = GetRSASignature(log_file, BinStr, ArgsDict['cert_keypair'], ArgsDict['cert_keypair_pwd'], DLLHandle)
+        
+        print_and_log(log_file, "\n Add the signature to the certificate ")
+        # Build the end of the certificate - add the signature
+        
+        BinStr = BinStr + Signature.VarsToBinString()
+        
+        print_and_log(log_file, "\n Write the certificate to file ")
+        # Write binary and text string to file    
+        Create_CertBinFile(log_file, BinStr, BinStrToList(BinStr), ArgsDict['cert_pkg']) 
+         
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+      
+        
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print_and_log(log_file, "I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print_and_log(log_file, "Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print_and_log(log_file, "Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_sb_content_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_sb_content_util.py
new file mode 100755
index 0000000..bed6c04
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/cert_sb_content_util.py
@@ -0,0 +1,281 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Content certificate structure is :
+#       FIELD NAME                                                  SIZE (words)
+#       ----------                                                  ------------
+#       Header token                                                   1
+#       version number                                                 1
+#       size in words (offset to signature)                            1
+#       Flags                                                          1
+#       N Pub key                                                     96
+#       Np                                                             5
+#       active SW version                                              1
+#       NONCE                                                          2
+#       signed S/W records(hash + load address + max size + flag)    N * (8+3)
+#       RSA Signature                                                 96
+#       none-signed S/W records(storage address + actual size)       N * (2)                
+#
+
+
+import sys
+import os 
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+# Adding the utility python scripts to the python PATH
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+
+from cert_cfg_parser_util import *
+
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+from key_data_structures import *
+from cnt_data_structures import *
+import string
+from global_defines import *
+from ctypes import *
+import global_defines
+import configparser
+import re
+from cert_basic_utilities import *
+
+####################################################################
+# Filename - securebootutility.py
+# Description - This file contains the main functionality of the
+#               secure boot utility. The utility creates a certificate
+#               that is used in the secure boot process
+####################################################################
+
+########### Certificate utility functions ##########################
+
+# The GetSWVersion function returns CertSwVersion object with S/W version value
+def GetSWVersion(logFile, swVersionVal):    
+    CertSwVersionObj = CertSwVersion(swVersionVal)
+
+    return CertSwVersionObj
+# End of GetSWVersion
+
+# The BinStrToList function takes a binary string and returns a list with HEX
+# representation for the bytes
+def BinStrToList(str1):    
+    TempList = list()
+    ConvList = list(str1.encode('iso-8859-1'))
+    for i in range(len(str1)):
+        TempList.append("0x%02x" % ConvList[i])
+        
+    return TempList
+# End of BinStrToList
+
+# The CreateCertBinFile opens a binary and text file and writes the certificate data into it 
+def Create_CertBinFile(logFile, binStr, txtList, certFileName):
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(certFileName, "wb")
+        FileObj.write(bytes(binStr.encode('iso-8859-1')))
+        FileObj.close()
+
+        # Assemble the text file name (certificate + .txt)
+        certFileNameTxt = certFileName[:-4] + '_' + Cert_FileName + Cert_FileExtTxt
+        # Open a text file and write the data into it, in lines of 4 bytes
+        FileObj = open(certFileNameTxt, "w")
+        
+        NumOfChars = len(txtList)
+        FileObj.write("char cert_bin_image[] = {\n")
+        for i in range(NumOfChars):   
+            FileObj.write(txtList[i])
+            if i !=  NumOfChars-1:
+                FileObj.write(',')
+            if (i+1) % 4 == 0:
+                FileObj.write('\n')
+        FileObj.write("}")
+        FileObj.close()    
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %certFileName)
+        sys.exit(1)
+    return       
+# End of CreateCertBinFile	
+
+def CreateWordsListFromBytesList(BytesList):
+    # Create words in reverse order
+    wordsList = list()
+    length = len(BytesList)/4        
+    for i in range(int(length)):
+        tmpStr = str()
+        for j in range(4):                
+            byte = str()
+            byte = BytesList[i*4 + 4 - j - 1]
+            byte = byte[2:]
+            tmpStr = tmpStr + byte
+        tmpStr = '0x' + tmpStr   
+        wordsList.append(tmpStr)
+    return wordsList    
+            
+
+########### certificate creation - Utility functions End ###########
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_content_cert.log"
+    return config_fname, log_fname
+
+# The function analyzes the input files and creates a content certificate binary file to be used in the
+# secure boot process. 
+# The function does the following steps:
+# 1. Extract and analyze image table information
+# 2. Create the certificate header and add to list 
+# 3. Create RSA public key parameters and add to list
+# 4. Create SW version parameters and add to list
+# 5. Add the next public key HASH
+# 6. In a loop create binary string out of the certificate so far (header + public key + sw version + HASH)
+# 7. Create signed S/W records to all images
+# 8. Do RSA signature over the HASH value of the certificate so far
+# 9. Create none-signed S/W records to all images
+# 10. Write the certificate as binary and text string to file
+
+# In case an error occurs the function throws exception and exits
+#################################################################################
+
+def CreateCertUtility(sysArgsList):        
+    try:          
+        config_fname, log_fname =  parse_shell_arguments()
+             
+        log_file = create_log_file(log_fname)             
+        # Check the input parameters and save it to list
+        ArgsDict, config = content_cert_config_file_parser(config_fname, log_file)
+        if ArgsDict == None:
+               log_file.close()
+               exit(1) 
+
+                
+        print_and_log(log_file, "**** Creating Content Certificate **** ")
+        # Create the certificate objects and add it to a list
+        CertDataList = list()
+        DLLHandle = LoadDLLGetHandle()        
+        
+        # Create nonce if code encryption is supported
+        keyNonce = KeyNonce(ArgsDict['aes_ce_id'], DLLHandle)                  
+
+        # Create list out of the sw component file (create HASH & addresses), the list contains data records objects
+        # In case the code encryption is supported the SW component will also be encrypted        
+        print_and_log(log_file, "\n Analyze the list of s/w components and create HASH value for each component")
+        
+        RecList = ImageFileAnalyzer(log_file, ArgsDict['images_table'], ArgsDict['load_verify_scheme'], ArgsDict['aes_ce_id'], DLLHandle, ArgsDict['aes_enc_key'], keyNonce.randStr, ArgsDict['crypto_type'])
+
+        print_and_log(log_file, "\n Prepare Certificate header ")
+        # Create the certificate header and add to list -> header includes 
+        CertDataList.append(CertHeader(log_file, int('0xf',16), CERT_TYPE_CONTENT, ArgsDict['aes_ce_id'], ArgsDict['load_verify_scheme'], ArgsDict['crypto_type'], len(RecList), PrjDefines))
+
+        print_and_log(log_file, "\n Create RSA public key parameters to insert to the certificate")        
+        # Create RSA key parameters and add to list (according to which Public key derivative is used)               
+        RSAPubKey = GetRSAKeyParams(log_file, ArgsDict['cert_keypair'], ArgsDict['cert_keypair_pwd'], DLLHandle)        
+        
+        CertDataList.append(RSAPubKey)
+
+        print_and_log(log_file, "\n Get SW version parameters")
+        # Create SW version parameters and add to list
+        CertDataList.append(GetSWVersion(log_file, ArgsDict['nvcounter_val']))
+        
+        # Add the nonce in case code encryption is supported        
+        CertDataList.append(keyNonce)
+        
+        print_and_log(log_file, "\n Create the certificate as binary string and calculate RSA signature on it")
+        # In a loop create binary string out of the certificate so far (header + public key + sw version + pub key HASH)
+        BinStr = str()
+        for obj in CertDataList:                        
+            BinStr = BinStr + obj.VarsToBinString()
+
+        # In a loop add the component objects to the binary string (only if not empty)
+        for obj in RecList:
+            BinStr = BinStr + obj.VarsToBinStringHashComp()
+
+        # Do RSA signature  
+        Signature = GetRSASignature(log_file, BinStr, ArgsDict['cert_keypair'], ArgsDict['cert_keypair_pwd'], DLLHandle)
+        
+        print_and_log(log_file, "\n Add the signature to the certificate ")
+        # Build the end of the certificate - add the signature
+        
+        BinStr = BinStr + Signature.VarsToBinString()
+        
+        # Add the none-signed info data        
+        for obj in RecList:
+            BinStr = BinStr + obj.VarsToBinStringParamComp()
+
+        print_and_log(log_file, "\n Write the certificate to file ")
+        # Write binary and text string to file    
+        Create_CertBinFile(log_file, BinStr, BinStrToList(BinStr), ArgsDict['cert-pkg']) 
+         
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+      
+        
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print("I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print("Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print("Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/hbk_gen_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/hbk_gen_util.py
new file mode 100755
index 0000000..6cecd14
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/cert_utils/hbk_gen_util.py
@@ -0,0 +1,236 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+import sys
+import os 
+from datetime import datetime
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+import string
+from ctypes import *
+from cert_basic_utilities import * 
+
+OUTPUT_SIZE_SHA_256 = 32
+OUTPUT_SIZE_SHA_256_TRUNC = int(OUTPUT_SIZE_SHA_256/2)
+BITS_WITHIN_WORD = 32
+BYTES_WITHIN_WORD = 4
+
+# Prim key hash file name
+PRIM_KEY_HASH_FILE_NAME = "prim_key_hash.txt"
+ZEROS_NUM_FILES_NAME = "zero_bits_in_hash.txt" 
+
+####################################################################
+# Filename - hbk_gen_util.py
+# Description - This file is responsible for creation of public key
+#               HASH and its corresponding number of Zeroes
+#               as it should be saved in the OTP/NVM
+####################################################################
+
+#################### Utility functions #############################
+
+# The function creates words list out of a string that contains hex
+# resrepesentation
+def CreateWordList(buff, buffWordSize, endiannes):
+
+    wordList = list()
+    
+    for i in range(int(buffWordSize)):
+        word = 0
+        if endiannes == 'L':
+            #int(buff[i].encode('hex'),16)
+            word = buff[i*4]
+            word = word+(buff[i*4+1]<<8)
+            word = word+(buff[i*4+2]<<16)
+            word = word+(buff[i*4+3]<<24)
+        else:
+            word = buff[i*4+3]
+            word = word+(buff[i*4+2]<<8)
+            word = word+(buff[i*4+1]<<16)
+            word = word+(buff[i*4]<<24)
+        wordList.append(format(word, 'x'))
+
+    return wordList    
+
+
+####################################################################
+
+
+# The function calculates the number of Zeroes for a given data
+def CalculateZeroBitCountOnData(HASHwordList, size):    
+#total number of zeros, start value
+    zero_sum = int(0)
+    
+    for word in HASHwordList:
+        if size == 0:
+            break
+        #1's bit count start value
+        count = 0
+        intWord = int(word, 16)        
+        while (intWord):      
+            count += (intWord & 1)
+            intWord >>= 1                      
+        zero_sum += (BITS_WITHIN_WORD - count)
+        size -=1
+    
+    return zero_sum
+
+      
+# The function writes the output to output files 
+# (a file for the HASH and a different file for the HBK num of Zeroes)
+# File names are fixed
+def WriteOutputToFile(HASHwordList, buffData, size, hash_file ,zeros_file):
+    fobHash = open(hash_file, 'w')
+    fobZeroNum = open(zeros_file, 'w')
+    
+    # The output is already set in the required endianess
+    for i in range(size):
+        if i != size - 1:
+            # Unless it is the last word add comma
+            fobHash.write(" 0x"+HASHwordList[i]+",")
+        else:
+            fobHash.write(" 0x"+HASHwordList[i] +" ")
+
+    # Write the num of zeroes to output file    
+    fobZeroNum.write(buffData)
+
+    # Close files        
+    fobHash.close()
+    fobZeroNum.close()
+    
+    return
+
+
+# This function prints the instructions of how to operate the utility
+def usage():
+    print("""Syntax: ./hbk_gen_util.py -key <RSA public-key file name> -endian <optional endianness> -hash_format <optional hash_format> \n
+hbk_gen_util.py creates HASH over concatenation of N (public key) and Np (Barrett N' value) and calculates number of zero bits over the HASH value.\n
+Input arguments:\n
+-key <RSA public key file name> - mandatory, RSA public key in PEM format\n
+-endian <endianness, B||L> - optional, endianness flag, B for Big endian or L for little endian; default is little endian\n
+-hash_format <[SHA256 | SHA256_TRUNC]> - optional, HASH algorithm identifier determines the hash public key size; default is SHA256\n
+outputs:\n
+"prim_key_hash.txt" - file containing primary key hash text file in word format\n
+"zero_bits_in_hash.txt" - file containing number of zeros for primary key hash\n 
+""")
+    sys.exit(1)
+
+
+# The function parses the input parameters and returns a list of the given parameters 
+def parse_shell_arguments():
+    # Input parameters are :
+    # -key [RSA pubkey name] - mandatory, RSA public key name
+    # -endian <endianness, B||L> - optional, endianness flag, B for Big endian or L for little endian
+    # -hash_format <[SHA256 | SHA256_TRUNC]> - optional, HASH algorithm identifier determines the hash public key size
+
+    sysArgsList = sys.argv
+
+    # check if the key exist if not return error
+    if "-key" in sysArgsList:
+        key_fname = sysArgsList[sysArgsList.index("-key") + 1]
+    else:
+        print("-key [RSA public key file name] is mandatory")
+        usage()
+        sys.exit(1)
+
+    # Read the endianity and set it in the project defines list 
+    if "-endian" in sysArgsList:
+        endianity = sysArgsList[sysArgsList.index("-endian") + 1]
+        if (endianity != 'B' and endianity != 'L'):
+            print("-endian <[B | L]> is illegal")
+            usage()
+            sys.exit(1)
+    else:
+        endianity = "L"
+
+    # check if the hash_format exist; if not, set default to SHA256
+    if "-hash_format" in sysArgsList:
+        hbk_format = sysArgsList[sysArgsList.index("-hash_format") + 1]
+        if (hbk_format != 'SHA256' and hbk_format != 'SHA256_TRUNC'):
+            print("-hash_format <[SHA256 | SHA256_TRUNC]> is illegal")
+            usage()
+            sys.exit(1)
+    else:
+        hbk_format = "SHA256"
+        
+    if "-hash_out" in sysArgsList:
+        hash_file =  sysArgsList[sysArgsList.index("-hash_out") + 1]
+    else:
+        hash_file = PRIM_KEY_HASH_FILE_NAME
+        
+    if "-zeros_out" in sysArgsList:
+        zeros_file =  sysArgsList[sysArgsList.index("-zeros_out") + 1] 
+    else:
+        zeros_file = ZEROS_NUM_FILES_NAME
+    
+    return key_fname, endianity, hbk_format, hash_file, zeros_file
+
+##########################################################################################################
+
+# Main functin, responsible for creating HASH value over N | Np and and the corresponding number of Zeroes value.
+# The function expects the following inputs :
+# 1. RSA public key file name mandatory (key file expected to be in openSSL PEM format)
+# 2. Output format flag (L||B) little or big endian (optional, if not given L - little endian will be used) 
+# 3. hash_format (SHA256||SHA256_TRUNC) (optional, if not given HASH SHA256 size will be used)
+# The output will be written to two files: PrimKeyHASH.txt & ZeroBitsInHASH.txt
+def main():
+
+    pubKeyFileName, endianness, hash_format ,hash_file ,zeros_file= parse_shell_arguments()
+    log_file = create_log_file("gen_hbk_log.log")
+    print_and_log(log_file, str(datetime.now()) + ": generate HBK Utility started (Logging to gen_hbk_log.log)\n")
+
+    #print_and_log(log_file, "**** loading library ****\n ") 
+    DLLHandle = LoadDLLGetHandle()        
+
+    # decide on hash output size
+    if (hash_format == 'SHA256'):
+        outputSize = OUTPUT_SIZE_SHA_256  
+    else:
+        outputSize = OUTPUT_SIZE_SHA_256_TRUNC  
+
+    outputWordSize = int(round(outputSize/BYTES_WITHIN_WORD))  
+
+    print_and_log(log_file, "\nStep 1 calculate hash")
+    IntArrayParam = c_ubyte * outputSize
+    publicKeyHash = IntArrayParam()
+    result = DLLHandle.SBU_GetHashOfNAndNpFromPubKey(str.encode(pubKeyFileName), byref(publicKeyHash), outputSize)
+    if result != 0:
+        print_and_log(log_file,  "unable to calc hash for " + str.encode(pubKeyFileName) + "\n")
+        sys.exit(1)
+
+    HASHWordsList = CreateWordList(publicKeyHash, outputWordSize, endianness)
+
+    print_and_log(log_file, "\nStep 2 - Calculate num of zero bits over the HASH")
+    # Calculate the num of zeroes on the data & write it to files
+    WriteOutputToFile(HASHWordsList, str(hex(CalculateZeroBitCountOnData(HASHWordsList,outputWordSize))), outputWordSize,hash_file ,zeros_file)
+    
+    print_and_log(log_file, "\nFunction completed successfully")
+
+    sys.exit(0)
+
+
+#############################
+if __name__ == "__main__":
+    main()
+    
+    
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_basic_utilities.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_basic_utilities.py
new file mode 100644
index 0000000..27886b7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_basic_utilities.py
@@ -0,0 +1,187 @@
+#****************************************************************
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+import sys, traceback
+import os
+import re
+import global_defines
+from global_defines import *
+from ctypes import *
+import binascii
+
+
+CURRENT_PATH = sys.path[0]
+
+####################################################################
+# Filename - basic_utilites.py
+# Description - This file contains basic utilities functions
+####################################################################
+
+# The function returns the path of the DLL - fixed path (relative to script path)
+def GetDLLPath(FileName):
+    
+    path = str()    
+    path = CURRENT_PATH    
+    # split according to dir names
+    if sys.platform != "win32" :
+        path_div = "/"    
+    else : #platform = win32
+        path_div = "\\"
+    
+    path_new = path + path_div + ".." + path_div
+        
+    path_new = path_new + FileName        
+    return path_new
+# End of GetDLLPath
+        
+# The function loads the crypto DLL and returns its handle
+def LoadDLLGetHandle():
+    # Load the crypto libraries
+    if sys.platform != "win32" : # Unix paths
+        global_defines.SBU_LibName = SBU_CRYPTO_LIB_Name
+        global_defines.SBU_OpenSSLCrypto_LibName = SBU_OSSL_CRYPTO_LIB_Name
+        global_defines.SBU_OpenSSLSSL_LibName = SBU_OSSL_LIB_Name
+    SBU_Crypto = cdll.LoadLibrary(GetDLLPath(global_defines.SBU_LibName))
+    return SBU_Crypto
+# End of LoadDLLGetHandle
+
+# log functions
+# Create a log file handle
+def create_log_file (log_file_path):
+    try:
+        log_file = open(log_file_path, 'w')
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print("Error in openning file - %s" %log_file_path)
+        sys.exit(1)
+    return log_file;
+
+# Print (stdout) and output also to log file given text
+def print_and_log (log_file, text):
+    print(text)
+    log_file.write(text)
+    sys.stdout.flush()
+    log_file.flush()
+
+# Print (stdout) and output also to log file given text
+def print_exception ():
+    traceback.print_exc(file=sys.stdout) 
+
+# Do synchronous write to log file
+def log_sync (log_file, text):
+        log_file.write(text)
+        log_file.flush()
+
+# Convert bytes to string
+def byte2stringBytesArray(DataBinBytes):
+    ResStr = str()
+    for i in range(len(DataBinBytes)):        
+        ResStr = ResStr + chr(DataBinBytes.raw[i])
+    return ResStr
+
+# The ReverseBytesinBinString function takes a binary string and reverse it
+def ReverseBytesinBinString(binStr): 
+    return binStr[::-1]
+# End of ReverseBytesinBinString
+
+# The ReverseBytesInString function reverse the bytes in a string and returns the reversed string
+def ReverseBytesInString(str1, strSize):   
+    str2 = str() 
+    if isinstance(str1, str):
+        TempStr = str1
+    else:              
+        TempStr = str1.decode("utf-8")
+    for i in range(strSize//2):
+        str2 = str2 + TempStr[strSize-i*2-2:strSize-i*2]
+    return str2
+# End of ReverseBytesInString
+
+# The ReverseBytesInString function reverse the bytes in a string and returns the reversed string
+def ReverseBytesInBytesArray(array, size):   
+
+    reversedArray = c_ubyte * size
+    revArray = reversedArray()
+    for i in range(size//4):
+        # reverse each word
+        for j in range(4):
+            revArray[4*i + j] = array[4*i + 3 - j]
+    return revArray
+# End of ReverseBytesInString
+
+
+# Convert bytes to string
+def byte2string (DataBinStr):
+    if type(DataBinStr).__name__ == 'str' :
+        return DataBinStr
+    ResStr = str()
+    for i in range(len(DataBinStr)) :
+        ResStr = ResStr + chr(DataBinStr[i])
+    return ResStr
+
+# Do synchronous print to appear immediately on the console
+def print_sync (text):
+    print (text)
+    sys.stdout.flush()
+
+
+
+
+# The CreateCertBinFile opens a binary and text file and writes the certificate data into it 
+def CreateCertBinFile(logFile, binStr, certFileName):
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(certFileName, "wb")
+        FileObj.write(bytes(binStr.encode('iso-8859-1')))
+        FileObj.close()
+
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %certFileName)
+        sys.exit(1)
+    return       
+# End of CreateCertBinFile            
+
+# The GetDataFromBinFile gets the data from a binary file
+def GetDataFromBinFile(logFile, certFileName):
+    binStr = str()
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(certFileName, "rb")
+        binStr = FileObj.read()
+        FileObj.close()
+
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %certFileName)
+        sys.exit(1)
+    return binStr     
+
+
+
+# parse configuration file according to list of parameters
+def parseConfFile(FileName, listOfDefines):
+    try:
+        fob = open(FileName,'r')
+        lines = fob.readlines()
+        valuesList = list()
+        for line in lines:
+            for define in listOfDefines:
+                if re.match(define,line):
+                    tmpList=line.split("=")
+                    valuesList.append(int(tmpList[len(tmpList)-1],16))
+        fob.close()
+    except IOError as Error1:
+        (errno, strerror) = Error1.args
+        print("\n Error in openning file - %s" %FileName)
+        sys.exit(1)
+        
+    return valuesList
+# End of parseConfFile
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_cfg_parser_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_cfg_parser_util.py
new file mode 100755
index 0000000..1230f3a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_cfg_parser_util.py
@@ -0,0 +1,384 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import sys
+import configparser
+from global_defines import *
+from cert_dbg_util_gen import *
+from cert_basic_utilities import *
+from cert_dbg_util_data import *
+
+# Parse given configuration file and return attributes as dictionary
+def key_cert_config_file_parser(config_fname, log_file):
+
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.readfp(config_file)
+    config_file.close()    
+    
+    local_dict = dict()
+    section_name = "KEY-CFG"
+    if not config.has_section(section_name):
+        print_and_log(log_file, "section " + section_name + " wasn't found in cfg file\n")        
+        return None, None
+
+    local_dict['cert_keypair'] = config.get(section_name, 'cert-keypair')                         
+    log_sync(log_file,"cert-keypair: " + local_dict['cert_keypair'] + "\n")                       
+
+    if config.has_option(section_name, 'cert-keypair-pwd'):
+        local_dict['cert_keypair_pwd'] = config.get(section_name, 'cert-keypair-pwd')                     
+        log_sync(log_file,"cert-keypair-pwd: " + local_dict['cert_keypair_pwd'] + "\n")
+    else:
+        local_dict['cert_keypair_pwd'] = ''                     
+
+    local_dict['hbk_id'] = int(config.get(section_name, 'hbk-id'))
+    if (local_dict['hbk_id'] != int(0) and local_dict['hbk_id'] != int(1) and local_dict['hbk_id'] != int(2)) :
+            log_sync(log_file, "Illegal hbk-id defined - exiting\n")
+            return None, None
+    log_sync(log_file,"hbk-id: " + str(local_dict['hbk_id']) + "\n")  
+
+    local_dict['nvcounter_val'] = int(config.get(section_name, 'nvcounter-val'))                                         
+    log_sync(log_file,"nvcounter-val: " + str(local_dict['nvcounter_val']) + "\n") 
+
+    # verify nvcounter_val according to HBK
+    if local_dict['hbk_id'] == int(0):
+        maxVal = SW_REVOCATION_MAX_NUM_OF_BITS_HBK0
+    else:
+        if local_dict['hbk_id'] == int(1):
+            maxVal = SW_REVOCATION_MAX_NUM_OF_BITS_HBK1
+        else:
+            maxVal = SW_REVOCATION_MAX_NUM_OF_BITS_HBK2
+    if (local_dict['nvcounter_val'] > maxVal):
+        log_sync(log_file, "Ilegal nvcounter-val\n")
+        return None, None
+
+    local_dict['next_cert_pubkey'] = config.get(section_name, 'next-cert-pubkey')                         
+    log_sync(log_file,"next-cert-pubkey: " + local_dict['next_cert_pubkey'] + "\n")  
+
+    local_dict['cert_pkg'] = config.get(section_name, 'cert-pkg')                         
+    log_sync(log_file,"cert-pkg: " + local_dict['cert_pkg'] + "\n")   
+        
+    return local_dict, config
+
+# Parse given configuration file and return attributes as dictionary
+def content_cert_config_file_parser (config_fname, log_file):
+
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.readfp(config_file)
+    config_file.close()    
+    
+    local_dict = dict()
+    
+    section_name = "CNT-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None, None
+
+    local_dict['cert_keypair'] = config.get(section_name, 'cert-keypair')                         
+    log_sync(log_file,"cert-keypair: " + local_dict['cert_keypair'] + "\n")                       
+
+    if config.has_option(section_name, 'cert-keypair-pwd'):
+        local_dict['cert_keypair_pwd'] = config.get(section_name, 'cert-keypair-pwd')                     
+        log_sync(log_file,"cert-keypair-pwd: " + local_dict['cert_keypair_pwd'] + "\n")
+    else:
+        local_dict['cert_keypair_pwd'] = ''                     
+
+    local_dict['nvcounter_val'] = int(config.get(section_name, 'nvcounter-val'))                                         
+    log_sync(log_file,"nvcounter-val: " + str(local_dict['nvcounter_val']) + "\n") 
+
+    # verify nvcounter_val according to HBK2
+    maxVal = SW_REVOCATION_MAX_NUM_OF_BITS_HBK2
+    if (local_dict['nvcounter_val'] > maxVal):
+        log_sync(log_file, "Ilegal nvcounter-val\n")
+        return None, None
+
+    local_dict['load_verify_scheme'] = int(config.get(section_name, 'load-verify-scheme'))                                         
+    if (local_dict['load_verify_scheme'] != int(0) and local_dict['load_verify_scheme'] != int(1) and local_dict['load_verify_scheme'] != int(2) and local_dict['load_verify_scheme'] != int(3)) :
+            log_sync(log_file, "Illegal load_verify_scheme defined - exiting\n")
+            return None, None
+    log_sync(log_file,"load-verify-scheme: " + str(local_dict['load_verify_scheme']) + "\n") 
+          
+    local_dict['aes_ce_id'] = int(config.get(section_name, 'aes-ce-id'))                                         
+    if (local_dict['aes_ce_id'] != int(0) and local_dict['aes_ce_id'] != int(1) and local_dict['aes_ce_id'] != int(2)) :
+            log_sync(log_file, "Illegal aes_ce_id defined - exiting\n")
+            return None, None
+    log_sync(log_file,"aes-ce-id: " + str(local_dict['aes_ce_id']) + "\n") 
+
+    if (local_dict['aes_ce_id'] != int(0)):
+        local_dict['aes_enc_key'] = config.get(section_name, 'aes-enc-key')                     
+        log_sync(log_file,"aes-enc-key: " + local_dict['aes_enc_key'] + "\n")
+        local_dict['crypto_type'] = int(config.get(section_name, 'crypto-type'))                                         
+        if (local_dict['crypto_type'] != int(0) and local_dict['crypto_type'] != int(1)) :
+                log_sync(log_file, "Illegal crypto_type defined - exiting\n")
+                return None, None
+        log_sync(log_file,"crypto-type: " + str(local_dict['crypto_type']) + "\n") 
+
+    else:
+        local_dict['aes_enc_key'] = None     
+        local_dict['crypto_type'] = int(0) 
+
+    local_dict['images_table'] = config.get(section_name, 'images-table')                         
+    log_sync(log_file,"images-table: " + local_dict['images_table'] + "\n")
+       
+    local_dict['cert-pkg'] = config.get(section_name, 'cert-pkg')                         
+    log_sync(log_file,"cert-pkg: " + local_dict['cert-pkg'] + "\n")       
+        
+    return local_dict, config
+
+
+
+
+
+
+# Parse given test configuration file and return test attributes as dictionary
+def enabler_cert_config_file_parser (config_fname, log_file):
+
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.readfp(config_file)
+    config_file.close()    
+    
+    local_dict = dict()
+    
+    section_name = "ENABLER-DBG-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None, None
+
+    is_debug = 0
+    if config.has_option(section_name, 'debug-mask[0-31]'): 
+        debug_mask0 = int(config.get(section_name, 'debug-mask[0-31]'), 16)
+        debug_mask1 = int(config.get(section_name, 'debug-mask[32-63]'), 16)
+        debug_mask2 = int(config.get(section_name, 'debug-mask[64-95]'), 16)
+        debug_mask3 = int(config.get(section_name, 'debug-mask[96-127]'), 16)
+
+        debug_lock0 = int(config.get(section_name, 'debug-lock[0-31]'), 16)
+        debug_lock1 = int(config.get(section_name, 'debug-lock[32-63]'), 16)
+        debug_lock2 = int(config.get(section_name, 'debug-lock[64-95]'), 16)
+        debug_lock3 = int(config.get(section_name, 'debug-lock[96-127]'), 16)
+        is_debug = 1
+
+    is_rma = 0
+    if config.has_option(section_name, 'rma-mode'): 
+        rma_mode = int(config.get(section_name, 'rma-mode'))
+        if rma_mode != int(0):
+            log_sync(log_file, "rma_mode " + str(rma_mode) + "\n")
+            is_rma = 1
+
+    is_hbk = 0
+    if config.has_option(section_name, 'hbk-id'): 
+        hbk_id = int(config.get(section_name, 'hbk-id'))
+        if (hbk_id == int(0) or hbk_id == int(1) or hbk_id == int(2)):
+                log_sync(log_file, "hbk_id " + str(hbk_id) + "\n")
+                is_hbk = 1
+        else:
+            log_sync(log_file, "Invalid HBK ID - exiting\n")
+            return None, None
+            
+
+    is_key_pkg = 0
+    if config.has_option(section_name, 'key-cert-pkg'): 
+        key_pkg = config.get(section_name, 'key-cert-pkg')
+        log_sync(log_file, "key_pkg " + key_pkg + "\n")
+        is_key_pkg = 1
+
+    if is_rma == 1  and is_debug == 1:
+        log_sync(log_file, "Both RMA and debug mode are defined - exiting\n")
+        return None, None
+    if is_rma == 0 and is_debug == 0:
+        log_sync(log_file, "RMA nor Debug mode not defined - exiting\n")
+        return None, None
+
+    if is_key_pkg == 0 and is_hbk == 0:
+        log_sync(log_file, "hbk-id nor key-cert-pkg not defined - exiting\n")
+        return None, None
+
+    if is_key_pkg == 1 and is_hbk == 1:
+        log_sync(log_file, "hbk-id and key-cert-pkg defined - exiting\n")
+        return None, None
+    
+
+    local_dict['debug_mask0'] = int(0)                                         
+    local_dict['debug_mask1'] = int(0)                                         
+    local_dict['debug_mask2'] = int(0)                                         
+    local_dict['debug_mask3'] = int(0)                                         
+    local_dict['debug_lock0'] = int(0)                                         
+    local_dict['debug_lock1'] = int(0)                                         
+    local_dict['debug_lock2'] = int(0)                                         
+    local_dict['debug_lock3'] = int(0)                                         
+    local_dict['rma_mode'] = int(0)
+    local_dict['hbk_id'] = int(0xF)
+    local_dict['key_cert_pkg'] = ""                         
+
+    if is_debug == 1: 
+        local_dict['debug_mask0'] = debug_mask0
+        log_sync(log_file,"debug-mask0: " + str(local_dict['debug_mask0']) + "\n")
+        local_dict['debug_mask1'] = debug_mask1
+        log_sync(log_file,"debug-mask1: " + str(local_dict['debug_mask1']) + "\n")
+        local_dict['debug_mask2'] = debug_mask2
+        log_sync(log_file,"debug-mask2: " + str(local_dict['debug_mask2']) + "\n")
+        local_dict['debug_mask3'] = debug_mask3
+        log_sync(log_file,"debug-mask3: " + str(local_dict['debug_mask3']) + "\n")
+        local_dict['debug_lock0'] = debug_lock0
+        log_sync(log_file,"debug-lock0: " + str(local_dict['debug_lock0']) + "\n")
+        local_dict['debug_lock1'] = debug_lock1
+        log_sync(log_file,"debug-lock1: " + str(local_dict['debug_lock1']) + "\n")
+        local_dict['debug_lock2'] = debug_lock2
+        log_sync(log_file,"debug-lock2: " + str(local_dict['debug_lock2']) + "\n")
+        local_dict['debug_lock3'] = debug_lock3
+        log_sync(log_file,"debug-lock3: " + str(local_dict['debug_lock3']) + "\n")
+   
+    if is_hbk == 1:
+        local_dict['hbk_id'] = hbk_id
+        log_sync(log_file,"hbk-id: " + str(local_dict['hbk_id']) + "\n") 
+    
+    if is_key_pkg == 1:
+        local_dict['key_cert_pkg'] = key_pkg
+              
+    if is_rma == 1:
+        local_dict['rma_mode'] = int(1)
+        log_sync(log_file,"rma-mode: " + str(local_dict['rma_mode']) + "\n") 
+ 
+    local_dict['cert_keypair'] = config.get(section_name, 'cert-keypair')
+    log_sync(log_file,"cert-keypair: " + str(local_dict['cert_keypair']) + "\n")                       
+
+    if config.has_option(section_name, 'cert-keypair-pwd'): #used for testing
+        local_dict['cert_keypair_pwd'] = config.get(section_name, 'cert-keypair-pwd')                     
+        log_sync(log_file,"cert-keypair-pwd: " + str(local_dict['cert_keypair_pwd']) + "\n")
+    else:
+        local_dict['cert_keypair_pwd'] = ''                     
+
+    local_dict['lcs'] = int(config.get(section_name, 'lcs'))                                         
+    log_sync(log_file,"lcs: " + str(local_dict['lcs']) + "\n") 
+    if local_dict['lcs'] == int(0):
+        local_dict['lcs'] = CC_MNG_CHIP_MANUFACTURE_LCS
+    elif local_dict['lcs'] == int(1):
+        local_dict['lcs'] = CC_MNG_DEVICE_MANUFACTURE_LCS
+    elif local_dict['lcs'] == int(5):
+        local_dict['lcs'] = CC_MNG_SECURE_LCS
+    elif local_dict['lcs'] == int(7):
+        local_dict['lcs'] = CC_MNG_RMA_LCS
+    else:
+        log_sync(log_file, "Ilegal lcs defined - exiting\n")
+        return None, None
+
+    local_dict['next_cert_pubkey'] = config.get(section_name, 'next-cert-pubkey')
+    log_sync(log_file,"next-cert-pubkey: " + str(local_dict['next_cert_pubkey']) + "\n") 
+      
+    local_dict['cert_pkg'] = str.encode(config.get(section_name, 'cert-pkg'))
+    log_sync(log_file,"cert-pkg: " + str(local_dict['cert_pkg']) + "\n")   
+               
+    return local_dict, config
+
+
+
+
+# Parse given test configuration file and return test attributes as dictionary
+def developer_cert_config_file_parser (config_fname, log_file):
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.readfp(config_file)
+    config_file.close()    
+    
+    local_dict = dict()    
+    
+    section_name = "DEVELOPER-DBG-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None, None
+
+    local_dict['cert_keypair'] = config.get(section_name, 'cert-keypair')
+    log_sync(log_file,"cert-keypair: " + str(local_dict['cert_keypair']) + "\n")                       
+
+    if config.has_option(section_name, 'cert-keypair-pwd'): #used for testing
+        local_dict['cert_keypair_pwd'] = config.get(section_name, 'cert-keypair-pwd')
+        log_sync(log_file,"cert-keypair-pwd: " + str(local_dict['cert_keypair_pwd']) + "\n")
+    else:
+        local_dict['cert_keypair_pwd'] = ''                     
+
+    local_dict['soc_id'] = config.get(section_name, 'soc-id')
+    log_sync(log_file,"soc-id: " + local_dict['soc_id'] + "\n")            
+    local_dict['debug_mask0'] = int(config.get(section_name, 'debug-mask[0-31]'), 16) 
+    log_sync(log_file,"debug-mask0: " + str(local_dict['debug_mask0']) + "\n")  
+    local_dict['debug_mask1'] = int(config.get(section_name, 'debug-mask[32-63]'), 16) 
+    log_sync(log_file,"debug-mask1: " + str(local_dict['debug_mask1']) + "\n")  
+    local_dict['debug_mask2'] = int(config.get(section_name, 'debug-mask[64-95]'), 16) 
+    log_sync(log_file,"debug-mask2: " + str(local_dict['debug_mask2']) + "\n")  
+    local_dict['debug_mask3'] = int(config.get(section_name, 'debug-mask[96-127]'), 16) 
+    log_sync(log_file,"debug-mask3: " + str(local_dict['debug_mask3']) + "\n")  
+
+    local_dict['enabler_cert_pkg'] = config.get(section_name, 'enabler-cert-pkg')
+    log_sync(log_file,"enabler-cert-pkg: " + str(local_dict['enabler_cert_pkg']) + "\n")
+    local_dict['cert_pkg'] = config.get(section_name, 'cert-pkg')
+    log_sync(log_file,"cert-pkg: " + str(local_dict['cert_pkg']) + "\n")   
+                    
+    return local_dict, config
+
+
+
+
+
+# build flags word
+# accordinf to EnablerFlags_t
+def build_flag_word_enabler (isRmaCert, hbkId, lcsId):
+    flag = 0x00000000
+    flag = flag + (hbkId << HBK_ID_FLAG_BIT_OFFSET)
+    flag = flag + (lcsId << LCS_ID_FLAG_BIT_OFFSET)
+    flag = flag + (isRmaCert << RMA_CERT_FLAG_BIT_OFFSET)
+
+    return flag
+# End of build_flag_word_enabler
+
+# build flags word
+# accordinf to EnablerFlags_t
+def build_flag_word_developer ():
+    flag = 0x00000000
+
+    return flag
+# End of build_flag_word_enabler
+
+
+# the function builds the certificate header, header contains token, version, flags, length
+def build_certificate_header (token, PrjDefines, LIST_OF_CONF_PARAMS, isRmaCert, hbkId, lcsId):
+
+    certVersion = ((PrjDefines[LIST_OF_CONF_PARAMS.index("CERT_VERSION_MAJOR")]) << 16) | (PrjDefines[LIST_OF_CONF_PARAMS.index("CERT_VERSION_MINOR")])
+    certLength = HEADER_SIZE_IN_BYTES # token + version + length + flags
+    certLength =certLength + PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES # certificate public key + Np
+
+    if token == DEBUG_ENABLER_TOKEN:
+        certLength = certLength  + 4*BYTES_WITHIN_WORD + 4*BYTES_WITHIN_WORD + SHA_256_HASH_SIZE_IN_BYTES  #debug mask + debug lock + developer pubKey hash
+        flag = build_flag_word_enabler(isRmaCert, hbkId, lcsId)
+    else:
+        certLength = certLength + 4*BYTES_WITHIN_WORD + SOC_ID_SIZE_IN_BYTES   #debug mask + socId
+        flag = build_flag_word_developer()
+
+    certLength = (certLength >> 2)  # size in certificate is word size
+    headerStrBin = struct.pack('<I', token) + struct.pack('<I', certVersion) + struct.pack('<I', certLength) + struct.pack('<I', flag)
+
+    return byte2string(headerStrBin)
+# End of build_certificate_header
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_dbg_util_data.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_dbg_util_data.py
new file mode 100755
index 0000000..d2ed717
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_dbg_util_data.py
@@ -0,0 +1,62 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+# This file contains the general classes used in the code
+
+import configparser
+import sys
+from cert_basic_utilities import *
+from global_defines import *
+
+
+# This class represents N public key data
+class CertNPublicKey:
+
+    # Constructor
+    # Np can stand either for Np or for H
+    def __init__(self, PubKeyBinStr):
+        self.PubKey = PubKeyBinStr
+
+    # The method __len__ returns the size of pubkey N and Np (string size in bytes)
+    def __len__(self):
+        return(PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES)
+
+    # This method returns a binary string of the N string and Np string (N is set as big endian
+    # Np is set as little endian)   
+    def VarsToBinString(self):
+        DataBinStr = str()
+        PubKey = self.PubKey
+
+        for i in range(PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES): 
+            byte = PubKey[i]
+            DataBinStr = DataBinStr + byte2string(byte)
+
+        return DataBinStr
+
+# End of CertNPublicKey
+
+# This class holds the RSA signature
+class CertRSASignature:
+
+    # Constructor
+    def __init__(self, SignatureBinStr):
+        self.SignatureStr = SignatureBinStr
+
+    # The method returns the signature size
+    def __len__(self):
+        return RSA_SIGNATURE_SIZE_IN_BYTES
+
+    # This method returns the binary signature
+    def VarsToBinString(self):
+        DataBinStr = self.SignatureStr
+     
+        return byte2string(DataBinStr)
+
+# End of CertRSASignature
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_dbg_util_gen.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_dbg_util_gen.py
new file mode 100755
index 0000000..068f922
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cert_dbg_util_gen.py
@@ -0,0 +1,102 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+# This file contains the general functions that are used in both certificates
+
+import configparser
+import sys
+from global_defines import *
+from cert_basic_utilities import *
+from cert_dbg_util_data import *
+
+# The function GetRSAKeyParams reads the key file (in PEM format) parse it and gets the public and private RSA key data.
+# Set the N buffer (in binary representation) and calculates the Np (Barrett n' value).
+def GetRSAKeyParams(logFile, RSAKeyFileName, PassphraseFileName, SBU_Crypto):
+    publicKey = create_string_buffer(RSA_SIGNATURE_SIZE_BYTES + NP_SIZE_IN_BYTES)
+    result = SBU_Crypto.SBU_GetNAndNpFromKeyPair(str.encode(RSAKeyFileName), str.encode(PassphraseFileName), publicKey)
+    if result != 0:
+        print_and_log (logFile, "Error in public key | Np")
+        sys.exit(1)
+      
+    # Create the public key object and return it in binary format
+    return CertNPublicKey(publicKey)
+# End of GetRSAKeyParams
+
+# The function GetRSAPubKeyParams reads the public  key file (in PEM format) parse it and gets the public RSA key data.
+# Set the N buffer (in binary representation) and calculates the Np (Barrett n' value). the function returns string of N + Np
+def GetRSAPubKeyParams(logFile, RSAKeyFileName, SBU_Crypto):
+    publicKey = create_string_buffer(RSA_SIGNATURE_SIZE_BYTES + NP_SIZE_IN_BYTES)
+    result = SBU_Crypto.SBU_GetNAndNpFromPubKey(str.encode(RSAKeyFileName), publicKey)    
+    if result != 0:
+        print_and_log (logFile, "Error in public key | Np")
+        sys.exit(1)
+      
+    # Create the public key object and return it in binary format
+    return CertNPublicKey(publicKey)
+# End of GetRSAPubKeyParams
+
+# The function GetRSASignature calculates the RSA signature
+def GetRSASignature(logFile, DataIn, PrivKeyFile, PassphraseFile, CryptoDLL_handle):
+    try:
+        DataInSize = len(DataIn)
+        Signature = create_string_buffer(RSA_SIGNATURE_SIZE_BYTES)
+        
+        # Do Rsa Sign and get the signature
+        # N, D and DataIn are sent to the function as int arrays     
+        p1=str.encode(PrivKeyFile)
+        p2=str.encode(PassphraseFile)
+        p3=DataIn.encode('iso-8859-1')
+        result = CryptoDLL_handle.SBU_RSA_Sign(1, p3, DataInSize, p1, p2, Signature)
+        if result != 0:
+            print_and_log(logFile, "\n SBU_CRYPTO_DLL.SBU_RSA_Sign returned an error !!")                
+            raise NameError
+
+    except NameError:        
+        sys.exit(1)
+    return CertRSASignature(ReverseBytesinBinString(Signature))
+# End of GetRSASignature
+
+# This class holds the secondary N HASH value
+class CertPubKeyHASHData:
+
+    # Constructor
+    def __init__(self, HASHData):
+        self.PubHashData = HASHData
+
+    # The method returns the signature size
+    def __len__(self):
+        return len(self.PubHashData)
+
+    # This method returns the binary signature
+    
+    def VarsToBinString(self):
+        DataBinStr = str()        
+
+        for i in range(SHA_256_HASH_SIZE_IN_BYTES): 
+            byte = self.PubHashData[i]
+            DataBinStr = DataBinStr + byte2string(byte)
+
+        return DataBinStr
+
+# End of CertPubKeyHASHData 
+
+# The function GetPubKeyHash returns the hash of the (N|Np).
+def GetPubKeyHash(logFile, RSAPubKeyFileName, CryptoDLL_handle):
+    hashData = create_string_buffer(SHA_256_HASH_SIZE_IN_BYTES)
+        
+    result = CryptoDLL_handle.SBU_GetHashOfNAndNpFromPubKey(str.encode(RSAPubKeyFileName), hashData, SHA_256_HASH_SIZE_IN_BYTES)
+    if result != 0:
+        print_and_log (logFile, "Error in hash(public key | Np)")
+        sys.exit(1)
+      
+    # Create the public key object and return it in binary format
+    return CertPubKeyHASHData(hashData)
+# End of GetPubKeyHash
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cnt_data_structures.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cnt_data_structures.py
new file mode 100644
index 0000000..8672460
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/cnt_data_structures.py
@@ -0,0 +1,369 @@
+#****************************************************************
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+import struct
+import math
+import sys, traceback
+from global_defines import *
+from flags_global_defines import *
+from hash_basic_utility import *
+from ctypes import *
+from cert_basic_utilities import *
+
+####################################################################
+# Filename - datastructures.py
+# Description - This file contains the data structures used in the
+#               SB utility
+####################################################################
+
+
+# The ReverseBytesInString function reverse the bytes in a string and returns the reversed string
+def tempReverseBytesInBytesArray(array, size):
+
+    reversedArray = c_ubyte * size
+    revArray = reversedArray()
+    for i in range(size//4):
+        # reverse each word
+        for j in range(4):
+            revArray[4*i + j] = array[4*i + 3 - j]
+    return revArray
+# End of ReverseBytesInString
+
+
+# This class represent a record info structure. It includes the SW Comp address,
+# the Size of the record, the place holder and the HASH result
+class CertRecordInfo:
+    FlashAddr = 0xabc
+    MemLoadAddr = 0x100
+    MemLoadAddrList = list()
+    LenInWords = int(0)
+    MaxLenInWords = int(0)
+    AesCodeEncUsed = int(0)
+    SwHASHResult = ""
+
+    # Constructor
+    def __init__(self, log, loadVerifyScheme, RecFlashAddr, RecMemAddr, RecMemAddrList, RecMaxInBytes, RecIsCeUsed, RecLenInBytes, RecHash):
+
+        # load address can be 0xffffffff only in case of "verify only in flash" mode
+        if (loadVerifyScheme == VERIFY_IMAGE_IN_FLASH and RecMemAddr != MEM_ADDRESS_UNLOAD_FLAG) :
+            print_and_log(log, "Illegal load address defined - exiting\n")
+            sys.exit()
+
+        if (loadVerifyScheme != VERIFY_IMAGE_IN_FLASH and RecMemAddr == MEM_ADDRESS_UNLOAD_FLAG) :
+            print_and_log(log, "Illegal load address defined - exiting\n")
+            sys.exit()
+
+        # flash storage address can be 0xffffffff only in case of "verify only in mem" mode
+        if (loadVerifyScheme == VERIFY_IMAGE_IN_MEM and RecFlashAddr != MEM_ADDRESS_UNLOAD_FLAG) :
+            print_and_log(log, "Illegal flash address defined - exiting\n")
+            sys.exit()
+
+        if (loadVerifyScheme != VERIFY_IMAGE_IN_MEM and RecFlashAddr == MEM_ADDRESS_UNLOAD_FLAG) :
+            print_and_log(log, "Illegal flash address defined - exiting\n")
+            sys.exit()
+
+        self.FlashAddr = RecFlashAddr
+        self.MemLoadAddr = RecMemAddr
+        self.MemLoadAddrList = RecMemAddrList
+        self.LenInWords = RecLenInBytes
+        self.MaxLenInWords = RecMaxInBytes
+        self.AesCodeEncUsed = RecIsCeUsed
+        self.SwHASHResult = RecHash
+
+    # The method VarsToBinStringHashComp creates a binary string out of the hash of component
+    # and the memory load address
+    def VarsToBinStringHashComp(self):
+        DataBinStr = str()
+        DataBinStr1 = str()
+        DataBinStr2 = str()
+        DataBinStr3 = str()
+
+        DataBinStr = self.SwHASHResult
+
+        DataBinStr1 = struct.pack('<I', self.MemLoadAddr)
+
+        DataBinStr2 = struct.pack('<I', self.MaxLenInWords)
+
+        DataBinStr3 = struct.pack('<I', self.AesCodeEncUsed)
+
+        DataBinStr = DataBinStr + DataBinStr1 + DataBinStr2 + DataBinStr3
+        return byte2string(DataBinStr)
+
+    # The method VarsToBinStringParamComp creates a binary string out of the component size
+    # and the storage address
+    def VarsToBinStringParamComp(self):
+        DataBinStr = str()
+        DataBinStr1 = str()
+
+        DataBinStr = struct.pack('<I', self.FlashAddr)
+
+        DataBinStr1 = struct.pack('<I', self.LenInWords)
+
+        DataBinStr = DataBinStr + DataBinStr1
+        return byte2string(DataBinStr)
+
+    # Return the load address
+    def GetLoadAddress(self):
+        return self.MemLoadAddr
+
+# End of CertRecordInfo
+
+
+# This class holds the AES encryption needed information
+class CodeEncryptionData:
+
+    # Constructor
+    def __init__(self, logFile, keyFileName, loadAddressList, nonce, cryptoType):
+        self.keyIntArray = self.extractAESKeyFromFile(keyFileName)
+        self.nonceStrBin = str()
+        self.cryptoType = cryptoType
+        self.IVIntArray = self.combineAESIV(loadAddressList, nonce)
+
+    # This method extracts the key from the file
+    def extractAESKeyFromFile(self, keyFileName):
+        try:
+            IntArrayKeyParam = c_ubyte * AES_DECRYPT_KEY_SIZE_IN_BYTES
+            keyIntArray = IntArrayKeyParam()
+
+            # Get the key data from the file. The key data format is text (0x01, 0x02 ,..etc)
+            fob = open(keyFileName, "r")
+            fileData = fob.read()
+            fob.close()
+            # Take each of the hex representation and save it as Int in the array
+            keyList = fileData.split(",")
+            i = 0
+            for obj in keyList:
+                if i == AES_DECRYPT_KEY_SIZE_IN_BYTES:
+                    print("aes key file is in illegal size")
+                    break
+                keyIntArray[i] = int(obj, 16)
+                i = i + 1
+
+        except IOError as Error1:
+            (errno, strerror) = Error1.args
+            print("Error in opening file - %s" %FileName)
+            sys.exit()
+        return keyIntArray
+
+    # This method combines the IV
+    def combineAESIV(self, loadAddressList, nonce):
+        try:
+            self.nonceStrBin = nonce
+            IntArrayIVParam = c_ubyte * AES_IV_SIZE_IN_BYTES
+            IVIntArray = IntArrayIVParam()
+            fillZeroes = 0
+
+            i = 0
+            for char in self.nonceStrBin:
+                IVIntArray[i] = struct.unpack("B",char)[0]
+                i = i + 1
+
+            # The IV is composed of - nonce (8 bytes) + load address (4 bytes)
+            # first need to verify that the list size is as expected
+            if len(loadAddressList) < NUM_OF_BYTES_IN_ADDRESS: # need to fill zeroes before
+                    fillZeroes = NUM_OF_BYTES_IN_ADDRESS - len(loadAddressList)
+
+            for j in range(fillZeroes):
+                IVIntArray[i] = int("0")
+                i = i + 1
+             # copy each byte as int to the array
+            for j in range(int(NUM_OF_BYTES_IN_ADDRESS)-fillZeroes):
+                IVIntArray[i] = int(loadAddressList[j], 16)
+                i = i + 1
+
+            # return the IV
+        except NameError:
+            print("\n combineAESIV failed !! ")
+            sys.exit()
+        return IVIntArray
+
+    # This method is responsible to write the encrypted data
+    def AESEncryptDataAndHash(self, inputFileName, SBU_Crypto):
+        try:
+            newFileName = inputFileName[:-4] + SW_COMP_FILE_NAME_POSTFIX
+            image_size = c_uint()
+            OutputDataIntArray = create_string_buffer(SHA_256_HASH_SIZE_IN_BYTES)
+
+            result = SBU_Crypto.SBU_AES_CTR_EncryptFile(str.encode(inputFileName), str.encode(newFileName), self.keyIntArray, AES_DECRYPT_KEY_SIZE_IN_BYTES,self.IVIntArray, OutputDataIntArray, byref(image_size), self.cryptoType)
+
+            if result != 0:
+                raise NameError
+
+        except NameError:
+            print("\n SBU_Crypto.SBU_AES_CTR_EncryptFile returned an error !!" + str(result))
+            sys.exit()
+
+        return dict(Hash = OutputDataIntArray.raw, SizeOfRec = image_size.value)
+
+
+# This class is used to keep the random nonce
+class KeyNonce:
+    #The function creates a random nonce (2 words)
+    def __init__(self, codeEncId, DLLHandle):
+        try:
+            #generate 8 bytes of random data, in binary format
+            if codeEncId != USE_AES_CE_ID_NONE:
+                self.randStr = create_string_buffer(8)
+                result = DLLHandle.SBU_RAND_Bytes(8, self.randStr)
+                if result <= 0:
+                    raise NameError
+            else:
+                self.randStr = create_string_buffer(8)
+                for i in range(8):
+                        self.randStr[i] = 0
+
+
+        except NameError:
+            print("\n CreateNonce failed, failed to create random number! ")
+            sys.exit()
+
+        return
+
+    # This method is used to return the Nonce as binary string
+    # The nonce is a byte array of 8 bytes but it is read in the sb code as 2 words, therefore in case of little endian
+    # it is reversed and in case of BIG lest as is.
+    def VarsToBinString(self):
+        str1 = byte2stringBytesArray(self.randStr)
+        return str1
+
+#End of CreateNonce
+########### Data Records analyzer functions ###########
+
+# The ImageFileAnalyzer function analyzes the files list file and return a list of data records objects.
+# The function does the following steps:
+# Step 1 - Open the file (that contain the files list)
+# Step 2 - Get each line in the file and insert it into a list of dictionaries
+#          each dictionary contain:
+#               image name (SW component name),
+#               Memory Load address
+#               Storage address of the image
+#               Max image size in Bytes
+# Step 3 - For each SW image (SW component) calculate its HASH and add to dictionary along with its size
+# Step 4 - Create a record object and insert the data into it
+def ImageFileAnalyzer(logFile, FileName, loadVerifyScheme, codeEncId, SBU_DLLHandle, keyFileName, nonce, cryptoType):
+
+    DataRecsList = list()
+
+    # SB does not support encrypted images in case of "loading only" and "verify only in flash" modes
+    if (loadVerifyScheme == VERIFY_IMAGE_IN_FLASH and codeEncId != USE_AES_CE_ID_NONE) :
+        print_and_log(logFile, "Verify encrypted image in Flash is illegal - exiting\n")
+        sys.exit()
+
+    if (loadVerifyScheme == LOADING_ONLY_IMAGE and codeEncId != USE_AES_CE_ID_NONE) :
+        print_and_log(logFile, "Loading only encrypted image is illegal - exiting\n")
+        sys.exit()
+
+    # Open the file (that contain the files list)
+    try:
+        FileObj = open(FileName , "r")
+        LinesDictList = list()
+        FileLines = FileObj.readlines()
+        # If the file is empty the data record list will be returned empty
+        if len(FileLines) == 0 :
+            print_and_log(logFile, "illegal number of images = 0 !")
+            sys.exit(1)
+        # Get each line in the file and insert it into a list of dictionaries
+        # each dictionary contain the image name (SW component name), memory load address and the Flash address
+        # of the image
+        for lineObj in FileLines:
+            # if it is comment ignore
+            if re.match(r'^#', lineObj):
+                continue
+            LinesDictList.append(LineAnalyzer(logFile, lineObj))
+        # For each SW image (SW component) calculate its HASH and add to dictionary (hash and size)
+        for ListObj in LinesDictList:
+            ListObj.update(HashResOnSWComponent(logFile, ListObj.get('ImgName'), ListObj.get('isAesCodeEncUsed'), codeEncId, SBU_DLLHandle,ListObj.get('MemLoadAddrList'), keyFileName, nonce, cryptoType))
+            # Create a record object and insert the data into it
+            CertRecordInfoObj = CertRecordInfo(logFile, loadVerifyScheme, ListObj.get('FlashStoreAddr'), ListObj.get('MemLoadAddr'), ListObj.get('MemLoadAddrList'), ListObj.get('ImgMaxSizeInBytes'), ListObj.get('isAesCodeEncUsed'), ListObj.get('SizeOfRec'),ListObj.get('Hash'))
+            DataRecsList.append(CertRecordInfoObj)
+
+    except IOError as Error1:
+        (errno, strerror) = Error1.args
+        print_and_log(logFile, "\n Error in openning file - %s" %FileName)
+        sys.exit(1)
+
+    return DataRecsList
+# End of ImageFileAnalyzer
+
+# The LineAnalyzer function takes each line in the files list file and separate it
+# Each line is expected to be in the following structure:
+# <s/w_comp_name> <mem_load_addr> <flash_store_addr> <Max s/w comp size> <aes-ce-used>
+# The function returns a dictionary with the line data. (ImgName, MemLoadAddr, FlashStoreAddr, ImgMaxSizeInBytes, isAesCodeEncUsed)
+# In case the functions reads an illegal image address (not word alligned) an exception is raised
+def LineAnalyzer(logFile, FileLine):
+    try:
+        LineList = FileLine.split(" ")
+        MemLoadAddr = int(LineList[1],16)
+        if MemLoadAddr == 0:
+            print_and_log(logFile, "\n Illegal Address - 0 is not allowed as load address !!")
+            sys.exit(1)
+        MemLoadAddrList = createAddrList(LineList[1][2:])
+        FlashStoreAddr = int(LineList[2],16)
+        ImgMaxSizeInBytes = int(LineList[3],16)
+        isAesCodeEncUsed = int(LineList[4],16)
+
+    except NameError:
+        print_and_log(logFile, "\n Illegal Address - not word alligned !!")
+        sys.exit(1)
+
+    return dict(ImgName = LineList[0], MemLoadAddr = MemLoadAddr, MemLoadAddrList = MemLoadAddrList, FlashStoreAddr = FlashStoreAddr, ImgMaxSizeInBytes = ImgMaxSizeInBytes, isAesCodeEncUsed = isAesCodeEncUsed)
+# End of LineAnalyzer
+
+# The HashResOnSWComponent decides on which HASH algorithm should be used and call the correct function
+# Currently HASH SHA256 output & SHA 256 output is trucated to 128 bits output are supported
+def HashResOnSWComponent(logFile, FileName, isAesCodeEncUsed, codeEncId, SBU_DLLHandle, memoryLoadAddr, keyFileName, nonce, cryptoType):
+    try:
+        if isAesCodeEncUsed == 1 :
+             # do Aes and Hash
+            if codeEncId != USE_AES_CE_ID_NONE :
+                codeEncObj = CodeEncryptionData(logFile, keyFileName, memoryLoadAddr, nonce, cryptoType)
+                return codeEncObj.AESEncryptDataAndHash(FileName, SBU_DLLHandle)
+            else:
+               print_and_log(logFile, "ERROR: No AES key was selected!")
+               sys.exit(1)
+        else:
+            # do only Hash
+            return HashResOnSWComponent_SHA256(logFile, FileName, SBU_DLLHandle)
+    except NameError:
+        print_exeption()
+        sys.exit(1)
+
+    return
+# End of HashResOnSWComponent
+
+# The HashResOnSWComponent_SHA256 function reads the image file (SW component) and calculate HASH on it
+def HashResOnSWComponent_SHA256(logFile, FileName, SBU_Crypto):
+    try:
+        image_size = c_uint()
+        OutputDataIntArray = create_string_buffer(SHA_256_HASH_SIZE_IN_BYTES)
+
+        result = SBU_Crypto.SBU_AES_CTR_EncryptFile(str.encode(FileName), None, None, 0 ,None, OutputDataIntArray, byref(image_size), 0)
+        if result != 0:
+            print_and_log(logFile, "Error in Hash!")
+            sys.exit(1)
+
+    except NameError:
+        print_and_log(logFile, "Error in Hash !")
+        sys.exit(1)
+
+    return dict(Hash = OutputDataIntArray.raw, SizeOfRec = image_size.value)
+
+def createAddrList (dataStr):
+    dataList = list()
+
+    if len(dataStr)%2 == 1: #miss a zero at the beginning
+        newStr = '0'+dataStr
+    else:
+        newStr = dataStr
+
+    for i in range(int(len(newStr)/2)):
+        dataList.append(newStr[i*2:i*2+2])
+    return dataList
+
+########### Data Records analyzer functions End ###########
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/flags_global_defines.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/flags_global_defines.py
new file mode 100644
index 0000000..c3b30fd
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/flags_global_defines.py
@@ -0,0 +1,45 @@
+####################################################################
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# Definition for certificate type
+#================================
+CERT_TYPE_KEY     = 1
+CERT_TYPE_CONTENT = 2
+
+# Definition for RSA Np or H usage
+#+================================
+# This flag is set to 1 for Np usage in case H should be used set it to 0
+RSA_ALG_USE_Np = 1
+
+# This definition is for the secondary HASH of public key calculation. The calculation is done according to the 
+# calculation of HASH of public key (as saved in the OTP) and is set according to platform type  
+OTP_HASH_CALC_ON_N_AND_NP = 0
+OTP_HASH_CALC_ON_N = 1
+OTP_HASH_ON_E_AND_N = 2 
+
+# This definition should be set according to platform and project 
+SECONDARY_KEY_HASH_CALC = OTP_HASH_CALC_ON_N_AND_NP
+
+# Definitions for specific projects, should be set to 0 if no additional data is required
+SPECIAL_ADDITIONAL_DATA_USED = 1
+
+# Content certificate flag word definition
+#=========================================
+CODE_ENCRYPTION_SUPPORT_BIT_POS       = 4
+
+LOAD_VERIFY_SCHEME_BIT_POS            = 8
+
+CRYPTO_TYPE_BIT_POS                   = 12  
+
+# Bit positions of signature offset and number of s/w components
+#================================================================
+NUM_OF_SW_COMPS_BIT_POS = 16
+
+SIGNATURE_OFFSET_BIT_POS = 0
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines.py
new file mode 100644
index 0000000..4ee9ca6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines.py
@@ -0,0 +1,126 @@
+####################################################################
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+
+# Filename - globaldefines.py
+# Description - This file contains global defines used in the secure
+#               boot utility
+####################################################################
+from datetime import datetime
+#
+import sys
+import re
+import struct
+from ctypes import *
+
+BYTES_WITHIN_WORD = 4
+PUBKEY_SIZE_BYTES = 384 #256 aligned with SB_CERT_RSA_KEY_SIZE_IN_BITS defined in cc_pka_hw_plat_defs.h
+PUBKEY_SIZE_WORDS = (PUBKEY_SIZE_BYTES//BYTES_WITHIN_WORD)
+NP_SIZE_IN_BYTES = 20
+NP_SIZE_IN_WORDS = (NP_SIZE_IN_BYTES//BYTES_WITHIN_WORD)
+SHA_256_HASH_SIZE_IN_BYTES = 32
+RSA_SIGNATURE_SIZE_BYTES = 384 #256 aligned with SB_CERT_RSA_KEY_SIZE_IN_BITS defined in cc_pka_hw_plat_defs.h
+
+CC_MNG_CHIP_MANUFACTURE_LCS = 0x0
+CC_MNG_DEVICE_MANUFACTURE_LCS = 0x1
+CC_MNG_SECURE_LCS = 0x5
+CC_MNG_RMA_LCS = 0x7
+
+#so name
+SBU_CRYPTO_LIB_DIR = "lib"
+SBU_CRYPTO_LIB_Name = SBU_CRYPTO_LIB_DIR + "/" + "libsbu_crypto.so"
+SBU_OSSL_CRYPTO_LIB_Name = "libcrypto.so.1.0.0"
+SBU_OSSL_LIB_Name = "libssl.so.1.0.0"
+
+
+CURRENT_PATH = sys.path[0]
+
+
+# DX default magic number for the certificate table
+KEY_CERT_TOKEN = 0x53426b63
+CONTENT_CERT_TOKEN = 0x53426363
+DEBUG_ENABLER_TOKEN = 0x5364656E
+DEBUG_DEVELOPER_TOKEN = 0x53646465
+
+#E value, in a string mode. for the HASh calculation
+E_VALUE_REVERSED = "00010001"
+# Memory unload flag
+MEM_ADDRESS_UNLOAD_FLAG = 0xFFFFFFFF
+
+# RSA Modulus size = RSA signature size (RSA 3072 key size is used)
+RSA_PRIVATE_KEY_SIZE = 3072
+
+RSA_SIGNATURE_SIZE_IN_BYTES = 384
+RSA_SIGNATURE_SIZE_IN_DOUBLE_BYTES = 768
+RSA_SIGNATURE_SIZE_IN_WORDS = 96
+# HASH size in SHA256 in bytes
+SHA_256_HASH_SIZE_IN_BYTES = 32
+HASH_ALGORITHM_SHA256_SIZE_IN_WORDS = (SHA_256_HASH_SIZE_IN_BYTES//BYTES_WITHIN_WORD)
+
+# H size
+RSA_H_SIZE_IN_BYTES = RSA_SIGNATURE_SIZE_IN_BYTES
+RSA_H_SIZE_IN_WORDS = (RSA_SIGNATURE_SIZE_IN_BYTES//BYTES_WITHIN_WORD)
+ 
+# Size of SW versions
+SW_VERSION_OBJ_SIZE_IN_WORDS = 1
+
+# header size in bytes
+HEADER_SIZE_IN_BYTES = (4*BYTES_WITHIN_WORD)
+HEADER_SIZE_IN_WORDS = (HEADER_SIZE_IN_BYTES//BYTES_WITHIN_WORD)
+#size number of bytes in address
+NUM_OF_BYTES_IN_ADDRESS = 4
+
+SOC_ID_SIZE_IN_BYTES = 32
+
+#enabler certificate flag offset
+HBK_ID_FLAG_BIT_OFFSET = 0
+LCS_ID_FLAG_BIT_OFFSET = 4
+RMA_CERT_FLAG_BIT_OFFSET = 8
+
+
+# HASH output representation
+HASH_BINARY_REPRESENTATION = 1
+HASH_HEX_REPRESENTATION    = 2 
+
+
+# certificate output file prefix
+Cert_FileName = "Cert"
+# certificate output file suffix
+Cert_FileExtBin = ".bin"
+Cert_FileExtTxt = ".txt"
+        
+# definitions for code encryption
+AES_IV_SIZE_IN_BYTES = 16
+AES_DECRYPT_KEY_SIZE_IN_BYTES = 16
+SW_COMP_FILE_NAME_POSTFIX = "_enc.bin"
+
+NONCE_SIZE_IN_WORDS = 2
+MAX_NUM_OF_IMAGES = 16
+
+# Definitions for sw version legal values - 
+#########################################
+SW_REVOCATION_MAX_NUM_OF_BITS_HBK0 = 64
+SW_REVOCATION_MAX_NUM_OF_BITS_HBK1 = 96
+SW_REVOCATION_MAX_NUM_OF_BITS_HBK2 = 160
+
+SW_REC_ADDR32_SIGNED_DATA_SIZE_IN_WORDS = 3
+
+USE_AES_CE_ID_NONE = 0
+USE_AES_CE_ID_KCEICV = 1
+USE_AES_CE_ID_KCE = 2
+
+LOAD_AND_VERIFY_IMAGE = 0
+VERIFY_IMAGE_IN_FLASH = 1
+VERIFY_IMAGE_IN_MEM = 2
+LOADING_ONLY_IMAGE = 3
+
+
+# Definitions for list of configurables parameters
+##################################################
+LIST_OF_CONF_PARAMS = ["CERT_VERSION_MAJOR","CERT_VERSION_MINOR"]
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines_prim_hash.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines_prim_hash.py
new file mode 100644
index 0000000..c1b8394
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines_prim_hash.py
@@ -0,0 +1,34 @@
+
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+# Global Definitions #
+#--------------------#
+
+# Output size definitions
+#------------------------#
+
+OUTPUT_SIZE_SHA_256 = 0x1
+
+OUTPUT_SIZE_SHA_256_TRUNC = 0x2
+
+# File names definitions
+#-----------------------#
+
+# Prim key hash file name
+PRIM_KEY_HASH_FILE_NAME = "PrimKeyHASH.txt"
+
+# ECC file name
+ECC_FILE_NAME = "PrimKeyHASHECC.txt"
+
+ZEROS_NUM_FILES_NAME = "ZeroBitsInHASH.txt" 
+
+# General definitions
+#--------------------
+SIZE_OF_WORD_IN_BITS = 32
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines_rsa_format.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines_rsa_format.py
new file mode 100644
index 0000000..36296ac
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/global_defines_rsa_format.py
@@ -0,0 +1,53 @@
+####################################################################
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+
+# Filename - globaldefinesrsaformat.py
+# Description - This file contains global defines used in the RSA 
+#               Format parser
+####################################################################
+
+# Parameter type
+PARAM_MOD = 1
+PARAM_PRIV_EXP = 2
+PARAM_EXP = 3
+
+# PEM header and footer 
+PEM_START = "-----BEGIN RSA PRIVATE KEY-----\n"
+PEM_END = "\n-----END RSA PRIVATE KEY-----\n"
+
+# PEM header size
+PEM_HEADER_SIZE_BYTES = 4
+
+# PEM version size
+PEM_VERSION_SIZE_BYTES = 3
+
+# Parameters ASN.1 DER type
+PARAM_HEADER_INTEGER_TYPE = 2
+
+# Length ASN.1 DER
+PARAM_LENGTH_INDICATION_BIT = 7
+PARAM_LENGTH_INDICATION = 0x1 << PARAM_LENGTH_INDICATION_BIT
+
+PARAM_LENGTH_BITS_MASK = 0x7F
+
+# Size of expected Mod & Priv exponent
+RSA_MOD_SIZE_BYTES = 256
+
+# Modulus & Priv Exponent ASN.1 header size
+MOD_HEADER_FIXED_SIZE_BYTES = 4
+
+# Exponent ASN.1 header size
+EXP_HEADER_FIXED_SIZE_BYTES = 2
+
+# Exponent expected value
+EXP_EXPECTED_VAL = 65537
+
+# AES key fixed size
+AES_KEY_SIZE_IN_BYTES = 32
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/hash_basic_utility.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/hash_basic_utility.py
new file mode 100644
index 0000000..a301aa6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/hash_basic_utility.py
@@ -0,0 +1,39 @@
+
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+import string
+from global_defines import *
+import hashlib
+
+####################################################################
+# Filename -    hashbasicutillity
+# Description - This file contains the main functionality of the
+#               secure boot utility. The utility creates a certificate
+#               that is used in the secure boot process
+####################################################################
+
+
+########### Basic Utilities ###############################
+
+# This function calculates HASH SHA256 on binary data and return the HASH result 
+def HASH_SHA256(BinData, OutputRep):
+
+    # Calculate SHA 256 on given binary data
+    HashObj = hashlib.sha256()
+    HashObj.update(BinData)
+
+    if OutputRep == HASH_BINARY_REPRESENTATION:
+        HashRes = HashObj.digest()
+    else:
+        HashRes = HashObj.hexdigest()
+    
+    return HashRes
+# End of HASH_SHA256
+
+
+######################################## END OF FILE ########################################
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/key_data_structures.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/key_data_structures.py
new file mode 100644
index 0000000..e83e63e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/common_utils/key_data_structures.py
@@ -0,0 +1,226 @@
+#****************************************************************
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+import struct
+import math
+from global_defines import *
+from flags_global_defines import *
+from cert_basic_utilities import *
+from hash_basic_utility import *
+from ctypes import *
+
+####################################################################
+# Filename - datastructures.py
+# Description - This file contains the data structures used in the
+#               SB utility
+####################################################################
+
+# This class represents the certificate header. The header contains the magic number, certificate version, certificate size and Flags
+class CertHeader:
+    flag = 0
+    CertSize = 0
+    MagicNum = 0
+    CertVersion = 0
+      
+    # Constructor, creates the flag, size and initializes the magic number
+    def __init__(self, log, hbkId, certType, codeEncId, loadVerifyScheme, cryptoType, numOfComps, prjDefines):
+        self.PrjDefines = prjDefines
+        self.CertHeaderFlagCreate(log, hbkId, codeEncId, loadVerifyScheme, cryptoType, numOfComps)
+        self.CertHeaderLenCreate(log, numOfComps)
+        self.CertVersion = ( (self.PrjDefines[LIST_OF_CONF_PARAMS.index("CERT_VERSION_MAJOR")]) << 16) | (self.PrjDefines[LIST_OF_CONF_PARAMS.index("CERT_VERSION_MINOR")])
+        if certType == CERT_TYPE_CONTENT:
+            self.MagicNum = CONTENT_CERT_TOKEN
+        else:
+            self.MagicNum = KEY_CERT_TOKEN
+       
+    # This method creates the flag word 
+    def CertHeaderFlagCreate(self, log, hbkId, codeEncId, loadVerifyScheme, cryptoType, numOfComps):
+        flag = 0
+        # build the flag value, first add the hash algorithm
+        flag = hbkId
+                
+        # Add is encrypted flag
+        flag = flag| (codeEncId << CODE_ENCRYPTION_SUPPORT_BIT_POS)
+   
+        # Add load&verify field flag
+        flag = flag| (loadVerifyScheme << LOAD_VERIFY_SCHEME_BIT_POS)
+
+        # Add cryptoType field flag
+        flag = flag| (cryptoType << CRYPTO_TYPE_BIT_POS)
+
+        # Add num of images
+        flag = flag | numOfComps << NUM_OF_SW_COMPS_BIT_POS 
+
+        self.flag = flag
+        return 
+
+    # This method creates the certificate size
+    def CertHeaderLenCreate(self, log, numOfComps):
+        # Calculate the offset to the signature (the offset will be set in words) :
+        # Header size = 4 words
+        # RSA N = 96 words
+        # RSA Np = 5 words 
+        # sw version = 1 word                
+        # HASH of pubkey = HASH size        
+        # Set the number of components in the appropriate field
+
+        if numOfComps > MAX_NUM_OF_IMAGES: # 16
+            print_and_log(log, "\nIllegal number of s/w components !!")
+            sys.exit()
+   
+        self.CertSize =  HEADER_SIZE_IN_WORDS + SW_VERSION_OBJ_SIZE_IN_WORDS + PUBKEY_SIZE_WORDS + NP_SIZE_IN_WORDS
+        if numOfComps > 0: #this is a content certificate
+            self.CertSize = self.CertSize + NONCE_SIZE_IN_WORDS + numOfComps * (HASH_ALGORITHM_SHA256_SIZE_IN_WORDS + SW_REC_ADDR32_SIGNED_DATA_SIZE_IN_WORDS)
+        else: #this is a key certificate 
+            self.CertSize = self.CertSize + HASH_ALGORITHM_SHA256_SIZE_IN_WORDS
+        return
+
+    # This method is used to return the header as binary string
+    def VarsToBinString(self):
+        DataBinStr = str()
+        DataBinStr1 = str()
+        DataBinStr2 = str()
+        DataBinStr3 = str()
+        
+        DataBinStr = struct.pack('<I', self.MagicNum) 
+        DataBinStr1 = struct.pack('<I', self.CertVersion) 
+        DataBinStr2 = struct.pack('<I', int(self.CertSize))
+        DataBinStr3 = struct.pack('<I', self.flag)
+            
+        DataBinStr =  DataBinStr +  DataBinStr1 + DataBinStr2 + DataBinStr3
+
+        return byte2string(DataBinStr)
+
+# End of class CertHeader
+
+
+# This class represents SW version fields in the certificate
+class CertSwVersion:
+    SwCurrentVersion = 0    
+    InternalNumOfObjects = 2 
+    # Costructor
+    def __init__(self, RecSwVersion=0):
+        self.SwCurrentVersion = RecSwVersion
+
+    # len returns the size of the object
+    def __len__(self):
+        return BYTES_WITHIN_WORD*InternalNumOfObjects
+    
+    # This method returns a binary string
+    def VarsToBinString(self):
+        DataBinStr = str()
+        
+        DataBinStr = struct.pack('<I', self.SwCurrentVersion) 
+        
+        return byte2string(DataBinStr)
+# End of CertSwVersion   
+
+# This class represents N public key data
+class CertNPublicKey:
+
+    # Constructor
+    # Np can stand either for Np or for H
+    def __init__(self, PubKeyBinStr):
+        self.PubKey = PubKeyBinStr
+
+    # The method __len__ returns the size of pubkey N and Np (string size in bytes)
+    def __len__(self):
+        return(RSA_SIGNATURE_SIZE_IN_BYTES + NP_SIZE_IN_BYTES)
+
+    # This method returns a binary string of the N string and Np string (N is set as big endian
+    # Np is set as little endian)   
+    def VarsToBinString(self):
+        DataBinStr = str()
+        PubKey = self.PubKey
+
+        for i in range(RSA_SIGNATURE_SIZE_IN_BYTES + NP_SIZE_IN_BYTES): 
+            byte = PubKey[i]
+            DataBinStr = DataBinStr + byte2string(byte)
+
+        return DataBinStr
+
+# End of CertNPublicKey
+
+# This class represents N public key data
+class CertNPublicKeyHData:
+
+    # Constructor
+    # Np can stand either for Np or for H
+    def __init__(self, PubKeyBinStr, HStr):
+        self.PubKey = PubKeyBinStr
+        self.HStr = HStr
+
+    # The method __len__ returns the size of pubkey N and H (string size in bytes)
+    def __len__(self):
+        return(RSA_SIGNATURE_SIZE_IN_BYTES + RSA_H_SIZE_IN_BYTES)
+
+    # This method returns a binary string of the N string and Np string (N is set as big endian
+    # Np is set as little endian)   
+    def VarsToBinString(self):
+        DataBinStr = str()
+        DataBinStr1 = str()
+
+        PubKey = self.PubKey
+        for i in range(RSA_SIGNATURE_SIZE_IN_BYTES):            
+            byte = PubKey[i]
+            DataBinStr = DataBinStr +  byte2string(byte)         
+            
+        Hstr = self.HStr        
+        for i in range(RSA_H_SIZE_IN_BYTES):  
+            DataBinStr1 =  DataBinStr1 + chr(int(Hstr[i*2:i*2+2],16))
+        
+        
+        DataBinStr = DataBinStr + DataBinStr1    
+        return byte2string(DataBinStr)
+# End of CertNPublicKeyHData
+
+# This class holds the RSA signature
+class CertRSASignature:
+
+    # Constructor
+    def __init__(self, SignatureBinStr):
+        self.SignatureStr = SignatureBinStr
+
+    # The method returns the signature size
+    def __len__(self):
+        return RSA_SIGNATURE_SIZE_IN_BYTES
+
+    # This method returns the binary signature
+    def VarsToBinString(self):
+        DataBinStr = self.SignatureStr
+     
+        return byte2string(DataBinStr)
+
+# End of CertRSASignature
+
+# This class holds the secondary N HASH value
+class CertPubKeyHASHData:
+
+    # Constructor
+    def __init__(self, HASHData):
+        self.PubHashData = HASHData
+
+    # The method returns the signature size
+    def __len__(self):
+        return len(self.PubHashData)
+
+    # This method returns the binary signature
+    
+    def VarsToBinString(self):
+        DataBinStr = str()        
+
+        for i in range(SHA_256_HASH_SIZE_IN_BYTES): 
+            byte = self.PubHashData[i]
+            DataBinStr = DataBinStr + byte2string(byte)
+
+        return DataBinStr
+
+# End of CertPubKeyHASHData 
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table.tbl b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table.tbl
new file mode 100644
index 0000000..7f07a88
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table.tbl
@@ -0,0 +1,2 @@
+image3.bin 0x30008000 0x0000cef0 0x00004000 0x0
+image2.bin 0x30006000 0x00003458 0x00003000 0x0
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_enc_0.tbl b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_enc_0.tbl
new file mode 100644
index 0000000..439ca2d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_enc_0.tbl
@@ -0,0 +1,2 @@
+image3.bin 0x30008000 0x0000cef0 0x00004000 0x1
+image2.bin 0x30006000 0x00003458 0x00003000 0x1
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_verify_flash.tbl b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_verify_flash.tbl
new file mode 100644
index 0000000..6e01cbc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_verify_flash.tbl
@@ -0,0 +1,2 @@
+image3.bin 0xffffffff 0x0000cef0 0x00004000 0x0
+image2.bin 0xffffffff 0x00003458 0x00003000 0x0
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_verify_mem.tbl b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_verify_mem.tbl
new file mode 100644
index 0000000..19e4296
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/images_table_verify_mem.tbl
@@ -0,0 +1,2 @@
+image3.bin 0x30008000 0xffffffff 0x00004000 0x0 
+image2.bin 0x30006000 0xffffffff 0x00003000 0x0
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert.cfg
new file mode 100644
index 0000000..7e02bf6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert.cfg
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for content certificate generation
+# [CNT-CFG]             Mandatory header.
+# cert-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# cert-keypair-pwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# aes-enc-key =         Text file containing the encryption key for the authenticated SW images. Comma-separated hex bytes ("0x12,0x34").
+#                       Optional - leave empty or undefined if no encryption is desired
+# images-table =        Text file containing the list of authenticated SW image files. Each line refers to a single image, with the following data:
+#                       <image file name> <mem load addr> <flash store addr><code encode flag>
+# nvcounter-val =       Value of the NV counter: 0..63 for HBK0 Trusted FW; 0..95 for HBK1 Trusted FW; 0..159 for full HBK Trusted FW.
+# load-verify-scheme =  Image verification scheme supports: 0 = load&verify from flash to mem; 1 = verify only in flash; 2 = verify only in mem; 3 = loading only.
+# aes-ce-id = 		SW image encryption type: 0 = none; 1 = Kceicv; 2 = Kce.
+# crypto-type = 	Cryptographic verification and decryption mode: 0 = do Hash on plain image; 1 = do Hash on cipher image.
+# cert-pkg =        	Content cdertificate output file. Binary format.
+[CNT-CFG]
+cert-keypair =  ../../host/src/tests/sbrom_test_cc3x/dat/input/content_keypair.pem
+cert-keypair-pwd = ../../host/src/tests/sbrom_test_cc3x/dat/input/pwd.txt
+images-table = ../../host/src/tests/sbrom_test_cc3x/dat/input/images_table.tbl
+nvcounter-val = 5
+load-verify-scheme = 0
+aes-ce-id = 0
+crypto-type = 0
+cert-pkg = content_cert.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_enc_0.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_enc_0.cfg
new file mode 100644
index 0000000..8202de0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_enc_0.cfg
@@ -0,0 +1,31 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for content certificate generation
+# [CNT-CFG]             Mandatory header.
+# cert-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# cert-keypair-pwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# aes-enc-key =         Text file containing the encryption key for the authenticated SW images. Comma-separated hex bytes ("0x12,0x34").
+#                       Optional - leave empty or undefined if no encryption is desired
+# images-table =        Text file containing the list of authenticated SW image files. Each line refers to a single image, with the following data:
+#                       <image file name> <mem load addr> <flash store addr><code encode flag>
+# nvcounter-val =       Value of the NV counter: 0..63 for HBK0 Trusted FW; 0..95 for HBK1 Trusted FW; 0..159 for full HBK Trusted FW.
+# load-verify-scheme =  Image verification scheme supports: 0 = load&verify from flash to mem; 1 = verify only in flash; 2 = verify only in mem; 3 = loading only.
+# aes-ce-id = 		SW image encryption type: 0 = none; 1 = Kceicv; 2 = Kce.
+# crypto-type = 	Cryptographic verification and decryption mode: 0 = do Hash on plain image; 1 = do Hash on cipher image.
+# cert-pkg =        	Content cdertificate output file. Binary format.
+[CNT-CFG]
+cert-keypair =  ../../host/src/tests/sbrom_test_cc3x/dat/input/content_keypair.pem
+cert-keypair-pwd = ../../host/src/tests/sbrom_test_cc3x/dat/input/pwd.txt
+images-table = ../../host/src/tests/sbrom_test_cc3x/dat/input/images_table_enc_0.tbl
+nvcounter-val = 5
+load-verify-scheme = 0
+aes-ce-id = 2
+crypto-type = 0
+aes-enc-key = ../../host/src/tests/sbrom_test_cc3x/dat/input/aes_key.txt
+cert-pkg = content_cert_enc_0.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_verify_flash.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_verify_flash.cfg
new file mode 100644
index 0000000..db45253
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_verify_flash.cfg
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for content certificate generation
+# [CNT-CFG]             Mandatory header.
+# cert-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# cert-keypair-pwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# aes-enc-key =         Text file containing the encryption key for the authenticated SW images. Comma-separated hex bytes ("0x12,0x34").
+#                       Optional - leave empty or undefined if no encryption is desired
+# images-table =        Text file containing the list of authenticated SW image files. Each line refers to a single image, with the following data:
+#                       <image file name> <mem load addr> <flash store addr><code encode flag>
+# nvcounter-val =       Value of the NV counter: 0..63 for HBK0 Trusted FW; 0..95 for HBK1 Trusted FW; 0..159 for full HBK Trusted FW.
+# load-verify-scheme =  Image verification scheme supports: 0 = load&verify from flash to mem; 1 = verify only in flash; 2 = verify only in mem; 3 = loading only.
+# aes-ce-id = 		SW image encryption type: 0 = none; 1 = Kceicv; 2 = Kce.
+# crypto-type = 	Cryptographic verification and decryption mode: 0 = do Hash on plain image; 1 = do Hash on cipher image.
+# cert-pkg =        	Content cdertificate output file. Binary format.
+[CNT-CFG]
+cert-keypair =  ../../host/src/tests/sbrom_test_cc3x/dat/input/content_keypair.pem
+cert-keypair-pwd = ../../host/src/tests/sbrom_test_cc3x/dat/input/pwd.txt
+images-table = ../../host/src/tests/sbrom_test_cc3x/dat/input/images_table_verify_flash.tbl
+nvcounter-val = 5
+load-verify-scheme = 1
+aes-ce-id = 0
+crypto-type = 0
+cert-pkg = content_cert_verify_flash.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_verify_mem.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_verify_mem.cfg
new file mode 100644
index 0000000..d0a0ee5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/content_cert/sb_cnt_cert_verify_mem.cfg
@@ -0,0 +1,30 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for content certificate generation
+# [CNT-CFG]             Mandatory header.
+# cert-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# cert-keypair-pwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# aes-enc-key =         Text file containing the encryption key for the authenticated SW images. Comma-separated hex bytes ("0x12,0x34").
+#                       Optional - leave empty or undefined if no encryption is desired
+# images-table =        Text file containing the list of authenticated SW image files. Each line refers to a single image, with the following data:
+#                       <image file name> <mem load addr> <flash store addr><code encode flag>
+# nvcounter-val =       Value of the NV counter: 0..63 for HBK0 Trusted FW; 0..95 for HBK1 Trusted FW; 0..159 for full HBK Trusted FW.
+# load-verify-scheme =  Image verification scheme supports: 0 = load&verify from flash to mem; 1 = verify only in flash; 2 = verify only in mem; 3 = loading only.
+# aes-ce-id = 		SW image encryption type: 0 = none; 1 = Kceicv; 2 = Kce.
+# crypto-type = 	Cryptographic verification and decryption mode: 0 = do Hash on plain image; 1 = do Hash on cipher image.<code encode flag>
+# cert-pkg =        	Content cdertificate output file. Binary format.
+[CNT-CFG]
+cert-keypair =  ../../host/src/tests/sbrom_test_cc3x/dat/input/content_keypair.pem
+cert-keypair-pwd = ../../host/src/tests/sbrom_test_cc3x/dat/input/pwd.txt
+images-table = ../../host/src/tests/sbrom_test_cc3x/dat/input/images_table_verify_mem.tbl
+nvcounter-val = 5
+load-verify-scheme = 2
+aes-ce-id = 0
+crypto-type = 0
+cert-pkg = content_cert_verify_mem.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert.cfg
new file mode 100644
index 0000000..d2bd362
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert.cfg
@@ -0,0 +1,27 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for developer debug certificate generation
+# [DEVELOPER-DBG-CFG]        required header - do not change!
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#soc-id =               Binary file holding the 16byte SOC_ID.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f).
+#                       If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#enabler-cert-pkg =    The enabler Debug certificate package.
+#cert-pkg =             Final certificate package (Enabler+Developer) output file. Binary format.
+[DEVELOPER-DBG-CFG]
+cert-keypair =  dev_keypair1.pem
+cert-keypair-pwd = pwd.txt
+soc-id = soc_id1.bin
+debug-mask[0-31]   = 0x00112233
+debug-mask[32-63]  = 0x44556677
+debug-mask[64-95]  = 0x8899AABB
+debug-mask[96-127] = 0xCCDDEEFF
+enabler-cert-pkg = cert_enabler_pkg.bin
+cert-pkg = cert_developer_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert_no_pwd.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert_no_pwd.cfg
new file mode 100644
index 0000000..c83f89a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert_no_pwd.cfg
@@ -0,0 +1,27 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for developer debug certificate generation
+# [DEVELOPER-DBG-CFG]        required header - do not change!
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#soc-id =               Binary file holding the 16byte SOC_ID.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f).
+#                       If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#enabler-cert-pkg =    The Enabler Debug certificate package.
+#cert-pkg =             Final certificate package (Enabler+Developer) output file. Binary format.
+[DEVELOPER-DBG-CFG]
+cert-keypair =  dev_keypair1.pem
+cert-keypair-pwd =
+soc-id = soc_id1.bin
+debug-mask[0-31]   = 0x00112233
+debug-mask[32-63]  = 0x44556677
+debug-mask[64-95]  = 0x8899AABB
+debug-mask[96-127] = 0xCCDDEEFF
+enabler-cert-pkg = cert_enabler_pkg.bin
+cert-pkg = cert_developer_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sd_gen_developer_cert.sh b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sd_gen_developer_cert.sh
new file mode 100755
index 0000000..b73cd53
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sd_gen_developer_cert.sh
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#!/bin/bash
+
+cd ../../../../bin/
+
+cp ../tester/cc3x_secure_debug_test/dat/dev_keypair1.pem .
+cp ../tester/cc3x_secure_debug_test/dat/dev_pwd1.txt .
+cp ../tester/cc3x_secure_debug_test/dat/oem_keypair1.pem .
+cp ../tester/cc3x_secure_debug_test/dat/oem_pwd1.txt .
+cp ../tester/cc3x_secure_debug_test/dat/root_key1.txt .
+cp ../src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert.cfg .
+
+
+echo
+echo " Gen: developer SOC ID... "
+echo "================================================"
+./get_pub_key.sh oem_keypair1.pem oem_pwd1.txt oem_pubkey1.pem
+./gen_hbk_app -h hbk1.bin -p oem_pubkey1.pem
+./gen_socid_app -h hbk1.bin -r root_key1.txt -s soc_id1.bin
+
+echo
+echo " Run: generate developer certificate "
+echo "================================================"
+./cert_dbg_developer_util.py sb_developer_dbg_cert.cfg
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sd_gen_developer_cert_enter_pem.sh b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sd_gen_developer_cert_enter_pem.sh
new file mode 100755
index 0000000..e95aecf
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/developer_cert/sd_gen_developer_cert_enter_pem.sh
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#!/bin/bash
+
+cd ../../../bin/
+
+cp ../tester/cc3x_secure_debug_test/dat/dev_keypair1_3k.pem ./dev_keypair1.pem
+cp ../tester/cc3x_secure_debug_test/dat/oem_keypair1_3k.pem ./oem_keypair1.pem
+cp ../tester/cc3x_secure_debug_test/dat/root_key1.txt .
+cp ../src/cc3x_boot_cert/examples/developer_cert/sb_developer_dbg_cert_no_pwd.cfg .
+
+
+echo
+echo " Gen: developer SOC ID... "
+echo "================================================"
+./get_pub_key.sh oem_keypair1.pem pwd.txt oem_pubkey1.pem
+./gen_hbk_app -h hbk1.bin -p oem_pubkey1.pem
+./gen_socid_app -h hbk1.bin -r root_key1.txt -s soc_id1.bin
+
+echo
+echo " Run: generate developer certificate "
+echo "================================================"
+./cert_dbg_developer_util.py sb_developer_dbg_cert_no_pwd.cfg
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert.cfg
new file mode 100644
index 0000000..7680261
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert.cfg
@@ -0,0 +1,46 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for enabler debug certificate generation
+# [ENABLER-DBG-CFG]        Mandatory header.
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#lcs =                  The LCS that this certificate is intended for: 0 = CM; 1 = DM LCS; 5 = Secure; 7 = RMA.
+#rma-mode =             Set to non-zero value to use this certificate for RMA mode entry. Mandatory if debug-mask is not defined.
+#                       Cannot be defined together with debug-mask.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode. If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#debug-mask[x-y] =      The additional DCU lock by the OEM. 128 bit mask in  4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode.
+#hbk-id =               The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit HBK0; 1 = 128bit HBK1; 2 = 256bit HBK.
+#                       if debug-mask is defined, either hbk-id or key-cert-pkg must be defined. hbk-id is required if two-level certificate scheme is used,
+#                       and key-cert-pkg is required if three-level certificate scheme is used.
+#                       Mandatory if rma-mode is defined (for rma-mode, only two-level certificate scheme is supported).
+#key-cert-pkg =         Key certificate package, generated by cert_key_util.py, if three-level certificate scheme is used.
+#                       Must be empty if rma-mode is defined.
+#next-cert-pubkey =     File holding the RSA public key for signing the next certificate in the chain (the Developer Debug certificate), in pem format.
+#cert-pkg =             Enabler Debug certificate package output file. Binary format.
+[ENABLER-DBG-CFG]
+cert-keypair =  oem_keypair1.pem
+cert-keypair-pwd = pwd.txt
+lcs =  1
+#rma-mode =
+debug-mask[0-31]   = 0x00112233
+debug-mask[32-63]  = 0x44556677
+debug-mask[64-95]  = 0x8899AABB
+debug-mask[96-127] = 0xCCDDEEFF
+
+debug-lock[0-31]   = 0x00112233
+debug-lock[32-63]  = 0x44556677
+debug-lock[64-95]  = 0x8899AABB
+debug-lock[96-127] = 0xCCDDEEFF
+
+hbk-id = 2
+#key-cert-pkg =
+next-cert-pubkey = dev_pubkey1.pem
+cert-pkg = cert_enabler_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_no_pwd.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_no_pwd.cfg
new file mode 100644
index 0000000..579403d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_no_pwd.cfg
@@ -0,0 +1,45 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for enabler debug certificate generation
+# [ENABLER-DBG-CFG]        Mandatory header.
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#lcs =                  The LCS that this certificate is intended for: 0 = CM; 1 = DM LCS; 5 = Secure; 7 = RMA.
+#rma-mode =             Set to non-zero value to use this certificate for RMA mode entry. Mandatory if debug-mask is not defined.
+#                       Cannot be defined together with debug-mask.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode. If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#debug-mask[x-y] =      The additional DCU lock by the OEM. 128 bit mask in  4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode.
+#hbk-id =               The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit HBK0; 1 = 128bit HBK1; 2 = 256bit HBK.
+#                       if debug-mask is defined, either hbk-id or key-cert-pkg must be defined. hbk-id is required if two-level certificate scheme is used,
+#                       and key-cert-pkg is required if three-level certificate scheme is used.
+#                       Mandatory if rma-mode is defined (for rma-mode, only two-level certificate scheme is supported).
+#key-cert-pkg =         Key certificate package, generated by cert_key_util.py, if three-level certificate scheme is used.
+#                       Must be empty if rma-mode is defined.
+#next-cert-pubkey =     File holding the RSA public key for signing the next certificate in the chain (the Developer Debug certificate), in pem format.
+#cert-pkg =             Enabler Debug certificate package output file. Binary format.
+[ENABLER-DBG-CFG]
+cert-keypair =  oem_keypair1.pem
+cert-keypair-pwd =
+lcs =  1
+#rma-mode =
+debug-mask[0-31]   = 0x00112233
+debug-mask[32-63]  = 0x44556677
+debug-mask[64-95]  = 0x8899AABB
+debug-mask[96-127] = 0xCCDDEEFF
+
+debug-lock[0-31]   = 0x00112233
+debug-lock[32-63]  = 0x44556677
+debug-lock[64-95]  = 0x8899AABB
+debug-lock[96-127] = 0xCCDDEEFF
+hbk-id = 2
+#key-cert-pkg =
+next-cert-pubkey = dev_pubkey1.pem
+cert-pkg = cert_enabler_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma.cfg
new file mode 100644
index 0000000..208dc39
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma.cfg
@@ -0,0 +1,44 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for enabler debug certificate generation
+# [ENABLER-DBG-CFG]        Mandatory header.
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#lcs =                  The LCS that this certificate is intended for: 0 = CM; 1 = DM LCS; 5 = Secure; 7 = RMA.
+#rma-mode =             Set to non-zero value to use this certificate for RMA mode entry. Mandatory if debug-mask is not defined.
+#                       Cannot be defined together with debug-mask.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode. If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#debug-mask[x-y] =      The additional DCU lock by the OEM. 128 bit mask in  4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode.
+#hbk-id =               The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit HBK0; 1 = 128bit HBK1; 2 = 256bit HBK.
+#                       if debug-mask is defined, either hbk-id or key-cert-pkg must be defined. hbk-id is required if two-level certificate scheme is used,
+#                       and key-cert-pkg is required if three-level certificate scheme is used.
+#                       Mandatory if rma-mode is defined (for rma-mode, only two-level certificate scheme is supported).
+#key-cert-pkg =         Key certificate package, generated by cert_key_util.py, if three-level certificate scheme is used.
+#next-cert-pubkey =     File holding the RSA public key for signing the next certificate in the chain (the Developer Debug certificate), in pem format.
+#cert-pkg =             Enabler Debug certificate package output file. Binary format.
+[ENABLER-DBG-CFG]
+cert-keypair =  oem_keypair1.pem
+cert-keypair-pwd = pwd.txt
+lcs =  1
+rma-mode = 1
+#debug-mask[0-31]   =
+#debug-mask[32-63]  =
+#debug-mask[64-95]  =
+#debug-mask[96-127] =
+
+#debug-lock[0-31]   =
+#debug-lock[32-63]  =
+#debug-lock[64-95]  =
+#debug-lock[96-127] =
+hbk-id = 2
+#key-cert-pkg =
+next-cert-pubkey = dev_pubkey1.pem
+cert-pkg = cert_enabler_pkg_rma.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma_no_pwd.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma_no_pwd.cfg
new file mode 100644
index 0000000..2f88c2a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma_no_pwd.cfg
@@ -0,0 +1,45 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for enabler debug certificate generation
+# [ENABLER-DBG-CFG]        Mandatory header.
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#lcs =                  The LCS that this certificate is intended for: 0 = CM; 1 = DM LCS; 5 = Secure; 7 = RMA.
+#rma-mode =             Set to non-zero value to use this certificate for RMA mode entry. Mandatory if debug-mask is not defined.
+#                       Cannot be defined together with debug-mask.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode. If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#debug-mask[x-y] =      The additional DCU lock by the OEM. 128 bit mask in  4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode.
+#hbk-id =               The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit HBK0; 1 = 128bit HBK1; 2 = 256bit HBK.
+#                       if debug-mask is defined, either hbk-id or key-cert-pkg must be defined. hbk-id is required if two-level certificate scheme is used,
+#                       and key-cert-pkg is required if three-level certificate scheme is used.
+#                       Mandatory if rma-mode is defined (for rma-mode, only two-level certificate scheme is supported).
+#key-cert-pkg =         Key certificate package, generated by cert_key_util.py, if three-level certificate scheme is used.
+#                       Must be empty if rma-mode is defined.
+#next-cert-pubkey =     File holding the RSA public key for signing the next certificate in the chain (the Developer Debug certificate), in pem format.
+#cert-pkg =             Enabler Debug certificate package output file. Binary format.
+[ENABLER-DBG-CFG]
+cert-keypair =  oem_keypair1.pem
+cert-keypair-pwd =
+lcs =  1
+rma-mode = 1
+#debug-mask[0-31]   =
+#debug-mask[32-63]  =
+#debug-mask[64-95]  =
+#debug-mask[96-127] =
+
+#debug-lock[0-31]   =
+#debug-lock[32-63]  =
+#debug-lock[64-95]  =
+#debug-lock[96-127] =
+hbk-id = 2
+#key-cert-pkg =
+next-cert-pubkey = dev_pubkey1.pem
+cert-pkg = cert_enabler_pkg_rma.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sd_gen_enabler_cert.sh b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sd_gen_enabler_cert.sh
new file mode 100755
index 0000000..1ddcb14
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sd_gen_enabler_cert.sh
@@ -0,0 +1,33 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#!/bin/bash
+
+cd ../../../../bin/
+
+cp ../tester/util_assisted/get_pub_key/get_pub_key.sh .
+cp ../tester/cc3x_secure_debug_test/dat/dev_keypair1_3k.pem ./dev_keypair1.pem
+cp ../tester/cc3x_secure_debug_test/dat/oem_keypair1_3k.pem ./oem_keypair1.pem
+cp ../tester/cc3x_secure_debug_test/dat/pwd.txt .
+cp ../src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert.cfg .
+cp ../src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma.cfg .
+
+echo
+echo " Gen: developer public key... "
+echo "================================================"
+./get_pub_key.sh dev_keypair1.pem pwd.txt dev_pubkey1.pem
+
+echo
+echo " Run: generate enabler debug certificate "
+echo "================================================"
+./cert_dbg_enabler_util.py sb_enabler_dbg_cert.cfg
+
+echo
+echo " Run: generate enabler RMA certificate "
+echo "================================================"
+./cert_dbg_enabler_util.py sb_enabler_dbg_cert_rma.cfg
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sd_gen_enabler_cert_enter_pem.sh b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sd_gen_enabler_cert_enter_pem.sh
new file mode 100755
index 0000000..83517e9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/sd_gen_enabler_cert_enter_pem.sh
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#!/bin/bash
+cd ../../../../bin/
+
+cp ../tester/util_assisted/get_pub_key/get_pub_key.sh .
+cp ../tester/cc3x_secure_debug_test/dat/dev_keypair1_3k.pem ./dev_keypair1.pem
+cp ../tester/cc3x_secure_debug_test/dat/oem_keypair1_3k.pem ./oem_keypair1.pem
+cp ../src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_no_pwd.cfg .
+cp ../src/cc3x_boot_cert/examples/enabler_cert/sb_enabler_dbg_cert_rma_no_pwd.cfg .
+
+
+echo
+echo " Gen: developer public key... "
+echo "================================================"
+./get_pub_key.sh dev_keypair1.pem pwd.txt dev_pubkey1.pem
+
+echo
+echo " Run: generate enabler debug certificate "
+echo "================================================"
+./cert_dbg_enabler_util.py sb_enabler_dbg_cert_no_pwd.cfg
+
+echo
+echo " Run: generate enabler RMA certificate "
+echo "================================================"
+./cert_dbg_enabler_util.py sb_enabler_dbg_cert_rma_no_pwd.cfg
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert.cfg
new file mode 100644
index 0000000..7680261
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert.cfg
@@ -0,0 +1,46 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for enabler debug certificate generation
+# [ENABLER-DBG-CFG]        Mandatory header.
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#lcs =                  The LCS that this certificate is intended for: 0 = CM; 1 = DM LCS; 5 = Secure; 7 = RMA.
+#rma-mode =             Set to non-zero value to use this certificate for RMA mode entry. Mandatory if debug-mask is not defined.
+#                       Cannot be defined together with debug-mask.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode. If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#debug-mask[x-y] =      The additional DCU lock by the OEM. 128 bit mask in  4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode.
+#hbk-id =               The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit HBK0; 1 = 128bit HBK1; 2 = 256bit HBK.
+#                       if debug-mask is defined, either hbk-id or key-cert-pkg must be defined. hbk-id is required if two-level certificate scheme is used,
+#                       and key-cert-pkg is required if three-level certificate scheme is used.
+#                       Mandatory if rma-mode is defined (for rma-mode, only two-level certificate scheme is supported).
+#key-cert-pkg =         Key certificate package, generated by cert_key_util.py, if three-level certificate scheme is used.
+#                       Must be empty if rma-mode is defined.
+#next-cert-pubkey =     File holding the RSA public key for signing the next certificate in the chain (the Developer Debug certificate), in pem format.
+#cert-pkg =             Enabler Debug certificate package output file. Binary format.
+[ENABLER-DBG-CFG]
+cert-keypair =  oem_keypair1.pem
+cert-keypair-pwd = pwd.txt
+lcs =  1
+#rma-mode =
+debug-mask[0-31]   = 0x00112233
+debug-mask[32-63]  = 0x44556677
+debug-mask[64-95]  = 0x8899AABB
+debug-mask[96-127] = 0xCCDDEEFF
+
+debug-lock[0-31]   = 0x00112233
+debug-lock[32-63]  = 0x44556677
+debug-lock[64-95]  = 0x8899AABB
+debug-lock[96-127] = 0xCCDDEEFF
+
+hbk-id = 2
+#key-cert-pkg =
+next-cert-pubkey = dev_pubkey1.pem
+cert-pkg = cert_enabler_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert_rma.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert_rma.cfg
new file mode 100644
index 0000000..208dc39
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert_rma.cfg
@@ -0,0 +1,44 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for enabler debug certificate generation
+# [ENABLER-DBG-CFG]        Mandatory header.
+#cert-keypair =         File holding the RSA keypair for signing this certificate, in pem format.
+#cert-keypair-pwd =     Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#lcs =                  The LCS that this certificate is intended for: 0 = CM; 1 = DM LCS; 5 = Secure; 7 = RMA.
+#rma-mode =             Set to non-zero value to use this certificate for RMA mode entry. Mandatory if debug-mask is not defined.
+#                       Cannot be defined together with debug-mask.
+#debug-mask[x-y] =      The DCU mask allowed by the OEM. 128 bit mask in 4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode. If bit 0 in debug-mask[0-31] is set, the HW keys reset in debug mode is not performed
+#debug-mask[x-y] =      The additional DCU lock by the OEM. 128 bit mask in  4*32 bits hex format (e.g. 0x7000000f). Mandatory if rma-mode is not defined.
+#                       Cannot be defined together with rma-mode.
+#hbk-id =               The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit HBK0; 1 = 128bit HBK1; 2 = 256bit HBK.
+#                       if debug-mask is defined, either hbk-id or key-cert-pkg must be defined. hbk-id is required if two-level certificate scheme is used,
+#                       and key-cert-pkg is required if three-level certificate scheme is used.
+#                       Mandatory if rma-mode is defined (for rma-mode, only two-level certificate scheme is supported).
+#key-cert-pkg =         Key certificate package, generated by cert_key_util.py, if three-level certificate scheme is used.
+#next-cert-pubkey =     File holding the RSA public key for signing the next certificate in the chain (the Developer Debug certificate), in pem format.
+#cert-pkg =             Enabler Debug certificate package output file. Binary format.
+[ENABLER-DBG-CFG]
+cert-keypair =  oem_keypair1.pem
+cert-keypair-pwd = pwd.txt
+lcs =  1
+rma-mode = 1
+#debug-mask[0-31]   =
+#debug-mask[32-63]  =
+#debug-mask[64-95]  =
+#debug-mask[96-127] =
+
+#debug-lock[0-31]   =
+#debug-lock[32-63]  =
+#debug-lock[64-95]  =
+#debug-lock[96-127] =
+hbk-id = 2
+#key-cert-pkg =
+next-cert-pubkey = dev_pubkey1.pem
+cert-pkg = cert_enabler_pkg_rma.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sd_gen_enabler_cert.sh b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sd_gen_enabler_cert.sh
new file mode 100755
index 0000000..1f35f400
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/enabler_cert/x509_sd_gen_enabler_cert.sh
@@ -0,0 +1,33 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#!/bin/bash
+
+cd ../../../../bin/
+
+cp ../tester/util_assisted/get_pub_key/get_pub_key.sh .
+cp ../tester/cc3x_secure_debug_test/dat/dev_keypair1_3k.pem ./dev_keypair1.pem
+cp ../tester/cc3x_secure_debug_test/dat/oem_keypair1_3k.pem ./oem_keypair1.pem
+cp ../tester/cc3x_secure_debug_test/dat/pwd.txt .
+cp ../src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert.cfg .
+cp ../src/cc3x_boot_cert/examples/enabler_cert/x509_sb_enabler_dbg_cert_rma.cfg .
+
+echo
+echo " Gen: developer public key... "
+echo "================================================"
+./get_pub_key.sh dev_keypair1.pem pwd.txt dev_pubkey1.pem
+
+echo
+echo " Run: generate enabler debug certificate "
+echo "================================================"
+./cert_dbg_enabler_util.py x509_sb_enabler_dbg_cert.cfg
+
+echo
+echo " Run: generate enabler RMA certificate "
+echo "================================================"
+./cert_dbg_enabler_util.py x509_sb_enabler_dbg_cert_rma.cfg
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert.cfg
new file mode 100644
index 0000000..b9a0070
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert.cfg
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for key certificate generation
+# [KEY-CFG]             Mandatory header.
+# cert-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# cert-keypair-pwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# hbk-id =              The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit ICV key (HBK0); 1 = 128bit OEM key (HBK1); 2 = 256bit full key (HBK).
+#                       hbk-id is required if this is the:
+#                       	* First certificate in Two-level SB certificate chain
+#                       	* First certificate in Three-level SB certificate chain
+#                       	* First certificate in Three-level Secure Debug chain
+# nvcounter-val =       Value of the NV counter: 0..63 for HBK0 Trusted FW; 0..95 for HBK1 Trusted FW; 0..159 for full HBK Trusted FW.
+# next-cert-pubkey =    File holding the RSA public key for signing the next certificate in the chain
+#                       (secondary key certificate or content certificate or primary debug certificate), in pem format.
+# cert-pkg =            Key certificate package output file. Binary format.
+[KEY-CFG]
+cert-keypair =  ../../host/src/tests/sbrom_test_cc3x/dat/input/key_keypair.pem
+cert-keypair-pwd =  ../../host/src/tests/sbrom_test_cc3x/dat/input/pwd.txt
+hbk-id = 2
+nvcounter-val = 5
+next-cert-pubkey = ../../host/src/tests/sbrom_test_cc3x/dat/input/content_pubkey.pem
+cert-pkg = key_cert.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert_hbk0.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert_hbk0.cfg
new file mode 100644
index 0000000..b00c399
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert_hbk0.cfg
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for key certificate generation
+# [KEY-CFG]             Mandatory header.
+# cert-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# cert-keypair-pwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# hbk-id =              The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit ICV key (HBK0); 1 = 128bit OEM key (HBK1); 2 = 256bit full key (HBK).
+#                       hbk-id is required if this is the:
+#                       	* First certificate in Two-level SB certificate chain
+#                       	* First certificate in Three-level SB certificate chain
+#                       	* First certificate in Three-level Secure Debug chain
+# nvcounter-val =       Value of the NV counter: 0..63 for HBK0 Trusted FW; 0..95 for HBK1 Trusted FW; 0..159 for full HBK Trusted FW.
+# next-cert-pubkey =    File holding the RSA public key for signing the next certificate in the chain
+#                       (secondary key certificate or content certificate or primary debug certificate), in pem format.
+# cert-pkg =            Key certificate package output file. Binary format.
+[KEY-CFG]
+cert-keypair =  ../../host/src/tests/sbrom_test_cc3x/dat/input/key_keypair.pem
+cert-keypair-pwd =  ../../host/src/tests/sbrom_test_cc3x/dat/input/pwd.txt
+hbk-id = 0
+nvcounter-val = 5
+next-cert-pubkey = ../../host/src/tests/sbrom_test_cc3x/dat/input/content_pubkey.pem
+cert-pkg = key_cert_hbk0.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert_hbk1.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert_hbk1.cfg
new file mode 100644
index 0000000..d14524e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/examples/key_cert/sb_key_cert_hbk1.cfg
@@ -0,0 +1,28 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for key certificate generation
+# [KEY-CFG]             Mandatory header.
+# cert-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# cert-keypair-pwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# hbk-id =              The ID of the OTP memory HBK field for verification of the public key:  0 = 128bit ICV key (HBK0); 1 = 128bit OEM key (HBK1); 2 = 256bit full key (HBK).
+#                       hbk-id is required if this is the:
+#                       	* First certificate in Two-level SB certificate chain
+#                       	* First certificate in Three-level SB certificate chain
+#                       	* First certificate in Three-level Secure Debug chain
+# nvcounter-val =       Value of the NV counter: 0..63 for HBK0 Trusted FW; 0..95 for HBK1 Trusted FW; 0..159 for full HBK Trusted FW.
+# next-cert-pubkey =    File holding the RSA public key for signing the next certificate in the chain
+#                       (secondary key certificate or content certificate or primary debug certificate), in pem format.
+# cert-pkg =            Key certificate package output file. Binary format.
+[KEY-CFG]
+cert-keypair =  ../../host/src/tests/sbrom_test_cc3x/dat/input/key_keypair.pem
+cert-keypair-pwd =  ../../host/src/tests/sbrom_test_cc3x/dat/input/pwd.txt
+hbk-id = 1
+nvcounter-val = 5
+next-cert-pubkey = ../../host/src/tests/sbrom_test_cc3x/dat/input/content_pubkey.pem
+cert-pkg = key_cert_hbk1.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_lib/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_lib/Makefile
new file mode 100644
index 0000000..dedfc42
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_lib/Makefile
@@ -0,0 +1,47 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for building sbu_crypto library
+SH_LIB_NAME = libsbu_crypto.so
+
+LIB_SRC_O = main.o common_rsa_keypair.o  common_crypto_x509.o
+LIB_SRC_O += common_crypto_sym.o common_crypto_asym.o common_util_files.o common_rsa_keypair_util.o
+
+UTILS_ROOT = $(shell pwd)/../../..
+SHARED_DIR = $(UTILS_ROOT)/../shared
+HOST_DIR = $(UTILS_ROOT)/../host
+CODESAFE_DIR = $(UTILS_ROOT)/../codesafe
+UTILS_LIB_PATH = $(UTILS_ROOT)/lib
+UTILS_COMMON_PATH = $(UTILS_ROOT)/src/common
+UTILS_INC_PATH = $(UTILS_ROOT)/include $(UTILS_COMMON_PATH) $(SHARED_DIR)/include $(SHARED_DIR)/include/sbrom  $(SHARED_DIR)/include/proj/$(PROJ_PRD)
+UTILS_INC_PATH += $(HOST_DIR)/src/cc3x_sbromlib $(SHARED_DIR)/include/pal/$(TEE_OS) $(CODESAFE_DIR)/src/secure_boot_debug/cc3x_verifier $(SHARED_DIR)/include/pal
+UTILS_INC_PATH += $(CODESAFE_DIR)/src/secure_boot_debug/secure_boot_gen $(SHARED_DIR)/hw/include $(CODESAFE_DIR)/src/secure_boot_debug/crypto_driver $(CODESAFE_DIR)/src/secure_boot_debug/platform/pal/cc3x
+UTILS_INC_PATH += $(CODESAFE_DIR)/src/secure_boot_debug/platform/common/cc3x $(CODESAFE_DIR)/src/secure_boot_debug/platform/stage/boot/cc3x $(CODESAFE_DIR)/src/secure_boot_debug/util
+UTILS_INC_PATH += $(CODESAFE_DIR)/src/secure_boot_debug/secure_debug/cc3x $(CODESAFE_DIR)/src/secure_boot_debug/platform/hal $(CODESAFE_DIR)/src/secure_boot_debug/crypto_driver/reg
+UTILS_INC_PATH += $(SHARED_DIR)/include/pal  $(SHARED_DIR)/include/pal/$(TEE_OS)
+
+CFLAGS += -fPIC $(foreach incdir,$(UTILS_INC_PATH),-I$(incdir)) -c
+CFLAGS += -DCC_SB_SUPPORT_IOT
+
+
+all: $(SH_LIB_NAME)
+
+# Compile and link the sbu_crypto library with hard-coded library run path to utils/lib
+# (to assure the private version of openssl libraries are used)
+$(SH_LIB_NAME): $(LIB_SRC_O)
+	gcc -shared -o $(SH_LIB_NAME) $(LIB_SRC_O) -Wl,-rpath,$(UTILS_LIB_PATH) -lcrypto -lssl
+
+vpath %.c $(UTILS_ROOT)/src/common
+
+%.o: %.c
+	gcc $(CFLAGS) $<
+
+clean:
+	rm -f $(SH_LIB_NAME) $(LIB_SRC_O)
+
+.PHONY: clean all
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_lib/main.c b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_lib/main.c
new file mode 100644
index 0000000..e66d07d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_lib/main.c
@@ -0,0 +1,921 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/sha.h>
+#include "common_crypto_sym.h"
+#include "common_crypto_asym.h"
+#include "common_crypto_encode.h"
+#include "common_crypto_x509.h"
+#include "common_rsa_keypair.h"
+#include "common_rsa_keypair_util.h"
+#include "common_util_files.h"
+#include "common_util_log.h"
+#include "cc_crypto_boot_defs.h"
+#include "cc_crypto_x509_common_defs.h"
+#include "cc_crypto_x509_defs.h"
+#include "secdebug_defs.h"
+#include "bootimagesverifier_def.h"
+#include "cc_bitops.h"
+
+
+#define NONCE_LENGTH 8
+#define IV_LENGTH  AES_BLOCK_SIZE
+#define SBU_TRUE  1
+#define SBU_FALSE  0
+
+static uint8_t *gpCertBuff = NULL;
+static uint32_t gCertSize = 0;
+static CCX509CertType_t  gCertType = 0;
+static uint8_t  isLibOpened = 0;
+
+#define NVCOUNTER_EXT_SIZE  28
+#define NUM_OF_BITS_IN_BYTE 8
+#define MAX_IMAGE_CHUNK (1024)
+
+
+#define Nullptr (void *)0
+#define SIZE_OF_DATA_FOR_DERIVATION 22
+
+#define HASH_ON_PLAIN_TEXT      0
+#define HASH_ON_CIPHER_TEXT     1
+
+static CCX509CertHeaderParamsIn_t gCertHeaderParams={0};
+
+
+/**
+* @brief The SBU_RAND_Bytes reads RSA key from the file using passphrase
+*        and returns its decrypted value.
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] Key_ptr - passphrase
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_RAND_Bytes(int numBytes, char *buf)
+{
+    int result = -1;
+
+    if (numBytes > 0)
+    {
+        result = RAND_bytes (buf, numBytes);
+        if (result <= 0)
+            printf ("\nSBU_RAND_Bytes - Internal error: Function RAND_bytes failed\n");
+    }
+    return result;
+}
+
+
+
+
+/**
+* @brief internal function to reverse 64 bit word
+*
+* @param[in] original word
+* @param[out] reversed word
+*
+*/
+/*********************************************************/
+static void SBU_x509_ReverseWord64Bit(uint64_t word, uint64_t *reversedWord)
+{
+    uint32_t i = 0;
+    uint8_t maxInd = sizeof(uint64_t) - 1;
+    uint8_t *tmpOrig = (uint8_t*)&word;
+    uint8_t *tmpDst = (uint8_t*)reversedWord;
+
+    for (i = 0; i < sizeof(uint64_t); i++ ){
+        *(tmpDst + i) = *(tmpOrig + (maxInd-i));
+    }
+
+    return;
+}
+
+/**
+* @brief initialize openSSL library
+*
+* @param[in] None
+* @param[out] None
+*
+*/
+/*********************************************************/
+static void SBU_InitOpenSsl(void)
+{
+    if (0 == isLibOpened) {
+          OpenSSL_add_all_algorithms();
+    }
+    isLibOpened++;
+}
+
+
+/**
+* @brief terminates and cleanup openSSL library
+*
+* @param[in]  None
+* @param[out] None
+*
+*/
+/*********************************************************/
+static void SBU_CloseOpenSsl(void)
+{
+    isLibOpened--;
+    if (0 == isLibOpened) {
+          EVP_cleanup();
+          //CYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+    }
+}
+
+
+/**
+* @brief clears statit buffer saing config params for certificate header
+*
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_ClearHeaderParams()
+{
+    uint32_t rc = 0;
+
+    memset(&gCertHeaderParams, 0, sizeof(gCertHeaderParams));
+    return (rc);
+}
+
+
+/**
+* @brief Set Issuer Name for Certificate Header
+*
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_SetHeaderParam_IssuerName(int8_t *pIssuerName)
+{
+    uint32_t rc = 0;
+
+    if ((pIssuerName == NULL) || (strlen(pIssuerName) <= 0)){
+        rc =1;
+        return rc;
+    }
+
+    if (strlen(pIssuerName) > sizeof(gCertHeaderParams.IssuerName)-1){
+        rc =1;
+        return rc;
+    }
+
+    gCertHeaderParams.setIssuerName = SBU_TRUE;
+    strcpy(gCertHeaderParams.IssuerName, pIssuerName);
+
+    return (rc);
+}
+
+
+/**
+* @brief Set Subject Name for Certificate Header
+*
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_SetHeaderParam_SubjectName(int8_t *pSubjectName)
+{
+    uint32_t rc = 0;
+
+    if ((pSubjectName == NULL) || (strlen(pSubjectName) <= 0)){
+        rc =1;
+        return rc;
+    }
+
+    if (strlen(pSubjectName) > sizeof(gCertHeaderParams.SubjectName)-1){
+        rc =1;
+        return rc;
+    }
+
+    gCertHeaderParams.setSubjectName = SBU_TRUE;
+    strcpy(gCertHeaderParams.SubjectName, pSubjectName);
+
+    return (rc);
+}
+
+/**
+* @brief Set Subject Name for Certificate Header
+*
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_SetHeaderParam_NotBefore(long NotBefore)
+{
+    uint32_t rc = 0;
+
+    gCertHeaderParams.setNotBefore= SBU_TRUE;
+    gCertHeaderParams.notBefore= NotBefore;
+
+    return (rc);
+}
+
+/**
+* @brief Set Subject Name for Certificate Header
+*
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_SetHeaderParam_NotAfter(long NotAfter)
+{
+    uint32_t rc = 0;
+
+    gCertHeaderParams.setNotAfter= SBU_TRUE;
+    gCertHeaderParams.notAfter= NotAfter;
+
+    return (rc);
+}
+
+/**
+* @brief Set Subject Name for Certificate Header
+*
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_SetHeaderParam_SerialNumber(uint32_t SerialNumber)
+{
+    uint32_t rc = 0;
+
+    gCertHeaderParams.setSerialNum= SBU_TRUE;
+    gCertHeaderParams.serialNum= SerialNumber;
+
+    return (rc);
+}
+
+
+
+/**
+* @brief The SBU_AES_CTR_Encrypt encrypts (AES CTR) a given data and returns it.
+* Also, it hash either the plain or the cipher text according to cryptoType.
+*
+* @param[in] pFileName - input plain text
+* @param[in] pOutputFileName - output cipher text
+* @param[in] Key_ptr - the AES key
+* @param[in] KeySize - AES key size (must be one of the allowed AES key sizes)
+* @param[in] IV_ptr - IV (AES IV size is constant)
+* @param[in] Output_ptr - Output hash buffer
+* @param[in] imageSize - size of input data
+* @param[in] cryptoType - 0 - hash the plain text; 1 = hash the cipher text
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_AES_CTR_EncryptFile(char *pFileName,
+                    char *pOutputFileName,
+                    char* Key_ptr, int KeySize,
+                    char* IV_ptr,
+                    char* Output_ptr,
+                    uint32_t *imageSize,
+                    int8_t cryptoType)
+{
+    int rc = 0;
+    FILE *fd = NULL;
+    FILE *encFd = NULL;
+    int actualFileLen = 0;
+    bool encFlag = false;
+    uint32_t totalRead = 0;
+    uint32_t actualRead = 0;
+    unsigned char m_iv[AES_BLOCK_SIZE];
+    unsigned char m_key[AES_BLOCK_SIZE*2];
+    uint8_t origBuff[MAX_IMAGE_CHUNK] = {0};
+    uint8_t encryptedBuff[MAX_IMAGE_CHUNK+AES_BLOCK_SIZE] = {0};
+    uint32_t actualWriten = 0;
+    uint8_t *pBuff2Hash = NULL;
+    uint8_t imageHash[HASH_SHA256_DIGEST_SIZE_IN_BYTES] = {0};
+    EVP_CIPHER_CTX ctrCtx;
+    SHA256_CTX sha256Ctx;
+    uint32_t encryptedBuffSize = 0;
+    uint32_t prevBuffLen = 0;
+
+    if (pFileName == NULL || Output_ptr == NULL || imageSize == NULL){
+        printf("illegal parameters !\n");
+        return 1;
+    }
+    if (IV_ptr != NULL){ /* if there is IV than key is required as well */
+        memcpy (m_iv, IV_ptr, sizeof (m_iv));
+        memcpy (m_key, Key_ptr, KeySize);
+        encFlag = true;
+    }
+
+    /* Open image file for reading */
+    fd = fopen(pFileName, "rb");
+    if (NULL == fd) {
+        printf( "failed to open file %s for reading\n", pFileName);
+        return 1;
+    }
+    /* Get file length */
+    fseek(fd, 0, SEEK_END);
+    actualFileLen=ftell(fd);
+    if (actualFileLen == -1){
+        printf("ftell failed\n");
+        goto END;
+    }
+    fseek(fd, 0, SEEK_SET);
+    // validate size legal and word aligned
+    if ((0 == actualFileLen) ||
+        (actualFileLen % 0x4)) {
+        printf( "ilegal actualFileLen == 0\n");
+        rc = 3;
+        goto END;
+    }
+
+    /* init SHA256 open-ssl context */
+    rc = SHA256_Init(&sha256Ctx);
+    if (rc == 0) {
+        printf( "failed to SHA256_Init 0x%x\n", rc);
+        rc = 1;
+        goto END;
+    }
+
+    /* init variables in case encryption is needed */
+    if (encFlag == true) {
+        /* open encrypted file for writing encrypted image */
+        encFd = fopen(pOutputFileName, "wb");
+        if (NULL == encFd) {
+            printf( "failed to open file %s for writing\n", pOutputFileName);
+            rc = 1;
+            goto END;
+        }
+
+        /* init AES CTR open-ssl context */
+        EVP_CIPHER_CTX_init(&ctrCtx);
+        rc = EVP_EncryptInit(&ctrCtx, EVP_aes_128_ctr(), m_key, m_iv);
+        if (rc == 0) {
+            printf( "failed to EVP_EncryptInit_ex 0x%x\n", rc);
+            rc = 1;
+            goto END;
+        }
+    }
+
+    /* read max 1M bytes from image file,
+      if encryption is required, encrype first and write into pOutputFileName;
+      then perform SHA256. */
+    totalRead = 0;
+    prevBuffLen = 0;
+    encryptedBuffSize = 0;
+
+    while(totalRead < actualFileLen) {
+        /* read file content */
+        actualRead = fread(origBuff, 1, MAX_IMAGE_CHUNK, fd);
+        if (actualRead == 0)
+        {
+            printf( "fread returned 0\n");
+            goto END;
+        }
+        totalRead += actualRead;
+
+        pBuff2Hash = origBuff;
+        /* handle encryption */
+        if (encFlag == true) {
+            encryptedBuffSize = 0;
+            pBuff2Hash = &encryptedBuff[0];
+            rc = EVP_EncryptUpdate(&ctrCtx, encryptedBuff, &prevBuffLen, origBuff, actualRead);
+            if (rc == 0) {
+                printf( "failed to EVP_EncryptUpdate, rc 0x%x\n", rc);
+                rc = 1;
+                goto END;
+            }
+            /* update total encrypted byte count */
+            encryptedBuffSize += prevBuffLen;
+            if (totalRead >= actualFileLen) {
+                    rc = EVP_EncryptFinal_ex(&ctrCtx, encryptedBuff+encryptedBuffSize, &prevBuffLen);
+                if (rc == 0) {
+                    printf( "failed to EVP_EncryptFinal_ex, rc 0x%x\n", rc);
+                    rc = 1;
+                    goto END;
+                }
+                encryptedBuffSize += prevBuffLen;
+            }
+
+            /* write encrypted data to binary file  */
+            actualWriten = fwrite(pBuff2Hash, 1, actualRead, encFd);
+            if (actualWriten != actualRead) {
+                printf( "failed to write data to file actual written %d, expected %d\n", actualWriten, actualRead);
+                rc = 1;
+                goto END;
+            }
+        }
+
+        /* calculate SHA256 on plain/cipher image */
+        if (cryptoType == HASH_ON_PLAIN_TEXT) {
+            rc = SHA256_Update(&sha256Ctx, origBuff, actualRead);
+        } else {
+            rc = SHA256_Update(&sha256Ctx, encryptedBuff, actualRead);
+        }
+        if (rc == 0) {
+            printf( "failed to SHA256_Update, rc 0x%x\n", rc);
+            rc = 1;
+            goto END;
+        }
+        if (totalRead >= actualFileLen) {
+            rc = SHA256_Final(imageHash, &sha256Ctx);
+            if (rc == 0) {
+                printf( "failed to SHA256_Final, rc 0x%x\n", rc);
+                rc = 1;
+                goto END;
+            }
+            OPENSSL_cleanse(&sha256Ctx,sizeof(sha256Ctx));
+        }
+
+    }
+    // if we reached here rc is OK
+    rc = 0;
+    // copy the output HASH back to the caller
+    memcpy(Output_ptr , imageHash, HASH_SHA256_DIGEST_SIZE_IN_BYTES);
+    *imageSize = actualFileLen;
+
+END:
+    if (fd != NULL) {
+        fclose(fd);
+    }
+    if (encFd != NULL) {
+        fclose(encFd);
+    }
+
+    return rc;
+
+}
+
+
+
+
+
+
+
+/**
+* @brief allocate x509 certifiacte and set its header
+*
+* @param[in] certType - certifiacte type
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_CreateAndSetHeader(CCX509CertType_t  certType)
+{
+    uint32_t rc = 0;
+
+    SBU_InitOpenSsl();
+    rc = CC_CommonX509CreateAndSetHeader(&gpCertBuff, certType,&gCertHeaderParams);
+    if ((rc != 0) ||
+        (NULL == gpCertBuff)) {
+        UTIL_LOG_ERR("failed to CC_CommonX509CreateAndSetHeader \n");
+        goto END;
+    }
+    /* save certificate in global variable */
+    gCertType = certType;
+    rc = 0;
+
+    END:
+    if (rc != 0) {
+        SBU_CloseOpenSsl();
+    }
+    return (rc);
+}
+
+
+/**
+* @brief calculate Np from key pair file and add it to x509 certificate extension
+*
+* @param[in] pKeyPairFileName - key pair PEM format file name
+* @param[in] pwdFileName - key pair passphrase
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_AddPubKeyNpBuffExtension(int8_t *pKeyPairFileName, int8_t *pwdFileName)
+{
+    uint32_t rc = 0;
+    DxRsaKeyNandNp_t pNAndNp = {0};
+    uint32_t pNAndNpSize = sizeof(pNAndNp);
+
+    /* validate inputs */
+    if ((NULL == gpCertBuff) ||
+        (NULL == pKeyPairFileName)) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+    /* calculate N and Np */
+    rc =  CC_CommonGetNAndNpFromKeyPair(pKeyPairFileName, pwdFileName, (uint8_t *)&pNAndNp, &pNAndNpSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonGetNAndNpFromKeyPair %s pwd %s\n", pKeyPairFileName, pwdFileName);
+        goto END;
+    }
+    UTIL_LOG_BYTE_BUFF("pNAndNp", (uint8_t *)pNAndNp.pNpBuff, NP_SIZE_IN_BYTES);
+    /* Add Np to the cerifiacte extension */
+    rc = CC_CommonX509AddStringExtension(gpCertBuff, gCertType, CC_X509_ID_EXT_PUB_KEY_NP, pNAndNp.pNpBuff, NP_SIZE_IN_BYTES);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509AddStringExtension \n");
+        goto END;
+    }
+    rc = 0;
+
+    END:
+    if (rc != 0) {
+        if (gpCertBuff != NULL) {
+            CC_CommonX509Free(&gpCertBuff);
+        }
+        SBU_CloseOpenSsl();
+    }
+    return rc;
+}
+
+
+
+/**
+* @brief Add proprietary header as X509 extension
+*
+* @param[in] pHeaderInfo - proprietary header
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_AddPropHeaderExtension(uint8_t *pHeaderInfo)
+{
+    uint32_t rc = 0;
+
+    /* validate inputs */
+    if ((gpCertBuff == NULL) ||
+        (pHeaderInfo == NULL)) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+    UTIL_LOG_BYTE_BUFF("pHeaderInfo", pHeaderInfo, sizeof(CCSbCertHeader_t));
+    rc = CC_CommonX509AddStringExtension(gpCertBuff, gCertType, CC_X509_ID_EXT_PROPRIETARY_HEADER, pHeaderInfo, sizeof(CCSbCertHeader_t));
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509AddStringExtension \n");
+        goto END;
+    }
+    return rc;
+    END:
+    if (rc != 0) {
+        if (gpCertBuff != NULL) {
+            CC_CommonX509Free(&gpCertBuff);
+        }
+        SBU_CloseOpenSsl();
+    }
+    return rc;
+}
+/**
+* @brief Add key certificate body to X509 extension
+*
+* @param[in] nvCounter - SW version of the certificate, must be at least as defined in OTP
+* @param[in] pPubKeyFileName - Next certificate public key file name
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_AddKeyCertBodyExtension(uint32_t nvCounter,
+        uint8_t *pPubKeyFileName)
+{
+    uint32_t rc = 0;
+    KeyCertMain_t keyCertBody;
+
+    /* validate inputs */
+    if ((gpCertBuff == NULL) ||
+        (pPubKeyFileName == NULL)) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+
+    /* calculate SHA256 on public key file*/
+    rc = CC_CommonCalcHBKFromFile(pPubKeyFileName, keyCertBody.nextPubKeyHash, HASH_SHA256_DIGEST_SIZE_IN_BYTES);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonCalcHBKFromFile \n");
+        goto END;
+    }
+    keyCertBody.swVer = nvCounter;
+
+    rc = CC_CommonX509AddStringExtension(gpCertBuff, gCertType, CC_X509_ID_EXT_KEY_CERT_MAIN_VAL, (uint8_t *)&keyCertBody, sizeof(KeyCertMain_t));
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509AddStringExtension \n");
+        goto END;
+    }
+    rc = 0;
+
+    END:
+    if (rc != 0) {
+        if (gpCertBuff != NULL) {
+            CC_CommonX509Free(&gpCertBuff);
+        }
+        SBU_CloseOpenSsl();
+    }
+    return rc;
+}
+
+
+
+
+/**
+* @brief Add content certificate body to X509 extension
+*
+* @param[in] nvCounter - SW version of the certificate, must be at least as defined in OTP
+* @param[in] pNonce - Key nonce - 8 bytes
+* @param[in] pImageList - images data list
+* @param[in] imageListSize -size of pImageList
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_AddContentCertBodyExtension(uint32_t nvCounter,
+        uint8_t *pNonce,
+        uint8_t *pImageList,
+        uint32_t numOfImages)
+{
+    uint32_t rc = 0;
+    ContentCertMain_t certBody;
+    uint32_t    certBodySize;
+
+    /* validate inputs */
+    if ((gpCertBuff == NULL) ||
+        (pImageList == NULL) ||
+        (numOfImages == 0) || (numOfImages > CC_SB_MAX_NUM_OF_IMAGES) ||
+        (pNonce == NULL)) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+
+    certBody.swVer = nvCounter;
+    memcpy((uint8_t *)certBody.nonce, pNonce, sizeof(CCSbNonce_t));
+    memcpy((uint8_t *)certBody.imageRec, pImageList, sizeof(ContentCertImageRecord_t)*numOfImages);
+    certBodySize = sizeof(ContentCertMain_t) - (sizeof(ContentCertImageRecord_t)*(CC_SB_MAX_NUM_OF_IMAGES - numOfImages));
+    rc = CC_CommonX509AddStringExtension(gpCertBuff, gCertType, CC_X509_ID_EXT_CONTENT_CERT_MAIN_VAL, (uint8_t *)&certBody, certBodySize);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509AddStringExtension \n");
+        goto END;
+    }
+
+    END:
+    if (rc != 0) {
+        if (gpCertBuff != NULL) {
+            CC_CommonX509Free(&gpCertBuff);
+        }
+        SBU_CloseOpenSsl();
+    }
+    return rc;
+}
+
+
+
+/**
+* @brief Add Enabler certificate body to X509 extension
+*
+* @param[in] pDebugMask - Enabler certificate debug mask
+* @param[in] pDebugLock - Enabler certificate debug lock
+* @param[in] pPubKeyFileName - Developer certificate public key file name
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_AddEnablerCertBodyExtension(uint8_t *pDebugMask,
+        uint8_t *pDebugLock,
+        uint8_t *pPubKeyFileName)
+{
+    uint32_t rc = 0;
+    EnablerCertMain_t enablerCertBody;
+
+    /* validate inputs */
+    if ((gpCertBuff == NULL) ||
+        (pDebugMask == NULL) ||
+        (pDebugLock == NULL) ||
+        (pPubKeyFileName == NULL)) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+
+    /* calculate SHA256 on public key file*/
+    rc = CC_CommonCalcHBKFromFile(pPubKeyFileName, enablerCertBody.nextPubKeyHash, HASH_SHA256_DIGEST_SIZE_IN_BYTES);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonCalcHBKFromFile \n");
+        goto END;
+    }
+    memcpy((uint8_t *)enablerCertBody.debugMask, pDebugMask, CC_BSV_SEC_DEBUG_DCU_SIZE_IN_BYTES);
+    memcpy((uint8_t *)enablerCertBody.debugLock, pDebugLock, CC_BSV_SEC_DEBUG_DCU_SIZE_IN_BYTES);
+
+    rc = CC_CommonX509AddStringExtension(gpCertBuff, gCertType, CC_X509_ID_EXT_ENABLER_CERT_MAIN_VAL, (uint8_t *)&enablerCertBody, sizeof(EnablerCertMain_t));
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509AddStringExtension \n");
+        goto END;
+    }
+    rc = 0;
+
+    END:
+    if (rc != 0) {
+        if (gpCertBuff != NULL) {
+            CC_CommonX509Free(&gpCertBuff);
+        }
+        SBU_CloseOpenSsl();
+    }
+    return rc;
+}
+
+
+/**
+* @brief Add Developer certificate body to X509 extension
+*
+* @param[in] pDebugMask - Developer certificate debug mask
+* @param[in] pSocId - Developer certificate SoC ID
+**/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_AddDeveloperCertBodyExtension(uint8_t *pDebugMask,
+        uint8_t *pSocId)
+{
+    uint32_t rc = 0;
+    DeveloperCertMain_t developerCertBody;
+
+    /* validate inputs */
+    if ((gpCertBuff == NULL) ||
+        (pDebugMask == NULL) ||
+        (pSocId == NULL)) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+
+    memcpy((uint8_t *)developerCertBody.debugMask, pDebugMask, CC_BSV_SEC_DEBUG_DCU_SIZE_IN_BYTES);
+    memcpy((uint8_t *)developerCertBody.socId, pSocId, HASH_SHA256_DIGEST_SIZE_IN_BYTES);
+
+    rc = CC_CommonX509AddStringExtension(gpCertBuff, gCertType, CC_X509_ID_EXT_DEVELOPER_CERT_MAIN_VAL, (uint8_t *)&developerCertBody, sizeof(DeveloperCertMain_t));
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509AddStringExtension \n");
+        goto END;
+    }
+    rc = 0;
+
+    END:
+    if (rc != 0) {
+        if (gpCertBuff != NULL) {
+            CC_CommonX509Free(&gpCertBuff);
+        }
+        SBU_CloseOpenSsl();
+    }
+    return rc;
+}
+
+
+/**
+* @brief Add subject public key to the X509 certificate
+*   and sign the certificate
+*
+* @param[in] pKeyPairFileName   - key pair file name in PEM format
+* @param[in] pKeyPairPwd    - passphrase of key pair
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_SetKeyAndSign(int8_t *pKeyPairFileName,
+                     int8_t *pPrivKeyPwd)
+{
+    uint32_t rc = 0;
+
+    /* verify inputs */
+    if ((NULL == gpCertBuff) ||
+        (NULL == pKeyPairFileName)) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+    UTIL_LOG_INFO("calling CC_CommonX509SetKeyAndSign pKeyPairFileName %s, pPrivKeyPwd %s\n", pKeyPairFileName, pPrivKeyPwd);
+    rc = CC_CommonX509SetKeyAndSign(gpCertBuff, pKeyPairFileName, pPrivKeyPwd);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509SetKeyAndSign \n");
+        goto END;
+    }
+
+    rc = CC_CommonX509ToDer(&gpCertBuff, &gCertSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonX509ToDer \n");
+        goto END;
+    }
+    rc = 0;
+
+    END:
+    if (rc != 0) {
+        SBU_CloseOpenSsl();
+    }
+    return rc;
+}
+
+
+/**
+* @brief build package for the certificate
+*
+* @param[in] pAddData       - additional data to add to package
+* @param[in] addDataSize        - length of additional data
+* @param[out] outPkgFile        - package file name to write the package to
+*/
+/*********************************************************/
+SBUEXPORT_C uint32_t SBU_x509_BuildCertPkg(uint8_t *pAddData,
+                    uint32_t addDataSize,
+                    uint32_t  isAddDataBefore,
+                    uint8_t *outPkgFile)
+{
+    uint32_t rc = 0;
+    FILE *fp = NULL;
+    uint8_t *pCertPkg = NULL;
+    uint32_t pkgBytesSize = 0;
+    uint32_t pkgLocation = 0;
+
+    /* verify inputs */
+    if ((NULL == gpCertBuff) ||
+        (NULL == outPkgFile) ||
+        ((pAddData != NULL) && (addDataSize == 0)) ||
+        ((pAddData == NULL) && (addDataSize != 0))) {
+        UTIL_LOG_ERR("invalid input\n");
+        rc = 1;
+        goto END;
+    }
+
+    UTIL_LOG_INFO("outPkgFile %s, addDataSize %d, gCertSize %d\n", outPkgFile, addDataSize, gCertSize);
+    UTIL_LOG_BYTE_BUFF("pAddData", pAddData, addDataSize);
+    // Offset within package must be aligned
+    if (isAddDataBefore == 1) {
+        addDataSize = ALIGN_TO_4BYTES(addDataSize);
+    } else {
+        gCertSize = ALIGN_TO_4BYTES(gCertSize);
+    }
+
+    /* Calculate package size */
+    pkgBytesSize = gCertSize + addDataSize;
+
+    UTIL_LOG_INFO("Opening certificate pkg file for writing\n");
+    fp = fopen(outPkgFile, "w");
+    if (NULL == fp) {
+        UTIL_LOG_ERR("failed to open %s\n", outPkgFile);
+        rc = (-1);
+        goto END;
+    }
+
+    /* create the package buffer */
+    pCertPkg = (uint8_t *) malloc(pkgBytesSize);
+    if (pCertPkg == NULL){
+        UTIL_LOG_ERR("failed to allocate pkg\n");
+        rc = (-1);
+        goto END;
+    }
+    pkgLocation = 0;
+    if ((pAddData != NULL) &&
+        (isAddDataBefore == 1)){
+        memcpy(&pCertPkg[pkgLocation], pAddData, addDataSize);
+        pkgLocation += addDataSize;
+    }
+      /* copy certificate PEM  to package */
+    memcpy(&pCertPkg[pkgLocation], gpCertBuff, gCertSize);
+    pkgLocation += gCertSize;
+    /* copy additional data to package */
+    if ((pAddData != NULL) &&
+        (isAddDataBefore == 0)){
+        memcpy(&pCertPkg[pkgLocation], pAddData, addDataSize);
+        pkgLocation += addDataSize;
+    }
+    if (pkgLocation != (pkgBytesSize)) {
+        UTIL_LOG_ERR("Invalid pkgLocation %d, addDataSize %d, gCertSize %d\n", pkgLocation, addDataSize, gCertSize);
+        rc = 1;
+        goto END;
+    }
+
+    /* write out the package in binary format  */
+    UTIL_LOG_INFO("writing pkg to file\n");
+    rc = CC_CommonUtilCopyBuffToBinFile(outPkgFile, pCertPkg, pkgBytesSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonUtilCopyBuffToBinFile\n");
+        rc = 1;
+        goto END;
+    }
+    rc = 0;
+    UTIL_LOG_INFO("OK\n");
+
+END:
+    if (fp != NULL){
+        fclose(fp);
+    }
+    if (pCertPkg != NULL) {
+        free(pCertPkg);
+    }
+    if (gpCertBuff != NULL) {
+        free(gpCertBuff);
+    }
+    SBU_CloseOpenSsl();
+    return rc;
+
+
+
+}
+
+/**
+* @brief Reads RSA public key from the file and returns its raw value and its Np
+*
+* @param[in] pPemFileName_ptr - file name
+* @param[out] pNAndNp - N and Np buffer
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_x509_GetHashOfNAndNpFromPubKey(char* pPemFileName_ptr, char *pHash, int hashSize)
+{
+    int rc = 0;
+
+    SBU_InitOpenSsl();
+
+    rc = CC_CommonCalcHBKFromFile(pPemFileName_ptr, pHash, hashSize);
+    if (rc != 0) {
+        printf( "failed to CC_CommonCalcHBKFromFile %d or ilegal size %d\n", rc, hashSize);
+    }
+
+    SBU_CloseOpenSsl();  /* cleanup application specific data to avoid memory leaks.*/
+
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_dbg_developer_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_dbg_developer_util.py
new file mode 100755
index 0000000..0493320
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_dbg_developer_util.py
@@ -0,0 +1,198 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+# This utility builds developer debug certificate package:
+#       enabler certificate should be located before the developer certificate
+#       x509 header containing: version of certificate
+#                               serial number
+#                               certificate algorithm identifier of the issuer signature
+#                               Certificate Issuer name
+#                               Validity period
+#                               Subject name
+#       certificate public key: public key algorithm ID
+#                               public key - 3072 bits
+#       certificate extensions: ARM certificate header: token, 
+#                                                       version, 
+#                                                       length, 
+#                                                       flags: reserved word
+#                               Barret Tag of public key (Np)
+#                               Developer certificate body: debug bits value - 128 bit
+#                                                           SoC-ID - 128 bit
+#       certificate signature: certificate algorithm identifier of the issuer signature
+#                              signature of (x509 header + certificate public key + certificate extensions) - 3072 bits
+#
+
+
+
+import configparser
+import sys
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+    
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+from cert_cfg_parser_util import *
+from x509_util_helper import *
+from cert_basic_utilities import *
+from global_defines import *
+
+
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_dbg2_cert.log"
+    return config_fname, log_fname
+
+def exit_main_func(log_file, config_fname, rc):
+    log_file.close()
+    config_fname.close()
+    sys.exit(rc)
+
+
+
+def CreateCertUtility(sysArgsList):        
+    try:          
+
+        config_fname, log_fname = parse_shell_arguments()
+        
+        log_file = create_log_file(log_fname)
+        print_and_log(log_file, str(datetime.now()) + ": Developer Debug Certificate Utility started (Logging to " + log_fname + ")\n")
+    
+        data_dict, config = developer_cert_config_file_parser(config_fname, log_file)
+        if data_dict == None:
+            log_file.close()
+            exit(1) 
+    
+        DLLHandle = LoadDLLGetHandle()        
+        if data_dict == None:
+            print_and_log(log_file, "**** x509_cert_config_file_parser failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        #print_and_log(log_file, "**** calling get_cert_from_pkg **** \n")
+        enablerCertBin,enablerCertBin_size  = parse_bin_file(data_dict['enabler_cert_pkg'])
+     
+        #print_and_log(log_file, "**** calling SBU_x509_CreateAndSetHeader **** \n") 
+        result = DLLHandle.SBU_x509_CreateAndSetHeader(int(CC_X509_CERT_TYPE_DEVELOPER_DBG), 16) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_CreateAndSetHeader failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        #print_and_log(log_file, "**** calling SBU_x509_AddPropHeaderExtension **** \n") 
+        propHeader = build_certificate_header(DEBUG_DEVELOPER_TOKEN, PrjDefines, LIST_OF_CONF_PARAMS, 0, 0, 0)
+        result = DLLHandle.SBU_x509_AddPropHeaderExtension(propHeader.encode('iso-8859-1')) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPropHeaderExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        #print_and_log(log_file, "**** calling SBU_x509_AddPubKeyNpBuffExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddPubKeyNpBuffExtension(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPubKeyNpBuffExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        debugStr = str()
+        debugStr = byte2string(struct.pack('<I', data_dict['debug_mask0']))
+        debugStr = debugStr + byte2string(struct.pack('<I', data_dict['debug_mask1']))
+        debugStr = debugStr + byte2string(struct.pack('<I', data_dict['debug_mask2']))
+        debugStr = debugStr + byte2string(struct.pack('<I', data_dict['debug_mask3']))
+
+        SOC_IS_SIZE = 32
+        socid_buff, socid_size = parse_bin_file(data_dict["soc_id"])
+        if socid_size != SOC_IS_SIZE:
+            print_and_log(log_file, "illegal soc_id file\n")
+            DLLHandle.SBU_CloseOpenSsl()
+            exit_main_func(log_file, config_fname, result)
+
+        #print_and_log(log_file, "**** calling SBU_x509_AddDeveloperCertBodyExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddDeveloperCertBodyExtension(debugStr.encode('iso-8859-1'), byref(socid_buff))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddSocIdExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        #print_and_log(log_file, "**** calling SBU_x509_SetKeyAndSign **** \n") 
+        result = DLLHandle.SBU_x509_SetKeyAndSign(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_SetKeyAndSign failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        #print_and_log(log_file, "**** calling SBU_x509_BuildCertPkg **** \n") 
+        result = DLLHandle.SBU_x509_BuildCertPkg(byref(enablerCertBin), enablerCertBin_size, 1, str.encode(data_dict["cert_pkg"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_BuildCertPkg failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+      
+        
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print_and_log(log_file, "I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print_and_log(log_file, "Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print_and_log(log_file, "Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_dbg_enabler_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_dbg_enabler_util.py
new file mode 100755
index 0000000..61b1093
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_dbg_enabler_util.py
@@ -0,0 +1,203 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+# This utility builds enabler debug certificate package:
+#       If key certificate exists it should be located before the enabler certificate
+#       x509 header containing: version of certificate
+#                               serial number
+#                               certificate algorithm identifier of the issuer signature
+#                               Certificate Issuer name
+#                               Validity period
+#                               Subject name
+#       certificate public key: public key algorithm ID
+#                               public key - 3072 bits
+#       certificate extensions: ARM certificate header: token, 
+#                                                       version, 
+#                                                       length, 
+#                                                       flags: HBK use, valid LCS, isRma
+#                               Barret Tag of public key (Np)
+#                               Enabler certificate body: debug mask value - 128 bit
+#                                                         debug lock value - 128 bit
+#                                                         SHA256 digest of developer public key
+#       certificate signature: certificate algorithm identifier of the issuer signature
+#                              signature of (x509 header + certificate public key + certificate extensions) - 3072 bits
+#
+
+
+import configparser
+import sys
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+    
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+
+from cert_cfg_parser_util import *
+from global_defines import *
+from cert_basic_utilities import *
+from x509_util_helper import *
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_dbg1_cert.log"
+    return config_fname, log_fname
+
+def exit_main_func(log_file, config_fname, rc):
+    log_file.close()
+    config_fname.close()
+    sys.exit(rc)
+
+
+def CreateCertUtility(sysArgsList):
+    try:          
+
+        config_fname, log_fname = parse_shell_arguments()
+        log_file = create_log_file(log_fname)
+        print_and_log(log_file, str(datetime.now()) + ": Enabler Debug Certificate Utility started (Logging to " + log_fname + ")\n")
+    
+        
+        data_dict, config = enabler_cert_config_file_parser(config_fname, log_file)
+        if data_dict == None:
+            log_file.close()
+            exit(1) 
+            
+        DLLHandle = LoadDLLGetHandle()    
+            
+        if data_dict == None:
+            print_and_log(log_file, "**** x509_cert_config_file_parser failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        # if key package exists need to insert it into the enabler certificate 
+        if data_dict['key_cert_pkg'] != "":
+            keyStr, keyStrSize = parse_bin_file(data_dict['key_cert_pkg'])
+        else:
+            keyStr = None
+            keyStrSize = 0
+
+        print_and_log(log_file, "**** calling SBU_x509_CreateAndSetHeader **** \n") 
+        result = DLLHandle.SBU_x509_CreateAndSetHeader(int(CC_X509_CERT_TYPE_ENABLER_DBG)) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_CreateAndSetHeader failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "**** calling SBU_x509_AddPropHeaderExtension **** \n") 
+        propHeader = build_certificate_header(DEBUG_ENABLER_TOKEN, PrjDefines, LIST_OF_CONF_PARAMS, data_dict['rma_mode'], data_dict['hbk_id'], data_dict['lcs'])
+        result = DLLHandle.SBU_x509_AddPropHeaderExtension(propHeader.encode('iso-8859-1')) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPropHeaderExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "**** calling SBU_x509_AddPubKeyNpBuffExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddPubKeyNpBuffExtension(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"])) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPubKeyNpBuffExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        debugStr = str()
+        debugStr = byte2string(struct.pack('<I', data_dict['debug_mask0']))
+        debugStr = debugStr + byte2string(struct.pack('<I', data_dict['debug_mask1']))
+        debugStr = debugStr + byte2string(struct.pack('<I', data_dict['debug_mask2']))
+        debugStr = debugStr + byte2string(struct.pack('<I', data_dict['debug_mask3']))
+    
+        debugStr1 = str()
+        debugStr1 = byte2string(struct.pack('<I', data_dict['debug_lock0']))
+        debugStr1 = debugStr1 + byte2string(struct.pack('<I', data_dict['debug_lock1']))
+        debugStr1 = debugStr1 + byte2string(struct.pack('<I', data_dict['debug_lock2']))
+        debugStr1 = debugStr1 + byte2string(struct.pack('<I', data_dict['debug_lock3']))
+
+        print_and_log(log_file, "**** calling SBU_x509_AddEnablerCertBodyExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddEnablerCertBodyExtension(debugStr.encode('iso-8859-1'), debugStr1.encode('iso-8859-1'), str.encode(data_dict["next_cert_pubkey"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddDebugMaskExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+        
+        print_and_log(log_file, "**** calling SBU_x509_SetKeyAndSign **** \n") 
+        result = DLLHandle.SBU_x509_SetKeyAndSign(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_SetKeyAndSign failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+ 
+        print_and_log(log_file, "**** calling SBU_x509_BuildCertPkg **** \n") 
+        if keyStr == None:
+            result = DLLHandle.SBU_x509_BuildCertPkg(0, 0, 1, data_dict["cert_pkg"])
+        else:
+            result = DLLHandle.SBU_x509_BuildCertPkg(byref(keyStr), keyStrSize, 1, data_dict["cert_pkg"])
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_BuildCertPkg failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print_and_log(log_file, "I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print_and_log(log_file, "Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print_and_log(log_file, "Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_key_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_key_util.py
new file mode 100755
index 0000000..aa3a687
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_key_util.py
@@ -0,0 +1,182 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+
+# This utility builds enabler debug certificate package:
+#       If key certificate exists it should be located before the enabler certificate
+#       x509 header containing: version of certificate
+#                               serial number
+#                               certificate algorithm identifier of the issuer signature
+#                               Certificate Issuer name
+#                               Validity period
+#                               Subject name
+#       certificate public key: public key algorithm ID
+#                               public key - 3072 bits
+#       certificate extensions: ARM certificate header: token, 
+#                                                       version, 
+#                                                       length, 
+#                                                       flags: HBK use, valid LCS, isRma
+#                               Barret Tag of public key (Np)
+#                               Enabler certificate body: SW version - 32 bit
+#                                                         SHA256 digest of Next ecrtificate public key
+#       certificate signature: certificate algorithm identifier of the issuer signature
+#                              signature of (x509 header + certificate public key + certificate extensions) - 3072 bits
+#
+
+
+import configparser
+import sys
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+    
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+from cert_cfg_parser_util import *
+from key_data_structures import *
+from global_defines import *
+from x509_util_helper import *
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_dbg1_cert.log"
+    return config_fname, log_fname
+
+def exit_main_func(log_file, config_fname, rc):
+    log_file.close()
+    config_fname.close()
+    sys.exit(rc)
+
+
+def CreateCertUtility(sysArgsList):
+    try:          
+
+        config_fname, log_fname = parse_shell_arguments()
+        log_file = create_log_file(log_fname)
+        print_and_log(log_file, str(datetime.now()) + ": Key Certificate Utility started (Logging to " + log_fname + ")\n")
+    
+        
+        data_dict, config = key_cert_config_file_parser(config_fname, log_file)
+        if data_dict == None:
+            log_file.close()
+            exit(1) 
+            
+        DLLHandle = LoadDLLGetHandle()    
+            
+        data_dict = x509_cert_config_file_parser("KEY-CFG", config, data_dict, log_file)
+        if data_dict == None:
+            print_and_log(log_file, "**** x509_cert_config_file_parser failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        print_and_log(log_file, "**** calling SBU_x509_CreateAndSetHeader **** \n") 
+        result = DLLHandle.SBU_x509_CreateAndSetHeader(int(CC_X509_CERT_TYPE_KEY)) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_CreateAndSetHeader failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "**** calling SBU_x509_AddPropHeaderExtension **** \n") 
+        propHeader = CertHeader(log_file, data_dict['hbk_id'], CERT_TYPE_KEY, 0, 0, 0, 0, PrjDefines)
+        headerStr = propHeader.VarsToBinString()
+        result = DLLHandle.SBU_x509_AddPropHeaderExtension(headerStr.encode('iso-8859-1')) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPropHeaderExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "**** calling SBU_x509_AddPubKeyNpBuffExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddPubKeyNpBuffExtension(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"])) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPubKeyNpBuffExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        print_and_log(log_file, "**** calling SBU_x509_AddKeyCertBodyExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddKeyCertBodyExtension(data_dict['nvcounter_val'], str.encode(data_dict["next_cert_pubkey"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddKeyCertBodyExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+        
+        print_and_log(log_file, "**** calling SBU_x509_SetKeyAndSign **** \n") 
+        result = DLLHandle.SBU_x509_SetKeyAndSign(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_SetKeyAndSign failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+ 
+        print_and_log(log_file, "**** calling SBU_x509_BuildCertPkg **** \n") 
+        result = DLLHandle.SBU_x509_BuildCertPkg(0, 0, 1, str.encode(data_dict["cert_pkg"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_BuildCertPkg failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print_and_log(log_file, "I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print_and_log(log_file, "Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print_and_log(log_file, "Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_sb_content_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_sb_content_util.py
new file mode 100755
index 0000000..d3a0bd7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/cert_sb_content_util.py
@@ -0,0 +1,201 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+
+# This utility builds enabler debug certificate package:
+#       If key certificate exists it should be located before the enabler certificate
+#       x509 header containing: version of certificate
+#                               serial number
+#                               certificate algorithm identifier of the issuer signature
+#                               Certificate Issuer name
+#                               Validity period
+#                               Subject name
+#       certificate public key: public key algorithm ID
+#                               public key - 3072 bits
+#       certificate extensions: ARM certificate header: token, 
+#                                                       version, 
+#                                                       length, 
+#                                                       flags: HBK use, valid LCS, isRma
+#                               Barret Tag of public key (Np)
+#                               Enabler certificate body: SW version - 32 bit
+#                                                         Nonce - 8 bytes
+#                                                         Data list
+#       certificate signature: certificate algorithm identifier of the issuer signature
+#                              signature of (x509 header + certificate public key + certificate extensions) - 3072 bits
+#
+
+
+import configparser
+import sys
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+    
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+from cert_cfg_parser_util import *
+from key_data_structures import *
+from global_defines import *
+from cnt_data_structures import *
+from x509_util_helper import *
+
+# this is the path of the proj config file
+PROJ_CFG_PATH = "src" + path_div
+PROJ_CONFIG = CURRENT_PATH + path_div + ".." + path_div + PROJ_CFG_PATH + 'proj.cfg'
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "sb_cnt_cert.log"
+    return config_fname, log_fname
+
+def exit_main_func(log_file, config_fname, rc):
+    log_file.close()
+    config_fname.close()
+    sys.exit(rc)
+
+
+def CreateCertUtility(sysArgsList):
+    try:          
+
+        config_fname, log_fname = parse_shell_arguments()
+        log_file = create_log_file(log_fname)
+        print_and_log(log_file, str(datetime.now()) + ": Content Certificate Utility started (Logging to " + log_fname + ")\n")
+    
+        
+        data_dict, config = content_cert_config_file_parser(config_fname, log_file)
+        if data_dict == None:
+            log_file.close()
+            exit(1) 
+            
+        DLLHandle = LoadDLLGetHandle()    
+            
+        data_dict = x509_cert_config_file_parser("CNT-CFG", config, data_dict, log_file)
+        if data_dict == None:
+            print_and_log(log_file, "**** x509_cert_config_file_parser failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        print_and_log(log_file, "**** calling SBU_x509_CreateAndSetHeader **** \n") 
+        result = DLLHandle.SBU_x509_CreateAndSetHeader(int(CC_X509_CERT_TYPE_CONTENT)) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_CreateAndSetHeader failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+        
+        #building the certificate body
+        keyNonce = KeyNonce(data_dict['aes_ce_id'], DLLHandle)  
+        nonceStr = keyNonce.VarsToBinString()  
+                      
+        RecList = ImageFileAnalyzer(log_file, data_dict['images_table'], data_dict['load_verify_scheme'], data_dict['aes_ce_id'], DLLHandle, data_dict['aes_enc_key'], keyNonce.randStr, data_dict['crypto_type'])
+   
+        print_and_log(log_file, "**** calling SBU_x509_AddPropHeaderExtension **** \n") 
+        propHeader = CertHeader(log_file, int('0xf',16), CERT_TYPE_CONTENT, data_dict['aes_ce_id'], data_dict['load_verify_scheme'], data_dict['crypto_type'], len(RecList), PrjDefines)
+        headerStr = propHeader.VarsToBinString()
+        result = DLLHandle.SBU_x509_AddPropHeaderExtension(headerStr.encode('iso-8859-1')) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPropHeaderExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "**** calling SBU_x509_AddPubKeyNpBuffExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddPubKeyNpBuffExtension(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"])) 
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddPubKeyNpBuffExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        BinStr = str()
+        # In a loop add the component objects to the binary string (only if not empty)
+        for obj in RecList:
+            BinStr = BinStr + obj.VarsToBinStringHashComp()
+
+        print_and_log(log_file, "**** calling SBU_x509_AddContentCertBodyExtension **** \n") 
+        result = DLLHandle.SBU_x509_AddContentCertBodyExtension(data_dict['nvcounter_val'], nonceStr.encode('iso-8859-1'), BinStr.encode('iso-8859-1'), len(RecList))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_AddContentCertBodyExtension failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+        
+        print_and_log(log_file, "**** calling SBU_x509_SetKeyAndSign **** \n") 
+        result = DLLHandle.SBU_x509_SetKeyAndSign(str.encode(data_dict["cert_keypair"]), str.encode(data_dict["cert_keypair_pwd"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_SetKeyAndSign failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+
+        # Add the none-signed info data        
+        BinStrNotSigned = str()
+        for obj in RecList:
+            BinStrNotSigned = BinStrNotSigned + obj.VarsToBinStringParamComp()
+
+        print_and_log(log_file, "**** calling SBU_x509_BuildCertPkg **** \n") 
+        #Non-signed table is after certificate
+        result = DLLHandle.SBU_x509_BuildCertPkg(BinStrNotSigned.encode('iso-8859-1'), len(BinStrNotSigned), 0, str.encode(data_dict["cert-pkg"]))
+        if result != 0:
+            print_and_log(log_file, "**** SBU_x509_BuildCertPkg failed ****\n")
+            exit_main_func(log_file, config_fname, result)
+    
+        print_and_log(log_file, "\n**** Certificate file creation has been completed successfully ****")
+
+    except IOError as Error8: 
+        (errno, strerror) = Error8.args 
+        print_and_log(log_file, "I/O error(%s): %s" % (errno, strerror))
+        raise
+    except NameError:
+        print_and_log(log_file, "Unexpected error, exiting program")
+        raise  # Debug info
+    except ValueError:
+        print_and_log(log_file, "Illegal variable type")
+        raise # Debug info
+
+
+##################################
+#       Main function
+##################################
+        
+if __name__ == "__main__":
+
+    import sys
+    if sys.version_info<(3,0,0):
+        print("You need python 3.0 or later to run this script")
+        exit(1)
+
+    if "-cfg_file" in sys.argv:
+        PROJ_CONFIG = sys.argv[sys.argv.index("-cfg_file") + 1]
+    print("Config File  - %s\n" %PROJ_CONFIG)
+
+    # Get the project configuration values
+    PrjDefines = parseConfFile(PROJ_CONFIG,LIST_OF_CONF_PARAMS)
+    
+    CreateCertUtility(sys.argv)
+
+
+
+
+    
+
+
+
+######################################## END OF FILE ########################################
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/hbk_gen_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/hbk_gen_util.py
new file mode 100755
index 0000000..fff2a67
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/hbk_gen_util.py
@@ -0,0 +1,236 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+import sys
+import os 
+from datetime import datetime
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+import string
+from ctypes import *
+from cert_basic_utilities import * 
+
+OUTPUT_SIZE_SHA_256 = 32
+OUTPUT_SIZE_SHA_256_TRUNC = int(OUTPUT_SIZE_SHA_256/2)
+BITS_WITHIN_WORD = 32
+BYTES_WITHIN_WORD = 4
+
+# Prim key hash file name
+PRIM_KEY_HASH_FILE_NAME = "prim_key_hash.txt"
+ZEROS_NUM_FILES_NAME = "zero_bits_in_hash.txt" 
+
+####################################################################
+# Filename - hbk_gen_util.py
+# Description - This file is responsible for creation of public key
+#               HASH and its corresponding number of Zeroes
+#               as it should be saved in the OTP/NVM
+####################################################################
+
+#################### Utility functions #############################
+
+# The function creates words list out of a string that contains hex
+# resrepesentation
+def CreateWordList(buff, buffWordSize, endiannes):
+
+    wordList = list()
+    
+    for i in range(int(buffWordSize)):
+        word = 0
+        if endiannes == 'L':
+            #int(buff[i].encode('hex'),16)
+            word = buff[i*4]
+            word = word+(buff[i*4+1]<<8)
+            word = word+(buff[i*4+2]<<16)
+            word = word+(buff[i*4+3]<<24)
+        else:
+            word = buff[i*4+3]
+            word = word+(buff[i*4+2]<<8)
+            word = word+(buff[i*4+1]<<16)
+            word = word+(buff[i*4]<<24)
+        wordList.append(format(word, 'x'))
+
+    return wordList    
+
+
+####################################################################
+
+
+# The function calculates the number of Zeroes for a given data
+def CalculateZeroBitCountOnData(HASHwordList, size):    
+#total number of zeros, start value
+    zero_sum = int(0)
+    
+    for word in HASHwordList:
+        if size == 0:
+            break
+        #1's bit count start value
+        count = 0
+        intWord = int(word, 16)        
+        while (intWord):      
+            count += (intWord & 1)
+            intWord >>= 1                      
+        zero_sum += (BITS_WITHIN_WORD - count)
+        size -=1
+    
+    return zero_sum
+
+      
+# The function writes the output to output files 
+# (a file for the HASH and a different file for the HBK num of Zeroes)
+# File names are fixed
+def WriteOutputToFile(HASHwordList, buffData, size, hash_file ,zeros_file):
+    fobHash = open(hash_file, 'w')
+    fobZeroNum = open(zeros_file, 'w')
+    
+    # The output is already set in the required endianess
+    for i in range(size):
+        if i != size - 1:
+            # Unless it is the last word add comma
+            fobHash.write(" 0x"+HASHwordList[i]+",")
+        else:
+            fobHash.write(" 0x"+HASHwordList[i] +" ")
+
+    # Write the num of zeroes to output file    
+    fobZeroNum.write(buffData)
+
+    # Close files        
+    fobHash.close()
+    fobZeroNum.close()
+    
+    return
+
+
+# This function prints the instructions of how to operate the utility
+def usage():
+    print("""Syntax: ./hbk_gen_util.py -key <RSA public-key file name> -endian <optional endianness> -hash_format <optional hash_format> \n
+hbk_gen_util.py creates HASH over concatenation of N (public key) and Np (Barrett N' value) and calculates number of zero bits over the HASH value.\n
+Input arguments:\n
+-key <RSA public key file name> - mandatory, RSA public key in PEM format\n
+-endian <endianness, B||L> - optional, endianness flag, B for Big endian or L for little endian; default is little endian\n
+-hash_format <[SHA256 | SHA256_TRUNC]> - optional, HASH algorithm identifier determines the hash public key size; default is SHA256\n
+outputs:\n
+"prim_key_hash.txt" - file containing primary key hash text file in word format\n
+"zero_bits_in_hash.txt" - file containing number of zeros for primary key hash\n 
+""")
+    sys.exit(1)
+
+
+# The function parses the input parameters and returns a list of the given parameters 
+def parse_shell_arguments():
+    # Input parameters are :
+    # -key [RSA pubkey name] - mandatory, RSA public key name
+    # -endian <endianness, B||L> - optional, endianness flag, B for Big endian or L for little endian
+    # -hash_format <[SHA256 | SHA256_TRUNC]> - optional, HASH algorithm identifier determines the hash public key size
+
+    sysArgsList = sys.argv
+
+    # check if the key exist if not return error
+    if "-key" in sysArgsList:
+        key_fname = sysArgsList[sysArgsList.index("-key") + 1]
+    else:
+        print("-key [RSA public key file name] is mandatory")
+        usage()
+        sys.exit(1)
+
+    # Read the endianity and set it in the project defines list 
+    if "-endian" in sysArgsList:
+        endianity = sysArgsList[sysArgsList.index("-endian") + 1]
+        if (endianity != 'B' and endianity != 'L'):
+            print("-endian <[B | L]> is illegal")
+            usage()
+            sys.exit(1)
+    else:
+        endianity = "L"
+
+    # check if the hash_format exist; if not, set default to SHA256
+    if "-hash_format" in sysArgsList:
+        hbk_format = sysArgsList[sysArgsList.index("-hash_format") + 1]
+        if (hbk_format != 'SHA256' and hbk_format != 'SHA256_TRUNC'):
+            print("-hash_format <[SHA256 | SHA256_TRUNC]> is illegal")
+            usage()
+            sys.exit(1)
+    else:
+        hbk_format = "SHA256"
+        
+    if "-hash_out" in sysArgsList:
+        hash_file =  sysArgsList[sysArgsList.index("-hash_out") + 1]
+    else:
+        hash_file = PRIM_KEY_HASH_FILE_NAME
+        
+    if "-zeros_out" in sysArgsList:
+        zeros_file =  sysArgsList[sysArgsList.index("-zeros_out") + 1] 
+    else:
+        zeros_file = ZEROS_NUM_FILES_NAME
+    
+    return key_fname, endianity, hbk_format, hash_file, zeros_file
+
+##########################################################################################################
+
+# Main functin, responsible for creating HASH value over N | Np and and the corresponding number of Zeroes value.
+# The function expects the following inputs :
+# 1. RSA public key file name mandatory (key file expected to be in openSSL PEM format)
+# 2. Output format flag (L||B) little or big endian (optional, if not given L - little endian will be used) 
+# 3. hash_format (SHA256||SHA256_TRUNC) (optional, if not given HASH SHA256 size will be used)
+# The output will be written to two files: PrimKeyHASH.txt & ZeroBitsInHASH.txt
+def main():
+
+    pubKeyFileName, endianness, hash_format ,hash_file ,zeros_file= parse_shell_arguments()
+    log_file = create_log_file("gen_hbk_log.log")
+    print_and_log(log_file, str(datetime.now()) + ": generate HBK Utility started (Logging to gen_hbk_log.log)\n")
+
+    #print_and_log(log_file, "**** loading library ****\n ") 
+    DLLHandle = LoadDLLGetHandle()        
+
+    # decide on hash output size
+    if (hash_format == 'SHA256'):
+        outputSize = OUTPUT_SIZE_SHA_256  
+    else:
+        outputSize = OUTPUT_SIZE_SHA_256_TRUNC  
+
+    outputWordSize = int(round(outputSize/BYTES_WITHIN_WORD))  
+
+    print_and_log(log_file, "\nStep 1 calculate hash")
+    IntArrayParam = c_ubyte * outputSize
+    publicKeyHash = IntArrayParam()
+    result = DLLHandle.SBU_x509_GetHashOfNAndNpFromPubKey(str.encode(pubKeyFileName), byref(publicKeyHash), outputSize)
+    if result != 0:
+        print_and_log(log_file,  "unable to calc hash for " + str.encode(pubKeyFileName) + "\n")
+        sys.exit(1)
+
+    HASHWordsList = CreateWordList(publicKeyHash, outputWordSize, endianness)
+
+    print_and_log(log_file, "\nStep 2 - Calculate num of zero bits over the HASH")
+    # Calculate the num of zeroes on the data & write it to files
+    WriteOutputToFile(HASHWordsList, str(hex(CalculateZeroBitCountOnData(HASHWordsList,outputWordSize))), outputWordSize,hash_file ,zeros_file)
+    
+    print_and_log(log_file, "\nFunction completed successfully")
+
+    sys.exit(0)
+
+
+#############################
+if __name__ == "__main__":
+    main()
+    
+    
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/x509_util_helper.py b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/x509_util_helper.py
new file mode 100755
index 0000000..f8d2e73
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cc3x_boot_cert/x509cert_utils/x509_util_helper.py
@@ -0,0 +1,107 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+
+from datetime import datetime
+#
+import sys
+import struct
+from ctypes import *
+import re
+
+# Definitions for paths
+#######################
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+# Adding the utility python scripts to the python PATH
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div + 'common_utils'
+
+    
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+
+from global_defines import *
+from cert_basic_utilities import *
+
+BYTES_WITHIN_WORD = 4
+
+CC_X509_CERT_TYPE_KEY = 1
+CC_X509_CERT_TYPE_CONTENT = 2
+CC_X509_CERT_TYPE_ENABLER_DBG = 3
+CC_X509_CERT_TYPE_DEVELOPER_DBG = 4
+
+# Parse given test configuration file and return test attributes as dictionary
+def x509_cert_config_file_parser (section_name, config, local_dict, log_file):
+
+    if config.has_option(section_name, 'issuer-name'):
+        local_dict['issuer_name'] = str.encode(config.get(section_name, 'issuer-name'))
+        log_sync(log_file, "issuer_name: " + str(local_dict['issuer_name']) + "\n")
+    else:
+        local_dict['issuer_name'] = ""
+
+    if config.has_option(section_name, 'subject-name'):
+        local_dict['subject_name'] = str.encode(config.get(section_name, 'subject-name'))
+        log_sync(log_file, "subject_name: " + str(local_dict['subject_name']) + "\n")
+    else:
+        local_dict['subject_name'] = ""
+
+    if config.has_option(section_name, 'not-before'):
+        local_dict['not_before'] = int(eval(config.get(section_name, 'not-before')))
+        log_sync(log_file, "not_before: " + str(local_dict['not_before']) + " =" + config.get(section_name, 'not-before') + "\n")
+    else:
+        local_dict['not_before'] = int(0)
+
+    if config.has_option(section_name, 'not-after'):
+        local_dict['not_after'] = int(eval(config.get(section_name, 'not-after')))
+        log_sync(log_file, "not_after: " + str(local_dict['not_after']) + " =" + config.get(section_name, 'not-after') + "\n")
+    else:
+        local_dict['not_after'] = int(0)
+
+    if config.has_option(section_name, 'serial-num'):
+        local_dict['serial_num'] = int(eval(config.get(section_name, 'serial-num')))
+        log_sync(log_file, "serial-num: " + str(local_dict['serial_num']) + " =" + config.get(section_name, 'serial-num') + "\n")
+    else:
+        local_dict['serial_num'] = int(0)
+
+    return local_dict
+
+
+# Parse bianry file into byte buffer
+def parse_bin_file(file_name):
+    buff = ""
+    buff_len = 0
+    if file_name != "":
+        try:            
+            # Get the image buffer from the file.
+            fob = open(file_name, "rb")
+            fileData = fob.read()
+            fob.close()
+
+            # convert read data to list, and get its size
+            buff_len = len(fileData)
+            #print "buff_len for " + file_name + " is " + str(buff_len) + "\n"
+
+            IntArrayParam = c_ubyte * buff_len
+            buff = IntArrayParam()
+            i = 0
+            for obj in fileData:
+                buff[i] = obj
+                i = i+1
+
+        except IOError as Error1:
+            (errno, strerror) = Error1.args
+            print("Error in opening file - %s" %FileName)
+            sys.exit()
+
+    return buff, buff_len
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/Makefile
new file mode 100644
index 0000000..328074e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/Makefile
@@ -0,0 +1,49 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for managing build and installation
+
+# shared library to build
+UTIL_ROOT = $(shell pwd)
+UTILS_DIR_ROOT = $(UTIL_ROOT)/../..
+HOST_DIR_ROOT = $(UTIL_ROOT)/../host
+UTILS_LIB_PATH = ./lib
+UTILS_LIB_NAME = lib_cmpuutil_crypto.so
+UTILS_SCRIPTS_DIRNAME = $(UTIL_ROOT)
+
+
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)), $(1))
+
+INSTALL_LIST = install_lib install_scripts
+
+all:   $(INSTALL_LIST)
+
+
+
+install_lib: build_lib $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/lib)
+	@echo Installing produtil_crypto library
+	@cp $(UTILS_LIB_PATH)/$(UTILS_LIB_NAME) $(UTILS_DIR_ROOT)/lib
+
+build_lib:
+	@echo build_lib for cmpu_asset_pkg_util.py.
+	@make -C $(UTILS_LIB_PATH)
+
+install_scripts: $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin)  $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin/example)
+	@echo Installing scripts for cmpu_asset_pkg_util.py.
+	@cp $(UTIL_ROOT)/*.py $(UTILS_DIR_ROOT)/bin
+	@cp $(UTIL_ROOT)/examples/*.cfg $(UTILS_DIR_ROOT)/bin/example
+
+$(UTILS_DIR_ROOT)/%:
+	@echo Creating directory  prod package
+	@mkdir $@
+
+
+clean:
+	@make -C $(UTILS_LIB_PATH) clean
+
+.PHONY: install_lib install_sd_scripts clean
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/cmpu_asset_pkg_util.py b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/cmpu_asset_pkg_util.py
new file mode 100755
index 0000000..42ee8b3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/cmpu_asset_pkg_util.py
@@ -0,0 +1,166 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# This utility builds production asset  package:
+# the package format is:
+#                       token, version, asset length, user data (20 bytes)
+#                       nonce(12 bytes)
+#                       encrypted asset (up to 512 bytes - multiple of 16 bytes)
+#                       aset tag (16 bytes)
+
+
+# This file contains the general functions that are used in both certificates
+
+ASSET_TYPE_ENC = 1
+ASSET_TYPE_PROV = 2
+
+ASSET_SIZE = 16
+USER_DATA_SIZE = 16
+KRTL_SIZE = 16
+
+import sys
+# Definitions for paths
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+import configparser
+from cmpu_util_helper import *
+import sys
+
+# Parse given test configuration file and return test attributes as dictionary
+def parse_config_file (config, log_file):
+    local_dict = {}
+    section_name = "CMPU-ASSET-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None
+
+    if config.get(section_name, 'asset-type') == "kpicv":
+         local_dict['asset_type'] = int(ASSET_TYPE_PROV)
+    elif config.get(section_name, 'asset-type') == "kceicv":
+          local_dict['asset_type'] = int(ASSET_TYPE_ENC)
+    else:
+        log_sync(log_file, "Illegal asset-type defined - exiting\n")
+        return None
+    log_sync(log_file,"asset-type: " + str(local_dict['asset_type']) + "\n")
+
+    local_dict['unique_data'] = config.get(section_name, 'unique-data')
+    log_sync(log_file,"unique-data: " + str(local_dict['unique_data']) + "\n")
+     
+    local_dict['key_filename'] = config.get(section_name, 'key-filename')
+    log_sync(log_file,"key-filename: " + str(local_dict['key_filename']) + "\n")
+     
+    if config.has_option(section_name, 'keypwd-filename'): #used for testing
+            local_dict['keypwd_filename'] = str.encode(config.get(section_name, 'keypwd-filename'))
+            log_sync(log_file,"keypwd-filename: " + str(local_dict['keypwd_filename']) + "\n")
+    else:
+        local_dict['keypwd_filename'] = ''
+
+    local_dict['asset_filename'] = config.get(section_name, 'asset-filename')
+    log_sync(log_file,"asset-filename: " + str(local_dict['asset_filename']) + "\n")
+
+    local_dict['pkg_filename'] = str.encode(config.get(section_name, 'pkg-filename'))
+    log_sync(log_file,"pkg-filename: " + str(local_dict['pkg_filename']) + "\n")
+
+    return local_dict
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "asset_prov.log"
+    return config_fname, log_fname
+
+
+# close files and exit script
+def exit_main_func(log_file, config_file, rc):
+    log_file.close()
+    config_file.close()
+    sys.exit(rc)
+
+
+def main():
+
+    config_fname, log_fname = parse_shell_arguments()
+    log_file = create_log_file(log_fname)
+    print_and_log(log_file, str(datetime.now()) + ": Asset provisioning Utility started (Logging to " + log_fname + ")\n")
+
+    DLLHandle = LoadDLLGetHandle()
+    
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        log_file.close()
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.read(config_fname)
+    data_dict = {}
+
+    data_dict = parse_config_file(config, log_file)
+
+    if (data_dict != None):
+        # Get assets and encrypted key from files
+        asset_size, assetStr = GetDataFromBinFile(log_file, data_dict['asset_filename'])
+        if (asset_size != ASSET_SIZE) :
+                print_and_log(log_file, "invalid asset size \n")
+                exit_main_func(log_file, config_file, 1)
+
+        userData_size, userData_Str = GetDataFromBinFile(log_file, data_dict['unique_data'])
+        if (userData_size < USER_DATA_SIZE) :
+                print_and_log(log_file, "invalid key size \n")
+                exit_main_func(log_file, config_file, 1)
+
+        key_size, keyStr = GetDataFromBinFile(log_file, data_dict['key_filename'])
+        if (key_size != KRTL_SIZE*2) :
+                print_and_log(log_file, "invalid key size  \n")
+                exit_main_func(log_file, config_file, 1)
+
+        print_and_log(log_file, "**** Generate production Asset package ****\n")        
+
+        result = DLLHandle.build_asset_pkg(keyStr, key_size, data_dict['keypwd_filename'],
+                         data_dict['asset_type'],
+                         userData_Str, int(USER_DATA_SIZE),
+                         assetStr, int(ASSET_SIZE),
+                         data_dict['pkg_filename'])
+        if result != 0:
+            raise NameError
+       
+        print_and_log(log_file, "**** Generate asset package completed successfully ****\n")
+        exit_main_func(log_file, config_file, 0)
+
+    else:
+        print_and_log(log_file, "**** Invalid config file ****\n")
+        exit_main_func(log_file, config_file, 1)
+
+    FreeDLLGetHandle(DLLHandle)
+
+#############################
+if __name__ == "__main__":
+    main()
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/cmpu_util_helper.py b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/cmpu_util_helper.py
new file mode 100755
index 0000000..68936b4
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/cmpu_util_helper.py
@@ -0,0 +1,98 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+from datetime import datetime
+#
+import sys
+import struct
+from ctypes import *
+
+#so name
+SBU_CRYPTO_LIB_DIR = "lib"
+SBU_CRYPTO_LIB_Name = SBU_CRYPTO_LIB_DIR + "/" + "lib_cmpuutil_crypto.so"
+SBU_OSSL_CRYPTO_LIB_Name = "libcrypto.so.1.0.0"
+SBU_OSSL_LIB_Name = "libssl.so.1.0.0"
+
+
+CURRENT_PATH = sys.path[0]
+
+
+# The function returns the path of the DLL - fixed path (relative to script path)
+def GetDLLPath(FileName):
+
+    path = str()
+    path = CURRENT_PATH
+    # split according to dir names
+    if sys.platform != "win32" :
+        path_div = "/"
+    else : #platform = win32
+        path_div = "\\"
+
+    path_new = path + path_div + ".." + path_div
+
+    path_new = path_new + FileName
+    return path_new
+# End of GetDLLPath
+
+# 
+# The function loads the crypto DLL and returns its handle
+def LoadDLLGetHandle():
+    # Load the crypto libraries
+    SBU_Crypto = cdll.LoadLibrary(GetDLLPath(SBU_CRYPTO_LIB_Name))
+    return SBU_Crypto
+# End of LoadDLLGetHandle
+
+# The function free the DLL - // not being used in Linux
+def FreeDLLGetHandle(DllHandle):
+    # free the libraries
+    cdll.FreeLibrary(DllHandle)
+    return 0
+# End of FreeDLLGetHandle
+
+
+# Create a log file handle
+def create_log_file (log_file_path):
+    
+    log_file = open(log_file_path, 'w')
+    return log_file;
+
+# Print (stdout) and output also to log file given text
+def print_and_log (log_file, text):
+    print (text)
+    log_file.write(text)
+    sys.stdout.flush()
+    log_file.flush()
+
+
+# Do synchronous print to appear immediately on the console
+def print_sync (text):
+    print (text)
+    sys.stdout.flush()
+
+
+# Do synchronous write to log file
+def log_sync (log_file, text):
+    log_file.write(text)
+    log_file.flush()
+
+
+# The GetDataFromBinFile gets the data from a binary file
+def GetDataFromBinFile(logFile, fileName):
+    binStr = str()
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(fileName, "rb")
+        binStr = FileObj.read()
+        binSize = len(binStr)
+        FileObj.close()
+
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %fileName)
+        sys.exit(1)
+    return binSize, binStr
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/examples/asset_icv_ce.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/examples/asset_icv_ce.cfg
new file mode 100644
index 0000000..74b92de
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/examples/asset_icv_ce.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for generating asset package for production phase applications - CMPU
+# [CMPU-ASSET-CFG]        Mandatory header.
+#asset-type = defines the asset type encryptin key or provisioning key <kpicv|kceicv>
+#unique-data =         File holding the user unique data, in binary format.
+#                            It is recommanded to use HBK0.
+#                            If ICV doesn't define HBK0 in the device it is recommanded to use 16 bytes random data
+#key-filename =         File holding the encrypted Krtl, in binary format.
+#keypwd-filename =      Passphrase for the key file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#asset-filename =       The asset to create the package for
+#pkg-filename =            The package file, generated by cmpu_asset_pkg_util.py.
+ [CMPU-ASSET-CFG]
+asset-type = kceicv
+unique-data =  user_data.bin
+key-filename =  rtl_enc_key.bin
+keypwd-filename = rtl_key_pwd.txt
+asset-filename = icv_enc_asset.bin
+pkg-filename = icv_enc_asset_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/examples/asset_icv_cp.cfg b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/examples/asset_icv_cp.cfg
new file mode 100644
index 0000000..1f76e43
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/examples/asset_icv_cp.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for generating asset package for production phase applications - CMPU
+# [CMPU-ASSET-CFG]        Mandatory header.
+#asset-type = defines the asset type encryptin key or provisioning key <kpicv|kceicv>
+#unique-data =         File holding the user unique data, in binary format.
+#                            It is recommanded to use HBK0
+#                            If ICV doesn't define HBK0 in the device it is recommanded to use 16 bytes random data
+#key-filename =         File holding the encrypted Krtl, in binary format.
+#keypwd-filename =      Passphrase for the key file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#asset-filename =       The asset to create the package for
+#pkg-filename =            The package file, generated by cmpu_asset_pkg_util.py.
+ [CMPU-ASSET-CFG]
+asset-type = kpicv
+unique-data =  hbk0.bin
+key-filename =  rtl_enc_key.bin
+keypwd-filename = rtl_key_pwd.txt
+asset-filename = icv_prov_asset.bin
+pkg-filename = icv_prov_asset_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/lib/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/lib/Makefile
new file mode 100644
index 0000000..b6ba2bc
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/lib/Makefile
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for building sbu_crypto library
+SH_LIB_NAME = lib_cmpuutil_crypto.so
+
+LIB_SRC_O = main.o common_crypto_asym.o  common_crypto_sym.o common_rsa_keypair_util.o common_rsa_keypair.o common_util_files.o
+
+UTILS_ROOT = $(shell pwd)/../../..
+SHARED_DIR = $(UTILS_ROOT)/../shared
+HOSTSRC_DIR = $(UTILS_ROOT)/../host/src
+UTILS_LIB_PATH = $(UTILS_ROOT)/lib
+UTILS_INC_PATH = $(SHARED_DIR)/include $(SHARED_DIR)/include/proj/$(PROJ_PRD) $(UTILS_ROOT)/include
+UTILS_INC_PATH += $(UTILS_ROOT)/src/common $(HOSTSRC_DIR)/cc3x_productionlib/common $(SHARED_DIR)/include/pal  $(SHARED_DIR)/include/pal/$(TEE_OS)
+
+CFLAGS += -fPIC $(foreach incdir,$(UTILS_INC_PATH),-I$(incdir)) -c
+
+all: $(SH_LIB_NAME)
+
+# Compile and link the sbu_crypto library with hard-coded library run path to utils/lib
+# (to assure the private version of openssl libraries are used)
+$(SH_LIB_NAME): $(LIB_SRC_O)
+	gcc -shared -o $(SH_LIB_NAME) $(LIB_SRC_O) -Wl,-rpath,$(UTILS_LIB_PATH) -lcrypto -lssl
+
+vpath %.c $(UTILS_ROOT)/src/common
+
+%.o: %.c
+	gcc $(CFLAGS) $<
+
+clean:
+	rm -f $(SH_LIB_NAME) $(LIB_SRC_O)
+
+.PHONY: clean all
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/lib/main.c b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/lib/main.c
new file mode 100644
index 0000000..273ef95
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/cmpu_asset_pkg_util/lib/main.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_util_log.h"
+#include "common_crypto_asym.h"
+#include "common_crypto_sym.h"
+#include "common_rsa_keypair_util.h"
+#include "common_util_files.h"
+#include "cc_production_asset.h"
+
+static uint8_t  isLibOpened = 0;
+
+/**
+* @brief initialize openSSL library
+*
+* @param[in] None
+* @param[out] None
+*
+*/
+/*********************************************************/
+static void InitOpenSsl(void)
+{
+    if (0 == isLibOpened) {
+          OpenSSL_add_all_algorithms();
+    }
+    isLibOpened++;
+}
+
+
+/**
+* @brief terminates and cleanup openSSL library
+*
+* @param[in]  None
+* @param[out] None
+*
+*/
+/*********************************************************/
+static void CloseOpenSsl(void)
+{
+    isLibOpened--;
+    if (0 == isLibOpened) {
+          EVP_cleanup();
+          //CYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+    }
+}
+
+
+/**
+* @brief performs CMAC key derivation for Kprov using openSSL library
+*
+* @param[in]  pKey & keySize - Kpicv key and its size
+*       lable & pContext & contextSize used to build the dataIn for derivation
+* @param[out] pOutKey - Kprov
+*
+*/
+/*********************************************************/
+static int AesCmacKeyDerivation(char *pKey, uint32_t keySize,
+                uint8_t *pLabel, uint32_t labelSize,
+                uint8_t *pContext, uint32_t contextSize,
+                char *pOutKey, uint32_t outKeySize)
+{
+        #define MAX_DATA_IN_SIZE  (PROD_KEY_TMP_LABEL_SIZE + PROD_KEY_TMP_CONTEXT_SIZE + 3)  // +3 for: iteration, key size and 0x0
+    int rc = 0;
+    int index = 0;
+    int8_t dataIn[MAX_DATA_IN_SIZE] = {0x0};
+
+        if ((pKey == NULL) ||
+            (keySize != PROD_KEY_TMP_KEY_SIZE) ||
+            (pLabel == NULL) ||
+            (labelSize > PROD_KEY_TMP_LABEL_SIZE) ||
+            (pContext == NULL) ||
+            (contextSize > PROD_KEY_TMP_CONTEXT_SIZE) ||
+            (pOutKey == NULL) ||
+            (outKeySize != PROD_KEY_TMP_KEY_SIZE)) {
+        UTIL_LOG_ERR( "Invalid inputs\n");
+        return (-1);
+        }
+
+        /* Create the input to the CMAC derivation
+           since key size is 16 bytes, we have 1 iteration for cmac  derivation*
+           the data or the derivation:
+           0x1 || label || 0x0 || context || size of derived key in bits */
+    dataIn[index++] = 0x1;
+    memcpy(&dataIn[index], pLabel, labelSize);
+    index += labelSize;
+    dataIn[index++] = 0x0;
+    memcpy(&dataIn[index], pContext, contextSize);
+    index += contextSize;
+    dataIn[index++] = outKeySize*CC_BITS_IN_BYTE; // size of the key in bits
+
+    UTIL_LOG_BYTE_BUFF("dataIn", dataIn, index);
+    UTIL_LOG_BYTE_BUFF("pKey", pKey, keySize);
+    rc = CC_CommonAesCmacEncrypt(dataIn, index,
+                     pKey, keySize, pOutKey);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCmacEncrypt(), rc %d\n", rc);
+        return (-1);
+    }
+    UTIL_LOG_BYTE_BUFF("pOutKey", pOutKey, outKeySize);
+    return rc;
+}
+
+
+/**
+* @brief Build the ICV asset package using openSSL library
+*
+* @param[in]  encKeyBuff & encKeyBuffSize & pKeyPwdFileName - the encryptes Kpicv key
+*           assetId - Asset ID, used for Kprov derivation
+*           asset & assetSize - The Asset to generate the package for
+*               pPkgFileName - OUT - the asset package binary
+*               file name
+* @param[out] None
+*
+*/
+/*********************************************************/
+int build_asset_pkg(char *encKeyBuff, uint32_t encKeyBuffSize,
+    char *pKeyPwdFileName,
+        uint32_t assetType,
+    uint8_t *pUserData, uint32_t userDataSize,
+        uint8_t *asset, uint32_t assetSize,
+    char *pPkgFileName)
+{
+    int rc = 0;
+    uint8_t keyRtl[PROD_KEY_RTL_KEY_SIZE + AES_BLOCK_SIZE] = {0};  // Adding AES_BLOCK_SIZE to avoid over-run
+    uint8_t keyTmpLabel[PROD_KEY_TMP_LABEL_SIZE] = {0};
+    uint8_t keyTmp[PROD_KEY_TMP_KEY_SIZE] = {0};
+    uint8_t keyProv[PROD_KPROV_KEY_SIZE] = {0};
+    uint8_t keyProvContext[PROD_KPROV_CONTEXT_SIZE] = {0};
+    uint8_t i = 0;
+    CCProdAssetPkg_t  assetPackage = {0};
+    uint32_t assetPkgSize = sizeof(CCProdAssetPkg_t);
+        uint8_t label[] = PROD_LABEL;
+
+    // Verify Inputs
+    UTIL_LOG_ERR( "encKeyBuffSize %d\n", encKeyBuffSize);
+    if ((encKeyBuff == NULL) ||
+        (encKeyBuffSize != (PROD_KEY_RTL_KEY_SIZE+ AES_BLOCK_SIZE)) ||
+        ((assetType != PROD_ASSET_TYPE_KCE)  && (assetType != PROD_ASSET_TYPE_KCP))||
+        (pUserData == NULL) ||
+        (userDataSize != PROD_KEY_TMP_CONTEXT_SIZE) ||
+        (asset == NULL) ||
+        (assetSize != PROD_ASSET_SIZE) ||
+        (pPkgFileName == NULL)) {
+        UTIL_LOG_ERR( "Invalid inputs\n");
+        return (-1);
+    }
+
+    InitOpenSsl();
+
+    // Build the package header
+    assetPackage.token = PROD_ASSET_PROV_TOKEN;
+    assetPackage.version = PROD_ASSET_PROV_VERSION;
+    assetPackage.assetSize = assetSize;
+        assetPackage.reserved[0] = PROD_ASSET_RESERVED1_VAL;
+        assetPackage.reserved[1] = PROD_ASSET_RESERVED2_VAL;
+        rc = CC_CommonRandBytes(PROD_ASSET_NONCE_SIZE, (uint8_t *)assetPackage.nonce);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonRandBytes() for nonce, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+
+    // Decrypt Krtl
+    rc = CC_CommonAesCbcDecrypt(pKeyPwdFileName, encKeyBuff, encKeyBuffSize, keyRtl);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCbcDecrypt() for Krtl, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+
+        memcpy(keyTmpLabel, PROD_ICV_KEY_TMP_LABEL, PROD_KEY_TMP_LABEL_SIZE);
+        if (assetType == PROD_ASSET_TYPE_KCE) {
+                memcpy(keyProvContext, PROD_ICV_ENC_CONTEXT, PROD_KPROV_CONTEXT_SIZE);
+        } else { // PROD_ASSET_TYPE_KCP
+                memcpy(keyProvContext, PROD_ICV_PROV_CONTEXT, PROD_KPROV_CONTEXT_SIZE);
+        }
+
+        // Calculate Ktmp = cmac(Krtl, 0x01 || ICV/OEM_label  || 0x0 || user context || 0x80)
+    rc = AesCmacKeyDerivation(keyRtl, PROD_KEY_RTL_KEY_SIZE,
+                keyTmpLabel,  PROD_KEY_TMP_LABEL_SIZE,
+                (uint8_t *)pUserData, PROD_KEY_TMP_CONTEXT_SIZE,
+                keyTmp, PROD_KEY_TMP_KEY_SIZE);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to AesCmacKeyDerivation() for Ktmp, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+        // Calculate Kprov= cmac(Ktmp, 0x01 || "P"  || 0x0 || asset_id || 0x80)
+    rc = AesCmacKeyDerivation(keyTmp, PROD_KEY_TMP_KEY_SIZE,
+                label,  PROD_KPROV_LABEL_SIZE,
+                keyProvContext, PROD_KPROV_CONTEXT_SIZE,
+                keyProv, PROD_KPROV_KEY_SIZE);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to AesCmacKeyDerivation() for Ktmp, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+    // Encrypt and authenticate the asset
+    rc = CC_CommonAesCcmEncrypt(keyProv,
+                (uint8_t *)assetPackage.nonce, PROD_ASSET_NONCE_SIZE,
+                (uint8_t *)&assetPackage, PROD_ASSET_ADATA_SIZE,
+                asset, assetSize,
+                (uint8_t *)assetPackage.encAsset, &assetSize,
+                                ((uint8_t *)assetPackage.encAsset)+assetSize, PROD_ASSET_TAG_SIZE);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCmacEncrypt() for Kprov, rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+
+    // Writing the asset package into bin file
+    rc = CC_CommonUtilCopyBuffToBinFile(pPkgFileName, (uint8_t *)&assetPackage, assetPkgSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonUtilCopyBuffToBinFile(), rc %d\n", rc);
+        rc = (-1);
+        goto end_func;
+    }
+    rc = 0;
+end_func:
+    CloseOpenSsl();
+    UTIL_LOG_ERR( "End rc %d\n", rc);
+    return rc;
+}
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_asym.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_asym.c
new file mode 100644
index 0000000..6bb830b
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_asym.c
@@ -0,0 +1,740 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include "common_rsa_keypair.h"
+#include "common_crypto_asym.h"
+#include "common_util_log.h"
+#include "common_util_files.h"
+#include "cc_crypto_defs.h"
+#include "cc_pka_hw_plat_defs.h"
+
+
+
+/**
+ * @brief The Sign_v15 generates RSA signature using PKCS#1 v1.5 algorithm.
+ *
+ * The function
+ * 1. Create RSA signature
+ * 2. Verify the signature correctness
+ * @param[in] pRsaPrivKey - the private key
+ * @param[in] pDataIn - the data to sign on
+ * @param[in] dataInSize - the data size
+ * @param[in] Key_ptr - passphrase string
+ * @param[out] pSignature - the RSA signature
+ *
+ */
+/*********************************************************/
+int32_t Sign_v15(RSA  *pRsaPrivKey,
+         int8_t *pDataIn,
+         int32_t  dataInSize,
+         int8_t *pSignature,
+         int8_t *Key_ptr)
+{
+    RSA *pRsaPubKey    = NULL;
+    BIO *bio           = NULL;
+    int32_t status         = -1;
+    EVP_PKEY *pKey     = NULL;
+    EVP_MD_CTX *md_ctx = NULL;
+    int32_t SignatureSize  = SB_CERT_RSA_KEY_SIZE_IN_BYTES;
+
+    if ((NULL == pRsaPrivKey) ||
+        (NULL == pDataIn) ||
+        (NULL == pSignature) ||
+        (NULL == Key_ptr)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(status);
+    }
+    /*EVP_PKEY_new() allocates an empty EVP_PKEY structure which
+    is used by OpenSSL to store private keys.*/
+    pKey = EVP_PKEY_new();
+    if (NULL == pKey) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_new\n");
+        goto rsaSign_v15_end;
+    }
+    /*set the referenced key to key*/
+    if (!EVP_PKEY_assign_RSA(pKey, pRsaPrivKey)) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_assign_RSA\n");
+        goto rsaSign_v15_end;
+    }
+
+    /* fill and sign on the HASH output */
+    md_ctx = EVP_MD_CTX_create();
+    if (NULL == md_ctx) {
+        UTIL_LOG_ERR("failed to EVP_MD_CTX_create\n");
+        goto rsaSign_v15_end;
+    }
+    /* initializes a signing context to use the default implementation of digest type.*/
+    if (!EVP_SignInit(md_ctx, EVP_sha256())) {
+        UTIL_LOG_ERR("failed to EVP_SignInit\n");
+        goto rsaSign_v15_end;
+    }
+    /*hash data into the signature */
+    if (!EVP_SignUpdate(md_ctx, pDataIn, dataInSize)) {
+        UTIL_LOG_ERR("failed to EVP_SignUpdate\n");
+        goto rsaSign_v15_end;
+    }
+    /*signs the data using the private key pkey and places the signature*/
+    if (!EVP_SignFinal(md_ctx, pSignature, &SignatureSize, pKey)) {
+        UTIL_LOG_ERR("failed to EVP_SignFinal\n");
+        goto rsaSign_v15_end;
+    }
+
+    // Create public key
+    bio = BIO_new(BIO_s_mem());
+    if (NULL == bio) {
+        UTIL_LOG_ERR("failed to BIO_new\n");
+        goto rsaSign_v15_end;
+    }
+    pRsaPubKey = RSA_new();
+    if (NULL == pRsaPubKey) {
+        UTIL_LOG_ERR("failed to RSA_new\n");
+        goto rsaSign_v15_end;
+    }
+    if (!PEM_write_bio_RSA_PUBKEY(bio, pRsaPrivKey)) {
+        UTIL_LOG_ERR("failed to PEM_write_bio_RSA_PUBKEY\n");
+        goto rsaSign_v15_end;
+    }
+
+    if (PEM_read_bio_RSA_PUBKEY(bio,&pRsaPubKey,NULL,Key_ptr) == NULL) {
+        UTIL_LOG_ERR("failed to PEM_read_bio_RSA_PUBKEY\n");
+        goto rsaSign_v15_end;
+    }
+
+    if (!EVP_PKEY_assign_RSA(pKey, pRsaPubKey)) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_assign_RSA\n");
+        goto rsaSign_v15_end;
+    }
+    /* initializes verification context ctx to use the default implementation of digest type*/
+    if (!EVP_VerifyInit(md_ctx, EVP_sha256())) {
+        UTIL_LOG_ERR("failed to EVP_VerifyInit\n");
+        goto rsaSign_v15_end;
+    }
+    /*hashes bytes of data into the verification context*/
+    if (!EVP_VerifyUpdate(md_ctx, pDataIn, dataInSize)) {
+        UTIL_LOG_ERR("failed to EVP_VerifyUpdate\n");
+        goto rsaSign_v15_end;
+    }
+    /*verifies the data in, using the public.*/
+    if (!EVP_VerifyFinal(md_ctx, pSignature, SignatureSize, pKey)) {
+        UTIL_LOG_ERR("failed to EVP_VerifyFinal\n");
+        goto rsaSign_v15_end;
+    }
+
+    status = 0;
+
+    rsaSign_v15_end:
+    if (pRsaPubKey != NULL) {
+        RSA_free(pRsaPubKey);
+    }
+    if (bio != NULL) {
+        BIO_free_all(bio);
+    }
+    if (pKey != NULL) {
+        EVP_PKEY_free(pKey);
+    }
+    if (md_ctx != NULL) {
+        EVP_MD_CTX_destroy(md_ctx);
+    }
+    return(status);
+}
+
+/**
+ * @brief The Sign_v21 generates RSA signature using PKCS#1 v2.1 algorithm.
+ *
+ * The function
+ * 1. Create RSA signature
+ * 2. Verify the signature correctness
+ * @param[in] pRsaPrivKey - the private key
+ * @param[in] pDataIn - the data to sign on
+ * @param[in] dataInSize - the data size
+ * @param[out] pSignature - the RSA signature
+ *
+ */
+/*********************************************************/
+int32_t Sign_v21(RSA   *pRsaPrivKey,
+         int8_t  *pDataIn,
+         uint32_t   dataInSize,
+         int8_t  *pSignature)
+{
+    uint8_t pDigest[HASH_SHA256_DIGEST_SIZE_IN_BYTES] = {0};
+    uint32_t uDigestLen = HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+    EVP_MD_CTX md_ctx;
+    uint8_t EM[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
+    uint8_t pDecrypted[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
+    int32_t status = -1;
+
+    if ((NULL == pRsaPrivKey) ||
+        (NULL == pDataIn) ||
+        (NULL == pSignature)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(status);
+    }
+    /* hash the message */
+    EVP_MD_CTX_init(&md_ctx);
+    EVP_DigestInit(&md_ctx, EVP_sha256());
+    EVP_DigestUpdate(&md_ctx, (const void*) pDataIn, dataInSize);
+    EVP_DigestFinal(&md_ctx, pDigest, &uDigestLen);
+    EVP_MD_CTX_cleanup(&md_ctx);
+
+    /* compute the PSS padded data */
+    if (!RSA_padding_add_PKCS1_PSS(pRsaPrivKey, EM, pDigest, EVP_sha256(), RSA_SALT_LEN)) {
+        return(status);
+    }
+
+    /* perform digital signature */
+    if (RSA_private_encrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, EM, pSignature, pRsaPrivKey, RSA_NO_PADDING) == -1) {
+        return(status);
+    }
+
+    /* verify the data */
+    if (RSA_public_decrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, pSignature, pDecrypted, pRsaPrivKey, RSA_NO_PADDING) == -1) {
+        return(status);
+    }
+
+    if (RSA_verify_PKCS1_PSS(pRsaPrivKey, pDigest, EVP_sha256(), pDecrypted, RSA_SALT_LEN) != 1) {
+        return(status);
+    }
+
+
+    status = 0;
+
+    return(status);
+}
+
+/**
+ * @brief The Sign_v21 generates RSA signature using PKCS#1 v2.1 algorithm.
+ *
+ * The function
+ * 1. Verify RSA signature
+ * 2. Verify the signature correctness
+ * @param[in] pRsaPrivKey - the private key
+ * @param[in] pDataIn - the data to sign on
+ * @param[in] dataInSize - the data size
+ * @param[out] pSignature - the RSA signature
+ *
+ */
+/*********************************************************/
+int32_t Verify_v21(RSA *pRsaPubKey,
+           int8_t  *pDataIn,
+           int32_t   dataInSize,
+           int8_t  *pSignature)
+{
+    uint8_t pDigest[HASH_SHA256_DIGEST_SIZE_IN_BYTES] = {0};
+    uint32_t uDigestLen = HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+    EVP_MD_CTX md_ctx;
+    uint8_t EM[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
+    uint8_t pDecrypted[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
+    int32_t status = -1;
+
+    if ((NULL == pRsaPubKey) ||
+        (NULL == pDataIn) ||
+        (NULL == pSignature)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(status);
+    }
+
+    /* hash the message */
+    EVP_MD_CTX_init(&md_ctx);
+    EVP_DigestInit(&md_ctx, EVP_sha256());
+    EVP_DigestUpdate(&md_ctx, (const void*) pDataIn, dataInSize);
+    EVP_DigestFinal(&md_ctx, pDigest, &uDigestLen);
+    EVP_MD_CTX_cleanup(&md_ctx);
+
+    /* decrypt the signature to get the hash */
+    if (RSA_public_decrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, pSignature, pDecrypted, pRsaPubKey, RSA_NO_PADDING) == -1) {
+        return(status);
+    }
+
+    if (RSA_verify_PKCS1_PSS(pRsaPubKey,  pDigest, EVP_sha256(), pDecrypted,RSA_SALT_LEN) != 1) {
+        return(status);
+    }
+
+    UTIL_LOG_INFO("\nVerify_v21: OK\n");
+    status = 0;
+
+    return(status);
+}
+
+/**
+ * @brief Verifies RSA signature.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] pDataIn - the data to sign on
+ * @param[in] dataInSize - the data size
+ * @param[in] pPrivKeyFileName - the private key file
+ * @param[in] pPrivKeyPwd - the passphrase string
+ * @param[out] pSignature - the RSA signature
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaVerify(int32_t  pkcsVersion,
+             int8_t *pPubKey,
+             int8_t *pDataIn,
+             int32_t  dataInSize,
+             int8_t *pSignature)
+{
+    RSA  *pRsaPubKey = NULL;
+    int32_t status = -1;
+    uint8_t pubKeyExp[] = {0x01, 0x00, 0x01};
+
+    if ((NULL == pPubKey) ||
+        (NULL == pDataIn) ||
+        (NULL == pSignature)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(status);
+    }
+
+    pRsaPubKey = RSA_new();
+    if (NULL == pRsaPubKey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto END;
+    }
+
+    /* set the modulus  and exponent from int8_t * into RSA key as BIGNUM */
+    pRsaPubKey->n = BN_bin2bn(pPubKey, SB_CERT_RSA_KEY_SIZE_IN_BYTES, NULL);
+    if (NULL == pRsaPubKey->n) {
+        UTIL_LOG_ERR("Failed BN_bin2bn for n\n");
+        goto END;
+    }
+    pRsaPubKey->e = BN_bin2bn(pubKeyExp, sizeof(pubKeyExp),NULL);
+    if (NULL == pRsaPubKey->e) {
+        UTIL_LOG_ERR("Failed BN_bin2bn for e\n");
+        goto END;
+    }
+
+    if (RSA_USE_PKCS_21_VERSION == pkcsVersion) {
+        status = Verify_v21(pRsaPubKey, pDataIn, dataInSize, pSignature);
+    } else {
+        UTIL_LOG_ERR("\nCC_CommonRsaVerify: Invalid pkcs version\n");
+        goto END;
+    }
+
+    END:
+    if (pRsaPubKey != NULL) {
+        RSA_free(pRsaPubKey);
+    }
+    return status;
+}
+
+
+/**
+ * @brief Generates RSA signature and returns it.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] pDataIn - the data to sign on
+ * @param[in] dataInSize - the data size
+ * @param[in] pPrivKeyFileName - the private key file
+ * @param[in] pPrivKeyPwd - the passphrase string
+ * @param[out] pSignature - the RSA signature
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaSign(int32_t pkcsVersion,
+               int8_t *pDataIn,
+               uint32_t dataInSize,
+               int8_t *pPrivKeyFileName,
+               int8_t *pPrivKeyPwd,
+               int8_t *pSignature)
+{
+    RSA  *pRsaPrivKey = NULL;
+    uint8_t *pwd = NULL;
+    int32_t status = -1;
+
+    if ((NULL == pDataIn) ||
+        (NULL == pPrivKeyFileName) ||
+        (NULL == pSignature)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(status);
+    }
+
+    /* parse the passphrase for a given file */
+    if ((NULL != pPrivKeyPwd)) {
+        if (CC_CommonGetPassphrase(pPrivKeyPwd, &pwd)) {
+        UTIL_LOG_ERR("Failed to retrieve pwd\n");
+        goto END;
+        }
+    }
+
+    pRsaPrivKey = RSA_new();
+
+    if (NULL == pRsaPrivKey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto END;
+    }
+    if (CC_CommonGetKeyPair (&pRsaPrivKey, pPrivKeyFileName, pwd) < 0) {
+        UTIL_LOG_ERR("CC_CommonGetKeyPair Cannot read RSA private key\n");
+        goto END;
+    }
+
+    if (RSA_USE_PKCS_21_VERSION == pkcsVersion) {
+        status = Sign_v21(pRsaPrivKey, pDataIn, dataInSize, pSignature);
+    } else if (RSA_USE_PKCS_15_VERSION == pkcsVersion) {
+        status = Sign_v15(pRsaPrivKey, pDataIn, dataInSize, pSignature, pwd);
+    } else {
+        UTIL_LOG_ERR("\nCC_CommonRsaSign: Invalid pkcs version\n");
+        goto END;
+    }
+
+    END:
+    if (pRsaPrivKey != NULL) {
+        RSA_free(pRsaPrivKey);
+    }
+    if (pwd != NULL) {
+        free(pwd);
+    }
+    return status;
+}
+
+
+
+/**
+ * @brief Encrypts data using RSA.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] pPrivKeyFileName - the private key file
+ * @param[in] pPrivKeyPwd - the passphrase string
+ * @param[in] pDataIn - the data to encrypt
+ * @param[in] dataInSize - the data size
+ * @param[out] pEncData - the encrypted data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaEncrypt(int32_t pkcsVersion,
+              int8_t *pPubKey,
+              int8_t *pDataIn,
+              int32_t  dataInSize,
+              int8_t *pEncData)
+{
+
+    RSA  *pRsaPubKey = NULL;
+    int32_t status = -1;
+    uint8_t pubKeyExp[] = {0x01, 0x00, 0x01};
+
+    if ((NULL == pPubKey) ||
+        (NULL == pDataIn) ||
+        (NULL == pEncData)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(status);
+    }
+    /* get RSA public key from provided buffer */
+    pRsaPubKey = RSA_new();
+    if (NULL == pRsaPubKey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto rsaEncryptEnd;
+    }
+
+    /* set the modulus  and exponent from int8_t * into RSA key as BIGNUM */
+    pRsaPubKey->n = BN_bin2bn(pPubKey, SB_CERT_RSA_KEY_SIZE_IN_BYTES, NULL);
+    if (NULL == pRsaPubKey->n) {
+        UTIL_LOG_ERR("Failed BN_bin2bn for n\n");
+        goto rsaEncryptEnd;
+    }
+    pRsaPubKey->e = BN_bin2bn(pubKeyExp, sizeof(pubKeyExp),NULL);
+    if (NULL == pRsaPubKey->e) {
+        UTIL_LOG_ERR("Failed BN_bin2bn for e\n");
+        goto rsaEncryptEnd;
+    }
+
+    /* now encrypt the data */
+    status = RSA_public_encrypt(dataInSize, pDataIn, pEncData, pRsaPubKey, RSA_PKCS1_OAEP_PADDING); /* returns the size of the encrypted data, On error, -1 is returned*/
+    if (status != SB_CERT_RSA_KEY_SIZE_IN_BYTES) { /* expected encryped size is RSA modulus sieze */
+        UTIL_LOG_ERR("Failed RSA_public_encrypt\n");
+        status = -1;
+        goto rsaEncryptEnd;
+    }
+    status = 0;
+
+    rsaEncryptEnd:
+    if (pRsaPubKey != NULL) {
+        RSA_free(pRsaPubKey);
+    }
+    return status;
+}
+
+
+/**
+ * @brief Decrypts data using RSA.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] pPrivKeyFileName - the private key file
+ * @param[in] pPrivKeyPwd - the passphrase string
+ * @param[in] pEnDataIn - the data to decrypt
+ * @param[in] enDataInSize - the encrypted data size
+ * @param[out] pData - the decrypted data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaDecrypt(int32_t pkcsVersion,
+              int8_t *pPrivKeyFileName,
+              int8_t *pPrivKeyPwd,
+              int8_t *pEnDataIn,
+              int32_t  enDataInSize,
+              int8_t *pData)
+{
+    RSA  *pRsaPrivKey = NULL;
+    uint8_t *pwd = NULL;
+    int32_t status = -1;
+
+    if ((NULL == pPrivKeyFileName) ||
+        (NULL == pEnDataIn) ||
+        (NULL == pData)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(status);
+    }
+
+    /* parse the passphrase for a given file */
+    if ((NULL != pPrivKeyPwd)) {
+        if (CC_CommonGetPassphrase(pPrivKeyPwd, &pwd)) {
+        UTIL_LOG_ERR("Failed to retrieve pwd\n");
+        goto rsaDecryptEnd;
+        }
+    }
+
+    /* build RSA key from pem private key file */
+    pRsaPrivKey = RSA_new();
+    if (NULL == pRsaPrivKey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto rsaDecryptEnd;
+    }
+    if (CC_CommonGetKeyPair (&pRsaPrivKey, pPrivKeyFileName, pwd) < 0) {
+        UTIL_LOG_ERR("Cannot read RSA key pair\n");
+        goto rsaDecryptEnd;
+    }
+
+    /* now decrypt the data */
+    status = RSA_private_decrypt(enDataInSize, pEnDataIn, pData, pRsaPrivKey, RSA_PKCS1_OAEP_PADDING);
+    if (status != (-1)) {  /* RSA_private_decrypt returns the size of the recovered plaintext. On error, -1 is returned */
+        status = 0;
+    }
+
+    rsaDecryptEnd:
+    if (pRsaPrivKey != NULL) {
+        RSA_free(pRsaPrivKey);
+    }
+    if (pwd != NULL) {
+        free(pwd);
+    }
+    return status;
+}
+
+
+
+
+
+/**
+* @brief Calculates the H it returns it as binary string
+*
+* @param[in] N_ptr - public key N, represented as array of ascii's (0xbc is translated
+*                    to 0x62 0x63)
+* @param[out] H_ptr - The H result. H size is N_SIZE_IN_BYTES*2 + 1
+*
+*/
+/*********************************************************/
+int32_t CC_CommonRsaCalculateH(const int8_t *N_ptr, int8_t *H_ptr)
+{
+    int8_t *H_res = NULL, *N_Temp = NULL, *H_resTemp = NULL;
+    int32_t len, i;
+    int32_t status = -1;
+    uint32_t s = SB_CERT_RSA_KEY_SIZE_IN_BITS + 2;
+
+    BN_CTX *bn_ctx = BN_CTX_new();
+
+    BIGNUM *bn_two   = BN_new();
+    BIGNUM *bn_twos  = BN_new();
+    BIGNUM *bn_n     = BN_new();
+    BIGNUM *bn_h     = BN_new();
+
+    if ((NULL == N_ptr) || ( NULL == H_ptr)) {
+        UTIL_LOG_ERR("illegal input\n");
+        goto calcH_end;
+    }
+
+    /* Copy the N to temporary N, allocate temporary N in N size + 2 */
+    N_Temp= (int8_t *)malloc ((SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2) * sizeof (int8_t));
+    if (NULL == N_Temp) {
+        UTIL_LOG_ERR("malloc N_Temp failed\n");
+        goto calcH_end;
+    }
+
+    /* set the temporary N to 0 */
+    memset (N_Temp, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2));
+
+    /* Copy the N to temp N */
+    memcpy (N_Temp, N_ptr, SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2);
+
+    /* Allocate the output buffer */
+    H_res = (int8_t *)malloc ((SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2) * sizeof (int8_t));
+    if (NULL == H_res) {
+        UTIL_LOG_ERR("malloc H_res failed\n");
+        goto calcH_end;
+    }
+
+    BN_set_word (bn_two, 2);
+    BN_set_word (bn_twos, 2 * s);
+
+    if (!BN_hex2bn(&bn_n, N_Temp)) {
+        UTIL_LOG_ERR("BN_hex2bn failed.");
+        goto calcH_end;
+    }
+
+    if (!BN_mod_exp(bn_h, bn_two, bn_twos, bn_n, bn_ctx)) {
+        UTIL_LOG_ERR("BN_mod_exp failed\n");
+        goto calcH_end;
+    }
+
+    H_resTemp = BN_bn2hex(bn_h);
+    if (H_resTemp == NULL) {
+        UTIL_LOG_ERR("BN_bn2hex failed\n");
+        goto calcH_end;
+    }
+
+    if (H_resTemp[0] == '-'){ // in case the output is negative
+        UTIL_LOG_ERR("BN_bn2hex returned negative value\n");
+        goto calcH_end;
+    }
+    len = (int32_t)strlen (H_resTemp);
+    memcpy(H_res, H_resTemp, len);
+
+    if (len < SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2) {
+        memmove (H_res + (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 - len), H_res, len + 1);
+        for (i = 0; i < (int32_t)(SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 - len); i++) {
+            H_res[i] = '0';
+        }
+    }
+
+    /* Set the output with 0 and than copy the result */
+    memset (H_ptr, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2)); //VERIFY THAT USER SENDS THE SAME SIZE
+    memcpy ((int8_t *)H_ptr, (int8_t *)H_res, SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2);
+
+    status = 0;
+
+    calcH_end:
+    if (N_Temp != NULL) {
+        free(N_Temp);
+    }
+    if (H_res != NULL) {
+        free(H_res);
+    }
+    if (bn_two != NULL) {
+        BN_free(bn_two);
+    }
+    if (bn_twos != NULL) {
+        BN_free(bn_twos);
+    }
+    if (bn_n != NULL) {
+        BN_free(bn_n);
+    }
+    if (bn_h != NULL) {
+        BN_free(bn_h);
+    }
+    if (bn_ctx != NULL) {
+        BN_CTX_free(bn_ctx);
+    }
+    if (H_resTemp != NULL) {
+        OPENSSL_free(H_resTemp);
+    }
+    return(status);
+}
+
+
+/**
+* @brief Reads RSA key from the file using passphrase and returns its decrypted value.
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] Key_ptr - passphrase
+*/
+/*********************************************************/
+int32_t CC_CommonRsaLoadKey(int8_t *PemEncryptedFileName_ptr, int8_t *Key_ptr, int8_t *PemDecryted)
+{
+    RSA *rsa_pkey = NULL;
+    int8_t buffer [256];
+    BIO *out=NULL;
+    int32_t status = -1;
+
+    *PemDecryted = '\0';
+    if (CC_CommonGetKeyPair (&rsa_pkey, PemEncryptedFileName_ptr, Key_ptr) < 0) {
+        UTIL_LOG_ERR ("failed to CC_CommonGetKeyPair\n");
+        goto rsaLoadKey_end;
+    }
+
+    out = BIO_new (BIO_s_mem());
+    if (PEM_write_bio_RSAPrivateKey (out, rsa_pkey, NULL, NULL, 0, 0, NULL) <= 0) {
+        UTIL_LOG_ERR ("failed to PEM_write_bio_RSAPrivateKey\n");
+        goto rsaLoadKey_end;
+    }
+
+    while (BIO_gets (out, buffer, sizeof(buffer)) > 0) {
+        if (strlen (PemDecryted) + strlen (buffer) + 2 > RSA_PRIVATE_KEY_SIZE) {
+            UTIL_LOG_ERR ("Internal error: The output buffer is too few\n");
+            break;
+        }
+        strncat (PemDecryted, buffer, strlen (buffer));
+    }
+    status = 0;
+
+    rsaLoadKey_end:
+    if (rsa_pkey != NULL) {
+        RSA_free (rsa_pkey);
+    }
+    if (out != NULL) {
+        BIO_free_all(out);
+    }
+    return status;
+}
+
+/**
+* @brief Generates random byte buffer
+*
+* @param[in] numBytes - nuber of bytes to random
+* @param[out] buf - buffer
+*/
+/*********************************************************/
+int32_t CC_CommonRandBytes(int32_t numBytes, int8_t *buf)
+{
+    int32_t result = -1;
+
+    if (numBytes > 0) {
+        result = RAND_bytes (buf, numBytes);
+        if (result <= 0) {
+            UTIL_LOG_ERR("\nCC_CommonRandBytes - Internal error: Function RAND_bytes failed\n");
+            return 1;
+        }
+        return 0;
+    }
+    return result;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_asym.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_asym.h
new file mode 100644
index 0000000..193c374
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_asym.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _COMMON_CRYPTO_ASYM_H
+#define _COMMON_CRYPTO_ASYM_H
+
+
+#include <stdint.h>
+
+#define RSA_USE_PKCS_21_VERSION  0x01
+#define RSA_USE_PKCS_15_VERSION  0x02
+
+#define RSA_SALT_LEN             32
+/**
+ * @brief Verifies RSA signature.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] pDataIn - the data to sign on
+ * @param[in] dataInSize - the data size
+ * @param[in] pPemEncryptedFileName - the private key file
+ * @param[in] pKeyPwd - the passphrase string
+ * @param[out] pSignature - the RSA signature
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaVerify(int32_t  pkcsVersion,
+             int8_t *pPubKey,
+             int8_t *pDataIn,
+             int32_t  dataInSize,
+             int8_t *pSignature);
+
+
+/**
+ * @brief The CC_CommonRsaSign generates RSA signature and returns it.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] DataIn_ptr - the data to sign on
+ * @param[in] DataInSize - the data size
+ * @param[in] PemEncryptedFileName_ptr - the private key file
+ * @param[in] Key_ptr - the passphrase string
+ * @param[out] Signature_ptr - the RSA signature
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaSign(int32_t pkcsVersion,
+               int8_t *DataIn_ptr,
+               uint32_t  DataInSize,
+               int8_t *PemEncryptedFileName_ptr,
+               int8_t *Key_ptr,
+               int8_t *Signature_ptr);
+
+
+
+/**
+ * @brief Encrypts data using RSA.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] pPemEncryptedFileName - the private key file
+ * @param[in] pKeyPwd - the passphrase string
+ * @param[in] pDataIn - the data to encrypt
+ * @param[in] dataInSize - the data size
+ * @param[out] pEncData - the encrypted data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaEncrypt(int32_t pkcsVersion,
+              int8_t *pPubKey,
+              int8_t *pDataIn,
+              int32_t  dataInSize,
+              int8_t *pEncData);
+
+
+/**
+ * @brief Decrypts data using RSA.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] pPemEncryptedFileName - the private key file
+ * @param[in] pKeyPwd - the passphrase string
+ * @param[in] pEnDataIn - the data to decrypt
+ * @param[in] enDataInSize - the encrypted data size
+ * @param[out] pData - the decrypted data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonRsaDecrypt(int32_t pkcsVersion,
+              int8_t *pPemEncryptedFileName,
+              int8_t *pKeyPwd,
+              int8_t *pEnDataIn,
+              int32_t  enDataInSize,
+              int8_t *pData);
+
+
+/**
+* @brief The function CC_CommonRsaCalculateH calculates the H it returns it as binary string
+*
+* @param[in] N_ptr - public key N, represented as array of ascii's (0xbc is translated
+*                    to 0x62 0x63)
+* @param[out] H_ptr - The H result. H size is N_SIZE_IN_BYTES*2 + 1
+*
+*/
+/*********************************************************/
+int32_t CC_CommonRsaCalculateH(const int8_t *N_ptr, int8_t *H_ptr);
+
+
+
+
+/**
+* @brief The CC_CommonRsaLoadKey reads RSA key from the file using passphrase
+*        and returns its decrypted value.
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] Key_ptr - passphrase
+*/
+/*********************************************************/
+int32_t CC_CommonRsaLoadKey(int8_t *PemEncryptedFileName_ptr, int8_t *Key_ptr, int8_t *PemDecryted);
+
+
+/**
+* @brief The CC_CommonRandBytes reads RSA key from the file using passphrase
+*        and returns its decrypted value.
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] Key_ptr - passphrase
+*/
+/*********************************************************/
+int32_t CC_CommonRandBytes(int32_t numBytes, int8_t *buf);
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_encode.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_encode.c
new file mode 100644
index 0000000..4360774
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_encode.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <openssl/evp.h>
+#include <openssl/bio.h>
+#include "common_crypto_encode.h"
+#include "common_util_log.h"
+
+
+/* header and footer of the PEM */
+#define CC_UTIL_COMMON_PEM_HEADER       "-----BEGIN CERTIFICATE-----"
+#define CC_UTIL_COMMON_PEM_FOOTER       "-----END CERTIFICATE-----"
+
+
+#define IS_BASE64_ENCODE_VAL(val) \
+        ((((val >= '0') && (val <= '9')) || \
+         ((val >= 'A') && (val <= 'Z')) || \
+         ((val >= 'a') && (val <= 'z')) || \
+         (val == '+') || (val == '/'))?1:0)
+
+/**
+* @brief Encodes data into base64 format
+*
+* @param[in] pBuff             - the buffer to encode
+* @param[in] buffLen           - input buffer length
+* @param[out] pEncBuff         - encoded buffer
+* @param[in/out] pEncBuffLen   - encoded buffer length
+*/
+/*********************************************************/
+int32_t CC_CommonBase64Encode(uint8_t *pBuff,
+                uint32_t  buffLen,
+                uint8_t *pEncBuff,
+                uint32_t *pEecBuffLen)
+{
+    BIO *bio = NULL;
+    BIO *b64 = NULL;;
+    size_t size;
+    FILE *stream = NULL;
+    int32_t actualWritten = 0;
+    int32_t rc = 0;
+
+    if ((NULL == pBuff) ||
+        (NULL == pEncBuff) ||
+        (NULL == pEecBuffLen) ||
+        (0 == buffLen)) {
+        UTIL_LOG_ERR("ilegal inputs\n");
+        return 1;
+    }
+    if (*pEecBuffLen < ((((buffLen*4)+2)/3)+1)) {
+        UTIL_LOG_ERR("ilegal outBuffLen %d \n", *pEecBuffLen);
+        return 1;
+    }
+
+    memset(pEncBuff, 0, *pEecBuffLen);
+
+    stream = fmemopen(pEncBuff, *pEecBuffLen, "w");
+    if (NULL == stream) {
+        UTIL_LOG_ERR("failed to open mem\n");
+        return 1;
+    }
+    b64 = BIO_new(BIO_f_base64());
+    if (NULL == b64) {
+        UTIL_LOG_ERR("failed to BIO_new\n");
+        rc = 1;
+        goto End_Base64Encode;
+    }
+    bio = BIO_new_fp(stream, BIO_NOCLOSE);
+    if (NULL == bio) {
+        UTIL_LOG_ERR("failed to BIO_new_fp\n");
+        rc = 1;
+        goto End_Base64Encode;
+    }
+    bio = BIO_push(b64, bio);
+    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
+    actualWritten = BIO_write(bio, pBuff, buffLen);
+    BIO_flush(bio);
+    if (actualWritten != buffLen) {
+        UTIL_LOG_ERR("failed to BIO_write buffLen %d = actualWritten %d\n", buffLen, actualWritten);
+        rc = 1;
+        goto End_Base64Encode;
+    }
+    rc = 0;
+
+    End_Base64Encode:
+    if (bio != NULL) { /* clears bio and b64, b64 mustn't clear explicitly*/
+        BIO_free_all(bio);
+    }
+    if (stream != NULL) {
+        fclose(stream);
+    }
+    return rc;
+}
+
+
+/**
+* @brief Decode base64-encoded data
+*
+* @param[in] pEncBuff          - base64-encoded buffer
+* @param[in] encBuffLen        - input buffer length
+* @param[out] pDecBuff         - decoded buffer
+* @param[in/out] pDecBuffLen   - decoded buffer length
+*/
+/*********************************************************/
+int32_t CC_CommonBase64Decode(uint8_t *pEncBuff,
+                uint32_t  encBuffLen,
+                uint8_t *pDecBuff,
+                uint32_t *pDecBuffLen)
+{
+    BIO *bio = NULL;
+    BIO *b64 = NULL;
+    int32_t actualRead = 0;
+    int32_t expDecBuffLen = 0;
+    FILE* stream = NULL;
+    int32_t padding = 0;
+    int32_t rc = 0;
+    int32_t i = 0;
+
+    if ((NULL == pEncBuff) ||
+        (NULL == pDecBuff) ||
+        (NULL == pDecBuffLen) ||
+        (0 == encBuffLen)) {
+        UTIL_LOG_ERR("ilegal inputs\n");
+        return 1;
+    }
+
+    UTIL_LOG_INFO("started. encBuffLen %d\n", encBuffLen);
+    /* check validity of decoded buffer length */
+    i = encBuffLen-1;
+    while (!IS_BASE64_ENCODE_VAL(pEncBuff[i])) {
+        UTIL_LOG_INFO("pEncBuff[%d] 0x%x\n", i, pEncBuff[i]);
+        padding++;
+        i--;
+    }
+    expDecBuffLen = (((encBuffLen-padding)*3)/4);
+    if (*pDecBuffLen < expDecBuffLen) {
+        UTIL_LOG_ERR("ilegal inputs outBuffLen %d expDecBuffLen %d\n", *pDecBuffLen, expDecBuffLen);
+        rc = 1;
+        goto End_Base64Decode;
+    }
+
+    memset(pDecBuff, 0, *pDecBuffLen);
+
+    stream = fmemopen(pEncBuff, encBuffLen, "r");
+    if (NULL == stream) {
+        UTIL_LOG_ERR("failed to open mem\n");
+        rc = 1;
+        goto End_Base64Decode;
+    }
+
+    b64 = BIO_new(BIO_f_base64());
+    if (NULL == b64) {
+        UTIL_LOG_ERR("failed to BIO_new\n");
+        rc = 1;
+        goto End_Base64Decode;
+    }
+    bio = BIO_new_fp(stream, BIO_NOCLOSE);
+    if (NULL == bio) {
+        UTIL_LOG_ERR("failed to BIO_new_fp\n");
+        rc = 1;
+        goto End_Base64Decode;
+    }
+    bio = BIO_push(b64, bio);
+    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Do not use newlines to flush buffer
+    actualRead = BIO_read(bio, pDecBuff, encBuffLen);
+    if (actualRead != expDecBuffLen) {
+        UTIL_LOG_ERR("failed to BIO_read expDecBuffLen %d = actualRead %d\n", expDecBuffLen, actualRead);
+        rc = 1;
+        goto End_Base64Decode;
+    }
+    *pDecBuffLen = actualRead;
+    rc = 0;
+
+    End_Base64Decode:
+    if (bio != NULL) { /* clears bio and b64, b64 mustn't clear explicitly*/
+        BIO_free_all(bio);
+    }
+    if (stream != NULL) {
+        fclose(stream);
+    }
+    UTIL_LOG_INFO("rc %d\n", rc);
+    return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_encode.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_encode.h
new file mode 100644
index 0000000..0a3bef7
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_encode.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _COMMON_CRYPTO_ENCODE_H
+#define _COMMON_CRYPTO_ENCODE_H
+
+#include <stdint.h>
+
+#define CC_COMMON_CALC_BASE64_ENCODE_SIZE(origSize) ((((origSize+2)/3)*4)+1)
+#define CC_COMMON_CALC_BASE64_MAX_DECODE_SIZE(encodedSize) ((encodedSize*3)/4)  /* max size in case no padding to encoded buffer */
+
+/**
+* @brief performs base64-encode
+*
+* @param[in] pBuff             - the buffer to encode
+* @param[in] buffLen           - input buffer length
+* @param[in/out] pEncBuffLen   - encoded buffer length
+* @param[out] pEncBuff         - encoded buffer
+*/
+/*********************************************************/
+int32_t CC_CommonBase64Encode(uint8_t *pBuff,
+                uint32_t  buffLen,
+                uint8_t *pEncBuff,
+                uint32_t *pEecBuffLen);
+
+
+/**
+* @brief performs base64-decode
+*
+* @param[in] pEncBuff          - base64-encoded buffer
+* @param[in] encBuffLen        - input buffer length
+* @param[in/out] pDecBuffLen   - decoded buffer length
+* @param[out] pDecBuff         - decoded buffer
+*/
+/*********************************************************/
+int32_t CC_CommonBase64Decode(uint8_t *pEncBuff,
+                uint32_t  encBuffLen,
+                uint8_t *pDecBuff,
+                uint32_t *pDecBuffLen);
+
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_sym.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_sym.c
new file mode 100644
index 0000000..7ce6b4d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_sym.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/cmac.h>
+#include <openssl/sha.h>
+#include "common_crypto_sym.h"
+#include "common_util_log.h"
+#include "common_util_files.h"
+
+/**
+* @brief Encrypts (AES CTR) a given data and returns it.
+*
+* @param[in] pDataIn - the data to encrypt
+* @param[in] dataInSize - the data size
+* @param[in] pKey - the AES key
+* @param[in] keySize - AES key size (must be one of the allowed AES key sizes)
+* @param[in] pIV - IV (AES IV size is constant)
+* @param[out] pEncBuff - the encrypted buffer
+*/
+/*********************************************************/
+int32_t CC_CommonAesCtrEncrypt(int8_t  *pDataIn,
+                  int32_t    dataInSize,
+                  int8_t   *pKey,
+                  int32_t    keySize,
+                  int8_t   *pIV,
+                  int8_t   *pEncBuff)
+{
+    AES_KEY key;
+    uint8_t m_iv[AES_BLOCK_SIZE];
+    uint8_t m_ecount_buf[AES_BLOCK_SIZE];
+    uint32_t m_num = 0;
+    int32_t ret = (-1);
+
+    if ((NULL == pDataIn) ||
+        (NULL == pKey) ||
+        (NULL == pIV) ||
+        (NULL == pEncBuff)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return -1;
+    }
+    memcpy (m_iv, pIV, sizeof (m_iv));
+    memset (m_ecount_buf, 0, sizeof (m_ecount_buf));
+
+    /* Initialize an AES_KEY from raw key bytes */
+    ret = AES_set_encrypt_key (pKey, keySize * 8, &key);
+    if (ret != 0) {
+        UTIL_LOG_ERR("\n AES_set_encrypt_key failed");
+        return -1;
+    }
+    /* Encrypting data and sending it to the destination */
+    AES_ctr128_encrypt (pDataIn, pEncBuff, dataInSize, &key, m_iv, m_ecount_buf, &m_num);
+
+    return 0;
+}
+
+
+/**
+* @brief The CC_CommonAesCbcDecrypt decrypts (AES CBC) a given data
+*               and returns the decrypted buffer. data was encrypted using:
+*   "openssl enc -e -nosalt -aes-128-cbc -in <in_file,bin> -out <out_file.bin> -pass file:<pwd_file.txt>"
+* @param[in] pwdFileName - file name for passsword to generate key and IV from
+* @param[in] pEncBuff - the encrypted buffer- input buffer
+* @param[in] encBuffSize - the encrypted buffer size
+* @param[out] pDecBuff -the decrypted buffer.
+*
+* NOTE: pDecBuff - alocated size must be multiple of 16 bytes. same as encBuffSize
+*/
+/*********************************************************/
+int32_t CC_CommonAesCbcDecrypt(int8_t *pwdFileName,
+                  int8_t *pEncBuff,
+                  int32_t   encBuffSize,
+                  int8_t *pDecBuff)
+{
+    uint8_t *pwdBuff = NULL;
+    int32_t pwdBuffLen = 0;
+    const EVP_CIPHER *cipher = NULL;
+    const EVP_MD *dgst = NULL;
+    int8_t keyBuff[EVP_MAX_KEY_LENGTH] = {0x0};
+    int8_t ivBuff[EVP_MAX_KEY_LENGTH] = {0x0};
+    AES_KEY aesKey;
+    int32_t status = 1;
+
+    if ((NULL == pEncBuff) ||
+        (NULL == pDecBuff)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return 1;
+    }
+
+    /* parse the passphrase for a given file */
+    if ((NULL != pwdFileName)) {
+        if (CC_CommonGetPassphrase(pwdFileName, &pwdBuff)) {
+        UTIL_LOG_ERR("Failed to retrieve pwd\n");
+        status = 1;
+        goto END;
+    }
+        pwdBuffLen = strlen(pwdBuff);
+    }
+
+    /* get the IV and key from pwd */
+    cipher = EVP_get_cipherbyname("aes-128-cbc");
+    if (NULL == cipher) {
+        UTIL_LOG_ERR("EVP_get_cipherbyname failed\n");
+        status = 1;
+        goto END;
+    }
+
+    dgst = EVP_get_digestbyname("md5");
+    if (NULL == dgst) {
+        UTIL_LOG_ERR("EVP_get_digestbyname failed\n");
+        status = 1;
+        goto END;
+    }
+
+    UTIL_LOG_BYTE_BUFF("pwdBuff", pwdBuff, strlen(pwdBuff));
+    status = EVP_BytesToKey(cipher, dgst, NULL, (uint8_t *) pwdBuff, pwdBuffLen, 1, keyBuff, ivBuff);
+    if (0 == status) {
+        UTIL_LOG_ERR("EVP_BytesToKey failed\n");
+        status = 1;
+        goto END;
+    }
+
+    UTIL_LOG_BYTE_BUFF("keyBuff", keyBuff, sizeof(keyBuff));
+    UTIL_LOG_BYTE_BUFF("ivBuff", ivBuff, sizeof(ivBuff));
+
+    /* key and IV are ready, start decryption */
+    memset (pDecBuff, 0, encBuffSize);  /* encBuffSize is multiple of 16 bytes */
+
+    /* Initialize an AES_KEY from raw key bytes */
+    status = AES_set_decrypt_key (keyBuff, 128, &aesKey);
+    if (status != 0) {
+        UTIL_LOG_ERR("\n AES_set_encrypt_key failed");
+        status = 1;
+        goto END;
+    }
+    /* Encrypting data and sending it to the destination */
+    AES_cbc_encrypt(pEncBuff, pDecBuff, encBuffSize, &aesKey, ivBuff, AES_DECRYPT);
+
+    status = 0;
+    END:
+    if (pwdBuff != NULL) {
+        free(pwdBuff);
+    }
+    return status;
+}
+
+/**
+* @brief Encrypts AES CBC-MAC a given data
+*               and returns the encrypted buffer.
+*
+* @param[in] pKey - key buffer
+* @param[in] pIv - iv buffer
+* @param[in] pBuff - the plaintext buffer
+* @param[in] encBuffSize - the plaintext buffer size
+* @param[in] pEncMacBuff -the encrypted - ciphertext buffer.
+* @param[out] pEncMacBuff -the encrypted - ciphertext buffer.
+*
+*/
+/*********************************************************/
+int32_t CC_CommonAesCbcMacEncrypt(int8_t *pKey,
+                  int8_t *pIv,
+                  int8_t *pBuff,
+                  uint32_t   buffSize,
+                  uint32_t   macSize,
+                  int8_t *pEncMacBuff)
+{
+    AES_KEY aesKey;
+    int32_t status = 1;
+    uint8_t *pOutBuff = NULL;
+
+    if ((NULL == pKey) ||
+        (NULL == pIv) ||
+        (NULL == pBuff) ||
+        (NULL == pEncMacBuff) ||
+        (0 == buffSize)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return 1;
+    }
+
+    memset (pEncMacBuff, 0, macSize);  /* buffSize is multiple of 16 bytes */
+
+    pOutBuff = malloc(buffSize);
+    if (NULL == pOutBuff) {
+        UTIL_LOG_ERR("malloc failed\n");
+        return 1;
+    }
+
+    /* Initialize an AES_KEY from raw key bytes */
+    status = AES_set_encrypt_key(pKey, 128, &aesKey);
+    if (status != 0) {
+        UTIL_LOG_ERR("\n AES_set_encrypt_key failed");
+        status = 1;
+        goto END;
+    }
+    /* Encrypting data and sending it to the destination */
+    AES_cbc_encrypt(pBuff, pOutBuff, buffSize, &aesKey, pIv, AES_ENCRYPT);
+    memcpy(pEncMacBuff, pOutBuff, macSize);
+
+    status = 0;
+    END:
+    if (pOutBuff != NULL) {
+        free(pOutBuff);
+    }
+    return status;
+}
+
+
+/**
+* @brief Encrypts (AES CCM) a given data and returns it.
+*
+* @param[in] pDataIn - the data to encrypt
+* @param[in] dataInSize - the data size
+* @param[in] pKey - the AES key
+* @param[in] keySize - AES key size (must be one of the allowed AES key sizes)
+* @param[out] pOutput - Output buffer
+*/
+/*********************************************************/
+int32_t CC_CommonAesCcmEncrypt(uint8_t *keyBuf,
+                  uint8_t *nonce,
+                  uint32_t  nonceLen,
+                  uint8_t *aData,
+                  uint32_t  aDatalen,
+                  uint8_t *plainTxt,
+                  uint32_t  plainTxtLen,
+                  uint8_t *enBuff,
+                  uint32_t  *enBuffLen,
+                  uint8_t *tagBuff,
+                  uint32_t  tagBuffLen)
+{
+    EVP_CIPHER_CTX ccm_ctx;
+    int32_t outlen = 0;
+    int32_t rc  = 0;
+
+    if ((NULL == keyBuf) ||
+        (NULL == nonce) ||
+        (NULL == plainTxt) ||
+        (NULL == enBuff) ||
+        (NULL == enBuffLen) ||
+        (NULL == tagBuff)) {
+        UTIL_LOG_ERR( "invalid input pointers\n");
+        return 1;
+    }
+    /* check legth validity*/
+    memset(enBuff, 0, plainTxtLen);
+    memset(tagBuff, 0, tagBuffLen);
+
+
+    EVP_CIPHER_CTX_init(&ccm_ctx);
+
+    /* Set cipher type and mode */
+    rc  = EVP_EncryptInit_ex(&ccm_ctx, EVP_aes_128_ccm(), NULL, NULL, NULL);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to EVP_EncryptInit_ex() for CCM cipher\n");
+        rc = 1;
+        goto ccmEnd;
+    }
+    /* Set nonce length if default 96 bits is not appropriate */
+    rc  = EVP_CIPHER_CTX_ctrl(&ccm_ctx, EVP_CTRL_CCM_SET_IVLEN, nonceLen, NULL);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to EVP_CIPHER_CTX_ctrl() for nonce length\n");
+        rc = 1;
+        goto ccmEnd;
+    }
+    /* Set tag length */
+    rc  = EVP_CIPHER_CTX_ctrl(&ccm_ctx, EVP_CTRL_CCM_SET_TAG, tagBuffLen, NULL);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to EVP_CIPHER_CTX_ctrl() for tag length\n");
+        rc = 1;
+        goto ccmEnd;
+    }
+    /* Initialise key and IV */
+    UTIL_LOG_BYTE_BUFF("nonce", nonce, nonceLen);
+    UTIL_LOG_BYTE_BUFF("keyBuf", keyBuf, 16);
+    rc  = EVP_EncryptInit_ex(&ccm_ctx, NULL, NULL, keyBuf, nonce);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to EVP_EncryptInit_ex() for key and IV\n");
+        rc = 1;
+        goto ccmEnd;
+    }
+    if ((aDatalen>0) && (aData != NULL)) {
+        /* Set plaintext length: only needed if AAD is used */
+        rc  = EVP_EncryptUpdate(&ccm_ctx, NULL, &outlen, NULL, plainTxtLen);
+        if (rc != 1) {
+            UTIL_LOG_ERR( "failed to EVP_EncryptUpdate() for plaintext length\n");
+            rc = 1;
+            goto ccmEnd;
+        }
+        /* Zero or one call to specify any AAD */
+        UTIL_LOG_BYTE_BUFF("aData", aData, aDatalen);
+        rc  = EVP_EncryptUpdate(&ccm_ctx, NULL, &outlen, aData, aDatalen);
+        if (rc != 1) {
+            UTIL_LOG_ERR( "failed to EVP_EncryptUpdate() for AAD\n");
+            rc = 1;
+            goto ccmEnd;
+        }
+    }
+
+    /* Encrypt plaintext: can only be called once */
+    UTIL_LOG_BYTE_BUFF("plainTxt", plainTxt, plainTxtLen);
+    rc  = EVP_EncryptUpdate(&ccm_ctx, enBuff, &outlen, plainTxt, plainTxtLen);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to EVP_EncryptUpdate() for plaintext\n");
+        rc = 1;
+        goto ccmEnd;
+    }
+    if (outlen != plainTxtLen) {
+        UTIL_LOG_ERR( "ccm encrypt size(%d) != palin text size(%d)\n", outlen, plainTxtLen);
+        rc = 1;
+        goto ccmEnd;
+    }
+    UTIL_LOG_BYTE_BUFF("enBuff", enBuff, outlen);
+    /* Finalise: note get no output for CCM */
+    rc  = EVP_EncryptFinal_ex(&ccm_ctx, &enBuff[outlen], &outlen);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to EVP_EncryptFinal_ex()\n");
+        rc = 1;
+        goto ccmEnd;
+    }
+    /* Get tag */
+    rc  = EVP_CIPHER_CTX_ctrl(&ccm_ctx, EVP_CTRL_CCM_GET_TAG, tagBuffLen, tagBuff);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to EVP_CIPHER_CTX_ctrl() to get the tag\n");
+        rc = 1;
+        goto ccmEnd;
+    }
+    UTIL_LOG_BYTE_BUFF("tagBuff", tagBuff, tagBuffLen);
+    rc = 0;
+
+    ccmEnd:
+
+    EVP_CIPHER_CTX_cleanup(&ccm_ctx);
+    return rc;
+}
+
+
+
+/**
+* @brief Encrypts (AES CMAC) a given data and returns it.
+*
+* @param[in] pDataIn - the data to encrypt
+* @param[in] dataInSize - the data size
+* @param[in] pKey - the AES key
+* @param[in] keySize - the key size in bytes
+* @param[in] pOutput - Output buffer
+*/
+/*********************************************************/
+int32_t CC_CommonAesCmacEncrypt(int8_t *pDataIn,
+                   int32_t  dataInSize,
+                   int8_t *pKey,
+                   int32_t  keySize,
+                   int8_t *pOutput)
+{
+    CMAC_CTX *cmac_ctx = NULL;
+    int32_t rc = 0;
+    size_t tempOutSize = 0;
+
+    if ((NULL == pKey) ||
+        (NULL == pDataIn) ||
+        (NULL == pOutput) ||
+        ((keySize != AES_BLOCK_SIZE) && (keySize != (AES_BLOCK_SIZE*2)))) {
+        UTIL_LOG_ERR( "Ilegal parameters\n");
+        return 1;
+    }
+    cmac_ctx = CMAC_CTX_new();
+    if (NULL == cmac_ctx) {
+        UTIL_LOG_ERR( "failed to CMAC_CTX_new\n");
+        return 1;
+    }
+    memset(pOutput, 0, AES_BLOCK_SIZE);
+    if (AES_BLOCK_SIZE == keySize) {
+        rc = CMAC_Init(cmac_ctx, pKey, AES_BLOCK_SIZE, EVP_aes_128_cbc(), 0);
+    } else {
+        rc = CMAC_Init(cmac_ctx, pKey, AES_BLOCK_SIZE*2, EVP_aes_256_cbc(), 0);
+    }
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to CMAC_Init\n");
+        rc = 2;
+        goto cmacEnd;
+    }
+    rc = CMAC_Update(cmac_ctx, pDataIn, dataInSize);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to CMAC_Update\n");
+        rc = 3;
+        goto cmacEnd;
+    }
+    rc = CMAC_Final(cmac_ctx, pOutput, &tempOutSize);
+    if (rc != 1) {
+        UTIL_LOG_ERR( "failed to CMAC_Final\n");
+        rc = 4;
+        goto cmacEnd;
+    }
+    rc = 0;
+    cmacEnd:
+    if (cmac_ctx != NULL) {
+        CMAC_CTX_free(cmac_ctx);
+    }
+    return rc;
+}
+
+
+/**
+ * @brief Calculates HASH on a given buffer, and returns the digest
+ *
+ * @param[in] pPemDecryted - the decrypted public key (input data for HASH)
+ * @param[out] pHash - the HASH SHA 256 calculated on the data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonCalcHash(uint8_t *pPemDecryted,
+               int32_t            pemDecryptedSize,
+               uint8_t *pHash,
+               int32_t           hashSize)
+{
+
+    uint8_t hash[HASH_SHA256_DIGEST_SIZE_IN_BYTES];
+    int32_t i;
+
+    /* Verify no NULL pointers */
+    if ((pPemDecryted == NULL) ||
+        (pHash == NULL)) {
+        UTIL_LOG_ERR("Illegal parameters \n");
+        return -1;
+    }
+
+    /* verify the size is correct */
+    if ((hashSize != HASH_SHA256_DIGEST_SIZE_IN_BYTES) && (hashSize != HASH_SHA256_DIGEST_SIZE_IN_BYTES/2)) {
+        UTIL_LOG_ERR("The digest size is incorrect it can either be %d or %d, given digest size is %d\n", HASH_SHA256_DIGEST_SIZE_IN_BYTES, HASH_SHA256_DIGEST_SIZE_IN_BYTES/2, hashSize);
+        return -1;
+    }
+
+    /* Calculate the hash */
+    SHA256(pPemDecryted, pemDecryptedSize,hash);
+
+    /* copy the hash according to requested size */
+    memcpy(pHash, hash, hashSize);
+    return 0;
+
+}
+
+
+/**
+ * @brief Calculates HASH on a given buffer, and returns the digest
+ *
+ * @param[in] pPemDecryted - the decrypted public key (input data for HASH)
+ * @param[out] pHash - the HASH SHA 256 calculated on the data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonCalcSha1(uint8_t *pDataIn,
+               int32_t            dataInSize,
+               uint8_t *pHash)
+{
+    uint8_t hash[HASH_SHA1_DIGEST_SIZE_IN_BYTES];
+    int32_t i;
+
+    /* Verify no NULL pointers */
+    if ((pDataIn == NULL) ||
+        (pHash == NULL)) {
+        UTIL_LOG_ERR("Illegal parameters \n");
+        return -1;
+    }
+
+    /* Calculate the hash */
+    SHA1(pDataIn, dataInSize, hash);
+
+    /* copy the hash according to requested size */
+    memcpy(pHash, hash, HASH_SHA1_DIGEST_SIZE_IN_BYTES);
+    return 0;
+
+}
+
+
+/**
+* @brief Encrypts (AES ECB) a given data and returns it.
+*
+* @param[in] pDataIn - the data to encrypt
+* @param[in] dataInSize - the data size
+* @param[in] pKey - the AES key
+* @param[in] keySize - AES key size (must be one of the allowed AES key sizes)
+* @param[out] pEncBuff - the encrypted buffer
+*/
+/*********************************************************/
+int32_t CC_CommonAesEcbEncrypt(uint8_t  *pDataIn,
+                  uint32_t    dataInSize,
+                  uint8_t   *pKey,
+                  uint32_t    keySize,
+                  uint8_t   *pEncBuff)
+{
+    #define BITS_WITHIN_BYTE 8
+
+    int rc = 0;
+    AES_KEY encKey;
+
+    if ((NULL == pDataIn) ||
+        (NULL == pKey) ||
+        (NULL == pEncBuff)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return 1;
+    }
+
+    UTIL_LOG_ERR("About to AES_set_encrypt_key\n");
+    rc = AES_set_encrypt_key(pKey, (keySize*BITS_WITHIN_BYTE), &encKey);
+    if (rc != 0) {
+        UTIL_LOG_ERR("Failed AES_set_encrypt_key\n");
+        return 1;
+    }
+
+    /* Encrypting data and sending it to the destination */
+    UTIL_LOG_ERR("About to AES_ecb_encrypt byteCount\n");
+    AES_ecb_encrypt(pDataIn, pEncBuff, &encKey, AES_ENCRYPT);
+
+    return 0;
+}
+
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_sym.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_sym.h
new file mode 100644
index 0000000..aa53690
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_sym.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _COMMON_CRYPTO_SYM_H
+#define _COMMON_CRYPTO_SYM_H
+
+
+#include <stdint.h>
+#include "cc_crypto_defs.h"
+
+#define CC_COMMON_CALC_CBC_ENCODE_SIZE(size)  (AES_BLOCK_SIZE + (((size + AES_BLOCK_SIZE)/AES_BLOCK_SIZE)*AES_BLOCK_SIZE))
+
+
+/**
+* @brief The CC_CommonAesCtrEncrypt encrypts (AES CTR) a given data and returns it.
+*
+* @param[in] DataIn_ptr - the data to encrypt
+* @param[in] DataInSize - the data size
+* @param[in] Key_ptr - the AES key
+* @param[in] KeySize - AES key size (must be one of the allowed AES key sizes)
+* @param[in] IV_ptr - IV (AES IV size is constant)
+* @param[in] Output_ptr - Output buffer
+*/
+/*********************************************************/
+int32_t CC_CommonAesCtrEncrypt(int8_t  *pDataIn,
+                  int32_t    dataInSize,
+                  int8_t   *pKey,
+                  int32_t    keySize,
+                  int8_t   *pIV,
+                  int8_t   *pEncBuff);
+
+
+/**
+* @brief The CC_CommonAesCbcDecrypt decrypts (AES CBC) a given data
+*               and returns the decrypted buffer.
+*
+* @param[in] pwdFileName - file name for passsword to generate key and IV from
+* @param[in] pEncBuff - the encrypted buffer- input buffer
+* @param[in] encBuffSize - the encrypted buffer size
+* @param[out] pDecBuff -the decrypted buffer.
+*
+* NOTE: pDecBuff - alocated size must be multiple of 16 bytes. same as encBuffSize
+*/
+/*********************************************************/
+int32_t CC_CommonAesCbcDecrypt(int8_t *pwdFileName,
+                  int8_t *pEncBuff,
+                  int32_t   encBuffSize,
+                  int8_t *pDecBuff);
+
+/**
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+int32_t CC_CommonAesCcmEncrypt(uint8_t *keyBuf,
+                  uint8_t *nonce, uint32_t nonceLen,
+                  uint8_t *aData, uint32_t aDatalen,
+                  uint8_t *plainTxt, uint32_t plainTxtLen,
+                  uint8_t *enBuff, uint32_t *enBuffLen,
+                  uint8_t *tagBuff, uint32_t tagBuffLen);
+
+/**
+* @brief Encrypts (AES CMAC) a given data and returns it.
+*
+* @param[in] pDataIn - the data to encrypt
+* @param[in] dataInSize - the data size
+* @param[in] pKey - the AES key
+* @param[in] keySize - the key size in bytes
+* @param[in] pOutput - Output buffer
+*/
+/*********************************************************/
+int32_t CC_CommonAesCmacEncrypt(int8_t *pDataIn,
+                   int32_t  dataInSize,
+                   int8_t *pKey,
+                   int32_t  keySize,
+                   int8_t *pOutput);
+
+
+
+/**
+ * @brief The Common_CalcHash calculates HASH on the public key and Np using OpenSSL.
+ *
+ * @param[in] pPemDecryted - the decrypted public key (input data for HASH)
+ * @param[out] pHash - the HASH SHA 256 calculated on the data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonCalcHash(uint8_t *pPemDecryted, int32_t pemDecryptedSize, uint8_t *pHash, int32_t hashSize );
+
+/**
+ * @brief The Common_CalcHash calculates HASH on the public key and Np using OpenSSL.
+ *
+ * @param[in] pPemDecryted - the decrypted public key (input data for HASH)
+ * @param[out] pHash - the HASH SHA 256 calculated on the data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonCalcSha1(uint8_t *pDataIn, int32_t dataInSize, uint8_t *pHash);
+
+
+/**
+* @brief Encrypts (AES ECB) a given data and returns it.
+*
+* @param[in] pDataIn - the data to encrypt
+* @param[in] dataInSize - the data size
+* @param[in] pKey - the AES key
+* @param[in] keySize - AES key size (must be one of the allowed AES key sizes)
+* @param[out] pEncBuff - the encrypted buffer
+*/
+/*********************************************************/
+int32_t CC_CommonAesEcbEncrypt(uint8_t  *pDataIn,
+                  uint32_t    dataInSize,
+                  uint8_t   *pKey,
+                  uint32_t    keySize,
+                  uint8_t   *pEncBuff);
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_x509.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_x509.c
new file mode 100644
index 0000000..e1827e5
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_x509.c
@@ -0,0 +1,722 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/opensslv.h>
+#include <openssl/conf.h>
+#include <openssl/x509v3.h>
+
+#include "common_crypto_x509.h"
+#include "common_crypto_asym.h"
+#include "common_rsa_keypair.h"
+#include "common_util_files.h"
+#include "common_util_log.h"
+#include "cc_crypto_boot_defs.h"
+#include "cc_crypto_x509_defs.h"
+
+#ifdef CC_SB_SUPPORT_IOT
+#include "secdebug_defs.h"
+#endif
+
+#define X509_VER_3  2  /* version 3 certificate */
+#define ENDLESS_VALIDITY  0xFFFFFFFE
+#define MAX_OBJ_ID_LEN  15
+#define EXT_PREFIX_LEN  16
+#ifdef CC_SB_SUPPORT_IOT
+#define MAX_EXT_VAL_LIST (CC_SB_MAX_CONTENT_CERT_BODY_SIZE_IN_BYTES)
+#else
+#define MAX_EXT_VAL_LIST 80 // additional data
+#endif
+#define MAX_EXT_INT_VAL_LEN  80
+
+/* multiple each byte by 3 for: each byte has 2 character representaion + ":" */
+#define MAX_EXT_VAL_LEN  (MAX_EXT_VAL_LIST *3 + EXT_PREFIX_LEN)
+#define CHAR_STR_LEN 6
+
+#define OPEN_SSL_ERROR   0
+#define IS_VALID_ENC_FLAG(encFlag) ((0 == (encFlag)) || (1 == (encFlag)) || (0xFF == (encFlag)))
+#define IS_VALID_HBK(hbkType) ((CC_SB_HASH_BOOT_KEY_0_128B == (hbkType)) ||\
+                   (CC_SB_HASH_BOOT_KEY_1_128B == (hbkType)) ||\
+                   (CC_SB_HASH_BOOT_KEY_256B == (hbkType)) ||\
+                   (CC_SB_HASH_BOOT_NOT_USED == (hbkType)))
+
+const uint8_t *certType2Str[CC_X509_CERT_TYPE_MAX] = {NULL,
+  /*CC_X509_CERT_TYPE_KEY      */      (uint8_t *)CC_X509_CERT_KEY_CERT,
+  /*CC_X509_CERT_TYPE_CONTENT  */      (uint8_t *)CC_X509_CERT_CNT_CERT,
+  /*CC_X509_CERT_TYPE_ENABLER_DBG */      (uint8_t *)CC_X509_CERT_ENABLER_CERT,
+  /*CC_X509_CERT_TYPE_DEVELOPER_DBG */      (uint8_t *)CC_X509_CERT_DEVELOPER_CERT
+};
+
+
+/**
+* @brief free X509 certificate
+*
+* @param[in/out] ppCertBuff          - x.509 certificate
+*/
+/*********************************************************/
+void CC_CommonX509Free(uint8_t **ppCertBuff)
+{
+    /* validate inputs */
+    if ((NULL == ppCertBuff) ||
+        (NULL == *ppCertBuff)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return;
+    }
+
+    UTIL_LOG_INFO("about to X509_free\n");
+    /* create the certificate buffer */
+    X509_free((X509 *)*ppCertBuff);
+    *ppCertBuff = NULL;
+    return;
+}
+
+
+/**
+* @brief Creates X509 certificate and set its header fields
+*
+* @param[in/out] ppCertBuff     - x.509 certificate
+* @param[in] certType           - certificate type
+*/
+/*********************************************************/
+int32_t CC_CommonX509CreateAndSetHeader(uint8_t **ppCertBuff,
+                CCX509CertType_t  certType,CCX509CertHeaderParamsIn_t *pCertHeaderParams)
+{
+    int32_t rc = 0;
+    long endDate = 0;
+    uint32_t  serialNum = 0;
+    long notBefore = 0; /*X509_CURRENT_TIME*/
+    long notAfter = ENDLESS_VALIDITY;
+    char* pIssuerName = CC_X509_CERT_ISSUER_NAME;
+    const char* pSubjectName = certType2Str[certType];
+    X509 *plCert = NULL;
+    ASN1_TIME *pDummy = NULL;
+
+    /* validate inputs */
+    if ((NULL == ppCertBuff) ||
+        (certType >= CC_X509_CERT_TYPE_MAX) ) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(-1);
+    }
+
+    /* create the certificate buffer */
+    plCert = (X509 *)X509_new();
+    if (OPEN_SSL_ERROR == plCert) {
+        UTIL_LOG_ERR("failed to X509_new\n");
+        return 1;
+    }
+
+    /* set certificate version to V3 */
+    rc = X509_set_version(plCert, X509_VER_3);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to X509_set_version\n");
+        rc = 1;
+        goto END;
+    }
+    /* set certificate serial number */
+    if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setSerialNum) ) {
+        serialNum = pCertHeaderParams->serialNum;
+    } else {
+        rc = CC_CommonRandBytes(4, (int8_t *)&serialNum);
+        if (rc != 0) {
+            UTIL_LOG_ERR("failed to set CC_CommonRandBytes\n");
+            rc = 1;
+            goto END;
+        }
+    }
+
+    rc = ASN1_INTEGER_set(X509_get_serialNumber(plCert), serialNum);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to set X509_get_serialNumber\n");
+        rc = 1;
+        goto END;
+    }
+    /* set ecrtificate start time to current time, and end date according to input */
+    if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setNotBefore) ) {
+        notBefore = pCertHeaderParams->notBefore;
+    }
+    pDummy = X509_gmtime_adj(X509_get_notBefore(plCert), (long)notBefore );
+    if (NULL == pDummy) {
+        UTIL_LOG_ERR("failed set X509_get_notBefore\n");
+        rc = 1;
+        goto END;
+    }
+    if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setNotAfter) ) {
+        notAfter = pCertHeaderParams->notAfter;
+    }
+    pDummy = X509_gmtime_adj(X509_get_notAfter(plCert),(long)notAfter);
+    if (NULL == pDummy) {
+        UTIL_LOG_ERR("failed set X509_get_notAfter\n");
+        rc = 1;
+        goto END;
+    }
+
+    /* set subject name */
+    if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setSubjectName) ) {
+        pSubjectName = pCertHeaderParams->SubjectName;
+    }
+    rc = X509_NAME_add_entry_by_txt(X509_get_subject_name(plCert),
+                        "CN",       /* common name */
+                        MBSTRING_ASC,
+                        pSubjectName,
+                        -1,
+                        -1, 0);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to set X509_get_subject_name\n");
+        rc = 1;
+        goto END;
+    }
+
+    /* set issuer name */
+    if ( (NULL != pCertHeaderParams) && (pCertHeaderParams->setIssuerName) ) {
+        pIssuerName = pCertHeaderParams->IssuerName;
+    }
+    rc = X509_NAME_add_entry_by_txt(X509_get_issuer_name(plCert),
+                        "CN",
+                        MBSTRING_ASC,
+                        pIssuerName,
+                        -1,
+                        -1, 0);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to set X509_get_issuer_name\n");
+        rc = 1;
+        goto END;
+    }
+
+
+
+    *ppCertBuff = (uint8_t *)plCert;
+    rc = 0;
+    UTIL_LOG_INFO("OK\n");
+
+    END:
+    if (rc != 0) {
+        if (plCert != NULL) {
+            X509_free(plCert);
+        }
+        *ppCertBuff = NULL;
+    }
+    return rc;
+}
+
+
+/**
+* @brief Add ASN.1 critical integer extension to X.509V3 certificate
+*
+* @param[in/out] pCertBuff          - x.509 certificate
+* @param[in] certType                 - certificate type
+* @param[in] extType              - extension type
+* @param[in] val              - Extension value
+*/
+/*********************************************************/
+int32_t CC_CommonX509AddIntegerExtension(uint8_t *pCertBuff,
+                       CCX509CertType_t certType,
+                       CCX509ExtType_t  extType,
+                       int32_t val)
+
+{
+    int32_t rc = 0;
+    int32_t nid = 0;
+    X509 *plCert = (X509 *)pCertBuff;
+    X509_EXTENSION *ext = NULL;
+    uint8_t objId[MAX_OBJ_ID_LEN];
+    uint8_t extValue[MAX_EXT_INT_VAL_LEN];
+    int32_t writtenBytes = 0;
+
+    /* validate inputs */
+    if (NULL == pCertBuff) {
+        UTIL_LOG_ERR("Illegal parameters \n");
+        return (-1);
+    }
+
+    /* create new object */
+    snprintf(objId, MAX_OBJ_ID_LEN, "2.20.%d.%d",certType,extType);
+    nid = OBJ_create(objId, "MyAlias", "My Test Alias Extension");
+    if (OPEN_SSL_ERROR == nid) {
+        UTIL_LOG_ERR("failed to OBJ_create\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+    rc = X509V3_EXT_add_alias(nid, NID_netscape_comment);
+    if (OPEN_SSL_ERROR == nid) {
+        UTIL_LOG_ERR("failed to X509V3_EXT_add_alias\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+    /* create the extension value */
+    writtenBytes = snprintf(extValue, MAX_EXT_INT_VAL_LEN, "critical,ASN1:INTEGER:0x%X",val);
+    /* build the extension */
+    ext = X509V3_EXT_conf_nid(NULL, NULL, nid, extValue);
+    if (OPEN_SSL_ERROR == ext) {
+        UTIL_LOG_ERR("failed to X509V3_EXT_conf_nid\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+
+    /* Add the extension to the certificate */
+    rc = X509_add_ext(plCert, ext, -1);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to X509_add_ext\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+    rc = 0;
+    UTIL_LOG_INFO("OK\n");
+
+    END:
+    X509_EXTENSION_free(ext);
+    return rc;
+}
+
+
+/**
+* @brief Add critical DER extension to X.509V3 certificate
+*
+* @param[in/out] pCertBuff          - x.509 certificate
+* @param[in] certType                 - certificate tyoes
+* @param[in] extType              - extension type
+* @param[in] pVal                 - Extension data
+* @param[in] valLen               - extension data length
+*/
+/*********************************************************/
+int32_t CC_CommonX509AddStringExtension(uint8_t *pCertBuff,
+                      CCX509CertType_t  certType,
+                      CCX509ExtType_t  extType,
+                      uint8_t *pVal,
+                      uint32_t valLen)
+
+{
+    int32_t rc = 0;
+    int32_t nid;
+    X509 *plCert = (X509 *)pCertBuff;
+    X509_EXTENSION *ext = NULL;
+    uint8_t objId[MAX_OBJ_ID_LEN];
+    uint8_t extValue[MAX_EXT_VAL_LEN];
+    int32_t writtenBytes = 0;
+    int32_t pValIdx = 0;
+
+    /* validate inputs */
+    if ((NULL == pCertBuff) ||
+        (NULL == pVal)||
+        (valLen > MAX_EXT_VAL_LIST)) {
+        UTIL_LOG_ERR("Illegal parameters \n");
+        return (-1);
+    }
+    /* create new object */
+    snprintf(objId, MAX_OBJ_ID_LEN, "2.20.%d.%d",certType,extType);
+    nid = OBJ_create(objId, "MyAlias", "My Test Alias Extension");
+    if (OPEN_SSL_ERROR == nid) {
+        UTIL_LOG_ERR("failed to OBJ_create\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+
+    pValIdx = 0;
+    writtenBytes = snprintf(extValue, MAX_EXT_VAL_LEN, "critical,DER: %02X",pVal[pValIdx++]);
+    UTIL_LOG_INFO("writtenBytes %d, extValue %s\n",writtenBytes, extValue);
+    while (pValIdx < valLen) {
+        writtenBytes += snprintf((extValue+writtenBytes), CHAR_STR_LEN, ":%02X", pVal[pValIdx++]);
+        UTIL_LOG_INFO("writtenBytes %d, extValue %s\n",writtenBytes, extValue);
+    }
+
+    rc = X509V3_EXT_add_alias(nid, NID_netscape_comment);  // if NID is unknown openssl ignores it. meaning it is not added to cert.
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to X509V3_EXT_add_alias\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+
+    ext = X509V3_EXT_conf_nid(NULL, NULL, nid, extValue);
+    if (OPEN_SSL_ERROR == ext) {
+        UTIL_LOG_ERR("failed to X509V3_EXT_conf_nid\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+
+    /* Add the extension to the certificate */
+    rc = X509_add_ext(plCert, ext, -1);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to X509_add_ext\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+    rc = 0;
+    UTIL_LOG_INFO("OK\n");
+
+    END:
+        if (ext != NULL) {
+                X509_EXTENSION_free(ext);
+        }
+    return rc;
+}
+
+
+/**
+* @brief Add subject public key to the X509 certificate
+*   and sign the certificate
+*
+* @param[in/out] pCertBuff      - x.509 certificate
+* @param[in] pKeyPairFileName   - key pair file name in PEM format
+* @param[in] pKeyPairPwd    - passphrase of key pair
+*/
+/*********************************************************/
+int32_t CC_CommonX509SetKeyAndSign(uint8_t *pCertBuff,
+                uint8_t *pKeyPairFileName,
+                uint8_t *pKeyPairPwd)
+{
+    int32_t rc = 0;
+    X509 *plCert = (X509 *)pCertBuff;
+    RSA  *pRsaKeyPair = NULL;
+    uint8_t *pwd = NULL;
+    EVP_PKEY *pKey     = NULL;
+    EVP_MD_CTX  mdCtx;
+    EVP_PKEY_CTX *pKeyCtx = NULL;
+
+    /* validate inputs */
+    if ((NULL == pCertBuff) ||
+        (NULL == pKeyPairFileName)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(-1);
+    }
+
+    /* get certificate Subject's RSA public and private key from key pair file */
+    /* parse the passphrase for a given file */
+    if (pKeyPairPwd != NULL) {
+        rc = CC_CommonGetPassphrase(pKeyPairPwd, &pwd);
+        if (rc != CC_COMMON_OK) {
+            UTIL_LOG_ERR("Failed to retrieve pwd\n");
+            goto END;
+        }
+    }
+    pRsaKeyPair = RSA_new();
+    if (NULL == pRsaKeyPair) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto END;
+    }
+    rc = CC_CommonGetKeyPair(&pRsaKeyPair, pKeyPairFileName, pwd);
+    if (rc != CC_COMMON_OK) {
+        UTIL_LOG_ERR("CC_CommonGetKeyPair Cannot read RSA private key\n");
+        rc = 1;
+        goto END;
+    }
+    /* allocate an empty EVP_PKEY structure which
+    is used by OpenSSL to store private keys.*/
+    pKey = EVP_PKEY_new();
+    if (NULL == pKey) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_new\n");
+        rc = 1;
+        goto END;
+    }
+    /*set the referenced key to RSA key*/
+    rc = EVP_PKEY_assign_RSA(pKey, pRsaKeyPair);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_assign_RSA\n");
+        rc = 1;
+        goto END;
+    }
+
+
+    EVP_MD_CTX_init(&mdCtx);
+    rc = EVP_DigestSignInit(&mdCtx, &pKeyCtx, EVP_sha256(), NULL, pKey);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to EVP_DigestSignInit\n");
+        rc = 1;
+        goto END;
+    }
+    rc = EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING);
+    if (rc <= OPEN_SSL_ERROR) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_CTX_set_rsa_padding\n");
+        rc = 1;
+        goto END;
+    }
+    rc = EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN);
+    if (rc <= OPEN_SSL_ERROR) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_CTX_set_rsa_pss_saltlen\n");
+        rc = 1;
+        goto END;
+    }
+    rc = EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256());
+    if (rc <= OPEN_SSL_ERROR) {
+        UTIL_LOG_ERR("failed to EVP_PKEY_CTX_set_rsa_mgf1_md\n");
+        rc = 1;
+        goto END;
+    }
+    UTIL_LOG_INFO("about to X509_set_pubkey\n");
+    /*set the key into certificate*/
+    rc = X509_set_pubkey(plCert,pKey);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to X509_set_pubkey\n");
+        ERR_print_errors_fp(stderr);
+        rc = 1;
+        goto END;
+    }
+
+    UTIL_LOG_INFO("about to X509_sign_ctx\n");
+    rc = X509_sign_ctx(plCert, &mdCtx);
+    if (OPEN_SSL_ERROR == rc) {
+        UTIL_LOG_ERR("failed to X509_sign\n");
+        rc = 1;
+        goto END;
+    }
+    rc = 0;
+    UTIL_LOG_INFO("OK\n");
+
+END:
+    EVP_MD_CTX_cleanup(&mdCtx);
+    if (pRsaKeyPair != NULL) {
+        RSA_free(pRsaKeyPair); // free pKey as well
+    }
+    if (pwd != NULL) {
+        free(pwd);
+    }
+    return rc;
+}
+
+
+/**
+* @brief convert the x.509 certificate to DER format
+*
+* @param[in/out] ppCertBuff      - x.509 certificate
+* @param[out] pOutCertSize  - certificate size in DER format
+*/
+/*********************************************************/
+int32_t CC_CommonX509ToDer(uint8_t **ppCertBuff,
+                uint32_t *pOutCertSize)
+{
+    unsigned char *outBuff = NULL;
+    uint8_t *pPemCertData = NULL;
+
+    /* validate inputs */
+    if ((NULL == ppCertBuff) ||
+        (NULL == pOutCertSize)) {
+        UTIL_LOG_ERR("ilegal input\n");
+        return(-1);
+    }
+
+
+    *pOutCertSize = i2d_X509((X509 *)*ppCertBuff, &outBuff);
+    CC_CommonX509Free(ppCertBuff);
+    *ppCertBuff = outBuff;
+
+    UTIL_LOG_INFO("OK\n");
+
+    return 0;
+}
+
+
+#ifdef CC_SB_SUPPORT_IOT
+
+/**
+* @brief build package for the certificate
+*
+* @param[in] ppCertBuff          - the x509 certificate  in PEM format
+* @param[in] certSize       - certificate size
+* @param[in] certType           - certificate type
+* @param[in] encFlag        - indicates whether images were encrypted
+* @param[in] hbkType        - hbk type to use by target, in the verification
+* @param[in] pAddData       - additional data to add to package
+* @param[in] addDataSize        - length of additional data
+* @param[in] outPkgFile     - package file name to write the package to
+*/
+/*********************************************************/
+int32_t CC_CommonX509BuildCertPkg(uint8_t **ppCertBuff,
+                uint32_t certSize,
+                uint8_t *pAddData,
+                uint32_t addDataSize,
+                uint8_t *outPkgFile)
+{
+    int32_t rc = 0;
+    FILE *fp = NULL;
+    uint8_t *pCertPkg = NULL;
+    uint32_t pkgBytesSize = 0;
+
+    UTIL_LOG_INFO("started\n");
+    /* check inputs */
+    if ((NULL == outPkgFile) ||
+        (NULL == ppCertBuff) || (NULL == *ppCertBuff) ||
+        (0 == certSize) ||
+        (certSize >= CC_X509_MAX_CERT_SIZE) ||
+        ((pAddData != NULL) && (0 == addDataSize)) ||
+        ((NULL == pAddData) && (addDataSize != 0))) {
+        UTIL_LOG_ERR("illegal input\n");
+        rc = (-1);
+        goto END;
+    }
+
+    /* calcultae package size */
+    pkgBytesSize = (certSize + addDataSize + 1); /* Adding 1 for "\0"*/
+
+    UTIL_LOG_INFO("openning certificate pkg file for writing\n");
+    fp = fopen(outPkgFile, "w");
+    if (NULL == fp) {
+        UTIL_LOG_ERR("failed to open %s\n", outPkgFile);
+        rc = (-1);
+        goto END;
+    }
+
+    UTIL_LOG_INFO("about to allocate memory for pkg:size %d, certSize %d, addDataSize %d\n",pkgBytesSize, certSize, addDataSize);
+
+    /* create the package buffer */
+    pCertPkg = (uint8_t *) malloc(pkgBytesSize);
+    if (pCertPkg == NULL){
+        UTIL_LOG_ERR("failed to allocate pkg\n");
+        rc = (-1);
+        goto END;
+    }
+    /* copy additional data to package */
+    if (pAddData != NULL) {
+        memcpy(&pCertPkg[0], pAddData, addDataSize);
+    }
+    /* copy certificate PEM  to package */
+    memcpy(&pCertPkg[addDataSize], *ppCertBuff, certSize);
+
+
+    /* write out the package in binary format  */
+    UTIL_LOG_INFO("writing pkg to file\n");
+    rc = CC_CommonUtilCopyBuffToBinFile(outPkgFile, pCertPkg, pkgBytesSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonUtilCopyBuffToBinFile\n");
+        rc = 1;
+        goto END;
+    }
+    rc = 0;
+    UTIL_LOG_INFO("OK\n");
+
+END:
+    if (fp != NULL){
+        fclose(fp);
+    }
+    if (pCertPkg != NULL) {
+        free(pCertPkg);
+    }
+    return rc;
+}
+
+#else
+/**
+* @brief build package for the certificate
+*
+* @param[in] ppCertBuff          - the x509 certificate  in PEM format
+* @param[in] certSize       - certificate size
+* @param[in] certType           - certificate type
+* @param[in] encFlag        - indicates whether images were encrypted
+* @param[in] hbkType        - hbk type to use by target, in the verification
+* @param[in] pAddData       - additional data to add to package
+* @param[in] addDataSize        - length of additional data
+* @param[in] outPkgFile     - package file name to write the package to
+*/
+/*********************************************************/
+int32_t CC_CommonX509BuildCertPkg(uint8_t **ppCertBuff,
+                uint32_t certSize,
+                CCX509CertType_t certType,
+                uint8_t encFlag,
+                uint8_t hbkType,
+                uint8_t *pAddData,
+                uint32_t addDataSize,
+                uint8_t *outPkgFile)
+{
+    int32_t rc = 0;
+    FILE *fp = NULL;
+    uint8_t *pCertPkg = NULL;
+    uint32_t nextBlockOffset = 0;
+    uint32_t pkgBytesSize = 0;
+
+    UTIL_LOG_INFO("started\n");
+    /* check inputs */
+    if ((NULL == outPkgFile) ||
+        (NULL == ppCertBuff) || (NULL == *ppCertBuff) ||
+        (0 == certSize) ||
+        (certSize >= CC_X509_MAX_CERT_SIZE) ||
+        ((certType <= CC_X509_CERT_TYPE_MIN) || (certType >= CC_X509_CERT_TYPE_MAX)) ||
+        ((pAddData != NULL) && (0 == addDataSize)) ||
+        ((NULL == pAddData) && (addDataSize != 0)) ||
+        (!IS_VALID_ENC_FLAG(encFlag & 0xFF)) ||
+        (!IS_VALID_HBK(hbkType & 0xFF))) {
+        UTIL_LOG_ERR("illegal input\n");
+        rc = (-1);
+        goto END;
+    }
+
+    /* calcultae package size */
+    pkgBytesSize = (sizeof(CCX509PkgHeader_t) + addDataSize);
+
+    UTIL_LOG_INFO("openning certificate pkg file for writing\n");
+    fp = fopen(outPkgFile, "w");
+    if (NULL == fp) {
+        UTIL_LOG_ERR("failed to open %s\n", outPkgFile);
+        rc = (-1);
+        goto END;
+    }
+
+    pkgBytesSize += certSize + 1; /* Adding 1 for "\0"*/
+    UTIL_LOG_INFO("about to allocate memory for pkg:size %d, certSize %d, addDataSize %d\n",pkgBytesSize, certSize, addDataSize);
+
+    /* create the package buffer */
+    pCertPkg = (uint8_t *) malloc(pkgBytesSize);
+    if (pCertPkg == NULL){
+        UTIL_LOG_ERR("failed to allocate pkg\n");
+        rc = (-1);
+        goto END;
+    }
+    nextBlockOffset = sizeof(CCX509PkgHeader_t);
+    /* copy additional data to package */
+    if (pAddData != NULL) {
+        memcpy(&pCertPkg[nextBlockOffset], pAddData, addDataSize);
+        nextBlockOffset += addDataSize;
+    }
+      /* copy certificate PEM  to package */
+    memcpy(&pCertPkg[nextBlockOffset], *ppCertBuff, certSize);
+
+    /* setting pkg header */
+    UTIL_LOG_INFO("setting pkg header\n");
+    ((CCX509PkgHeader_t *)pCertPkg)->pkgToken = CC_X509_CERT_PKG_TOKEN;
+    ((CCX509PkgHeader_t *)pCertPkg)->pkgVer = CC_X509_CERT_PKG_VERSION;
+    ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsWord = 0;
+    ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsBits.certType = certType & 0xFF;
+    ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsBits.imageEnc = encFlag & 0xFF;
+    ((CCX509PkgHeader_t *)pCertPkg)->pkgFlags.pkgFlagsBits.hbkType = hbkType & 0xFF;
+    ((CCX509PkgHeader_t *)pCertPkg)->certInfo.certInfoWord = 0;
+    ((CCX509PkgHeader_t *)pCertPkg)->certInfo.certInfoBits.certOffset = (sizeof(CCX509PkgHeader_t)+addDataSize) & 0xFFFF;
+    ((CCX509PkgHeader_t *)pCertPkg)->certInfo.certInfoBits.certSize = certSize;
+
+
+
+    /* write out the package in binary format  */
+    UTIL_LOG_INFO("writing pkg to file\n");
+    rc = CC_CommonUtilCopyBuffToBinFile(outPkgFile, pCertPkg, pkgBytesSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR("failed to CC_CommonUtilCopyBuffToBinFile\n");
+        rc = 1;
+        goto END;
+    }
+    rc = 0;
+    UTIL_LOG_INFO("OK\n");
+
+END:
+    if (fp != NULL){
+        fclose(fp);
+    }
+    if (pCertPkg != NULL) {
+        free(pCertPkg);
+    }
+    return rc;
+}
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_x509.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_x509.h
new file mode 100644
index 0000000..20b1c14
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_crypto_x509.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _COMMON_CRYPTO_X509_H
+#define _COMMON_CRYPTO_X509_H
+
+#include <stdint.h>
+#include "cc_crypto_x509_defs.h"
+#include "cc_crypto_x509_common_defs.h"
+
+
+typedef struct {
+    uint8_t   setSerialNum;
+    uint32_t  serialNum;
+    uint8_t   setNotBefore;
+    long      notBefore;
+    uint8_t   setNotAfter;
+    long      notAfter;
+    uint8_t   setIssuerName;
+    char      IssuerName[X509_ISSUER_NAME_MAX_STRING_SIZE+1];
+    uint8_t   setSubjectName;
+    char      SubjectName[X509_SUBJECT_NAME_MAX_STRING_SIZE+1];
+}CCX509CertHeaderParamsIn_t;
+
+/**
+* @brief free X509 certificate
+*
+* @param[in/out] ppCertBuff          - x.509 certificate
+*/
+/*********************************************************/
+void CC_CommonX509Free(uint8_t **ppCertBuff);
+
+
+/**
+* @brief Creates X509 certificate and set its header fields
+*
+* @param[in/out] ppCertBuff     - x.509 certificate
+* @param[in] certType           - certificate type
+*/
+/*********************************************************/
+int32_t CC_CommonX509CreateAndSetHeader(uint8_t **ppCertBuff,
+                CCX509CertType_t  certType,CCX509CertHeaderParamsIn_t *pCertHeaderParams);
+
+
+/**
+* @brief Add ASN.1 critical integer extension to X.509V3 certificate
+*
+* @param[in/out] pCertBuff          - x.509 certificate
+* @param[in] certType                 - certificate type
+* @param[in] extType              - extension type
+* @param[in] val              - Extension value
+*/
+/*********************************************************/
+int32_t CC_CommonX509AddIntegerExtension(uint8_t *pCertBuff,
+                       CCX509CertType_t certType,
+                       CCX509ExtType_t  extType,
+                       int32_t val);
+
+
+/**
+* @brief Add critical DER extension to X.509V3 certificate
+*
+* @param[in/out] pCertBuff          - x.509 certificate
+* @param[in] certType                 - certificate tyoes
+* @param[in] extType              - extension type
+* @param[in] pVal                 - Extension data
+* @param[in] valLen               - extension data length
+*/
+/*********************************************************/
+int32_t CC_CommonX509AddStringExtension(uint8_t *pCertBuff,
+                      CCX509CertType_t  certType,
+                      CCX509ExtType_t  extType,
+                      uint8_t *pVal,
+                      uint32_t valLen);
+
+/**
+* @brief Add subject public key to the X509 certificate
+*   and sign the certificate
+*
+* @param[in/out] pCertBuff      - x.509 certificate
+* @param[in] pKeyPairFileName   - key pair file name in PEM format
+* @param[in] pKeyPairPwd    - passphrase of key pair
+*/
+/*********************************************************/
+int32_t CC_CommonX509SetKeyAndSign(uint8_t *pCertBuff,
+                uint8_t *pKeyPairFileName,
+                uint8_t *pKeyPairPwd);
+
+
+
+/**
+* @brief convert the x.509 certificate to DER format
+*
+* @param[in/out] ppCertBuff      - x.509 certificate
+* @param[out] pOutCertSize  - certificate size in DER format
+/*********************************************************/
+int32_t CC_CommonX509ToDer(uint8_t **pCertBuff,
+                uint32_t *pOutCertSize);
+
+
+/**
+* @brief build package for the certificate
+*
+* @param[in] ppCertBuff          - the x509 certificate  in PEM format
+* @param[in] certSize       - certificate size
+* @param[in] certType           - certificate type
+* @param[in] encFlag        - indicates whether images were encrypted
+* @param[in] hbkType        - hbk type to use by target, in the verification
+* @param[in] pAddData       - additional data to add to package
+* @param[in] addDataSize        - length of additional data
+* @param[in] outPkgFile     - package file name to write the package to
+*/
+/*********************************************************/
+#ifdef CC_SB_SUPPORT_IOT
+int32_t CC_CommonX509BuildCertPkg(uint8_t **ppCertBuff,
+                uint32_t certSize,
+                uint8_t *pAddData,
+                uint32_t addDataSize,
+                uint8_t *outPkgFile);
+
+#else
+int32_t CC_CommonX509BuildCertPkg(uint8_t **ppCertBuff,
+                uint32_t certSize,
+                CCX509CertType_t certType,
+                uint8_t encFlag,
+                uint8_t hbkType,
+                uint8_t *pAddData,
+                uint32_t addDataSize,
+                uint8_t *outPkgFile);
+
+#endif
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair.c
new file mode 100644
index 0000000..6055ffa
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_rsa_keypair.h"
+#include "common_util_log.h"
+#include "cc_pka_hw_plat_defs.h"
+
+/**
+ * @brief The CC_CommonGetKeyPair reads RSA private key from the file, along with retrieving the private key,
+ *    it also retrieves the public key.
+ *
+ * The function
+ * 1. Build RSA public key structure
+ * @param[out] pRsaPrivKey - the private key
+ * @param[in] PemEncryptedFileName_ptr - private key file
+ * @param[in] Key_ptr - passphrase string
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonGetKeyPair(RSA **pRsaKeyPair, int8_t *PemEncryptedFileName_ptr, int8_t *Key_ptr)
+{
+    FILE *fp = NULL;
+
+    if (PemEncryptedFileName_ptr == NULL) {
+        UTIL_LOG_ERR("Illegal RSA key pair or pwd file name\n");
+        return -1;
+    }
+
+    fp = fopen (PemEncryptedFileName_ptr, "r");
+    if (fp == NULL) {
+        UTIL_LOG_ERR("Cannot open RSA file %s\n", PemEncryptedFileName_ptr);
+        return -1;
+    }
+
+
+    if ((PEM_read_RSAPrivateKey (fp, pRsaKeyPair, NULL, Key_ptr)) == NULL) {
+        UTIL_LOG_ERR("Cannot read RSA private key\n");
+        ERR_print_errors_fp(stderr);
+        fclose (fp);
+        return -1;
+    }
+
+    fclose (fp);
+    return 0;
+}
+
+/**
+ * @brief The CC_CommonGetPubKey reads RSA public key from the file.
+ *
+ * The function
+ * 1. Build RSA public key structure
+ * @param[out] pRsaPrivKey - the rsa key
+ * @param[in] PemEncryptedFileName_ptr - public key file name
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonGetPubKey(RSA **pRsaKeyPair, int8_t *PemEncryptedFileName_ptr)
+{
+    FILE *fp = NULL;
+
+    if (PemEncryptedFileName_ptr == NULL) {
+        UTIL_LOG_ERR("Illegal RSA file name\n");
+        return -1;
+    }
+
+    fp = fopen (PemEncryptedFileName_ptr, "r");
+    if (fp == NULL) {
+        UTIL_LOG_ERR("Cannot open RSA file %s\n", PemEncryptedFileName_ptr);
+        return -1;
+    }
+
+
+    if ((PEM_read_RSA_PUBKEY(fp, pRsaKeyPair, NULL, NULL)) == NULL) {
+        UTIL_LOG_ERR("Cannot read RSA public key\n");
+        ERR_print_errors_fp(stderr);
+        fclose (fp);
+        return -1;
+    }
+
+    fclose (fp);
+    return 0;
+}
+
+/**
+* @brief The function CC_CommonRsaCalculateNp calculates the Np it returns it as array of ascii's
+*
+* @param[in] N_ptr - public key N, represented as array of ascii's (0xbc is translated
+*                    to 0x62 0x63)
+* @param[out] NP_ptr - The NP result. NP size is NP_SIZE_IN_BYTES*2 + 1
+*
+*/
+/*********************************************************/
+SBUEXPORT_C int32_t CC_CommonRsaCalculateNp(const int8_t *N_ptr,
+                      int8_t *NP_ptr)
+{
+    int8_t *N_Temp = NULL;
+    int32_t  status  = -1;
+    BIGNUM *bn_n = BN_new();
+
+    if ((NULL == N_ptr) || (NULL == NP_ptr)) {
+        UTIL_LOG_ERR("Illegal input\n");
+        goto calcNp_end;
+    }
+
+    /* Copy the N to temporary N, allocate temporary N in N size + 2 */
+    N_Temp= (int8_t *)malloc ((SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2) * sizeof (int8_t));
+    if (NULL == N_Temp) {
+        UTIL_LOG_ERR("failed to malloc.\n");
+        goto calcNp_end;
+    }
+
+    if (NULL == bn_n) {
+        UTIL_LOG_ERR("failed to BN_new.\n");
+        goto calcNp_end;
+    }
+
+    /* set the temporary N to 0 */
+    memset(N_Temp, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2));
+
+    /* Copy the N to temp N */
+    memcpy (N_Temp, N_ptr, SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2);
+
+    if (!BN_hex2bn (&bn_n, N_Temp)) {
+        UTIL_LOG_ERR("BN_hex2bn failed.\n");
+        goto calcNp_end;
+    }
+
+    if (CC_CommonRSACalculateNpInt(bn_n, NP_ptr, NP_HEX) != 0) {
+        UTIL_LOG_ERR("CC_CommonRSACalculateNpInt failed.\n");
+        goto calcNp_end;
+    }
+
+    status = 0;
+
+    calcNp_end:
+    if (N_Temp != NULL) {
+        free(N_Temp);
+    }
+    if (bn_n != NULL) {
+        BN_free (bn_n);
+    }
+    return(status);
+}
+
+/**
+ * @brief The function calculates Np when given N as BIGNUM.
+ *
+ * @param[in] n - modulus as BIGNUM ptr
+ * @param[out] NP_ptr - the Np
+ *
+ */
+/*********************************************************/
+SBUEXPORT_C int32_t CC_CommonRSACalculateNpInt(BIGNUM *n,
+                         uint8_t *NP_ptr,
+                         NP_RESULT_TYPE_t resultType)
+{
+    int32_t len;
+    uint8_t *NP_res = NULL, *NP_resTemp = NULL;
+    int32_t  status  = -1;
+    BN_CTX *bn_ctx = BN_CTX_new();
+
+    BIGNUM *bn_r   = BN_new();
+    BIGNUM *bn_a   = BN_new();
+    BIGNUM *bn_p   = BN_new();
+    BIGNUM *bn_n   = BN_new();
+    BIGNUM *bn_quo = BN_new();
+    BIGNUM *bn_rem = BN_new();
+
+    if ((NULL == n) || (NULL == NP_ptr)) {
+        UTIL_LOG_ERR("Illegal input parameters.\n");
+        goto calcNpInt_end;
+    }
+
+    NP_res = (int8_t*)malloc(NP_SIZE_IN_BYTES);
+    if (NP_res == NULL) {
+        UTIL_LOG_ERR("failed to malloc.\n");
+        goto calcNpInt_end;
+    }
+    if ((NULL == bn_r) ||
+        (NULL == bn_a) ||
+        (NULL == bn_p) ||
+        (NULL == bn_n) ||
+        (NULL == bn_quo) ||
+        (NULL == bn_rem) ||
+        (NULL == bn_ctx)) {
+        UTIL_LOG_ERR("failed to BN_new or BN_CTX_new.\n");
+        goto calcNpInt_end;
+    }
+
+    /* computes a = 2^SNP */
+    BN_set_word (bn_a, 2);
+    BN_set_word (bn_p, SNP);
+    if (!BN_exp (bn_r, bn_a, bn_p, bn_ctx)) {
+        UTIL_LOG_ERR("failed to BN_exp.\n");
+        goto calcNpInt_end;
+    }
+    if (!BN_div (bn_quo, bn_rem, bn_r, n, bn_ctx)) {
+        UTIL_LOG_ERR("failed to BN_div.\n");
+        goto calcNpInt_end;
+    }
+
+    if (resultType == NP_BIN) {
+        len = BN_bn2bin (bn_quo, NP_res);
+
+        /* Set the output with 0 and than copy the result */
+        memset (NP_ptr, 0, NP_SIZE_IN_BYTES);
+        memcpy ((uint8_t *)(NP_ptr + (NP_SIZE_IN_BYTES - len)), (int8_t *)NP_res, len);
+    } else { /* resultType == HEX*/
+        NP_resTemp = BN_bn2hex (bn_quo);
+        if (NP_resTemp == NULL) {
+            UTIL_LOG_ERR("BN_bn2hex failed\n");
+            goto calcNpInt_end;
+        }
+        if (NP_resTemp[0] == '-'){
+            UTIL_LOG_ERR("BN_bn2hex returned negative values\n");
+            goto calcNpInt_end;
+        }
+        len = (int32_t)strlen (NP_resTemp);
+        memcpy(NP_res, NP_resTemp, len);
+
+        /* Set the output with 0 and than copy the result */
+        memset (NP_ptr, 0, (NP_SIZE_IN_BYTES * 2 + 2));
+        memcpy ((int8_t *)(NP_ptr + (NP_SIZE_IN_BYTES * 2 + 2 - len)), (int8_t *)NP_res, len);
+    }
+
+    status = 0;
+
+    calcNpInt_end:
+    if (NP_res != NULL) {
+        free(NP_res);
+    }
+    if (bn_r != NULL) {
+        BN_free (bn_r);
+    }
+    if (bn_a != NULL) {
+        BN_free (bn_a);
+    }
+    if (bn_p != NULL) {
+        BN_free (bn_p);
+    }
+    if (bn_n != NULL) {
+        BN_free (bn_n);
+    }
+    if (bn_quo != NULL) {
+        BN_free (bn_quo);
+    }
+    if (bn_rem != NULL) {
+        BN_free (bn_rem);
+    }
+    if (bn_ctx != NULL) {
+        BN_CTX_free(bn_ctx);
+    }
+    if (NP_resTemp != NULL){
+        OPENSSL_free(NP_resTemp);
+    }
+    return(status);
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair.h
new file mode 100644
index 0000000..78920b8
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _COMMON_RSA_KEYPAIR_H
+#define _COMMON_RSA_KEYPAIR_H
+
+#include <stdint.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include "cc_pka_hw_plat_defs.h"
+
+#ifdef WIN32
+#define SBUEXPORT_C __declspec(dllexport)
+#else
+#define SBUEXPORT_C
+#endif
+
+typedef enum NP_RESULT_TYPE {
+    NP_BIN = 0,
+    NP_HEX = 1
+}NP_RESULT_TYPE_t;
+
+
+/* Global defines */
+#define RSA_PRIVATE_KEY_SIZE     SB_CERT_RSA_KEY_SIZE_IN_BITS
+#define NP_SIZE_IN_BYTES         20
+#define NEW_PKA_WORD_SIZE_BITS   CC_PKA_WORD_SIZE_IN_BITS
+#define NEW_PAK_ADDITIONAL_BITS  8
+#define SNP                      SB_CERT_RSA_KEY_SIZE_IN_BITS + NEW_PKA_WORD_SIZE_BITS + NEW_PAK_ADDITIONAL_BITS -1
+
+
+/**
+ * @brief The CC_CommonGetKeyPair reads RSA private key from the file, along with retrieving the private key,
+ *    it also retrieves the public key.
+ *
+ * The function
+ * 1. Build RSA public key structure
+ * @param[out] pRsaPrivKey - the private key
+ * @param[in] PemEncryptedFileName_ptr - private key file
+ * @param[in] Key_ptr - passphrase string
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonGetKeyPair (RSA **pRsaKeyPair, int8_t *PemEncryptedFileName_ptr, int8_t *Key_ptr);
+
+/**
+ * @brief The CC_CommonGetPubKey reads RSA public key from the file.
+ *
+ * The function
+ * 1. Build RSA public key structure
+ * @param[out] pRsaPrivKey - the rsa key
+ * @param[in] PemEncryptedFileName_ptr - public key file name
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonGetPubKey (RSA **pRsaKeyPair, int8_t *PemEncryptedFileName_ptr);
+
+/**
+ * @brief The function calculates Np when given N as hex data.
+ *
+ * @param[in] n - modulus as hex data
+ * @param[out] NP_ptr - the Np
+ *
+ */
+/*********************************************************/
+SBUEXPORT_C int32_t CC_CommonRsaCalculateNp(const int8_t* N_ptr,
+                      int8_t *NP_ptr);
+
+
+/**
+ * @brief The function calculates Np when given N as BIGNUM.
+ *
+ * @param[in] n - modulus as BIGNUM ptr
+ * @param[out] NP_ptr - the Np
+ *
+ */
+/*********************************************************/
+SBUEXPORT_C int32_t CC_CommonRSACalculateNpInt(BIGNUM *n,
+                         uint8_t *NP_ptr,
+                         NP_RESULT_TYPE_t resultType);
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair_util.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair_util.c
new file mode 100644
index 0000000..e4503ec
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair_util.c
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include <openssl/rsa.h>
+#include "common_rsa_keypair_util.h"
+#include "common_util_files.h"
+#include "common_util_log.h"
+#include "common_crypto_sym.h"
+#include "cc_pka_hw_plat_defs.h"
+#define RSA_OAEP_KEY_SIZE_IN_BITS 2048UL //temp -RC
+#define RSA_OAEP_KEY_SIZE_IN_BYTES (RSA_OAEP_KEY_SIZE_IN_BITS/8) //temp -RC
+
+/************************************* Globals  *************************************/
+
+uint8_t gNp[NP_SIZE_IN_BYTES] = {0};
+DxRsaKeyNandNp_t gNAndNp = {0};
+uint8_t gN[SB_CERT_RSA_KEY_SIZE_IN_BYTES +1] = {0};
+
+
+/**
+* @brief The function reads RSA key from the file and returns its N and Np.
+*
+* @param[in] PemEncryptedFileName_ptr - file name of the key pair
+* @param[in] pwdFileName - file name of the password
+* @param[out] pNbuff - N  buffer
+* @param[in/out] pNbuffSize - as input - max size of pNbuff
+*                              as output - actual size of pNbuff
+*/
+/*********************************************************/
+int32_t CC_CommonGetNbuffFromKeyPair(int8_t *PemEncryptedFileName_ptr, int8_t *pwdFileName, uint8_t *pNbuff, uint32_t *pNbuffSize)
+{
+
+    int32_t status = -1;
+    uint8_t *pwd = NULL;
+    RSA *rsa_pkey = NULL;
+    int32_t i;
+
+    if ((NULL == pNbuff) ||
+        (NULL == pNbuffSize) ||
+        (NULL == PemEncryptedFileName_ptr)) {
+        return status;
+    }
+    if (*pNbuffSize != SB_CERT_RSA_KEY_SIZE_IN_BYTES) {
+        return status;
+    }
+
+    /* parse the passphrase for a given file */
+    if ((NULL != pwdFileName)) {
+        if (CC_CommonGetPassphrase(pwdFileName, &pwd) != 0) {
+            UTIL_LOG_ERR("Failed to retrieve pwd\n");
+            goto END;
+        }
+        }
+
+    rsa_pkey = RSA_new();
+    if (NULL == rsa_pkey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto END;
+    }
+    if (CC_CommonGetKeyPair (&rsa_pkey, PemEncryptedFileName_ptr, pwd) != 0) {
+        UTIL_LOG_ERR("Cannot read RSA public key.\n");
+        goto END;
+    }
+
+    /* get the modulus from BIGNUM to uint8_t* */
+    BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
+    UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+
+    /* copy the Np to the end of N */
+    memcpy(pNbuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    *pNbuffSize = SB_CERT_RSA_KEY_SIZE_IN_BYTES;
+    status = 0;
+
+
+    END:
+    if (rsa_pkey != NULL) {
+        RSA_free(rsa_pkey);
+    }
+    if (pwd != NULL) {
+        free(pwd);
+    }
+    return status;
+}
+
+
+
+/**
+* @brief The function reads RSA key from the file and returns its N and Np.
+*
+* @param[in] PemEncryptedFileName_ptr - file name of the key pair
+* @param[in] pwdFileName - file name of the password
+* @param[out] pNAndNp - N and Np buffer
+* @param[in/out] pNAndNpSize - as input - max size of pNAndNp
+*                              as output - actual size of pNAndNp
+*/
+/*********************************************************/
+int32_t CC_CommonGetNAndNpFromKeyPair(int8_t *PemEncryptedFileName_ptr, int8_t *pwdFileName, uint8_t *pNAndNp, uint32_t *pNAndNpSize)
+{
+
+    int32_t status = -1;
+    uint8_t *pwd = NULL;
+    RSA *rsa_pkey = NULL;
+    DxRsaKeyNandNp_t *pNandNpBuff = (DxRsaKeyNandNp_t *)pNAndNp;
+    int32_t i;
+
+    if ((NULL == pNAndNp) ||
+        (NULL == pNAndNpSize) ||
+        (NULL == PemEncryptedFileName_ptr)) {
+        return status;
+    }
+    if (*pNAndNpSize != sizeof(DxRsaKeyNandNp_t)) {
+        return status;
+    }
+
+    /* parse the passphrase for a given file */
+    if ((NULL != pwdFileName)) {
+        if (CC_CommonGetPassphrase(pwdFileName, &pwd) != 0) {
+            UTIL_LOG_ERR("Failed to retrieve pwd %s\n", pwdFileName);
+            goto END;
+        }
+    }
+
+    rsa_pkey = RSA_new();
+
+    if (NULL == rsa_pkey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto END;
+    }
+    if (CC_CommonGetKeyPair (&rsa_pkey, PemEncryptedFileName_ptr, pwd)  != 0) {
+        UTIL_LOG_ERR("Cannot read RSA public key.\n");
+        goto END;
+    }
+
+    /* get the modulus from BIGNUM to uint8_t* */
+    BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
+
+    /* calculate the Np, and get the output as BIGNUM*/
+    if (CC_CommonRSACalculateNpInt(rsa_pkey->n, gNp, NP_BIN)) {
+        UTIL_LOG_ERR("Failed creating Np\n");
+        goto END;
+    }
+
+    /* copy the Np to the end of N */
+    memcpy(pNandNpBuff->pNBuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    memcpy(pNandNpBuff->pNpBuff, gNp, NP_SIZE_IN_BYTES);
+    *pNAndNpSize = (SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES);
+    UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
+    status = 0;
+
+
+    END:
+    if (rsa_pkey != NULL) {
+        RSA_free(rsa_pkey);
+    }
+    if (pwd != NULL) {
+        free(pwd);
+    }
+    return status;
+}
+
+
+
+/**
+* @brief The function reads RSA key from the file and returns its N and Np.
+*
+* @param[in] pubKeyFileName_ptr - file name of the key pair
+* @param[out] pNAndNp - N and Np buffer
+* @param[in/out] pNAndNpSize - as input - max size of pNAndNp
+*                              as output - actual size of pNAndNp
+*/
+/*********************************************************/
+int32_t CC_CommonGetNAndNpFromPubKey(int8_t *pubKeyFileName_ptr, uint8_t *pNAndNp, uint32_t *pNAndNpSize)
+{
+    int32_t status = -1;
+    int32_t i;
+    RSA *rsa_pkey = NULL;
+    DxRsaKeyNandNp_t *pNandNpBuff = (DxRsaKeyNandNp_t *)pNAndNp;
+
+    if ((NULL == pNAndNp) ||
+        (NULL == pNAndNpSize) ||
+        (NULL == pubKeyFileName_ptr)) {
+        return status;
+    }
+    if (*pNAndNpSize != sizeof(DxRsaKeyNandNp_t)) {
+        return status;
+    }
+    rsa_pkey = RSA_new();
+    if (NULL == rsa_pkey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto END;
+    }
+    if (CC_CommonGetPubKey (&rsa_pkey, pubKeyFileName_ptr) < 0) {
+        UTIL_LOG_ERR("Cannot read RSA public key.\n");
+        goto END;
+    }
+
+    /* get the modulus from BIGNUM to uint8_t* */
+    BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
+
+    /* calculate the Np, and get the output as BIGNUM*/
+    if (CC_CommonRSACalculateNpInt(rsa_pkey->n, gNp, NP_BIN) != 0) {
+        UTIL_LOG_ERR("Failed creating Np\n");
+        goto END;
+    }
+
+    /* copy the Np to the end of N */
+    memcpy(pNandNpBuff->pNBuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    memcpy(pNandNpBuff->pNpBuff, gNp, NP_SIZE_IN_BYTES);
+    *pNAndNpSize = (SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES);
+    UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
+    status = 0;
+
+    END:
+    if (rsa_pkey != NULL) {
+        RSA_free(rsa_pkey);
+    }
+    return status;
+}
+
+
+/**
+* @brief The CC_CommonCalcHBKFromBuff calculates Np from given pNbuff.
+*        Then calculates HASH both N and Np
+*
+* @param[in] pNBuff - the N - modulus buff
+* @param[out] pHash - hash output
+* @param[in] hashSize - hash output size
+*/
+/*********************************************************/
+int32_t CC_CommonCalcHBKFromBuff(int8_t* pNBuff, uint8_t *pHash, int32_t hashSize)
+{
+
+    int32_t status = -1;
+    int32_t i;
+    BIGNUM *bn_n = NULL;
+
+    memcpy((uint8_t *)&gNAndNp, pNBuff, RSA_OAEP_KEY_SIZE_IN_BYTES);
+    UTIL_LOG_BYTE_BUFF("gN", (uint8_t *)&gNAndNp, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+
+    /* calculate the Np */
+    bn_n = BN_bin2bn(pNBuff, SB_CERT_RSA_KEY_SIZE_IN_BYTES, bn_n);
+    if (NULL == bn_n) {
+        UTIL_LOG_ERR ("BN_bin2bn failed\n");
+        return -1;
+    }
+
+    if (CC_CommonRSACalculateNpInt(bn_n, gNp, NP_BIN) != 0) {
+        UTIL_LOG_ERR ("BN_bin2bn failed\n");
+        goto END;
+    }
+    UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
+
+    /* copy the Np to the end of N and calc hash on both */
+    memcpy(gNAndNp.pNpBuff, gNp, NP_SIZE_IN_BYTES);
+
+    /* write hash*/
+    /* calculate hash and write to */
+    if (CC_CommonCalcHash((uint8_t *)&gNAndNp, sizeof(gNAndNp), pHash, hashSize) != 0) {
+        UTIL_LOG_ERR ("Common_CalcHashOnPubKey failed\n");
+        goto END;
+    }
+
+    /* write hash*/
+    status = 0;
+
+    END:
+    if (bn_n != NULL) {
+        BN_free(bn_n);
+    }
+    return status;
+}
+
+/**
+* @brief The CC_CommonCalcHBKFromFile reads RSA key from the file using passphrase
+*        and returns its decrypted value.
+*
+* @param[in] pubKeyFileName_ptr - file name of the public key
+* @param[out] pHash - hash output
+* @param[in] hashSize - hash output size
+*/
+/*********************************************************/
+int32_t CC_CommonCalcHBKFromFile(int8_t* pubKeyFileName_ptr, uint8_t *pHash, int32_t hashSize)
+{
+
+    int32_t status = -1;
+    int32_t i;
+    RSA *rsa_pkey = NULL;
+
+    rsa_pkey = RSA_new();
+    if (NULL == rsa_pkey) {
+        UTIL_LOG_ERR("Failed RSA_new\n");
+        goto END;
+    }
+    if (CC_CommonGetPubKey (&rsa_pkey, pubKeyFileName_ptr) != 0) {
+        UTIL_LOG_ERR("Cannot read RSA public key\n");
+        goto END;
+    }
+
+    /* get the modulus from BIGNUM to uint8_t* */
+    BN_bn2bin(rsa_pkey->n, (uint8_t *)gN);
+    UTIL_LOG_BYTE_BUFF("gN", gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+
+    /* calculate the Np, and get the output as BIGNUM*/
+    if (CC_CommonRSACalculateNpInt(rsa_pkey->n, gNp, NP_BIN) != 0) {
+        UTIL_LOG_ERR("Failed creating Np\n");
+        goto END;
+    }
+    UTIL_LOG_BYTE_BUFF("gNp", gNp, NP_SIZE_IN_BYTES);
+
+    /* copy the Np to the end of N and calc hash on both */
+    memcpy(gNAndNp.pNBuff, gN, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    memcpy(gNAndNp.pNpBuff, gNp, NP_SIZE_IN_BYTES);
+    /* write hash*/
+
+    /* calculate hash and write to */
+    if (CC_CommonCalcHash((uint8_t *)&gNAndNp, SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES, pHash, hashSize) != 0) {
+        UTIL_LOG_ERR ("Common_CalcHashOnPubKey failed\n");
+        goto END;
+    }
+
+    /* write hash*/
+    status = 0;
+
+    END:
+    if (rsa_pkey != NULL) {
+        RSA_free(rsa_pkey);
+    }
+    return status;
+}
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair_util.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair_util.h
new file mode 100644
index 0000000..9f4f1a0
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_rsa_keypair_util.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _COMMON_RSA_KEYPAIR_UTIL_H
+#define _COMMON_RSA_KEYPAIR_UTIL_H
+
+#include <stdint.h>
+
+#include "common_rsa_keypair.h"
+#include "cc_pka_hw_plat_defs.h"
+
+typedef struct {
+    uint8_t pNBuff[SB_CERT_RSA_KEY_SIZE_IN_BYTES];
+    uint8_t pNpBuff[NP_SIZE_IN_BYTES];
+}DxRsaKeyNandNp_t;
+
+/**
+* @brief The function reads RSA key from the file and returns its N and Np.
+*
+* @param[in] PemEncryptedFileName_ptr - file name of the key pair
+* @param[in] pwdFileName - file name of the password
+* @param[out] pNbuff - N  buffer
+* @param[in/out] pNbuffSize - as input - max size of pNbuff
+*                              as output - actual size of pNbuff
+*/
+/*********************************************************/
+int32_t CC_CommonGetNbuffFromKeyPair(int8_t *PemEncryptedFileName_ptr, int8_t *pwdFileName, uint8_t *pNbuff, uint32_t *pNbuffSize);
+
+/**
+* @brief The function reads RSA key from the file and returns its N and Np.
+*
+* @param[in] PemEncryptedFileName_ptr - file name of the key pair
+* @param[in] pwdFileName - file name of the password
+* @param[out] pNAndNp - N and Np buffer
+* @param[in/out] pNAndNpSize - as input - max size of pNAndNp
+*                              as output - actual size of pNAndNp
+*/
+/*********************************************************/
+int32_t CC_CommonGetNAndNpFromKeyPair(int8_t *PemEncryptedFileName_ptr, int8_t *pwdFileName, uint8_t *pNAndNp, uint32_t *pNAndNpSize);
+
+
+/**
+* @brief The function reads RSA key from the file and returns its N and Np.
+*
+* @param[in] pubKeyFileName_ptr - file name of the key pair
+* @param[out] pNAndNp - N and Np buffer
+* @param[in/out] pNAndNpSize - as input - max size of pNAndNp
+*                              as output - actual size of pNAndNp
+*/
+/*********************************************************/
+int32_t CC_CommonGetNAndNpFromPubKey(int8_t *pubKeyFileName_ptr, uint8_t *pNAndNp, uint32_t *pNAndNpSize);
+
+
+/**
+* @brief The CC_CommonCalcHBKFromFile reads RSA key from the file using passphrase
+*        and returns its decrypted value.
+*
+* @param[in] pubKeyFileName_ptr - file name of the public key
+* @param[out] pHash - hash output
+* @param[in] hashSize - hash output size
+*/
+/*********************************************************/
+int32_t CC_CommonCalcHBKFromFile(int8_t* pubKeyFileName_ptr, uint8_t *pHash, int32_t hashSize);
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_sb_ops.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_sb_ops.c
new file mode 100644
index 0000000..d3e9b74
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_sb_ops.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include "common_sb_ops.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_rsa_keypair.h"
+#include "common_rsa_keypair_util.h"
+#include "common_crypto_asym.h"
+#include "common_util_log.h"
+#include "cc_crypto_defs.h"
+#include "cc_pka_hw_plat_defs.h"
+
+/**
+ * @brief The Sign_v15 generates RSA signature using PKCS#1 v1.5 algorithm.
+ *
+ * The function
+ * 1. Create RSA signature
+ * 2. Verify the signature correctness
+ * @param[in] pRsaPrivKey - the private key
+ * @param[in] DataIn_ptr - the data to sign on
+ * @param[in] DataInSize - the data size
+ * @param[in] Key_ptr - passphrase string
+ * @param[out] Signature_ptr - the RSA signature
+ *
+ */
+ /*********************************************************/
+int Sign_v15(RSA *pRsaPrivKey, char *DataIn_ptr,  // IG - merge with common implementation
+             int DataInSize, char *Signature_ptr,
+             char *Key_ptr)
+{
+    RSA *pRsaPubKey    = NULL;
+    BIO *bio           = NULL;
+    int status         = -1;
+    EVP_PKEY *pKey     = NULL;
+    EVP_MD_CTX *md_ctx = NULL;
+    int SignatureSize  = SB_CERT_RSA_KEY_SIZE_IN_BYTES;
+
+    /*EVP_PKEY_new() allocates an empty EVP_PKEY structure which
+        is used by OpenSSL to store private keys.*/
+    pKey = EVP_PKEY_new();
+    /*set the referenced key to key*/
+    if (!EVP_PKEY_assign_RSA(pKey, pRsaPrivKey))
+        SIGN_RELEASE("EVP_PKEY_assign_RSA Private key")
+
+    /* fill and sign on the HASH output */
+    md_ctx = EVP_MD_CTX_create();
+    /* initializes a signing context to use the default implementation of digest type.*/
+    if (!EVP_SignInit(md_ctx, EVP_sha256()))
+        SIGN_RELEASE("EVP_SignInit")
+    /*hash data into the signature */
+    if (!EVP_SignUpdate(md_ctx, DataIn_ptr, DataInSize))
+        SIGN_RELEASE("EVP_SignUpdate")
+    /*signs the data using the private key pkey and places the signature*/
+    if (!EVP_SignFinal(md_ctx, Signature_ptr, &SignatureSize, pKey))
+        SIGN_RELEASE("EVP_SignFinal")
+
+    // Create public key
+    bio = BIO_new(BIO_s_mem());
+    pRsaPubKey = RSA_new();
+    if (!PEM_write_bio_RSA_PUBKEY(bio, pRsaPrivKey))
+        SIGN_RELEASE("PEM_write_bio_RSA_PUBKEY")
+
+    if (PEM_read_bio_RSA_PUBKEY(bio,&pRsaPubKey,NULL,Key_ptr) == NULL)
+        SIGN_RELEASE("PEM_read_bio_RSA_PUBKEY")
+
+    if (!EVP_PKEY_assign_RSA(pKey, pRsaPubKey))
+        SIGN_RELEASE("EVP_PKEY_assign_RSA Public key")
+    /* initializes verification context ctx to use the default implementation of digest type*/
+    if (!EVP_VerifyInit(md_ctx, EVP_sha256()))
+        SIGN_RELEASE("EVP_VerifyInit")
+    /*hashes bytes of data into the verification context*/
+    if (!EVP_VerifyUpdate(md_ctx, DataIn_ptr, DataInSize))
+        SIGN_RELEASE("EVP_VerifyUpdate")
+    /*verifies the data in, using the public.*/
+    if (!EVP_VerifyFinal(md_ctx, Signature_ptr, SignatureSize, pKey))
+        SIGN_RELEASE("EVP_VerifyFinal")
+
+    status = 0;
+
+    SIGN_RELEASE("")
+}
+
+
+/**
+ * @brief The Sign_v21 generates RSA signature using PKCS#1 v2.1 algorithm.
+ *
+ * The function
+ * 1. Create RSA signature
+ * 2. Verify the signature correctness
+ * @param[in] pRsaPrivKey - the private key
+ * @param[in] DataIn_ptr - the data to sign on
+ * @param[in] DataInSize - the data size
+ * @param[out] Signature_ptr - the RSA signature
+ *
+ */
+ /*********************************************************/
+int Sign_v21(RSA *pRsaPrivKey, char *DataIn_ptr,
+             int DataInSize, char *Signature_ptr)
+{
+    unsigned char pDigest[HASH_SHA256_DIGEST_SIZE_IN_BYTES];
+    unsigned int uDigestLen = HASH_SHA256_DIGEST_SIZE_IN_BYTES;
+    EVP_MD_CTX md_ctx;
+    unsigned char EM[SB_CERT_RSA_KEY_SIZE_IN_BYTES];
+    unsigned char pDecrypted[SB_CERT_RSA_KEY_SIZE_IN_BYTES];
+    int status = -1;
+
+   /* hash the message */
+    EVP_MD_CTX_init(&md_ctx);
+    EVP_DigestInit(&md_ctx, EVP_sha256());
+    EVP_DigestUpdate(&md_ctx, (const void*) DataIn_ptr, DataInSize);
+    EVP_DigestFinal(&md_ctx, pDigest, &uDigestLen);
+    EVP_MD_CTX_cleanup(&md_ctx);
+
+    /* compute the PSS padded data */
+    if (!RSA_padding_add_PKCS1_PSS(pRsaPrivKey, EM, pDigest, EVP_sha256(), RSA_SALT_LEN))
+        SIGN21_RELEASE("RSA_padding_add_PKCS1_PSS")
+
+    /* perform digital signature */
+    if (RSA_private_encrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, EM, Signature_ptr, pRsaPrivKey, RSA_NO_PADDING) == -1)
+        SIGN21_RELEASE("RSA_private_encrypt")
+
+    /* verify the data */
+    if (RSA_public_decrypt(SB_CERT_RSA_KEY_SIZE_IN_BYTES, Signature_ptr, pDecrypted, pRsaPrivKey, RSA_NO_PADDING) == -1)
+        SIGN21_RELEASE("RSA_public_decrypt")
+
+    if (RSA_verify_PKCS1_PSS(pRsaPrivKey, pDigest, EVP_sha256(), pDecrypted, RSA_SALT_LEN) != 1)
+        SIGN21_RELEASE("RSA_verify_PKCS1_PSS")
+
+    status = 0;
+
+    SIGN21_RELEASE("")
+}
+
+
+void reverseBuff( uint8_t *pBuff , uint32_t size )
+{
+    uint32_t i;
+    uint32_t temp;
+
+    for( i = 0 ; i < (size / 2) ; i++ )
+    {
+        temp = pBuff[i];
+        pBuff[i] = pBuff[size - i - 1];
+        pBuff[size - i - 1] = temp;
+    }
+
+    return;
+
+}/* END OF UTIL_ReverseBuff */
+
+
+/**
+* @brief The function SBU_GetNFromKeyPairAndCalcH Reads RSA key from the file using passphrase,
+*       and returns its decrypted value and its calculated Hash
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] pwdFileName - file name of the password
+* @param[out] PemDecryted - N buffer
+* @param[out] H_ptr - The H result. H size is N_SIZE_IN_BYTES*2 + 1
+*
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetNFromKeyPairAndCalcH(char* PemEncryptedFileName_ptr, char *pwdFileName, char *N_ptr, char *H_ptr)
+{
+    char *H_res = NULL, *N_Temp = NULL, *H_resTemp = NULL;
+    int len, i;
+    int status = -1;
+    unsigned long s = SB_CERT_RSA_KEY_SIZE_IN_BITS + 2;
+    int rc = 0;
+    int nSize = SB_CERT_RSA_KEY_SIZE_IN_BYTES;
+    unsigned char *pwdPtr = NULL;
+
+    if( strlen(pwdFileName) )
+        pwdPtr = pwdFileName;
+    else
+        pwdPtr = Nullptr;
+
+    OpenSSL_add_all_algorithms ();
+
+    /* get N  buffer */
+    rc = CC_CommonGetNbuffFromKeyPair(PemEncryptedFileName_ptr, pwdPtr, N_ptr, &nSize);
+    EVP_cleanup();
+    CRYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+    if (rc != 0) {
+        printf( "failed to CC_CommonGetNbuffFromKeyPair %d \n", rc);
+        return rc;
+    }
+
+    BN_CTX *bn_ctx = BN_CTX_new();
+
+    BIGNUM *bn_two   = BN_new();
+    BIGNUM *bn_twos  = BN_new();
+    BIGNUM *bn_n     = BN_new();
+    BIGNUM *bn_h     = BN_new();
+
+    if ((NULL == N_ptr) || ( NULL == H_ptr))
+        CALCULATE_H_RELEASE("SBU_RSA_CalculateH: Illegal input parameters.")
+
+    /* Copy the N to temporary N, allocate temporary N in N size + 2 */
+    N_Temp= (char *)malloc ((SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2) * sizeof (char));
+
+    /* If malloc failed return error */
+    if (NULL == N_Temp)
+        CALCULATE_H_RELEASE("Error during memory allocation.")
+
+    /* set the temporary N to 0 */
+    memset (N_Temp, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2));
+
+    /* Copy the N to temp N */
+    memcpy (N_Temp, N_ptr, SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2);
+
+    /* Allocate the output buffer */
+    if (NULL == (H_res = (char *)malloc ((SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2) * sizeof (char))))
+        CALCULATE_H_RELEASE("Error during memory allocation.")
+
+    BN_set_word (bn_two, 2);
+    BN_set_word (bn_twos, 2 * s);
+
+    bn_n = BN_bin2bn(N_ptr, SB_CERT_RSA_KEY_SIZE_IN_BYTES, bn_n);
+    if (NULL == bn_n)
+        CALCULATE_H_RELEASE("BN_bin2bn failed.")
+
+    if (!BN_mod_exp (bn_h, bn_two, bn_twos, bn_n, bn_ctx))
+        CALCULATE_H_RELEASE("BN_mod_exp failed.")
+
+    H_resTemp = BN_bn2hex (bn_h);
+    if (H_resTemp == NULL)
+        CALCULATE_H_RELEASE("BN_bn2hex failed.")
+    if (H_resTemp[0] == '-'){
+        CALCULATE_H_RELEASE("BN_bn2hex failed.")
+    }
+
+    len = (int)strlen (H_resTemp);
+    memcpy(H_res, H_resTemp, len);
+
+    if (len < SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2)
+    {
+        memmove (H_res + (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 - len), H_res, len + 1);
+        for (i = 0; i < (int)(SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 - len); i++)
+            H_res[i] = '0';
+    }
+
+    /* Set the output with 0 and than copy the result */
+    memset (H_ptr, 0, (SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2));
+    memcpy ((char *)H_ptr, (char *)H_res, SB_CERT_RSA_KEY_SIZE_IN_BYTES * 2 + 2);
+
+    status = 0;
+
+    CALCULATE_H_RELEASE("")
+}
+
+/**
+* @brief The SBU_RAND_Bytes reads RSA key from the file using passphrase
+*        and returns its decrypted value.
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] Key_ptr - passphrase
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_RAND_Bytes(int numBytes, char *buf)
+{
+    int result = -1;
+
+    if (numBytes > 0)
+    {
+        result = RAND_bytes (buf, numBytes);
+        if (result <= 0)
+            printf ("\nSBU_RAND_Bytes - Internal error: Function RAND_bytes failed\n");
+    }
+    return result;
+}
+
+
+/**
+* @brief Reads RSA key from the file using passphrase, and returns its decrypted value and its Np
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] pwdFileName - file name of the password
+* @param[out] PemDecryted - N and Np buffer
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetNAndNpFromKeyPair(char* PemEncryptedFileName_ptr, char *pwdFileName, char *PemDecryted)
+{
+    int rc = 0;
+    int nAndNpSize = SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES;
+    unsigned char *pwdPtr = NULL;
+
+    if( strlen(pwdFileName) )
+        pwdPtr = pwdFileName;
+    else
+        pwdPtr = Nullptr;
+
+    OpenSSL_add_all_algorithms ();
+
+    /* get N and Np buffer */
+    rc = CC_CommonGetNAndNpFromKeyPair(PemEncryptedFileName_ptr, pwdPtr, PemDecryted, &nAndNpSize);
+    if (rc != 0) {
+        printf( "failed to CC_CommonGetNAndNpFromKeyPair %d or ilegal size %d\n", rc, nAndNpSize);
+    }
+
+    EVP_cleanup();
+    CRYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+
+    return rc;
+}
+
+
+/**
+* @brief Reads RSA key from the file using passphrase, and returns its decrypted value and its Np
+*
+* @param[in] PemEncryptedFileName_ptr - public key file name
+* @param[out] PemDecryted - N and Np buffer
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetNAndNpFromPubKey(char* PemEncryptedFileName_ptr, char *PemDecryted)
+{
+    int rc = 0;
+    int nAndNpSize = SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES;
+
+    OpenSSL_add_all_algorithms ();
+
+    /* get N and Np buffer */
+    rc = CC_CommonGetNAndNpFromPubKey(PemEncryptedFileName_ptr, PemDecryted, &nAndNpSize);
+    if (rc != 0) {
+        printf( "failed to CC_CommonGetNAndNpFromPubKey %d or ilegal size %d\n", rc, nAndNpSize);
+    }
+
+    EVP_cleanup();
+    CRYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+
+    return rc;
+}
+
+
+/**
+* @brief Reads RSA public key from the file and returns its raw value and its Np
+*
+* @param[in] pPemFileName_ptr - file name
+* @param[out] pNAndNp - N and Np buffer
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetHashOfNAndNpFromPubKey(char* pPemFileName_ptr, char *pHash, int hashSize)
+{
+    int rc = 0;
+
+    OpenSSL_add_all_algorithms ();
+
+    rc = CC_CommonCalcHBKFromFile(pPemFileName_ptr, pHash, hashSize);
+    if (rc != 0) {
+        printf( "failed to CC_CommonCalcHBKFromFile %d or ilegal size %d\n", rc, hashSize);
+    }
+
+    EVP_cleanup();
+    CRYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+
+    return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_sb_ops.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_sb_ops.h
new file mode 100644
index 0000000..a746fa6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_sb_ops.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef _COMMON_SB_OPS_H
+#define _COMMON_SB_OPS_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_rsa_keypair.h"
+#include "common_crypto_asym.h"
+#include "common_util_log.h"
+#include "cc_crypto_defs.h"
+#include "cc_pka_hw_plat_defs.h"
+
+/* Global defines */
+#define Nullptr (void *)0
+#define SIZE_OF_DATA_FOR_DERIVATION 22
+
+/**
+ * @brief The SIGN_RELEASE releases the allocated memory from the sign operation.
+ */
+
+#define SIGN_RELEASE(fname) \
+{\
+    if (status < 0) \
+        printf("\n%s failed.\n", fname); \
+    if (pRsaPubKey) \
+        RSA_free (pRsaPubKey); \
+    if (bio) \
+        BIO_free (bio); \
+    if (md_ctx) \
+        EVP_MD_CTX_destroy(md_ctx); \
+    return (status); \
+}
+
+#define SIGN21_RELEASE(fname) \
+{\
+    if (status < 0) \
+        printf("\n%s failed.\n", fname); \
+    if (pRsaPrivKey) \
+        RSA_free (pRsaPrivKey); \
+    return (status); \
+}
+/**
+ * @brief The RSA_LOADKEY_RELEASE releases the allocated memory from the loading key operation.
+ */
+#define RSA_LOADKEY_RELEASE(msg) \
+{\
+    if(status < 0) \
+        printf("\n%s\n", msg); \
+    if (rsa_pkey) \
+        RSA_free (rsa_pkey); \
+    if (out) \
+        BIO_free (out); \
+    return status; \
+}
+
+/**
+ * @brief The CALCULATE_NP_RELEASE releases the allocated memory from the Np calculation operation.
+ */
+#define CALCULATE_NP_RELEASE(msg) \
+{\
+    if(status < 0) \
+        printf("\n%s\n", msg); \
+    if (N_Temp) \
+        free(N_Temp); \
+    if(NP_res) \
+        free(NP_res); \
+    BN_free (bn_r); \
+    BN_free (bn_a); \
+    BN_free (bn_p); \
+    BN_free (bn_n); \
+    BN_free (bn_quo); \
+    BN_free (bn_rem); \
+    return (status); \
+}
+
+/**
+ * @brief The CALCULATE_H_RELEASE releases the allocated memory from the H calculation operation.
+ */
+#define CALCULATE_H_RELEASE(msg) \
+{\
+    if(status < 0) \
+        printf("\n%s\n", msg); \
+    if (N_Temp) \
+        free(N_Temp); \
+    if(H_res) \
+        free(H_res); \
+    if (H_resTemp) \
+        OPENSSL_free(H_resTemp); \
+    BN_free (bn_two); \
+    BN_free (bn_twos); \
+    BN_free (bn_n); \
+    BN_free (bn_h); \
+    return (status); \
+}
+
+#define MAX_IMAGE_CHUNK (1024)  // 1K byte
+
+#ifdef USE_CONST_N
+char N_Const[] =
+{
+    0x64, 0x39, 0x34, 0x38, 0x36, 0x66, 0x65, 0x34, 0x38, 0x64, 0x62, 0x34, 0x32, 0x34, 0x32, 0x36,
+    0x62, 0x38, 0x64, 0x37, 0x37, 0x65, 0x62, 0x30, 0x30, 0x34, 0x33, 0x61, 0x35, 0x30, 0x37, 0x38,
+    0x35, 0x61, 0x38, 0x65, 0x64, 0x31, 0x39, 0x36, 0x31, 0x36, 0x66, 0x38, 0x33, 0x33, 0x62, 0x63,
+    0x36, 0x37, 0x65, 0x32, 0x62, 0x36, 0x37, 0x35, 0x33, 0x66, 0x64, 0x35, 0x32, 0x33, 0x62, 0x38,
+    0x32, 0x62, 0x32, 0x64, 0x31, 0x37, 0x32, 0x65, 0x66, 0x64, 0x32, 0x34, 0x30, 0x34, 0x62, 0x33,
+    0x65, 0x39, 0x30, 0x63, 0x31, 0x33, 0x39, 0x37, 0x65, 0x66, 0x66, 0x32, 0x64, 0x63, 0x61, 0x34,
+    0x33, 0x61, 0x66, 0x64, 0x66, 0x35, 0x35, 0x61, 0x38, 0x36, 0x63, 0x32, 0x33, 0x63, 0x65, 0x37,
+    0x64, 0x37, 0x32, 0x30, 0x36, 0x38, 0x38, 0x34, 0x66, 0x35, 0x33, 0x63, 0x38, 0x30, 0x62, 0x37,
+    0x39, 0x30, 0x37, 0x38, 0x38, 0x63, 0x33, 0x63, 0x38, 0x61, 0x36, 0x38, 0x32, 0x34, 0x38, 0x64,
+    0x39, 0x39, 0x37, 0x38, 0x30, 0x37, 0x63, 0x31, 0x61, 0x64, 0x39, 0x39, 0x31, 0x37, 0x31, 0x32,
+    0x37, 0x38, 0x33, 0x64, 0x37, 0x38, 0x35, 0x65, 0x61, 0x37, 0x39, 0x64, 0x66, 0x36, 0x35, 0x31,
+    0x32, 0x61, 0x64, 0x32, 0x37, 0x35, 0x31, 0x34, 0x38, 0x35, 0x31, 0x36, 0x62, 0x34, 0x36, 0x36,
+    0x30, 0x35, 0x31, 0x31, 0x38, 0x64, 0x33, 0x33, 0x36, 0x35, 0x38, 0x61, 0x62, 0x38, 0x37, 0x38,
+    0x66, 0x30, 0x34, 0x35, 0x32, 0x36, 0x66, 0x66, 0x62, 0x64, 0x65, 0x61, 0x32, 0x31, 0x39, 0x65,
+    0x34, 0x33, 0x35, 0x66, 0x36, 0x61, 0x37, 0x32, 0x65, 0x65, 0x62, 0x31, 0x64, 0x32, 0x36, 0x64,
+    0x64, 0x63, 0x31, 0x62, 0x33, 0x30, 0x35, 0x30, 0x61, 0x34, 0x38, 0x66, 0x36, 0x36, 0x65, 0x64,
+    0x33, 0x33, 0x65, 0x31, 0x35, 0x62, 0x34, 0x34, 0x33, 0x64, 0x32, 0x63, 0x38, 0x61, 0x63, 0x65,
+    0x35, 0x35, 0x62, 0x33, 0x63, 0x33, 0x63, 0x64, 0x62, 0x64, 0x62, 0x31, 0x63, 0x62, 0x63, 0x66,
+    0x32, 0x63, 0x64, 0x32, 0x61, 0x63, 0x32, 0x61, 0x35, 0x32, 0x63, 0x64, 0x38, 0x34, 0x65, 0x34,
+    0x62, 0x34, 0x31, 0x35, 0x36, 0x38, 0x61, 0x35, 0x63, 0x66, 0x66, 0x62, 0x63, 0x30, 0x63, 0x37,
+    0x30, 0x36, 0x36, 0x38, 0x32, 0x31, 0x33, 0x61, 0x65, 0x34, 0x33, 0x64, 0x38, 0x34, 0x62, 0x38,
+    0x61, 0x38, 0x33, 0x39, 0x35, 0x36, 0x66, 0x36, 0x37, 0x62, 0x64, 0x31, 0x62, 0x32, 0x62, 0x62,
+    0x34, 0x38, 0x38, 0x38, 0x34, 0x65, 0x34, 0x65, 0x36, 0x38, 0x36, 0x30, 0x39, 0x33, 0x30, 0x66,
+    0x63, 0x66, 0x66, 0x36, 0x33, 0x34, 0x61, 0x64, 0x39, 0x34, 0x64, 0x37, 0x30, 0x32, 0x36, 0x63,
+    0x34, 0x66, 0x34, 0x64, 0x35, 0x63, 0x36, 0x32, 0x65, 0x31, 0x66, 0x37, 0x66, 0x31, 0x33, 0x32,
+    0x61, 0x65, 0x61, 0x33, 0x65, 0x64, 0x61, 0x62, 0x37, 0x63, 0x39, 0x63, 0x62, 0x62, 0x64, 0x63,
+    0x31, 0x31, 0x39, 0x66, 0x64, 0x66, 0x61, 0x39, 0x65, 0x39, 0x64, 0x38, 0x37, 0x63, 0x65, 0x37,
+    0x36, 0x31, 0x34, 0x32, 0x65, 0x37, 0x65, 0x33, 0x38, 0x66, 0x35, 0x31, 0x32, 0x62, 0x63, 0x31,
+    0x35, 0x62, 0x62, 0x34, 0x35, 0x33, 0x37, 0x62, 0x39, 0x62, 0x65, 0x37, 0x64, 0x32, 0x61, 0x32,
+    0x36, 0x32, 0x30, 0x65, 0x36, 0x39, 0x35, 0x36, 0x65, 0x37, 0x35, 0x39, 0x66, 0x66, 0x38, 0x66,
+    0x65, 0x34, 0x64, 0x37, 0x31, 0x65, 0x65, 0x66, 0x36, 0x31, 0x32, 0x39, 0x64, 0x64, 0x39, 0x36,
+    0x38, 0x61, 0x62, 0x30, 0x30, 0x64, 0x31, 0x65, 0x64, 0x39, 0x63, 0x31, 0x39, 0x37, 0x30, 0x35
+};
+#endif
+
+/**
+ * @brief The Sign_v15 generates RSA signature using PKCS#1 v1.5 algorithm.
+ *
+ * The function
+ * 1. Create RSA signature
+ * 2. Verify the signature correctness
+ * @param[in] pRsaPrivKey - the private key
+ * @param[in] DataIn_ptr - the data to sign on
+ * @param[in] DataInSize - the data size
+ * @param[in] Key_ptr - passphrase string
+ * @param[out] Signature_ptr - the RSA signature
+ *
+ */
+ /*********************************************************/
+int Sign_v15(RSA *pRsaPrivKey, char *DataIn_ptr,  // IG - merge with common implementation
+             int DataInSize, char *Signature_ptr,
+             char *Key_ptr);
+
+/**
+ * @brief The Sign_v21 generates RSA signature using PKCS#1 v2.1 algorithm.
+ *
+ * The function
+ * 1. Create RSA signature
+ * 2. Verify the signature correctness
+ * @param[in] pRsaPrivKey - the private key
+ * @param[in] DataIn_ptr - the data to sign on
+ * @param[in] DataInSize - the data size
+ * @param[out] Signature_ptr - the RSA signature
+ *
+ */
+ /*********************************************************/
+int Sign_v21(RSA *pRsaPrivKey, char *DataIn_ptr,
+             int DataInSize, char *Signature_ptr);
+
+/**
+* @brief The function SBU_GetNFromKeyPairAndCalcH Reads RSA key from the file using passphrase,
+*       and returns its decrypted value and its calculated Hash
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] pwdFileName - file name of the password
+* @param[out] PemDecryted - N buffer
+* @param[out] H_ptr - The H result. H size is N_SIZE_IN_BYTES*2 + 1
+*
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetNFromKeyPairAndCalcH(char* PemEncryptedFileName_ptr, char *pwdFileName, char *N_ptr, char *H_ptr);
+
+/**
+* @brief The SBU_RAND_Bytes reads RSA key from the file using passphrase
+*        and returns its decrypted value.
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] Key_ptr - passphrase
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_RAND_Bytes(int numBytes, char *buf);
+
+/**
+* @brief Reads RSA key from the file using passphrase, and returns its decrypted value and its Np
+*
+* @param[in] PemEncryptedFileName_ptr - file name
+* @param[in] pwdFileName - file name of the password
+* @param[out] PemDecryted - N and Np buffer
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetNAndNpFromKeyPair(char* PemEncryptedFileName_ptr, char *pwdFileName, char *PemDecryted);
+
+/**
+* @brief Reads RSA key from the file using passphrase, and returns its decrypted value and its Np
+*
+* @param[in] PemEncryptedFileName_ptr - public key file name
+* @param[out] PemDecryted - N and Np buffer
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetNAndNpFromPubKey(char* PemEncryptedFileName_ptr, char *PemDecryted);
+
+/**
+* @brief Reads RSA public key from the file and returns its raw value and its Np
+*
+* @param[in] pPemFileName_ptr - file name
+* @param[out] pNAndNp - N and Np buffer
+*/
+/*********************************************************/
+SBUEXPORT_C int SBU_GetHashOfNAndNpFromPubKey(char* pPemFileName_ptr, char *pHash, int hashSize);
+
+
+
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_files.c b/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_files.c
new file mode 100644
index 0000000..98c1b90
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_files.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "common_util_log.h"
+
+/**
+ * @brief This function reads bytes from text file into provided buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+int32_t CC_CommonUtilCopyDataFromRawTextFile (uint8_t *fileName, uint8_t *outBuff, uint32_t *outBuffLen)
+{
+    int32_t status = 0;
+    FILE *fd;
+    int32_t actualFileLen=0;
+    size_t actualRead=0;
+    size_t maxBytesToRead = 0;
+
+
+    if ((NULL == fileName) ||
+        (NULL == outBuff) ||
+        (NULL == outBuffLen)) {
+        UTIL_LOG_ERR( "ilegal parameters for %s\n", __func__);
+        return 1;
+    }
+    if (0 == *outBuffLen) {
+        UTIL_LOG_ERR( "ilegal outBuffLen \n");
+        return 1;
+    }
+    fd = fopen(fileName, "rt");
+    if (NULL == fd) {
+        UTIL_LOG_ERR( "failed to open file %s for reading\n", fileName);
+        return 1;
+    }
+    memset(outBuff, 0, *outBuffLen);
+
+    /* Get file length */
+    fseek(fd, 0, SEEK_END);
+    actualFileLen = ftell(fd);
+    if (actualFileLen == -1) {
+        UTIL_LOG_ERR( "ftell error actualFileLen == -1\n");
+        status = 1;
+        goto EXIT;
+    }
+    fseek(fd, 0, SEEK_SET);
+
+    /* calculate max bytes to read. should be the min of bytes in file and buffer size*/
+    maxBytesToRead = (actualFileLen > (*outBuffLen))?(*outBuffLen):actualFileLen;
+    if (0 == maxBytesToRead) {
+        UTIL_LOG_ERR( "ilegal maxBytesToRead == 0\n");
+        status = 1;
+        goto EXIT;
+    }
+
+    /* read file content */
+    actualRead = fread(outBuff, 1, maxBytesToRead, fd);
+
+    while ((outBuff[actualRead-1] == ' ') ||
+           (outBuff[actualRead-1] == '\n') ||
+           (outBuff[actualRead-1] == '\0') ||
+           (outBuff[actualRead-1] == 0x0A) ||
+           (outBuff[actualRead-1] == 0x0D)) {
+        actualRead--;
+    }
+    *outBuffLen = actualRead;
+
+    EXIT:
+    if (fd != NULL) {
+        fclose(fd);
+    }
+    return status;
+}
+
+
+/**
+ * @brief This function reads bytes from text file into provided buffer
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+int32_t CC_CommonUtilCopyDataFromTextFile (uint8_t *fileName, uint8_t *outBuff, uint32_t *outBuffLen)
+{
+    #define NUM_OF_CHARS_FOR_BYTE 4
+    int32_t status = 0;
+    FILE *fd;
+    int32_t i = 0, j=0, k=0;
+    int32_t actualFileLen=0;
+    int32_t tempNum=0;
+    size_t actualRead=0;
+    size_t maxBytesToRead = 0;
+    int8_t *filebufptr = NULL;
+    int8_t str[NUM_OF_CHARS_FOR_BYTE+1];
+
+
+    if ((NULL == fileName) ||
+        (NULL == outBuff) ||
+        (NULL == outBuffLen)) {
+        UTIL_LOG_ERR( "ilegal parameters for %s\n", __func__);
+        return 1;
+    }
+    if (0 == *outBuffLen) {
+        UTIL_LOG_ERR( "ilegal outBuffLen \n");
+        return 1;
+    }
+    fd = fopen(fileName, "rt");
+    if (NULL == fd) {
+        UTIL_LOG_ERR( "failed to open file %s for reading\n", fileName);
+        return 1;
+    }
+    memset(outBuff, 0, *outBuffLen);
+
+    /* Get file length */
+    fseek(fd, 0, SEEK_END);
+    actualFileLen = ftell(fd);
+    if (actualFileLen == -1) {
+        UTIL_LOG_ERR( "ftell error actualFileLen == -1\n");
+        status = 1;
+        goto EXIT;
+    }
+    fseek(fd, 0, SEEK_SET);
+
+    /* calculate max bytes to read. should be the min of bytes in file and buffer size*/
+    maxBytesToRead = (actualFileLen > (*outBuffLen*5))?(*outBuffLen*5):actualFileLen;
+    if (0 == maxBytesToRead) {
+        UTIL_LOG_ERR( "ilegal maxBytesToRead == 0\n");
+        status = 1;
+        goto EXIT;
+    }
+
+
+    /* allocate buffer for data from file */
+    filebufptr = (int8_t*)malloc(maxBytesToRead+1);
+    if (filebufptr == NULL) {
+        UTIL_LOG_ERR( "failed to allocate memory\n");
+        status = 1;
+        goto EXIT;
+    }
+
+    /* NULL terminated string to avoid buffer overflow of the sscanf that is used later */
+    filebufptr[maxBytesToRead] = '\0';
+
+    /* read file content */
+    actualRead = fread(filebufptr, 1, maxBytesToRead, fd);
+    j=0;
+    k=0;
+    for (i=0; i<maxBytesToRead; i++) {
+        if (((filebufptr[i] >= '0') && (filebufptr[i] <= '9')) ||
+            ((filebufptr[i] >= 'a') && (filebufptr[i] <= 'f')) ||
+            ((filebufptr[i] >= 'A') && (filebufptr[i] <= 'F')) ||
+            (filebufptr[i] == 'x') || (filebufptr[i] == 'X') &&
+            (k<NUM_OF_CHARS_FOR_BYTE)) {
+            str[k++] = filebufptr[i];
+        } else {
+            if ((filebufptr[i] == ' ') ||
+                (filebufptr[i] == '\n') ||
+                (filebufptr[i] == '\0') ||
+                (filebufptr[i] == ',')) {
+                if (k>0) {
+                    str[k] = '\0';
+                    tempNum = strtol(str, NULL, 16);
+                    if ((LONG_MIN == tempNum) ||
+                        (LONG_MAX == tempNum)) {
+                        UTIL_LOG_ERR( "strtol failed. check file name %s\n", fileName);
+                        status = 1;
+                        goto EXIT_AND_FREE;
+                    }
+                    outBuff[j++] = tempNum;
+                    k = 0;
+                }
+                continue;
+            } else {
+                UTIL_LOG_ERR( "ilegal uint8_t in file %c offset %d within file name %s\n", filebufptr[i], i, fileName);
+                status = 1;
+                goto EXIT_AND_FREE;
+            }
+        }
+    }
+    *outBuffLen = j;
+
+    EXIT_AND_FREE:
+    if (filebufptr != NULL) {
+        free(filebufptr);
+    }
+    EXIT:
+    if (fd != NULL) {
+        fclose(fd);
+    }
+    return status;
+}
+
+
+/**
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+int32_t CC_CommonUtilCopyDataFromBinFile(uint8_t *fileName, uint8_t *outBuff, uint32_t *outBuffLen)
+{
+    int32_t rc = 0;
+    FILE *fd;
+    size_t actualRead = 0;
+    size_t actualFileLen = 0;
+
+
+    if ((NULL == fileName) ||
+        (NULL == outBuff) ||
+        (0 == *outBuffLen)) {
+        UTIL_LOG_ERR( "ilegal parameters for %s\n", __func__);
+        return 1;
+    }
+    UTIL_LOG_INFO( "opening %s\n", fileName);
+    fd = fopen(fileName, "rb");
+    if (NULL == fd) {
+        UTIL_LOG_ERR( "failed to open file %s for reading\n", fileName);
+        return 1;
+    }
+    /* Get file length */
+    fseek(fd, 0, SEEK_END);
+    actualFileLen=ftell(fd);
+    if (actualFileLen == -1)
+    {
+        UTIL_LOG_ERR( "failed to ftell file %s\n", fileName);
+        goto EXIT_AND_FREE;
+    }
+    fseek(fd, 0, SEEK_SET);
+    if (0 == actualFileLen) {
+        UTIL_LOG_ERR( "ilegal actualFileLen == 0\n");
+        rc = 3;
+        goto EXIT_AND_FREE;
+    }
+
+    /* calculate max bytes to read. should be the min of bytes in file and buffer size*/
+    if (actualFileLen > *outBuffLen) {
+        UTIL_LOG_ERR( "ilegal actualFileLen %d > *outBuffLen %d\n", (int)actualFileLen, *outBuffLen);
+        rc = 2;
+        goto EXIT_AND_FREE;
+    }
+
+    /* read file content */
+    actualRead = fread(outBuff, 1, actualFileLen, fd);
+    if (actualRead == 0)
+    {
+        UTIL_LOG_ERR( "failed to open fread %s for reading\n", fileName);
+        goto EXIT_AND_FREE;
+    }
+    if ((uint8_t)EOF == outBuff[actualRead-1]) {
+        actualRead--;
+    }
+    *outBuffLen = actualRead;
+
+    EXIT_AND_FREE:
+    if (fd != NULL) {
+        fclose(fd);
+    }
+    return rc;
+}
+
+
+/**
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+int32_t CC_CommonUtilCopyBuffToBinFile(uint8_t *fileName, uint8_t *inBuff, uint32_t inBuffLen)
+{
+    int32_t rc = 0;
+    int32_t actualWriten = 0;
+    FILE *fd;
+
+
+    if ((NULL == fileName) ||
+        (NULL == inBuff) ||
+        (0 == inBuffLen)) {
+        UTIL_LOG_ERR( "ilegal parameters for %s\n", __func__);
+        return 1;
+    }
+    fd = fopen(fileName, "wb");
+    if (NULL == fd) {
+        UTIL_LOG_ERR( "failed to open file %s for writing\n", fileName);
+        return 1;
+    }
+
+    actualWriten = fwrite(inBuff, 1, inBuffLen, fd);
+    if (actualWriten != inBuffLen) {
+        UTIL_LOG_ERR( "failed to write data to file actual written %d, expected %d\n", actualWriten, inBuffLen);
+        rc = 1;
+    }
+
+    if (fd != NULL) {
+        fclose(fd);
+    }
+    UTIL_LOG_ERR( "%d bytes were written %s\n", actualWriten, fileName);
+
+
+    return rc;
+}
+
+
+/**
+ * @brief The function reads the pwd file name gets the pwd and returns it
+ *
+ * @param[in] pPwdFileName - file name of the password
+ * @param[out] pwd - passphrase data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonGetPassphrase(int8_t *pPwdFileName, uint8_t **pwd)
+{
+
+    FILE *fp = NULL;
+    int32_t fsize = 0;
+    int32_t seek =0, i=0;
+    uint8_t *tmpBuf;
+    int32_t status = 0;
+
+    if (pPwdFileName == NULL) {
+        UTIL_LOG_ERR("illegal file name\n");
+        return -1;
+    }
+
+    if (pwd == NULL) {
+        UTIL_LOG_ERR("illegal pwd\n");
+        return -1;
+    }
+
+    fp = fopen (pPwdFileName, "r");
+    if (fp == NULL) {
+        UTIL_LOG_ERR ("Cannot open file %s\n", pPwdFileName);
+        return -1;
+    }
+
+
+    /* Get the pwd file size */
+    seek = fseek(fp, 0, SEEK_END);
+    fsize = ftell(fp);
+    fseek(fp, 0, SEEK_SET);
+
+    if (fsize == 0) {
+        UTIL_LOG_ERR("PWD file is empty!\n");
+        status = -1;
+        goto END;
+    }
+
+    tmpBuf = (int8_t *)malloc(fsize+1);
+    if (tmpBuf == NULL) {
+        UTIL_LOG_ERR("failed to allocate memory\n");
+        status = -1;
+        goto END;
+    }
+
+    memset(tmpBuf, 0, fsize+1);
+    /* get the file data */
+    for (i=0; i<fsize; i++) {
+        tmpBuf[i] = (uint8_t)fgetc(fp);
+        if (tmpBuf[i] == (uint8_t)EOF || tmpBuf[i] == '\n') {
+            tmpBuf[i] = '\0';
+        }
+    }
+    *pwd = tmpBuf;
+    status = 0;
+
+    END:
+    fclose(fp);
+    return status;
+}
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_files.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_files.h
new file mode 100644
index 0000000..f63728c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_files.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef _COMMON_UTIL_FILES_H
+#define _COMMON_UTIL_FILES_H
+
+
+#include <stdint.h>
+
+#ifdef WIN32
+#define UTILEXPORT_C __declspec(dllexport)
+#else
+#define UTILEXPORT_C
+#endif
+
+#define UTIL_MAX_FILE_NAME  256
+
+/**
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+UTILEXPORT_C int32_t CC_CommonUtilCopyDataFromRawTextFile (uint8_t *fileName, uint8_t *outBuff, uint32_t *outBuffLen);
+
+/**
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+UTILEXPORT_C int32_t CC_CommonUtilCopyDataFromTextFile (uint8_t *fileName, uint8_t *outBuff, uint32_t *outBuffLen);
+
+/**
+ * @brief This function
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+UTILEXPORT_C int32_t CC_CommonUtilCopyDataFromBinFile (uint8_t *fileName, uint8_t *outBuff, uint32_t *outBuffLen);
+
+/**
+ * @brief This function copies a buffer to a file
+ *
+ * @param[in]
+ *
+ * @param[out]
+ *
+ * @return uint8_t -
+
+ */
+UTILEXPORT_C int32_t CC_CommonUtilCopyBuffToBinFile (uint8_t *fileName, uint8_t *inBuff, uint32_t inBuffLen);
+
+
+/**
+ * @brief The function reads the pwd file name gets the pwd and returns it
+ *
+ * @param[in] pPwdFileName - file name of the password
+ * @param[out] pwd - passphrase data
+ *
+ */
+/*********************************************************/
+int32_t CC_CommonGetPassphrase(int8_t *pPwdFileName, uint8_t **pwd);
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_log.h b/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_log.h
new file mode 100644
index 0000000..f35998f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/common/common_util_log.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+#ifndef _UTIL_LOG_H
+#define _UTIL_LOG_H
+
+#include "stdio.h"
+#include <stdint.h>
+
+
+#define CC_COMMON_OK   0
+#define WORD_BYTE_SIZE (sizeof(uint32_t))
+
+#define UTIL_LOG_ERR(format, args...) \
+        fprintf(stderr, "%s(): " format, __FUNCTION__, ##args)
+
+#ifdef UTIL_DEBUG
+#define UTIL_LOG_INFO UTIL_LOG_ERR
+#define UTIL_LOG_BYTE_BUFF(str, buff, size) {\
+    uint32_t i=0;\
+    unsigned long buff_addr = (unsigned long)buff;\
+    UTIL_LOG_ERR("\nprinting %s, %lu bytes", str, (unsigned long)size);\
+    for (i=0; i<size; i++){\
+        if (!(i%16)) {\
+            fprintf(stderr, "\n");\
+        }\
+        fprintf(stderr, " 0x%02X ", *((uint8_t *)buff_addr + i));\
+    }\
+    fprintf(stderr, "\n");\
+}
+#define UTIL_LOG_WORD_BUFF(str, buff, wordSize) {\
+    uint32_t i=0;\
+    unsigned long buff_addr = (unsigned long)buff;\
+    UTIL_LOG_ERR("\nprinting %s, %lu words", str, (unsigned long)wordSize);\
+    for (i=0; i<wordSize; i++){\
+        if (!(i%4)) {\
+            fprintf(stderr, "\n");\
+        }\
+        fprintf(stderr, " 0x%08lX ", *((unsigned long *)buff_addr + i));\
+    }\
+    fprintf(stderr, "\n");\
+}
+#else
+#define UTIL_LOG_INFO(format...)  do{ }while(0)
+#define UTIL_LOG_BYTE_BUFF(str, buff, size) do{ }while(0)
+#define UTIL_LOG_WORD_BUFF(str, buff, size) do{ }while(0)
+#endif
+
+
+#define UTIL_REVERSE_WORD_ORDER(buff, buffSize) {\
+    uint32_t i = 0;\
+    uint8_t  tmpByte = 0;\
+    if (buffSize % WORD_BYTE_SIZE) {\
+        memset(buff, 0, buffSize);\
+    } else {\
+        while ((i+3)<buffSize) {\
+            tmpByte = buff[i+3];\
+            buff[i+3] = buff[i];\
+            buff[i] = tmpByte;\
+            tmpByte = buff[i+2];\
+            buff[i+2] = buff[i+1];\
+            buff[i+1] = tmpByte;\
+            i += 4;\
+        }\
+    }\
+}
+
+#endif
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/Makefile
new file mode 100644
index 0000000..b822b29
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/Makefile
@@ -0,0 +1,21 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+SUB_DIRS = oem_key_request icv_key_response oem_asset_package
+
+all: $(foreach sub_dir,$(SUB_DIRS),do_$(sub_dir))
+
+clean: $(foreach sub_dir,$(SUB_DIRS),clean_$(sub_dir))
+
+clean_%:
+	@make -C $* clean
+
+do_%:
+	@make -C $*
+
+.PHONY: all clean clean_% do_%
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_common.c b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_common.c
new file mode 100644
index 0000000..1fedca1
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_common.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_util_log.h"
+#include "common_crypto_sym.h"
+#include "cc_production_asset.h"
+#include "cc_pal_types.h"
+
+
+uint8_t  isLibOpened = 0;
+
+/**
+* @brief initialize openSSL library
+*
+* @param[in] None
+* @param[out] None
+*
+*/
+/*********************************************************/
+void InitOpenSsl(void)
+{
+    if (0 == isLibOpened) {
+          OpenSSL_add_all_algorithms();
+    }
+    isLibOpened++;
+}
+
+
+/**
+* @brief terminates and cleanup openSSL library
+*
+* @param[in]  None
+* @param[out] None
+*
+*/
+/*********************************************************/
+void CloseOpenSsl(void)
+{
+    isLibOpened--;
+    if (0 == isLibOpened) {
+          EVP_cleanup();
+          //CYPTO_cleanup_all_ex_data();  /* cleanup application specific data to avoid memory leaks.*/
+    }
+}
+
+
+/**
+* @brief performs CMAC key derivation for Kprov using openSSL library
+*
+* @param[in]  pKey & keySize - Kpicv key and its size
+*       lable & pContext & contextSize used to build the dataIn for derivation
+* @param[out] pOutKey - Kprov
+*
+*/
+/*********************************************************/
+int AesCmacKeyDerivation(char *pKey, uint32_t keySize,
+                uint8_t *pLabel, uint32_t labelSize,
+                uint8_t *pContext, uint32_t contextSize,
+                char *pOutKey, uint32_t outKeySize)
+{
+        #define MAX_DATA_IN_SIZE  (PROD_KEY_TMP_LABEL_SIZE + PROD_KEY_TMP_CONTEXT_SIZE + 3)  // +3 for: iteration, key size and 0x0
+    int rc = 0;
+    int index = 0;
+    int8_t dataIn[MAX_DATA_IN_SIZE] = {0x0};
+
+        if ((pKey == NULL) ||
+            (keySize != PROD_KEY_TMP_KEY_SIZE) ||
+            (pLabel == NULL) ||
+            (labelSize > PROD_KEY_TMP_LABEL_SIZE) ||
+            (pContext == NULL) ||
+            (contextSize > PROD_KEY_TMP_CONTEXT_SIZE) ||
+            (pOutKey == NULL) ||
+            (outKeySize != PROD_KEY_TMP_KEY_SIZE)) {
+        UTIL_LOG_ERR( "Invalid inputs\n");
+        return (-1);
+        }
+
+        /* Create the input to the CMAC derivation
+           since key size is 16 bytes, we have 1 iteration for cmac  derivation*
+           the data or the derivation:
+           0x1 || label || 0x0 || context || size of derived key in bits */
+    dataIn[index++] = 0x1;
+    memcpy(&dataIn[index], pLabel, labelSize);
+    index += labelSize;
+    dataIn[index++] = 0x0;
+    memcpy(&dataIn[index], pContext, contextSize);
+    index += contextSize;
+    dataIn[index++] = outKeySize*CC_BITS_IN_BYTE; // size of the key in bits
+
+    UTIL_LOG_BYTE_BUFF("dataIn", dataIn, index);
+    UTIL_LOG_BYTE_BUFF("pKey", pKey, keySize);
+    rc = CC_CommonAesCmacEncrypt(dataIn, index,
+                     pKey, keySize, pOutKey);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCmacEncrypt(), rc %d\n", rc);
+        return (-1);
+    }
+    UTIL_LOG_BYTE_BUFF("pOutKey", pOutKey, outKeySize);
+    return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_util_crypto_helper.py b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_util_crypto_helper.py
new file mode 100644
index 0000000..f789a1d
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_util_crypto_helper.py
@@ -0,0 +1,123 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+from ctypes import *
+from dmpu_util_helper import *
+
+# oem key request certificate struct is:
+#  token || version || size || main N+Np || enc N + Np || signature
+#   4           4              4       384+20            384+20           384
+OEM_KEY_REQ_CERT_SIZE = 1204 
+DMPU_CERT_HEADER_SIZE_IN_BYTES = 12     # token || version || size
+DMPU_OEM_KEY_REQ_TOKEN = 0x52455144
+DMPU_OEM_KEY_REQ_VERSION = 0x01
+
+PUBKEY_SIZE_BYTES = 384     # 3072 bits
+NP_SIZE_IN_BYTES = 20
+
+KRTL_SIZE = 16
+
+
+# This class represents N public key data
+class CertNPublicKey:
+
+    # Constructor
+    # Np can stand either for Np or for H
+    def __init__(self, PubKeyBinStr):
+        self.PubKey = PubKeyBinStr
+
+    # The method __len__ returns the size of pubkey N and Np (string size in bytes)
+    def __len__(self):
+        return(PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES)
+
+    # This method returns a binary string of the N string and Np string (N is set as big endian
+    # Np is set as little endian)   
+    def VarsToBinString(self):
+        DataBinStr = str()
+        PubKey = self.PubKey
+
+        for i in range(PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES): 
+            byte = PubKey[i]
+            DataBinStr = DataBinStr + byte2string(byte)
+
+        return DataBinStr
+
+# End of CertNPublicKey
+
+
+# This class holds the RSA signature
+class CertRSASignature:
+
+    # Constructor
+    def __init__(self, SignatureBinStr):
+        self.SignatureStr = SignatureBinStr
+
+    # The method returns the signature size
+    def __len__(self):
+        return PUBKEY_SIZE_BYTES
+
+    # This method returns the binary signature
+    def VarsToBinString(self):
+        DataBinStr = str()
+        SignatureStr = self.SignatureStr
+        for i in range(PUBKEY_SIZE_BYTES): 
+            byte = SignatureStr[i]
+            DataBinStr = DataBinStr + byte2string(byte)
+
+        return DataBinStr
+     
+# End of CertRSASignature
+
+# The function GetRSAKeyParams reads the key file (in PEM format) parse it and gets the public and private RSA key data.
+# Set the N buffer (in binary representation) and calculates the Np (Barrett n' value).
+def GetRSAKeyParams(logFile, RSAKeyFileName, PassphraseFileName, crypto_lib):
+    publicKey = create_string_buffer(PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES)
+    result = crypto_lib.SBU_GetNAndNpFromKeyPair(str.encode(RSAKeyFileName), str.encode(PassphraseFileName), publicKey)
+    if result != 0:
+        print_and_log (logFile, "Error in public key | Np")
+        sys.exit(1)
+      
+    # Create the public key object and return it in binary format
+    return CertNPublicKey(publicKey)
+# End of GetRSAKeyParams
+
+
+# The function GetRSAPubKeyParams reads the public  key file (in PEM format) parse it and gets the public RSA key data.
+# Set the N buffer (in binary representation) and calculates the Np (Barrett n' value). the function returns string of N + Np
+def GetRSAPubKeyParams(logFile, RSAKeyFileName, crypto_lib):
+    publicKey = create_string_buffer(PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES)
+    result = crypto_lib.SBU_GetNAndNpFromPubKey(str.encode(RSAKeyFileName), publicKey)    
+    if result != 0:
+        print_and_log (logFile, "Error in public key | Np")
+        sys.exit(1)
+      
+    # Create the public key object and return it in binary format
+    return CertNPublicKey(publicKey)
+# End of GetRSAPubKeyParams
+
+# The function GetRSASignature calculates the RSA signature
+def GetRSASignature(logFile, DataIn, PrivKeyFile, PassphraseFile, CryptoDLL_handle):
+    try:
+        DataInSize = len(DataIn)
+        Signature = create_string_buffer(PUBKEY_SIZE_BYTES)
+        
+        # Do Rsa Sign and get the signature
+        # N, D and DataIn are sent to the function as int arrays     
+        p1=str.encode(PrivKeyFile)
+        p2=str.encode(PassphraseFile)
+        p3=DataIn.encode('iso-8859-1')
+        result = CryptoDLL_handle.SBU_RSA_Sign(1, p3, DataInSize, p1, p2, Signature)
+        if result != 0:
+            print_and_log(logFile, "\n SBU_CRYPTO_DLL.SBU_RSA_Sign returned an error !!")                
+            raise NameError
+
+    except NameError:        
+        sys.exit(1)
+    #return CertRSASignature(ReverseBytesinBinString(Signature))
+    return CertRSASignature(Signature)
+# End of GetRSASignature
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_util_helper.py b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_util_helper.py
new file mode 100755
index 0000000..2eab8b2
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_util_helper.py
@@ -0,0 +1,128 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+from datetime import datetime
+#
+import sys
+import struct
+from ctypes import *
+
+
+SBU_CRYPTO_LIB_DIR = "lib"
+CURRENT_PATH = sys.path[0]
+ASSET_TYPE_ENC = 1
+ASSET_TYPE_PROV = 2
+
+ASSET_SIZE = 16
+USER_DATA_SIZE = 16
+
+# The function returns the path of the DLL - fixed path (relative to script path)
+def GetDLLPath(FileName):
+
+    path = str()
+    path = CURRENT_PATH
+    # split according to dir names
+    if sys.platform != "win32" :
+        path_div = "/"
+    else : #platform = win32
+        path_div = "\\"
+
+    path_new = path + path_div + ".." + path_div
+
+    path_new = path_new + FileName
+    return path_new
+# End of GetDLLPath
+
+# 
+# The function loads the crypto DLL and returns its handle
+def LoadDLLGetHandle(FileName):
+    # Load the crypto libraries
+    crypto_lib = cdll.LoadLibrary(GetDLLPath(FileName))
+    return crypto_lib
+# End of LoadDLLGetHandle
+
+# The function free the DLL - // not being used in Linux
+def FreeDLLGetHandle(DllHandle):
+    # free the libraries
+    cdll.FreeLibrary(DllHandle)
+    return 0
+# End of FreeDLLGetHandle
+
+
+# Create a log file handle
+def create_log_file (log_file_path):
+    
+    log_file = open(log_file_path, 'w')
+    return log_file;
+
+# Print (stdout) and output also to log file given text
+def print_and_log (log_file, text):
+    print (text)
+    log_file.write(text)
+    sys.stdout.flush()
+    log_file.flush()
+
+
+# Do synchronous print to appear immediately on the console
+def print_sync (text):
+    print (text)
+    sys.stdout.flush()
+
+
+# Do synchronous write to log file
+def log_sync (log_file, text):
+    log_file.write(text)
+    log_file.flush()
+
+
+# The GetDataFromBinFile gets the data from a binary file
+def GetDataFromBinFile(logFile, fileName):
+    binStr = str()
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(fileName, "rb")
+        binStr = FileObj.read()
+        binSize = len(binStr)
+        FileObj.close()
+
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %fileName)
+        sys.exit(1)
+    return binSize, binStr
+
+
+# Convert bytes to string
+def byte2string (DataBinStr):
+    if type(DataBinStr).__name__ == 'str' :
+        return DataBinStr
+    ResStr = str()
+    for i in range(len(DataBinStr)) :
+        ResStr = ResStr + chr(DataBinStr[i])
+    return ResStr
+
+# close files and exit script
+def exit_main_func(log_file, config_file, rc):
+    log_file.close()
+    config_file.close()
+    sys.exit(rc)
+
+# The CreateCertBinFile opens a binary and text file and writes the certificate data into it 
+def CreateCertBinFile(logFile, binStr, certFileName):
+    try:
+        # Open a binary file and write the data to it
+        FileObj = open(certFileName, "wb")
+        FileObj.write(bytes(binStr.encode('iso-8859-1')))
+        FileObj.close()
+
+    except IOError as Error7:
+        (errno, strerror) = Error7.args
+        print_and_log(logFile, "Error in openning file - %s" %certFileName)
+        sys.exit(1)
+    return       
+# End of CreateCertBinFile	        
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_utils.h b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_utils.h
new file mode 100644
index 0000000..e7ca81f
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/common/dmpu_utils.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef  _CC_DMPU_UTIL_H
+#define  _CC_DMPU_UTLI_H
+
+/*!
+@file
+@brief This file contains the functions and definitions for the OEM Asset provisioning.
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "common_rsa_keypair.h"
+#include "cc_pka_hw_plat_defs.h"
+
+#define DMPU_CERT_HEADER_SIZE_IN_BYTES   12     // token || version || size
+#define DMPU_OEM_KEY_REQ_TOKEN  0x52455144
+#define DMPU_OEM_KEY_REQ_VERSION    0x01UL
+
+typedef struct {
+        uint32_t  token;
+        uint32_t  version;
+        uint32_t  size;
+        uint8_t   oemMainPubKey[ SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES];
+        uint8_t   oemEncPubKey[ SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES];
+        uint8_t   signature[SB_CERT_RSA_KEY_SIZE_IN_BYTES];
+}CCOemRequestCert_t;
+
+/**
+* @brief initialize openSSL library
+*
+* @param[in] None
+* @param[out] None
+*
+*/
+/*********************************************************/
+void InitOpenSsl(void);
+
+
+/**
+* @brief terminates and cleanup openSSL library
+*
+* @param[in]  None
+* @param[out] None
+*
+*/
+/*********************************************************/
+void CloseOpenSsl(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+* @brief performs CMAC key derivation for Kprov using openSSL library
+*
+* @param[in]  pKey & keySize - Kpicv key and its size
+*       lable & pContext & contextSize used to build the dataIn for derivation
+* @param[out] pOutKey - Kprov
+*
+*/
+/*********************************************************/
+int AesCmacKeyDerivation(char *pKey, uint32_t keySize,
+                uint8_t *pLabel, uint32_t labelSize,
+                uint8_t *pContext, uint32_t contextSize,
+                char *pOutKey, uint32_t outKeySize);
+
+#endif /*_CC_DMPU_UTIL_H */
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/Makefile
new file mode 100644
index 0000000..cd7cfa3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/Makefile
@@ -0,0 +1,48 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for managing build and installation
+
+# shared library to build
+UTIL_ROOT = $(shell pwd)
+UTILS_DIR_ROOT = $(UTIL_ROOT)/../../..
+HOST_DIR_ROOT = $(UTILS_DIR_ROOT)/../host
+UTILS_LIB_PATH = ./lib
+UTILS_LIB_NAME = lib_icv_key_response.so
+UTILS_SCRIPTS_DIRNAME = $(UTIL_ROOT)
+
+
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)), $(1))
+
+INSTALL_LIST = install_lib install_scripts
+
+all:   $(INSTALL_LIST)
+
+install_lib: build_lib $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/lib)
+	@echo Installing icv_key_response library
+	@cp $(UTILS_LIB_PATH)/$(UTILS_LIB_NAME) $(UTILS_DIR_ROOT)/lib
+
+build_lib:
+	@echo build_lib for dmpu_icv_key_response_util.py.
+	@make -C $(UTILS_LIB_PATH)
+
+install_scripts: $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin)  $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin/example)
+	@echo Installing scripts for dmpu_icv_key_response_util.py.
+	@cp $(UTIL_ROOT)/../common/*.py $(UTILS_DIR_ROOT)/bin
+	@cp $(UTIL_ROOT)/*.py $(UTILS_DIR_ROOT)/bin
+	@cp $(UTIL_ROOT)/examples/*.cfg $(UTILS_DIR_ROOT)/bin/example
+
+$(UTILS_DIR_ROOT)/%:
+	@echo Creating directory  for dmpu package
+	@mkdir $@
+
+
+clean:
+	@make -C $(UTILS_LIB_PATH) clean
+
+.PHONY: install_lib install_sd_scripts clean
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/dmpu_icv_key_response_util.py b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/dmpu_icv_key_response_util.py
new file mode 100755
index 0000000..30acba9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/dmpu_icv_key_response_util.py
@@ -0,0 +1,121 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# This utility enables the ICV to build the encrypted OEM temporary key
+
+import sys
+# Definitions for paths
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+import configparser
+from dmpu_util_helper import *
+from dmpu_util_crypto_helper import *
+import sys
+
+UTILITY_LIB_DIR = "lib"
+UTILITY_LIB_Name = SBU_CRYPTO_LIB_DIR + "/" + "lib_icv_key_response.so"
+
+# Parse given test configuration file and return test attributes as dictionary
+def parse_config_file (config, log_file):
+    local_dict = {}
+    section_name = "DMPU-ICV-KEY-RES-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None
+
+    local_dict['oem_cert_pkg'] = config.get(section_name, 'oem-cert-pkg')
+    log_sync(log_file,"oem-cert-pkg: " + str(local_dict['oem_cert_pkg']) + "\n")
+     
+    local_dict['key_filename'] = config.get(section_name, 'key-filename')
+    log_sync(log_file,"key-filename: " + str(local_dict['key_filename']) + "\n")
+     
+    if config.has_option(section_name, 'keypwd-filename'): #used for testing
+            local_dict['keypwd_filename'] = str.encode(config.get(section_name, 'keypwd-filename'))
+            log_sync(log_file,"keypwd-filename: " + str(local_dict['keypwd_filename']) + "\n")
+    else:
+        local_dict['keypwd_filename'] = ''
+
+    local_dict['pkg_filename'] = str.encode(config.get(section_name, 'icv-enc-oem-key'))
+    log_sync(log_file,"icv-enc-oem-key: " + str(local_dict['pkg_filename']) + "\n")
+
+    return local_dict
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "asset_prov.log"
+    return config_fname, log_fname
+
+def main():
+
+    config_fname, log_fname = parse_shell_arguments()
+    log_file = create_log_file(log_fname)
+    print_and_log(log_file, str(datetime.now()) + ": ICV key response Utility started (Logging to " + log_fname + ")\n")
+
+    DLLHandle = LoadDLLGetHandle(UTILITY_LIB_Name)
+    
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        log_file.close()
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.read(config_fname)
+    data_dict = {}
+
+    data_dict = parse_config_file(config, log_file)
+
+    if (data_dict != None):
+        # Get assets and encrypted key from files
+        cert_size, certStr = GetDataFromBinFile(log_file, data_dict['oem_cert_pkg'])
+        if (cert_size != OEM_KEY_REQ_CERT_SIZE) :
+                print_and_log(log_file, "invalid certificate size " + str(cert_size) +" \n")
+                exit_main_func(log_file, config_file, 1)
+
+        key_size, keyStr = GetDataFromBinFile(log_file, data_dict['key_filename'])
+        if (key_size != KRTL_SIZE*2) :
+                print_and_log(log_file, "invalid key size  \n")
+                exit_main_func(log_file, config_file, 1)
+
+        print_and_log(log_file, "**** Generate OEM key package ****\n")        
+
+        result = DLLHandle.generateIcvKeyRespPkg(keyStr, key_size, data_dict['keypwd_filename'],
+                          certStr, cert_size,
+                         data_dict['pkg_filename'])
+        if result != 0:
+            raise NameError
+       
+        print_and_log(log_file, "**** ICV key response utility completed successfully ****\n")
+        exit_main_func(log_file, config_file, 0)
+
+    else:
+        print_and_log(log_file, "**** Invalid config file ****\n")
+        exit_main_func(log_file, config_file, 1)
+
+    FreeDLLGetHandle(DLLHandle)
+
+#############################
+if __name__ == "__main__":
+    main()
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/examples/dmpu_icv_key_response.cfg b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/examples/dmpu_icv_key_response.cfg
new file mode 100644
index 0000000..307023a
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/examples/dmpu_icv_key_response.cfg
@@ -0,0 +1,19 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for generating key request certificate by OEM
+# [DMPU-ICV-KEY-RES-CFG]        Mandatory header.
+# oem-cert-pkg =            OEM key request certificate package output file. Binary format.
+#key-filename =         File holding the encrypted Krtl, in binary format.
+#keypwd-filename =      Passphrase for the key file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#icv-enc-oem-key =            The file containing teh encrypted oem key, generated by dmpu_key_response_util.py.
+ [DMPU-ICV-KEY-RES-CFG]
+oem-cert-pkg = oem_request_pkg.bin
+key-filename = rtl_enc_key.bin
+keypwd-filename = rtl_key_pwd.txt
+icv-enc-oem-key = icv_response_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/lib/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/lib/Makefile
new file mode 100644
index 0000000..3384104
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/lib/Makefile
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for building sbu_crypto library
+SH_LIB_NAME = lib_icv_key_response.so
+
+LIB_SRC_O = main.o dmpu_common.o common_crypto_asym.o  common_crypto_sym.o common_rsa_keypair_util.o common_rsa_keypair.o common_util_files.o
+
+UTILS_ROOT = $(shell pwd)/../../../..
+SHARED_DIR = $(UTILS_ROOT)/../shared
+HOSTSRC_DIR = $(UTILS_ROOT)/../host/src
+UTILS_LIB_PATH = $(UTILS_ROOT)/lib
+UTILS_INC_PATH = $(SHARED_DIR)/include $(SHARED_DIR)/include/proj/$(PROJ_PRD) $(UTILS_ROOT)/include
+UTILS_INC_PATH += $(UTILS_ROOT)/src/common $(UTILS_ROOT)/src/dmpu_asset_pkg_util/common $(HOSTSRC_DIR)/cc3x_productionlib/common $(SHARED_DIR)/include/pal $(SHARED_DIR)/include/pal/$(TEE_OS)
+
+CFLAGS += -fPIC $(foreach incdir,$(UTILS_INC_PATH),-I$(incdir)) -c
+
+all: $(SH_LIB_NAME)
+
+# Compile and link the sbu_crypto library with hard-coded library run path to utils/lib
+# (to assure the private version of openssl libraries are used)
+$(SH_LIB_NAME): $(LIB_SRC_O)
+	gcc -shared -o $(SH_LIB_NAME) $(LIB_SRC_O) -Wl,-rpath,$(UTILS_LIB_PATH) -lcrypto -lssl
+
+vpath %.c $(UTILS_ROOT)/src/common $(UTILS_ROOT)/src/dmpu_asset_pkg_util/common
+
+%.o: %.c
+	gcc $(CFLAGS) $<
+
+clean:
+	rm -f $(SH_LIB_NAME) $(LIB_SRC_O)
+
+.PHONY: clean all
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/lib/main.c b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/lib/main.c
new file mode 100644
index 0000000..bd429bb
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/icv_key_response/lib/main.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_util_log.h"
+#include "common_crypto_asym.h"
+#include "common_crypto_sym.h"
+#include "common_rsa_keypair_util.h"
+#include "common_util_files.h"
+#include "cc_production_asset.h"
+#include "dmpu_utils.h"
+
+static int verifyCert(CCOemRequestCert_t * pCertStruct)
+{
+        int rc = 0;
+        unsigned int csrBuffSize = 0;
+
+        if (pCertStruct == NULL){
+                return 1;
+        }
+
+        /* verify cert header */
+        if (pCertStruct->token != DMPU_OEM_KEY_REQ_TOKEN) {
+                UTIL_LOG_ERR("Ilegal token in cert 0x%x\n", pCertStruct->token);
+                return 1;
+        }
+        if (pCertStruct->version != DMPU_OEM_KEY_REQ_VERSION) {
+                UTIL_LOG_ERR("Ilegal version in cert 0x%x\n", pCertStruct->version);
+                return 1;
+        }
+        if (pCertStruct->size != sizeof(CCOemRequestCert_t) - SB_CERT_RSA_KEY_SIZE_IN_BYTES) {
+                UTIL_LOG_ERR("Ilegal length in cert 0x%x\n", pCertStruct->size);
+                return 1;
+        }
+
+        /* verify certificate signatire */
+        rc = CC_CommonRsaVerify(RSA_USE_PKCS_21_VERSION,                    /* RSA version */
+                                  pCertStruct->oemMainPubKey,                            /* public key to verify with */
+                                  (char *)pCertStruct,                           /* data */
+                                  pCertStruct->size,   /* data size */
+                                  pCertStruct->signature);                            /* signature */
+        if (rc != 0) {
+                UTIL_LOG_ERR( "failed to CC_CommonRsaVerify() for certificate, rc %d\n", rc);
+                return 1;
+        }
+        UTIL_LOG_ERR("verifyCert: OK\n");
+        return 0;
+}
+
+
+/**
+* @brief Build the ICV key response package using openSSL
+*        library
+*
+* @param[in]  encKeyBuff & encKeyBuffSize & pKeyPwdFileName - the encryptes Kpicv key
+*           assetId - Asset ID, used for Kprov derivation
+*           asset & assetSize - The Asset to generate the package for
+*               pPkgFileName - OUT - the asset package binary
+*               file name
+* @param[out] None
+*
+*/
+/*********************************************************/
+int generateIcvKeyRespPkg(char *encKeyBuff, uint32_t encKeyBuffSize,
+    char *pKeyPwdFileName,
+    uint8_t *pCertbuff, uint32_t certbuffSize,
+    char *pPkgFileName)
+{
+    int rc = 0;
+    uint8_t i = 0;
+        CCOemRequestCert_t  *pCertStruct;
+    uint8_t keyRtl[PROD_KEY_RTL_KEY_SIZE + AES_BLOCK_SIZE] = {0};  // Adding AES_BLOCK_SIZE to avoid over-run
+        uint8_t hbkBuff[HASH_SHA256_DIGEST_SIZE_IN_BYTES];
+        uint8_t keyTmp[PROD_KEY_TMP_KEY_SIZE] = {0};
+        uint8_t     encKeyTmp[SB_CERT_RSA_KEY_SIZE_IN_BYTES] = {0};
+
+    // Verify Inputs
+    if ( (pPkgFileName == NULL) ||
+             (encKeyBuff == NULL) ||
+             (encKeyBuffSize != (PROD_KEY_RTL_KEY_SIZE+ AES_BLOCK_SIZE)) ||
+             (pCertbuff == NULL) ||
+             (certbuffSize !=  sizeof (CCOemRequestCert_t))) {
+        UTIL_LOG_ERR( "Invalid inputs\n");
+        return 1;
+    }
+        pCertStruct = (CCOemRequestCert_t  *)pCertbuff;
+
+    InitOpenSsl();
+
+        // First, verify the certificate
+        rc = verifyCert(pCertStruct);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to verifyCert() for Krtl, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+    // Decrypt Krtl
+    rc = CC_CommonAesCbcDecrypt(pKeyPwdFileName, encKeyBuff, encKeyBuffSize, keyRtl);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCbcDecrypt() for Krtl, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+        // Calculate HBK from oem main public key hash
+        rc = CC_CommonCalcHash((uint8_t *)&pCertStruct->oemMainPubKey,
+                               SB_CERT_RSA_KEY_SIZE_IN_BYTES+NP_SIZE_IN_BYTES,
+                               hbkBuff,
+                               HASH_SHA256_DIGEST_SIZE_IN_BYTES);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonCalcHash() for Krtl, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+        // Calculate Ktmp = cmac(Krtl, 0x01 || OEM label  || 0x0 || HBK(only 16 bytes) || 0x80)
+    rc = AesCmacKeyDerivation(keyRtl, PROD_KEY_RTL_KEY_SIZE,
+                PROD_OEM_KEY_TMP_LABEL,  PROD_KEY_TMP_LABEL_SIZE,
+                (uint8_t *)hbkBuff, PROD_KEY_TMP_CONTEXT_SIZE,
+                keyTmp, PROD_KEY_TMP_KEY_SIZE);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to AesCmacKeyDerivation() for Ktmp, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+        // Encrypt the OEM key with the dedicated key pair
+        rc = CC_CommonRsaEncrypt(RSA_USE_PKCS_21_VERSION,
+                            (uint8_t *)&pCertStruct->oemEncPubKey,
+              keyTmp, PROD_KEY_TMP_KEY_SIZE,
+              encKeyTmp) ;
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonRsaEncrypt() for Ktmp, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+
+    // Writie the encrypted key  into bin file
+    rc = CC_CommonUtilCopyBuffToBinFile(pPkgFileName, encKeyTmp, SB_CERT_RSA_KEY_SIZE_IN_BYTES);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonUtilCopyBuffToBinFile(), rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+end_func:
+    CloseOpenSsl();
+    UTIL_LOG_ERR( "End rc %d\n", rc);
+    return rc;
+}
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/Makefile
new file mode 100644
index 0000000..a059b63
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/Makefile
@@ -0,0 +1,48 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for managing build and installation
+
+# shared library to build
+UTIL_ROOT = $(shell pwd)
+UTILS_DIR_ROOT = $(UTIL_ROOT)/../../..
+HOST_DIR_ROOT = $(UTILS_DIR_ROOT)/../host
+UTILS_LIB_PATH = ./lib
+UTILS_LIB_NAME = lib_oem_asset_pkg.so
+UTILS_SCRIPTS_DIRNAME = $(UTIL_ROOT)
+
+
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)), $(1))
+
+INSTALL_LIST = install_lib install_scripts
+
+all:   $(INSTALL_LIST)
+
+install_lib: build_lib $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/lib)
+	@echo Installing oem_asset_pkg library
+	@cp $(UTILS_LIB_PATH)/$(UTILS_LIB_NAME) $(UTILS_DIR_ROOT)/lib
+
+build_lib:
+	@echo build_lib for oem_asset_pkg.py.
+	@make -C $(UTILS_LIB_PATH)
+
+install_scripts: $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin)  $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin/example)
+	@echo Installing scripts for oem_asset_pkg.py.
+	@cp $(UTIL_ROOT)/../common/*.py $(UTILS_DIR_ROOT)/bin
+	@cp $(UTIL_ROOT)/*.py $(UTILS_DIR_ROOT)/bin
+	@cp $(UTIL_ROOT)/examples/*.cfg $(UTILS_DIR_ROOT)/bin/example
+
+$(UTILS_DIR_ROOT)/%:
+	@echo Creating directory  for dmpu package
+	@mkdir $@
+
+
+clean:
+	@make -C $(UTILS_LIB_PATH) clean
+
+.PHONY: install_lib install_sd_scripts clean
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/dmpu_oem_asset_pkg_util.py b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/dmpu_oem_asset_pkg_util.py
new file mode 100755
index 0000000..1dd9878
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/dmpu_oem_asset_pkg_util.py
@@ -0,0 +1,146 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# This utility builds production asset  package:
+# the package format is:
+#                       token, version, asset length, user data (20 bytes)
+#                       nonce(12 bytes)
+#                       encrypted asset (up to 512 bytes - multiple of 16 bytes)
+#                       aset tag (16 bytes)
+
+
+# This file contains the general functions that are used in both certificates
+
+
+
+import sys
+# Definitions for paths
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+import configparser
+from dmpu_util_helper import *
+from dmpu_util_crypto_helper import *
+import sys
+
+UTILITY_LIB_DIR = "lib"
+UTILITY_LIB_Name = SBU_CRYPTO_LIB_DIR + "/" + "lib_oem_asset_pkg.so"
+
+# Parse given test configuration file and return test attributes as dictionary
+def parse_config_file (config, log_file):
+    local_dict = {}
+    section_name = "DMPU-OEM-ASSET-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None
+
+    if config.get(section_name, 'asset-type') == "kce":
+          local_dict['asset_type'] = int(ASSET_TYPE_ENC)
+    elif config.get(section_name, 'asset-type') == "kcp":
+          local_dict['asset_type'] = int(ASSET_TYPE_PROV)
+    else:
+        log_sync(log_file, "Illegal asset-type defined - exiting\n")
+        return None
+    log_sync(log_file,"asset-type: " + str(local_dict['asset_type']) + "\n")
+
+    local_dict['icv_enc_oem_key'] = config.get(section_name, 'icv-enc-oem-key')
+    log_sync(log_file,"icv-enc-oem-key: " + str(local_dict['icv_enc_oem_key']) + "\n")
+     
+    local_dict['oem_enc_keypair'] =  str.encode(config.get(section_name, 'oem-enc-keypair'))
+    log_sync(log_file,"oem-enc-keypair: " + str(local_dict['oem_enc_keypair']) + "\n")
+     
+    if config.has_option(section_name, 'oem-enc-keypwd'): #used for testing
+            local_dict['oem_enc_keypwd'] = str.encode(config.get(section_name, 'oem-enc-keypwd'))
+            log_sync(log_file,"oem-enc-keypwd: " + str(local_dict['oem_enc_keypwd']) + "\n")
+    else:
+        local_dict['oem_enc_keypwd'] = ''
+
+    local_dict['asset_filename'] = config.get(section_name, 'asset-filename')
+    log_sync(log_file,"asset-filename: " + str(local_dict['asset_filename']) + "\n")
+
+    local_dict['pkg_filename'] = str.encode(config.get(section_name, 'pkg-filename'))
+    log_sync(log_file,"pkg-filename: " + str(local_dict['pkg_filename']) + "\n")
+
+    return local_dict
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "asset_prov.log"
+    return config_fname, log_fname
+
+def main():
+
+    config_fname, log_fname = parse_shell_arguments()
+    log_file = create_log_file(log_fname)
+    print_and_log(log_file, str(datetime.now()) + ": OEM Asset provisioning Utility started (Logging to " + log_fname + ")\n")
+
+    DLLHandle = LoadDLLGetHandle(UTILITY_LIB_Name)
+    
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        log_file.close()
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.read(config_fname)
+    data_dict = {}
+
+    data_dict = parse_config_file(config, log_file)
+
+    if (data_dict != None):
+        # Get assets and encrypted key from files
+        asset_size, assetStr = GetDataFromBinFile(log_file, data_dict['asset_filename'])
+        if (asset_size != ASSET_SIZE) :
+                print_and_log(log_file, "invalid asset size \n")
+                exit_main_func(log_file, config_file, 1)
+
+        encKey_size, encKey_Str = GetDataFromBinFile(log_file, data_dict['icv_enc_oem_key'])
+        if (encKey_size != PUBKEY_SIZE_BYTES) :
+                print_and_log(log_file, "invalid key size \n")
+                exit_main_func(log_file, config_file, 1)
+
+
+        print_and_log(log_file, "**** Generate DMPU Asset package ****\n")        
+
+        result = DLLHandle.build_oem_asset_pkg(data_dict['oem_enc_keypair'], data_dict['oem_enc_keypwd'],
+                          encKey_Str, encKey_size,
+                         data_dict['asset_type'],
+                         assetStr, asset_size,
+                         data_dict['pkg_filename'])
+        if result != 0:
+            raise NameError
+       
+        print_and_log(log_file, "**** Generate OEM asset package completed successfully ****\n")
+        exit_main_func(log_file, config_file, 0)
+
+    else:
+        print_and_log(log_file, "**** Invalid config file ****\n")
+        exit_main_func(log_file, config_file, 1)
+
+    FreeDLLGetHandle(DLLHandle)
+
+#############################
+if __name__ == "__main__":
+    main()
+
+
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/examples/asset_oem_ce.cfg b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/examples/asset_oem_ce.cfg
new file mode 100644
index 0000000..7c02cea
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/examples/asset_oem_ce.cfg
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for generating asset package for production phase application - DMPU
+# [DMPU-OEM-ASSET-CFG]        Mandatory header.
+#asset-type = defines the asset type encryptin key or provisioning key <kcp|kce>
+#icv-enc-oem-key =            The file containing the encrypted oem key, generated by dmpu_icv_key_response_util.py.
+# oem-enc-keypair =        File holding the RSA keypair for decrypting " oem-enc-keypair", in pem format.
+# oem-enc-keypwd =    Passphrase for the "oem-enc-keypair" file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#asset-filename =       The asset to create the package for
+#pkg-filename =            The package file, generated by dmpu_asset_pkg_util.py.
+ [DMPU-OEM-ASSET-CFG]
+asset-type = kce
+icv-enc-oem-key = icv_response_pkg.bin
+oem-enc-keypair =  oem_enc_key_pair.pem
+oem-enc-keypwd = oem_enc_key_pair_pwd.txt
+asset-filename = oem_enc_asset.bin
+pkg-filename = oem_enc_asset_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/examples/asset_oem_cp.cfg b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/examples/asset_oem_cp.cfg
new file mode 100644
index 0000000..823b7a9
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/examples/asset_oem_cp.cfg
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for generating asset package for production phase application - DMPU
+# [DMPU-OEM-ASSET-CFG]        Mandatory header.
+#asset-type = defines the asset type encryptin key or provisioning key <kcp|kce>
+#icv-enc-oem-key =            The file containing the encrypted oem key, generated by dmpu_icv_key_response_util.py.
+# oem-enc-keypair =        File holding the RSA keypair for decrypting " oem-enc-keypair", in pem format.
+# oem-enc-keypwd =    Passphrase for the "oem-enc-keypair" file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+#asset-filename =       The asset to create the package for
+#pkg-filename =            The package file, generated by dmpu_asset_pkg_util.py.
+ [DMPU-OEM-ASSET-CFG]
+asset-type = kcp
+icv-enc-oem-key = icv_response_pkg.bin
+oem-enc-keypair =  oem_enc_key_pair.pem
+oem-enc-keypwd = oem_enc_key_pair_pwd.txt
+asset-filename = oem_prov_asset.bin
+pkg-filename = oem_prov_asset_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/lib/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/lib/Makefile
new file mode 100644
index 0000000..529bc36
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/lib/Makefile
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for building sbu_crypto library
+SH_LIB_NAME = lib_oem_asset_pkg.so
+
+LIB_SRC_O = main.o dmpu_common.o common_crypto_asym.o  common_crypto_sym.o common_rsa_keypair_util.o common_rsa_keypair.o common_util_files.o
+
+UTILS_ROOT = $(shell pwd)/../../../..
+SHARED_DIR = $(UTILS_ROOT)/../shared
+HOSTSRC_DIR = $(UTILS_ROOT)/../host/src
+UTILS_LIB_PATH = $(UTILS_ROOT)/lib
+UTILS_INC_PATH = $(SHARED_DIR)/include $(SHARED_DIR)/include/proj/$(PROJ_PRD) $(UTILS_ROOT)/include
+UTILS_INC_PATH += $(UTILS_ROOT)/src/common $(HOSTSRC_DIR)/cc3x_productionlib/common $(UTILS_ROOT)/src/dmpu_asset_pkg_util/common $(SHARED_DIR)/include/pal $(SHARED_DIR)/include/pal/$(TEE_OS)
+
+CFLAGS += -fPIC $(foreach incdir,$(UTILS_INC_PATH),-I$(incdir)) -c
+
+all: $(SH_LIB_NAME)
+
+# Compile and link the sbu_crypto library with hard-coded library run path to utils/lib
+# (to assure the private version of openssl libraries are used)
+$(SH_LIB_NAME): $(LIB_SRC_O)
+	gcc -shared -o $(SH_LIB_NAME) $(LIB_SRC_O) -Wl,-rpath,$(UTILS_LIB_PATH) -lcrypto -lssl
+
+vpath %.c $(UTILS_ROOT)/src/common $(UTILS_ROOT)/src/dmpu_asset_pkg_util/common
+
+%.o: %.c
+	gcc $(CFLAGS) $<
+
+clean:
+	rm -f $(SH_LIB_NAME) $(LIB_SRC_O)
+
+.PHONY: clean all
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/lib/main.c b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/lib/main.c
new file mode 100644
index 0000000..f898ee3
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_asset_package/lib/main.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_util_log.h"
+#include "common_crypto_asym.h"
+#include "common_crypto_sym.h"
+#include "common_rsa_keypair_util.h"
+#include "common_util_files.h"
+#include "dmpu_utils.h"
+#include "cc_production_asset.h"
+
+
+/**
+* @brief Build the ICV asset package using openSSL library
+*
+* @param[in]  encKeyBuff & encKeyBuffSize & pKeyPwdFileName - the encryptes Kpicv key
+*           assetId - Asset ID, used for Kprov derivation
+*           asset & assetSize - The Asset to generate the package for
+*               pPkgFileName - OUT - the asset package binary
+*               file name
+* @param[out] None
+*
+*/
+/*********************************************************/
+int build_oem_asset_pkg(char *pKeyFileName, char *pKeyPwdFileName,
+                    char *encKeyBuff, uint32_t encKeyBuffSize,
+        uint32_t assetType,
+        uint8_t *asset, uint32_t assetSize,
+    char *pPkgFileName)
+{
+    int rc = 0;
+    uint8_t keyTmp[PROD_KEY_TMP_KEY_SIZE] = {0};
+    uint8_t keyProv[PROD_KPROV_KEY_SIZE] = {0};
+    uint8_t keyProvContext[PROD_KPROV_CONTEXT_SIZE] = {0};
+    uint8_t i = 0;
+    CCProdAssetPkg_t  assetPackage = {0};
+    uint32_t assetPkgSize = sizeof(CCProdAssetPkg_t);
+        uint8_t label[] = PROD_LABEL;
+
+    // Verify Inputs
+    UTIL_LOG_ERR( "encKeyBuffSize %d\n", encKeyBuffSize);
+    if ((encKeyBuff == NULL) ||
+        (encKeyBuffSize != SB_CERT_RSA_KEY_SIZE_IN_BYTES) ||
+        ((assetType != PROD_ASSET_TYPE_KCE)  && (assetType != PROD_ASSET_TYPE_KCP))||
+        (pKeyFileName == NULL) ||
+        (pKeyPwdFileName == NULL) ||
+        (asset == NULL) ||
+        (assetSize != PROD_ASSET_SIZE) ||
+        (pPkgFileName == NULL)) {
+        UTIL_LOG_ERR( "Invalid inputs\n");
+        return 1;
+    }
+
+    InitOpenSsl();
+
+    // Build the package header
+    assetPackage.token = PROD_ASSET_PROV_TOKEN;
+    assetPackage.version = PROD_ASSET_PROV_VERSION;
+    assetPackage.assetSize = assetSize;
+        assetPackage.reserved[0] = PROD_ASSET_RESERVED1_VAL;
+        assetPackage.reserved[1] = PROD_ASSET_RESERVED2_VAL;
+        rc = CC_CommonRandBytes(PROD_ASSET_NONCE_SIZE, (uint8_t *)assetPackage.nonce);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonRandBytes() for nonce, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+    // Decrypt temporary key created by ICV
+    rc = CC_CommonRsaDecrypt(RSA_USE_PKCS_21_VERSION,
+              pKeyFileName, pKeyPwdFileName,
+              encKeyBuff, encKeyBuffSize,
+              keyTmp) ;
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonRsaDecrypt() for key temp, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+
+        if (assetType == PROD_ASSET_TYPE_KCE) {
+                memcpy(keyProvContext, PROD_OEM_ENC_CONTEXT, PROD_KPROV_CONTEXT_SIZE);
+        } else { // PROD_ASSET_TYPE_KCP
+                memcpy(keyProvContext, PROD_OEM_PROV_CONTEXT, PROD_KPROV_CONTEXT_SIZE);
+        }
+
+        // Calculate Kprov= cmac(Ktmp, 0x01 || "P"  || 0x0 || asset_id || 0x80)
+    rc = AesCmacKeyDerivation(keyTmp, PROD_KEY_TMP_KEY_SIZE,
+                label,  PROD_KPROV_LABEL_SIZE,
+                keyProvContext, PROD_KPROV_CONTEXT_SIZE,
+                keyProv, PROD_KPROV_KEY_SIZE);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to AesCmacKeyDerivation() for Kprov, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+    // Encrypt and authenticate the asset
+    rc = CC_CommonAesCcmEncrypt(keyProv,
+                (uint8_t *)assetPackage.nonce, PROD_ASSET_NONCE_SIZE,
+                (uint8_t *)&assetPackage, PROD_ASSET_ADATA_SIZE,
+                asset, assetSize,
+                (uint8_t *)assetPackage.encAsset, &assetSize,
+                                ((uint8_t *)assetPackage.encAsset)+assetSize, PROD_ASSET_TAG_SIZE);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonAesCmacEncrypt() for Kprov, rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+    // Writing the asset package into bin file
+    rc = CC_CommonUtilCopyBuffToBinFile(pPkgFileName, (uint8_t *)&assetPackage, assetPkgSize);
+    if (rc != 0) {
+        UTIL_LOG_ERR( "failed to CC_CommonUtilCopyBuffToBinFile(), rc %d\n", rc);
+        rc = 1;
+        goto end_func;
+    }
+
+end_func:
+    CloseOpenSsl();
+    UTIL_LOG_ERR( "End rc %d\n", rc);
+    return rc;
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/Makefile
new file mode 100644
index 0000000..78ec76c
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/Makefile
@@ -0,0 +1,48 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for managing build and installation
+
+# shared library to build
+UTIL_ROOT = $(shell pwd)
+UTILS_DIR_ROOT = $(UTIL_ROOT)/../../..
+HOST_DIR_ROOT = $(UTILS_DIR_ROOT)/../host
+UTILS_LIB_PATH = ./lib
+UTILS_LIB_NAME = lib_oem_key_request.so
+UTILS_SCRIPTS_DIRNAME = $(UTIL_ROOT)
+
+
+DEPENDENCY_ON_EXISTENCE_OF = $(filter-out $(wildcard $(1)), $(1))
+
+INSTALL_LIST = install_lib install_scripts
+
+all:   $(INSTALL_LIST)
+
+install_lib: build_lib $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/lib)
+	@echo Installing dmpu_oem_key_request_util library
+	@cp $(UTILS_LIB_PATH)/$(UTILS_LIB_NAME) $(UTILS_DIR_ROOT)/lib
+
+build_lib:
+	@echo build_lib for dmpu_oem_key_request_util.py.
+	@make -C $(UTILS_LIB_PATH)
+
+install_scripts: $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin)  $(call DEPENDENCY_ON_EXISTENCE_OF,$(UTILS_DIR_ROOT)/bin/example)
+	@echo Installing scripts for dmpu_oem_key_request_util.py.
+	@cp $(UTIL_ROOT)/../common/*.py $(UTILS_DIR_ROOT)/bin
+	@cp $(UTIL_ROOT)/*.py $(UTILS_DIR_ROOT)/bin
+	@cp $(UTIL_ROOT)/examples/*.cfg $(UTILS_DIR_ROOT)/bin/example
+
+$(UTILS_DIR_ROOT)/%:
+	@echo Creating directory  for dmpu package
+	@mkdir $@
+
+
+clean:
+	@make -C $(UTILS_LIB_PATH) clean
+
+.PHONY: install_lib install_sd_scripts clean
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/dmpu_oem_key_request_util.py b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/dmpu_oem_key_request_util.py
new file mode 100755
index 0000000..4a7ddc6
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/dmpu_oem_key_request_util.py
@@ -0,0 +1,142 @@
+#!/usr/local/bin/python3
+#
+# Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+# This utility builds key request certifiacte sent from OEM to ICV:
+# the package Header format is:
+#                       token, version, length, 
+#                       certifiacte main PubKey (pub key)
+#                       certifiacte encryption PubKey (pub key)
+#                       certSign
+
+
+import sys
+# Definitions for paths
+if sys.platform != "win32" :
+    path_div = "//"    
+else : #platform = win32
+    path_div = "\\"
+
+
+CURRENT_PATH = sys.path[0]
+# In case the scripts were run from current directory
+CURRENT_PATH_SCRIPTS = path_div
+# this is the scripts local path, from where the program was called
+sys.path.append(CURRENT_PATH+CURRENT_PATH_SCRIPTS)
+
+import configparser
+from dmpu_util_helper import *
+from dmpu_util_crypto_helper import *
+import sys
+
+# Parse given test configuration file and return test attributes as dictionary
+def parse_config_file (config, log_file):
+    local_dict = {}
+    section_name = "DMPU-OEM-KEY-REQ-CFG"
+    if not config.has_section(section_name):
+        log_sync(log_file, "section " + section_name + " wasn't found in cfg file\n")
+        return None
+
+    local_dict['main_keypair_filename'] = config.get(section_name, 'oem-main-keypair')
+    log_sync(log_file,"oem-main-keypair: " + str(local_dict['main_keypair_filename']) + "\n")
+     
+    if config.has_option(section_name, 'oem-main-keypwd'): #used for testing
+            local_dict['main_keypwd_filename'] = config.get(section_name, 'oem-main-keypwd')
+            log_sync(log_file,"oem-main-keypwd: " + str(local_dict['main_keypwd_filename']) + "\n")
+    else:
+        local_dict['main_keypwd_filename'] = ''
+
+    local_dict['enc_pubkey_filename'] = config.get(section_name, 'oem-enc-pubkey')
+    log_sync(log_file,"oem-enc-pubkey: " + str(local_dict['enc_pubkey_filename']) + "\n")
+
+    local_dict['cert_pkg_filename'] = str.encode(config.get(section_name, 'oem-cert-pkg'))
+    log_sync(log_file,"oem-cert-pkg: " + str(local_dict['cert_pkg_filename']) + "\n")
+
+    return local_dict
+
+
+# Parse script parameters
+def parse_shell_arguments ():
+    len_arg =  len(sys.argv)
+    if len_arg < 2:
+        print_sync("len " + str(len_arg) + " invalid. Usage:" + sys.argv[0] + "<test configuration file>\n")
+        for i in range(1,len_arg):
+            print_sync("i " + str(i) + " arg " + sys.argv[i] + "\n")
+        sys.exit(1)
+    config_fname = sys.argv[1]
+    if len_arg == 3:
+        log_fname = sys.argv[2]
+    else:
+        log_fname = "key_request_cert.log"
+    return config_fname, log_fname
+
+
+def main():
+
+    config_fname, log_fname = parse_shell_arguments()
+    log_file = create_log_file(log_fname)
+    print_and_log(log_file, str(datetime.now()) + ": OEM key request Utility started (Logging to " + log_fname + ")\n")
+
+    UTILITY_LIB_Name = SBU_CRYPTO_LIB_DIR + "/" + "lib_oem_key_request.so"
+    DLLHandle = LoadDLLGetHandle(UTILITY_LIB_Name)
+    
+    try:
+        config_file = open(config_fname, 'r')
+    except IOError as e:
+        print_and_log(log_file,"Failed opening " + config_fname + " (" + e.strerror + ")\n")
+        log_file.close()
+        sys.exit(e.errno)
+
+    config = configparser.ConfigParser()
+    config.read(config_fname)
+    data_dict = {}
+
+    data_dict = parse_config_file(config, log_file)
+
+    if (data_dict != None):
+         certStrBin = str()
+         dataToSign = str()
+         print_and_log(log_file, "**** Generate OEM key requesting certificate ****\n")        
+
+         token = DMPU_OEM_KEY_REQ_TOKEN
+         certVersion = DMPU_OEM_KEY_REQ_VERSION
+         # token || version || size || main public key + Np || enc public key + Np
+         certLength = DMPU_CERT_HEADER_SIZE_IN_BYTES + PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES + PUBKEY_SIZE_BYTES + NP_SIZE_IN_BYTES
+
+         header = struct.pack('<I', token) + struct.pack('<I', certVersion) + struct.pack('<I', certLength)
+         dataToSign = byte2string(header)
+
+
+         # get the enabler certificate public key + Np
+         mainNPublicKey = GetRSAKeyParams(log_file, data_dict['main_keypair_filename'], data_dict['main_keypwd_filename'], DLLHandle)
+         dataToSign = dataToSign + mainNPublicKey.VarsToBinString()        
+
+         # get encrypted  public key  (from public key)
+         encNPublicKey = GetRSAPubKeyParams(log_file, data_dict['enc_pubkey_filename'], DLLHandle)
+         dataToSign = dataToSign + encNPublicKey.VarsToBinString()
+
+         # Do RSA signature  
+         Signature = GetRSASignature(log_file, dataToSign, data_dict['main_keypair_filename'], data_dict['main_keypwd_filename'], DLLHandle)
+
+         # Build the end of the certificate - add the signature       
+         certStrBin = dataToSign + Signature.VarsToBinString()
+
+         # add signature and write to binary file
+         CreateCertBinFile(log_file, certStrBin, data_dict['cert_pkg_filename'])
+
+         print_and_log(log_file, "**** Generate OEM key requesting successfully ****\n")
+         exit_main_func(log_file, config_file, 0)
+    else:
+        print_and_log(log_file, "**** Invalid config file ****\n")
+        exit_main_func(log_file, config_file, 1)
+
+    FreeDLLGetHandle(DLLHandle)
+
+#############################
+if __name__ == "__main__":
+    main()
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/examples/dmpu_oem_key_request.cfg b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/examples/dmpu_oem_key_request.cfg
new file mode 100644
index 0000000..7ba9f66
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/examples/dmpu_oem_key_request.cfg
@@ -0,0 +1,19 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# This is configuration file example for generating key request certificate by OEM
+# [DMPU-OEM-KEY-REQ-CFG]        Mandatory header.
+# oem-main-keypair =        File holding the RSA keypair for signing this certificate, in pem format.
+# oem-main-keypwd =    Passphrase for the keypair file, in txt format.
+#                       For enhanced security, this parameter can be omitted, and then the utility will prompt for direct TTY input.
+# oem-enc-pubkey =    File holding the RSA public key for ICV to encrypt the requested key, in pem format.
+# oem-cert-pkg =            OEM key request certificate package output file. Binary format created by dmpu_oem_key_request_util.py.
+ [DMPU-OEM-KEY-REQ-CFG]
+oem-main-keypair =  oem_main_key_pair.pem
+oem-main-keypwd = oem_main_key_pair_pwd.txt
+oem-enc-pubkey =  oem_enc_pub_key.pem
+oem-cert-pkg = oem_request_pkg.bin
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/lib/Makefile b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/lib/Makefile
new file mode 100644
index 0000000..9faf46e
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/lib/Makefile
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Makefile for building sbu_crypto library
+SH_LIB_NAME = lib_oem_key_request.so
+
+LIB_SRC_O = main.o common_sb_ops.o common_rsa_keypair_util.o common_rsa_keypair.o common_util_files.o common_crypto_sym.o #common_crypto_asym.o
+
+UTILS_ROOT = $(shell pwd)/../../../..
+SHARED_DIR = $(UTILS_ROOT)/../shared
+HOSTSRC_DIR = $(UTILS_ROOT)/../host/src
+UTILS_LIB_PATH = $(UTILS_ROOT)/lib
+UTILS_INC_PATH = $(SHARED_DIR)/include $(SHARED_DIR)/include/proj/$(PROJ_PRD) $(UTILS_ROOT)/include
+UTILS_INC_PATH += $(UTILS_ROOT)/src/common $(HOSTSRC_DIR)/cc3x_productionlib/common $(SHARED_DIR)/include/pal  $(SHARED_DIR)/include/pal/$(TEE_OS)
+
+CFLAGS += -fPIC $(foreach incdir,$(UTILS_INC_PATH),-I$(incdir)) -c
+
+all: $(SH_LIB_NAME)
+
+# Compile and link the sbu_crypto library with hard-coded library run path to utils/lib
+# (to assure the private version of openssl libraries are used)
+$(SH_LIB_NAME): $(LIB_SRC_O)
+	gcc -shared -o $(SH_LIB_NAME) $(LIB_SRC_O) -Wl,-rpath,$(UTILS_LIB_PATH) -lcrypto -lssl
+
+vpath %.c $(UTILS_ROOT)/src/common
+
+%.o: %.c
+	gcc $(CFLAGS) $<
+
+clean:
+	rm -f $(SH_LIB_NAME) $(LIB_SRC_O)
+
+.PHONY: clean all
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/lib/main.c b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/lib/main.c
new file mode 100644
index 0000000..9d8aa06
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/dmpu_asset_pkg_util/oem_key_request/lib/main.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/bn.h>
+#include <openssl/aes.h>
+#include <openssl/err.h>
+#include "common_util_log.h"
+#include "common_crypto_asym.h"
+#include "common_crypto_sym.h"
+#include "common_util_files.h"
+#include "cc_production_asset.h"
+#include "common_sb_ops.h"
+
+#define Nullptr (void *)0
+
+/**
+ * @brief The SBU_RSA_Sign generates RSA signature and returns it.
+ *
+ * The function follows the steps:
+ * 1. Read RSA private key structure
+ * 2. Call function according to PKCS version to create RSA signature
+ *
+ * @param[in] pkcsVersion - the version used (according to global definitions of available versions)
+ * @param[in] DataIn_ptr - the data to sign on
+ * @param[in] DataInSize - the data size
+ * @param[in] PemEncryptedFileName_ptr - the private key file
+ * @param[in] pwdFileName - file name of the password
+ * @param[out] Signature_ptr - the RSA signature
+ *
+ */
+ /*********************************************************/
+SBUEXPORT_C int SBU_RSA_Sign(int pkcsVersion,
+                             char* DataIn_ptr,
+                             unsigned int DataInSize,
+                             char* PemEncryptedFileName_ptr,
+                             char* pwdFileName,
+                             char* Signature_ptr)
+{
+    RSA  *pRsaPrivKey = NULL;
+    unsigned char *pwd = NULL;
+    int  ret_code;
+
+    OpenSSL_add_all_algorithms ();
+
+    /* parse the passphrase for a given file */
+    if( strlen(pwdFileName) ) {
+        if(CC_CommonGetPassphrase(pwdFileName, &pwd) != 0){
+            printf("Failed to retrieve pwd\n");
+            if (pwd != NULL)
+                free(pwd);
+            return (-1);
+        }
+    }
+    else {
+        pwd = Nullptr;
+    }
+
+    if (CC_CommonGetKeyPair (&pRsaPrivKey, PemEncryptedFileName_ptr, pwd) < 0)
+    {
+        printf ("\nCC_CommonGetKeyPair Cannot read RSA private key\n");
+        return (-1);
+    }
+
+        ret_code = Sign_v21(pRsaPrivKey, DataIn_ptr, DataInSize, Signature_ptr);
+
+END:
+    EVP_cleanup();
+    return (ret_code);
+}
+
diff --git a/lib/ext/cryptocell-312-runtime/utils/src/proj.cfg b/lib/ext/cryptocell-312-runtime/utils/src/proj.cfg
new file mode 100644
index 0000000..f435860
--- /dev/null
+++ b/lib/ext/cryptocell-312-runtime/utils/src/proj.cfg
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2001-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Project configuration for cc312 utils
+PROJ_NAME = cc312
+# Default HW for ARM is the zc706
+PROJ_HW = zc706
+
+PROJ_PRD = cc3x
+TEE_OS = linux
+
+# List of targets to build for utils/src
+PROJ_TARGETS = cc3x_asset_prov_rt cc3x_boot_cert  cmpu_asset_pkg_util dmpu_asset_pkg_util
+
+CERT_ENDIANITY = 0
+CERT_VERSION_MAJOR = 1
+CERT_VERSION_MINOR = 0
+
+# Specific project definitions
+SPECIAL_ADDITIONAL_DATA_USED = 0
+CONFIG_SB_SUPPORT_IOT = 1