/* devcrypto_ecdsa.c * * Copyright (C) 2006-2026 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 3 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 */ #include #if defined(WOLFSSL_DEVCRYPTO_ECDSA) #include #include 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 /* WOLFSSL_DEVCRYPTO_ECDSA */