Skip to content

Commit f95e001

Browse files
authored
Merge pull request #42 from dgarske/qat_eckg
Intel QuickAssist ECC Key Generation acceleration
2 parents 1f6f041 + 96d6f64 commit f95e001

2 files changed

Lines changed: 229 additions & 15 deletions

File tree

wolfcrypt/src/port/intel/quickassist.c

Lines changed: 199 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@
8686
#ifndef QAT_ECDHE_ASYNC
8787
#define QAT_ECDHE_ASYNC 1
8888
#endif
89+
#ifndef QAT_ECMUL_ASYNC
90+
#define QAT_ECMUL_ASYNC 1
91+
#endif
8992
#ifndef QAT_DH_ASYNC
9093
#define QAT_DH_ASYNC 1
9194
#endif
@@ -3385,6 +3388,181 @@ int IntelQaSymSha3(WC_ASYNC_DEV* dev, byte* out, const byte* in, word32 sz)
33853388
#ifdef HAVE_ECC
33863389

33873390
#ifdef HAVE_ECC_DHE
3391+
3392+
/* ECC Point Multiple Used for Public Key computation Key Gen */
3393+
static void IntelQaEccPointMulFree(WC_ASYNC_DEV* dev)
3394+
{
3395+
CpaCyEcPointMultiplyOpData* opData = &dev->qat.op.ecc_mul.opData;
3396+
CpaFlatBuffer* pXk = &dev->qat.op.ecc_mul.pXk;
3397+
CpaFlatBuffer* pYk = &dev->qat.op.ecc_mul.pYk;
3398+
3399+
if (pXk) {
3400+
if (pXk->pData != NULL) {
3401+
XFREE(pXk->pData, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
3402+
}
3403+
XMEMSET(pXk, 0, sizeof(CpaFlatBuffer));
3404+
}
3405+
if (pYk) {
3406+
if (pYk->pData != NULL) {
3407+
XFREE(pYk->pData, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
3408+
}
3409+
XMEMSET(pYk, 0, sizeof(CpaFlatBuffer));
3410+
}
3411+
3412+
if (opData) {
3413+
if (opData->h.pData) {
3414+
if (opData->h.pData != g_qatEcdhCofactor1) {
3415+
XFREE(opData->h.pData, dev->heap, DYNAMIC_TYPE_ASYNC_NUMA);
3416+
}
3417+
opData->h.pData = NULL;
3418+
}
3419+
XMEMSET(opData, 0, sizeof(CpaCyEcPointMultiplyOpData));
3420+
}
3421+
3422+
/* clear temp pointers */
3423+
dev->qat.op.ecc_mul.pubX = NULL;
3424+
dev->qat.op.ecc_mul.pubY = NULL;
3425+
dev->qat.op.ecc_mul.pubZ = NULL;
3426+
}
3427+
3428+
static void IntelQaEccPointMulCallback(void *pCallbackTag, CpaStatus status,
3429+
void* pOpData, CpaBoolean multiplyStatus, CpaFlatBuffer* pXk,
3430+
CpaFlatBuffer* pYk)
3431+
{
3432+
WC_ASYNC_DEV* dev = (WC_ASYNC_DEV*)pCallbackTag;
3433+
CpaCyEcPointMultiplyOpData* opData = (CpaCyEcPointMultiplyOpData*)pOpData;
3434+
int ret = ASYNC_OP_E;
3435+
3436+
#ifdef QAT_DEBUG
3437+
printf("IntelQaEccPointMulCallback: dev %p, status %d, multiplyStatus %d, xLen %d, yLen %d\n",
3438+
dev, status, multiplyStatus, pXk->dataLenInBytes, pYk->dataLenInBytes);
3439+
#endif
3440+
3441+
if (status == CPA_STATUS_SUCCESS) {
3442+
/* check multiply status */
3443+
if (multiplyStatus == 0) {
3444+
/* fail */
3445+
WOLFSSL_MSG("IntelQaEccPointMulCallback: multiply failed");
3446+
ret = ECC_CURVE_OID_E;
3447+
}
3448+
else {
3449+
ret = mp_read_unsigned_bin(dev->qat.op.ecc_mul.pubX,
3450+
pXk->pData, pXk->dataLenInBytes);
3451+
if (ret == 0)
3452+
ret = mp_read_unsigned_bin(dev->qat.op.ecc_mul.pubY,
3453+
pYk->pData, pYk->dataLenInBytes);
3454+
if (ret == 0)
3455+
ret = mp_set(dev->qat.op.ecc_mul.pubZ, 1); /* always 1 */
3456+
}
3457+
}
3458+
(void)opData;
3459+
3460+
/* set return code to mark complete */
3461+
dev->qat.ret = ret;
3462+
}
3463+
3464+
int IntelQaEccPointMul(WC_ASYNC_DEV* dev, WC_BIGINT* k,
3465+
MATH_INT_T* pubX, MATH_INT_T* pubY, MATH_INT_T* pubZ,
3466+
WC_BIGINT* xG, WC_BIGINT* yG, WC_BIGINT* a, WC_BIGINT* b, WC_BIGINT* q,
3467+
word32 cofactor)
3468+
{
3469+
int ret, retryCount = 0;
3470+
CpaStatus status = CPA_STATUS_SUCCESS;
3471+
CpaCyEcPointMultiplyOpData* opData = NULL;
3472+
CpaFlatBuffer* pXk = NULL;
3473+
CpaFlatBuffer* pYk = NULL;
3474+
CpaCyEcPointMultiplyCbFunc callback = IntelQaEccPointMulCallback;
3475+
CpaBoolean* multiplyStatus;
3476+
3477+
/* check arguments */
3478+
if (dev == NULL) {
3479+
return BAD_FUNC_ARG;
3480+
}
3481+
3482+
#ifdef QAT_DEBUG
3483+
printf("IntelQaEccPointMul dev %p\n", dev);
3484+
#endif
3485+
3486+
/* setup operation */
3487+
opData = &dev->qat.op.ecc_mul.opData;
3488+
pXk = &dev->qat.op.ecc_mul.pXk;
3489+
pYk = &dev->qat.op.ecc_mul.pYk;
3490+
multiplyStatus = &dev->qat.op.ecc_mul.multiplyStatus;
3491+
3492+
/* init buffers */
3493+
XMEMSET(opData, 0, sizeof(CpaCyEcPointMultiplyOpData));
3494+
XMEMSET(pXk, 0, sizeof(CpaFlatBuffer));
3495+
XMEMSET(pYk, 0, sizeof(CpaFlatBuffer));
3496+
XMEMSET(multiplyStatus, 0, sizeof(CpaBoolean));
3497+
3498+
/* setup operation data */
3499+
opData->fieldType = CPA_CY_EC_FIELD_TYPE_PRIME;
3500+
ret = IntelQaBigIntToFlatBuffer(k, &opData->k);
3501+
ret += IntelQaBigIntToFlatBuffer(xG, &opData->xg);
3502+
ret += IntelQaBigIntToFlatBuffer(yG, &opData->yg);
3503+
ret += IntelQaBigIntToFlatBuffer(a, &opData->a);
3504+
ret += IntelQaBigIntToFlatBuffer(b, &opData->b);
3505+
ret += IntelQaBigIntToFlatBuffer(q, &opData->q);
3506+
if (ret != 0) {
3507+
ret = BAD_FUNC_ARG; goto exit;
3508+
}
3509+
3510+
/* setup cofactor */
3511+
/* if using default value 1 then use shared global */
3512+
opData->h.dataLenInBytes = 4;
3513+
if (cofactor == 1) {
3514+
opData->h.pData = g_qatEcdhCofactor1;
3515+
}
3516+
else {
3517+
/* if not default value 1, then use own buffer */
3518+
opData->h.pData = XMALLOC(opData->h.dataLenInBytes, dev->heap,
3519+
DYNAMIC_TYPE_ASYNC_NUMA);
3520+
if (opData->h.pData == NULL) {
3521+
ret = MEMORY_E; goto exit;
3522+
}
3523+
*((word32*)opData->h.pData) = OS_HOST_TO_NW_32(cofactor);
3524+
}
3525+
3526+
ret = IntelQaAllocFlatBuffer(pXk, q->len, dev->heap);
3527+
ret += IntelQaAllocFlatBuffer(pYk, q->len, dev->heap);
3528+
if (ret != 0) {
3529+
ret = MEMORY_E; goto exit;
3530+
}
3531+
3532+
/* store info needed for output */
3533+
dev->qat.op.ecc_mul.pubX = pubX;
3534+
dev->qat.op.ecc_mul.pubY = pubY;
3535+
dev->qat.op.ecc_mul.pubZ = pubZ;
3536+
IntelQaOpInit(dev, IntelQaEccPointMulFree);
3537+
3538+
/* perform point multiply */
3539+
do {
3540+
status = cpaCyEcPointMultiply(dev->qat.handle,
3541+
callback,
3542+
dev,
3543+
opData,
3544+
multiplyStatus,
3545+
pXk,
3546+
pYk);
3547+
} while (IntelQaHandleCpaStatus(dev, status, &ret, QAT_ECMUL_ASYNC, callback,
3548+
&retryCount));
3549+
3550+
if (ret == WC_PENDING_E)
3551+
return ret;
3552+
3553+
exit:
3554+
3555+
if (ret != 0) {
3556+
printf("cpaCyEcPointMultiply failed! dev %p, status %d, ret %d\n",
3557+
dev, status, ret);
3558+
}
3559+
3560+
/* handle cleanup */
3561+
IntelQaEccPointMulFree(dev);
3562+
3563+
return ret;
3564+
}
3565+
33883566
static void IntelQaEcdhFree(WC_ASYNC_DEV* dev)
33893567
{
33903568
CpaCyEcdhPointMultiplyOpData* opData = &dev->qat.op.ecc_ecdh.opData;
@@ -3476,7 +3654,7 @@ int IntelQaEcdh(WC_ASYNC_DEV* dev, WC_BIGINT* k, WC_BIGINT* xG,
34763654
CpaFlatBuffer* pXk = NULL;
34773655
CpaFlatBuffer* pYk = NULL;
34783656
CpaCyEcdhPointMultiplyCbFunc callback = IntelQaEcdhCallback;
3479-
CpaBoolean multiplyStatus;
3657+
CpaBoolean* multiplyStatus;
34803658

34813659
/* check arguments */
34823660
if (dev == NULL) {
@@ -3491,11 +3669,13 @@ int IntelQaEcdh(WC_ASYNC_DEV* dev, WC_BIGINT* k, WC_BIGINT* xG,
34913669
opData = &dev->qat.op.ecc_ecdh.opData;
34923670
pXk = &dev->qat.op.ecc_ecdh.pXk;
34933671
pYk = &dev->qat.op.ecc_ecdh.pYk;
3672+
multiplyStatus = &dev->qat.op.ecc_ecdh.multiplyStatus;
34943673

34953674
/* init buffers */
34963675
XMEMSET(opData, 0, sizeof(CpaCyEcdhPointMultiplyOpData));
34973676
XMEMSET(pXk, 0, sizeof(CpaFlatBuffer));
34983677
XMEMSET(pYk, 0, sizeof(CpaFlatBuffer));
3678+
XMEMSET(multiplyStatus, 0, sizeof(CpaBoolean));
34993679

35003680
/* setup operation data */
35013681
opData->fieldType = CPA_CY_EC_FIELD_TYPE_PRIME;
@@ -3525,10 +3705,10 @@ int IntelQaEcdh(WC_ASYNC_DEV* dev, WC_BIGINT* k, WC_BIGINT* xG,
35253705
*((word32*)opData->h.pData) = OS_HOST_TO_NW_32(cofactor);
35263706
}
35273707

3528-
pXk->dataLenInBytes = a->len; /* bytes key size / 8 (aligned) */
3708+
pXk->dataLenInBytes = q->len; /* bytes key size / 8 (aligned) */
35293709
pXk->pData = XREALLOC(out, pXk->dataLenInBytes, dev->heap,
35303710
DYNAMIC_TYPE_ASYNC_NUMA);
3531-
pYk->dataLenInBytes = a->len;
3711+
pYk->dataLenInBytes = q->len;
35323712
pYk->pData = g_qatEcdhY;
35333713

35343714
/* store info needed for output */
@@ -3542,7 +3722,7 @@ int IntelQaEcdh(WC_ASYNC_DEV* dev, WC_BIGINT* k, WC_BIGINT* xG,
35423722
callback,
35433723
dev,
35443724
opData,
3545-
&multiplyStatus,
3725+
multiplyStatus,
35463726
pXk,
35473727
pYk);
35483728
} while (IntelQaHandleCpaStatus(dev, status, &ret, QAT_ECDHE_ASYNC, callback,
@@ -3645,7 +3825,7 @@ int IntelQaEcdsaSign(WC_ASYNC_DEV* dev,
36453825
CpaStatus status = CPA_STATUS_SUCCESS;
36463826
CpaCyEcdsaSignRSOpData* opData = NULL;
36473827
CpaCyEcdsaSignRSCbFunc callback = IntelQaEcdsaSignCallback;
3648-
CpaBoolean signStatus;
3828+
CpaBoolean* signStatus;
36493829
CpaFlatBuffer* pR = NULL;
36503830
CpaFlatBuffer* pS = NULL;
36513831

@@ -3661,11 +3841,13 @@ int IntelQaEcdsaSign(WC_ASYNC_DEV* dev,
36613841
opData = &dev->qat.op.ecc_sign.opData;
36623842
pR = &dev->qat.op.ecc_sign.R;
36633843
pS = &dev->qat.op.ecc_sign.S;
3844+
signStatus = &dev->qat.op.ecc_sign.signStatus;
36643845

36653846
/* init buffers */
36663847
XMEMSET(opData, 0, sizeof(CpaCyEcdsaSignRSOpData));
36673848
XMEMSET(pR, 0, sizeof(CpaFlatBuffer));
36683849
XMEMSET(pS, 0, sizeof(CpaFlatBuffer));
3850+
XMEMSET(signStatus, 0, sizeof(CpaBoolean));
36693851

36703852
/* setup operation data */
36713853
opData->fieldType = CPA_CY_EC_FIELD_TYPE_PRIME;
@@ -3702,7 +3884,7 @@ int IntelQaEcdsaSign(WC_ASYNC_DEV* dev,
37023884
callback,
37033885
dev,
37043886
opData,
3705-
&signStatus,
3887+
signStatus,
37063888
pR,
37073889
pS);
37083890
} while (IntelQaHandleCpaStatus(dev, status, &ret, QAT_ECDSA_ASYNC, callback,
@@ -3783,7 +3965,7 @@ int IntelQaEcdsaVerify(WC_ASYNC_DEV* dev, WC_BIGINT* m,
37833965
CpaStatus status = CPA_STATUS_SUCCESS;
37843966
CpaCyEcdsaVerifyOpData* opData = NULL;
37853967
CpaCyEcdsaVerifyCbFunc callback = IntelQaEcdsaVerifyCallback;
3786-
CpaBoolean verifyStatus;
3968+
CpaBoolean* verifyStatus;
37873969

37883970
if (dev == NULL) {
37893971
return BAD_FUNC_ARG;
@@ -3795,21 +3977,23 @@ int IntelQaEcdsaVerify(WC_ASYNC_DEV* dev, WC_BIGINT* m,
37953977

37963978
/* setup operation */
37973979
opData = &dev->qat.op.ecc_verify.opData;
3980+
verifyStatus = &dev->qat.op.ecc_verify.verifyStatus;
37983981

37993982
/* init buffers */
38003983
XMEMSET(opData, 0, sizeof(CpaCyEcdsaVerifyOpData));
3984+
XMEMSET(verifyStatus, 0, sizeof(CpaBoolean));
38013985

38023986
/* setup operation data */
38033987
opData->fieldType = CPA_CY_EC_FIELD_TYPE_PRIME;
3804-
ret = IntelQaBigIntToFlatBuffer(m, &opData->m);
3805-
ret += IntelQaBigIntToFlatBuffer(r, &opData->r);
3806-
ret += IntelQaBigIntToFlatBuffer(s, &opData->s);
3988+
ret = IntelQaBigIntToFlatBuffer(m, &opData->m);
3989+
ret += IntelQaBigIntToFlatBuffer(r, &opData->r);
3990+
ret += IntelQaBigIntToFlatBuffer(s, &opData->s);
38073991
ret += IntelQaBigIntToFlatBuffer(xp, &opData->xp);
38083992
ret += IntelQaBigIntToFlatBuffer(yp, &opData->yp);
3809-
ret += IntelQaBigIntToFlatBuffer(a, &opData->a);
3810-
ret += IntelQaBigIntToFlatBuffer(b, &opData->b);
3811-
ret += IntelQaBigIntToFlatBuffer(q, &opData->q);
3812-
ret += IntelQaBigIntToFlatBuffer(n, &opData->n);
3993+
ret += IntelQaBigIntToFlatBuffer(a, &opData->a);
3994+
ret += IntelQaBigIntToFlatBuffer(b, &opData->b);
3995+
ret += IntelQaBigIntToFlatBuffer(q, &opData->q);
3996+
ret += IntelQaBigIntToFlatBuffer(n, &opData->n);
38133997
ret += IntelQaBigIntToFlatBuffer(xg, &opData->xg);
38143998
ret += IntelQaBigIntToFlatBuffer(yg, &opData->yg);
38153999
if (ret != 0) {
@@ -3826,7 +4010,7 @@ int IntelQaEcdsaVerify(WC_ASYNC_DEV* dev, WC_BIGINT* m,
38264010
callback,
38274011
dev,
38284012
opData,
3829-
&verifyStatus);
4013+
verifyStatus);
38304014
} while (IntelQaHandleCpaStatus(dev, status, &ret, QAT_ECDSA_ASYNC, callback,
38314015
&retryCount));
38324016

wolfssl/wolfcrypt/port/intel/quickassist.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,17 @@ typedef void (*IntelQaFreeFunc)(struct WC_ASYNC_DEV*);
180180
};
181181
#endif
182182

183+
#ifdef WOLFSSL_SP_MATH
184+
struct sp_int;
185+
#define MATH_INT_T struct sp_int
186+
#elif defined(USE_FAST_MATH)
187+
struct fp_int;
188+
#define MATH_INT_T struct fp_int
189+
#else
190+
struct mp_int;
191+
#define MATH_INT_T struct mp_int
192+
#endif
193+
183194
/* QuickAssist device */
184195
typedef struct IntelQaDev {
185196
CpaInstanceHandle handle;
@@ -238,18 +249,31 @@ typedef struct IntelQaDev {
238249
} cipher;
239250
#endif
240251
#if defined(QAT_ENABLE_PKI) && defined(HAVE_ECC)
252+
struct {
253+
CpaCyEcPointMultiplyOpData opData;
254+
CpaFlatBuffer pXk;
255+
CpaFlatBuffer pYk;
256+
CpaBoolean multiplyStatus;
257+
258+
/* output pub */
259+
MATH_INT_T* pubX;
260+
MATH_INT_T* pubY;
261+
MATH_INT_T* pubZ;
262+
} ecc_mul;
241263
#ifdef HAVE_ECC_DHE
242264
struct {
243265
CpaCyEcdhPointMultiplyOpData opData;
244266
CpaFlatBuffer pXk;
245267
CpaFlatBuffer pYk;
268+
CpaBoolean multiplyStatus;
246269
} ecc_ecdh;
247270
#endif
248271
#ifdef HAVE_ECC_SIGN
249272
struct {
250273
CpaCyEcdsaSignRSOpData opData;
251274
CpaFlatBuffer R;
252275
CpaFlatBuffer S;
276+
CpaBoolean signStatus;
253277

254278
struct WC_BIGINT* pR;
255279
struct WC_BIGINT* pS;
@@ -258,6 +282,7 @@ typedef struct IntelQaDev {
258282
#ifdef HAVE_ECC_VERIFY
259283
struct {
260284
CpaCyEcdsaVerifyOpData opData;
285+
CpaBoolean verifyStatus;
261286
int* stat;
262287
} ecc_verify;
263288
#endif
@@ -428,6 +453,11 @@ WOLFSSL_LOCAL int IntelQaGetCyInstanceCount(void);
428453

429454
#ifdef HAVE_ECC
430455
#ifdef HAVE_ECC_DHE
456+
WOLFSSL_LOCAL int IntelQaEccPointMul(struct WC_ASYNC_DEV* dev,
457+
struct WC_BIGINT* k, MATH_INT_T* pubX, MATH_INT_T* pubY, MATH_INT_T* pubZ,
458+
struct WC_BIGINT* xG, struct WC_BIGINT* yG,
459+
struct WC_BIGINT* a, struct WC_BIGINT* b,
460+
struct WC_BIGINT* q, word32 cofactor);
431461
WOLFSSL_LOCAL int IntelQaEcdh(struct WC_ASYNC_DEV* dev,
432462
struct WC_BIGINT* k, struct WC_BIGINT* xG,
433463
struct WC_BIGINT* yG, byte* out, word32* outlen,

0 commit comments

Comments
 (0)