diff --git a/examples/wrap/wrap_test.c b/examples/wrap/wrap_test.c index ac03ebcf..971064dc 100644 --- a/examples/wrap/wrap_test.c +++ b/examples/wrap/wrap_test.c @@ -448,20 +448,26 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[]) (word32)sizeof(kRsaKeyPrivDer)); PRIVATE_KEY_LOCK(); if (rc != 0) goto exit; - rc = wolfTPM2_RsaKey_WolfToTpm_ex(&dev, &storageKey, &wolfRsaPrivKey, - &rsaKey); + XMEMSET(&testKey, 0, sizeof(testKey)); + rc = wolfTPM2_CreateRsaKeyBlob(&dev, &storageKey, &wolfRsaPrivKey, + &testKey); wc_FreeRsaKey(&wolfRsaPrivKey); if (rc != 0 && rc != NOT_COMPILED_IN) { /* NOT_COMPILED_IN here likely means that AES-CFB is not enabled for * encrypting secrets */ goto exit; } + printf("RSA Private Key Blob created (private = %d bytes)\n", + testKey.priv.size); + + rc = wolfTPM2_LoadKey(&dev, &testKey, &storageKey.handle); + if (rc != 0) goto exit; printf("RSA Private Key Loaded into TPM: Handle 0x%x\n", (word32)rsaKey.handle.hndl); /* Use TPM Handle... */ - rc = wolfTPM2_UnloadHandle(&dev, &rsaKey.handle); + rc = wolfTPM2_UnloadHandle(&dev, &testKey.handle); if (rc != 0) goto exit; #endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_RSA && !NO_ASN */ @@ -682,8 +688,9 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[]) rc = wc_EccPrivateKeyDecode(kEccKeyPrivDer, &idx, &wolfEccPrivKey, (word32)sizeof(kEccKeyPrivDer)); if (rc != 0) goto exit; - rc = wolfTPM2_EccKey_WolfToTpm_ex(&dev, &storageKey, &wolfEccPrivKey, - &eccKey); + XMEMSET(&testKey, 0, sizeof(testKey)); + rc = wolfTPM2_CreateEccKeyBlob(&dev, &storageKey, &wolfEccPrivKey, + &testKey); wc_ecc_free(&wolfEccPrivKey); if (rc != 0 && rc != NOT_COMPILED_IN) { /* NOT_COMPILED_IN here likely means the WOLFSSL_PUBLIC_MP is enabled @@ -691,12 +698,16 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[]) * Both are needed for encrypting secrets */ goto exit; } + printf("ECC Private Key Blob created (private = %d bytes)\n", + testKey.priv.size); + rc = wolfTPM2_LoadKey(&dev, &testKey, &storageKey.handle); + if (rc != 0) goto exit; printf("ECC Private Key Loaded into TPM: Handle 0x%x\n", - (word32)eccKey.handle.hndl); + (word32)testKey.handle.hndl); /* Use TPM Handle... */ - rc = wolfTPM2_UnloadHandle(&dev, &eccKey.handle); + rc = wolfTPM2_UnloadHandle(&dev, &testKey.handle); if (rc != 0) goto exit; #endif /* !WOLFTPM2_NO_WOLFCRYPT && HAVE_ECC && !NO_ASN */ diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index b7515f94..bc5bf273 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -3502,6 +3502,51 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey, return rc; } +int wolfTPM2_CreateRsaKeyBlob(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey, + RsaKey* wolfKey, WOLFTPM2_KEYBLOB* tpmKey) +{ + int rc; + word32 exponent; + byte e[sizeof(exponent)]; + byte n[WOLFTPM2_WRAP_RSA_KEY_BITS / 8]; + byte d[WOLFTPM2_WRAP_RSA_KEY_BITS / 8]; + byte p[WOLFTPM2_WRAP_RSA_KEY_BITS / 8]; + byte q[WOLFTPM2_WRAP_RSA_KEY_BITS / 8]; + word32 eSz = sizeof(e); + word32 nSz = sizeof(n); + word32 dSz = sizeof(d); + word32 pSz = sizeof(p); + word32 qSz = sizeof(q); + + if (dev == NULL || tpmKey == NULL || wolfKey == NULL || parentKey == NULL || + wolfKey->type != RSA_PRIVATE) { + return BAD_FUNC_ARG; + } + + XMEMSET(e, 0, sizeof(e)); + XMEMSET(n, 0, sizeof(n)); + XMEMSET(d, 0, sizeof(d)); + XMEMSET(p, 0, sizeof(p)); + XMEMSET(q, 0, sizeof(q)); + + /* export the raw private and public RSA as unsigned binary */ + PRIVATE_KEY_UNLOCK(); + rc = wc_RsaExportKey(wolfKey, e, &eSz, n, &nSz, + d, &dSz, p, &pSz, q, &qSz); + PRIVATE_KEY_LOCK(); + if (rc == 0) { + exponent = wolfTPM2_RsaKey_Exponent(e, eSz); + + rc = wolfTPM2_ImportRsaPrivateKey(dev, parentKey, tpmKey, n, nSz, + exponent, q, qSz, TPM_ALG_NULL, TPM_ALG_NULL); + } + + /* not used */ + (void)p; + + return rc; +} + int wolfTPM2_RsaKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey, RsaKey* wolfKey, WOLFTPM2_KEY* tpmKey) { @@ -3652,6 +3697,76 @@ int wolfTPM2_EccKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey, } #endif /* HAVE_ECC_KEY_IMPORT */ #ifdef HAVE_ECC_KEY_EXPORT +int wolfTPM2_CreateEccKeyBlob(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey, + ecc_key* wolfKey, WOLFTPM2_KEYBLOB* tpmKey) +{ + int rc, curve_id = 0; + byte qx[WOLFTPM2_WRAP_ECC_KEY_BITS / 8]; + byte qy[WOLFTPM2_WRAP_ECC_KEY_BITS / 8]; + byte d[WOLFTPM2_WRAP_ECC_KEY_BITS / 8]; + word32 qxSz = sizeof(qx); + word32 qySz = sizeof(qy); + word32 dSz = sizeof(d); + + if (dev == NULL || tpmKey == NULL || wolfKey == NULL || parentKey == NULL || + wolfKey->type == ECC_PUBLICKEY) { + return BAD_FUNC_ARG; + } + + XMEMSET(tpmKey, 0, sizeof(*tpmKey)); + XMEMSET(qx, 0, sizeof(qx)); + XMEMSET(qy, 0, sizeof(qy)); + XMEMSET(d, 0, sizeof(d)); + + if (wolfKey->dp) + curve_id = wolfKey->dp->id; + + rc = TPM2_GetTpmCurve(curve_id); + if (rc < 0) + return rc; + curve_id = rc; + rc = 0; + + if (wolfKey->type == ECC_PRIVATEKEY_ONLY) { + /* compute public point without modifying incoming wolf key */ + int keySz = wc_ecc_size(wolfKey); + ecc_point* point = wc_ecc_new_point(); + if (point == NULL) { + rc = MEMORY_E; + } + if (rc == 0) { + #ifdef ECC_TIMING_RESISTANT + rc = wc_ecc_make_pub_ex(wolfKey, point, wolfKey->rng); + #else + rc = wc_ecc_make_pub(wolfKey, point); + #endif + if (rc == 0) + rc = wc_export_int(point->x, qx, &qxSz, keySz, + WC_TYPE_UNSIGNED_BIN); + if (rc == 0) + rc = wc_export_int(point->y, qy, &qySz, keySz, + WC_TYPE_UNSIGNED_BIN); + if (rc == 0) + rc = wc_ecc_export_private_only(wolfKey, d, &dSz); + wc_ecc_del_point(point); + } + } + else { + /* export the raw private/public ECC portions */ + rc = wc_ecc_export_private_raw(wolfKey, + qx, &qxSz, + qy, &qySz, + d, &dSz); + } + + if (rc == 0) { + rc = wolfTPM2_ImportEccPrivateKey(dev, parentKey, tpmKey, curve_id, + qx, qxSz, qy, qySz, d, dSz); + } + + return rc; +} + int wolfTPM2_EccKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey, ecc_key* wolfKey, WOLFTPM2_KEY* tpmKey) { diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index 19a45598..f01a0a53 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -1423,6 +1423,27 @@ WOLFTPM_API int wolfTPM2_RsaKey_WolfToTpm(WOLFTPM2_DEV* dev, RsaKey* wolfKey, WOLFTPM_API int wolfTPM2_RsaKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey, RsaKey* wolfKey, WOLFTPM2_KEY* tpmKey); +/*! + \ingroup wolfTPM2_Wrappers + \brief Create an encrypted RSA key blob from a wolfCrypt key under a specific parent key + \note Creates an encrypted version of the key in WOLFTPM2_KEYBLOB format, but does not load the key into the TPM. Use wolfTPM2_LoadKey() to load the key. + + \return TPM_RC_SUCCESS: successful + \return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code) + \return BAD_FUNC_ARG: check the provided arguments + + \param dev pointer to a TPM2_DEV struct + \param parentKey pointer to a WOLFTPM2_KEY struct, pointing to a Primary Key or TPM Hierarchy + \param wolfKey pointer to a struct of RsaKey type, holding a wolfcrypt key + \param tpmKey pointer to an empty struct of WOLFTPM2_KEYBLOB type, to hold the encrypted key blob + + \sa wolfTPM2_LoadKey + \sa wolfTPM2_RsaKey_WolfToTpm_ex + \sa wolfTPM2_CreateEccKeyBlob +*/ +WOLFTPM_API int wolfTPM2_CreateRsaKeyBlob(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey, + RsaKey* wolfKey, WOLFTPM2_KEYBLOB* tpmKey); + /*! \ingroup wolfTPM2_Wrappers \brief Import a PEM format public key from a file into the TPM @@ -1520,6 +1541,27 @@ WOLFTPM_API int wolfTPM2_EccKey_WolfToTpm(WOLFTPM2_DEV* dev, ecc_key* wolfKey, WOLFTPM_API int wolfTPM2_EccKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey, ecc_key* wolfKey, WOLFTPM2_KEY* tpmKey); +/*! + \ingroup wolfTPM2_Wrappers + \brief Create an encrypted ECC key blob from a wolfCrypt key under a specific parent key + \note Creates an encrypted version of the key in WOLFTPM2_KEYBLOB format, but does not load the key into the TPM. Use wolfTPM2_LoadKey() to load the key. + + \return TPM_RC_SUCCESS: successful + \return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code) + \return BAD_FUNC_ARG: check the provided arguments + + \param dev pointer to a TPM2_DEV struct + \param parentKey pointer to a WOLFTPM2_KEY struct, pointing to a Primary Key or TPM Hierarchy + \param wolfKey pointer to a struct of ecc_key type, holding a wolfcrypt key + \param tpmKey pointer to an empty struct of WOLFTPM2_KEYBLOB type, to hold the encrypted key blob + + \sa wolfTPM2_LoadKey + \sa wolfTPM2_EccKey_WolfToTpm_ex + \sa wolfTPM2_CreateRsaKeyBlob +*/ +WOLFTPM_API int wolfTPM2_CreateEccKeyBlob(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey, + ecc_key* wolfKey, WOLFTPM2_KEYBLOB* tpmKey); + /*! \ingroup wolfTPM2_Wrappers \brief Import a ECC public key generated from wolfcrypt key into the TPM