Skip to content

Commit 6cfe800

Browse files
authored
Merge pull request #428 from dgarske/handle_private
Improvements for key creation and exporting encrypted private key
2 parents 2ce5bbc + 2fbbef4 commit 6cfe800

File tree

6 files changed

+327
-76
lines changed

6 files changed

+327
-76
lines changed

.github/workflows/make-test-swtpm.yml

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,26 @@ jobs:
161161
- name: make not provisioning
162162
run: make
163163

164+
# test with symmetric encryption
165+
- name: configure symmetric
166+
run: ./configure --enable-swtpm CFLAGS="-DWOLFTPM_USE_SYMMETRIC"
167+
- name: make symmetric
168+
run: make
169+
- name: make check symmetric
170+
run: |
171+
make check
172+
WOLFSSL_PATH=./wolfssl ./examples/run_examples.sh
173+
174+
# test with software ecdhe
175+
- name: configure swecdhe
176+
run: ./configure --enable-swtpm CFLAGS="-DWOLFTPM2_USE_SW_ECDHE"
177+
- name: make swecdhe
178+
run: make
179+
- name: make check swecdhe
180+
run: |
181+
make check
182+
WOLFSSL_PATH=./wolfssl ./examples/run_examples.sh
183+
164184
# test without ECC
165185
- name: wolfssl no ECC
166186
working-directory: ./wolfssl
@@ -240,16 +260,6 @@ jobs:
240260
make check
241261
WOLFSSL_PATH=./wolfssl NO_PUBASPRIV=1 ./examples/run_examples.sh
242262
243-
# test with symmetric encryption
244-
- name: configure symmetric
245-
run: ./configure --enable-swtpm CFLAGS="-DWOLFTPM_USE_SYMMETRIC"
246-
- name: make symmetric
247-
run: make
248-
- name: make check symmetric
249-
run: |
250-
make check
251-
WOLFSSL_PATH=./wolfssl ./examples/run_examples.sh
252-
253263
# capture logs on failure
254264
- name: Upload failure logs
255265
if: failure()

examples/wrap/wrap_test.c

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
124124
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
125125
WOLFTPM2_SESSION tpmSession;
126126

127+
XMEMSET(&rsaKey, 0, sizeof(rsaKey));
128+
XMEMSET(&eccKey, 0, sizeof(eccKey));
127129
XMEMSET(&aesKey, 0, sizeof(aesKey));
128130
XMEMSET(&publicKey, 0, sizeof(publicKey));
129131
#ifndef WOLFTPM2_NO_WOLFCRYPT
@@ -172,11 +174,9 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
172174
/* Setup the wolf crypto device callback */
173175
XMEMSET(&tpmCtx, 0, sizeof(tpmCtx));
174176
#ifndef NO_RSA
175-
XMEMSET(&rsaKey, 0, sizeof(rsaKey));
176177
tpmCtx.rsaKey = &rsaKey;
177178
#endif
178179
#ifdef HAVE_ECC
179-
XMEMSET(&eccKey, 0, sizeof(eccKey));
180180
tpmCtx.eccKey = &eccKey;
181181
#endif
182182
tpmCtx.storageKey = &storageKey;
@@ -448,21 +448,30 @@ 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);
453-
wc_FreeRsaKey(&wolfRsaPrivKey);
454-
if (rc != 0 && rc != NOT_COMPILED_IN) {
451+
XMEMSET(&testKey, 0, sizeof(testKey));
452+
rc = wolfTPM2_CreateRsaKeyBlob(&dev, &storageKey, &wolfRsaPrivKey,
453+
&testKey);
454+
wc_FreeRsaKey(&wolfRsaPrivKey); /* free wolf key */
455+
456+
if (rc == 0) {
457+
printf("RSA Private Key Blob created (private = %d bytes)\n",
458+
testKey.priv.size);
459+
460+
rc = wolfTPM2_LoadKey(&dev, &testKey, &storageKey.handle);
461+
if (rc != 0) goto exit;
462+
printf("RSA Private Key Loaded into TPM: Handle 0x%x\n",
463+
(word32)rsaKey.handle.hndl);
464+
465+
/* Use TPM Handle... */
466+
467+
rc = wolfTPM2_UnloadHandle(&dev, &testKey.handle);
468+
if (rc != 0) goto exit;
469+
}
470+
else if (rc != NOT_COMPILED_IN) {
455471
/* NOT_COMPILED_IN here likely means that AES-CFB is not enabled for
456472
* encrypting secrets */
457473
goto exit;
458474
}
459-
printf("RSA Private Key Loaded into TPM: Handle 0x%x\n",
460-
(word32)rsaKey.handle.hndl);
461-
462-
/* Use TPM Handle... */
463-
464-
rc = wolfTPM2_UnloadHandle(&dev, &rsaKey.handle);
465-
if (rc != 0) goto exit;
466475
#endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_RSA && !NO_ASN */
467476

468477
/* Load raw RSA private key into TPM */
@@ -682,22 +691,29 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
682691
rc = wc_EccPrivateKeyDecode(kEccKeyPrivDer, &idx, &wolfEccPrivKey,
683692
(word32)sizeof(kEccKeyPrivDer));
684693
if (rc != 0) goto exit;
685-
rc = wolfTPM2_EccKey_WolfToTpm_ex(&dev, &storageKey, &wolfEccPrivKey,
686-
&eccKey);
687-
wc_ecc_free(&wolfEccPrivKey);
688-
if (rc != 0 && rc != NOT_COMPILED_IN) {
694+
XMEMSET(&testKey, 0, sizeof(testKey));
695+
rc = wolfTPM2_CreateEccKeyBlob(&dev, &storageKey, &wolfEccPrivKey,
696+
&testKey);
697+
wc_ecc_free(&wolfEccPrivKey); /* free wolf key */
698+
if (rc == 0) {
699+
printf("ECC Private Key Blob created (private = %d bytes)\n",
700+
testKey.priv.size);
701+
rc = wolfTPM2_LoadKey(&dev, &testKey, &storageKey.handle);
702+
if (rc != 0) goto exit;
703+
printf("ECC Private Key Loaded into TPM: Handle 0x%x\n",
704+
(word32)testKey.handle.hndl);
705+
706+
/* Use TPM Handle... */
707+
708+
rc = wolfTPM2_UnloadHandle(&dev, &testKey.handle);
709+
if (rc != 0) goto exit;
710+
}
711+
else if (rc != NOT_COMPILED_IN) {
689712
/* NOT_COMPILED_IN here likely means the WOLFSSL_PUBLIC_MP is enabled
690713
* exposing the mp_ math API's or AES CFB is not enabled.
691714
* Both are needed for encrypting secrets */
692715
goto exit;
693716
}
694-
printf("ECC Private Key Loaded into TPM: Handle 0x%x\n",
695-
(word32)eccKey.handle.hndl);
696-
697-
/* Use TPM Handle... */
698-
699-
rc = wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
700-
if (rc != 0) goto exit;
701717
#endif /* !WOLFTPM2_NO_WOLFCRYPT && HAVE_ECC && !NO_ASN */
702718

703719
/* Load raw ECC private key into TPM */

src/tpm2_cryptocb.c

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -177,80 +177,123 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
177177
#endif /* !NO_RSA */
178178
#ifdef HAVE_ECC
179179
if (info->pk.type == WC_PK_TYPE_EC_KEYGEN) {
180-
#ifdef WOLFTPM2_USE_SW_ECDHE
181-
rc = exit_rc;
182-
#else
183180
int curve_id;
184181
WOLFTPM2_KEY* key;
185182

183+
#ifdef WOLFTPM2_USE_SW_ECDHE
184+
if (tlsCtx->ecdhKey == NULL) {
185+
return exit_rc;
186+
}
187+
#endif
188+
189+
if ( tlsCtx->eccKey == NULL
190+
&& tlsCtx->ecdsaKey == NULL
191+
&& tlsCtx->ecdhKey == NULL
192+
) {
193+
#ifdef DEBUG_WOLFTPM
194+
printf("No crypto callback key pointer set!\n");
195+
#endif
196+
return BAD_FUNC_ARG;
197+
}
198+
186199
/* Make sure an ECDH key has been set and curve is supported */
187200
curve_id = info->pk.eckg.curveId;
188201
if (curve_id == 0 && info->pk.eckg.key->dp != NULL) {
189202
curve_id = info->pk.eckg.key->dp->id; /* use dp */
190203
}
191204
rc = TPM2_GetTpmCurve(curve_id);
192-
if (rc < 0 || (tlsCtx->ecdhKey == NULL && tlsCtx->eccKey == NULL)) {
205+
if (rc < 0) {
193206
return exit_rc;
194207
}
195208
curve_id = rc;
196209
rc = 0;
197210

198211
/* If ecdhKey is NULL then it is a signing key */
199-
if (tlsCtx->ecdhKey == NULL) {
212+
#ifndef WOLFTPM2_USE_SW_ECDHE
213+
if (tlsCtx->ecdhKey == NULL)
214+
#endif
215+
{
200216
/* Create an ECC key for ECDSA - if one isn't already created */
201-
key = tlsCtx->eccKey;
217+
key = (tlsCtx->ecdsaKey != NULL) ?
218+
(WOLFTPM2_KEY*)tlsCtx->ecdsaKey : tlsCtx->eccKey;
202219
if (key->handle.hndl == 0 ||
203220
key->handle.hndl == TPM_RH_NULL
204221
) {
205222
TPMT_PUBLIC publicTemplate;
206-
XMEMSET(&publicTemplate, 0, sizeof(publicTemplate));
223+
TPMI_ALG_HASH hashAlg;
224+
225+
if (curve_id == TPM_ECC_NIST_P521)
226+
hashAlg = TPM_ALG_SHA512;
227+
else if (curve_id == TPM_ECC_NIST_P384)
228+
hashAlg = TPM_ALG_SHA384;
229+
else
230+
hashAlg = TPM_ALG_SHA256;
207231

208-
rc = wolfTPM2_GetKeyTemplate_ECC(&publicTemplate,
232+
XMEMSET(&publicTemplate, 0, sizeof(publicTemplate));
233+
rc = wolfTPM2_GetKeyTemplate_ECC_ex(&publicTemplate, hashAlg,
209234
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
210235
TPMA_OBJECT_sign | TPMA_OBJECT_noDA,
211-
curve_id, TPM_ALG_ECDSA);
236+
curve_id, TPM_ALG_ECDSA, hashAlg);
212237
if (rc == 0) {
213-
publicTemplate.nameAlg = TPM_ALG_SHA256; /* make sure its SHA256 */
214-
rc = wolfTPM2_CreateAndLoadKey(tlsCtx->dev, key,
215-
&tlsCtx->storageKey->handle, &publicTemplate,
216-
(byte*)key->handle.auth.buffer,
217-
key->handle.auth.size);
238+
if (tlsCtx->ecdsaKey != NULL) {
239+
/* Use create key and load key directly instead to make
240+
* sure the private portion is populated */
241+
rc = wolfTPM2_CreateKey(tlsCtx->dev, tlsCtx->ecdsaKey,
242+
&tlsCtx->storageKey->handle, &publicTemplate,
243+
(byte*)key->handle.auth.buffer,
244+
key->handle.auth.size);
245+
if (rc == TPM_RC_SUCCESS) {
246+
rc = wolfTPM2_LoadKey(tlsCtx->dev, tlsCtx->ecdsaKey,
247+
&tlsCtx->storageKey->handle);
248+
}
249+
}
250+
else {
251+
/* Create and load key - encrypted private is not exported */
252+
rc = wolfTPM2_CreateAndLoadKey(tlsCtx->dev, tlsCtx->eccKey,
253+
&tlsCtx->storageKey->handle, &publicTemplate,
254+
(byte*)key->handle.auth.buffer,
255+
key->handle.auth.size);
256+
}
218257
}
219258
}
220259
}
260+
#ifndef WOLFTPM2_USE_SW_ECDHE
221261
else {
222262
/* Generate ephemeral key - if one isn't already created */
223263
key = tlsCtx->ecdhKey;
224264
if (key->handle.hndl == 0 ||
225265
key->handle.hndl == TPM_RH_NULL) {
226-
rc = wolfTPM2_ECDHGenKey(tlsCtx->dev, key, curve_id,
227-
NULL, 0 /* no auth for ephemeral key */
266+
rc = wolfTPM2_ECDHGenKey(tlsCtx->dev, tlsCtx->ecdhKey,
267+
curve_id, NULL, 0 /* no auth for ephemeral key */
228268
);
229269
}
230270
}
271+
#endif
272+
231273
if (rc == 0) {
232274
/* Export public key info to wolf ecc_key */
233275
rc = wolfTPM2_EccKey_TpmToWolf(tlsCtx->dev, key,
234276
info->pk.eckg.key);
235277
if (rc != 0) {
236278
/* if failure, release key */
237-
wolfTPM2_UnloadHandle(tlsCtx->dev, &tlsCtx->ecdhKey->handle);
279+
wolfTPM2_UnloadHandle(tlsCtx->dev, &key->handle);
238280
}
239281
}
240282
else if (rc & TPM_RC_CURVE) {
241283
/* if the curve is not supported on TPM, then fall-back to software */
242284
rc = exit_rc;
243-
/* Make sure ECDHE key indicates nothing loaded */
285+
/* Make sure key indicates nothing loaded */
244286
key->handle.hndl = TPM_RH_NULL;
245287
}
246-
#endif /* WOLFTPM2_USE_SW_ECDHE */
247288
}
248289
else if (info->pk.type == WC_PK_TYPE_ECDSA_SIGN) {
249290
byte sigRS[MAX_ECC_BYTES*2];
250291
word32 rsLen = sizeof(sigRS), keySz;
251292
word32 inlen = info->pk.eccsign.inlen;
293+
WOLFTPM2_KEY* key = (tlsCtx->ecdsaKey != NULL) ?
294+
(WOLFTPM2_KEY*)tlsCtx->ecdsaKey : tlsCtx->eccKey;
252295

253-
if (tlsCtx->eccKey == NULL) {
296+
if (key == NULL) {
254297
/* TPM key not setup, fallback to software */
255298
return exit_rc;
256299
}
@@ -260,13 +303,13 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
260303
if (keySz == 0) {
261304
/* if not populated fallback to key size for TPM key */
262305
keySz = TPM2_GetCurveSize(
263-
tlsCtx->eccKey->pub.publicArea.parameters.eccDetail.curveID);
306+
key->pub.publicArea.parameters.eccDetail.curveID);
264307
}
265308
/* truncate input to match key size */
266309
if (inlen > keySz)
267310
inlen = keySz;
268311

269-
rc = wolfTPM2_SignHash(tlsCtx->dev, tlsCtx->eccKey,
312+
rc = wolfTPM2_SignHash(tlsCtx->dev, key,
270313
info->pk.eccsign.in, inlen, sigRS, (int*)&rsLen);
271314
if (rc == 0) {
272315
byte *r, *s;
@@ -335,8 +378,9 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
335378
TPM2B_ECC_POINT pubPoint;
336379

337380
/* Make sure an ECDH key has been set */
338-
if (tlsCtx->ecdhKey == NULL || tlsCtx->eccKey == NULL ||
339-
tlsCtx->ecdhKey->handle.hndl == TPM_RH_NULL) {
381+
if (tlsCtx->ecdhKey == NULL ||
382+
tlsCtx->ecdhKey->handle.hndl == TPM_RH_NULL ||
383+
tlsCtx->ecdhKey->handle.hndl == 0) {
340384
return exit_rc;
341385
}
342386

0 commit comments

Comments
 (0)