Skip to content

Commit 085e486

Browse files
committed
Helpers for importing an external private key and creating an encrypted key blob.
1 parent 541a85c commit 085e486

File tree

3 files changed

+175
-7
lines changed

3 files changed

+175
-7
lines changed

examples/wrap/wrap_test.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -448,20 +448,26 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
448448
(word32)sizeof(kRsaKeyPrivDer));
449449
PRIVATE_KEY_LOCK();
450450
if (rc != 0) goto exit;
451-
rc = wolfTPM2_RsaKey_WolfToTpm_ex(&dev, &storageKey, &wolfRsaPrivKey,
452-
&rsaKey);
451+
XMEMSET(&testKey, 0, sizeof(testKey));
452+
rc = wolfTPM2_CreateRsaKeyBlob(&dev, &storageKey, &wolfRsaPrivKey,
453+
&testKey);
453454
wc_FreeRsaKey(&wolfRsaPrivKey);
454455
if (rc != 0 && rc != NOT_COMPILED_IN) {
455456
/* NOT_COMPILED_IN here likely means that AES-CFB is not enabled for
456457
* encrypting secrets */
457458
goto exit;
458459
}
460+
printf("RSA Private Key Blob created (private = %d bytes)\n",
461+
testKey.priv.size);
462+
463+
rc = wolfTPM2_LoadKey(&dev, &testKey, &storageKey.handle);
464+
if (rc != 0) goto exit;
459465
printf("RSA Private Key Loaded into TPM: Handle 0x%x\n",
460466
(word32)rsaKey.handle.hndl);
461467

462468
/* Use TPM Handle... */
463469

464-
rc = wolfTPM2_UnloadHandle(&dev, &rsaKey.handle);
470+
rc = wolfTPM2_UnloadHandle(&dev, &testKey.handle);
465471
if (rc != 0) goto exit;
466472
#endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_RSA && !NO_ASN */
467473

@@ -682,21 +688,26 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
682688
rc = wc_EccPrivateKeyDecode(kEccKeyPrivDer, &idx, &wolfEccPrivKey,
683689
(word32)sizeof(kEccKeyPrivDer));
684690
if (rc != 0) goto exit;
685-
rc = wolfTPM2_EccKey_WolfToTpm_ex(&dev, &storageKey, &wolfEccPrivKey,
686-
&eccKey);
691+
XMEMSET(&testKey, 0, sizeof(testKey));
692+
rc = wolfTPM2_CreateEccKeyBlob(&dev, &storageKey, &wolfEccPrivKey,
693+
&testKey);
687694
wc_ecc_free(&wolfEccPrivKey);
688695
if (rc != 0 && rc != NOT_COMPILED_IN) {
689696
/* NOT_COMPILED_IN here likely means the WOLFSSL_PUBLIC_MP is enabled
690697
* exposing the mp_ math API's or AES CFB is not enabled.
691698
* Both are needed for encrypting secrets */
692699
goto exit;
693700
}
701+
printf("ECC Private Key Blob created (private = %d bytes)\n",
702+
testKey.priv.size);
703+
rc = wolfTPM2_LoadKey(&dev, &testKey, &storageKey.handle);
704+
if (rc != 0) goto exit;
694705
printf("ECC Private Key Loaded into TPM: Handle 0x%x\n",
695-
(word32)eccKey.handle.hndl);
706+
(word32)testKey.handle.hndl);
696707

697708
/* Use TPM Handle... */
698709

699-
rc = wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
710+
rc = wolfTPM2_UnloadHandle(&dev, &testKey.handle);
700711
if (rc != 0) goto exit;
701712
#endif /* !WOLFTPM2_NO_WOLFCRYPT && HAVE_ECC && !NO_ASN */
702713

src/tpm2_wrap.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3502,6 +3502,51 @@ int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
35023502
return rc;
35033503
}
35043504

3505+
int wolfTPM2_CreateRsaKeyBlob(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey,
3506+
RsaKey* wolfKey, WOLFTPM2_KEYBLOB* tpmKey)
3507+
{
3508+
int rc;
3509+
word32 exponent;
3510+
byte e[sizeof(exponent)];
3511+
byte n[WOLFTPM2_WRAP_RSA_KEY_BITS / 8];
3512+
byte d[WOLFTPM2_WRAP_RSA_KEY_BITS / 8];
3513+
byte p[WOLFTPM2_WRAP_RSA_KEY_BITS / 8];
3514+
byte q[WOLFTPM2_WRAP_RSA_KEY_BITS / 8];
3515+
word32 eSz = sizeof(e);
3516+
word32 nSz = sizeof(n);
3517+
word32 dSz = sizeof(d);
3518+
word32 pSz = sizeof(p);
3519+
word32 qSz = sizeof(q);
3520+
3521+
if (dev == NULL || tpmKey == NULL || wolfKey == NULL || parentKey == NULL ||
3522+
wolfKey->type != RSA_PRIVATE) {
3523+
return BAD_FUNC_ARG;
3524+
}
3525+
3526+
XMEMSET(e, 0, sizeof(e));
3527+
XMEMSET(n, 0, sizeof(n));
3528+
XMEMSET(d, 0, sizeof(d));
3529+
XMEMSET(p, 0, sizeof(p));
3530+
XMEMSET(q, 0, sizeof(q));
3531+
3532+
/* export the raw private and public RSA as unsigned binary */
3533+
PRIVATE_KEY_UNLOCK();
3534+
rc = wc_RsaExportKey(wolfKey, e, &eSz, n, &nSz,
3535+
d, &dSz, p, &pSz, q, &qSz);
3536+
PRIVATE_KEY_LOCK();
3537+
if (rc == 0) {
3538+
exponent = wolfTPM2_RsaKey_Exponent(e, eSz);
3539+
3540+
rc = wolfTPM2_ImportRsaPrivateKey(dev, parentKey, tpmKey, n, nSz,
3541+
exponent, q, qSz, TPM_ALG_NULL, TPM_ALG_NULL);
3542+
}
3543+
3544+
/* not used */
3545+
(void)p;
3546+
3547+
return rc;
3548+
}
3549+
35053550
int wolfTPM2_RsaKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey,
35063551
RsaKey* wolfKey, WOLFTPM2_KEY* tpmKey)
35073552
{
@@ -3652,6 +3697,76 @@ int wolfTPM2_EccKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
36523697
}
36533698
#endif /* HAVE_ECC_KEY_IMPORT */
36543699
#ifdef HAVE_ECC_KEY_EXPORT
3700+
int wolfTPM2_CreateEccKeyBlob(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey,
3701+
ecc_key* wolfKey, WOLFTPM2_KEYBLOB* tpmKey)
3702+
{
3703+
int rc, curve_id = 0;
3704+
byte qx[WOLFTPM2_WRAP_ECC_KEY_BITS / 8];
3705+
byte qy[WOLFTPM2_WRAP_ECC_KEY_BITS / 8];
3706+
byte d[WOLFTPM2_WRAP_ECC_KEY_BITS / 8];
3707+
word32 qxSz = sizeof(qx);
3708+
word32 qySz = sizeof(qy);
3709+
word32 dSz = sizeof(d);
3710+
3711+
if (dev == NULL || tpmKey == NULL || wolfKey == NULL || parentKey == NULL ||
3712+
wolfKey->type == ECC_PUBLICKEY) {
3713+
return BAD_FUNC_ARG;
3714+
}
3715+
3716+
XMEMSET(tpmKey, 0, sizeof(*tpmKey));
3717+
XMEMSET(qx, 0, sizeof(qx));
3718+
XMEMSET(qy, 0, sizeof(qy));
3719+
XMEMSET(d, 0, sizeof(d));
3720+
3721+
if (wolfKey->dp)
3722+
curve_id = wolfKey->dp->id;
3723+
3724+
rc = TPM2_GetTpmCurve(curve_id);
3725+
if (rc < 0)
3726+
return rc;
3727+
curve_id = rc;
3728+
rc = 0;
3729+
3730+
if (wolfKey->type == ECC_PRIVATEKEY_ONLY) {
3731+
/* compute public point without modifying incoming wolf key */
3732+
int keySz = wc_ecc_size(wolfKey);
3733+
ecc_point* point = wc_ecc_new_point();
3734+
if (point == NULL) {
3735+
rc = MEMORY_E;
3736+
}
3737+
if (rc == 0) {
3738+
#ifdef ECC_TIMING_RESISTANT
3739+
rc = wc_ecc_make_pub_ex(wolfKey, point, wolfKey->rng);
3740+
#else
3741+
rc = wc_ecc_make_pub(wolfKey, point);
3742+
#endif
3743+
if (rc == 0)
3744+
rc = wc_export_int(point->x, qx, &qxSz, keySz,
3745+
WC_TYPE_UNSIGNED_BIN);
3746+
if (rc == 0)
3747+
rc = wc_export_int(point->y, qy, &qySz, keySz,
3748+
WC_TYPE_UNSIGNED_BIN);
3749+
if (rc == 0)
3750+
rc = wc_ecc_export_private_only(wolfKey, d, &dSz);
3751+
wc_ecc_del_point(point);
3752+
}
3753+
}
3754+
else {
3755+
/* export the raw private/public ECC portions */
3756+
rc = wc_ecc_export_private_raw(wolfKey,
3757+
qx, &qxSz,
3758+
qy, &qySz,
3759+
d, &dSz);
3760+
}
3761+
3762+
if (rc == 0) {
3763+
rc = wolfTPM2_ImportEccPrivateKey(dev, parentKey, tpmKey, curve_id,
3764+
qx, qxSz, qy, qySz, d, dSz);
3765+
}
3766+
3767+
return rc;
3768+
}
3769+
36553770
int wolfTPM2_EccKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey,
36563771
ecc_key* wolfKey, WOLFTPM2_KEY* tpmKey)
36573772
{

wolftpm/tpm2_wrap.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,6 +1423,27 @@ WOLFTPM_API int wolfTPM2_RsaKey_WolfToTpm(WOLFTPM2_DEV* dev, RsaKey* wolfKey,
14231423
WOLFTPM_API int wolfTPM2_RsaKey_WolfToTpm_ex(WOLFTPM2_DEV* dev,
14241424
const WOLFTPM2_KEY* parentKey, RsaKey* wolfKey, WOLFTPM2_KEY* tpmKey);
14251425

1426+
/*!
1427+
\ingroup wolfTPM2_Wrappers
1428+
\brief Create an encrypted RSA key blob from a wolfCrypt key under a specific parent key
1429+
\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.
1430+
1431+
\return TPM_RC_SUCCESS: successful
1432+
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)
1433+
\return BAD_FUNC_ARG: check the provided arguments
1434+
1435+
\param dev pointer to a TPM2_DEV struct
1436+
\param parentKey pointer to a WOLFTPM2_KEY struct, pointing to a Primary Key or TPM Hierarchy
1437+
\param wolfKey pointer to a struct of RsaKey type, holding a wolfcrypt key
1438+
\param tpmKey pointer to an empty struct of WOLFTPM2_KEYBLOB type, to hold the encrypted key blob
1439+
1440+
\sa wolfTPM2_LoadKey
1441+
\sa wolfTPM2_RsaKey_WolfToTpm_ex
1442+
\sa wolfTPM2_CreateEccKeyBlob
1443+
*/
1444+
WOLFTPM_API int wolfTPM2_CreateRsaKeyBlob(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey,
1445+
RsaKey* wolfKey, WOLFTPM2_KEYBLOB* tpmKey);
1446+
14261447
/*!
14271448
\ingroup wolfTPM2_Wrappers
14281449
\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,
15201541
WOLFTPM_API int wolfTPM2_EccKey_WolfToTpm_ex(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey,
15211542
ecc_key* wolfKey, WOLFTPM2_KEY* tpmKey);
15221543

1544+
/*!
1545+
\ingroup wolfTPM2_Wrappers
1546+
\brief Create an encrypted ECC key blob from a wolfCrypt key under a specific parent key
1547+
\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.
1548+
1549+
\return TPM_RC_SUCCESS: successful
1550+
\return TPM_RC_FAILURE: generic failure (check TPM IO and TPM return code)
1551+
\return BAD_FUNC_ARG: check the provided arguments
1552+
1553+
\param dev pointer to a TPM2_DEV struct
1554+
\param parentKey pointer to a WOLFTPM2_KEY struct, pointing to a Primary Key or TPM Hierarchy
1555+
\param wolfKey pointer to a struct of ecc_key type, holding a wolfcrypt key
1556+
\param tpmKey pointer to an empty struct of WOLFTPM2_KEYBLOB type, to hold the encrypted key blob
1557+
1558+
\sa wolfTPM2_LoadKey
1559+
\sa wolfTPM2_EccKey_WolfToTpm_ex
1560+
\sa wolfTPM2_CreateRsaKeyBlob
1561+
*/
1562+
WOLFTPM_API int wolfTPM2_CreateEccKeyBlob(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* parentKey,
1563+
ecc_key* wolfKey, WOLFTPM2_KEYBLOB* tpmKey);
1564+
15231565
/*!
15241566
\ingroup wolfTPM2_Wrappers
15251567
\brief Import a ECC public key generated from wolfcrypt key into the TPM

0 commit comments

Comments
 (0)