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

SSH support for public key based authentication #192

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions examples/keygen/keygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include <stdio.h>
#include <stdlib.h> /* atoi */
#include <wolfssl/wolfcrypt/rsa.h>
#include <wolfssl/wolfcrypt/asn_public.h>

#ifndef WOLFTPM2_NO_WRAPPER

Expand All @@ -56,6 +58,9 @@ static void usage(void)
printf("* -sym: Use Symmetric Cypher for key generation\n");
printf("\tDefault Symmetric Cypher is AES CTR with 256 bits\n");
printf("* -t: Use default template (otherwise AIK)\n");
printf("* -ssh: Use template for SSH key (only RSA algorithm)\n");
printf("\tStores public key in id_rsa.pub\n");
printf("\tStores private key in keyblob.bin\n");
printf("* -aes/xor: Use Parameter Encryption\n");
printf("Example usage:\n");
printf("\t* RSA, default template\n");
Expand Down Expand Up @@ -108,6 +113,34 @@ static int symChoice(const char* arg, TPM_ALG_ID* algSym, int* keyBits,
return TPM_RC_SUCCESS;
}

static int writeKeyPubSsh(const char *filename, const byte *buf, word32 buf_size)
{
int rc = TPM_RC_FAILURE;
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM)
XFILE fp = NULL;
size_t fileSz = 0;

if (filename == NULL || buf == NULL)
return BAD_FUNC_ARG;

fp = XFOPEN(filename, "wt");
if (fp != XBADFILE) {
fileSz = XFWRITE(buf, 1, buf_size, fp);
/* sanity check */
if (fileSz == buf_size) {
rc = TPM_RC_SUCCESS;
}
#ifdef DEBUG_WOLFTPM
printf("Public PEM file size = %zu\n", fileSz);
TPM2_PrintBin(buf, buf_size);
#endif
XFCLOSE(fp);
}
#endif
return rc;

}

int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
{
int rc;
Expand All @@ -127,6 +160,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
int endorseKey = 0;
int pemFiles = 0;
int bAIK = 1;
int bSSH = 0;
int keyBits = 256;
const char *outputFile = "keyblob.bin";
const char *ekPubFile = "ek.pub";
Expand Down Expand Up @@ -183,6 +217,10 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
if (XSTRNCMP(argv[argc-1], "-pem", 4) == 0) {
pemFiles = 1;
}
if (XSTRNCMP(argv[argc-1], "-ssh", 4) == 0) {
bSSH = 1;
bAIK = 0;
}
if (XSTRNCMP(argv[argc-1], "-aes", 4) == 0) {
paramEncAlg = TPM_ALG_CFB;
}
Expand Down Expand Up @@ -273,6 +311,20 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
XMEMCPY(auth.buffer, gAiKeyAuth, auth.size);

}
else if (bSSH) {
if (alg == TPM_ALG_RSA) {
printf("SSH template for RSA key\n");
rc = wolfTPM2_GetKeyTemplate_RSA_SSH(&publicTemplate, TPM_ALG_SHA1);

/* set session for authorization key */
auth.size = (int)sizeof(gKeyAuth)-1;
XMEMCPY(auth.buffer, gKeyAuth, auth.size);
}
else {
printf("SSH template for ECC key not implemented\n");
rc = BAD_FUNC_ARG;
}
}
else {
if (alg == TPM_ALG_RSA) {
printf("RSA template\n");
Expand Down Expand Up @@ -315,6 +367,11 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
/* Save key as encrypted blob to the disk */
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && !defined(NO_FILESYSTEM)
rc = writeKeyBlob(outputFile, &newKeyBlob);
if (rc != 0) {
printf("Failure to store key blob\n");
goto exit;
}

/* Generate key artifacts needed for remote attestation */
if (bAIK) {
/* Store primary public key */
Expand All @@ -328,6 +385,33 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
XFCLOSE(fp);
}
}

if (bSSH) {
WOLFTPM2_KEY tpmKey;
RsaKey rsaKey;
byte der[MAX_RSA_KEY_BYTES], pem[MAX_RSA_KEY_BYTES];
int derSz, pemSz;

/* Prepare wolfCrypt key structure */
rc = wc_InitRsaKey(&rsaKey, NULL);
if (rc != 0) goto exit;
/* Prepare wolfTPM key structure */
XMEMCPY(&tpmKey.handle, &newKey.handle, sizeof(tpmKey.handle));
XMEMCPY(&tpmKey.pub, &newKey.pub, sizeof(tpmKey.pub));
/* Convert the wolfTPM key to wolfCrypt format */
rc = wolfTPM2_RsaKey_TpmToWolf(&dev, &tpmKey, &rsaKey);
if (rc != 0) goto exit;
/* Convert the wolfCrypt key to DER format */
rc = wc_RsaKeyToPublicDer(&rsaKey, der, sizeof(der));
if (rc <= 0) goto exit;
derSz = rc;
/* Convert the DER key to PEM format */
rc = wc_DerToPem(der, derSz, pem, sizeof(pem), PUBLICKEY_TYPE);
if (rc <= 0) goto exit;
pemSz = rc;
/* Store PEM output to file */
rc = writeKeyPubSsh("id_rsa.pub", pem, (word32)pemSz);
}
#else
if (alg == TPM_ALG_SYMCIPHER) {
printf("The Public Part of a symmetric key contains only meta data\n");
Expand Down
19 changes: 19 additions & 0 deletions src/tpm2_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -4149,6 +4149,25 @@ int wolfTPM2_GetKeyTemplate_ECC_AIK(TPMT_PUBLIC* publicTemplate)
return ret;
}

int wolfTPM2_GetKeyTemplate_RSA_SSH(TPMT_PUBLIC* publicTemplate, TPM_ALG_ID hashAlg)
{
int ret;
TPMA_OBJECT objectAttributes = (
TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent |
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_decrypt | TPMA_OBJECT_noDA);

/* "ssh-rsa" requires RSA key be:
* at least 2048 bits
* OAEP signature scheme with SHA1 hash algorithm */
ret = GetKeyTemplateRSA(publicTemplate, TPM_ALG_SHA256,
objectAttributes, 2048, 0, TPM_ALG_OAEP, hashAlg);
if (ret == 0) {
publicTemplate->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL;
}
return ret;
}

int wolfTPM2_GetNvAttributesTemplate(TPM_HANDLE auth, word32* nvAttributes)
{
if (nvAttributes == NULL)
Expand Down
16 changes: 16 additions & 0 deletions wolftpm/tpm2_wrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,22 @@ WOLFTPM_API int wolfTPM2_GetKeyTemplate_RSA_AIK(TPMT_PUBLIC* publicTemplate);
*/
WOLFTPM_API int wolfTPM2_GetKeyTemplate_ECC_AIK(TPMT_PUBLIC* publicTemplate);

/*!
\ingroup wolfTPM2_Wrappers
\brief Prepares a TPM public template for generating a new TPM key that can be used with the SSH protocol
Note: Choose the hashing algorithm carefully, SSH servers could require SHA-256 or even SHA-512

\return TPM_RC_SUCCESS: successful
\return BAD_FUNC_ARG: check the provided arguments

\param publicTemplate pointer to an empty structure of TPMT_PUBLIC type, to store the new template
\param hashAlg integer value of TPM_ALG_ID type, specify the hashing algorithm used by ssh-rsa

\sa wolfTPM2_GetKeyTemplate_RSA
\sa wolfTPM2_GetKeyTemplate_RSA_AIK
*/
WOLFTPM_API int wolfTPM2_GetKeyTemplate_RSA_SSH(TPMT_PUBLIC* publicTemplate, TPM_ALG_ID hashAlg);

/*!
\ingroup wolfTPM2_Wrappers
\brief Prepares a TPM NV Index template
Expand Down