Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ HAVE_INTEL_QAT_SYNC
HAVE_INTEL_SPEEDUP
HAVE_MDK_RTX
HAVE_NETX_BSD
HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK
HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK
HAVE_POCO_LIB
HAVE_RTP_SYS
Expand Down
64 changes: 64 additions & 0 deletions tests/api/test_pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,46 @@ static int rsaSignRawDigestCb(PKCS7* pkcs7, byte* digest, word32 digestSz,
}
#endif

#if defined(HAVE_PKCS7) && defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && \
defined(HAVE_ECC) && !defined(NO_SHA256)
/* ECC sign raw digest callback */
static int eccSignRawDigestCb(PKCS7* pkcs7, byte* digest, word32 digestSz,
byte* out, word32 outSz, byte* privateKey,
word32 privateKeySz, int devid, int hashOID)
{
int ret;
word32 idx = 0;
word32 sigSz = outSz;
ecc_key ecc;

if (pkcs7 == NULL || digest == NULL || out == NULL) {
return -1;
}

(void)hashOID;

/* set up ECC key */
ret = wc_ecc_init_ex(&ecc, pkcs7->heap, devid);
if (ret != 0) {
return ret;
}

ret = wc_EccPrivateKeyDecode(privateKey, &idx, &ecc, privateKeySz);

/* sign digest */
if (ret == 0) {
ret = wc_ecc_sign_hash(digest, digestSz, out, &sigSz, pkcs7->rng, &ecc);
if (ret == 0) {
ret = (int)sigSz;
}
}

wc_ecc_free(&ecc);

return ret;
}
#endif

#if defined(HAVE_PKCS7) && defined(ASN_BER_TO_DER)
typedef struct encodeSignedDataStream {
byte out[FOURK_BUF*3];
Expand Down Expand Up @@ -769,6 +809,30 @@ int test_wc_PKCS7_EncodeSignedData(void)
ExpectIntGT(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), 0);
#endif

#if defined(HAVE_PKCS7) && defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && \
defined(HAVE_ECC) && !defined(NO_SHA256)
/* test ECC sign raw digest callback, if using ECC and compiled in.
* Example callback assumes SHA-256, so only run test if compiled in. */
wc_PKCS7_Free(pkcs7);
pkcs7 = NULL;
ExpectNotNull(pkcs7 = wc_PKCS7_New(HEAP_HINT, testDevId));
ExpectIntEQ(wc_PKCS7_InitWithCert(pkcs7, cert, certSz), 0);

if (pkcs7 != NULL) {
pkcs7->content = data;
pkcs7->contentSz = (word32)sizeof(data);
pkcs7->privateKey = key;
pkcs7->privateKeySz = (word32)keySz;
pkcs7->encryptOID = ECDSAk;
pkcs7->hashOID = SHA256h;
pkcs7->rng = &rng;
}

ExpectIntEQ(wc_PKCS7_SetEccSignRawDigestCb(pkcs7, eccSignRawDigestCb), 0);

ExpectIntGT(wc_PKCS7_EncodeSignedData(pkcs7, output, outputSz), 0);
#endif

wc_PKCS7_Free(pkcs7);
DoExpectIntEQ(wc_FreeRng(&rng), 0);

Expand Down
38 changes: 38 additions & 0 deletions wolfcrypt/src/pkcs7.c
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,20 @@ static int wc_PKCS7_SignedDataBuildSignature(wc_PKCS7* pkcs7,

#ifdef HAVE_ECC
case ECDSAk:
#ifdef HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK
if (pkcs7->eccSignRawDigestCb != NULL) {
/* get hash OID */
int eccHashOID = wc_HashGetOID(esd->hashType);

/* user signing plain digest */
ret = pkcs7->eccSignRawDigestCb(pkcs7,
esd->contentAttribsDigest, hashSz,
esd->encContentDigest, sizeof(esd->encContentDigest),
pkcs7->privateKey, pkcs7->privateKeySz, pkcs7->devId,
eccHashOID);
break;
}
#endif
/* CMS with ECDSA does not sign DigestInfo structure
* like PKCS#7 with RSA does */
ret = wc_PKCS7_EcdsaSign(pkcs7, esd->contentAttribsDigest,
Expand Down Expand Up @@ -3986,6 +4000,30 @@ int wc_PKCS7_SetRsaSignRawDigestCb(wc_PKCS7* pkcs7, CallbackRsaSignRawDigest cb)
}
#endif

#endif /* NO_RSA */


#ifdef HAVE_ECC

#ifdef HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK
/* register raw ECC sign digest callback */
int wc_PKCS7_SetEccSignRawDigestCb(wc_PKCS7* pkcs7, CallbackEccSignRawDigest cb)
{
if (pkcs7 == NULL || cb == NULL) {
return BAD_FUNC_ARG;
}

pkcs7->eccSignRawDigestCb = cb;

return 0;
}
#endif

#endif /* HAVE_ECC */


#ifndef NO_RSA

/* returns size of signature put into out, negative on error */
static int wc_PKCS7_RsaVerify(wc_PKCS7* pkcs7, byte* sig, int sigSz,
byte* hash, word32 hashSz)
Expand Down
17 changes: 17 additions & 0 deletions wolfssl/wolfcrypt/pkcs7.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ typedef int (*CallbackRsaSignRawDigest)(wc_PKCS7* pkcs7, byte* digest,
int devId, int hashOID);
#endif

#if defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && defined(HAVE_ECC)
/* ECC sign raw digest callback, user signs hash directly */
typedef int (*CallbackEccSignRawDigest)(wc_PKCS7* pkcs7, byte* digest,
word32 digestSz, byte* out, word32 outSz,
byte* privateKey, word32 privateKeySz,
int devId, int hashOID);
#endif


/* Public Structure Warning:
* Existing members must not be changed to maintain backwards compatibility!
Expand Down Expand Up @@ -376,6 +384,10 @@ struct wc_PKCS7 {

CallbackAESKeyWrapUnwrap aesKeyWrapUnwrapCb;

#if defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && defined(HAVE_ECC)
CallbackEccSignRawDigest eccSignRawDigestCb;
#endif

/* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */
};

Expand Down Expand Up @@ -511,6 +523,11 @@ WOLFSSL_API int wc_PKCS7_SetRsaSignRawDigestCb(wc_PKCS7* pkcs7,
CallbackRsaSignRawDigest cb);
#endif

#if defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK) && defined(HAVE_ECC)
WOLFSSL_API int wc_PKCS7_SetEccSignRawDigestCb(wc_PKCS7* pkcs7,
CallbackEccSignRawDigest cb);
#endif

/* CMS/PKCS#7 EnvelopedData */
WOLFSSL_API int wc_PKCS7_EncodeEnvelopedData(wc_PKCS7* pkcs7,
byte* output, word32 outputSz);
Expand Down