mirror of https://github.com/wolfSSL/wolfTPM.git
Add RSA key import methods to handle PEM and DER encoding directly (#252)
parent
b4e439a595
commit
3a1ece8da1
|
|
@ -0,0 +1,28 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCePbYR1SIZAL/2
|
||||
8FYbgpxynENgvHACM9LczZnsgVkZYxx3O9DTba2VTxhMN21i/aocJCzZB35qvz+R
|
||||
ickyvWBqPDXauJEn9icPXgSknqxzw0ZATzL0wbq/Tk5T+oITFFCGJ8/baFoktOKu
|
||||
iP5H50Dx6X2W1qNHiLkbGq7NbXHA8YG2wzK9kwikowSXQVB7pZ5bgjW2q73vIGSs
|
||||
eW802f7I/30wbf4oR1vfk4OQursT9sl2CFLNt5bJSw6lFTm4BOgC7Q3bpHPzC/YK
|
||||
uFYWKGeQL9GCsEZVWHCM6vzek6SNwQ0eoQ0i9IuF0os/0nJDwdXEZX9OoBhFT717
|
||||
svlxDXpFAgMBAAECggEABYIV6Jx/5ZloVTbr9GSxP+8PDFq61mTJ6fwxJ7Gf8ZmI
|
||||
1+Cp5fYrJOeeK6cBRIEabwTWV86iOKKEGrOOYJkFdmU2pbCngtnXZbpK1JUeYSAy
|
||||
vZHULv9gWgDmipdNeE8Md4MCwfspqh3uxw8HNOcIlHMhd0Ls55RLhzVAUO/GliXz
|
||||
5HIDhohyQAUvPvkwz1yrPNn5BQwMlJBARc2OKSKf+pJrlFw1KJWR9TKzGvRzMbI4
|
||||
gwrq9BZ5LCX5y6C7BpuzXdySHXofwihPNmi1KU/88cWhas2E0Xz+p+N/ifmkquTN
|
||||
3EqzqKBW+xobryM6X9JfQ6has211eUaZKNuU2/idKQKBgQC5rymu0UKHuAkr4uPS
|
||||
NLGmaWb4p+kDNxbVyzS2ENjtoJ6JyEo/pZQrTG4S/kCWFgGsuztCbx+1Kgk0Pgwi
|
||||
znaGvcfrjiP9XE1oVfMifA2JmH+drjASyjPqNfsf0BKQtlk0nZXwUO/C1FQ5vUU4
|
||||
lpmpx4EhTnucQ9E7r0+uXnQHTQKBgQDaKh4bBV7dLBF4ZxwCdydMMSZkBgckBiH7
|
||||
83BvyLW6I0GKXcFTa7KKLgTj41pXeWh6bmM9365+Cr8fxTZop28EfGRYFBMp08/g
|
||||
wHpmS3NZ4moSgirJ+PhZsH+nBq89W75INR7BqV4SAc3n4lcwv9eBL9q0Q/YJZ1ph
|
||||
NCKvz79y2QKBgFyDFPVwdQFBg/BFntRARLJwmUkR/1oGvG3QTHbZdfsOp25mR/fl
|
||||
+yiHb+AupOciF7uDnUbALsAILYXF1C4TR6JiM5T8wJmev0JYcEaiH+yJ+isJehIi
|
||||
hDMQqglzlYxcDZ3VVbrh2FLtjvklf7Nt9SlNqNx7ScLVVw2xjrWFgbGRAoGBAMjo
|
||||
Wnsl0fu6Noh74/Z9RmpLJQCd8HuDTk6ZHCVFX91/1D6ZIo0xM+U+hfBbkfnWa5m8
|
||||
CJaVZDrcqK+YTQfJkVo/N6VJL3Coh9qBRvbnat4OvQI4bzE6n3LxME1fwYeu8ifL
|
||||
C3zq/R92G+n8rbDOKqbkq/KwV2bHkBrOCVeA6NzZAoGACztyZbS5jCuSlPqk/xoN
|
||||
EzX9Cev/GipF5tZMeOcQlty+anPg3TC70O06yZ1SIJKLzOOyoPCUDNrM2M5TCaau
|
||||
vT0vW1GeNAryc+q9aOmFT3AlZ93Tfst+90Q+NJecEEhkO43tU5S1ZK2iVf9XAOV6
|
||||
ovHegJU35IUeaoyg23HjFWU=
|
||||
-----END PRIVATE KEY-----
|
||||
|
|
@ -7,4 +7,5 @@ EXTRA_DIST += \
|
|||
certs/ca-rsa.cnf \
|
||||
certs/ca-ecc.cnf \
|
||||
certs/wolf-ca-ecc-cert.pem \
|
||||
certs/wolf-ca-rsa-cert.pem
|
||||
certs/wolf-ca-rsa-cert.pem \
|
||||
certs/example-rsa-key.pem
|
||||
|
|
|
|||
|
|
@ -40,14 +40,16 @@
|
|||
static void usage(void)
|
||||
{
|
||||
printf("Expected usage:\n");
|
||||
printf("./examples/keygen/keyimport [keyblob.bin] [-ecc/-rsa] [-aes/xor]\n");
|
||||
printf("./examples/keygen/keyimport [keyblob.bin] [-ecc/-rsa] [-pem/-der] [-aes/xor]\n");
|
||||
printf("* -ecc: Use RSA or ECC for keys\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");
|
||||
}
|
||||
|
||||
int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
int i;
|
||||
WOLFTPM2_DEV dev;
|
||||
WOLFTPM2_KEY storage; /* SRK */
|
||||
WOLFTPM2_KEYBLOB impKey;
|
||||
|
|
@ -55,6 +57,14 @@ 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;
|
||||
FILE* pemFile = NULL;
|
||||
const char* pemName = "./certs/example-rsa-key.pem";
|
||||
char pemBuf[WOLFTPM2_MAX_BUFFER];
|
||||
#endif
|
||||
|
||||
if (argc >= 2) {
|
||||
if (XSTRCMP(argv[1], "-?") == 0 ||
|
||||
|
|
@ -67,20 +77,41 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
|
|||
if (argv[1][0] != '-')
|
||||
outputFile = argv[1];
|
||||
}
|
||||
while (argc > 1) {
|
||||
if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
|
||||
/* i = 1 to skip binary */
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (XSTRCMP(argv[i], "-ecc") == 0) {
|
||||
alg = TPM_ALG_ECC;
|
||||
}
|
||||
else if (XSTRCMP(argv[argc-1], "-aes") == 0) {
|
||||
else if (XSTRCMP(argv[i], "-aes") == 0) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
}
|
||||
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
|
||||
else if (XSTRCMP(argv[i], "-xor") == 0) {
|
||||
paramEncAlg = TPM_ALG_XOR;
|
||||
}
|
||||
else {
|
||||
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
|
||||
else if (XSTRCMP(argv[i], "-der") == 0) {
|
||||
derEncode = 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[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--;
|
||||
}
|
||||
|
||||
XMEMSET(&storage, 0, sizeof(storage));
|
||||
|
|
@ -91,6 +122,11 @@ 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
|
||||
|
||||
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
|
|
@ -121,12 +157,37 @@ int TPM2_Keyimport_Example(void* userCtx, int argc, char *argv[])
|
|||
XMEMCPY(impKey.handle.auth.buffer, gKeyAuth, impKey.handle.auth.size);
|
||||
|
||||
if (alg == TPM_ALG_RSA) {
|
||||
/* 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);
|
||||
if (derEncode == 1) {
|
||||
rc = wolfTPM2_RsaPrivateKeyImportDer(&dev, &storage, &impKey,
|
||||
kRsaKeyPrivDer, sizeof(kRsaKeyPrivDer), TPM_ALG_NULL,
|
||||
TPM_ALG_NULL);
|
||||
}
|
||||
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
|
||||
else if (pemEncode == 1) {
|
||||
pemFile = XFOPEN(pemName, "r");
|
||||
|
||||
if (pemFile == NULL)
|
||||
printf("Failed to read pem file %s\n", pemName);
|
||||
|
||||
if (rc == 0)
|
||||
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);
|
||||
}
|
||||
#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 if (alg == TPM_ALG_ECC) {
|
||||
/* Import raw ECC private key into TPM */
|
||||
|
|
|
|||
|
|
@ -1903,6 +1903,7 @@ int wolfTPM2_LoadRsaPrivateKey_ex(WOLFTPM2_DEV* dev,
|
|||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wolfTPM2_LoadRsaPrivateKey(WOLFTPM2_DEV* dev, const WOLFTPM2_KEY* parentKey,
|
||||
WOLFTPM2_KEY* key, const byte* rsaPub, word32 rsaPubSz, word32 exponent,
|
||||
const byte* rsaPriv, word32 rsaPrivSz)
|
||||
|
|
@ -2059,6 +2060,94 @@ int wolfTPM2_ReadPublicKey(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
|
|||
|
||||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
#ifndef NO_RSA
|
||||
int wolfTPM2_RsaPrivateKeyImportDer(WOLFTPM2_DEV* dev,
|
||||
const WOLFTPM2_KEY* parentKey, WOLFTPM2_KEYBLOB* keyBlob, const byte* input,
|
||||
word32 inSz, TPMI_ALG_RSA_SCHEME scheme, TPMI_ALG_HASH hashAlg)
|
||||
{
|
||||
int rc = 0;
|
||||
int initRc = -1;
|
||||
RsaKey key[1];
|
||||
word32 idx = 0;
|
||||
word32 e;
|
||||
byte n[RSA_MAX_SIZE / 8];
|
||||
byte d[RSA_MAX_SIZE / 8];
|
||||
byte p[RSA_MAX_SIZE / 8];
|
||||
byte q[RSA_MAX_SIZE / 8];
|
||||
word32 eSz = (word32)sizeof(e);
|
||||
word32 nSz = (word32)sizeof(n);
|
||||
word32 dSz = (word32)sizeof(d);
|
||||
word32 pSz = (word32)sizeof(p);
|
||||
word32 qSz = (word32)sizeof(q);
|
||||
|
||||
if (dev == NULL || parentKey == NULL || keyBlob == NULL || input == NULL ||
|
||||
inSz == 0) {
|
||||
rc = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (rc == 0)
|
||||
rc = initRc = wc_InitRsaKey(key, NULL);
|
||||
|
||||
if (rc == 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);
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
rc = wolfTPM2_ImportRsaPrivateKey(dev, parentKey, keyBlob, n, nSz, e, q,
|
||||
qSz, scheme, hashAlg);
|
||||
}
|
||||
|
||||
if (initRc == 0)
|
||||
wc_FreeRsaKey(key);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef WOLFTPM2_NO_HEAP
|
||||
|
||||
int wolfTPM2_RsaPrivateKeyImportPem(WOLFTPM2_DEV* dev,
|
||||
const WOLFTPM2_KEY* parentKey, WOLFTPM2_KEYBLOB* keyBlob,
|
||||
const char* input, word32 inSz, char* pass,
|
||||
TPMI_ALG_RSA_SCHEME scheme, TPMI_ALG_HASH hashAlg)
|
||||
{
|
||||
int rc = 0;
|
||||
byte* derBuf;
|
||||
word32 derSz;
|
||||
|
||||
if (dev == NULL || parentKey == NULL || keyBlob == NULL || input == NULL ||
|
||||
inSz == 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* 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_KeyPemToDer((byte*)input, inSz, derBuf, derSz, pass);
|
||||
|
||||
/* returns the number of bytes */
|
||||
if (rc > 0) {
|
||||
rc = wolfTPM2_RsaPrivateKeyImportDer(dev, parentKey, keyBlob, derBuf,
|
||||
(word32)rc, scheme, hashAlg);
|
||||
}
|
||||
/* shouldn't be possible to have a 0 length der, check anyways */
|
||||
else if (rc == 0) {
|
||||
rc = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* WOLFTPM2_NO_HEAP */
|
||||
|
||||
int wolfTPM2_RsaKey_TpmToWolf(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* tpmKey,
|
||||
RsaKey* wolfKey)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1019,6 +1019,48 @@ WOLFTPM_API int wolfTPM2_SensitiveToPrivate(TPM2B_SENSITIVE* sens, TPM2B_PRIVATE
|
|||
|
||||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
#ifndef NO_RSA
|
||||
/*!
|
||||
\ingroup wolfTPM2_Wrappers
|
||||
\brief Helper function to import Der rsa key directly
|
||||
|
||||
\return TPM_RC_SUCCESS: successful
|
||||
\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 parentKey pointer to a WOLFTPM2_KEY struct, pointing to a Primary Key or TPM Hierarchy
|
||||
\param keyBlob pointer to a struct of WOLFTPM2_KEY type, to import the rsa key to
|
||||
\param input buffer holding the rsa der
|
||||
\param inSz length of the input der buffer
|
||||
\param scheme value of TPMI_ALG_RSA_SCHEME type, specifying the RSA scheme
|
||||
\param hashAlg value of TPMI_ALG_HASH type, specifying the TPM hashing algorithm
|
||||
*/
|
||||
WOLFTPM_API int wolfTPM2_RsaPrivateKeyImportDer(WOLFTPM2_DEV* dev,
|
||||
const WOLFTPM2_KEY* parentKey, WOLFTPM2_KEYBLOB* keyBlob, const byte* input,
|
||||
word32 inSz, TPMI_ALG_RSA_SCHEME scheme, TPMI_ALG_HASH hashAlg);
|
||||
|
||||
/*!
|
||||
\ingroup wolfTPM2_Wrappers
|
||||
\brief Helper function to import Der rsa key directly
|
||||
|
||||
\return TPM_RC_SUCCESS: successful
|
||||
\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 parentKey pointer to a WOLFTPM2_KEY struct, pointing to a Primary Key or TPM Hierarchy
|
||||
\param keyBlob pointer to a struct of WOLFTPM2_KEY type, to import the rsa key to
|
||||
\param input buffer holding the rsa pem
|
||||
\param inSz length of the input pem buffer
|
||||
\param pass optional password of the key
|
||||
\param scheme value of TPMI_ALG_RSA_SCHEME type, specifying the RSA scheme
|
||||
\param hashAlg value of TPMI_ALG_HASH type, specifying the TPM hashing algorithm
|
||||
*/
|
||||
WOLFTPM_API int wolfTPM2_RsaPrivateKeyImportPem(WOLFTPM2_DEV* dev,
|
||||
const WOLFTPM2_KEY* parentKey, WOLFTPM2_KEYBLOB* keyBlob,
|
||||
const char* input, word32 inSz, char* pass,
|
||||
TPMI_ALG_RSA_SCHEME scheme, TPMI_ALG_HASH hashAlg);
|
||||
|
||||
/*!
|
||||
\ingroup wolfTPM2_Wrappers
|
||||
\brief Extract a RSA TPM key and convert it to a wolfcrypt key
|
||||
|
|
|
|||
Loading…
Reference in New Issue