#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#ifdef HAVE_ARIA
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/port/aria/aria-cryptocb.h>
int wc_AriaInit(void)
{
MC_RV rv = MC_OK;
static char isInit = 0;
if (isInit == 0) {
if (rv == MC_OK)
rv = MC_Initialize(NULL);
if (rv == MC_OK)
isInit = 1;
#ifdef WOLF_CRYPTO_CB
if (rv == MC_OK) {
rv = wc_CryptoDev_RegisterDevice(WOLFSSL_ARIA_DEVID, wc_AriaCryptoCb, NULL);
}
#endif
}
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return WC_INIT_E;
}
return 0;
}
int wc_AriaInitSha(MC_HSESSION* hSession, MC_ALGID algo)
{
MC_RV rv = MC_OK;
MC_APIMODE gApimode = MC_MODE_KCMV;
MC_ALGORITHM mcAlg = {algo, NULL, 0};
WOLFSSL_MSG_EX("AriaInitSha(0x%X)",algo);
if (hSession == NULL) {
return BAD_FUNC_ARG;
}
if (rv == MC_OK)
rv = wc_AriaInit();
if (rv == MC_OK)
rv = MC_OpenSession(hSession);
if (rv == MC_OK)
rv = MC_SetApiMode(*hSession, gApimode);
if (rv == MC_OK)
rv = MC_DigestInit(*hSession, &mcAlg);
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return WC_INIT_E;
}
return 0;
}
int wc_AriaShaUpdate(MC_HSESSION hSession, byte* data, word32 len)
{
MC_RV rv = MC_OK;
WOLFSSL_ENTER("AriaShaUpdate");
if (data == NULL) {
return BAD_FUNC_ARG;
}
if (rv == MC_OK)
rv = MC_DigestUpdate(hSession, data, len);
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return BAD_FUNC_ARG;
}
return 0;
}
int wc_AriaShaFinal(MC_HSESSION hSession, byte* out, word32* len)
{
MC_RV rv = MC_OK;
WOLFSSL_ENTER("AriaShaFinal");
if (out == NULL || len == NULL) {
return BAD_FUNC_ARG;
}
if (rv == MC_OK)
rv = MC_DigestUpdate(hSession, NULL, 0);
if (rv == MC_OK)
rv = MC_DigestFinal(hSession, out, len);
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return BAD_FUNC_ARG;
}
return 0;
}
int wc_AriaFree(MC_HSESSION* hSession, MC_HOBJECT *obj1)
{
MC_RV rv = MC_OK;
WOLFSSL_ENTER("AriaFree");
if (hSession == NULL && obj1 != NULL) {
return BAD_FUNC_ARG;
}
if (obj1 != NULL) {
if (rv == MC_OK)
rv = MC_DestroyObject(*hSession, *obj1);
if (rv == MC_OK)
*obj1 = NULL;
}
if (hSession != NULL) {
if (rv == MC_OK)
rv = MC_CloseSession(*hSession);
if (rv == MC_OK)
*hSession = NULL;
}
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return BAD_STATE_E;
}
return 0;
}
int wc_AriaSign(byte* in, word32 inSz, byte* out, word32* outSz, ecc_key* key)
{
MC_HOBJECT hPrikey = 0;
MC_HSESSION hSession = 0;
const ecc_set_type* dp;
MC_RV rv = MC_OK;
MC_APIMODE gApimode = MC_MODE_KCMV;
MC_ALGORITHM mcAlg = {MC_ALGID_NONE, NULL, 0};
byte keyarr[ARIA_KEYASN1_MAXSZ];
word32 keySz=(word32)sizeof(keyarr);
WOLFSSL_ENTER("AriaSign");
if (in == NULL || out == NULL || outSz == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
if (rv == MC_OK)
rv = wc_AriaInit();
if (rv == MC_OK)
rv = MC_OpenSession(&hSession);
if (rv == MC_OK)
rv = MC_SetApiMode(hSession, gApimode);
if (rv == MC_OK) {
int ret = wc_EccPrivateKeyToDer(key, keyarr, keySz);
if (ret < 0) { rv = ret; }
else { keySz = ret; }
}
WOLFSSL_MSG_EX("AriaSign key(%d):",keySz);
WOLFSSL_BUFFER(keyarr,keySz);
WOLFSSL_MSG_EX("AriaSign rv=%d",rv);
if (key->dp != NULL) {
dp = key->dp;
}
else {
dp = wc_ecc_get_curve_params(key->idx);
}
if (dp->id == ECC_SECP256R1) {
mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P256_r1;
} else if (dp->id == ECC_SECP224R1) {
mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P224_12;
} else {
rv = MC_ERR_UNSUPPORTED_ALGORITHM;
}
if (rv == MC_OK)
rv = MC_CreateObject(hSession, keyarr, keySz, &hPrikey);
WOLFSSL_MSG_EX("AriaSign CreateObject rv=%d",rv);
if (rv == MC_OK)
rv = MC_SignInit(hSession, &mcAlg, hPrikey);
WOLFSSL_MSG_EX("AriaSign SignInit rv=%d",rv);
if (rv == MC_OK)
rv = MC_Sign(hSession, in, inSz, out, outSz);
WOLFSSL_MSG_EX("AriaSign Sign rv=%d",rv);
wc_AriaFree(&hSession, &hPrikey);
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return BAD_STATE_E;
}
return 0;
}
int wc_AriaVerify(byte* sig, word32 sigSz, byte* hash, word32 hashSz,
int* res, ecc_key* key)
{
MC_HOBJECT hPubkey = 0;
MC_HSESSION hSession = 0;
const ecc_set_type* dp;
MC_RV rv = MC_OK;
MC_APIMODE gApimode = MC_MODE_KCMV;
MC_ALGORITHM mcAlg = {MC_ALGID_NONE, NULL, 0};
byte keyarr[ARIA_KEYASN1_MAXSZ];
word32 keySz=sizeof(keyarr);
WOLFSSL_ENTER("AriaVerify");
if (sig == NULL || hash == NULL || res == NULL || key == NULL) {
return BAD_FUNC_ARG;
}
*res = 0;
if (rv == MC_OK)
rv = wc_AriaInit();
if (rv == MC_OK)
rv = MC_OpenSession(&hSession);
if (rv == MC_OK)
rv = MC_SetApiMode(hSession, gApimode);
if (rv == MC_OK) {
int ret = wc_EccPublicKeyToDer(key, keyarr, keySz, 0);
if (ret < 0) { rv = ret; }
else { keySz = ret; }
}
WOLFSSL_MSG_EX("AriaVerify key(%d):",keySz);
WOLFSSL_BUFFER(keyarr,keySz);
WOLFSSL_MSG_EX("AriaVerify rv=%d",rv);
if (key->dp != NULL) {
dp = key->dp;
}
else {
dp = wc_ecc_get_curve_params(key->idx);
}
if (dp->id == ECC_SECP256R1) {
mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P256_r1;
} else if (dp->id == ECC_SECP224R1) {
mcAlg.mcAlgId = MC_ALGID_SHA256WithECDSA_P224_12;
} else {
rv = MC_ERR_UNSUPPORTED_ALGORITHM;
}
if (rv == MC_OK)
rv = MC_CreateObject(hSession, keyarr, keySz, &hPubkey);
WOLFSSL_MSG_EX("AriaVerify CreateObject rv=%d",rv);
if (rv == MC_OK)
rv = MC_VerifyInit(hSession, &mcAlg, hPubkey);
WOLFSSL_MSG_EX("AriaVerify VerifyInit rv=%d",rv);
if (rv == MC_OK)
rv = MC_Verify(hSession, hash, hashSz, sig, sigSz);
WOLFSSL_MSG_EX("AriaVerify Verify rv=%d",rv);
wc_AriaFree(&hSession, &hPubkey);
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return BAD_STATE_E;
}
*res = 1;
return 0;
}
int wc_AriaDerive(ecc_key* private_key, ecc_key* public_key,
byte* out, word32* outSz)
{
MC_HOBJECT hPrikey = 0;
MC_HSESSION hSession = 0;
const ecc_set_type* dp;
MC_RV rv = MC_OK;
MC_APIMODE gApimode = MC_MODE_KCMV;
MC_ALGORITHM mcAlg = {MC_ALGID_NONE, NULL, 0};
byte pubAsn1[ARIA_KEYASN1_MAXSZ];
word32 pubAsn1Sz=sizeof(pubAsn1);
byte privAsn1[ARIA_KEYASN1_MAXSZ];
word32 privAsn1Sz=sizeof(privAsn1);
WOLFSSL_ENTER("AriaDerive");
if (private_key == NULL || public_key == NULL ||
out == NULL || outSz == NULL) {
return BAD_FUNC_ARG;
}
if (rv == MC_OK)
rv = wc_AriaInit();
if (rv == MC_OK)
rv = MC_OpenSession(&hSession);
if (rv == MC_OK)
rv = MC_SetApiMode(hSession, gApimode);
if (rv == MC_OK) {
int ret = wc_EccPublicKeyToDer(public_key,pubAsn1,pubAsn1Sz,0);
if (ret < 0) {
rv = ret;
} else {
pubAsn1Sz = ret;
}
WOLFSSL_MSG_EX("AriaDerive PublicKeyToDer ret=%d",ret);
}
WOLFSSL_MSG_EX("AriaVerify pubAsn1(%d):",pubAsn1Sz);
WOLFSSL_BUFFER(pubAsn1,pubAsn1Sz);
mcAlg.pParam=pubAsn1;
mcAlg.nParam=pubAsn1Sz;
if (rv == MC_OK) {
int ret = wc_BuildEccKeyDer(private_key,privAsn1,&privAsn1Sz,0,0);
if (ret < 0) {
rv = ret;
} else {
privAsn1Sz = ret;
}
WOLFSSL_MSG_EX("AriaDerive PrivateKeyToDer ret=%d",ret);
}
WOLFSSL_MSG_EX("AriaVerify privAsn1(%d):",privAsn1Sz);
WOLFSSL_BUFFER(privAsn1,privAsn1Sz);
if (private_key->dp != NULL) {
dp = private_key->dp;
}
else {
dp = wc_ecc_get_curve_params(private_key->idx);
}
if (dp->id == ECC_SECP256R1) {
mcAlg.mcAlgId = MC_ALGID_ECDH_P256_r1;
} else if (dp->id == ECC_SECP224R1) {
mcAlg.mcAlgId = MC_ALGID_ECDH_P224_12;
} else {
rv = MC_ERR_UNSUPPORTED_ALGORITHM;
}
if (rv == MC_OK)
rv = MC_CreateObject(hSession, privAsn1, privAsn1Sz, &hPrikey);
WOLFSSL_MSG_EX("AriaDerive CreateObject rv=%d",rv);
if (rv == MC_OK)
rv = MC_DeriveKey(hSession, &mcAlg, hPrikey, out, outSz);
WOLFSSL_MSG_EX("AriaDerive DeriveKey rv=%d",rv);
wc_AriaFree(&hSession, &hPrikey);
if (rv != MC_OK) {
WOLFSSL_MSG(MC_GetErrorString(rv));
return BAD_STATE_E;
}
return 0;
}
#ifdef WOLF_CRYPTO_CB
static void printOutput(const char* strName, unsigned char* data,
unsigned int dataSz)
{
#ifdef DEBUG_WOLFSSL
WOLFSSL_MSG_EX("%s (%d):", strName,dataSz);
WOLFSSL_BUFFER(data,dataSz);
#else
#if 0 #else
(void)strName;
(void)data;
(void)dataSz;
#endif
#endif
}
int wc_AriaCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
{
int ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
(void)ctx;
if (info == NULL)
return BAD_FUNC_ARG;
#ifdef DEBUG_CRYPTOCB
wc_CryptoCb_InfoString(info);
#endif
if (info->algo_type == WC_ALGO_TYPE_PK) {
if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
info->pk.eccsign.key->devId = INVALID_DEVID;
printOutput((char *)"eccsign.in (before)",
(byte *)info->pk.eccsign.in,info->pk.eccsign.inlen);
printOutput((char *)"eccsign.out(before)",
(byte *)info->pk.eccsign.out,*(info->pk.eccsign.outlen));
printOutput((char *)"eccsign.key(before)",
(byte *)info->pk.eccsign.key,sizeof(info->pk.eccsign.key));
byte buf[ARIA_KEYASN1_MAXSZ];
word32 bufSz = sizeof(buf);
ret = wc_AriaSign((byte *)info->pk.eccsign.in,info->pk.eccsign.inlen,
buf,&bufSz,
info->pk.eccsign.key);
if (ret != 0) {
ret = CRYPTOCB_UNAVAILABLE;
} else {
memcpy(info->pk.eccsign.out, buf, bufSz);
*(info->pk.eccsign.outlen) = bufSz;
}
printOutput((char *)"eccsign.in (after)",
(byte *)info->pk.eccsign.in,info->pk.eccsign.inlen);
printOutput((char *)"eccsign.out(after)",
(byte *)info->pk.eccsign.out,*(info->pk.eccsign.outlen));
printOutput((char *)"eccsign.key(after)",
(byte *)info->pk.eccsign.key,sizeof(info->pk.eccsign.key));
info->pk.eccsign.key->devId = devIdArg;
}
else if (info->pk.type == WC_PK_TYPE_ECDSA_VERIFY) {
info->pk.eccverify.key->devId = INVALID_DEVID;
printOutput((char *)"eccverify.sig (before)",
(byte *)info->pk.eccverify.sig,info->pk.eccverify.siglen);
printOutput((char *)"eccverify.hash(before)",
(byte *)info->pk.eccverify.hash,info->pk.eccverify.hashlen);
printOutput((char *)"eccverify.key (before)",
(byte *)info->pk.eccverify.key,sizeof(info->pk.eccverify.key));
ret = wc_AriaVerify((byte *)info->pk.eccverify.sig,info->pk.eccverify.siglen,
(byte *)info->pk.eccverify.hash, info->pk.eccverify.hashlen,
info->pk.eccverify.res, info->pk.eccverify.key);
printOutput((char *)"eccverify.sig (after)",
(byte *)info->pk.eccverify.sig,info->pk.eccverify.siglen);
printOutput((char *)"eccverify.hash(after)",
(byte *)info->pk.eccverify.hash,info->pk.eccverify.hashlen);
printOutput((char *)"eccverify.key (after)",
(byte *)info->pk.eccverify.key,sizeof(info->pk.eccverify.key));
if (ret != 0)
ret = CRYPTOCB_UNAVAILABLE;
info->pk.eccverify.key->devId = devIdArg;
}
else if (info->pk.type == WC_PK_TYPE_ECDH) {
info->pk.ecdh.private_key->devId = INVALID_DEVID;
ret = wc_AriaDerive(
info->pk.ecdh.private_key, info->pk.ecdh.public_key,
info->pk.ecdh.out, info->pk.ecdh.outlen);
if (ret != 0)
ret = CRYPTOCB_UNAVAILABLE;
info->pk.ecdh.private_key->devId = devIdArg;
}
}
else if (info->algo_type == WC_ALGO_TYPE_HASH) {
if (info->hash.type == WC_HASH_TYPE_SHA256) {
if (info->hash.sha256 == NULL)
return CRYPTOCB_UNAVAILABLE;
info->hash.sha256->devId = INVALID_DEVID;
if (info->hash.sha256->hSession == NULL) {
ret = wc_AriaInitSha(&(info->hash.sha256->hSession), MC_ALGID_SHA256);
}
if ((ret == 0) ||
(ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))) {
ret = wc_AriaShaUpdate(info->hash.sha256->hSession,
(byte *) info->hash.in, info->hash.inSz);
}
if ((ret == 0) ||
(ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))) {
MC_UINT digestSz = 32;
ret = wc_AriaShaFinal(info->hash.sha256->hSession,
info->hash.digest, &digestSz);
if ((ret == 0) ||
(ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)))
ret = wc_AriaFree(&(info->hash.sha256->hSession),NULL);
}
if (ret != 0) {
wc_AriaFree(&(info->hash.sha256->hSession),NULL);
ret = CRYPTOCB_UNAVAILABLE;
}
info->hash.sha256->devId = devIdArg;
}
else if (info->hash.type == WC_HASH_TYPE_SHA384) {
if (info->hash.sha384 == NULL)
return CRYPTOCB_UNAVAILABLE;
info->hash.sha384->devId = INVALID_DEVID;
if (info->hash.sha384->hSession == NULL) {
ret = wc_AriaInitSha(&(info->hash.sha384->hSession), MC_ALGID_SHA384);
}
if ((ret == 0) ||
(ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))) {
ret = wc_AriaShaUpdate(info->hash.sha384->hSession,
(byte *) info->hash.in, info->hash.inSz);
}
if ((ret == 0) ||
(ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))) {
MC_UINT digestSz = 48;
ret = wc_AriaShaFinal(info->hash.sha384->hSession,
info->hash.digest, &digestSz);
if ((ret == 0) ||
(ret == WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)))
{
ret = wc_AriaFree(&(info->hash.sha384->hSession),NULL);
}
}
if (ret != 0) {
wc_AriaFree(&(info->hash.sha384->hSession),NULL);
ret = CRYPTOCB_UNAVAILABLE;
}
info->hash.sha384->devId = devIdArg;
}
}
return ret;
}
#endif
#endif