123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /*
- * SPDX-License-Identifier: BSD-2-Clause
- * Copyright (c) 2019, Intel Corporation
- */
- #ifdef HAVE_CONFIG_H
- #include <config.h>
- #endif
- #include <inttypes.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "tss2_sys.h"
- #include "context-util.h"
- #include "sys-util.h"
- #include "session-util.h"
- #define LOGMODULE test
- #include "util/log.h"
- #define TPM20_INDEX_PASSWORD_TEST 0x01500020
- #define NV_DATA_SIZE 4
- #define NV_DATA { 0x00, 0xff, 0x55, 0xaa }
- #define SECRET_SIZE 13
- #define SECRET_DATA { 's', 'h', 'a', 'r', 'e', 'd', ' ', \
- 's', 'e', 'c', 'r', 'e', 't', }
- TSS2_RC
- create_policy (TSS2_SYS_CONTEXT *sys_ctx,
- TPM2B_DIGEST *authPolicy)
- {
- TSS2_RC rc;
- SESSION *trialPolicySession = NULL;
- TPM2B_NONCE nonceCaller = { 0, };
- TPM2B_ENCRYPTED_SECRET encryptedSalt = { 0, };
- TPMT_SYM_DEF symmetric = {
- .algorithm = TPM2_ALG_NULL,
- };
- TSS2_TCTI_CONTEXT *tcti_ctx;
- rc = Tss2_Sys_GetTctiContext (sys_ctx, &tcti_ctx);
- if (rc != TSS2_RC_SUCCESS || tcti_ctx == NULL) {
- LOG_ERROR("InitSysContext failed, exiting...");
- return rc;
- }
- rc = create_auth_session (&trialPolicySession,
- TPM2_RH_NULL,
- 0,
- TPM2_RH_NULL,
- 0,
- &nonceCaller,
- &encryptedSalt,
- TPM2_SE_TRIAL,
- &symmetric,
- TPM2_ALG_SHA256,
- tcti_ctx);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("create_auth_session failed with rc: 0x%x", rc);
- return rc;
- }
- rc = Tss2_Sys_PolicyAuthValue (sys_ctx,
- trialPolicySession->sessionHandle,
- 0,
- 0);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_PolicyAuthValue failed with rc: 0x%x", rc);
- return rc;
- }
- rc = Tss2_Sys_PolicyGetDigest (sys_ctx,
- trialPolicySession->sessionHandle,
- 0,
- authPolicy,
- 0);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_PolicyGetDigest failed with rc: 0x%x", rc);
- return rc;
- }
- rc = Tss2_Sys_FlushContext (sys_ctx,
- trialPolicySession->sessionHandle);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_FlushContext failed with rc: 0x%x", rc);
- return rc;
- }
- end_auth_session (trialPolicySession);
- return rc;
- }
- TSS2_RC
- nv_rw_with_session (
- TSS2_SYS_CONTEXT *sys_ctx,
- const TPM2B_DIGEST *authPolicy,
- TPMA_NV nvAttributes,
- TPM2_SE session_type)
- {
- TSS2_RC rc;
- TPM2B_AUTH nvAuth = {
- .size = SECRET_SIZE,
- .buffer = SECRET_DATA,
- };
- SESSION *nvSession = NULL;
- TPM2B_NAME nvName;
- TPM2B_NONCE nonceCaller = { 0, };
- TPM2B_MAX_NV_BUFFER nvWriteData = {
- .size = NV_DATA_SIZE,
- .buffer = NV_DATA,
- };
- TPM2B_MAX_NV_BUFFER nvReadData = { .size = TPM2B_SIZE (nvReadData), };
- TPM2B_ENCRYPTED_SECRET encryptedSalt = { 0, };
- TPMT_SYM_DEF symmetric = {
- .algorithm = TPM2_ALG_NULL,
- };
- TSS2_TCTI_CONTEXT *tcti_ctx;
- TSS2L_SYS_AUTH_RESPONSE nvRspAuths;
- TSS2L_SYS_AUTH_COMMAND nvCmdAuths = {
- .count = 1,
- .auths= {
- {
- .nonce = {
- .size = 1,
- .buffer = { 0xa5, },
- },
- .sessionHandle = TPM2_RH_PW,
- .sessionAttributes = TPMA_SESSION_CONTINUESESSION,
- }
- }
- };
- const TSS2L_SYS_AUTH_COMMAND auth_cmd_null_pwd = {
- .count = 1,
- .auths = {
- {
- .sessionHandle = TPM2_RH_PW,
- },
- },
- };
- rc = Tss2_Sys_GetTctiContext (sys_ctx, &tcti_ctx);
- if (rc != TSS2_RC_SUCCESS || tcti_ctx == NULL) {
- LOG_ERROR ("Failed to get TCTI from Sys context, got RC: 0x%x", rc);
- return TSS2_SYS_RC_GENERAL_FAILURE;
- }
- rc = DefineNvIndex (sys_ctx,
- TPM2_RH_PLATFORM,
- &nvAuth,
- authPolicy,
- TPM20_INDEX_PASSWORD_TEST,
- TPM2_ALG_SHA256,
- nvAttributes,
- 32);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("DefineNvIndex failed with RC: 0x%x", rc);
- return rc;
- }
- /*
- * Add index and associated authorization value to
- * entity table. This helps when we need
- * to calculate HMACs.
- */
- rc = AddEntity(TPM20_INDEX_PASSWORD_TEST, &nvAuth);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("AddEntity failed with RC: 0x%x", rc);
- return rc;
- }
- /* Get the name of the NV index. */
- rc = tpm_handle_to_name (tcti_ctx,
- TPM20_INDEX_PASSWORD_TEST,
- &nvName);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("tpm_handle_to_name failed with RC: 0x%x", rc);
- return rc;
- }
- /*
- * Start HMAC or real (non-trial) policy authorization session:
- * it's an unbound and unsalted session, no symmetric
- * encryption algorithm, and SHA256 is the session's
- * hash algorithm.
- */
- rc = create_auth_session (&nvSession,
- TPM2_RH_NULL,
- 0,
- TPM2_RH_NULL,
- 0,
- &nonceCaller,
- &encryptedSalt,
- session_type,
- &symmetric,
- TPM2_ALG_SHA256,
- tcti_ctx);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("create_auth_session failed with RC: 0x%x", rc);
- return rc;
- }
- /* set handle in command auth */
- nvCmdAuths.auths[0].sessionHandle = nvSession->sessionHandle;
- /*
- * Get the name of the session and save it in
- * the nvSession structure.
- */
- rc = tpm_handle_to_name (tcti_ctx,
- nvSession->sessionHandle,
- &nvSession->name);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("tpm_handle_to_name failed with RC: 0x%x", rc);
- return rc;
- }
- /*
- * Now setup for writing the NV index.
- */
- if (session_type == TPM2_SE_POLICY) {
- rc = Tss2_Sys_PolicyAuthValue (sys_ctx,
- nvSession->sessionHandle,
- 0,
- 0);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_PolicyAuthValue failed with RC: 0x%x", rc);
- return rc;
- }
- }
- /* First call prepare in order to create cpBuffer. */
- rc = Tss2_Sys_NV_Write_Prepare (sys_ctx,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- &nvWriteData,
- 0);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_NV_Write_Prepare failed with RC: 0x%x", rc);
- return rc;
- }
- /* Roll nonces for command */
- roll_nonces (nvSession, &nvCmdAuths.auths[0].nonce);
- /*
- * Complete command authorization area, by computing
- * HMAC and setting it in nvCmdAuths.
- */
- rc = compute_command_hmac(sys_ctx,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- TPM2_RH_NULL,
- &nvCmdAuths);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("compute_command_hmac failed with RC: 0x%x", rc);
- return rc;
- }
- /*
- * Finally!! Write the data to the NV index.
- * If the command is successful, the command
- * HMAC was correct.
- */
- rc = TSS2_RETRY_EXP (Tss2_Sys_NV_Write (sys_ctx,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- &nvCmdAuths,
- &nvWriteData,
- 0,
- &nvRspAuths));
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_NV_Write failed with RC: 0x%x", rc);
- return rc;
- }
- /* Roll nonces for response */
- roll_nonces (nvSession, &nvRspAuths.auths[0].nonce);
- /*
- * If the command was successful, check the
- * response HMAC to make sure that the
- * response was received correctly.
- */
- rc = check_response_hmac (sys_ctx,
- &nvCmdAuths,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- TPM2_RH_NULL,
- &nvRspAuths);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("check_response_hmac failed with RC: 0x%x", rc);
- return rc;
- }
- if (session_type == TPM2_SE_POLICY) {
- rc = Tss2_Sys_PolicyAuthValue (sys_ctx,
- nvSession->sessionHandle,
- 0,
- 0);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_PolicyAuthValue failed with RC: 0x%x", rc);
- return rc;
- }
- }
- /* First call prepare in order to create cpBuffer. */
- rc = Tss2_Sys_NV_Read_Prepare (sys_ctx,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- NV_DATA_SIZE,
- 0);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_NV_Read_Prepare failed with RC: 0x%x", rc);
- return rc;
- }
- roll_nonces (nvSession, &nvCmdAuths.auths[0].nonce);
- /* End the session after next command. */
- nvCmdAuths.auths[0].sessionAttributes &= ~TPMA_SESSION_CONTINUESESSION;
- /*
- * Complete command authorization area, by computing
- * HMAC and setting it in nvCmdAuths.
- */
- rc = compute_command_hmac (sys_ctx,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- TPM2_RH_NULL,
- &nvCmdAuths);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("compute_command_hmac failed with RC: 0x%x", rc);
- return rc;
- }
- /*
- * And now read the data back.
- * If the command is successful, the command
- * HMAC was correct.
- */
- rc = Tss2_Sys_NV_Read (sys_ctx,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- &nvCmdAuths,
- NV_DATA_SIZE,
- 0,
- &nvReadData,
- &nvRspAuths);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_NV_Read failed with RC: 0x%x", rc);
- return rc;
- }
- /* Roll nonces for response */
- roll_nonces (nvSession, &nvRspAuths.auths[0].nonce);
- /*
- * If the command was successful, check the
- * response HMAC to make sure that the
- * response was received correctly.
- */
- rc = check_response_hmac (sys_ctx,
- &nvCmdAuths,
- TPM20_INDEX_PASSWORD_TEST,
- TPM20_INDEX_PASSWORD_TEST,
- TPM2_RH_NULL,
- &nvRspAuths);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("check_response_hmac failed with RC: 0x%x", rc);
- return rc;
- }
- /* Check that write and read data are equal. */
- if (memcmp ((void *)&nvReadData.buffer[0],
- (void *)&nvWriteData.buffer[0],
- nvReadData.size))
- {
- LOG_ERROR ("Data read not equal to data written.");
- return 1;
- }
- /*
- * Now cleanup: undefine the NV index and delete
- * the NV index's entity table entry.
- */
- /* Undefine the NV index. */
- rc = Tss2_Sys_NV_UndefineSpace (sys_ctx,
- TPM2_RH_PLATFORM,
- TPM20_INDEX_PASSWORD_TEST,
- &auth_cmd_null_pwd,
- 0);
- if (rc != TSS2_RC_SUCCESS) {
- LOG_ERROR ("Tss2_Sys_NV_UndefineSpace failed with RC: 0x%x", rc);
- return rc;
- }
- /* Delete the NV index's entry in the entity table. */
- DeleteEntity (TPM20_INDEX_PASSWORD_TEST);
- /* Remove the real session from sessions table. */
- end_auth_session (nvSession);
- return rc;
- }
- int
- test_invoke (TSS2_SYS_CONTEXT *sys_ctx)
- {
- TSS2_RC rc;
- TPM2B_DIGEST authPolicy = { 0, };
- TPMA_NV nvAttributes;
- LOG_INFO ("HMAC session test");
- nvAttributes = TPMA_NV_AUTHREAD | TPMA_NV_AUTHWRITE | TPMA_NV_PLATFORMCREATE;
- rc = nv_rw_with_session (sys_ctx, &authPolicy, nvAttributes, TPM2_SE_HMAC);
- if (rc != TSS2_RC_SUCCESS)
- return rc;
- LOG_INFO ("Policy session test");
- authPolicy.size = TPM2B_SIZE (authPolicy);
- rc = create_policy (sys_ctx, &authPolicy);
- if (rc != TSS2_RC_SUCCESS)
- return rc;
- nvAttributes = TPMA_NV_POLICYREAD | TPMA_NV_POLICYWRITE | TPMA_NV_PLATFORMCREATE;
- rc = nv_rw_with_session (sys_ctx, &authPolicy, nvAttributes, TPM2_SE_POLICY);
- if (rc != TSS2_RC_SUCCESS)
- return rc;
- return TSS2_RC_SUCCESS;
- }
|