@@ -7332,6 +7332,105 @@ typedef struct CSRKey {
73327332 TpmCryptoDevCtx tpmCtx ;
73337333} CSRKey ;
73347334
7335+ /*
7336+ * Internal callback function for wc_SignCert_cb that uses TPM for signing.
7337+ *
7338+ * This callback implements the wc_SignCertCb interface to perform certificate
7339+ * and CSR signing using the TPM. It is used internally by CSR_MakeAndSign_Cb
7340+ * when the callback-based signing approach is selected.
7341+ *
7342+ * For RSA keys:
7343+ * - Input is PKCS#1 v1.5 padded digest (already encoded by wolfSSL)
7344+ * - Uses wolfTPM2_RsaDecrypt with TPM_ALG_NULL (no padding) to perform
7345+ * the private key operation for signing
7346+ *
7347+ * For ECC keys:
7348+ * - Input is the raw hash to sign
7349+ * - Uses wolfTPM2_SignHash to sign with TPM
7350+ * - Converts TPM's R||S format to DER-encoded ECDSA signature
7351+ *
7352+ * Parameters:
7353+ * in - Data to sign (encoded for RSA, raw hash for ECC)
7354+ * inLen - Length of input data
7355+ * out - Output buffer for signature
7356+ * outLen - Input: buffer size, Output: signature size
7357+ * sigAlgo - Signature algorithm (not used, determined by keyType)
7358+ * keyType - Key type (RSA_TYPE or ECC_TYPE)
7359+ * ctx - TpmSignCbCtx containing TPM device and key
7360+ *
7361+ * Returns:
7362+ * 0 on success
7363+ * BAD_FUNC_ARG on invalid parameters
7364+ * NOT_COMPILED_IN if key type not supported
7365+ * Other negative values on TPM errors
7366+ */
7367+ static int wolfTPM2_SignCertCb (const byte * in , word32 inLen ,
7368+ byte * out , word32 * outLen , int sigAlgo , int keyType , void * ctx )
7369+ {
7370+ int rc ;
7371+ TpmSignCbCtx * tpmCtx = (TpmSignCbCtx * )ctx ;
7372+
7373+ if (tpmCtx == NULL || tpmCtx -> dev == NULL || tpmCtx -> key == NULL ) {
7374+ return BAD_FUNC_ARG ;
7375+ }
7376+
7377+ (void )sigAlgo ; /* Algorithm determined by key type */
7378+
7379+ if (keyType == ECC_TYPE ) {
7380+ #ifdef HAVE_ECC
7381+ byte sigRS [MAX_ECC_BYTES * 2 ];
7382+ int rsLen = (int )sizeof (sigRS );
7383+ word32 keySz ;
7384+
7385+ /* Get key size for proper R/S formatting */
7386+ keySz = TPM2_GetCurveSize (
7387+ tpmCtx -> key -> pub .publicArea .parameters .eccDetail .curveID );
7388+
7389+ /* Sign using TPM */
7390+ rc = wolfTPM2_SignHash (tpmCtx -> dev , tpmCtx -> key ,
7391+ in , inLen , sigRS , & rsLen );
7392+
7393+ if (rc == 0 ) {
7394+ byte * r , * s ;
7395+ word32 rLen , sLen ;
7396+
7397+ /* Split R and S from concatenated signature */
7398+ rLen = sLen = rsLen / 2 ;
7399+ r = & sigRS [0 ];
7400+ s = & sigRS [rLen ];
7401+
7402+ /* Encode as DER ECDSA signature */
7403+ rc = wc_ecc_rs_raw_to_sig (r , rLen , s , sLen , out , outLen );
7404+ }
7405+ #else
7406+ rc = NOT_COMPILED_IN ;
7407+ #endif
7408+ }
7409+ else if (keyType == RSA_TYPE ) {
7410+ #ifndef NO_RSA
7411+ int outSz = (int )* outLen ;
7412+
7413+ /* For RSA, input is already PKCS#1 v1.5 padded digest
7414+ * Use RSA decrypt (private key operation) for signing */
7415+ rc = wolfTPM2_RsaDecrypt (tpmCtx -> dev , tpmCtx -> key ,
7416+ TPM_ALG_NULL , /* No padding - input is pre-padded */
7417+ in , inLen , out , & outSz );
7418+
7419+ if (rc == 0 ) {
7420+ * outLen = (word32 )outSz ;
7421+ }
7422+ #else
7423+ rc = NOT_COMPILED_IN ;
7424+ #endif
7425+ }
7426+ else {
7427+ rc = BAD_FUNC_ARG ;
7428+ }
7429+
7430+ return rc ;
7431+ }
7432+
7433+
73357434static int CSR_MakeAndSign (WOLFTPM2_DEV * dev , WOLFTPM2_CSR * csr , CSRKey * key ,
73367435 int outFormat , byte * out , int outSz , int selfSignCert )
73377436{
@@ -7382,6 +7481,96 @@ static int CSR_MakeAndSign(WOLFTPM2_DEV* dev, WOLFTPM2_CSR* csr, CSRKey* key,
73827481 return rc ;
73837482}
73847483
7484+ /*
7485+ * Internal function for CSR/Certificate generation and signing using the
7486+ * callback-based approach.
7487+ *
7488+ * This function generates and signs a Certificate Signing Request (CSR) or
7489+ * self-signed certificate using the new wc_SignCert_cb() API. Unlike the
7490+ * legacy CSR_MakeAndSign() function which requires crypto callback setup,
7491+ * this function calls TPM signing directly via wolfTPM2_SignCertCb().
7492+ *
7493+ * Advantages of this approach:
7494+ * - FIPS compliant (no wolfCrypt crypto offloading)
7495+ * - Simpler code path (no crypto callback infrastructure)
7496+ * - Direct TPM signing without intermediate key structures
7497+ *
7498+ * Parameters:
7499+ * dev - Initialized TPM device
7500+ * csr - CSR structure with subject, extensions, etc.
7501+ * key - TPM key to use for signing
7502+ * keyType - Key type (RSA_TYPE or ECC_TYPE)
7503+ * outFormat - Output format (ENCODING_TYPE_PEM or ENCODING_TYPE_ASN1)
7504+ * out - Output buffer
7505+ * outSz - Size of output buffer
7506+ * selfSignCert - 1 to create self-signed cert, 0 for CSR
7507+ *
7508+ * Returns:
7509+ * Positive value: size of generated CSR/certificate
7510+ * BAD_FUNC_ARG: invalid parameters
7511+ * BUFFER_E: output buffer too small
7512+ * Other negative: error code from wolfSSL or TPM
7513+ */
7514+ static int CSR_MakeAndSign_Cb (WOLFTPM2_DEV * dev , WOLFTPM2_CSR * csr ,
7515+ WOLFTPM2_KEY * key , int keyType , int outFormat , byte * out , int outSz ,
7516+ int selfSignCert )
7517+ {
7518+ int rc = 0 ;
7519+ TpmSignCbCtx signCtx ;
7520+
7521+ if (dev == NULL || csr == NULL || key == NULL || out == NULL ) {
7522+ return BAD_FUNC_ARG ;
7523+ }
7524+
7525+ /* Setup signing context */
7526+ signCtx .dev = dev ;
7527+ signCtx .key = key ;
7528+
7529+ /* Create certificate body */
7530+ if (selfSignCert ) {
7531+ #ifdef WOLFSSL_CERT_GEN
7532+ rc = wc_MakeCert_ex (& csr -> req , out , outSz , keyType , NULL ,
7533+ wolfTPM2_GetRng (dev ));
7534+ #else
7535+ rc = NOT_COMPILED_IN ;
7536+ #endif
7537+ }
7538+ else {
7539+ rc = wc_MakeCertReq_ex (& csr -> req , out , outSz , keyType , NULL );
7540+ }
7541+
7542+ /* Sign using TPM via callback */
7543+ if (rc >= 0 ) {
7544+ rc = wc_SignCert_cb (csr -> req .bodySz , csr -> req .sigType , out ,
7545+ (word32 )outSz , keyType , wolfTPM2_SignCertCb , & signCtx ,
7546+ wolfTPM2_GetRng (dev ));
7547+ }
7548+
7549+ /* Optionally convert to PEM */
7550+ if (rc >= 0 && outFormat == ENCODING_TYPE_PEM ) {
7551+ #ifdef WOLFSSL_DER_TO_PEM
7552+ byte tmp [MAX_CONTEXT_SIZE ];
7553+ if (rc > (int )sizeof (tmp )) {
7554+ rc = BUFFER_E ;
7555+ }
7556+ else {
7557+ XMEMCPY (tmp , out , rc );
7558+ XMEMSET (out , 0 , outSz );
7559+ rc = wc_DerToPem (tmp , (word32 )rc , out , outSz ,
7560+ selfSignCert ? CERT_TYPE : CERTREQ_TYPE );
7561+ }
7562+ #else
7563+ #ifdef DEBUG_WOLFTPM
7564+ printf ("CSR_MakeAndSign_Cb PEM not supported\n" );
7565+ #endif
7566+ rc = NOT_COMPILED_IN ;
7567+ #endif
7568+ }
7569+
7570+ return rc ;
7571+ }
7572+
7573+
73857574static int CSR_KeySetup (WOLFTPM2_DEV * dev , WOLFTPM2_CSR * csr , WOLFTPM2_KEY * key ,
73867575 CSRKey * csrKey , int sigType , int devId )
73877576{
@@ -7576,12 +7765,36 @@ int wolfTPM2_CSR_MakeAndSign_ex(WOLFTPM2_DEV* dev, WOLFTPM2_CSR* csr,
75767765 int sigType , int selfSignCert , int devId )
75777766{
75787767 int rc ;
7579- CSRKey csrKey ;
7768+ int keyType ;
75807769
75817770 if (dev == NULL || key == NULL || csr == NULL || out == NULL ) {
75827771 return BAD_FUNC_ARG ;
75837772 }
75847773
7774+ /* Determine key type from TPM key */
7775+ if (key -> pub .publicArea .type == TPM_ALG_ECC ) {
7776+ keyType = ECC_TYPE ;
7777+ }
7778+ else if (key -> pub .publicArea .type == TPM_ALG_RSA ) {
7779+ keyType = RSA_TYPE ;
7780+ }
7781+ else {
7782+ return BAD_FUNC_ARG ;
7783+ }
7784+
7785+ /* Set signature type if not specified */
7786+ if (sigType == 0 ) {
7787+ if (keyType == RSA_TYPE ) {
7788+ csr -> req .sigType = CTC_SHA256wRSA ;
7789+ }
7790+ else if (keyType == ECC_TYPE ) {
7791+ csr -> req .sigType = CTC_SHA256wECDSA ;
7792+ }
7793+ }
7794+ else {
7795+ csr -> req .sigType = sigType ;
7796+ }
7797+
75857798 /* Set version to 2 for self-signed certificates, 0 for regular CSRs per RFC2986 */
75867799 if (selfSignCert ) {
75877800 csr -> req .version = 2 ;
@@ -7590,12 +7803,21 @@ int wolfTPM2_CSR_MakeAndSign_ex(WOLFTPM2_DEV* dev, WOLFTPM2_CSR* csr,
75907803 csr -> req .version = 0 ;
75917804 }
75927805
7593- rc = CSR_KeySetup ( dev , csr , key , & csrKey , sigType , devId );
7594- if (rc == 0 ) {
7595- rc = CSR_MakeAndSign (dev , csr , & csrKey , outFormat , out , outSz ,
7806+ /* Use new callback-based signing if devId not specified */
7807+ if (devId == INVALID_DEVID ) {
7808+ rc = CSR_MakeAndSign_Cb (dev , csr , key , keyType , outFormat , out , outSz ,
75967809 selfSignCert );
75977810 }
7598- CSR_KeyCleanup (dev , & csrKey );
7811+ else {
7812+ /* Fall back to crypto callback approach for backward compatibility */
7813+ CSRKey csrKey ;
7814+ rc = CSR_KeySetup (dev , csr , key , & csrKey , sigType , devId );
7815+ if (rc == 0 ) {
7816+ rc = CSR_MakeAndSign (dev , csr , & csrKey , outFormat , out , outSz ,
7817+ selfSignCert );
7818+ }
7819+ CSR_KeyCleanup (dev , & csrKey );
7820+ }
75997821
76007822 return rc ;
76017823}
0 commit comments