From 6126d04be3756326f4a66cf86fd198678f1da43f Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 14 Aug 2023 16:59:48 -0700 Subject: [PATCH] Support for importing and loading public ECC/RSA keys formatted as PEM or DER. --- certs/example-ecc256-key-pub.der | Bin 0 -> 91 bytes certs/example-ecc256-key-pub.pem | 4 + certs/example-ecc256-key.der | Bin 0 -> 121 bytes certs/example-ecc256-key.pem | 9 + certs/example-ecc384-key-pub.der | Bin 0 -> 120 bytes certs/example-ecc384-key-pub.pem | 5 + certs/example-ecc384-key.der | Bin 0 -> 167 bytes certs/example-ecc384-key.pem | 6 + ...ey-pub.der => example-rsa2048-key-pub.der} | Bin ...ey-pub.pem => example-rsa2048-key-pub.pem} | 0 ...le-rsa-key.der => example-rsa2048-key.der} | Bin ...le-rsa-key.pem => example-rsa2048-key.pem} | 0 certs/include.am | 26 ++- examples/keygen/keyimport.c | 199 ++++++++++-------- examples/keygen/keyload.c | 17 +- examples/tpm_test_keys.c | 56 +++++ examples/tpm_test_keys.h | 2 + src/tpm2_wrap.c | 139 ++++++++++-- wolftpm/tpm2_wrap.h | 25 ++- 19 files changed, 362 insertions(+), 126 deletions(-) create mode 100644 certs/example-ecc256-key-pub.der create mode 100644 certs/example-ecc256-key-pub.pem create mode 100644 certs/example-ecc256-key.der create mode 100644 certs/example-ecc256-key.pem create mode 100644 certs/example-ecc384-key-pub.der create mode 100644 certs/example-ecc384-key-pub.pem create mode 100644 certs/example-ecc384-key.der create mode 100644 certs/example-ecc384-key.pem rename certs/{example-rsa-key-pub.der => example-rsa2048-key-pub.der} (100%) rename certs/{example-rsa-key-pub.pem => example-rsa2048-key-pub.pem} (100%) rename certs/{example-rsa-key.der => example-rsa2048-key.der} (100%) rename certs/{example-rsa-key.pem => example-rsa2048-key.pem} (100%) diff --git a/certs/example-ecc256-key-pub.der b/certs/example-ecc256-key-pub.der new file mode 100644 index 0000000000000000000000000000000000000000..91aa79beebf2e0bab79b4fb2c4699f0ea0b94678 GIT binary patch literal 91 zcmXqrG!SNE*J|@PXUoLM#sOw9GqN)~F|h15UgM)4;C0MvDa&D-d-Kh17wMjx@=E*H uX$4M89kCaQOfT2_US^s+%P@NSB*pp<=Ou1U6l5}Kd!Z0v%-vwpc>@4lI3fA~ literal 0 HcmV?d00001 diff --git a/certs/example-ecc256-key-pub.pem b/certs/example-ecc256-key-pub.pem new file mode 100644 index 0000000..30363ef --- /dev/null +++ b/certs/example-ecc256-key-pub.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuzOsTCdQSsZKpQTDPN6fNttyLc6U +6iv6yyAJOSwW6GEC6a9N0wKTmjFbl5Ihf/DPGNqREQI0huggWDMLgDSJ2A== +-----END PUBLIC KEY----- diff --git a/certs/example-ecc256-key.der b/certs/example-ecc256-key.der new file mode 100644 index 0000000000000000000000000000000000000000..a88d141e08cceb829f2bc756ffcabd7d8e8c0b79 GIT binary patch literal 121 zcmV-<0EYiCcLD(c1RzDWX##VcY=xmXTXN{=$E?HyjZ-xQ`fMoNG>ze?35=i$1_&yK zNX|V20SBQ(13~}x++j1?=l= 2) { if (XSTRCMP(argv[1], "-?") == 0 || @@ -75,44 +85,53 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[]) return 0; } - if (argv[1][0] != '-') + if (argv[1][0] != '-') { outputFile = argv[1]; + } } - /* i = 1 to skip binary */ - for (i = 1; i < argc; i++) { - if (XSTRCMP(argv[i], "-ecc") == 0) { + while (argc > 1) { + if (XSTRCMP(argv[argc-1], "-ecc") == 0) { alg = TPM_ALG_ECC; } - else if (XSTRCMP(argv[i], "-aes") == 0) { + else if (XSTRCMP(argv[argc-1], "-aes") == 0) { paramEncAlg = TPM_ALG_CFB; } - else if (XSTRCMP(argv[i], "-xor") == 0) { + else if (XSTRCMP(argv[argc-1], "-xor") == 0) { paramEncAlg = TPM_ALG_XOR; } - else if (XSTRCMP(argv[i], "-der") == 0) { - derEncode = 1; + else if (XSTRCMP(argv[argc-1], "-public") == 0) { + isPublicKey = 1; } -#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) - else if (XSTRCMP(argv[i], "-pem") == 0) { - pemEncode = 1; - printf("Warning: No pem file specified, using default: %s\n", pemName); + else if (XSTRNCMP(argv[argc-1], "-password=", XSTRLEN("-password=")) == 0) { + password = (const char*)(argv[argc-1] + XSTRLEN("-password=")); + } + else if (XSTRCMP(argv[argc-1], "-der") == 0) { + encType = ENCODING_TYPE_ASN1; + } + else if (XSTRNCMP(argv[argc-1], "-der=", XSTRLEN("-der=")) == 0) { + encType = ENCODING_TYPE_ASN1; + impFile = (const char*)(argv[argc-1] + XSTRLEN("-der=")); + } + else if (XSTRCMP(argv[argc-1], "-pem") == 0) { + encType = ENCODING_TYPE_PEM; + } + else if (XSTRNCMP(argv[argc-1], "-pem=", XSTRLEN("-pem=")) == 0) { + encType = ENCODING_TYPE_PEM; + impFile = (const char*)(argv[argc-1] + XSTRLEN("-pem=")); + } + else { + printf("Warning: Unrecognized option: %s\n", argv[argc-1]); } - else if (XSTRNCMP(argv[i], "-pem=", XSTRLEN("-pem=")) == 0) { - pemEncode = 1; - if (XSTRLEN(argv[i] + XSTRLEN("-pem=")) == 0) { - printf("Warning: No pem file specified, using default: %s\n", pemName); - } - else { - pemName = (const char*)(argv[i] + XSTRLEN("-pem=")); - printf("Warning: No pem file specified, using default: %s\n", pemName); - } - } -#endif - /* we already got outfile */ - else if (i == 1 && argv[1][0] != '-') { - printf("Warning: Unrecognized option: %s\n", argv[i]); - } + argc--; + } + + /* setup default import file */ + if (impFile == NULL) { + if (alg == TPM_ALG_RSA) + impFile = "./certs/example-rsa2048-key.der"; + else if (alg == TPM_ALG_ECC) + impFile = "./certs/example-ecc256-key.der"; } XMEMSET(&storage, 0, sizeof(storage)); @@ -123,11 +142,7 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[]) printf("\tKey Blob: %s\n", outputFile); printf("\tAlgorithm: %s\n", TPM2_GetAlgName(alg)); printf("\tUse Parameter Encryption: %s\n", TPM2_GetAlgName(paramEncAlg)); -#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) - if (pemEncode) { - printf("\tUse Pem Keyfile: %s\n", pemName); - } -#endif + printf("\tpassword: %s\n", password); rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); if (rc != TPM_RC_SUCCESS) { @@ -136,7 +151,7 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[]) } /* get SRK */ - rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA); + rc = getPrimaryStoragekey(&dev, &storage, alg); if (rc != 0) goto exit; if (paramEncAlg != TPM_ALG_NULL) { @@ -154,51 +169,61 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[]) } /* setup an auth value */ - impKey.handle.auth.size = (int)sizeof(gKeyAuth)-1; - XMEMCPY(impKey.handle.auth.buffer, gKeyAuth, impKey.handle.auth.size); + if (password != NULL) { + impKey.handle.auth.size = (int)XSTRLEN(password); + XMEMCPY(impKey.handle.auth.buffer, password, impKey.handle.auth.size); + } - if (alg == TPM_ALG_RSA) { - if (derEncode == 1) { - #if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_RSA) && \ - !defined(NO_ASN) - rc = wolfTPM2_RsaPrivateKeyImportDer(&dev, &storage, &impKey, - kRsaKeyPrivDer, sizeof(kRsaKeyPrivDer), TPM_ALG_NULL, - TPM_ALG_NULL); - #else - rc = NOT_COMPILED_IN; - #endif - } - #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) - else if (pemEncode == 1) { - #if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_RSA) - pemFile = XFOPEN(pemName, "r"); - if (pemFile != XBADFILE) { - rc = (int)XFREAD(pemBuf, 1, sizeof(pemBuf), pemFile); - if (rc > 0) { - rc = wolfTPM2_RsaPrivateKeyImportPem(&dev, &storage, &impKey, - pemBuf, rc, NULL, TPM_ALG_NULL, TPM_ALG_NULL); - } - XFCLOSE(pemFile); + attributes = (TPMA_OBJECT_restricted | + TPMA_OBJECT_sensitiveDataOrigin | + TPMA_OBJECT_decrypt | + TPMA_OBJECT_userWithAuth | + TPMA_OBJECT_noDA); + +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM) + if (impFile != NULL) { + printf("Loading %s%s key file: %s\n", + encType == ENCODING_TYPE_PEM ? "PEM" : "DER", + isPublicKey ? " public" : "", + impFile); + rc = loadFile(impFile, &buf, &bufSz); + if (rc == 0) { + if (isPublicKey) { + rc = wolfTPM2_ImportPublicKeyBuffer(&dev, + alg, + (WOLFTPM2_KEY*)&impKey, + encType, + (const char*)buf, (word32)bufSz, + attributes + ); } - else { - printf("Failed to read pem file %s\n", pemName); - rc = BUFFER_E; + else { /* private key */ + rc = wolfTPM2_ImportPrivateKeyBuffer(&dev, &storage, + alg, + &impKey, + encType, + (const char*)buf, (word32)bufSz, + password, + attributes, NULL, 0 + ); } - #else - rc = NOT_COMPILED_IN; - #endif - } - #endif - else { - /* Import raw RSA private key into TPM */ - rc = wolfTPM2_ImportRsaPrivateKey(&dev, &storage, &impKey, - kRsaKeyPubModulus, (word32)sizeof(kRsaKeyPubModulus), - kRsaKeyPubExponent, - kRsaKeyPrivQ, (word32)sizeof(kRsaKeyPrivQ), - TPM_ALG_NULL, TPM_ALG_NULL); } } + else +#endif + if (alg == TPM_ALG_RSA) { + printf("Loading example RSA key (see kRsaKeyPrivQ)\n"); + + /* Import raw RSA private key into TPM */ + rc = wolfTPM2_ImportRsaPrivateKey(&dev, &storage, &impKey, + kRsaKeyPubModulus, (word32)sizeof(kRsaKeyPubModulus), + kRsaKeyPubExponent, + kRsaKeyPrivQ, (word32)sizeof(kRsaKeyPrivQ), + TPM_ALG_NULL, TPM_ALG_NULL); + } else if (alg == TPM_ALG_ECC) { + printf("Loading example ECC key (see kEccKeyPrivD)\n"); + /* Import raw ECC private key into TPM */ rc = wolfTPM2_ImportEccPrivateKey(&dev, &storage, &impKey, TPM_ECC_NIST_P256, @@ -212,7 +237,7 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[]) TPM2_GetAlgName(alg), impKey.pub.size, impKey.priv.size); /* Save key as encrypted blob to the disk */ -#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM) +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) rc = writeKeyBlob(outputFile, &impKey); #else printf("Key Public Blob %d\n", impKey.pub.size); diff --git a/examples/keygen/keyload.c b/examples/keygen/keyload.c index 6ccb19e..8c667e3 100644 --- a/examples/keygen/keyload.c +++ b/examples/keygen/keyload.c @@ -79,12 +79,12 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[]) if (argv[1][0] != '-') { inputFile = argv[1]; } - if (XSTRCMP(argv[1], "-eh") == 0) { - endorseKey = 1; - } } while (argc > 1) { - if (XSTRCMP(argv[argc-1], "-aes") == 0) { + if (XSTRCMP(argv[argc-1], "-eh") == 0) { + endorseKey = 1; + } + else if (XSTRCMP(argv[argc-1], "-aes") == 0) { paramEncAlg = TPM_ALG_CFB; } else if (XSTRCMP(argv[argc-1], "-xor") == 0) { @@ -160,9 +160,14 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[]) goto exit; #endif - rc = wolfTPM2_LoadKey(&dev, &newKey, &primary->handle); + if (newKey.priv.size == 0) { + rc = wolfTPM2_LoadPublicKey(&dev, (WOLFTPM2_KEY*)&newKey, &newKey.pub); + } + else { + rc = wolfTPM2_LoadKey(&dev, &newKey, &primary->handle); + } if (rc != TPM_RC_SUCCESS) { - printf("wolfTPM2_LoadKey failed\n"); + printf("Load Key failed!\n"); goto exit; } printf("Loaded key to 0x%x\n", diff --git a/examples/tpm_test_keys.c b/examples/tpm_test_keys.c index d8ba762..d544b54 100644 --- a/examples/tpm_test_keys.c +++ b/examples/tpm_test_keys.c @@ -165,6 +165,9 @@ int readKeyBlob(const char* filename, WOLFTPM2_KEYBLOB* key) } rc = 0; /* success */ } + if (key->priv.size == 0) { + printf("No private key loaded\n"); + } /* sanity check the sizes */ if (pubAreaSize != (key->pub.size + (int)sizeof(key->pub.size)) || @@ -391,4 +394,57 @@ int getECCkey(WOLFTPM2_DEV* pDev, return rc; } +int loadFile(const char* fname, byte** buf, size_t* bufLen) +{ + int ret; +#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM) && \ + !defined(WOLFTPM2_NO_HEAP) + long int fileSz; + XFILE lFile; + + if (fname == NULL || buf == NULL || bufLen == NULL) + return BAD_FUNC_ARG; + + /* set defaults */ + *buf = NULL; + *bufLen = 0; + + /* open file (read-only binary) */ + lFile = XFOPEN(fname, "rb"); + if (!lFile) { + fprintf(stderr, "Error loading %s\n", fname); + return BUFFER_E; + } + + XFSEEK(lFile, 0, XSEEK_END); + fileSz = (int)ftell(lFile); + XFSEEK(lFile, 0, XSEEK_SET); + if (fileSz > 0) { + *bufLen = (size_t)fileSz; + *buf = (byte*)XMALLOC(*bufLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (*buf == NULL) { + ret = MEMORY_E; + fprintf(stderr, + "Error allocating %lu bytes\n", (unsigned long)*bufLen); + } + else { + size_t readLen = fread(*buf, *bufLen, 1, lFile); + + /* check response code */ + ret = (readLen > 0) ? 0 : -1; + } + } + else { + ret = BUFFER_E; + } + fclose(lFile); +#else + (void)fname; + (void)buf; + (void)bufLen; + ret = NOT_COMPILED_IN; +#endif /* !WOLFTPM2_NO_WOLFCRYPT && !NO_FILESYSTEM && !WOLFTPM2_NO_HEAP */ + return ret; +} + #endif /* !WOLFTPM2_NO_WRAPPER */ diff --git a/examples/tpm_test_keys.h b/examples/tpm_test_keys.h index 8d2813b..03b8e27 100644 --- a/examples/tpm_test_keys.h +++ b/examples/tpm_test_keys.h @@ -66,6 +66,8 @@ WOLFTPM_LOCAL int getECCkey(WOLFTPM2_DEV* pDev, const byte* auth, int authSz, TPMT_PUBLIC* publicTemplate); +WOLFTPM_LOCAL int loadFile(const char* fname, byte** buf, size_t* bufLen); + #endif /* !WOLFTPM2_NO_WRAPPER */ #endif /* _TPM_TEST_KEYS_H_ */ diff --git a/src/tpm2_wrap.c b/src/tpm2_wrap.c index 18bc6ba..aabba9b 100644 --- a/src/tpm2_wrap.c +++ b/src/tpm2_wrap.c @@ -2470,7 +2470,7 @@ int wolfTPM2_ReadPublicKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key, #ifndef NO_ASN #ifndef NO_RSA -static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, +static int DecodeRsaDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, const byte* input, word32 inSz, TPMA_OBJECT attributes) { int rc = 0; @@ -2486,6 +2486,7 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, word32 dSz = (word32)sizeof(d); word32 pSz = (word32)sizeof(p); word32 qSz = (word32)sizeof(q); + int isPrivateKey = 0; XMEMSET(n, 0, sizeof(n)); XMEMSET(d, 0, sizeof(d)); @@ -2494,15 +2495,26 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, rc = wc_InitRsaKey(key, NULL); if (rc == 0) { + idx = 0; rc = wc_RsaPrivateKeyDecode(input, &idx, key, inSz); - if (rc == 0) { - rc = wc_RsaExportKey(key, (byte*)&e, &eSz, n, &nSz, d, &dSz, - p, &pSz, q, &qSz); + isPrivateKey = 1; + } + else { + idx = 0; + rc = wc_RsaPublicKeyDecode(input, &idx, key, inSz); + } + if (rc == 0) { + if (isPrivateKey) + rc = wc_RsaExportKey(key, (byte*)&e, &eSz, n, &nSz, d, &dSz, + p, &pSz, q, &qSz); + else + rc = wc_RsaFlattenPublicKey(key, (byte*)&e, &eSz, n, &nSz); } if (rc == 0 && nSz > sizeof(pub->publicArea.unique.rsa.buffer)) rc = BUFFER_E; - if (rc == 0 && qSz > sizeof(sens->sensitiveArea.sensitive.rsa.buffer)) + if (rc == 0 && sens != NULL && isPrivateKey && + qSz > sizeof(sens->sensitiveArea.sensitive.rsa.buffer)) rc = BUFFER_E; if (rc == 0) { /* Set up public key */ @@ -2529,9 +2541,11 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, } /* Set up private key */ - sens->sensitiveArea.sensitiveType = TPM_ALG_RSA; - sens->sensitiveArea.sensitive.rsa.size = qSz; - XMEMCPY(sens->sensitiveArea.sensitive.rsa.buffer, q, qSz); + if (sens != NULL && isPrivateKey) { + sens->sensitiveArea.sensitiveType = TPM_ALG_RSA; + sens->sensitiveArea.sensitive.rsa.size = qSz; + XMEMCPY(sens->sensitiveArea.sensitive.rsa.buffer, q, qSz); + } } wc_FreeRsaKey(key); } @@ -2540,12 +2554,12 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, } #endif #ifdef HAVE_ECC -static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, +static int DecodeEccDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, const byte* input, word32 inSz, TPMA_OBJECT attributes) { int rc; int curveId = 0; - word32 idx = 0; + word32 idx; ecc_key key[1]; byte d[WOLFTPM2_WRAP_ECC_KEY_BITS / 8]; byte qx[WOLFTPM2_WRAP_ECC_KEY_BITS / 8]; @@ -2553,6 +2567,7 @@ static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, word32 dSz = sizeof(d); word32 qxSz = sizeof(qx); word32 qySz = sizeof(qy); + int isPrivateKey = 0; XMEMSET(d, 0, sizeof(d)); XMEMSET(qx, 0, sizeof(qx)); @@ -2560,17 +2575,29 @@ static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, rc = wc_ecc_init(key); if (rc == 0) { + idx = 0; rc = wc_EccPrivateKeyDecode(input, &idx, key, inSz); + if (rc == 0) { + isPrivateKey = 1; + } + else { + idx = 0; + rc = wc_EccPublicKeyDecode(input, &idx, key, inSz); + } if (rc == 0) { curveId = TPM2_GetTpmCurve(key->dp->id); - rc = wc_ecc_export_private_raw(key, qx, &qxSz, qy, &qySz, d, &dSz); + if (isPrivateKey) + rc = wc_ecc_export_private_raw(key, qx, &qxSz, qy, &qySz, d, &dSz); + else + rc = wc_ecc_export_public_raw(key, qx, &qxSz, qy, &qySz); } if (rc == 0 && qxSz > sizeof(pub->publicArea.unique.ecc.x.buffer)) rc = BUFFER_E; if (rc == 0 && qySz > sizeof(pub->publicArea.unique.ecc.y.buffer)) rc = BUFFER_E; - if (rc == 0 && dSz > sizeof(sens->sensitiveArea.sensitive.ecc.buffer)) + if (rc == 0 && sens != NULL && isPrivateKey && + dSz > sizeof(sens->sensitiveArea.sensitive.ecc.buffer)) rc = BUFFER_E; if (rc == 0) { /* Set up public key */ @@ -2601,9 +2628,11 @@ static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, } /* Set up private key */ - sens->sensitiveArea.sensitiveType = TPM_ALG_ECC; - sens->sensitiveArea.sensitive.ecc.size = dSz; - XMEMCPY(sens->sensitiveArea.sensitive.ecc.buffer, d, dSz); + if (sens != NULL && isPrivateKey) { + sens->sensitiveArea.sensitiveType = TPM_ALG_ECC; + sens->sensitiveArea.sensitive.ecc.size = dSz; + XMEMCPY(sens->sensitiveArea.sensitive.ecc.buffer, d, dSz); + } } wc_ecc_free(key); @@ -2613,9 +2642,68 @@ static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens, } #endif /* HAVE_ECC */ +int wolfTPM2_ImportPublicKeyBuffer(WOLFTPM2_DEV* dev, int keyType, + WOLFTPM2_KEY* key, int encodingType, const char* input, word32 inSz, + TPMA_OBJECT objectAttributes) +{ + int rc = 0; + byte* derBuf; + word32 derSz; + + if (dev == NULL || key == NULL || input == NULL || inSz == 0) { + return BAD_FUNC_ARG; + } + + if (encodingType == ENCODING_TYPE_PEM) { + #if !defined(WOLFTPM2_NO_HEAP) && defined(WOLFSSL_PEM_TO_DER) + /* der size is base 64 decode length */ + derSz = inSz * 3 / 4 + 1; + derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (derBuf == NULL) + return MEMORY_E; + rc = wc_PubKeyPemToDer((byte*)input, inSz, derBuf, derSz); + if (rc >= 0) { + derSz = rc; + rc = 0; + } + #else + (void)pass; + return NOT_COMPILED_IN; + #endif + } + else { /* ASN.1 (DER) */ + derBuf = (byte*)input; + derSz = inSz; + } + + /* Handle DER Import */ + if (keyType == TPM_ALG_RSA) { + #ifndef NO_RSA + rc = DecodeRsaDer(&key->pub, NULL, derBuf, derSz, objectAttributes); + #else + rc = NOT_COMPILED_IN; + #endif + } + else if (keyType == TPM_ALG_ECC) { + #ifdef HAVE_ECC + rc = DecodeEccDer(&key->pub, NULL, derBuf, derSz, objectAttributes); + #else + rc = NOT_COMPILED_IN; + #endif + } + +#if !defined(WOLFTPM2_NO_HEAP) && defined(WOLFSSL_PEM_TO_DER) + if (derBuf != (byte*)input) { + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +#endif + + return rc; +} + int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey, int keyType, WOLFTPM2_KEYBLOB* keyBlob, - int encodingType, const char* input, word32 inSz, char* pass, + int encodingType, const char* input, word32 inSz, const char* pass, TPMA_OBJECT objectAttributes, byte* seed, word32 seedSz) { int rc = 0; @@ -2658,14 +2746,14 @@ int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev, /* Handle DER Import */ if (keyType == TPM_ALG_RSA) { #ifndef NO_RSA - rc = DecodeRsaPrivateDer(&pub, &sens, derBuf, derSz, objectAttributes); + rc = DecodeRsaDer(&pub, &sens, derBuf, derSz, objectAttributes); #else rc = NOT_COMPILED_IN; #endif } else if (keyType == TPM_ALG_ECC) { #ifdef HAVE_ECC - rc = DecodeEccPrivateDer(&pub, &sens, derBuf, derSz, objectAttributes); + rc = DecodeEccDer(&pub, &sens, derBuf, derSz, objectAttributes); #else rc = NOT_COMPILED_IN; #endif @@ -3120,10 +3208,17 @@ int wolfTPM2_NVStoreKey(WOLFTPM2_DEV* dev, TPM_HANDLE primaryHandle, int rc; EvictControl_In in; - if (dev == NULL || key == NULL || - (primaryHandle != TPM_RH_OWNER && primaryHandle != TPM_RH_PLATFORM) || - persistentHandle < PERSISTENT_FIRST || - persistentHandle > PERSISTENT_LAST) { + if (dev == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + if (primaryHandle == TPM_RH_OWNER && + (persistentHandle < PERSISTENT_FIRST || + persistentHandle > PERSISTENT_LAST)) { + return BAD_FUNC_ARG; + } + if (primaryHandle == TPM_RH_PLATFORM && + (persistentHandle < PLATFORM_PERSISTENT || + persistentHandle > PERSISTENT_LAST)) { return BAD_FUNC_ARG; } diff --git a/wolftpm/tpm2_wrap.h b/wolftpm/tpm2_wrap.h index e6b530d..0f31e0b 100644 --- a/wolftpm/tpm2_wrap.h +++ b/wolftpm/tpm2_wrap.h @@ -1128,8 +1128,9 @@ WOLFTPM_API int wolfTPM2_SensitiveToPrivate(TPM2B_SENSITIVE* sens, TPM2B_PRIVATE \return BAD_FUNC_ARG: check the provided arguments \param dev pointer to a TPM2_DEV struct + \param keyType The type of key (TPM_ALG_RSA or TPM_ALG_ECC) \param parentKey pointer to a WOLFTPM2_KEY struct, pointing to a Primary Key or TPM Hierarchy - \param keyBlob pointer to a struct of WOLFTPM2_KEYBLOB type, to import the rsa key to + \param keyBlob pointer to a struct of WOLFTPM2_KEYBLOB type, to import the private key to \param encodingType ENCODING_TYPE_PEM or ENCODING_TYPE_ASN1 (DER) \param input buffer holding the rsa pem \param inSz length of the input pem buffer @@ -1140,9 +1141,29 @@ WOLFTPM_API int wolfTPM2_SensitiveToPrivate(TPM2B_SENSITIVE* sens, TPM2B_PRIVATE */ WOLFTPM_API int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey, int keyType, WOLFTPM2_KEYBLOB* keyBlob, - int encodingType, const char* input, word32 inSz, char* pass, + int encodingType, const char* input, word32 inSz, const char* pass, TPMA_OBJECT objectAttributes, byte* seed, word32 seedSz); +/*! + \ingroup wolfTPM2_Wrappers + \brief Helper function to import PEM/DER formatted RSA/ECC public key + + \return TPM_RC_SUCCESS: successful - populates key->pub + \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 keyType The type of key (TPM_ALG_RSA or TPM_ALG_ECC) + \param key pointer to a struct of WOLFTPM2_KEY type, to import the public key to + \param encodingType ENCODING_TYPE_PEM or ENCODING_TYPE_ASN1 (DER) + \param input buffer holding the rsa pem + \param inSz length of the input pem buffer + \param objectAttributes integer value of OR'd TPMA_OBJECT_* types +*/ +WOLFTPM_API int wolfTPM2_ImportPublicKeyBuffer(WOLFTPM2_DEV* dev, int keyType, + WOLFTPM2_KEY* key, int encodingType, const char* input, word32 inSz, + TPMA_OBJECT objectAttributes); + #ifndef NO_RSA /*! \ingroup wolfTPM2_Wrappers