@@ -388,12 +388,15 @@ int test_wc_PKCS7_EncodeData(void)
388388
389389#if defined(HAVE_PKCS7 ) && defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK ) && \
390390 !defined(NO_RSA ) && !defined(NO_SHA256 )
391- /* RSA sign raw digest callback */
391+ /* RSA sign raw digest callback
392+ * This callback demonstrates HSM/secure element use case where the private
393+ * key is not passed through PKCS7 structure but obtained independently.
394+ */
392395static int rsaSignRawDigestCb (PKCS7 * pkcs7 , byte * digest , word32 digestSz ,
393396 byte * out , word32 outSz , byte * privateKey ,
394397 word32 privateKeySz , int devid , int hashOID )
395398{
396- /* specific DigestInfo ASN.1 encoding prefix for a SHA2565 digest */
399+ /* specific DigestInfo ASN.1 encoding prefix for a SHA256 digest */
397400 byte digInfoEncoding [] = {
398401 0x30 , 0x31 , 0x30 , 0x0d , 0x06 , 0x09 , 0x60 , 0x86 ,
399402 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x01 , 0x05 ,
@@ -407,6 +410,11 @@ static int rsaSignRawDigestCb(PKCS7* pkcs7, byte* digest, word32 digestSz,
407410 word32 idx = 0 ;
408411 RsaKey rsa ;
409412
413+ /* privateKey may be NULL in HSM/secure element use case - we load it
414+ * independently in this callback to simulate that scenario */
415+ (void )privateKey ;
416+ (void )privateKeySz ;
417+
410418 /* SHA-256 required only for this example callback due to above
411419 * digInfoEncoding[] */
412420 if (pkcs7 == NULL || digest == NULL || out == NULL ||
@@ -427,7 +435,33 @@ static int rsaSignRawDigestCb(PKCS7* pkcs7, byte* digest, word32 digestSz,
427435 return ret ;
428436 }
429437
430- ret = wc_RsaPrivateKeyDecode (privateKey , & idx , & rsa , privateKeySz );
438+ /* Load key from test buffer - simulates HSM/secure element access */
439+ #if defined(USE_CERT_BUFFERS_2048 )
440+ ret = wc_RsaPrivateKeyDecode (client_key_der_2048 , & idx , & rsa ,
441+ sizeof_client_key_der_2048 );
442+ #elif defined(USE_CERT_BUFFERS_1024 )
443+ ret = wc_RsaPrivateKeyDecode (client_key_der_1024 , & idx , & rsa ,
444+ sizeof_client_key_der_1024 );
445+ #else
446+ {
447+ XFILE fp ;
448+ byte keyBuf [ONEK_BUF ];
449+ int keySz ;
450+
451+ fp = XFOPEN ("./certs/client-key.der" , "rb" );
452+ if (fp == XBADFILE ) {
453+ wc_FreeRsaKey (& rsa );
454+ return -1 ;
455+ }
456+ keySz = (int )XFREAD (keyBuf , 1 , sizeof (keyBuf ), fp );
457+ XFCLOSE (fp );
458+ if (keySz <= 0 ) {
459+ wc_FreeRsaKey (& rsa );
460+ return -1 ;
461+ }
462+ ret = wc_RsaPrivateKeyDecode (keyBuf , & idx , & rsa , (word32 )keySz );
463+ }
464+ #endif
431465
432466 /* sign DigestInfo */
433467 if (ret == 0 ) {
@@ -451,6 +485,76 @@ static int rsaSignRawDigestCb(PKCS7* pkcs7, byte* digest, word32 digestSz,
451485}
452486#endif
453487
488+ #if defined(HAVE_PKCS7 ) && defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK ) && \
489+ defined(HAVE_ECC ) && !defined(NO_SHA256 )
490+ /* ECC sign raw digest callback
491+ * This callback demonstrates HSM/secure element use case where the private
492+ * key is not passed through PKCS7 structure but obtained independently.
493+ */
494+ static int eccSignRawDigestCb (PKCS7 * pkcs7 , byte * digest , word32 digestSz ,
495+ byte * out , word32 outSz , byte * privateKey ,
496+ word32 privateKeySz , int devid , int hashOID )
497+ {
498+ int ret ;
499+ word32 idx = 0 ;
500+ word32 sigSz = outSz ;
501+ ecc_key ecc ;
502+
503+ /* privateKey may be NULL in HSM/secure element use case - we load it
504+ * independently in this callback to simulate that scenario */
505+ (void )privateKey ;
506+ (void )privateKeySz ;
507+ (void )hashOID ;
508+
509+ if (pkcs7 == NULL || digest == NULL || out == NULL ) {
510+ return -1 ;
511+ }
512+
513+ /* set up ECC key */
514+ ret = wc_ecc_init_ex (& ecc , pkcs7 -> heap , devid );
515+ if (ret != 0 ) {
516+ return ret ;
517+ }
518+
519+ /* Load key from test buffer - simulates HSM/secure element access */
520+ #if defined(USE_CERT_BUFFERS_256 )
521+ ret = wc_EccPrivateKeyDecode (ecc_clikey_der_256 , & idx , & ecc ,
522+ sizeof_ecc_clikey_der_256 );
523+ #else
524+ {
525+ XFILE fp ;
526+ byte keyBuf [ONEK_BUF ];
527+ int keySz ;
528+
529+ fp = XFOPEN ("./certs/client-ecc-key.der" , "rb" );
530+ if (fp == XBADFILE ) {
531+ wc_ecc_free (& ecc );
532+ return -1 ;
533+ }
534+ keySz = (int )XFREAD (keyBuf , 1 , sizeof (keyBuf ), fp );
535+ XFCLOSE (fp );
536+ if (keySz <= 0 ) {
537+ wc_ecc_free (& ecc );
538+ return -1 ;
539+ }
540+ ret = wc_EccPrivateKeyDecode (keyBuf , & idx , & ecc , (word32 )keySz );
541+ }
542+ #endif
543+
544+ /* sign digest */
545+ if (ret == 0 ) {
546+ ret = wc_ecc_sign_hash (digest , digestSz , out , & sigSz , pkcs7 -> rng , & ecc );
547+ if (ret == 0 ) {
548+ ret = (int )sigSz ;
549+ }
550+ }
551+
552+ wc_ecc_free (& ecc );
553+
554+ return ret ;
555+ }
556+ #endif
557+
454558#if defined(HAVE_PKCS7 ) && defined(ASN_BER_TO_DER )
455559typedef struct encodeSignedDataStream {
456560 byte out [FOURK_BUF * 3 ];
@@ -757,8 +861,7 @@ int test_wc_PKCS7_EncodeSignedData(void)
757861 if (pkcs7 != NULL ) {
758862 pkcs7 -> content = data ;
759863 pkcs7 -> contentSz = (word32 )sizeof (data );
760- pkcs7 -> privateKey = key ;
761- pkcs7 -> privateKeySz = (word32 )sizeof (key );
864+ /* privateKey not set - callback simulates HSM/secure element access */
762865 pkcs7 -> encryptOID = RSAk ;
763866 pkcs7 -> hashOID = SHA256h ;
764867 pkcs7 -> rng = & rng ;
@@ -769,6 +872,47 @@ int test_wc_PKCS7_EncodeSignedData(void)
769872 ExpectIntGT (wc_PKCS7_EncodeSignedData (pkcs7 , output , outputSz ), 0 );
770873#endif
771874
875+ #if defined(HAVE_PKCS7 ) && defined(HAVE_PKCS7_ECC_RAW_SIGN_CALLBACK ) && \
876+ defined(HAVE_ECC ) && !defined(NO_SHA256 )
877+ /* test ECC sign raw digest callback, if using ECC and compiled in.
878+ * Example callback assumes SHA-256, so only run test if compiled in. */
879+ {
880+ #if defined(USE_CERT_BUFFERS_256 )
881+ byte eccCert [sizeof (cliecc_cert_der_256 )];
882+ word32 eccCertSz = (word32 )sizeof (eccCert );
883+ XMEMCPY (eccCert , cliecc_cert_der_256 , eccCertSz );
884+ #else
885+ byte eccCert [ONEK_BUF ];
886+ int eccCertSz ;
887+ XFILE eccFp = XBADFILE ;
888+
889+ ExpectTrue ((eccFp = XFOPEN ("./certs/client-ecc-cert.der" , "rb" )) !=
890+ XBADFILE );
891+ ExpectIntGT (eccCertSz = (int )XFREAD (eccCert , 1 , ONEK_BUF , eccFp ), 0 );
892+ if (eccFp != XBADFILE )
893+ XFCLOSE (eccFp );
894+ #endif
895+
896+ wc_PKCS7_Free (pkcs7 );
897+ pkcs7 = NULL ;
898+ ExpectNotNull (pkcs7 = wc_PKCS7_New (HEAP_HINT , testDevId ));
899+ ExpectIntEQ (wc_PKCS7_InitWithCert (pkcs7 , eccCert , (word32 )eccCertSz ), 0 );
900+
901+ if (pkcs7 != NULL ) {
902+ pkcs7 -> content = data ;
903+ pkcs7 -> contentSz = (word32 )sizeof (data );
904+ /* privateKey not set - callback simulates HSM/secure element access */
905+ pkcs7 -> encryptOID = ECDSAk ;
906+ pkcs7 -> hashOID = SHA256h ;
907+ pkcs7 -> rng = & rng ;
908+ }
909+
910+ ExpectIntEQ (wc_PKCS7_SetEccSignRawDigestCb (pkcs7 , eccSignRawDigestCb ), 0 );
911+
912+ ExpectIntGT (wc_PKCS7_EncodeSignedData (pkcs7 , output , outputSz ), 0 );
913+ }
914+ #endif
915+
772916 wc_PKCS7_Free (pkcs7 );
773917 DoExpectIntEQ (wc_FreeRng (& rng ), 0 );
774918
0 commit comments