Merge pull request #4322 from dgarske/se050_branch

NXP SE050 Support
This commit is contained in:
Daniele Lacamera
2021-10-12 07:37:58 -07:00
committed by GitHub
20 changed files with 1789 additions and 9 deletions

View File

@ -1336,6 +1336,60 @@ AC_ARG_WITH([cryptoauthlib],
]
)
# NXP SE050
# Example: "./configure --with-se050=/home/pi/simw_top"
ENABLED_SE050="no"
trylibse050dir=""
AC_ARG_WITH([se050],
[AS_HELP_STRING([--with-se050=PATH],[PATH to SE050 install (default /usr/local/lib/)])],
[
AC_MSG_CHECKING([for SE050])
LIBS="$LIBS -lSSS_APIs"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fsl_sss_api.h>]], [[ sss_mac_init(0);]])],[ libse050_linked=yes ],[ libse050_linked=no ])
if test "x$libse050_linked" = "xno" ; then
if test "x$withval" != "xno" ; then
trylibse050dir=$withval
fi
if test "x$withval" = "xyes" ; then
trylibse050dir="/usr/local/lib/"
fi
LDFLAGS="$LDFLAGS -L$trylibse050dir/build/sss"
CPPFLAGS="$CPPFLAGS -I$trylibse050dir/build"
CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/inc"
CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/ex/inc"
CPPFLAGS="$CPPFLAGS -I$trylibse050dir/sss/port/default"
CPPFLAGS="$CPPFLAGS -I$trylibse050dir/hostlib/hostLib/inc"
CPPFLAGS="$CPPFLAGS -I$trylibse050dir/hostlib/hostLib/libCommon/infra"
AC_CHECK_FILES([$trylibse050dir/build/sss/libSSS_APIs.a], [SE050_STATIC=yes], [SE050_STATIC=no])
if test "x$SE050_STATIC" = "xyes"; then
LIB_STATIC_ADD="$trylibse050dir/build/sss/ex/src/libex_common.a \
$trylibse050dir/build/sss/libSSS_APIs.a \
$trylibse050dir/build/hostlib/hostLib/se05x/libse05x.a \
$trylibse050dir/build/hostlib/hostLib/liba7x_utils.a \
$trylibse050dir/build/hostlib/hostLib/libCommon/libsmCom.a $LIB_STATIC_ADD"
else
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fsl_sss_api.h>]], [[ sss_mac_init(0); ]])],[ libse050_linked=yes ],[ libse050_linked=no ])
if test "x$libse050_linked" = "xno" ; then
AC_MSG_ERROR([SE050 isn't found.
If it's already installed, specify its path using --with-se050=/dir/])
fi
fi
# Requires AES direct
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_DIRECT"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([yes])
fi
ENABLED_SE050="yes"
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SE050 -DSSS_USE_FTR_FILE"
]
)
# sniffer doesn't work in maxstrength mode
if test "$ENABLED_SNIFFER" = "yes" && test "$ENABLED_MAXSTRENGTH" = "yes"
@ -7035,6 +7089,7 @@ AM_CONDITIONAL([BUILD_RC2],[test "x$ENABLED_RC2" = "xyes"])
AM_CONDITIONAL([BUILD_QNXCAAM],[test "x$ENABLED_CAAM" = "xqnx"])
AM_CONDITIONAL([BUILD_IOTSAFE],[test "x$ENABLED_IOTSAFE" = "xyes"])
AM_CONDITIONAL([BUILD_IOTSAFE_HWRNG],[test "x$ENABLED_IOTSAFE_HWRNG" = "xyes"])
AM_CONDITIONAL([BUILD_SE050],[test "x$ENABLED_SE050" = "xyes"])
if test "$ax_enable_debug" = "yes" ||
test "$ENABLED_STACKSIZE" != "no" ||
@ -7409,6 +7464,7 @@ echo " * Crypto callbacks: $ENABLED_CRYPTOCB"
echo " * i.MX6 CAAM: $ENABLED_CAAM"
echo " * IoT-Safe: $ENABLED_IOTSAFE"
echo " * IoT-Safe HWRNG: $ENABLED_IOTSAFE_HWRNG"
echo " * NXP SE050: $ENABLED_SE050"
echo ""
echo "---"

View File

@ -68,7 +68,9 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#ifdef WOLFSSL_IMXRT_DCP
#include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
#endif
#ifdef WOLFSSL_SE050
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
/* fips wrapper calls, user can call direct */
#if defined(HAVE_FIPS) && \
@ -867,6 +869,28 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#elif defined(WOLFSSL_DEVCRYPTO_AES)
/* implemented in wolfcrypt/src/port/devcrypto/devcrypto_aes.c */
#elif defined(WOLFSSL_SE050)
static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock,
int sz)
{
return se050_aes_crypt(aes, inBlock, outBlock, sz, AES_ENCRYPTION,
kAlgorithm_SSS_AES_ECB);
}
static int AES_ECB_decrypt(Aes* aes, const byte* inBlock, byte* outBlock,
int sz)
{
return se050_aes_crypt(aes, inBlock, outBlock, sz, AES_DECRYPTION,
kAlgorithm_SSS_AES_ECB);
}
static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
{
return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
}
static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
{
return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE);
}
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES)
#include "hal_data.h"
@ -2576,6 +2600,35 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
return wc_AesSetKey(aes, userKey, keylen, iv, dir);
}
#elif defined(WOLFSSL_SE050)
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const byte* iv,
int dir)
{
int ret;
if (aes == NULL || (keylen != 16 && keylen != 24 && keylen != 32)) {
return BAD_FUNC_ARG;
}
aes->ctxInitDone = 0;
#if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \
defined(WOLFSSL_AES_OFB)
aes->left = 0;
#endif
ret = se050_aes_set_key(aes, userKey, keylen, iv, dir);
if (ret == 0) {
ret = wc_AesSetIV(aes, iv);
}
return ret;
}
int wc_AesSetKeyDirect(Aes* aes, const byte* userKey, word32 keylen,
const byte* iv, int dir)
{
return wc_AesSetKey(aes, userKey, keylen, iv, dir);
}
#elif defined(WOLFSSL_NRF51_AES)
int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen,
const byte* iv, int dir)
@ -3830,6 +3883,18 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
#elif defined(WOLFSSL_DEVCRYPTO_CBC)
/* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */
#elif defined(WOLFSSL_SE050)
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
return se050_aes_crypt(aes, in, out, sz, AES_ENCRYPTION,
kAlgorithm_SSS_AES_CBC);
}
int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
return se050_aes_crypt(aes, in, out, sz, AES_DECRYPTION,
kAlgorithm_SSS_AES_CBC);
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
/* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
@ -10331,6 +10396,11 @@ void wc_AesFree(Aes* aes)
XFREE(aes->streamData, aes->heap, DYNAMIC_TYPE_AES);
}
#endif
#if defined(WOLFSSL_SE050)
se050_aes_free(aes);
#endif
}

View File

@ -3943,6 +3943,8 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
err = silabs_ecc_shared_secret(private_key, public_key, out, outlen);
#elif defined(WOLFSSL_KCAPI_ECC)
err = KcapiEcc_SharedSecret(private_key, public_key, out, outlen);
#elif defined(WOLFSSL_SE050)
err = se050_ecc_shared_secret(private_key, public_key, out, outlen);
#else
err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
#endif /* WOLFSSL_ATECC508A */
@ -4615,7 +4617,8 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
int err;
#if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC)
!defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_KCAPI_ECC) && \
!defined(WOLFSSL_SE050)
#if !defined(WOLFSSL_SP_MATH)
DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
#endif
@ -4698,6 +4701,9 @@ int wc_ecc_make_key_ex2(WC_RNG* rng, int keysize, ecc_key* key, int curve_id,
else {
err = NOT_COMPILED_IN;
}
#elif defined(WOLFSSL_SE050)
err = se050_ecc_create_key(key, curve_id, keysize);
key->type = ECC_PRIVATEKEY;
#elif defined(WOLFSSL_CRYPTOCELL)
pDomain = CRYS_ECPKI_GetEcDomain(cc310_mapCurve(key->dp->id));
@ -5002,6 +5008,11 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
#if defined(WOLFSSL_DSP)
key->handle = -1;
#endif
#ifdef WOLFSSL_SE050
key->keyId = -1;
#endif
return ret;
}
@ -5098,7 +5109,8 @@ static int wc_ecc_get_curve_order_bit_count(const ecc_set_type* dp)
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC)
defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
defined(WOLFSSL_SE050)
static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
mp_int* r, mp_int* s, byte* out, word32 *outlen, WC_RNG* rng,
ecc_key* key)
@ -5183,6 +5195,12 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
#elif defined(WOLFSSL_KCAPI_ECC)
err = KcapiEcc_Sign(key, in, inlen, out, outlen);
(void)rng;
#elif defined(WOLFSSL_SE050)
err = se050_ecc_sign_hash_ex(in, inlen, out, outlen, key);
if (err == 0)
err = DecodeECC_DSA_Sig(out, *outlen, r, s);
return err;
#endif
/* Load R and S */
@ -5357,7 +5375,8 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
/* hardware crypto */
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A) || \
defined(PLUTON_CRYPTO_ECC) || defined(WOLFSSL_CRYPTOCELL) || \
defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC)
defined(WOLFSSL_SILABS_SE_ACCEL) || defined(WOLFSSL_KCAPI_ECC) || \
defined(WOLFSSL_SE050)
err = wc_ecc_sign_hash_hw(in, inlen, r, s, out, outlen, rng, key);
#else
err = wc_ecc_sign_hash_ex(in, inlen, rng, key, r, s);
@ -6280,6 +6299,10 @@ int wc_ecc_free(ecc_key* key)
}
#endif
#ifdef WOLFSSL_SE050
se050_ecc_free_key(key);
#endif
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
atmel_ecc_free(key->slot);
key->slot = ATECC_INVALID_SLOT;
@ -6952,6 +6975,12 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
#elif defined(WOLFSSL_KCAPI_ECC)
byte sigRS[MAX_ECC_BYTES*2];
#elif defined(WOLFSSL_SE050)
#ifdef WOLFSSL_SMALL_STACK
byte* sigRS = NULL;
#else
byte sigRS[ECC_MAX_CRYPTO_HW_SIZE * 2];
#endif
#elif !defined(WOLFSSL_SP_MATH) || defined(FREESCALE_LTC_ECC)
int did_init = 0;
ecc_point *mG = NULL, *mQ = NULL;
@ -7095,6 +7124,42 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
}
err = KcapiEcc_Verify(key, hash, hashlen, sigRS, key->dp->size * 2);
#elif defined(WOLFSSL_SE050)
{
/* Used when following a hardware sign operation */
int rLeadingZero = mp_leading_bit(r);
int sLeadingZero = mp_leading_bit(s);
int rLen = mp_unsigned_bin_size(r);
int sLen = mp_unsigned_bin_size(s);
word32 signatureLen = rLeadingZero + sLeadingZero +
rLen + sLen + SIG_HEADER_SZ; /* see StoreECC_DSA_Sig */
#ifdef WOLFSSL_SMALL_STACK
sigRS = (byte*)XMALLOC(signatureLen, NULL, DYNAMIC_TYPE_SIGNATURE);
if (sigRS == NULL) {
err = MEMORY_E;
}
#else
if (signatureLen > sizeof(sigRS)) {
err = BUFFER_E;
}
#endif
if (err == 0) {
err = StoreECC_DSA_Sig(sigRS, &signatureLen, r, s);
}
if (err == 0) {
err = se050_ecc_verify_hash_ex(hash, hashlen, sigRS,
signatureLen, key, res);
}
#ifdef WOLFSSL_SMALL_STACK
if (sigRS != NULL) {
XFREE(sigRS, NULL, DYNAMIC_TYPE_SIGNATURE);
sigRS = NULL;
}
#endif
if (err != 0)
return err;
}
#else
/* checking if private key with no public part */
if (key->type == ECC_PRIVATEKEY_ONLY) {

View File

@ -262,6 +262,13 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
word32 *outLen, ed25519_key* key, byte type,
const byte* context, byte contextLen)
{
int ret;
#ifdef WOLFSSL_SE050
(void)context;
(void)contextLen;
(void)type;
ret = se050_ed25519_sign_msg(in, inLen, out, outLen, key);
#else
#ifdef FREESCALE_LTC_ECC
byte tempBuf[ED25519_PRV_KEY_SIZE];
ltc_pkha_ecc_point_t ltcPoint = {0};
@ -271,7 +278,6 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
byte nonce[WC_SHA512_DIGEST_SIZE];
byte hram[WC_SHA512_DIGEST_SIZE];
byte az[ED25519_PRV_KEY_SIZE];
int ret;
/* sanity check on arguments */
if (in == NULL || out == NULL || outLen == NULL || key == NULL ||
@ -406,7 +412,7 @@ int wc_ed25519_sign_msg_ex(const byte* in, word32 inLen, byte* out,
sc_reduce(hram);
sc_muladd(out + (ED25519_SIG_SIZE/2), hram, az, nonce);
#endif
#endif /* WOLFSSL_SE050 */
return ret;
}
@ -492,7 +498,7 @@ int wc_ed25519ph_sign_msg(const byte* in, word32 inLen, byte* out,
#endif /* HAVE_ED25519_SIGN */
#ifdef HAVE_ED25519_VERIFY
#ifndef WOLFSSL_SE050
/*
sig is array of bytes containing the signature
sigLen is the length of sig byte array
@ -633,6 +639,7 @@ static int ed25519_verify_msg_final_with_sha(const byte* sig, word32 sigLen,
return ret;
}
#endif /* WOLFSSL_SE050 */
#ifdef WOLFSSL_ED25519_STREAMING_VERIFY
@ -670,6 +677,13 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
byte type, const byte* context, byte contextLen)
{
int ret;
#ifdef WOLFSSL_SE050
(void)type;
(void)context;
(void)contextLen;
(void)ed25519Ctx;
ret = se050_ed25519_verify_msg(sig, sigLen, msg, msgLen, key, res);
#else
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
wc_Sha512 *sha;
#else
@ -709,7 +723,7 @@ int wc_ed25519_verify_msg_ex(const byte* sig, word32 sigLen, const byte* msg,
#ifndef WOLFSSL_ED25519_PERSISTENT_SHA
ed25519_hash_free(key, sha);
#endif
#endif /* WOLFSSL_SE050 */
return ret;
}
@ -813,6 +827,10 @@ int wc_ed25519_init_ex(ed25519_key* key, void* heap, int devId)
fe_init();
#endif
#ifdef WOLFSSL_SE050
se050_ed25519_create_key(key);
#endif
#ifdef WOLFSSL_ED25519_PERSISTENT_SHA
return ed25519_hash_init(key, &key->sha);
#else /* !WOLFSSL_ED25519_PERSISTENT_SHA */
@ -835,6 +853,10 @@ void wc_ed25519_free(ed25519_key* key)
ed25519_hash_free(key, &key->sha);
#endif
#ifdef WOLFSSL_SE050
se050_ed25519_free_key(key);
#endif
ForceZero(key, sizeof(ed25519_key));
}

View File

@ -68,6 +68,8 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
wolfcrypt/src/port/arm/armv8-32-sha512-asm.c \
wolfcrypt/src/port/nxp/ksdk_port.c \
wolfcrypt/src/port/nxp/dcp_port.c \
wolfcrypt/src/port/nxp/se050_port.c \
wolfcrypt/src/port/nxp/README.md \
wolfcrypt/src/port/atmel/README.md \
wolfcrypt/src/port/xilinx/xil-sha3.c \
wolfcrypt/src/port/xilinx/xil-aesgcm.c \
@ -174,3 +176,7 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_qnx.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_ecdsa.c
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/caam/wolfcaam_cmac.c
endif
if BUILD_SE050
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/nxp/se050_port.c
endif

View File

@ -0,0 +1,114 @@
# NXP Ports
Support for the NXP DCP, KSDK and SE050 hardware acceleration boards.
## NXP SE050
Support for the SE050 on-board crypto hardware acceleration for symmetric AES, SHA1/SHA256/SHA384/SHA512, ECC (including ed25519) and RNG.
## SE050 Acceleration
For details about SE050 HW acceleration, see [NXP's SE050 page](https://www.nxp.com/products/security-and-authentication/authentication/edgelock-se050-plug-trust-secure-element-family-enhanced-iot-security-with-maximum-flexibility:SE050).
## Building simw-top
The code required to communicate with the SE050 is the `EdgeLock SE05x Plug & Trust Middleware (03.03.00)`, which can be found here [link](https://www.nxp.com/products/security-and-authentication/authentication/edgelock-se050-plug-trust-secure-element-family-enhanced-iot-security-with-maximum-flexibility:SE050?tab=Design_Tools_Tab) (An NXP account is required to download).
Follow the build instruction in AN12570 (EdgeLockTM SE05x Quick start guide with Raspberry Pi) [here](https://www.nxp.com/docs/en/application-note/AN12570.pdf).
In summary here are the steps for building:
```
# from simw-top directory
mkdir build
cd build
ccmake ..
# Change:
# `Host OS` to `Raspbian`
# `Host Crypto` to `None`
# `SMCOM` to `T1oI2C`
c # to configure
q
make
```
## Building wolfSSL
To enable support run:
``sh
./configure --with-se050=PATH
make
``
Where `PATH` is the directory location of `simw-top`.
Example: `./configure --enable-debug --disable-shared --with-se050=/home/pi/simw-top CFLAGS="-DWOLFSSL_SE050_INIT"`
## Building Examples
Confirm that you are able to run the examples from the directory:
``sh
/simw-top_build/raspbian_native_se050_t1oi2c/bin/
``
Modify one of those examples in order to tie into wolfSSL. The `./se05x_Minimal` is the easiest one to modify.
Open the `simw-top/demos/se05x/se05x_Minimal` directory and edit `se05x_Minimal.c`. Add these headers to source file:
``c
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
``
If you would like to run our wolfcrypt test or benchmark tool, add: `#include "test.h"` or `#include benchmark.h`.
Below is the code that was replaced in `ex_sss_entry()` to run the wolfcrypt test:
``c
sss_status_t status = kStatus_SSS_Success;
int ret;
sss_session_t *pSession2 = (sss_session_t *)&pCtx->session;
sss_key_store_t *pHostSession = (sss_key_store_t *)&pCtx->host_ks;
LOG_I("running setconfig");
ret = wc_se050_set_config(pSession2, pHostSession);
if (ret != 0) {
return kStatus_SSS_Fail;
}
LOG_I("ran setconfig correctly");
wolfcrypt_test(NULL);
LOG_I("ran wolfcrypt test");
return status;
``
Note: `wolfcrypt_test(NULL);` can be replaced with `benchmark_test();`
The two variables used in `wc_se050_set_config` are session and key store variables that are required to reference parts of the hardware.
The Makefile needs to be edited. At the top of the Makefile, the base wolfssl directory needs to be added to `INCLUDE_FLAGS`.
Next, Inside `CFLAGS`, the `se05x_Minimal` directory needs to be added so that test.c and benchmark.c are included.
Finally, underneath 'all', test.c, test.h, benchmark.c and benchmark.h need to be added, along with `-L[wolfssl directory] -lwolfssl` at the end of the line.
### Wolfcrypt Test
To run the wolfcrypt test, two files, `test.h` and `test.c` need to be added to the `./se05x_Minimal` directory. These files can be found inside of `/wolfcrypt/test`.
Make sure `NO_MAIN_DRIVER` is defined to avoid `int main()` conflicts. Either in the Makefile or modify test.h to define it.
You should be able to run `wolfcrypt_test()` now.
### wolfCrypt Benchmark
To run the benchmark, both `benchmark.c` and `benchmark.h` need to be copied from wolfcrypt/benchmark to the `./se05x_Minimal` directory.
In addition, the entire `./certs` directory will need to copied into the directory.
Make sure `NO_MAIN_DRIVER` is defined to avoid `int main()` conflicts. Either in the Makefile or modify test.h to define it.
Now you can run `benchmark_test()`.
## Support
For questions please email support@wolfssl.com

File diff suppressed because it is too large Load Diff

View File

@ -2574,6 +2574,24 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
}
return 0;
}
#elif defined(WOLFSSL_SE050)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz){
int ret = 0;
(void)os;
if (output == NULL) {
return BUFFER_E;
}
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = se050_get_random_number(sz, output);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
#elif defined(DOLPHIN_EMULATOR)

View File

@ -336,6 +336,41 @@
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
/* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
#elif defined(WOLFSSL_SE050)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
{
if (sha == NULL) {
return BAD_FUNC_ARG;
}
(void)devId;
return se050_hash_init(&sha->se050Ctx, heap);
}
int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
{
return se050_hash_update(&sha->se050Ctx, data, len);
}
int wc_ShaFinal(wc_Sha* sha, byte* hash)
{
int ret = 0;
ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE,
kAlgorithm_SSS_SHA1);
(void)wc_InitSha(sha);
return ret;
}
int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
{
int ret = 0;
ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE,
kAlgorithm_SSS_SHA1);
(void)wc_InitSha(sha);
return ret;
}
#else
/* Software implementation */
@ -811,6 +846,9 @@ void wc_ShaFree(wc_Sha* sha)
#ifdef WOLFSSL_PIC32MZ_HASH
wc_ShaPic32Free(sha);
#endif
#ifdef WOLFSSL_SE050
se050_hash_free(&sha->se050Ctx);
#endif
#if (defined(WOLFSSL_RENESAS_TSIP_CRYPT) && \
!defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH))
if (sha->msg != NULL) {

View File

@ -184,7 +184,7 @@ where 0 <= L < 2^64.
(!defined(WOLFSSL_ESP32WROOM32_CRYPT) || defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)) && \
(!defined(WOLFSSL_RENESAS_TSIP_CRYPT) || defined(NO_WOLFSSL_RENESAS_TSIP_HASH)) && \
!defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
!defined(WOLFSSL_KCAPI_HASH)
!defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050)
static int InitSha256(wc_Sha256* sha256)
@ -597,6 +597,41 @@ static int InitSha256(wc_Sha256* sha256)
!defined(WOLFSSL_QNX_CAAM)
/* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
#elif defined(WOLFSSL_SE050)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
{
if (sha256 == NULL) {
return BAD_FUNC_ARG;
}
(void)devId;
return se050_hash_init(&sha256->se050Ctx, heap);
}
int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
{
return se050_hash_update(&sha256->se050Ctx, data, len);
}
int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
{
int ret = 0;
ret = se050_hash_final(&sha256->se050Ctx, hash, WC_SHA256_DIGEST_SIZE,
kAlgorithm_SSS_SHA256);
(void)wc_InitSha256(sha256);
return ret;
}
int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
{
int ret = 0;
ret = se050_hash_final(&sha256->se050Ctx, hash, WC_SHA256_DIGEST_SIZE,
kAlgorithm_SSS_SHA256);
(void)wc_InitSha256(sha256);
return ret;
}
#elif defined(WOLFSSL_AFALG_HASH)
/* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
@ -1388,6 +1423,32 @@ static int InitSha256(wc_Sha256* sha256)
return ret;
}
#elif defined(WOLFSSL_SE050)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
{
if (sha224 == NULL) {
return BAD_FUNC_ARG;
}
(void)devId;
return se050_hash_init(&sha224->se050Ctx, heap);
}
int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
{
return se050_hash_update(&sha224->se050Ctx, data, len);
}
int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
{
int ret = 0;
ret = se050_hash_final(&sha224->se050Ctx, hash, WC_SHA224_DIGEST_SIZE,
kAlgorithm_SSS_SHA224);
(void)wc_InitSha224(sha224);
return ret;
}
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
!defined(WOLFSSL_QNX_CAAM)

View File

@ -49,6 +49,10 @@
#include <wolfssl/wolfcrypt/cryptocb.h>
#endif
#ifdef WOLFSSL_SE050
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
/* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */
#if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512)
#define USE_SLOW_SHA512
@ -199,6 +203,60 @@
#elif defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050)
int wc_InitSha512(wc_Sha512* sha512)
{
if (sha512 == NULL)
return BAD_FUNC_ARG;
return se050_hash_init(&sha512->se050Ctx, NULL);
}
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
{
if (sha512 == NULL) {
return BAD_FUNC_ARG;
}
(void)devId;
return se050_hash_init(&sha512->se050Ctx, heap);
}
int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
{
return se050_hash_update(&sha512->se050Ctx, data, len);
}
int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
int devId = INVALID_DEVID;
if (sha512 == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLF_CRYPTO_CB
devId = sha512->devId;
#endif
ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE,
kAlgorithm_SSS_SHA512);
(void)wc_InitSha512_ex(sha512, sha512->heap, devId);
return ret;
}
int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
{
int ret = 0;
int devId = INVALID_DEVID;
if (sha512 == NULL) {
return BAD_FUNC_ARG;
}
#ifdef WOLF_CRYPTO_CB
devId = sha512->devId;
#endif
ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE,
kAlgorithm_SSS_SHA512);
(void)wc_InitSha512_ex(sha512, sha512->heap, devId);
return ret;
}
void wc_Sha512Free(wc_Sha512* sha512)
{
(void)sha512;
}
#else
#ifdef WOLFSSL_SHA512
@ -900,8 +958,10 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA384 */
#if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050)
#else
@ -1012,6 +1072,7 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512)
#if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050)
#else
@ -1083,6 +1144,7 @@ int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
#endif /* WOLFSSL_KCAPI_HASH */
#ifndef WOLFSSL_SE050
int wc_InitSha512(wc_Sha512* sha512)
{
return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID);
@ -1164,6 +1226,8 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
}
#endif /* OPENSSL_EXTRA */
#endif /* WOLFSSL_SHA512 */
#endif /* !WOLFSSL_SE050 */
/* -------------------------------------------------------------------------- */
/* SHA384 */
@ -1173,6 +1237,36 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
!defined(WOLFSSL_QNX_CAAM)
/* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
#elif defined(WOLFSSL_SE050)
int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
{
if (sha384 == NULL) {
return BAD_FUNC_ARG;
}
(void)devId;
return se050_hash_init(&sha384->se050Ctx, heap);
}
int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
{
return se050_hash_update(&sha384->se050Ctx, data, len);
}
int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
{
int ret = 0;
ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE,
kAlgorithm_SSS_SHA384);
(void)wc_InitSha384(sha384);
return ret;
}
int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
{
int ret = 0;
ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE,
kAlgorithm_SSS_SHA384);
(void)wc_InitSha384(sha384);
return ret;
}
#elif defined(WOLFSSL_SILABS_SHA512)
/* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */
@ -1478,8 +1572,10 @@ int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len)
{
return wc_Sha512Update(sha, data, len);
}
#if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050)
#else
int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash)
@ -1498,6 +1594,8 @@ void wc_Sha512_224Free(wc_Sha512* sha)
}
#if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050)
#else
int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
@ -1541,6 +1639,7 @@ int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len)
}
#if defined(WOLFSSL_KCAPI_HASH)
/* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
#elif defined(WOLFSSL_SE050)
#else
int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash)

View File

@ -91,6 +91,10 @@
#include <wolfssl/wolfcrypt/port/cavium/cavium_octeon_sync.h>
#endif
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT)
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#ifdef WOLFSSL_SCE
#include "hal_data.h"
#endif
@ -230,6 +234,10 @@ int wolfCrypt_Init(void)
ret = sl_se_init();
#endif
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_INIT)
ret = wc_se050_init(NULL);
#endif
#ifdef WOLFSSL_ARMASM
WOLFSSL_MSG("Using ARM hardware acceleration");
#endif

View File

@ -70,6 +70,10 @@ block cipher mechanism that uses n-bit binary string parameter key with 128-bits
#include "xsecure_aes.h"
#endif
#ifdef WOLFSSL_SE050
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#if defined(WOLFSSL_AFALG) || defined(WOLFSSL_AFALG_XILINX_AES)
/* included for struct msghdr */
#include <wolfssl/wolfcrypt/port/af_alg/wc_afalg.h>
@ -178,6 +182,12 @@ struct Aes {
word32 aadLen; /* additional authenticated data len */
#endif
#ifdef WOLFSSL_SE050
sss_symmetric_t aes_ctx; /* used as the function context */
int ctxInitDone;
int keyId;
#endif
#ifdef GCM_TABLE
/* key-based fast multiplication table. */
ALIGN16 byte M0[256][AES_BLOCK_SIZE];

View File

@ -66,6 +66,10 @@
#include <wolfssl/wolfcrypt/port/kcapi/kcapi_ecc.h>
#endif
#ifdef WOLFSSL_SE050
#include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
#endif
#ifdef WOLFSSL_HAVE_SP_ECC
#include <wolfssl/wolfcrypt/sp_int.h>
#endif
@ -168,8 +172,12 @@ enum {
CRYPTOCELL_KEY_SIZE = ECC_MAXSIZE,
#endif
ECC_MAX_CRYPTO_HW_SIZE = CRYPTOCELL_KEY_SIZE,
#elif defined(WOLFSSL_SE050)
ECC_MAX_CRYPTO_HW_SIZE = 32,
ECC_MAX_CRYPTO_HW_PUBKEY_SIZE = 64,
#endif
/* point compression type */
ECC_POINT_COMP_EVEN = 0x02,
ECC_POINT_COMP_ODD = 0x03,
@ -436,6 +444,9 @@ struct ecc_key {
word32 securePubKey; /* address of public key in secure memory */
int partNum; /* partition number*/
#endif
#ifdef WOLFSSL_SE050
int keyId;
#endif
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC608A)
int slot; /* Key Slot Number (-1 unknown) */
byte pubkey_raw[ECC_MAX_CRYPTO_HW_PUBKEY_SIZE];

View File

@ -85,6 +85,9 @@ struct ed25519_key {
/* uncompressed point coordinates */
byte pointX[ED25519_KEY_SIZE]; /* recovered X coordinate */
byte pointY[ED25519_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */
#endif
#ifdef WOLFSSL_SE050
int keyId;
#endif
word16 pubKeySet:1;
#ifdef WOLFSSL_ASYNC_CRYPT

View File

@ -78,6 +78,7 @@ noinst_HEADERS+= \
wolfssl/wolfcrypt/port/nrf51.h \
wolfssl/wolfcrypt/port/nxp/ksdk_port.h \
wolfssl/wolfcrypt/port/nxp/dcp_port.h \
wolfssl/wolfcrypt/port/nxp/se050_port.h \
wolfssl/wolfcrypt/port/xilinx/xil-sha3.h \
wolfssl/wolfcrypt/port/caam/caam_driver.h \
wolfssl/wolfcrypt/port/caam/caam_error.h \

View File

@ -0,0 +1,151 @@
/* se050_port.h
*
* Copyright (C) 2006-2021 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef _SE050_PORT_H_
#define _SE050_PORT_H_
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/visibility.h>
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wundef"
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#include "fsl_sss_se05x_types.h"
#include "fsl_sss_se05x_apis.h"
#if (SSS_HAVE_SSS > 1)
#include "fsl_sss_api.h"
#endif
#ifdef WOLFSSL_SE050
/* NXP SE050 - Disable SHA512 224/256 support */
#ifndef WOLFSSL_NOSHA512_224
#define WOLFSSL_NOSHA512_224
#endif
#ifndef WOLFSSL_NOSHA512_256
#define WOLFSSL_NOSHA512_256
#endif
#endif
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
/* Default key ID's */
#ifndef SE050_KEYID_AES
#define SE050_KEYID_AES 55
#endif
#ifndef SE050_KEYID_ECC_SIGN
#define SE050_KEYID_ECC_SIGN 56
#endif
#ifndef SE050_KEYID_ECC_VERIFY
#define SE050_KEYID_ECC_VERIFY 57
#endif
#ifndef SE050_KEYID_ED25519
#define SE050_KEYID_ED25519 58
#endif
enum {
SSS_BLOCK_SIZE = 512
};
enum SE050KeyType {
SE050_KEYID_ANY,
SE050_AES_KEY,
SE050_ECC_SIGN,
SE050_ECC_VERIFY,
SE050_ED25519,
};
typedef struct {
void* heap;
byte* msg;
word32 used;
word32 len;
} SE050_HASH_Context;
/* Public Functions */
WOLFSSL_API int wc_se050_set_config(sss_session_t *pSession,
sss_key_store_t *pHostKeyStore, sss_key_store_t *pKeyStore);
#ifdef WOLFSSL_SE050_INIT
WOLFSSL_API int wc_se050_init(const char* portName);
#endif
/* Private Functions */
WOLFSSL_LOCAL int se050_allocate_key(int keyType);
WOLFSSL_LOCAL int se050_get_random_number(uint32_t count, uint8_t* rand_out);
WOLFSSL_LOCAL int se050_hash_init(SE050_HASH_Context* se050Ctx, void* heap);
WOLFSSL_LOCAL int se050_hash_update(SE050_HASH_Context* se050Ctx,
const byte* data, word32 len);
WOLFSSL_LOCAL int se050_hash_final(SE050_HASH_Context* se050Ctx, byte* hash,
size_t digestLen, word32 algo);
WOLFSSL_LOCAL void se050_hash_free(SE050_HASH_Context* se050Ctx);
struct Aes;
WOLFSSL_LOCAL int se050_aes_set_key(struct Aes* aes, const byte* key,
word32 len, const byte* iv, int dir);
WOLFSSL_LOCAL int se050_aes_crypt(struct Aes* aes, const byte* in, byte* out,
word32 sz, int dir, sss_algorithm_t algorithm);
WOLFSSL_LOCAL void se050_aes_free(struct Aes* aes);
struct ecc_key;
struct WC_RNG;
#ifdef WOLFSSL_SP_MATH
struct sp_int;
#define MATH_INT_T struct sp_int
#elif defined(USE_FAST_MATH)
struct fp_int;
#define MATH_INT_T struct fp_int
#else
struct mp_int;
#define MATH_INT_T struct mp_int
#endif
WOLFSSL_LOCAL int se050_ecc_sign_hash_ex(const byte* in, word32 inLen,
byte* out, word32 *outLen, struct ecc_key* key);
WOLFSSL_LOCAL int se050_ecc_verify_hash_ex(const byte* hash, word32 hashlen,
byte* signature, word32 signatureLen, struct ecc_key* key, int* res);
WOLFSSL_LOCAL int se050_ecc_create_key(struct ecc_key* key, int curve_id, int keySize);
WOLFSSL_LOCAL int se050_ecc_shared_secret(struct ecc_key* private_key,
struct ecc_key* public_key, byte* out, word32* outlen);
WOLFSSL_LOCAL int se050_ecc_free_key(struct ecc_key* key);
struct ed25519_key;
WOLFSSL_LOCAL int se050_ed25519_create_key(struct ed25519_key* key);
WOLFSSL_LOCAL void se050_ed25519_free_key(struct ed25519_key* key);
WOLFSSL_LOCAL int se050_ed25519_sign_msg(const byte* in, word32 inLen,
byte* out, word32 *outLen, struct ed25519_key* key);
WOLFSSL_LOCAL int se050_ed25519_verify_msg(const byte* signature,
word32 signatureLen, const byte* msg, word32 msgLen,
struct ed25519_key* key, int* res);
#endif /* _SE050_PORT_H_ */

View File

@ -110,10 +110,16 @@ enum {
#include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h"
#else
#if defined(WOLFSSL_SE050)
#include "wolfssl/wolfcrypt/port/nxp/se050_port.h"
#endif
/* Sha digest */
struct wc_Sha {
#ifdef FREESCALE_LTC_SHA
ltc_hash_ctx_t ctx;
#elif defined(WOLFSSL_SE050)
SE050_HASH_Context se050Ctx;
#elif defined(STM32_HASH)
STM32_HASH_Context stmCtx;
#elif defined(WOLFSSL_SILABS_SE_ACCEL)

View File

@ -144,10 +144,16 @@ enum {
#include "wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h"
#else
#if defined(WOLFSSL_SE050)
#include "wolfssl/wolfcrypt/port/nxp/se050_port.h"
#endif
/* wc_Sha256 digest */
struct wc_Sha256 {
#ifdef FREESCALE_LTC_SHA
ltc_hash_ctx_t ctx;
#elif defined(WOLFSSL_SE050)
SE050_HASH_Context se050Ctx;
#elif defined(STM32_HASH_SHA2)
STM32_HASH_Context stmCtx;
#elif defined(WOLFSSL_SILABS_SE_ACCEL)

View File

@ -138,6 +138,9 @@ enum {
#if defined(WOLFSSL_IMX6_CAAM) && !defined(WOLFSSL_QNX_CAAM)
#include "wolfssl/wolfcrypt/port/caam/wolfcaam_sha.h"
#else
#if defined(WOLFSSL_SE050)
#include "wolfssl/wolfcrypt/port/nxp/se050_port.h"
#endif
/* wc_Sha512 digest */
struct wc_Sha512 {
#ifdef WOLFSSL_PSOC6_CRYPTO
@ -170,6 +173,9 @@ struct wc_Sha512 {
#ifdef WOLFSSL_KCAPI_HASH
wolfssl_KCAPI_Hash kcapi;
#endif
#if defined(WOLFSSL_SE050)
SE050_HASH_Context se050Ctx;
#endif
#ifdef WOLF_CRYPTO_CB
int devId;
void* devCtx; /* generic crypto callback context */