/* * SPDX-License-Identifier: BSD-2-Clause * Copyright (c) 2019, Intel Corporation */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "tss2_sys.h" #include "context-util.h" #include "sapi-util.h" #include "session-util.h" #include "util/aux_util.h" #define LOGMODULE test #include "util/log.h" #define NV_PS_INDEX_SIZE 34 #define INDEX_LCP_OWN 0x01400001 #define INDEX_LCP_SUP 0x01800001 #define TPM2B_SIZE_MAX(type) (sizeof (type) - 2) const TSS2L_SYS_AUTH_COMMAND auth_cmd_null_pwd = { .count = 1, .auths = { { .sessionHandle = TPM2_RS_PW, }, }, }; static TSS2_RC create_policy_session ( TSS2_SYS_CONTEXT *sys_ctx, TPMI_SH_AUTH_SESSION *handle) { TSS2_RC rc; TPM2B_ENCRYPTED_SECRET salt = { 0 }; TPM2B_NONCE nonce = { .size = GetDigestSize (TPM2_ALG_SHA1), }; TPM2B_NONCE nonce_tpm = { 0, }; TPMT_SYM_DEF symmetric = { .algorithm = TPM2_ALG_NULL, }; rc = Tss2_Sys_StartAuthSession (sys_ctx, TPM2_RH_NULL, TPM2_RH_NULL, 0, &nonce, &salt, TPM2_SE_POLICY, &symmetric, TPM2_ALG_SHA1, handle, &nonce_tpm, 0); return_if_error (rc, "Tss2_Sys_StartAuthSession"); return TSS2_RC_SUCCESS; } static TSS2_RC setup_nv (TSS2_SYS_CONTEXT *sys_ctx, TPMI_RH_NV_INDEX index) { TSS2_RC rc; TPMI_SH_AUTH_SESSION auth_handle; TPM2B_DIGEST policy_hash = { .size = TPM2B_SIZE_MAX (policy_hash), }; TPM2B_AUTH nv_auth = { 0, }; TSS2L_SYS_AUTH_RESPONSE auth_rsp; TPM2B_NV_PUBLIC public_info = { .nvPublic = { .nameAlg = TPM2_ALG_SHA1, .attributes = TPMA_NV_AUTHREAD | TPMA_NV_AUTHWRITE | TPMA_NV_PLATFORMCREATE | TPMA_NV_WRITEDEFINE | TPMA_NV_ORDERLY, .dataSize = NV_PS_INDEX_SIZE, .nvIndex = index, }, }; rc = create_policy_session (sys_ctx, &auth_handle); return_if_error (rc, "create_policy_session"); rc = Tss2_Sys_PolicyGetDigest (sys_ctx, auth_handle, 0, &policy_hash, 0); return_if_error (rc, "Tss2_Sys_PolicyGetDigest"); LOGBLOB_INFO (policy_hash.buffer, policy_hash.size, "policy_hash"); rc = Tss2_Sys_NV_DefineSpace (sys_ctx, TPM2_RH_PLATFORM, &auth_cmd_null_pwd, &nv_auth, &public_info, &auth_rsp); return_if_error (rc, "Tss2_Sys_NV_DefineSpace"); rc = Tss2_Sys_FlushContext (sys_ctx, auth_handle); return_if_error (rc, "Tss2_Sys_FlushContext"); return TSS2_RC_SUCCESS; } static TSS2_RC nv_write_read_test (TSS2_SYS_CONTEXT *sys_ctx, TPMI_RH_NV_INDEX index) { TSS2_RC rc; TPM2B_MAX_NV_BUFFER write_data = { .size = 4, .buffer = { 0xde, 0xad, 0xbe, 0xef }, }; TPM2B_MAX_NV_BUFFER nv_buf = { 0, }; TSS2L_SYS_AUTH_RESPONSE auth_resp = { 0, }; rc = TSS2_RETRY_EXP (Tss2_Sys_NV_Write (sys_ctx, index, index, &auth_cmd_null_pwd, &write_data, 0, &auth_resp)); return_if_error (rc, "Tss2_Sys_NV_Write"); rc = Tss2_Sys_NV_Read (sys_ctx, index, index, &auth_cmd_null_pwd, 4, 0, &nv_buf, &auth_resp); return_if_error (rc, "Tss2_Sys_NV_Read"); if (memcmp (nv_buf.buffer, write_data.buffer, write_data.size) != 0) { LOG_ERROR ("%s: data read from NV is different from data written", __func__); LOGBLOB_DEBUG (write_data.buffer, write_data.size, "write_data"); LOGBLOB_DEBUG (nv_buf.buffer, nv_buf.size, "nv_buf"); return 1; } return TSS2_RC_SUCCESS; } static TSS2_RC teardown_nv (TSS2_SYS_CONTEXT *sys_ctx, TPMI_RH_NV_INDEX index) { TSS2_RC rc; TSS2L_SYS_AUTH_RESPONSE auth_resp = { 0, }; rc = Tss2_Sys_NV_UndefineSpace (sys_ctx, TPM2_RH_PLATFORM, index, &auth_cmd_null_pwd, &auth_resp); return_if_error (rc, "Tss2_Sys_NV_UndefineSpace"); return TSS2_RC_SUCCESS; } int test_invoke (TSS2_SYS_CONTEXT *sys_ctx) { TSS2_RC rc, rc_teardown; rc = setup_nv (sys_ctx, INDEX_LCP_OWN); return_if_error (rc, "setup_nv for INDEX_LCP_OWN"); rc = nv_write_read_test (sys_ctx, INDEX_LCP_OWN); LOG_ERROR ("nv_write_read_test for INDEX_LCP_OWN"); rc_teardown = teardown_nv (sys_ctx, INDEX_LCP_OWN); return_if_error (rc, "INDEX_LCP_OWN test"); return_if_error (rc_teardown, "teardown_nv for INDEX_LCP_OWN"); rc = setup_nv (sys_ctx, INDEX_LCP_SUP); return_if_error (rc, "setup_nv for INDEX_LCP_SUP"); rc = nv_write_read_test (sys_ctx, INDEX_LCP_SUP); LOG_ERROR ("nv_write_read_test for INDEX_LCP_SUP"); rc_teardown = teardown_nv (sys_ctx, INDEX_LCP_SUP); return_if_error (rc, "INDEX_LCP_SUP test"); return_if_error (rc_teardown, "teardown_nv for INDEX_LCP_SUP"); return 0; }