blob: 2477c53489c73fd9736c0b88733f0f5ab8136ab5 [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"
Will Arthur54e04e42015-07-15 11:29:25 -040033
Will Arthur54e04e42015-07-15 11:29:25 -040034//
35// This function is a helper function used to calculate cpHash and rpHash.
36//
37// NOTE: for calculating cpHash, set responseCode to TPM_RC_NO_RESPONSE; this
38// tells the function to leave it out of the calculation.
39//
40TPM_RC TpmCalcPHash( TSS2_SYS_CONTEXT *sysContext, TPM_HANDLE handle1, TPM_HANDLE handle2,
41 TPMI_ALG_HASH authHash, TPM_RC responseCode, TPM2B_DIGEST *pHash )
42{
43 TPM_RC rval = TPM_RC_SUCCESS;
44 UINT32 i;
45 TPM2B_NAME name1;
46 TPM2B_NAME name2;
47 TPM2B_MAX_BUFFER hashInput; // Byte stream to be hashed to create pHash
48 UINT8 *hashInputPtr;
49 size_t parametersSize;
50 const uint8_t *startParams;
51 UINT8 cmdCode[4] = {0,0,0,0};
52 UINT8 *cmdCodePtr = &cmdCode[0];
wcarthur098f8c02016-03-30 12:08:14 -040053
Will Arthur54e04e42015-07-15 11:29:25 -040054 name1.b.size = name2.b.size = 0;
wcarthur098f8c02016-03-30 12:08:14 -040055
Will Arthur54e04e42015-07-15 11:29:25 -040056 // Calculate pHash
57 //
58
59 // Only get names for commands
60 if( responseCode == TPM_RC_NO_RESPONSE )
61 {
wcarthur098f8c02016-03-30 12:08:14 -040062 if( handle1 == TPM_HT_NO_HANDLE )
63 {
64 name1.t.size = 0;
65 }
66 else
67 {
68 // Get names for the handles
69 rval = TpmHandleToName( handle1, &name1 );
70 if( rval != TPM_RC_SUCCESS )
71 return rval;
72 }
Will Arthur54e04e42015-07-15 11:29:25 -040073 }
74
75#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -080076 DebugPrintf( 0, "\n\nNAME1 = \n" );
Will Arthur54e04e42015-07-15 11:29:25 -040077 PrintSizedBuffer( &(name1.b) );
Will Arthur54e04e42015-07-15 11:29:25 -040078#endif
wcarthur098f8c02016-03-30 12:08:14 -040079
Will Arthur54e04e42015-07-15 11:29:25 -040080 // Only get names for commands
81 if( responseCode == TPM_RC_NO_RESPONSE )
82 {
83 rval = Tss2_Sys_GetCpBuffer( sysContext, &parametersSize, &startParams);
84 if( rval != TPM_RC_SUCCESS )
85 return rval;
86
wcarthur098f8c02016-03-30 12:08:14 -040087 if( handle2 == TPM_HT_NO_HANDLE )
88 {
89 name2.t.size = 0;
90 }
91 else
92 {
93 rval = TpmHandleToName( handle2, &name2 );
94 if( rval != TPM_RC_SUCCESS )
95 return rval;
96 }
Will Arthur54e04e42015-07-15 11:29:25 -040097 }
98 else
99 {
100 rval = Tss2_Sys_GetRpBuffer( sysContext, &parametersSize, &startParams);
101 if( rval != TPM_RC_SUCCESS )
102 return rval;
103 }
wcarthur098f8c02016-03-30 12:08:14 -0400104
Will Arthur54e04e42015-07-15 11:29:25 -0400105#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -0800106 DebugPrintf( 0, "\n\nNAME2 = \n" );
Will Arthur54e04e42015-07-15 11:29:25 -0400107 PrintSizedBuffer( &(name2.b) );
Will Arthur54e04e42015-07-15 11:29:25 -0400108#endif
wcarthur098f8c02016-03-30 12:08:14 -0400109
Will Arthur54e04e42015-07-15 11:29:25 -0400110 // Create pHash input byte stream: first add response code, if any.
111 hashInput.b.size = 0;
112 if( responseCode != TPM_RC_NO_RESPONSE )
113 {
114 hashInputPtr = &( hashInput.t.buffer[hashInput.b.size] );
115 *(UINT32 *)hashInputPtr = CHANGE_ENDIAN_DWORD( responseCode );
116 hashInput.b.size += 4;
117 hashInputPtr += 4;
118 }
119
120 // Create pHash input byte stream: now add command code.
121 rval = Tss2_Sys_GetCommandCode( sysContext, &cmdCode );
122 if( rval != TPM_RC_SUCCESS )
123 return rval;
124
Philip Triccadfa41a52016-07-20 17:43:57 -0700125 hashInputPtr = &( hashInput.t.buffer[hashInput.b.size] );
Will Arthur54e04e42015-07-15 11:29:25 -0400126 *(UINT32 *)hashInputPtr = CHANGE_ENDIAN_DWORD( *(UINT32 *)cmdCodePtr );
127 hashInput.t.size += 4;
128
129 // Create pHash input byte stream: now add in names for the handles.
130 rval = ConcatSizedByteBuffer( &hashInput, &( name1.b ) );
131 if( rval != TPM_RC_SUCCESS )
132 return rval;
wcarthur098f8c02016-03-30 12:08:14 -0400133
Will Arthur54e04e42015-07-15 11:29:25 -0400134 rval = ConcatSizedByteBuffer( &hashInput, &( name2.b ) );
135 if( rval != TPM_RC_SUCCESS )
136 return rval;
137
138 if( ( hashInput.t.size + parametersSize ) <= sizeof( hashInput.t.buffer ) )
139 {
140 // Create pHash input byte stream: now add in parameters byte stream
141 for( i = 0; i < parametersSize; i++ )
142 hashInput.t.buffer[hashInput.t.size + i ] = startParams[i];
143 hashInput.t.size += (UINT16)parametersSize;
144 }
145 else
146 {
147 return( APPLICATION_ERROR( TSS2_BASE_RC_INSUFFICIENT_BUFFER ) );
148
149 }
150#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -0800151 DebugPrintf( 0, "\n\nPHASH input bytes= \n" );
Will Arthur54e04e42015-07-15 11:29:25 -0400152 PrintSizedBuffer( &(hashInput.b) );
Will Arthur54e04e42015-07-15 11:29:25 -0400153#endif
wcarthur098f8c02016-03-30 12:08:14 -0400154
Will Arthur54e04e42015-07-15 11:29:25 -0400155 // Now hash the whole mess.
156 if( hashInput.t.size > sizeof( hashInput.t.buffer ) )
157 {
158 rval = APPLICATION_ERROR( TSS2_BASE_RC_INSUFFICIENT_BUFFER );
159 }
160 else
161 {
162 rval = TpmHash( authHash, hashInput.t.size, &( hashInput.t.buffer[0] ), pHash );
163 if( rval != TPM_RC_SUCCESS )
164 return rval;
165#ifdef DEBUG
Philip Triccab33221d2016-03-10 15:37:24 -0800166 DebugPrintf( 0, "\n\nPHASH = " );
Will Arthur54e04e42015-07-15 11:29:25 -0400167 PrintSizedBuffer( &(pHash->b) );
Will Arthur54e04e42015-07-15 11:29:25 -0400168#endif
169 }
wcarthur098f8c02016-03-30 12:08:14 -0400170
Will Arthur54e04e42015-07-15 11:29:25 -0400171 return rval;
wcarthur098f8c02016-03-30 12:08:14 -0400172}