Support for importing and loading public ECC/RSA keys formatted as PEM or DER.

pull/290/head
David Garske 2023-08-14 16:59:48 -07:00
parent 456424de60
commit 6126d04be3
19 changed files with 362 additions and 126 deletions

Binary file not shown.

View File

@ -0,0 +1,4 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuzOsTCdQSsZKpQTDPN6fNttyLc6U
6iv6yyAJOSwW6GEC6a9N0wKTmjFbl5Ihf/DPGNqREQI0huggWDMLgDSJ2A==
-----END PUBLIC KEY-----

Binary file not shown.

View File

@ -0,0 +1,9 @@
ASN1 OID: prime256v1
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIEW2aQJznGyFoThbcujox6zEA41TNQT6bCjcNI3hqAmMoAoGCCqGSM49
AwEHoUQDQgAEuzOsTCdQSsZKpQTDPN6fNttyLc6U6iv6yyAJOSwW6GEC6a9N0wKT
mjFbl5Ihf/DPGNqREQI0huggWDMLgDSJ2A==
-----END EC PRIVATE KEY-----

Binary file not shown.

View File

@ -0,0 +1,5 @@
-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE6s+TTywJuzkUD1Zkw0C03w5jruVxSwDM
BJf/4ek4lrtfkbJqzLU5X49wWfEB9lorAWxoC89VJa9tmEgKqHTJqRegDMP70yNo
/gQ8Y1CIO7lPfGc09zupc+cbw1FeIhjs
-----END PUBLIC KEY-----

Binary file not shown.

View File

@ -0,0 +1,6 @@
-----BEGIN PRIVATE KEY-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCk5QboBhY+q4n4YEPA
YCXbunv+GTUIVWV24tzgAYtraN/Pb4ASznk36yuce8RoHHShZANiAATqz5NPLAm7
ORQPVmTDQLTfDmOu5XFLAMwEl//h6TiWu1+RsmrMtTlfj3BZ8QH2WisBbGgLz1Ul
r22YSAqodMmpF6AMw/vTI2j+BDxjUIg7uU98ZzT3O6lz5xvDUV4iGOw=
-----END PRIVATE KEY-----

View File

@ -3,12 +3,20 @@
#
EXTRA_DIST += \
certs/certreq.sh \
certs/ca-rsa.cnf \
certs/ca-ecc.cnf \
certs/wolf-ca-ecc-cert.pem \
certs/wolf-ca-rsa-cert.pem \
certs/example-rsa-key.pem \
certs/example-rsa-key.der \
certs/example-rsa-key-pub.pem \
certs/example-rsa-key-pub.der
certs/certreq.sh \
certs/ca-rsa.cnf \
certs/ca-ecc.cnf \
certs/wolf-ca-ecc-cert.pem \
certs/wolf-ca-rsa-cert.pem \
certs/example-rsa2048-key.pem \
certs/example-rsa2048-key.der \
certs/example-rsa2048-key-pub.pem \
certs/example-rsa2048-key-pub.der \
certs/example-ecc256-key.pem \
certs/example-ecc256-key.der \
certs/example-ecc256-key-pub.pem \
certs/example-ecc256-key-pub.der \
certs/example-ecc384-key.pem \
certs/example-ecc384-key.der \
certs/example-ecc384-key-pub.pem \
certs/example-ecc384-key-pub.der

View File

@ -39,16 +39,29 @@
static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/keygen/keyimport [keyblob.bin] [-ecc/-rsa] [-pem/-der] [-aes/xor]\n");
printf("* -ecc: Use RSA or ECC for keys\n");
printf("./examples/keygen/keyimport [keyblob.bin] [-ecc/-rsa] [-pem/-der] [-aes/xor] [-password] [-public]\n");
printf("* -aes/xor: Use Parameter Encryption\n");
printf("* -pem=[keyfile]/der: Key encoding type, none for binary. Optional pem key file defaults to ./certs/example-rsa-key.pem\n");
printf("* -rsa/-ecc: Use RSA or ECC key\n");
printf("* -public: Input file is public key only\n");
printf("* -password=[password]: Optional password for private key\n");
printf("* -pem=[keyfile]: PEM (Base64 Encoded) key file\n");
printf("* -der=[keyfile]: DER (ASN.1) binary key file\n");
printf("Examples:\n");
printf("\t./examples/keygen/keyimport -ecc\n");
printf("\t./examples/keygen/keyimport -rsa\n");
printf("\t./examples/keygen/keyimport -ecc -pem=./certs/example-ecc256-key.pem -aes\n");
printf("\t./examples/keygen/keyimport -rsa -pem=./certs/example-rsa2048-key.pem -aes\n");
printf("\t./examples/keygen/keyimport -ecc -der=./certs/example-ecc256-key.der -aes\n");
printf("\t./examples/keygen/keyimport -rsa -der=./certs/example-rsa2048-key.der -aes\n");
printf("\t./examples/keygen/keyimport -ecc -pem=../wolfssl/certs/ecc-keyPkcs8Enc.pem -password=yassl123 -aes\n");
printf("\t./examples/keygen/keyimport -rsa -pem=../wolfssl/certs/server-keyPkcs8Enc.pem -password=yassl123 -aes\n");
printf("\t./examples/keygen/keyimport -ecc -der=./certs/example-ecc256-key-pub.der -public\n");
printf("\t./examples/keygen/keyimport -rsa -der=./certs/example-rsa2048-key-pub.der -public\n");
}
int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
{
int rc;
int i;
WOLFTPM2_DEV dev;
WOLFTPM2_KEY storage; /* SRK */
WOLFTPM2_KEYBLOB impKey;
@ -56,16 +69,13 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
WOLFTPM2_SESSION tpmSession;
const char* outputFile = "keyblob.bin";
byte derEncode = 0;
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
byte pemEncode = 0;
const char* pemName = "./certs/example-rsa-key.pem";
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_RSA)
FILE* pemFile = NULL;
char pemBuf[WOLFTPM2_MAX_BUFFER];
#endif
#endif
const char* impFile = NULL;
int encType = ENCODING_TYPE_ASN1;
const char* password = NULL;
TPMA_OBJECT attributes;
byte* buf = NULL;
size_t bufSz = 0;
int isPublicKey = 0;
if (argc >= 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);

View File

@ -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",

View File

@ -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 */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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