libtpmtss: Some minor improvements
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#ifdef TSS_TSS2_V2
|
#ifdef TSS_TSS2_V2
|
||||||
|
|
||||||
#include "tpm_tss_tss2_session.h"
|
#include "tpm_tss_tss2_session.h"
|
||||||
|
#include "tpm_tss_tss2_names.h"
|
||||||
|
|
||||||
#define LABEL "TPM 2.0 - "
|
#define LABEL "TPM 2.0 - "
|
||||||
|
|
||||||
@@ -56,9 +57,9 @@ struct private_tpm_tss_tss2_session_t {
|
|||||||
TPM2B_NONCE nonceTPM;
|
TPM2B_NONCE nonceTPM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AES-CFB encryption of protected communication with TPM 2.0
|
* AES-CFB key size in bytes
|
||||||
*/
|
*/
|
||||||
crypter_t *crypter;
|
size_t aes_key_len;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SYS context
|
* SYS context
|
||||||
@@ -314,6 +315,7 @@ METHOD(tpm_tss_tss2_session_t, get_rsp_auths, bool,
|
|||||||
hasher_t *hasher;
|
hasher_t *hasher;
|
||||||
pseudo_random_function_t prf_alg;
|
pseudo_random_function_t prf_alg;
|
||||||
prf_t *prf;
|
prf_t *prf;
|
||||||
|
crypter_t *crypter;
|
||||||
chunk_t kdf_label = chunk_from_chars('C','F','B', 0x00);
|
chunk_t kdf_label = chunk_from_chars('C','F','B', 0x00);
|
||||||
chunk_t data, rp_hash, rp_hmac, nonce_caller, nonce_tpm, session_attributes;
|
chunk_t data, rp_hash, rp_hmac, nonce_caller, nonce_tpm, session_attributes;
|
||||||
chunk_t key_mat, aes_key, aes_iv;
|
chunk_t key_mat, aes_key, aes_iv;
|
||||||
@@ -426,8 +428,17 @@ METHOD(tpm_tss_tss2_session_t, get_rsp_auths, bool,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
key_len = this->crypter->get_key_size(this->crypter);
|
crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CFB,
|
||||||
iv_len = this->crypter->get_iv_size(this->crypter);
|
this->aes_key_len);
|
||||||
|
if (!crypter)
|
||||||
|
{
|
||||||
|
DBG1(DBG_PTS, "could not create %N crypter", encryption_algorithm_names,
|
||||||
|
ENCR_AES_CFB);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
key_len = crypter->get_key_size(crypter);
|
||||||
|
iv_len = crypter->get_iv_size(crypter);
|
||||||
|
|
||||||
/* derive decryption key using KDFa */
|
/* derive decryption key using KDFa */
|
||||||
if (!kdf_a(this->hash_alg, this->session_key, kdf_label, nonce_tpm,
|
if (!kdf_a(this->hash_alg, this->session_key, kdf_label, nonce_tpm,
|
||||||
@@ -438,8 +449,9 @@ METHOD(tpm_tss_tss2_session_t, get_rsp_auths, bool,
|
|||||||
aes_key = chunk_create(key_mat.ptr, key_len);
|
aes_key = chunk_create(key_mat.ptr, key_len);
|
||||||
aes_iv = chunk_create(key_mat.ptr + key_len, iv_len);
|
aes_iv = chunk_create(key_mat.ptr + key_len, iv_len);
|
||||||
|
|
||||||
if (!this->crypter->set_key(this->crypter, aes_key))
|
if (!crypter->set_key(crypter, aes_key))
|
||||||
{
|
{
|
||||||
|
crypter->destroy(crypter);
|
||||||
chunk_clear(&key_mat);
|
chunk_clear(&key_mat);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -449,7 +461,8 @@ METHOD(tpm_tss_tss2_session_t, get_rsp_auths, bool,
|
|||||||
memcpy(data.ptr, param_buffer, param_size);
|
memcpy(data.ptr, param_buffer, param_size);
|
||||||
|
|
||||||
/* decrypt ciphertext */
|
/* decrypt ciphertext */
|
||||||
success = this->crypter->decrypt(this->crypter, data, aes_iv, NULL);
|
success = crypter->decrypt(crypter, data, aes_iv, NULL);
|
||||||
|
crypter->destroy(crypter);
|
||||||
chunk_clear(&key_mat);
|
chunk_clear(&key_mat);
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
@@ -487,7 +500,6 @@ METHOD(tpm_tss_tss2_session_t, destroy, void,
|
|||||||
}
|
}
|
||||||
chunk_clear(&this->session_key);
|
chunk_clear(&this->session_key);
|
||||||
}
|
}
|
||||||
DESTROY_IF(this->crypter);
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,8 +757,7 @@ tpm_tss_tss2_session_t* tpm_tss_tss2_session_create(uint32_t ek_handle,
|
|||||||
|
|
||||||
TPM2B_ENCRYPTED_SECRET encryptedSalt;
|
TPM2B_ENCRYPTED_SECRET encryptedSalt;
|
||||||
TPM2_SE sessionType = TPM2_SE_HMAC;
|
TPM2_SE sessionType = TPM2_SE_HMAC;
|
||||||
TPMT_SYM_DEF symmetric = { .algorithm = TPM2_ALG_AES,
|
TPMT_SYM_DEF *sym;
|
||||||
.mode.aes = TPM2_ALG_CFB, .keyBits.aes = 128 };
|
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
@@ -760,15 +771,6 @@ tpm_tss_tss2_session_t* tpm_tss_tss2_session_create(uint32_t ek_handle,
|
|||||||
|
|
||||||
hash_len = hash_len_from_tpm_alg_id(this->hash_alg);
|
hash_len = hash_len_from_tpm_alg_id(this->hash_alg);
|
||||||
|
|
||||||
this->crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_CFB,
|
|
||||||
symmetric.keyBits.aes / 8);
|
|
||||||
if (!this->crypter)
|
|
||||||
{
|
|
||||||
DBG1(DBG_PTS, "could not create %N crypter", encryption_algorithm_names,
|
|
||||||
ENCR_AES_CFB);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!generate_nonce(hash_len, &this->nonceCaller))
|
if (!generate_nonce(hash_len, &this->nonceCaller))
|
||||||
{
|
{
|
||||||
goto error;
|
goto error;
|
||||||
@@ -785,7 +787,8 @@ tpm_tss_tss2_session_t* tpm_tss_tss2_session_create(uint32_t ek_handle,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TPM2_ALG_ECC:
|
case TPM2_ALG_ECC:
|
||||||
DBG1(DBG_PTS, LABEL "ECC EK handle: 0x%08x", ek_handle);
|
DBG1(DBG_PTS, LABEL "ECC %N EK handle: 0x%08x", tpm_ecc_curve_names,
|
||||||
|
public->publicArea.parameters.eccDetail.curveID, ek_handle);
|
||||||
if (!ecc_salt(public, this->hash_alg, &secret, &encryptedSalt))
|
if (!ecc_salt(public, this->hash_alg, &secret, &encryptedSalt))
|
||||||
{
|
{
|
||||||
goto error;
|
goto error;
|
||||||
@@ -796,8 +799,12 @@ tpm_tss_tss2_session_t* tpm_tss_tss2_session_create(uint32_t ek_handle,
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sym = (TPMT_SYM_DEF*)&public->publicArea.parameters.asymDetail.symmetric;
|
||||||
|
DBG2(DBG_PTS, LABEL "AES-CFB with %u bits", sym->keyBits.aes);
|
||||||
|
this->aes_key_len = sym->keyBits.aes / 8;
|
||||||
|
|
||||||
rval = Tss2_Sys_StartAuthSession(this->sys_context, ek_handle, TPM2_RH_NULL,
|
rval = Tss2_Sys_StartAuthSession(this->sys_context, ek_handle, TPM2_RH_NULL,
|
||||||
NULL, &this->nonceCaller, &encryptedSalt, sessionType, &symmetric,
|
NULL, &this->nonceCaller, &encryptedSalt, sessionType, sym,
|
||||||
this->hash_alg, &this->session_handle, &this->nonceTPM, NULL);
|
this->hash_alg, &this->session_handle, &this->nonceTPM, NULL);
|
||||||
if (rval != TSS2_RC_SUCCESS)
|
if (rval != TSS2_RC_SUCCESS)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -572,7 +572,6 @@ METHOD(tpm_tss_t, get_public, chunk_t,
|
|||||||
private_tpm_tss_tss2_t *this, uint32_t handle)
|
private_tpm_tss_tss2_t *this, uint32_t handle)
|
||||||
{
|
{
|
||||||
TPM2B_PUBLIC public = { 0, };
|
TPM2B_PUBLIC public = { 0, };
|
||||||
TPM2_ALG_ID sig_alg, digest_alg;
|
|
||||||
chunk_t aik_pubkey = chunk_empty;
|
chunk_t aik_pubkey = chunk_empty;
|
||||||
|
|
||||||
if (!read_public(this, handle, &public))
|
if (!read_public(this, handle, &public))
|
||||||
@@ -586,15 +585,10 @@ METHOD(tpm_tss_t, get_public, chunk_t,
|
|||||||
case TPM2_ALG_RSA:
|
case TPM2_ALG_RSA:
|
||||||
{
|
{
|
||||||
TPM2B_PUBLIC_KEY_RSA *rsa;
|
TPM2B_PUBLIC_KEY_RSA *rsa;
|
||||||
TPMT_RSA_SCHEME *scheme;
|
|
||||||
chunk_t aik_exponent = chunk_from_chars(0x01, 0x00, 0x01);
|
chunk_t aik_exponent = chunk_from_chars(0x01, 0x00, 0x01);
|
||||||
chunk_t aik_modulus;
|
chunk_t aik_modulus;
|
||||||
uint32_t exponent;
|
uint32_t exponent;
|
||||||
|
|
||||||
scheme = &public.publicArea.parameters.rsaDetail.scheme;
|
|
||||||
sig_alg = scheme->scheme;
|
|
||||||
digest_alg = scheme->details.anySig.hashAlg;
|
|
||||||
|
|
||||||
rsa = &public.publicArea.unique.rsa;
|
rsa = &public.publicArea.unique.rsa;
|
||||||
aik_modulus = chunk_create(rsa->buffer, rsa->size);
|
aik_modulus = chunk_create(rsa->buffer, rsa->size);
|
||||||
exponent = htonl(public.publicArea.parameters.rsaDetail.exponent);
|
exponent = htonl(public.publicArea.parameters.rsaDetail.exponent);
|
||||||
@@ -617,13 +611,32 @@ METHOD(tpm_tss_t, get_public, chunk_t,
|
|||||||
case TPM2_ALG_ECC:
|
case TPM2_ALG_ECC:
|
||||||
{
|
{
|
||||||
TPMS_ECC_POINT *ecc;
|
TPMS_ECC_POINT *ecc;
|
||||||
TPMT_ECC_SCHEME *scheme;
|
|
||||||
chunk_t ecc_point;
|
chunk_t ecc_point;
|
||||||
|
int curve_oid;
|
||||||
uint8_t *pos;
|
uint8_t *pos;
|
||||||
|
|
||||||
scheme = &public.publicArea.parameters.eccDetail.scheme;
|
/* determine ECC curveID */
|
||||||
sig_alg = scheme->scheme;
|
switch (public.publicArea.parameters.eccDetail.curveID)
|
||||||
digest_alg = scheme->details.anySig.hashAlg;
|
{
|
||||||
|
case TPM2_ECC_NIST_P192:
|
||||||
|
curve_oid = OID_PRIME192V1;
|
||||||
|
break;
|
||||||
|
case TPM2_ECC_NIST_P224:
|
||||||
|
curve_oid = OID_SECT224R1;
|
||||||
|
break;
|
||||||
|
case TPM2_ECC_NIST_P256:
|
||||||
|
curve_oid = OID_PRIME256V1;
|
||||||
|
break;
|
||||||
|
case TPM2_ECC_NIST_P384:
|
||||||
|
curve_oid = OID_SECT384R1;
|
||||||
|
break;
|
||||||
|
case TPM2_ECC_NIST_P521:
|
||||||
|
curve_oid = OID_SECT521R1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DBG1(DBG_PTS, "ECC curve type not supported");
|
||||||
|
return chunk_empty;
|
||||||
|
}
|
||||||
|
|
||||||
ecc = &public.publicArea.unique.ecc;
|
ecc = &public.publicArea.unique.ecc;
|
||||||
|
|
||||||
@@ -639,12 +652,12 @@ METHOD(tpm_tss_t, get_public, chunk_t,
|
|||||||
pos += ecc->x.size;
|
pos += ecc->x.size;
|
||||||
/* copy y coordinate of ECC point */
|
/* copy y coordinate of ECC point */
|
||||||
memcpy(pos, ecc->y.buffer, ecc->y.size);
|
memcpy(pos, ecc->y.buffer, ecc->y.size);
|
||||||
|
|
||||||
/* subjectPublicKeyInfo encoding of ECC public key */
|
/* subjectPublicKeyInfo encoding of ECC public key */
|
||||||
aik_pubkey = asn1_wrap(ASN1_SEQUENCE, "mm",
|
aik_pubkey = asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
asn1_wrap(ASN1_SEQUENCE, "mm",
|
asn1_wrap(ASN1_SEQUENCE, "mm",
|
||||||
asn1_build_known_oid(OID_EC_PUBLICKEY),
|
asn1_build_known_oid(OID_EC_PUBLICKEY),
|
||||||
asn1_build_known_oid(ecc->x.size == 32 ?
|
asn1_build_known_oid(curve_oid)),
|
||||||
OID_PRIME256V1 : OID_SECT384R1)),
|
|
||||||
ecc_point);
|
ecc_point);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -652,8 +665,25 @@ METHOD(tpm_tss_t, get_public, chunk_t,
|
|||||||
DBG1(DBG_PTS, LABEL "unsupported key type");
|
DBG1(DBG_PTS, LABEL "unsupported key type");
|
||||||
return chunk_empty;
|
return chunk_empty;
|
||||||
}
|
}
|
||||||
DBG1(DBG_PTS, "signature algorithm is %N with %N hash",
|
if (public.publicArea.objectAttributes & TPMA_OBJECT_SIGN_ENCRYPT)
|
||||||
tpm_alg_id_names, sig_alg, tpm_alg_id_names, digest_alg);
|
{
|
||||||
|
TPMT_ASYM_SCHEME *s;
|
||||||
|
|
||||||
|
s = &public.publicArea.parameters.asymDetail.scheme;
|
||||||
|
DBG1(DBG_PTS, "signature algorithm is %N with %N hash",
|
||||||
|
tpm_alg_id_names, s->scheme,
|
||||||
|
tpm_alg_id_names, s->details.anySig.hashAlg);
|
||||||
|
}
|
||||||
|
if (public.publicArea.objectAttributes & TPMA_OBJECT_DECRYPT)
|
||||||
|
{
|
||||||
|
TPMT_SYM_DEF_OBJECT *s;
|
||||||
|
|
||||||
|
s = &public.publicArea.parameters.asymDetail.symmetric;
|
||||||
|
DBG1(DBG_PTS, "encryption algorithm is %N-%N with %u bits",
|
||||||
|
tpm_alg_id_names, s->algorithm,
|
||||||
|
tpm_alg_id_names, s->mode, s->keyBits.sym);
|
||||||
|
}
|
||||||
|
|
||||||
return aik_pubkey;
|
return aik_pubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user