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

@ -8,7 +8,15 @@ EXTRA_DIST += \
certs/ca-ecc.cnf \ certs/ca-ecc.cnf \
certs/wolf-ca-ecc-cert.pem \ certs/wolf-ca-ecc-cert.pem \
certs/wolf-ca-rsa-cert.pem \ certs/wolf-ca-rsa-cert.pem \
certs/example-rsa-key.pem \ certs/example-rsa2048-key.pem \
certs/example-rsa-key.der \ certs/example-rsa2048-key.der \
certs/example-rsa-key-pub.pem \ certs/example-rsa2048-key-pub.pem \
certs/example-rsa-key-pub.der 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) static void usage(void)
{ {
printf("Expected usage:\n"); printf("Expected usage:\n");
printf("./examples/keygen/keyimport [keyblob.bin] [-ecc/-rsa] [-pem/-der] [-aes/xor]\n"); printf("./examples/keygen/keyimport [keyblob.bin] [-ecc/-rsa] [-pem/-der] [-aes/xor] [-password] [-public]\n");
printf("* -ecc: Use RSA or ECC for keys\n");
printf("* -aes/xor: Use Parameter Encryption\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 TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
{ {
int rc; int rc;
int i;
WOLFTPM2_DEV dev; WOLFTPM2_DEV dev;
WOLFTPM2_KEY storage; /* SRK */ WOLFTPM2_KEY storage; /* SRK */
WOLFTPM2_KEYBLOB impKey; WOLFTPM2_KEYBLOB impKey;
@ -56,16 +69,13 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL; TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
WOLFTPM2_SESSION tpmSession; WOLFTPM2_SESSION tpmSession;
const char* outputFile = "keyblob.bin"; const char* outputFile = "keyblob.bin";
byte derEncode = 0; const char* impFile = NULL;
int encType = ENCODING_TYPE_ASN1;
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) const char* password = NULL;
byte pemEncode = 0; TPMA_OBJECT attributes;
const char* pemName = "./certs/example-rsa-key.pem"; byte* buf = NULL;
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_RSA) size_t bufSz = 0;
FILE* pemFile = NULL; int isPublicKey = 0;
char pemBuf[WOLFTPM2_MAX_BUFFER];
#endif
#endif
if (argc >= 2) { if (argc >= 2) {
if (XSTRCMP(argv[1], "-?") == 0 || if (XSTRCMP(argv[1], "-?") == 0 ||
@ -75,44 +85,53 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
return 0; return 0;
} }
if (argv[1][0] != '-') if (argv[1][0] != '-') {
outputFile = argv[1]; outputFile = argv[1];
} }
/* i = 1 to skip binary */ }
for (i = 1; i < argc; i++) { while (argc > 1) {
if (XSTRCMP(argv[i], "-ecc") == 0) { if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
alg = TPM_ALG_ECC; alg = TPM_ALG_ECC;
} }
else if (XSTRCMP(argv[i], "-aes") == 0) { else if (XSTRCMP(argv[argc-1], "-aes") == 0) {
paramEncAlg = TPM_ALG_CFB; paramEncAlg = TPM_ALG_CFB;
} }
else if (XSTRCMP(argv[i], "-xor") == 0) { else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
paramEncAlg = TPM_ALG_XOR; paramEncAlg = TPM_ALG_XOR;
} }
else if (XSTRCMP(argv[i], "-der") == 0) { else if (XSTRCMP(argv[argc-1], "-public") == 0) {
derEncode = 1; isPublicKey = 1;
} }
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) else if (XSTRNCMP(argv[argc-1], "-password=", XSTRLEN("-password=")) == 0) {
else if (XSTRCMP(argv[i], "-pem") == 0) { password = (const char*)(argv[argc-1] + XSTRLEN("-password="));
pemEncode = 1;
printf("Warning: No pem file specified, using default: %s\n", pemName);
} }
else if (XSTRNCMP(argv[i], "-pem=", XSTRLEN("-pem=")) == 0) { else if (XSTRCMP(argv[argc-1], "-der") == 0) {
pemEncode = 1; encType = ENCODING_TYPE_ASN1;
}
if (XSTRLEN(argv[i] + XSTRLEN("-pem=")) == 0) { else if (XSTRNCMP(argv[argc-1], "-der=", XSTRLEN("-der=")) == 0) {
printf("Warning: No pem file specified, using default: %s\n", pemName); 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 { else {
pemName = (const char*)(argv[i] + XSTRLEN("-pem=")); printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
printf("Warning: No pem file specified, using default: %s\n", pemName);
} }
argc--;
} }
#endif
/* we already got outfile */ /* setup default import file */
else if (i == 1 && argv[1][0] != '-') { if (impFile == NULL) {
printf("Warning: Unrecognized option: %s\n", argv[i]); 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)); 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("\tKey Blob: %s\n", outputFile);
printf("\tAlgorithm: %s\n", TPM2_GetAlgName(alg)); printf("\tAlgorithm: %s\n", TPM2_GetAlgName(alg));
printf("\tUse Parameter Encryption: %s\n", TPM2_GetAlgName(paramEncAlg)); printf("\tUse Parameter Encryption: %s\n", TPM2_GetAlgName(paramEncAlg));
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) printf("\tpassword: %s\n", password);
if (pemEncode) {
printf("\tUse Pem Keyfile: %s\n", pemName);
}
#endif
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx); rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) { if (rc != TPM_RC_SUCCESS) {
@ -136,7 +151,7 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
} }
/* get SRK */ /* get SRK */
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA); rc = getPrimaryStoragekey(&dev, &storage, alg);
if (rc != 0) goto exit; if (rc != 0) goto exit;
if (paramEncAlg != TPM_ALG_NULL) { if (paramEncAlg != TPM_ALG_NULL) {
@ -154,42 +169,51 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
} }
/* setup an auth value */ /* setup an auth value */
impKey.handle.auth.size = (int)sizeof(gKeyAuth)-1; if (password != NULL) {
XMEMCPY(impKey.handle.auth.buffer, gKeyAuth, impKey.handle.auth.size); impKey.handle.auth.size = (int)XSTRLEN(password);
XMEMCPY(impKey.handle.auth.buffer, password, impKey.handle.auth.size);
}
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 { /* private key */
rc = wolfTPM2_ImportPrivateKeyBuffer(&dev, &storage,
alg,
&impKey,
encType,
(const char*)buf, (word32)bufSz,
password,
attributes, NULL, 0
);
}
}
}
else
#endif
if (alg == TPM_ALG_RSA) { if (alg == TPM_ALG_RSA) {
if (derEncode == 1) { printf("Loading example RSA key (see kRsaKeyPrivQ)\n");
#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);
}
else {
printf("Failed to read pem file %s\n", pemName);
rc = BUFFER_E;
}
#else
rc = NOT_COMPILED_IN;
#endif
}
#endif
else {
/* Import raw RSA private key into TPM */ /* Import raw RSA private key into TPM */
rc = wolfTPM2_ImportRsaPrivateKey(&dev, &storage, &impKey, rc = wolfTPM2_ImportRsaPrivateKey(&dev, &storage, &impKey,
kRsaKeyPubModulus, (word32)sizeof(kRsaKeyPubModulus), kRsaKeyPubModulus, (word32)sizeof(kRsaKeyPubModulus),
@ -197,8 +221,9 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
kRsaKeyPrivQ, (word32)sizeof(kRsaKeyPrivQ), kRsaKeyPrivQ, (word32)sizeof(kRsaKeyPrivQ),
TPM_ALG_NULL, TPM_ALG_NULL); TPM_ALG_NULL, TPM_ALG_NULL);
} }
}
else if (alg == TPM_ALG_ECC) { else if (alg == TPM_ALG_ECC) {
printf("Loading example ECC key (see kEccKeyPrivD)\n");
/* Import raw ECC private key into TPM */ /* Import raw ECC private key into TPM */
rc = wolfTPM2_ImportEccPrivateKey(&dev, &storage, &impKey, rc = wolfTPM2_ImportEccPrivateKey(&dev, &storage, &impKey,
TPM_ECC_NIST_P256, 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); TPM2_GetAlgName(alg), impKey.pub.size, impKey.priv.size);
/* Save key as encrypted blob to the disk */ /* 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); rc = writeKeyBlob(outputFile, &impKey);
#else #else
printf("Key Public Blob %d\n", impKey.pub.size); 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] != '-') { if (argv[1][0] != '-') {
inputFile = argv[1]; inputFile = argv[1];
} }
if (XSTRCMP(argv[1], "-eh") == 0) {
endorseKey = 1;
}
} }
while (argc > 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; paramEncAlg = TPM_ALG_CFB;
} }
else if (XSTRCMP(argv[argc-1], "-xor") == 0) { else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
@ -160,9 +160,14 @@ int TPM2_Keyload_Example(void* userCtx, int argc, char *argv[])
goto exit; goto exit;
#endif #endif
if (newKey.priv.size == 0) {
rc = wolfTPM2_LoadPublicKey(&dev, (WOLFTPM2_KEY*)&newKey, &newKey.pub);
}
else {
rc = wolfTPM2_LoadKey(&dev, &newKey, &primary->handle); rc = wolfTPM2_LoadKey(&dev, &newKey, &primary->handle);
}
if (rc != TPM_RC_SUCCESS) { if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_LoadKey failed\n"); printf("Load Key failed!\n");
goto exit; goto exit;
} }
printf("Loaded key to 0x%x\n", printf("Loaded key to 0x%x\n",

View File

@ -165,6 +165,9 @@ int readKeyBlob(const char* filename, WOLFTPM2_KEYBLOB* key)
} }
rc = 0; /* success */ rc = 0; /* success */
} }
if (key->priv.size == 0) {
printf("No private key loaded\n");
}
/* sanity check the sizes */ /* sanity check the sizes */
if (pubAreaSize != (key->pub.size + (int)sizeof(key->pub.size)) || if (pubAreaSize != (key->pub.size + (int)sizeof(key->pub.size)) ||
@ -391,4 +394,57 @@ int getECCkey(WOLFTPM2_DEV* pDev,
return rc; 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 */ #endif /* !WOLFTPM2_NO_WRAPPER */

View File

@ -66,6 +66,8 @@ WOLFTPM_LOCAL int getECCkey(WOLFTPM2_DEV* pDev,
const byte* auth, int authSz, const byte* auth, int authSz,
TPMT_PUBLIC* publicTemplate); TPMT_PUBLIC* publicTemplate);
WOLFTPM_LOCAL int loadFile(const char* fname, byte** buf, size_t* bufLen);
#endif /* !WOLFTPM2_NO_WRAPPER */ #endif /* !WOLFTPM2_NO_WRAPPER */
#endif /* _TPM_TEST_KEYS_H_ */ #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_ASN
#ifndef NO_RSA #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) const byte* input, word32 inSz, TPMA_OBJECT attributes)
{ {
int rc = 0; int rc = 0;
@ -2486,6 +2486,7 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens,
word32 dSz = (word32)sizeof(d); word32 dSz = (word32)sizeof(d);
word32 pSz = (word32)sizeof(p); word32 pSz = (word32)sizeof(p);
word32 qSz = (word32)sizeof(q); word32 qSz = (word32)sizeof(q);
int isPrivateKey = 0;
XMEMSET(n, 0, sizeof(n)); XMEMSET(n, 0, sizeof(n));
XMEMSET(d, 0, sizeof(d)); XMEMSET(d, 0, sizeof(d));
@ -2494,15 +2495,26 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens,
rc = wc_InitRsaKey(key, NULL); rc = wc_InitRsaKey(key, NULL);
if (rc == 0) { if (rc == 0) {
idx = 0;
rc = wc_RsaPrivateKeyDecode(input, &idx, key, inSz); rc = wc_RsaPrivateKeyDecode(input, &idx, key, inSz);
if (rc == 0) { if (rc == 0) {
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, rc = wc_RsaExportKey(key, (byte*)&e, &eSz, n, &nSz, d, &dSz,
p, &pSz, q, &qSz); p, &pSz, q, &qSz);
else
rc = wc_RsaFlattenPublicKey(key, (byte*)&e, &eSz, n, &nSz);
} }
if (rc == 0 && nSz > sizeof(pub->publicArea.unique.rsa.buffer)) if (rc == 0 && nSz > sizeof(pub->publicArea.unique.rsa.buffer))
rc = BUFFER_E; 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; rc = BUFFER_E;
if (rc == 0) { if (rc == 0) {
/* Set up public key */ /* Set up public key */
@ -2529,10 +2541,12 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens,
} }
/* Set up private key */ /* Set up private key */
if (sens != NULL && isPrivateKey) {
sens->sensitiveArea.sensitiveType = TPM_ALG_RSA; sens->sensitiveArea.sensitiveType = TPM_ALG_RSA;
sens->sensitiveArea.sensitive.rsa.size = qSz; sens->sensitiveArea.sensitive.rsa.size = qSz;
XMEMCPY(sens->sensitiveArea.sensitive.rsa.buffer, q, qSz); XMEMCPY(sens->sensitiveArea.sensitive.rsa.buffer, q, qSz);
} }
}
wc_FreeRsaKey(key); wc_FreeRsaKey(key);
} }
@ -2540,12 +2554,12 @@ static int DecodeRsaPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens,
} }
#endif #endif
#ifdef HAVE_ECC #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) const byte* input, word32 inSz, TPMA_OBJECT attributes)
{ {
int rc; int rc;
int curveId = 0; int curveId = 0;
word32 idx = 0; word32 idx;
ecc_key key[1]; ecc_key key[1];
byte d[WOLFTPM2_WRAP_ECC_KEY_BITS / 8]; byte d[WOLFTPM2_WRAP_ECC_KEY_BITS / 8];
byte qx[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 dSz = sizeof(d);
word32 qxSz = sizeof(qx); word32 qxSz = sizeof(qx);
word32 qySz = sizeof(qy); word32 qySz = sizeof(qy);
int isPrivateKey = 0;
XMEMSET(d, 0, sizeof(d)); XMEMSET(d, 0, sizeof(d));
XMEMSET(qx, 0, sizeof(qx)); XMEMSET(qx, 0, sizeof(qx));
@ -2560,17 +2575,29 @@ static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens,
rc = wc_ecc_init(key); rc = wc_ecc_init(key);
if (rc == 0) { if (rc == 0) {
idx = 0;
rc = wc_EccPrivateKeyDecode(input, &idx, key, inSz); 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) { if (rc == 0) {
curveId = TPM2_GetTpmCurve(key->dp->id); curveId = TPM2_GetTpmCurve(key->dp->id);
if (isPrivateKey)
rc = wc_ecc_export_private_raw(key, qx, &qxSz, qy, &qySz, d, &dSz); 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)) if (rc == 0 && qxSz > sizeof(pub->publicArea.unique.ecc.x.buffer))
rc = BUFFER_E; rc = BUFFER_E;
if (rc == 0 && qySz > sizeof(pub->publicArea.unique.ecc.y.buffer)) if (rc == 0 && qySz > sizeof(pub->publicArea.unique.ecc.y.buffer))
rc = BUFFER_E; 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; rc = BUFFER_E;
if (rc == 0) { if (rc == 0) {
/* Set up public key */ /* Set up public key */
@ -2601,10 +2628,12 @@ static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens,
} }
/* Set up private key */ /* Set up private key */
if (sens != NULL && isPrivateKey) {
sens->sensitiveArea.sensitiveType = TPM_ALG_ECC; sens->sensitiveArea.sensitiveType = TPM_ALG_ECC;
sens->sensitiveArea.sensitive.ecc.size = dSz; sens->sensitiveArea.sensitive.ecc.size = dSz;
XMEMCPY(sens->sensitiveArea.sensitive.ecc.buffer, d, dSz); XMEMCPY(sens->sensitiveArea.sensitive.ecc.buffer, d, dSz);
} }
}
wc_ecc_free(key); wc_ecc_free(key);
} }
@ -2613,9 +2642,68 @@ static int DecodeEccPrivateDer(TPM2B_PUBLIC* pub, TPM2B_SENSITIVE* sens,
} }
#endif /* HAVE_ECC */ #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, int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev,
const WOLFTPM2_KEY* parentKey, int keyType, WOLFTPM2_KEYBLOB* keyBlob, 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) TPMA_OBJECT objectAttributes, byte* seed, word32 seedSz)
{ {
int rc = 0; int rc = 0;
@ -2658,14 +2746,14 @@ int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev,
/* Handle DER Import */ /* Handle DER Import */
if (keyType == TPM_ALG_RSA) { if (keyType == TPM_ALG_RSA) {
#ifndef NO_RSA #ifndef NO_RSA
rc = DecodeRsaPrivateDer(&pub, &sens, derBuf, derSz, objectAttributes); rc = DecodeRsaDer(&pub, &sens, derBuf, derSz, objectAttributes);
#else #else
rc = NOT_COMPILED_IN; rc = NOT_COMPILED_IN;
#endif #endif
} }
else if (keyType == TPM_ALG_ECC) { else if (keyType == TPM_ALG_ECC) {
#ifdef HAVE_ECC #ifdef HAVE_ECC
rc = DecodeEccPrivateDer(&pub, &sens, derBuf, derSz, objectAttributes); rc = DecodeEccDer(&pub, &sens, derBuf, derSz, objectAttributes);
#else #else
rc = NOT_COMPILED_IN; rc = NOT_COMPILED_IN;
#endif #endif
@ -3120,10 +3208,17 @@ int wolfTPM2_NVStoreKey(WOLFTPM2_DEV* dev, TPM_HANDLE primaryHandle,
int rc; int rc;
EvictControl_In in; EvictControl_In in;
if (dev == NULL || key == NULL || if (dev == NULL || key == NULL) {
(primaryHandle != TPM_RH_OWNER && primaryHandle != TPM_RH_PLATFORM) || return BAD_FUNC_ARG;
persistentHandle < PERSISTENT_FIRST || }
persistentHandle > PERSISTENT_LAST) { 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; 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 \return BAD_FUNC_ARG: check the provided arguments
\param dev pointer to a TPM2_DEV struct \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 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 encodingType ENCODING_TYPE_PEM or ENCODING_TYPE_ASN1 (DER)
\param input buffer holding the rsa pem \param input buffer holding the rsa pem
\param inSz length of the input pem buffer \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, WOLFTPM_API int wolfTPM2_ImportPrivateKeyBuffer(WOLFTPM2_DEV* dev,
const WOLFTPM2_KEY* parentKey, int keyType, WOLFTPM2_KEYBLOB* keyBlob, 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); 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 #ifndef NO_RSA
/*! /*!
\ingroup wolfTPM2_Wrappers \ingroup wolfTPM2_Wrappers