Skip to content

Commit

Permalink
Merge pull request #123 from xaptum/zanebeckwith/tpm-key-gen
Browse files Browse the repository at this point in the history
Store longterm key in TPM
  • Loading branch information
zanebeckwith committed Sep 11, 2020
2 parents fffb562 + b8a8e8b commit 7088f12
Show file tree
Hide file tree
Showing 11 changed files with 422 additions and 67 deletions.
28 changes: 28 additions & 0 deletions include/xtt/context.h
Expand Up @@ -27,6 +27,7 @@
#include <xtt/daa_wrapper.h>

#ifdef USE_TPM
#include <xaptum-tpm/keys.h>
#include <tss2/tss2_sys.h>
#endif

Expand Down Expand Up @@ -187,6 +188,17 @@ struct xtt_client_handshake_context {
union {
xtt_ecdsap256_priv_key ecdsap256;
} longterm_private_key;

#ifdef USE_TPM
TSS2_TCTI_CONTEXT *tcti_context;

TPMI_RH_HIERARCHY hierarchy;
char hierarchy_password[MAX_TPM_PASSWORD_LENGTH];
size_t hierarchy_password_length;

TPM2_HANDLE parent_handle;
struct xtpm_key longterm_private_key_tpm;
#endif
};

struct xtt_server_cookie_context {
Expand Down Expand Up @@ -267,6 +279,22 @@ xtt_initialize_client_handshake_context(struct xtt_client_handshake_context* ctx
xtt_version version,
xtt_suite_spec suite_spec);

#ifdef USE_TPM
xtt_return_code_type
xtt_initialize_client_handshake_context_TPM(struct xtt_client_handshake_context* ctx_out,
unsigned char *in_buffer,
uint16_t in_buffer_size,
unsigned char *out_buffer,
uint16_t out_buffer_size,
xtt_version version,
xtt_suite_spec suite_spec,
TPMI_RH_HIERARCHY hierarchy,
const char *hierarchy_password,
size_t hierarchy_password_length,
TPM2_HANDLE parent_handle,
TSS2_TCTI_CONTEXT *tcti_context);
#endif

xtt_return_code_type
xtt_initialize_server_handshake_context(struct xtt_server_handshake_context* ctx_out,
unsigned char *in_buffer,
Expand Down
2 changes: 2 additions & 0 deletions include/xtt/crypto/hmac.h
Expand Up @@ -33,6 +33,7 @@ extern "C" {
* They are used to ensure that the :xtt_crypto_hmac: generic buffer
* is large enough for any HMAC output.
*/
typedef struct {unsigned char data[32];} xtt_crypto_sha256;
typedef struct {unsigned char data[64];} xtt_crypto_sha512;
typedef struct {unsigned char data[64];} xtt_crypto_blake2b;

Expand All @@ -50,6 +51,7 @@ typedef struct {unsigned char data[64];} xtt_crypto_blake2b;
struct xtt_crypto_hmac {
union {
unsigned char buf;
xtt_crypto_sha256 sha256;
xtt_crypto_sha512 sha512;
xtt_crypto_blake2b blake2b;
};
Expand Down
4 changes: 4 additions & 0 deletions include/xtt/crypto_wrapper.h
Expand Up @@ -42,6 +42,10 @@ int xtt_crypto_kx_x25519_exchange(struct xtt_crypto_kx_shared* shared,
const struct xtt_crypto_kx_public* other_public,
const struct xtt_crypto_kx_secret* my_secret);

int xtt_crypto_hash_sha256(struct xtt_crypto_hmac* out,
const unsigned char* in,
uint16_t in_len);

int xtt_crypto_hash_sha512(struct xtt_crypto_hmac* out,
const unsigned char* in,
uint16_t inlen);
Expand Down
17 changes: 17 additions & 0 deletions include/xtt/util/asn1.h
Expand Up @@ -22,6 +22,10 @@

#include <stddef.h>

#ifdef USE_TPM
#include <xaptum-tpm/keys.h>
#endif

#include <xtt/crypto_types.h>

#ifdef __cplusplus
Expand All @@ -48,6 +52,19 @@ int xtt_x509_from_ecdsap256_keypair(const xtt_ecdsap256_pub_key *pub_key_in,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t certificate_out_length);

#ifdef USE_TPM
/*
* Same as above, but uses a TPM signing key.
*/
int xtt_x509_from_ecdsap256_TPM(const xtt_ecdsap256_pub_key *pub_key_in,
const struct xtpm_key *priv_key_in,
TSS2_TCTI_CONTEXT *tcti_context,
const xtt_identity_type *common_name,
unsigned char *certificate_out,
size_t certificate_out_length);
#endif

/*
* Writes the ECDSA keypair from the keys given
*
Expand Down
175 changes: 132 additions & 43 deletions src/context.c
Expand Up @@ -30,6 +30,16 @@
#include <string.h>
#include <assert.h>

static
xtt_return_code_type
initialize_client_handshake_context_common(struct xtt_client_handshake_context* ctx_out,
unsigned char *in_buffer,
uint16_t in_buffer_size,
unsigned char *out_buffer,
uint16_t out_buffer_size,
xtt_version version,
xtt_suite_spec suite_spec);

xtt_return_code_type
xtt_initialize_server_handshake_context(struct xtt_server_handshake_context* ctx_out,
unsigned char *in_buffer,
Expand Down Expand Up @@ -112,63 +122,79 @@ xtt_initialize_client_handshake_context(struct xtt_client_handshake_context* ctx
xtt_version version,
xtt_suite_spec suite_spec)
{
if (ctx_out == NULL)
return XTT_RETURN_NULL_BUFFER;
xtt_return_code_type common_ret = initialize_client_handshake_context_common(ctx_out,
in_buffer,
in_buffer_size,
out_buffer,
out_buffer_size,
version,
suite_spec);
if (XTT_RETURN_SUCCESS != common_ret)
return common_ret;

if (MAX_HANDSHAKE_SERVER_MESSAGE_LENGTH > in_buffer_size || MAX_HANDSHAKE_CLIENT_MESSAGE_LENGTH > out_buffer_size)
return XTT_RETURN_CONTEXT_BUFFER_OVERFLOW;

if (XTT_VERSION_ONE != version)
return XTT_RETURN_UNKNOWN_VERSION;

ctx_out->state = XTT_CLIENT_HANDSHAKE_STATE_START;

ctx_out->base.version = version;
ctx_out->base.suite_spec = suite_spec;
ctx_out->base.suite_ops = xtt_suite_ops_get(suite_spec);
if (NULL == ctx_out->base.suite_ops)
return XTT_RETURN_UNKNOWN_SUITE_SPEC;

ctx_out->base.in_buffer_start = in_buffer;
ctx_out->base.in_message_start = ctx_out->base.in_buffer_start;
ctx_out->base.in_end = ctx_out->base.in_buffer_start;
ctx_out->base.out_buffer_start = out_buffer;
ctx_out->base.out_message_start = ctx_out->base.out_buffer_start;
ctx_out->base.out_end = ctx_out->base.out_buffer_start;

xtt_crypto_hmac_init(&ctx_out->base.hash_out, ctx_out->base.suite_ops->hmac);
xtt_crypto_hmac_init(&ctx_out->base.inner_hash, ctx_out->base.suite_ops->hmac);
xtt_crypto_hmac_init(&ctx_out->base.prf_key, ctx_out->base.suite_ops->hmac);
xtt_crypto_hmac_init(&ctx_out->base.handshake_secret, ctx_out->base.suite_ops->hmac);
ctx_out->longterm_sign = longterm_sign_ecdsap256;

xtt_crypto_aead_key_init(&ctx_out->base.rx_key, ctx_out->base.suite_ops->aead);
xtt_crypto_aead_key_init(&ctx_out->base.tx_key, ctx_out->base.suite_ops->aead);
xtt_crypto_aead_nonce_init(&ctx_out->base.rx_iv, ctx_out->base.suite_ops->aead);
xtt_crypto_aead_nonce_init(&ctx_out->base.tx_iv, ctx_out->base.suite_ops->aead);
if (0 != xtt_crypto_create_ecdsap256_key_pair(&ctx_out->longterm_key.ecdsap256, &ctx_out->longterm_private_key.ecdsap256))
return XTT_RETURN_CRYPTO;

ctx_out->base.longterm_key_length = sizeof(xtt_ecdsap256_pub_key);
ctx_out->base.longterm_key_signature_length = sizeof(xtt_ecdsap256_signature);
return XTT_RETURN_SUCCESS;
}

ctx_out->base.tx_sequence_num = 0;
ctx_out->base.rx_sequence_num = 0;
#ifdef USE_TPM
xtt_return_code_type
xtt_initialize_client_handshake_context_TPM(struct xtt_client_handshake_context* ctx_out,
unsigned char *in_buffer,
uint16_t in_buffer_size,
unsigned char *out_buffer,
uint16_t out_buffer_size,
xtt_version version,
xtt_suite_spec suite_spec,
TPMI_RH_HIERARCHY hierarchy,
const char *hierarchy_password,
size_t hierarchy_password_length,
TPM2_HANDLE parent_handle,
TSS2_TCTI_CONTEXT *tcti_context)
{
xtt_return_code_type common_ret = initialize_client_handshake_context_common(ctx_out,
in_buffer,
in_buffer_size,
out_buffer,
out_buffer_size,
version,
suite_spec);
if (XTT_RETURN_SUCCESS != common_ret)
return common_ret;

ctx_out->hierarchy = hierarchy;

if (hierarchy_password_length > sizeof(ctx_out->hierarchy_password))
return XTT_RETURN_BAD_INIT;
memcpy(ctx_out->hierarchy_password,
hierarchy_password,
hierarchy_password_length);
ctx_out->hierarchy_password_length = hierarchy_password_length;

ctx_out->verify_server_signature = verify_server_signature_ecdsap256;
ctx_out->parent_handle = parent_handle;

ctx_out->copy_longterm_key = copy_longterm_key_ecdsap256;
ctx_out->tcti_context = tcti_context;

ctx_out->compare_longterm_keys = compare_longterm_keys_ecdsap256;
ctx_out->longterm_sign = longterm_sign_ecdsap256;
ctx_out->copy_in_my_pseudonym = copy_in_pseudonym_client_lrsw;
ctx_out->longterm_sign = longterm_sign_ecdsap256TPM;

if (0 != ctx_out->base.suite_ops->kx->keypair(&ctx_out->base.kx_pubkey,
&ctx_out->base.kx_seckey))
if (TSS2_RC_SUCCESS != xtpm_gen_key(ctx_out->tcti_context,
ctx_out->parent_handle,
ctx_out->hierarchy,
ctx_out->hierarchy_password,
ctx_out->hierarchy_password_length,
&ctx_out->longterm_private_key_tpm))
return XTT_RETURN_CRYPTO;

if (0 != xtt_crypto_create_ecdsap256_key_pair(&ctx_out->longterm_key.ecdsap256, &ctx_out->longterm_private_key.ecdsap256))
if (TSS2_RC_SUCCESS != xtpm_get_public_key(&ctx_out->longterm_private_key_tpm,
ctx_out->longterm_key.ecdsap256.data))
return XTT_RETURN_CRYPTO;

return XTT_RETURN_SUCCESS;
}
#endif

xtt_return_code_type
xtt_initialize_server_cookie_context(struct xtt_server_cookie_context* ctx)
Expand Down Expand Up @@ -414,3 +440,66 @@ xtt_get_my_pseudonym_lrsw(xtt_daa_pseudonym_lrsw *pseudonym_out,

return XTT_RETURN_SUCCESS;
}

xtt_return_code_type
initialize_client_handshake_context_common(struct xtt_client_handshake_context* ctx_out,
unsigned char *in_buffer,
uint16_t in_buffer_size,
unsigned char *out_buffer,
uint16_t out_buffer_size,
xtt_version version,
xtt_suite_spec suite_spec)
{
if (ctx_out == NULL)
return XTT_RETURN_NULL_BUFFER;

if (MAX_HANDSHAKE_SERVER_MESSAGE_LENGTH > in_buffer_size || MAX_HANDSHAKE_CLIENT_MESSAGE_LENGTH > out_buffer_size)
return XTT_RETURN_CONTEXT_BUFFER_OVERFLOW;

if (XTT_VERSION_ONE != version)
return XTT_RETURN_UNKNOWN_VERSION;

ctx_out->state = XTT_CLIENT_HANDSHAKE_STATE_START;

ctx_out->base.version = version;
ctx_out->base.suite_spec = suite_spec;
ctx_out->base.suite_ops = xtt_suite_ops_get(suite_spec);
if (NULL == ctx_out->base.suite_ops)
return XTT_RETURN_UNKNOWN_SUITE_SPEC;

ctx_out->base.in_buffer_start = in_buffer;
ctx_out->base.in_message_start = ctx_out->base.in_buffer_start;
ctx_out->base.in_end = ctx_out->base.in_buffer_start;
ctx_out->base.out_buffer_start = out_buffer;
ctx_out->base.out_message_start = ctx_out->base.out_buffer_start;
ctx_out->base.out_end = ctx_out->base.out_buffer_start;

xtt_crypto_hmac_init(&ctx_out->base.hash_out, ctx_out->base.suite_ops->hmac);
xtt_crypto_hmac_init(&ctx_out->base.inner_hash, ctx_out->base.suite_ops->hmac);
xtt_crypto_hmac_init(&ctx_out->base.prf_key, ctx_out->base.suite_ops->hmac);
xtt_crypto_hmac_init(&ctx_out->base.handshake_secret, ctx_out->base.suite_ops->hmac);

xtt_crypto_aead_key_init(&ctx_out->base.rx_key, ctx_out->base.suite_ops->aead);
xtt_crypto_aead_key_init(&ctx_out->base.tx_key, ctx_out->base.suite_ops->aead);
xtt_crypto_aead_nonce_init(&ctx_out->base.rx_iv, ctx_out->base.suite_ops->aead);
xtt_crypto_aead_nonce_init(&ctx_out->base.tx_iv, ctx_out->base.suite_ops->aead);

ctx_out->base.longterm_key_length = sizeof(xtt_ecdsap256_pub_key);
ctx_out->base.longterm_key_signature_length = sizeof(xtt_ecdsap256_signature);

ctx_out->base.tx_sequence_num = 0;
ctx_out->base.rx_sequence_num = 0;

ctx_out->verify_server_signature = verify_server_signature_ecdsap256;

ctx_out->copy_longterm_key = copy_longterm_key_ecdsap256;

ctx_out->compare_longterm_keys = compare_longterm_keys_ecdsap256;
ctx_out->copy_in_my_pseudonym = copy_in_pseudonym_client_lrsw;

if (0 != ctx_out->base.suite_ops->kx->keypair(&ctx_out->base.kx_pubkey,
&ctx_out->base.kx_seckey))
return XTT_RETURN_CRYPTO;

return XTT_RETURN_SUCCESS;
}
36 changes: 36 additions & 0 deletions src/internal/crypto_utils.c
Expand Up @@ -23,6 +23,11 @@
#include <xtt/daa_wrapper.h>
#include <xtt/certificates.h>

#ifdef USE_TPM
#include <xaptum-tpm.h>
#include <tss2/tss2_tpm2_types.h>
#endif

#include <stddef.h>
#include <string.h>
#include <assert.h>
Expand Down Expand Up @@ -95,6 +100,37 @@ int longterm_sign_ecdsap256(unsigned char *signature_out,
&self->longterm_private_key.ecdsap256);
}

#ifdef USE_TPM
int longterm_sign_ecdsap256TPM(unsigned char *signature_out,
const unsigned char *msg,
uint16_t msg_len,
const struct xtt_client_handshake_context *self)
{
TPM2B_DIGEST hash = {};
struct xtt_crypto_hmac xtt_hash = {};
if (0 != xtt_crypto_hash_sha256(&xtt_hash, msg, msg_len))
return XTT_RETURN_CRYPTO;
memcpy(hash.buffer, &xtt_hash.buf, sizeof(xtt_crypto_sha256));
hash.size = xtt_hash.len;

TPMT_SIGNATURE tpm_signature = {};
if (TSS2_RC_SUCCESS != xtpm_sign(self->tcti_context,
&self->longterm_private_key_tpm,
&hash,
&tpm_signature))
return XTT_RETURN_CRYPTO;

memcpy(signature_out,
&tpm_signature.signature.ecdsa.signatureR.buffer[0],
tpm_signature.signature.ecdsa.signatureR.size);
memcpy(&signature_out[tpm_signature.signature.ecdsa.signatureR.size],
tpm_signature.signature.ecdsa.signatureS.buffer,
tpm_signature.signature.ecdsa.signatureS.size);

return XTT_RETURN_SUCCESS;
}
#endif

int verify_root_ecdsap256(const unsigned char *signature, //equivalent to verify_signature
const struct xtt_server_certificate_raw_type *certificate,
const struct xtt_server_root_certificate_context *self)
Expand Down
7 changes: 7 additions & 0 deletions src/internal/crypto_utils.h
Expand Up @@ -59,6 +59,13 @@ int longterm_sign_ecdsap256(unsigned char *signature_out,
uint16_t msg_len,
const struct xtt_client_handshake_context *self);

#ifdef USE_TPM
int longterm_sign_ecdsap256TPM(unsigned char *signature_out,
const unsigned char *msg,
uint16_t msg_len,
const struct xtt_client_handshake_context *self);
#endif

int verify_root_ecdsap256(const unsigned char *signature,
const struct xtt_server_certificate_raw_type *certificate,
const struct xtt_server_root_certificate_context *self);
Expand Down

0 comments on commit 7088f12

Please sign in to comment.