#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
#if defined(WOLFSSL_DEVCRYPTO_ECDSA)
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
static int CurveIDToFlag(int curveId)
{
int ret = 0;
switch (curveId) {
case ECC_SECP256R1:
ret = CAAM_EC_CURVE_P_256;
break;
case ECC_SECP384R1:
ret = CAAM_EC_CURVE_P_384;
break;
default:
WOLFSSL_MSG("Curve id not found");
}
return ret;
}
int wc_DevCryptoEccKeyGen(int curveId, int enc, byte* pri, word32 priSz,
byte* pub, word32 pubSz)
{
struct crypt_kop kop;
int inIdx = 0;
int outIdx = 0;
int ret = 0;
WC_CRYPTODEV ctx;
int ecdsel;
ecdsel = CurveIDToFlag(curveId);
if (ecdsel == 0) {
ret = NOT_COMPILED_IN;
}
if (ret == 0) {
ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECC_KEYGEN, NULL, 0);
}
if (ret == 0) {
kop.crk_op = CRK_ECC_KEYGEN;
kop.ses = ctx.sess.ses;
kop.crk_flags = ecdsel;
if (enc) {
kop.crk_flags |= (CAAM_KEY_COLOR_BLACK << 8);
}
kop.crk_param[inIdx + outIdx].crp_p = pri;
kop.crk_param[inIdx + outIdx].crp_nbits = priSz * WOLFSSL_BIT_SIZE;
outIdx++;
kop.crk_param[inIdx + outIdx].crp_p = pub;
kop.crk_param[inIdx + outIdx].crp_nbits = pubSz * WOLFSSL_BIT_SIZE;
outIdx++;
kop.crk_iparams = inIdx;
kop.crk_oparams = outIdx;
if (ioctl(ctx.cfd, CIOCKEY, &kop)) {
#if defined(DEBUG_DEVCRYPTO)
perror("Error value with ECC keygen operation was ");
#endif
WOLFSSL_MSG("Error with call to ioctl");
ret = WC_DEVCRYPTO_E;
}
wc_DevCryptoFree(&ctx);
}
return ret;
}
int wc_DevCryptoEccEcdh(int curveId, int enc, byte* pri, word32 priSz,
byte* pub, word32 pubSz, byte* out, word32 outSz)
{
struct crypt_kop kop;
int inIdx = 0;
int outIdx = 0;
int ret = 0;
int ecdsel;
WC_CRYPTODEV ctx;
ecdsel = CurveIDToFlag(curveId);
if (ecdsel == 0) {
ret = NOT_COMPILED_IN;
}
if (ret == 0) {
ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECC_ECDH, NULL, 0);
}
if (ret == 0) {
XMEMSET(&kop, 0, sizeof(kop));
kop.crk_op = CRK_ECC_ECDH;
kop.ses = ctx.sess.ses;
kop.crk_flags = CurveIDToFlag(curveId);
if (enc) {
kop.crk_flags |= (CAAM_KEY_COLOR_BLACK << 8);
}
kop.crk_param[inIdx].crp_p = pub;
kop.crk_param[inIdx].crp_nbits = pubSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_param[inIdx].crp_p = pri;
kop.crk_param[inIdx].crp_nbits = priSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_param[inIdx + outIdx].crp_p = out;
kop.crk_param[inIdx + outIdx].crp_nbits = outSz * WOLFSSL_BIT_SIZE;
outIdx++;
kop.crk_iparams = inIdx;
kop.crk_oparams = outIdx;
if (ioctl(ctx.cfd, CIOCKEY, &kop)) {
#if defined(DEBUG_DEVCRYPTO)
perror("Error value with ECC keygen operation was ");
#endif
WOLFSSL_MSG("Error with call to ioctl");
ret = WC_DEVCRYPTO_E;
}
wc_DevCryptoFree(&ctx);
}
return ret;
}
int wc_DevCryptoEccSign(int curveId, int enc, byte* pri, word32 priSz,
const byte* hash, word32 hashSz, byte* r, word32 rSz, byte* s, word32 sSz)
{
struct crypt_kop kop;
int inIdx = 0;
int outIdx = 0;
int ret = 0;
int ecdsel;
WC_CRYPTODEV ctx;
ecdsel = CurveIDToFlag(curveId);
if (ecdsel == 0) {
ret = NOT_COMPILED_IN;
}
if (ret == 0) {
ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECDSA_SIGN, NULL, 0);
}
if (ret == 0) {
XMEMSET(&kop, 0, sizeof(kop));
kop.crk_op = CRK_ECDSA_SIGN;
kop.ses = ctx.sess.ses;
kop.crk_flags = CurveIDToFlag(curveId);
if (enc) {
kop.crk_flags |= (CAAM_KEY_COLOR_BLACK << 8);
}
kop.crk_param[inIdx].crp_p = pri;
kop.crk_param[inIdx].crp_nbits = priSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_param[inIdx].crp_p = (byte*)hash;
kop.crk_param[inIdx].crp_nbits = hashSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_param[inIdx + outIdx].crp_p = r;
kop.crk_param[inIdx + outIdx].crp_nbits = rSz * WOLFSSL_BIT_SIZE;
outIdx++;
kop.crk_param[inIdx + outIdx].crp_p = s;
kop.crk_param[inIdx + outIdx].crp_nbits = sSz * WOLFSSL_BIT_SIZE;
outIdx++;
kop.crk_iparams = inIdx;
kop.crk_oparams = outIdx;
if (ioctl(ctx.cfd, CIOCKEY, &kop)) {
#if defined(DEBUG_DEVCRYPTO)
perror("Error value with ECC keygen operation was ");
#endif
WOLFSSL_MSG("Error with call to ioctl");
ret = WC_DEVCRYPTO_E;
}
wc_DevCryptoFree(&ctx);
}
return ret;
}
int wc_DevCryptoEccVerify(int curveId, byte* pub, word32 pubSz,
const byte* hash, word32 hashSz, byte* r, word32 rSz, byte* s, word32 sSz)
{
struct crypt_kop kop;
int inIdx = 0;
int outIdx = 0;
int ret = 0;
int ecdsel;
WC_CRYPTODEV ctx;
ecdsel = CurveIDToFlag(curveId);
if (ecdsel == 0) {
ret = NOT_COMPILED_IN;
}
if (ret == 0) {
ret = wc_DevCryptoCreate(&ctx, CRYPTO_ASYM_ECDSA_VERIFY, NULL, 0);
}
if (ret == 0) {
XMEMSET(&kop, 0, sizeof(kop));
kop.crk_op = CRK_ECDSA_VERIFY;
kop.ses = ctx.sess.ses;
kop.crk_flags = CurveIDToFlag(curveId);
kop.crk_param[inIdx].crp_p = pub;
kop.crk_param[inIdx].crp_nbits = pubSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_param[inIdx].crp_p = (byte*)hash;
kop.crk_param[inIdx].crp_nbits = hashSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_param[inIdx].crp_p = r;
kop.crk_param[inIdx].crp_nbits = rSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_param[inIdx].crp_p = s;
kop.crk_param[inIdx].crp_nbits = sSz * WOLFSSL_BIT_SIZE;
inIdx++;
kop.crk_iparams = inIdx;
kop.crk_oparams = outIdx;
if (ioctl(ctx.cfd, CIOCKEY, &kop)) {
#if defined(DEBUG_DEVCRYPTO)
perror("Error value with ECC keygen operation was ");
#endif
WOLFSSL_MSG("Error with call to ioctl");
ret = WC_DEVCRYPTO_E;
}
wc_DevCryptoFree(&ctx);
}
if (ret == 0) {
if (kop.crk_status == 0) {
ret = SIG_VERIFY_E;
}
}
return ret;
}
#endif