blob: 9a96842f634a9ba5fe0c6a22302bf66a04b85588 [file] [log] [blame]
Will Arthur54e04e42015-07-15 11:29:25 -04001//**********************************************************************;
2// Copyright (c) 2015, Intel Corporation
3// All rights reserved.
Philip Tricca1ea84a52015-11-19 18:07:06 -08004//
5// Redistribution and use in source and binary forms, with or without
Will Arthur54e04e42015-07-15 11:29:25 -04006// modification, are permitted provided that the following conditions are met:
Philip Tricca1ea84a52015-11-19 18:07:06 -08007//
8// 1. Redistributions of source code must retain the above copyright notice,
Will Arthur54e04e42015-07-15 11:29:25 -04009// this list of conditions and the following disclaimer.
Philip Tricca1ea84a52015-11-19 18:07:06 -080010//
11// 2. Redistributions in binary form must reproduce the above copyright notice,
12// this list of conditions and the following disclaimer in the documentation
Will Arthur54e04e42015-07-15 11:29:25 -040013// and/or other materials provided with the distribution.
Philip Tricca1ea84a52015-11-19 18:07:06 -080014//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
Will Arthur54e04e42015-07-15 11:29:25 -040025// THE POSSIBILITY OF SUCH DAMAGE.
26//**********************************************************************;
27
Philip Triccadd3b03c2017-03-05 11:38:08 -080028#include "sapi/tpm20.h"
Will Arthur54e04e42015-07-15 11:29:25 -040029#include "sample.h"
30#include <stdio.h>
31#include <stdlib.h>
Philip Triccac3dedc22016-01-15 13:47:22 -080032#include "sysapi_util.h"
Tadeusz Struk8203a372017-06-26 15:15:18 -070033#include "tss2_endian.h"
Will Arthur54e04e42015-07-15 11:29:25 -040034
Will Arthur54e04e42015-07-15 11:29:25 -040035//
36// This function is a helper function used to calculate cpHash and rpHash.
37//
38// NOTE: for calculating cpHash, set responseCode to TPM_RC_NO_RESPONSE; this
39// tells the function to leave it out of the calculation.
40//
41TPM_RC TpmCalcPHash( TSS2_SYS_CONTEXT *sysContext, TPM_HANDLE handle1, TPM_HANDLE handle2,
42 TPMI_ALG_HASH authHash, TPM_RC responseCode, TPM2B_DIGEST *pHash )
43{
44 TPM_RC rval = TPM_RC_SUCCESS;
45 UINT32 i;
46 TPM2B_NAME name1;
47 TPM2B_NAME name2;
48 TPM2B_MAX_BUFFER hashInput; // Byte stream to be hashed to create pHash
49 UINT8 *hashInputPtr;
50 size_t parametersSize;
51 const uint8_t *startParams;
52 UINT8 cmdCode[4] = {0,0,0,0};
53 UINT8 *cmdCodePtr = &cmdCode[0];
wcarthur098f8c02016-03-30 12:08:14 -040054
Will Arthur54e04e42015-07-15 11:29:25 -040055 name1.b.size = name2.b.size = 0;
wcarthur098f8c02016-03-30 12:08:14 -040056
Will Arthur54e04e42015-07-15 11:29:25 -040057 // Calculate pHash
58 //
59
60 // Only get names for commands
61 if( responseCode == TPM_RC_NO_RESPONSE )
62 {
wcarthur098f8c02016-03-30 12:08:14 -040063 if( handle1 == TPM_HT_NO_HANDLE )
64 {
65 name1.t.size = 0;
66 }
67 else
68 {
69 // Get names for the handles
70 rval = TpmHandleToName( handle1, &name1 );
71 if( rval != TPM_RC_SUCCESS )
72 return rval;
73 }
Will Arthur54e04e42015-07-15 11:29:25 -040074 }
75
76#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -080077 DebugPrintf( 0, "\n\nNAME1 = \n" );
Will Arthur54e04e42015-07-15 11:29:25 -040078 PrintSizedBuffer( &(name1.b) );
Will Arthur54e04e42015-07-15 11:29:25 -040079#endif
wcarthur098f8c02016-03-30 12:08:14 -040080
Will Arthur54e04e42015-07-15 11:29:25 -040081 // Only get names for commands
82 if( responseCode == TPM_RC_NO_RESPONSE )
83 {
84 rval = Tss2_Sys_GetCpBuffer( sysContext, &parametersSize, &startParams);
85 if( rval != TPM_RC_SUCCESS )
86 return rval;
87
wcarthur098f8c02016-03-30 12:08:14 -040088 if( handle2 == TPM_HT_NO_HANDLE )
89 {
90 name2.t.size = 0;
91 }
92 else
93 {
94 rval = TpmHandleToName( handle2, &name2 );
95 if( rval != TPM_RC_SUCCESS )
96 return rval;
97 }
Will Arthur54e04e42015-07-15 11:29:25 -040098 }
99 else
100 {
101 rval = Tss2_Sys_GetRpBuffer( sysContext, &parametersSize, &startParams);
102 if( rval != TPM_RC_SUCCESS )
103 return rval;
104 }
wcarthur098f8c02016-03-30 12:08:14 -0400105
Will Arthur54e04e42015-07-15 11:29:25 -0400106#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -0800107 DebugPrintf( 0, "\n\nNAME2 = \n" );
Will Arthur54e04e42015-07-15 11:29:25 -0400108 PrintSizedBuffer( &(name2.b) );
Will Arthur54e04e42015-07-15 11:29:25 -0400109#endif
wcarthur098f8c02016-03-30 12:08:14 -0400110
Will Arthur54e04e42015-07-15 11:29:25 -0400111 // Create pHash input byte stream: first add response code, if any.
112 hashInput.b.size = 0;
113 if( responseCode != TPM_RC_NO_RESPONSE )
114 {
115 hashInputPtr = &( hashInput.t.buffer[hashInput.b.size] );
Tadeusz Struk8203a372017-06-26 15:15:18 -0700116 *(UINT32 *)hashInputPtr = BE_TO_HOST_32(responseCode);
Will Arthur54e04e42015-07-15 11:29:25 -0400117 hashInput.b.size += 4;
118 hashInputPtr += 4;
119 }
120
121 // Create pHash input byte stream: now add command code.
122 rval = Tss2_Sys_GetCommandCode( sysContext, &cmdCode );
123 if( rval != TPM_RC_SUCCESS )
124 return rval;
125
Philip Triccadfa41a52016-07-20 17:43:57 -0700126 hashInputPtr = &( hashInput.t.buffer[hashInput.b.size] );
Tadeusz Struk8203a372017-06-26 15:15:18 -0700127 *(UINT32 *)hashInputPtr = BE_TO_HOST_32(*(UINT32 *)cmdCodePtr);
Will Arthur54e04e42015-07-15 11:29:25 -0400128 hashInput.t.size += 4;
129
130 // Create pHash input byte stream: now add in names for the handles.
131 rval = ConcatSizedByteBuffer( &hashInput, &( name1.b ) );
132 if( rval != TPM_RC_SUCCESS )
133 return rval;
wcarthur098f8c02016-03-30 12:08:14 -0400134
Will Arthur54e04e42015-07-15 11:29:25 -0400135 rval = ConcatSizedByteBuffer( &hashInput, &( name2.b ) );
136 if( rval != TPM_RC_SUCCESS )
137 return rval;
138
139 if( ( hashInput.t.size + parametersSize ) <= sizeof( hashInput.t.buffer ) )
140 {
141 // Create pHash input byte stream: now add in parameters byte stream
142 for( i = 0; i < parametersSize; i++ )
143 hashInput.t.buffer[hashInput.t.size + i ] = startParams[i];
144 hashInput.t.size += (UINT16)parametersSize;
145 }
146 else
147 {
148 return( APPLICATION_ERROR( TSS2_BASE_RC_INSUFFICIENT_BUFFER ) );
149
150 }
151#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -0800152 DebugPrintf( 0, "\n\nPHASH input bytes= \n" );
Will Arthur54e04e42015-07-15 11:29:25 -0400153 PrintSizedBuffer( &(hashInput.b) );
Will Arthur54e04e42015-07-15 11:29:25 -0400154#endif
wcarthur098f8c02016-03-30 12:08:14 -0400155
Will Arthur54e04e42015-07-15 11:29:25 -0400156 // Now hash the whole mess.
157 if( hashInput.t.size > sizeof( hashInput.t.buffer ) )
158 {
159 rval = APPLICATION_ERROR( TSS2_BASE_RC_INSUFFICIENT_BUFFER );
160 }
161 else
162 {
163 rval = TpmHash( authHash, hashInput.t.size, &( hashInput.t.buffer[0] ), pHash );
164 if( rval != TPM_RC_SUCCESS )
165 return rval;
166#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -0800167 DebugPrintf( 0, "\n\nPHASH = " );
Will Arthur54e04e42015-07-15 11:29:25 -0400168 PrintSizedBuffer( &(pHash->b) );
Will Arthur54e04e42015-07-15 11:29:25 -0400169#endif
170 }
wcarthur098f8c02016-03-30 12:08:14 -0400171
Will Arthur54e04e42015-07-15 11:29:25 -0400172 return rval;
wcarthur098f8c02016-03-30 12:08:14 -0400173}