mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-08-03 12:44:45 +02:00
Merge pull request #1815 from dgarske/atecc508_fixes
Fixes for ATECC508A
This commit is contained in:
46
configure.ac
46
configure.ac
@@ -788,6 +788,50 @@ fi
|
||||
AM_CONDITIONAL([BUILD_PKCALLBACKS], [ test "x$ENABLED_PKCALLBACKS" = "xyes" ])
|
||||
|
||||
|
||||
# Microchip/Atmel CryptoAuthLib
|
||||
ENABLED_CRYPTOAUTHLIB="no"
|
||||
trylibatcadir=""
|
||||
AC_ARG_WITH([cryptoauthlib],
|
||||
[AS_HELP_STRING([--with-cryptoauthlib=PATH],[PATH to CryptoAuthLib install (default /usr/)])],
|
||||
[
|
||||
AC_MSG_CHECKING([for cryptoauthlib])
|
||||
CPPFLAGS="$CPPFLAGS -DWOLFSSL_ATECC508A"
|
||||
LIBS="$LIBS -lcryptoauth"
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <cryptoauthlib.h>]], [[ atcab_init(0); ]])],[ libatca_linked=yes ],[ libatca_linked=no ])
|
||||
|
||||
if test "x$libatca_linked" == "xno" ; then
|
||||
if test "x$withval" != "xno" ; then
|
||||
trylibatcadir=$withval
|
||||
fi
|
||||
if test "x$withval" == "xyes" ; then
|
||||
trylibatcadir="/usr"
|
||||
fi
|
||||
|
||||
LDFLAGS="$LDFLAGS -L$trylibatcadir/lib"
|
||||
CPPFLAGS="$CPPFLAGS -I$trylibatcadir/lib"
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <cryptoauthlib.h>]], [[ atcab_init(0); ]])],[ libatca_linked=yes ],[ libatca_linked=no ])
|
||||
|
||||
if test "x$libatca_linked" == "xno" ; then
|
||||
AC_MSG_ERROR([cryptoauthlib isn't found.
|
||||
If it's already installed, specify its path using --with-cryptoauthlib=/dir/])
|
||||
fi
|
||||
|
||||
AM_LDFLAGS="$AM_LDFLAGS -L$trylibatcadir/lib"
|
||||
AM_CFLAGS="$AM_CFLAGS -I$trylibatcadir/lib"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
|
||||
ENABLED_CRYPTOAUTHLIB="yes"
|
||||
AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ATECC508A"
|
||||
]
|
||||
)
|
||||
AM_CONDITIONAL([BUILD_CRYPTOAUTHLIB], [test "x$ENABLED_CRYPTOAUTHLIB" = "xyes"])
|
||||
|
||||
|
||||
# sniffer doesn't work in maxstrength mode
|
||||
if test "$ENABLED_SNIFFER" = "yes" && test "$ENABLED_MAXSTRENGTH" = "yes"
|
||||
then
|
||||
@@ -3528,7 +3572,7 @@ AC_ARG_WITH([libz],
|
||||
trylibzdir="/usr"
|
||||
fi
|
||||
|
||||
AM_LDFLAGS="$AM_LDFLAGS -L$trylibzdir/lib"
|
||||
LDFLAGS="$LDFLAGS -L$trylibzdir/lib"
|
||||
CPPFLAGS="$CPPFLAGS -I$trylibzdir/include"
|
||||
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <zlib.h>]], [[ deflateInit(0, 8); ]])],[ libz_linked=yes ],[ libz_linked=no ])
|
||||
|
@@ -14266,7 +14266,8 @@ static int test_wc_ecc_pointFns (void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(WC_NO_RNG)
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && \
|
||||
!defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A)
|
||||
ecc_key key;
|
||||
WC_RNG rng;
|
||||
ecc_point* point = NULL;
|
||||
@@ -14440,7 +14441,8 @@ static int test_wc_ecc_shared_secret_ssh (void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_DHE) && !defined(WC_NO_RNG)
|
||||
#if defined(HAVE_ECC) && defined(HAVE_ECC_DHE) && \
|
||||
!defined(WC_NO_RNG) && !defined(WOLFSSL_ATECC508A)
|
||||
ecc_key key, key2;
|
||||
WC_RNG rng;
|
||||
int keySz = KEY32;
|
||||
|
@@ -3381,12 +3381,17 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out,
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
err = atcatls_ecdh(private_key->slot, public_key->pubkey_raw, out);
|
||||
if (err != ATCA_SUCCESS) {
|
||||
err = BAD_COND_E;
|
||||
/* For SECP256R1 use hardware */
|
||||
if (private_key->dp->id == ECC_SECP256R1) {
|
||||
err = atmel_ecc_create_pms(private_key->slot, public_key->pubkey_raw, out);
|
||||
*outlen = private_key->dp->size;
|
||||
}
|
||||
*outlen = private_key->dp->size;
|
||||
else {
|
||||
err = NOT_COMPILED_IN;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
err = wc_ecc_shared_secret_ex(private_key, &public_key->pubkey, out, outlen);
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
@@ -3757,7 +3762,7 @@ static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
|
||||
#endif
|
||||
ecc_point* pub;
|
||||
DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
|
||||
#endif
|
||||
#endif /* !WOLFSSL_ATECC508A */
|
||||
|
||||
if (key == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
@@ -3857,9 +3862,7 @@ static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn,
|
||||
/* free up local curve */
|
||||
if (curveIn == NULL) {
|
||||
wc_ecc_curve_free(curve);
|
||||
#ifndef WOLFSSL_ATECC508A
|
||||
FREE_CURVE_SPECS();
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -3899,7 +3902,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
|
||||
#ifndef WOLFSSL_SP_MATH
|
||||
DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* !WOLFSSL_ATECC508A */
|
||||
|
||||
if (key == NULL || rng == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
@@ -3942,10 +3945,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
err = atcatls_create_key(key->slot, key->pubkey_raw);
|
||||
if (err != ATCA_SUCCESS) {
|
||||
err = BAD_COND_E;
|
||||
}
|
||||
err = atmel_ecc_create_key(key->slot, key->pubkey_raw);
|
||||
|
||||
/* populate key->pubkey */
|
||||
err = mp_read_unsigned_bin(key->pubkey.x, key->pubkey_raw,
|
||||
@@ -3999,9 +3999,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id)
|
||||
|
||||
/* cleanup allocations */
|
||||
wc_ecc_curve_free(curve);
|
||||
#ifndef WOLFSSL_ATECC508A
|
||||
FREE_CURVE_SPECS();
|
||||
#endif
|
||||
#endif /* WOLFSSL_SP_MATH */
|
||||
}
|
||||
|
||||
@@ -4103,10 +4101,7 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
key->slot = atmel_ecc_alloc();
|
||||
if (key->slot == ATECC_INVALID_SLOT) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
key->slot = -1;
|
||||
#else
|
||||
#ifdef ALT_ECC_SIZE
|
||||
key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
|
||||
@@ -4201,10 +4196,15 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen,
|
||||
}
|
||||
|
||||
#if defined(WOLFSSL_ATECC508A)
|
||||
key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);
|
||||
if (key->slot == ATECC_INVALID_SLOT) {
|
||||
return ECC_BAD_ARG_E;
|
||||
}
|
||||
|
||||
/* Sign: Result is 32-bytes of R then 32-bytes of S */
|
||||
err = atcatls_sign(key->slot, in, out);
|
||||
if (err != ATCA_SUCCESS) {
|
||||
return BAD_COND_E;
|
||||
err = atmel_ecc_sign(key->slot, in, out);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
#elif defined(PLUTON_CRYPTO_ECC)
|
||||
{
|
||||
@@ -5282,9 +5282,9 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
|
||||
return err;
|
||||
}
|
||||
|
||||
err = atcatls_verify(hash, sigRS, key->pubkey_raw, (bool*)res);
|
||||
if (err != ATCA_SUCCESS) {
|
||||
return BAD_COND_E;
|
||||
err = atmel_ecc_verify(hash, sigRS, key->pubkey_raw, res);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
}
|
||||
(void)hashlen;
|
||||
|
||||
@@ -5569,7 +5569,6 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
|
||||
ecc_point* point)
|
||||
{
|
||||
int err = 0;
|
||||
#ifndef WOLFSSL_ATECC508A
|
||||
int compressed = 0;
|
||||
int keysize;
|
||||
byte pointType;
|
||||
@@ -5619,11 +5618,6 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
|
||||
/* calculate key size based on inLen / 2 */
|
||||
keysize = inLen>>1;
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* populate key->pubkey_raw */
|
||||
XMEMCPY(key->pubkey_raw, (byte*)in, sizeof(key->pubkey_raw));
|
||||
#endif
|
||||
|
||||
/* read data */
|
||||
if (err == MP_OKAY)
|
||||
err = mp_read_unsigned_bin(point->x, (byte*)in, keysize);
|
||||
@@ -5703,14 +5697,6 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx,
|
||||
mp_clear(point->z);
|
||||
}
|
||||
|
||||
#else
|
||||
err = NOT_COMPILED_IN;
|
||||
(void)in;
|
||||
(void)inLen;
|
||||
(void)curve_idx;
|
||||
(void)point;
|
||||
#endif /* !WOLFSSL_ATECC508A */
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif /* HAVE_ECC_KEY_IMPORT */
|
||||
@@ -5722,13 +5708,11 @@ int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
|
||||
{
|
||||
int ret = MP_OKAY;
|
||||
word32 numlen;
|
||||
#ifndef WOLFSSL_ATECC508A
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
byte* buf;
|
||||
#else
|
||||
byte buf[ECC_BUFSIZE];
|
||||
#endif
|
||||
#endif /* !WOLFSSL_ATECC508A */
|
||||
|
||||
if ((curve_idx < 0) || (wc_ecc_is_valid_idx(curve_idx) == 0))
|
||||
return ECC_BAD_ARG_E;
|
||||
@@ -5750,12 +5734,6 @@ int wc_ecc_export_point_der(const int curve_idx, ecc_point* point, byte* out,
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* TODO: Implement equiv call to ATECC508A */
|
||||
ret = BAD_COND_E;
|
||||
|
||||
#else
|
||||
|
||||
/* store byte point type */
|
||||
out[0] = ECC_POINT_UNCOMP;
|
||||
|
||||
@@ -5787,7 +5765,6 @@ done:
|
||||
#ifdef WOLFSSL_SMALL_STACK
|
||||
XFREE(buf, NULL, DYNAMIC_TYPE_ECC_BUFFER);
|
||||
#endif
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -6086,8 +6063,8 @@ static int ecc_check_privkey_gen_helper(ecc_key* key)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* TODO: Implement equiv call to ATECC508A */
|
||||
err = BAD_COND_E;
|
||||
/* Hardware based private key, so this operation is not supported */
|
||||
err = MP_OKAY; /* just report success */
|
||||
|
||||
#else
|
||||
ALLOC_CURVE_SPECS(2);
|
||||
@@ -6176,10 +6153,7 @@ int wc_ecc_check_key(ecc_key* key)
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
|
||||
if (key->slot == ATECC_INVALID_SLOT)
|
||||
return ECC_BAD_ARG_E;
|
||||
|
||||
err = 0; /* consider key check success on ECC508A */
|
||||
err = 0; /* consider key check success on ATECC508A */
|
||||
|
||||
#else
|
||||
#ifdef USE_ECC_B_PARAM
|
||||
@@ -6335,6 +6309,14 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
|
||||
inLen -= 1;
|
||||
in += 1;
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* For SECP256R1 only save raw public key for hardware */
|
||||
if (curve_id == ECC_SECP256R1 && !compressed &&
|
||||
inLen <= sizeof(key->pubkey_raw)) {
|
||||
XMEMCPY(key->pubkey_raw, (byte*)in, inLen);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (err == MP_OKAY) {
|
||||
#ifdef HAVE_COMP_KEY
|
||||
/* adjust inLen if compressed */
|
||||
@@ -6472,7 +6454,7 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* Hardware cannot export private portion */
|
||||
return BAD_COND_E;
|
||||
return NOT_COMPILED_IN;
|
||||
#else
|
||||
err = wc_export_int(&key->k, d, dLen, keySz, encType);
|
||||
if (err != MP_OKAY)
|
||||
@@ -6573,8 +6555,8 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
|
||||
return ret;
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* TODO: Implement equiv call to ATECC508A */
|
||||
return BAD_COND_E;
|
||||
/* Hardware does not support loading private keys */
|
||||
return NOT_COMPILED_IN;
|
||||
|
||||
#else
|
||||
|
||||
@@ -6836,14 +6818,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* TODO: Implement equiv call to ATECC508A */
|
||||
err = BAD_COND_E;
|
||||
(void)d;
|
||||
(void)encType;
|
||||
|
||||
#else
|
||||
|
||||
/* init key */
|
||||
#ifdef ALT_ECC_SIZE
|
||||
key->pubkey.x = (mp_int*)&key->pubkey.xyz[0];
|
||||
@@ -6882,9 +6856,25 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
if (err == MP_OKAY)
|
||||
err = mp_set(key->pubkey.z, 1);
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* For SECP256R1 only save raw public key for hardware */
|
||||
if (err == MP_OKAY && curve_id == ECC_SECP256R1) {
|
||||
word32 keySz = key->dp->size;
|
||||
err = wc_export_int(key->pubkey.x, key->pubkey_raw,
|
||||
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
|
||||
if (err == MP_OKAY)
|
||||
err = wc_export_int(key->pubkey.y, &key->pubkey_raw[keySz],
|
||||
&keySz, keySz, WC_TYPE_UNSIGNED_BIN);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* import private key */
|
||||
if (err == MP_OKAY) {
|
||||
if (d != NULL) {
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* Hardware doesn't support loading private key */
|
||||
err = NOT_COMPILED_IN;
|
||||
#else
|
||||
key->type = ECC_PRIVATEKEY;
|
||||
|
||||
if (encType == WC_TYPE_HEX_STR)
|
||||
@@ -6892,7 +6882,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
else
|
||||
err = mp_read_unsigned_bin(&key->k, (const byte*)d,
|
||||
key->dp->size);
|
||||
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
} else {
|
||||
key->type = ECC_PUBLICKEY;
|
||||
}
|
||||
@@ -6909,7 +6899,6 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
|
||||
mp_clear(key->pubkey.z);
|
||||
mp_clear(&key->k);
|
||||
}
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -9404,12 +9393,6 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen
|
||||
return BUFFER_E;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
/* TODO: Implement equiv call to ATECC508A */
|
||||
ret = BAD_COND_E;
|
||||
|
||||
#else
|
||||
|
||||
/* store first byte */
|
||||
out[0] = mp_isodd(key->pubkey.y) == MP_YES ? ECC_POINT_COMP_ODD : ECC_POINT_COMP_EVEN;
|
||||
|
||||
@@ -9419,8 +9402,6 @@ static int wc_ecc_export_x963_compressed(ecc_key* key, byte* out, word32* outLen
|
||||
out+1 + (numlen - mp_unsigned_bin_size(key->pubkey.x)));
|
||||
*outLen = 1 + numlen;
|
||||
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -52,7 +52,6 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \
|
||||
wolfcrypt/src/port/arm/armv8-aes.c \
|
||||
wolfcrypt/src/port/arm/armv8-sha256.c \
|
||||
wolfcrypt/src/port/nxp/ksdk_port.c \
|
||||
wolfcrypt/src/port/atmel/atmel.c \
|
||||
wolfcrypt/src/port/atmel/README.md \
|
||||
wolfcrypt/src/port/xilinx/xil-sha3.c \
|
||||
wolfcrypt/src/port/xilinx/xil-aesgcm.c \
|
||||
@@ -96,3 +95,7 @@ src_libwolfssl_la_SOURCES += wolfcrypt/src/port/intel/quickassist_mem.c
|
||||
|
||||
EXTRA_DIST += wolfcrypt/src/port/intel/README.md
|
||||
endif
|
||||
|
||||
if BUILD_CRYPTOAUTHLIB
|
||||
src_libwolfssl_la_SOURCES += wolfcrypt/src/port/atmel/atmel.c
|
||||
endif
|
||||
|
@@ -1,17 +1,36 @@
|
||||
# Atmel ATECC508A Port
|
||||
# Microchip/Atmel ATECC508A/ATECC608A Support
|
||||
|
||||
* Adds wolfCrypt support for ECC Hardware acceleration using the ATECC508A
|
||||
* The new defines added for this port are: `WOLFSSL_ATMEL` and `WOLFSSL_ATECC508A`.
|
||||
* Adds new PK callback for Pre Master Secret.
|
||||
Support for ATECC508A using these methods:
|
||||
* TLS: Using the PK callbacks and reference ATECC508A callbacks. See Coding section below. Requires options `HAVE_PK_CALLBACKS` and `WOLFSSL_ATECC_PKCB or WOLFSSL_ATECC508A`
|
||||
* wolfCrypt: Native wc_ecc_* API's using the `./configure CFLAGS="-DWOLFSSL_ATECC508A"` or `#define WOLFSSL_ATECC508A`.
|
||||
|
||||
## Dependency
|
||||
|
||||
Requires the Microchip CryptoAuthLib. The examples in `wolfcrypt/src/port/atmel/atmel.c` make calls to the `atcatls_*` API's.
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
`./configure --enable-pkcallbacks CFLAGS="-DWOLFSSL_ATECC508A"`
|
||||
### Build Options
|
||||
|
||||
* `HAVE_PK_CALLBACKS`: Option for enabling wolfSSL's PK callback support for TLS.
|
||||
* `WOLFSSL_ATECC508A`: Enables support for initializing the CryptoAuthLib and setting up the encryption key used for the I2C communication.
|
||||
* `WOLFSSL_ATECC_PKCB`: Enables support for the reference PK callbacks without init.
|
||||
* `WOLFSSL_ATMEL`: Enables ASF hooks seeding random data using the `atmel_get_random_number` function.
|
||||
* `WOLFSSL_ATMEL_TIME`: Enables the built-in `atmel_get_curr_time_and_date` function get getting time from ASF RTC.
|
||||
* `ATECC_GET_ENC_KEY`: Macro to define your own function for getting the encryption key.
|
||||
* `ATECC_SLOT_I2C_ENC`: Macro for the default encryption key slot. Can also get via the slot callback with `ATMEL_SLOT_ENCKEY`.
|
||||
* `ATECC_MAX_SLOT`: Macro for the maximum dynamically allocated slots.
|
||||
|
||||
### Build Command Examples
|
||||
|
||||
`./configure --enable-pkcallbacks CFLAGS="-DWOLFSSL_ATECC_PKCB"`
|
||||
`#define HAVE_PK_CALLBACKS`
|
||||
`#define WOLFSSL_ATECC_PKCB`
|
||||
|
||||
or
|
||||
|
||||
`#define HAVE_PK_CALLBACKS`
|
||||
`./configure CFLAGS="-DWOLFSSL_ATECC508A"`
|
||||
`#define WOLFSSL_ATECC508A`
|
||||
|
||||
|
||||
@@ -31,7 +50,7 @@ wolfSSL_CTX_SetEccSharedSecretCb(ctx, atcatls_create_pms_cb);
|
||||
The reference ATECC508A PK callback functions are located in the `wolfcrypt/src/port/atmel/atmel.c` file.
|
||||
|
||||
|
||||
Adding a custom contex to the callbacks:
|
||||
Adding a custom context to the callbacks:
|
||||
|
||||
```
|
||||
/* Setup PK Callbacks context */
|
||||
@@ -45,11 +64,13 @@ wolfSSL_SetEccSharedSecretCtx(ssl, myOwnCtx);
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Supports ECC SECP256R1 (NIST P-256)
|
||||
|
||||
### TLS
|
||||
|
||||
TLS Establishment Times:
|
||||
|
||||
* Hardware accelerated ATECC508A: 2.342 seconds avgerage
|
||||
* Hardware accelerated ATECC508A: 2.342 seconds average
|
||||
* Software only: 13.422 seconds average
|
||||
|
||||
The TLS connection establishment time is 5.73 times faster with the ATECC508A.
|
||||
@@ -58,16 +79,16 @@ The TLS connection establishment time is 5.73 times faster with the ATECC508A.
|
||||
|
||||
Software only implementation (SAMD21 48Mhz Cortex-M0, Fast Math TFM-ASM):
|
||||
|
||||
`ECC 256 key generation 3123.000 milliseconds, avg over 5 iterations`
|
||||
`EC-DHE key agreement 3117.000 milliseconds, avg over 5 iterations`
|
||||
`EC-DSA sign time 1997.000 milliseconds, avg over 5 iterations`
|
||||
`EC-DSA verify time 5057.000 milliseconds, avg over 5 iterations`
|
||||
`EC-DHE key generation 3123.000 milliseconds, avg over 5 iterations, 1.601 ops/sec`
|
||||
`EC-DHE key agreement 3117.000 milliseconds, avg over 5 iterations, 1.604 ops/sec`
|
||||
`EC-DSA sign time 1997.000 milliseconds, avg over 5 iterations, 2.504 ops/sec`
|
||||
`EC-DSA verify time 5057.000 milliseconds, avg over 5 iterations, 0.988 ops/sec`
|
||||
|
||||
ATECC508A HW accelerated implementation:
|
||||
`ECC 256 key generation 144.400 milliseconds, avg over 5 iterations`
|
||||
`EC-DHE key agreement 134.200 milliseconds, avg over 5 iterations`
|
||||
`EC-DSA sign time 293.400 milliseconds, avg over 5 iterations`
|
||||
`EC-DSA verify time 208.400 milliseconds, avg over 5 iterations`
|
||||
`EC-DHE key generation 144.400 milliseconds, avg over 5 iterations, 34.722 ops/sec`
|
||||
`EC-DHE key agreement 134.200 milliseconds, avg over 5 iterations, 37.313 ops/sec`
|
||||
`EC-DSA sign time 293.400 milliseconds, avg over 5 iterations, 17.065 ops/sec`
|
||||
`EC-DSA verify time 208.400 milliseconds, avg over 5 iterations, 24.038 ops/sec`
|
||||
|
||||
|
||||
For details see our [wolfSSL Atmel ATECC508A](https://wolfssl.com/wolfSSL/wolfssl-atmel.html) page.
|
||||
|
@@ -25,14 +25,22 @@
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
|
||||
#if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A)
|
||||
#if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC_PKCB)
|
||||
|
||||
#include <wolfssl/wolfcrypt/memory.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/internal.h>
|
||||
|
||||
#ifdef NO_INLINE
|
||||
#include <wolfssl/wolfcrypt/misc.h>
|
||||
#else
|
||||
#define WOLFSSL_MISC_INCLUDED
|
||||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_ATMEL
|
||||
/* remap name conflicts */
|
||||
#define Aes Aes_Remap
|
||||
#define Gmac Gmac_Remap
|
||||
#include "asf.h"
|
||||
@@ -42,27 +50,29 @@
|
||||
|
||||
#include <wolfssl/wolfcrypt/port/atmel/atmel.h>
|
||||
|
||||
static bool mAtcaInitDone = 0;
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
|
||||
/* List of available key slots */
|
||||
static int mSlotList[ATECC_MAX_SLOT+1];
|
||||
static int mAtcaInitDone = 0;
|
||||
|
||||
/**
|
||||
* \brief Structure to contain certificate information.
|
||||
*/
|
||||
t_atcert atcert = {
|
||||
.signer_ca_size = 512,
|
||||
.signer_ca = { 0 },
|
||||
.signer_ca_pubkey = { 0 },
|
||||
.end_user_size = 512,
|
||||
.end_user = { 0 },
|
||||
.end_user_pubkey = { 0 }
|
||||
};
|
||||
|
||||
static int atmel_init_enc_key(void);
|
||||
/* ATECC slotId handling */
|
||||
static atmel_slot_alloc_cb mSlotAlloc;
|
||||
static atmel_slot_dealloc_cb mSlotDealloc;
|
||||
static byte mSlotList[ATECC_MAX_SLOT];
|
||||
#ifndef SINGLE_THREADED
|
||||
static wolfSSL_Mutex mSlotMutex;
|
||||
#endif
|
||||
|
||||
/* Raspberry Pi uses /dev/i2c-1 */
|
||||
#ifndef ATECC_I2C_ADDR
|
||||
#define ATECC_I2C_ADDR 0xC0
|
||||
#endif
|
||||
#ifndef ATECC_I2C_BUS
|
||||
#define ATECC_I2C_BUS 1
|
||||
#endif
|
||||
#ifndef ATECC_DEV_TYPE
|
||||
#define ATECC_DEV_TYPE ATECC508A
|
||||
#endif
|
||||
static ATCAIfaceCfg cfg_ateccx08a_i2c_pi;
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
|
||||
@@ -81,10 +91,9 @@ int atmel_get_random_number(uint32_t count, uint8_t* rand_out)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while(i < count) {
|
||||
|
||||
ret = atcatls_random(rng_buffer);
|
||||
if (ret != 0) {
|
||||
while (i < count) {
|
||||
ret = atcab_random(rng_buffer);
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
WOLFSSL_MSG("Failed to create random number!");
|
||||
return -1;
|
||||
}
|
||||
@@ -92,9 +101,9 @@ int atmel_get_random_number(uint32_t count, uint8_t* rand_out)
|
||||
XMEMCPY(&rand_out[i], rng_buffer, copy_count);
|
||||
i += copy_count;
|
||||
}
|
||||
atcab_printbin_label((const uint8_t*)"\r\nRandom Number", rand_out, count);
|
||||
atcab_printbin_label((const char*)"\r\nRandom Number", rand_out, count);
|
||||
#else
|
||||
// TODO: Use on-board TRNG
|
||||
/* TODO: Use on-board TRNG */
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
@@ -104,164 +113,351 @@ int atmel_get_random_block(unsigned char* output, unsigned int sz)
|
||||
return atmel_get_random_number((uint32_t)sz, (uint8_t*)output);
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_ATMEL_TIME
|
||||
#if defined(WOLFSSL_ATMEL) && defined(WOLFSSL_ATMEL_TIME)
|
||||
extern struct rtc_module *_rtc_instance[RTC_INST_NUM];
|
||||
#endif
|
||||
|
||||
long atmel_get_curr_time_and_date(long* tm)
|
||||
{
|
||||
(void)tm;
|
||||
long rt = 0;
|
||||
|
||||
#ifdef WOLFSSL_ATMEL_TIME
|
||||
/* Get current time */
|
||||
struct rtc_calendar_time rtcTime;
|
||||
const int monthDay[] = {0,31,59,90,120,151,181,212,243,273,304,334};
|
||||
int month, year, yearLeap;
|
||||
|
||||
//struct rtc_calendar_time rtcTime;
|
||||
//rtc_calendar_get_time(_rtc_instance[0], &rtcTime);
|
||||
rtc_calendar_get_time(_rtc_instance[0], &rtcTime);
|
||||
|
||||
/* Convert rtc_calendar_time to seconds since UTC */
|
||||
#endif
|
||||
month = rtcTime.month % 12;
|
||||
year = rtcTime.year + rtcTime.month / 12;
|
||||
if (month < 0) {
|
||||
month += 12;
|
||||
year--;
|
||||
}
|
||||
yearLeap = (month > 1) ? year + 1 : year;
|
||||
rt = rtcTime.second
|
||||
+ 60 * (rtcTime.minute
|
||||
+ 60 * (rtcTime.hour
|
||||
+ 24 * (monthDay[month] + rtcTime.day - 1
|
||||
+ 365 * (year - 70)
|
||||
+ (yearLeap - 69) / 4
|
||||
- (yearLeap - 1) / 100
|
||||
+ (yearLeap + 299) / 400
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return 0;
|
||||
(void)tm;
|
||||
return rt;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
|
||||
/* Function to allocate new slot number */
|
||||
int atmel_ecc_alloc(void)
|
||||
int atmel_ecc_translate_err(int status)
|
||||
{
|
||||
int i, slot = -1;
|
||||
for (i=0; i <= ATECC_MAX_SLOT; i++) {
|
||||
/* Find free slot */
|
||||
if (mSlotList[i] == ATECC_INVALID_SLOT) {
|
||||
mSlotList[i] = i;
|
||||
slot = i;
|
||||
switch (status) {
|
||||
case ATCA_SUCCESS:
|
||||
return 0;
|
||||
case ATCA_BAD_PARAM:
|
||||
return BAD_FUNC_ARG;
|
||||
case ATCA_ALLOC_FAILURE:
|
||||
return MEMORY_E;
|
||||
default:
|
||||
#ifdef WOLFSSL_ATECC508A_DEBUG
|
||||
printf("ATECC Failure: %x\n", (word32)status);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return WC_HW_E;
|
||||
}
|
||||
|
||||
/* Function to set the slotId allocator and deallocator */
|
||||
int atmel_set_slot_allocator(atmel_slot_alloc_cb alloc,
|
||||
atmel_slot_dealloc_cb dealloc)
|
||||
{
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_LockMutex(&mSlotMutex);
|
||||
#endif
|
||||
mSlotAlloc = alloc;
|
||||
mSlotDealloc = dealloc;
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_UnLockMutex(&mSlotMutex);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Function to allocate new slotId number */
|
||||
int atmel_ecc_alloc(int slotType)
|
||||
{
|
||||
int slotId = ATECC_INVALID_SLOT, i;
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_LockMutex(&mSlotMutex);
|
||||
#endif
|
||||
|
||||
if (mSlotAlloc) {
|
||||
slotId = mSlotAlloc(slotType);
|
||||
}
|
||||
else {
|
||||
switch (slotType) {
|
||||
case ATMEL_SLOT_ENCKEY:
|
||||
/* not reserved in mSlotList, so return */
|
||||
slotId = ATECC_SLOT_I2C_ENC;
|
||||
goto exit;
|
||||
case ATMEL_SLOT_DEVICE:
|
||||
/* not reserved in mSlotList, so return */
|
||||
slotId = ATECC_SLOT_AUTH_PRIV;
|
||||
goto exit;
|
||||
case ATMEL_SLOT_ECDHE:
|
||||
slotId = ATECC_SLOT_ECDHE_PRIV;
|
||||
break;
|
||||
case ATMEL_SLOT_ECDHE_ENC:
|
||||
slotId = ATECC_SLOT_ENC_PARENT;
|
||||
break;
|
||||
case ATMEL_SLOT_ANY:
|
||||
for (i=0; i < ATECC_MAX_SLOT; i++) {
|
||||
/* Find free slotId */
|
||||
if (mSlotList[i] == ATECC_INVALID_SLOT) {
|
||||
slotId = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* is slot available */
|
||||
if (mSlotList[slotId] != ATECC_INVALID_SLOT) {
|
||||
slotId = ATECC_INVALID_SLOT;
|
||||
}
|
||||
else {
|
||||
mSlotList[slotId] = slotId;
|
||||
}
|
||||
}
|
||||
return slot;
|
||||
|
||||
exit:
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_UnLockMutex(&mSlotMutex);
|
||||
#endif
|
||||
|
||||
return slotId;
|
||||
}
|
||||
|
||||
|
||||
/* Function to return slot number to avail list */
|
||||
void atmel_ecc_free(int slot)
|
||||
/* Function to return slotId number to available list */
|
||||
void atmel_ecc_free(int slotId)
|
||||
{
|
||||
if (slot >= 0 && slot <= ATECC_MAX_SLOT) {
|
||||
/* Mark slot of free */
|
||||
mSlotList[slot] = ATECC_INVALID_SLOT;
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_LockMutex(&mSlotMutex);
|
||||
#endif
|
||||
if (mSlotDealloc) {
|
||||
mSlotDealloc(slotId);
|
||||
}
|
||||
else if (slotId >= 0 && slotId < ATECC_MAX_SLOT) {
|
||||
if (slotId != ATECC_SLOT_AUTH_PRIV && slotId != ATECC_SLOT_I2C_ENC) {
|
||||
/* Mark slotId free */
|
||||
mSlotList[slotId] = ATECC_INVALID_SLOT;
|
||||
}
|
||||
}
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_UnLockMutex(&mSlotMutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Give enc key to read pms.
|
||||
* \brief Callback function for getting the current encryption key
|
||||
*/
|
||||
static int atmel_set_enc_key(uint8_t* enckey, int16_t keysize)
|
||||
int atmel_get_enc_key_default(byte* enckey, word16 keysize)
|
||||
{
|
||||
if (enckey == NULL || keysize != ATECC_KEY_SIZE) {
|
||||
return -1;
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XMEMSET(enckey, 0xFF, keysize); // use default values
|
||||
XMEMSET(enckey, 0xFF, keysize); /* use default value */
|
||||
|
||||
return SSL_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Write enc key before.
|
||||
*/
|
||||
static int atmel_init_enc_key(void)
|
||||
{
|
||||
uint8_t ret = 0;
|
||||
uint8_t read_key[ATECC_KEY_SIZE] = { 0 };
|
||||
int ret;
|
||||
uint8_t read_key[ATECC_KEY_SIZE];
|
||||
uint8_t writeBlock = 0;
|
||||
uint8_t writeOffset = 0;
|
||||
int slotId;
|
||||
|
||||
XMEMSET(read_key, 0xFF, sizeof(read_key));
|
||||
ret = atcab_write_bytes_slot(TLS_SLOT_ENC_PARENT, 0, read_key, sizeof(read_key));
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
WOLFSSL_MSG("Failed to write key");
|
||||
return -1;
|
||||
}
|
||||
slotId = atmel_ecc_alloc(ATMEL_SLOT_ENCKEY);
|
||||
|
||||
ret = atcatlsfn_set_get_enckey(atmel_set_enc_key);
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
WOLFSSL_MSG("Failed to set enckey");
|
||||
return -1;
|
||||
}
|
||||
/* check for encryption key slotId */
|
||||
if (slotId == ATECC_INVALID_SLOT)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* get encryption key */
|
||||
ATECC_GET_ENC_KEY(read_key, sizeof(read_key));
|
||||
|
||||
ret = atcab_write_zone(ATCA_ZONE_DATA, slotId, writeBlock, writeOffset,
|
||||
read_key, ATCA_BLOCK_SIZE);
|
||||
ForceZero(read_key, sizeof(read_key));
|
||||
ret = atmel_ecc_translate_err(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void atmel_show_rev_info(void)
|
||||
int atmel_get_rev_info(word32* revision)
|
||||
{
|
||||
#if 0
|
||||
uint32_t revision = 0;
|
||||
atcab_info((uint8_t*)&revision);
|
||||
printf("ATECC508A Revision: %x\n", (unsigned int)revision);
|
||||
int ret;
|
||||
ret = atcab_info((uint8_t*)revision);
|
||||
ret = atmel_ecc_translate_err(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void atmel_show_rev_info(void)
|
||||
{
|
||||
#ifdef WOLFSSL_ATECC508A_DEBUG
|
||||
word32 revision = 0;
|
||||
atmel_get_rev_info(&revision);
|
||||
printf("ATECC508A Revision: %x\n", (word32)revision);
|
||||
#endif
|
||||
}
|
||||
|
||||
int atmel_ecc_create_pms(int slotId, const uint8_t* peerKey, uint8_t* pms)
|
||||
{
|
||||
int ret;
|
||||
uint8_t read_key[ATECC_KEY_SIZE];
|
||||
int slotIdEnc;
|
||||
|
||||
slotIdEnc = atmel_ecc_alloc(ATMEL_SLOT_ECDHE_ENC);
|
||||
if (slotIdEnc != ATECC_INVALID_SLOT)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* get encryption key */
|
||||
ATECC_GET_ENC_KEY(read_key, sizeof(read_key));
|
||||
|
||||
/* send the encrypted version of the ECDH command */
|
||||
ret = atcab_ecdh_enc(slotId, peerKey, pms, read_key, slotIdEnc);
|
||||
ret = atmel_ecc_translate_err(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int atmel_ecc_create_key(int slotId, byte* peerKey)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* generate new ephemeral key on device */
|
||||
ret = atcab_genkey(slotId, peerKey);
|
||||
ret = atmel_ecc_translate_err(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int atmel_ecc_sign(int slotId, const byte* message, byte* signature)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = atcab_sign(slotId, message, signature);
|
||||
ret = atmel_ecc_translate_err(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int atmel_ecc_verify(const byte* message, const byte* signature,
|
||||
const byte* pubkey, int* verified)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = atcab_verify_extern(message, signature, pubkey, (bool*)verified);
|
||||
ret = atmel_ecc_translate_err(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
|
||||
|
||||
void atmel_init(void)
|
||||
int atmel_init(void)
|
||||
{
|
||||
if (!mAtcaInitDone) {
|
||||
int ret = 0;
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
if (!mAtcaInitDone) {
|
||||
ATCA_STATUS status;
|
||||
int i;
|
||||
|
||||
/* Init the free slot list */
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_InitMutex(&mSlotMutex);
|
||||
#endif
|
||||
|
||||
/* Init the free slotId list */
|
||||
for (i=0; i<=ATECC_MAX_SLOT; i++) {
|
||||
if (i == 0 || i == 2 || i == 7) {
|
||||
if (i == ATECC_SLOT_AUTH_PRIV || i == ATECC_SLOT_I2C_ENC) {
|
||||
mSlotList[i] = i;
|
||||
}
|
||||
else {
|
||||
/* ECC Slots (mark avail) */
|
||||
mSlotList[i] = ATECC_INVALID_SLOT;
|
||||
}
|
||||
else {
|
||||
mSlotList[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the hardware interface */
|
||||
XMEMSET(&cfg_ateccx08a_i2c_pi, 0, sizeof(cfg_ateccx08a_i2c_pi));
|
||||
cfg_ateccx08a_i2c_pi.iface_type = ATCA_I2C_IFACE;
|
||||
cfg_ateccx08a_i2c_pi.devtype = ATECC_DEV_TYPE;
|
||||
cfg_ateccx08a_i2c_pi.atcai2c.slave_address = ATECC_I2C_ADDR;
|
||||
cfg_ateccx08a_i2c_pi.atcai2c.bus = ATECC_I2C_BUS;
|
||||
cfg_ateccx08a_i2c_pi.atcai2c.baud = 400000;
|
||||
cfg_ateccx08a_i2c_pi.wake_delay = 1500;
|
||||
cfg_ateccx08a_i2c_pi.rx_retries = 20;
|
||||
|
||||
/* Initialize the CryptoAuthLib to communicate with ATECC508A */
|
||||
atcatls_init(&cfg_ateccx08a_i2c_default);
|
||||
status = atcab_init(&cfg_ateccx08a_i2c_pi);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
WOLFSSL_MSG("Failed to initialize atcab");
|
||||
return WC_HW_E;
|
||||
}
|
||||
|
||||
/* Init the I2C pipe encryption key. */
|
||||
/* Value is generated/stored during pair for the ATECC508A and stored
|
||||
on micro flash */
|
||||
/* For this example its a fixed value */
|
||||
if (atmel_init_enc_key() != ATCA_SUCCESS) {
|
||||
if (atmel_init_enc_key() != 0) {
|
||||
WOLFSSL_MSG("Failed to initialize transport key");
|
||||
return WC_HW_E;
|
||||
}
|
||||
|
||||
/* show revision information */
|
||||
atmel_show_rev_info();
|
||||
|
||||
/* Configure the ECC508 for use with TLS API functions */
|
||||
#if 0
|
||||
atcatls_device_provision();
|
||||
#else
|
||||
atcatls_config_default();
|
||||
#endif
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
mAtcaInitDone = 1;
|
||||
}
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
return ret;
|
||||
}
|
||||
|
||||
void atmel_finish(void)
|
||||
{
|
||||
if (mAtcaInitDone) {
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
atcatls_finish();
|
||||
#endif
|
||||
if (mAtcaInitDone) {
|
||||
atcab_release();
|
||||
|
||||
#ifndef SINGLE_THREADED
|
||||
wc_FreeMutex(&mSlotMutex);
|
||||
#endif
|
||||
|
||||
mAtcaInitDone = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Reference PK Callbacks */
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
|
||||
/**
|
||||
* \brief Used on the server-side only for creating the ephemeral key for ECDH
|
||||
*/
|
||||
int atcatls_create_key_cb(WOLFSSL* ssl, ecc_key* key, word32 keySz,
|
||||
int ecc_curve, void* ctx)
|
||||
{
|
||||
@@ -269,35 +465,54 @@ int atcatls_create_key_cb(WOLFSSL* ssl, ecc_key* key, word32 keySz,
|
||||
uint8_t peerKey[ATECC_PUBKEY_SIZE];
|
||||
uint8_t* qx = &peerKey[0];
|
||||
uint8_t* qy = &peerKey[ATECC_PUBKEY_SIZE/2];
|
||||
int slotId;
|
||||
|
||||
(void)ssl;
|
||||
(void)ctx;
|
||||
|
||||
/* only supports P-256 */
|
||||
if (ecc_curve != ECC_SECP256R1 && keySz != ATECC_PUBKEY_SIZE/2) {
|
||||
return BAD_FUNC_ARG;
|
||||
/* ATECC508A only supports P-256 */
|
||||
if (ecc_curve == ECC_SECP256R1) {
|
||||
slotId = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
|
||||
if (slotId == ATECC_INVALID_SLOT)
|
||||
return WC_HW_WAIT_E;
|
||||
|
||||
/* generate new ephemeral key on device */
|
||||
ret = atmel_ecc_create_key(slotId, peerKey);
|
||||
|
||||
/* load generated ECC508A public key into key, used by wolfSSL */
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ECC_SECP256R1);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
key->slot = slotId;
|
||||
}
|
||||
else {
|
||||
atmel_ecc_free(slotId);
|
||||
#ifdef WOLFSSL_ATECC508A_DEBUG
|
||||
printf("atcatls_create_key_cb: ret %d\n", ret);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* generate new ephemeral key on device */
|
||||
ret = atcatls_create_key(TLS_SLOT_ECDHE_PRIV, peerKey);
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
ret = WC_HW_E; goto exit;
|
||||
else {
|
||||
#ifndef WOLFSSL_ATECC508A_NOSOFTECC
|
||||
/* use software for non P-256 cases */
|
||||
WC_RNG rng;
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_make_key_ex(&rng, keySz, key, ecc_curve);
|
||||
wc_FreeRng(&rng);
|
||||
}
|
||||
#else
|
||||
ret = NOT_COMPILED_IN;
|
||||
#endif /* !WOLFSSL_ATECC508A_NOSOFTECC */
|
||||
}
|
||||
|
||||
/* load generated ECC508A public key into key, used by wolfSSL */
|
||||
ret = wc_ecc_import_unsigned(key, qx, qy, NULL, ECC_SECP256R1);
|
||||
|
||||
exit:
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A_DEBUG
|
||||
if (ret != 0) {
|
||||
printf("atcatls_create_key_cb: ret %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates a shared secret using a peer public key and a device key
|
||||
*/
|
||||
int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
|
||||
unsigned char* pubKeyDer, unsigned int* pubKeySz,
|
||||
unsigned char* out, unsigned int* outlen,
|
||||
@@ -324,59 +539,113 @@ int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMSET(peerKey, 0, ATECC_PUBKEY_SIZE);
|
||||
/* ATECC508A only supports P-256 */
|
||||
if (otherKey->dp->id == ECC_SECP256R1) {
|
||||
XMEMSET(peerKey, 0, ATECC_PUBKEY_SIZE);
|
||||
|
||||
/* for client: create and export public key */
|
||||
if (side == WOLFSSL_CLIENT_END) {
|
||||
/* generate new ephemeral key on device */
|
||||
ret = atcatls_create_key(TLS_SLOT_ECDHE_PRIV, peerKey);
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
ret = WC_HW_E; goto exit;
|
||||
/* for client: create and export public key */
|
||||
if (side == WOLFSSL_CLIENT_END) {
|
||||
int slotId = atmel_ecc_alloc(ATMEL_SLOT_ECDHE);
|
||||
if (slotId == ATECC_INVALID_SLOT)
|
||||
return WC_HW_WAIT_E;
|
||||
tmpKey.slot = slotId;
|
||||
|
||||
/* generate new ephemeral key on device */
|
||||
ret = atmel_ecc_create_key(slotId, peerKey);
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* convert raw unsigned public key to X.963 format for TLS */
|
||||
ret = wc_ecc_import_unsigned(&tmpKey, qx, qy, NULL, ECC_SECP256R1);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_export_x963(&tmpKey, pubKeyDer, pubKeySz);
|
||||
}
|
||||
|
||||
/* export peer's key as raw unsigned for hardware */
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_export_public_raw(otherKey, qx, &qxLen, qy, &qyLen);
|
||||
}
|
||||
}
|
||||
|
||||
/* convert raw unsigned public key to X.963 format for TLS */
|
||||
ret = wc_ecc_import_unsigned(&tmpKey, qx, qy, NULL, ECC_SECP256R1);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_export_x963(&tmpKey, pubKeyDer, pubKeySz);
|
||||
}
|
||||
}
|
||||
/* for server: import public key */
|
||||
else if (side == WOLFSSL_SERVER_END) {
|
||||
tmpKey.slot = otherKey->slot;
|
||||
|
||||
/* for server: import public key */
|
||||
else if (side == WOLFSSL_SERVER_END) {
|
||||
/* import peer's key and export as raw unsigned for hardware */
|
||||
ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, &tmpKey, ECC_SECP256R1);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_export_public_raw(&tmpKey, qx, &qxLen, qy, &qyLen);
|
||||
/* import peer's key and export as raw unsigned for hardware */
|
||||
ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, &tmpKey, ECC_SECP256R1);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_export_public_raw(&tmpKey, qx, &qxLen, qy, &qyLen);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = atmel_ecc_create_pms(tmpKey.slot, peerKey, out);
|
||||
*outlen = ATECC_SIG_SIZE;
|
||||
|
||||
#ifndef WOLFSSL_ATECC508A_NOIDLE
|
||||
/* put chip into idle to prevent watchdog situation on chip */
|
||||
atcab_idle();
|
||||
#endif
|
||||
|
||||
(void)qxLen;
|
||||
(void)qyLen;
|
||||
}
|
||||
else {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
#ifndef WOLFSSL_ATECC508A_NOSOFTECC
|
||||
/* use software for non P-256 cases */
|
||||
ecc_key* privKey = NULL;
|
||||
ecc_key* pubKey = NULL;
|
||||
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
/* for client: create and export public key */
|
||||
if (side == WOLFSSL_CLIENT_END)
|
||||
{
|
||||
WC_RNG rng;
|
||||
privKey = &tmpKey;
|
||||
pubKey = otherKey;
|
||||
|
||||
#if 1
|
||||
ret = atcatls_ecdh(TLS_SLOT_ECDHE_PRIV, peerKey, out);
|
||||
#else
|
||||
/* other syntax for encrypted ECDH using key in another slot */
|
||||
ret = atcatls_ecdh_enc(TLS_SLOT_ECDHE_PRIV, TLS_SLOT_FEATURE_PRIV,
|
||||
peerKey, out);
|
||||
#endif
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
ret = WC_HW_E;
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_make_key_ex(&rng, 0, privKey, otherKey->dp->id);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_export_x963(privKey, pubKeyDer, pubKeySz);
|
||||
}
|
||||
wc_FreeRng(&rng);
|
||||
}
|
||||
}
|
||||
/* for server: import public key */
|
||||
else if (side == WOLFSSL_SERVER_END) {
|
||||
privKey = otherKey;
|
||||
pubKey = &tmpKey;
|
||||
|
||||
ret = wc_ecc_import_x963_ex(pubKeyDer, *pubKeySz, pubKey,
|
||||
otherKey->dp->id);
|
||||
}
|
||||
else {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* generate shared secret and return it */
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_shared_secret(privKey, pubKey, out, outlen);
|
||||
}
|
||||
#else
|
||||
ret = NOT_COMPILED_IN;
|
||||
#endif /* !WOLFSSL_ATECC508A_NOSOFTECC */
|
||||
}
|
||||
*outlen = ATECC_SIG_SIZE;
|
||||
|
||||
exit:
|
||||
wc_ecc_free(&tmpKey);
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A_DEBUG
|
||||
if (ret != 0) {
|
||||
printf("atcatls_create_pms_cb: ret %d\n", ret);
|
||||
printf("atcab_ecdh_enc: ret %d\n", ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -385,13 +654,14 @@ exit:
|
||||
|
||||
|
||||
/**
|
||||
* \brief Sign received digest so far for private key to be proved.
|
||||
* \brief Sign received digest using private key on device
|
||||
*/
|
||||
int atcatls_sign_certificate_cb(WOLFSSL* ssl, const byte* in, word32 inSz,
|
||||
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
|
||||
{
|
||||
int ret;
|
||||
byte sigRs[ATECC_SIG_SIZE*2];
|
||||
int slotId;
|
||||
|
||||
(void)ssl;
|
||||
(void)inSz;
|
||||
@@ -403,11 +673,21 @@ int atcatls_sign_certificate_cb(WOLFSSL* ssl, const byte* in, word32 inSz,
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
ret = atcatls_sign(TLS_SLOT_AUTH_PRIV, in, sigRs);
|
||||
slotId = atmel_ecc_alloc(ATMEL_SLOT_DEVICE);
|
||||
if (slotId == ATECC_INVALID_SLOT)
|
||||
return WC_HW_WAIT_E;
|
||||
|
||||
/* We can only sign with P-256 */
|
||||
ret = atmel_ecc_sign(slotId, in, sigRs);
|
||||
if (ret != ATCA_SUCCESS) {
|
||||
ret = WC_HW_E; goto exit;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_ATECC508A_NOIDLE
|
||||
/* put chip into idle to prevent watchdog situation on chip */
|
||||
atcab_idle();
|
||||
#endif
|
||||
|
||||
/* Encode with ECDSA signature */
|
||||
ret = wc_ecc_rs_raw_to_sig(
|
||||
&sigRs[0], ATECC_SIG_SIZE,
|
||||
@@ -419,6 +699,8 @@ int atcatls_sign_certificate_cb(WOLFSSL* ssl, const byte* in, word32 inSz,
|
||||
|
||||
exit:
|
||||
|
||||
atmel_ecc_free(slotId);
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A_DEBUG
|
||||
if (ret != 0) {
|
||||
printf("atcatls_sign_certificate_cb: ret %d\n", ret);
|
||||
@@ -454,36 +736,50 @@ int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, word32 sigSz,
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* import public key and export public as unsigned bin for hardware */
|
||||
/* import public key */
|
||||
ret = wc_ecc_init(&tmpKey);
|
||||
if (ret == 0) {
|
||||
ret = wc_EccPublicKeyDecode(key, &idx, &tmpKey, keySz);
|
||||
if (ret == 0) {
|
||||
ret = wc_ecc_export_public_raw(&tmpKey, qx, &qxLen, qy, &qyLen);
|
||||
}
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (tmpKey.dp->id == ECC_SECP256R1) {
|
||||
/* export public as unsigned bin for hardware */
|
||||
ret = wc_ecc_export_public_raw(&tmpKey, qx, &qxLen, qy, &qyLen);
|
||||
wc_ecc_free(&tmpKey);
|
||||
|
||||
(void)qxLen;
|
||||
(void)qyLen;
|
||||
/* decode the ECDSA signature */
|
||||
ret = wc_ecc_sig_to_rs(sig, sigSz,
|
||||
&sigRs[0], &rSz,
|
||||
&sigRs[ATECC_SIG_SIZE], &sSz);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = atmel_ecc_verify(hash, sigRs, peerKey, result);
|
||||
if (ret != ATCA_SUCCESS || !*result) {
|
||||
ret = WC_HW_E; goto exit;
|
||||
}
|
||||
|
||||
#ifndef WOLFSSL_ATECC508A_NOIDLE
|
||||
/* put chip into idle to prevent watchdog situation on chip */
|
||||
atcab_idle();
|
||||
#endif
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
else {
|
||||
#ifndef WOLFSSL_ATECC508A_NOSOFTECC
|
||||
ret = wc_ecc_verify_hash(sig, sigSz, hash, hashSz, result, &tmpKey);
|
||||
#else
|
||||
ret = NOT_COMPILED_IN;
|
||||
#endif /* !WOLFSSL_ATECC508A_NOSOFTECC */
|
||||
}
|
||||
|
||||
/* decode the ECDSA signature */
|
||||
ret = wc_ecc_sig_to_rs(sig, sigSz,
|
||||
&sigRs[0], &rSz,
|
||||
&sigRs[ATECC_SIG_SIZE], &sSz);
|
||||
if (ret != 0) {
|
||||
goto exit;
|
||||
}
|
||||
(void)rSz;
|
||||
(void)sSz;
|
||||
|
||||
ret = atcatls_verify(hash, sigRs, peerKey, (bool*)result);
|
||||
if (ret != ATCA_SUCCESS || !*result) {
|
||||
ret = WC_HW_E; goto exit;
|
||||
}
|
||||
(void)qxLen;
|
||||
(void)qyLen;
|
||||
|
||||
ret = 0; /* success */
|
||||
|
||||
@@ -498,6 +794,25 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int atcatls_set_callbacks(WOLFSSL_CTX* ctx)
|
||||
{
|
||||
wolfSSL_CTX_SetEccKeyGenCb(ctx, atcatls_create_key_cb);
|
||||
wolfSSL_CTX_SetEccVerifyCb(ctx, atcatls_verify_signature_cb);
|
||||
wolfSSL_CTX_SetEccSignCb(ctx, atcatls_sign_certificate_cb);
|
||||
wolfSSL_CTX_SetEccSharedSecretCb(ctx, atcatls_create_pms_cb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int atcatls_set_callback_ctx(WOLFSSL* ssl, void* user_ctx)
|
||||
{
|
||||
wolfSSL_SetEccKeyGenCtx(ssl, user_ctx);
|
||||
wolfSSL_SetEccVerifyCtx(ssl, user_ctx);
|
||||
wolfSSL_SetEccSignCtx(ssl, user_ctx);
|
||||
wolfSSL_SetEccSharedSecretCtx(ssl, user_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
|
||||
#endif /* WOLFSSL_ATMEL || WOLFSSL_ATECC508A */
|
||||
#endif /* WOLFSSL_ATMEL || WOLFSSL_ATECC508A || WOLFSSL_ATECC_PKCB */
|
||||
|
@@ -153,7 +153,11 @@ int wolfCrypt_Init(void)
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_ATMEL) || defined(WOLFSSL_ATECC508A)
|
||||
atmel_init();
|
||||
ret = atmel_init();
|
||||
if (ret != 0) {
|
||||
WOLFSSL_MSG("CryptoAuthLib init failed");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFSSL_STSAFEA100)
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/* atecc508.h
|
||||
/* atmel.h
|
||||
*
|
||||
* Copyright (C) 2006-2018 wolfSSL Inc.
|
||||
*
|
||||
@@ -25,65 +25,107 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <wolfssl/wolfcrypt/settings.h>
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
#if defined(WOLFSSL_ATECC508A) || defined(WOLFSSL_ATECC_PKCB)
|
||||
#undef SHA_BLOCK_SIZE
|
||||
#define SHA_BLOCK_SIZE SHA_BLOCK_SIZE_REMAP
|
||||
#include <cryptoauthlib.h>
|
||||
#include <tls/atcatls.h>
|
||||
#include <atcacert/atcacert_client.h>
|
||||
#include <tls/atcatls_cfg.h>
|
||||
#undef SHA_BLOCK_SIZE
|
||||
#endif
|
||||
|
||||
/* ATECC508A only supports ECC-256 */
|
||||
/* ATECC508A only supports ECC P-256 */
|
||||
#define ATECC_KEY_SIZE (32)
|
||||
#define ATECC_PUBKEY_SIZE (ATECC_KEY_SIZE*2) /* X and Y */
|
||||
#define ATECC_SIG_SIZE (ATECC_KEY_SIZE*2) /* R and S */
|
||||
#ifndef ATECC_MAX_SLOT
|
||||
#define ATECC_MAX_SLOT (0x7) /* Only use 0-7 */
|
||||
#define ATECC_INVALID_SLOT (-1)
|
||||
#endif
|
||||
#define ATECC_INVALID_SLOT (0xFF)
|
||||
|
||||
/* Device Key for signing */
|
||||
#ifndef ATECC_SLOT_AUTH_PRIV
|
||||
#define ATECC_SLOT_AUTH_PRIV (0x0)
|
||||
#endif
|
||||
/* Ephemeral key */
|
||||
#ifndef ATECC_SLOT_ECDHE_PRIV
|
||||
#define ATECC_SLOT_ECDHE_PRIV (0x2)
|
||||
#endif
|
||||
/* Symmetric encryption key */
|
||||
#ifndef ATECC_SLOT_I2C_ENC
|
||||
#define ATECC_SLOT_I2C_ENC (0x04)
|
||||
#endif
|
||||
/* Parent encryption key */
|
||||
#ifndef ATECC_SLOT_ENC_PARENT
|
||||
#define ATECC_SLOT_ENC_PARENT (0x7)
|
||||
#endif
|
||||
|
||||
/* ATECC_KEY_SIZE required for ecc.h */
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
|
||||
struct WOLFSSL;
|
||||
struct WOLFSSL_CTX;
|
||||
struct WOLFSSL_X509_STORE_CTX;
|
||||
struct ecc_key;
|
||||
|
||||
// Cert Structure
|
||||
typedef struct t_atcert {
|
||||
uint32_t signer_ca_size;
|
||||
uint8_t signer_ca[512];
|
||||
uint8_t signer_ca_pubkey[64];
|
||||
uint32_t end_user_size;
|
||||
uint8_t end_user[512];
|
||||
uint8_t end_user_pubkey[64];
|
||||
} t_atcert;
|
||||
|
||||
extern t_atcert atcert;
|
||||
|
||||
|
||||
/* Amtel port functions */
|
||||
void atmel_init(void);
|
||||
/* Atmel port functions */
|
||||
int atmel_init(void);
|
||||
void atmel_finish(void);
|
||||
int atmel_get_random_number(uint32_t count, uint8_t* rand_out);
|
||||
int atmel_get_random_number(uint32_t count, uint8_t* rand_out);
|
||||
int atmel_get_random_block(unsigned char* output, unsigned int sz);
|
||||
long atmel_get_curr_time_and_date(long* tm);
|
||||
|
||||
int atmel_ecc_alloc(void);
|
||||
void atmel_ecc_free(int slot);
|
||||
#ifdef WOLFSSL_ATECC508A
|
||||
|
||||
enum atmelSlotType {
|
||||
ATMEL_SLOT_ANY,
|
||||
ATMEL_SLOT_ENCKEY,
|
||||
ATMEL_SLOT_DEVICE,
|
||||
ATMEL_SLOT_ECDHE,
|
||||
ATMEL_SLOT_ECDHE_ENC,
|
||||
};
|
||||
|
||||
int atmel_ecc_alloc(int slotType);
|
||||
void atmel_ecc_free(int slotId);
|
||||
|
||||
typedef int (*atmel_slot_alloc_cb)(int);
|
||||
typedef void (*atmel_slot_dealloc_cb)(int);
|
||||
int atmel_set_slot_allocator(atmel_slot_alloc_cb alloc,
|
||||
atmel_slot_dealloc_cb dealloc);
|
||||
|
||||
int atmel_ecc_translate_err(int status);
|
||||
int atmel_get_rev_info(word32* revision);
|
||||
void atmel_show_rev_info(void);
|
||||
|
||||
/* The macro ATECC_GET_ENC_KEY can be set to override the default
|
||||
encryption key with your own at build-time */
|
||||
#ifndef ATECC_GET_ENC_KEY
|
||||
#define ATECC_GET_ENC_KEY(enckey, keysize) atmel_get_enc_key_default((enckey), (keysize))
|
||||
#endif
|
||||
int atmel_get_enc_key_default(byte* enckey, word16 keysize);
|
||||
int atmel_ecc_create_pms(int slotId, const uint8_t* peerKey, uint8_t* pms);
|
||||
int atmel_ecc_create_key(int slotId, byte* peerKey);
|
||||
int atmel_ecc_sign(int slotId, const byte* message, byte* signature);
|
||||
int atmel_ecc_verify(const byte* message, const byte* signature,
|
||||
const byte* pubkey, int* verified);
|
||||
|
||||
#endif /* WOLFSSL_ATECC508A */
|
||||
|
||||
#ifdef HAVE_PK_CALLBACKS
|
||||
int atcatls_create_key_cb(WOLFSSL* ssl, ecc_key* key, word32 keySz,
|
||||
int atcatls_create_key_cb(struct WOLFSSL* ssl, struct ecc_key* key, word32 keySz,
|
||||
int ecc_curve, void* ctx);
|
||||
int atcatls_create_pms_cb(WOLFSSL* ssl, ecc_key* otherKey,
|
||||
int atcatls_create_pms_cb(struct WOLFSSL* ssl, struct ecc_key* otherKey,
|
||||
unsigned char* pubKeyDer, unsigned int* pubKeySz,
|
||||
unsigned char* out, unsigned int* outlen,
|
||||
int side, void* ctx);
|
||||
int atcatls_sign_certificate_cb(WOLFSSL* ssl, const byte* in, word32 inSz,
|
||||
int atcatls_sign_certificate_cb(struct WOLFSSL* ssl, const byte* in, word32 inSz,
|
||||
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx);
|
||||
int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, word32 sigSz,
|
||||
int atcatls_verify_signature_cb(struct WOLFSSL* ssl, const byte* sig, word32 sigSz,
|
||||
const byte* hash, word32 hashSz, const byte* key, word32 keySz, int* result,
|
||||
void* ctx);
|
||||
|
||||
int atcatls_set_callbacks(struct WOLFSSL_CTX* ctx);
|
||||
int atcatls_set_callback_ctx(struct WOLFSSL* ssl, void* user_ctx);
|
||||
#endif
|
||||
|
||||
#endif /* _ATECC508_H_ */
|
||||
|
Reference in New Issue
Block a user