Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add rsa key import methods to handle pem and der encoding directly #252

Merged
merged 6 commits into from Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 28 additions & 0 deletions certs/example-rsa-key.pem
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
dgarske marked this conversation as resolved.
Show resolved Hide resolved
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-----
3 changes: 2 additions & 1 deletion certs/include.am
Expand Up @@ -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
89 changes: 75 additions & 14 deletions examples/keygen/keyimport.c
Expand Up @@ -40,21 +40,31 @@
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;
TPMI_ALG_PUBLIC alg = TPM_ALG_RSA; /* TPM_ALG_ECC */
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
WOLFTPM2_SESSION tpmSession;
const char* outputFile = "keyblob.bin";
byte derEncode = 0;
dgarske marked this conversation as resolved.
Show resolved Hide resolved

#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 ||
Expand All @@ -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)
dgarske marked this conversation as resolved.
Show resolved Hide resolved
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));
Expand All @@ -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) {
Expand Down Expand Up @@ -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 */
Expand Down
89 changes: 89 additions & 0 deletions src/tpm2_wrap.c
Expand Up @@ -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)
Expand Down Expand Up @@ -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];
dgarske marked this conversation as resolved.
Show resolved Hide resolved
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,
dgarske marked this conversation as resolved.
Show resolved Hide resolved
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) {
dgarske marked this conversation as resolved.
Show resolved Hide resolved
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)
{
Expand Down
42 changes: 42 additions & 0 deletions wolftpm/tpm2_wrap.h
Expand Up @@ -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
Expand Down