1 /* Software-based Mobile Trusted Module (MTM) Emulator
2  * Copyright (C) 2004-2010 Mario Strasser <mast@gmx.net>
3  * Copyright (C) 2007 Jan-Erik Ekberg <jan-erik.ekberg@nokia.com>,
4  *                    Nokia Corporation and/or its subsidiary(-ies)
5  *
6  * This module is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation; either version 2 of the License,
9  * or (at your option) any later version.
10  *
11  * This module is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * $Id$
17  */
18 
19 #include "mtm_commands.h"
20 #include "mtm_marshalling.h"
21 
22 extern void tpm_compute_in_param_digest(TPM_REQUEST *req);
23 
execute_MTM_InstallRIM(TPM_REQUEST * req,TPM_RESPONSE * rsp)24 static TPM_RESULT execute_MTM_InstallRIM(TPM_REQUEST *req, TPM_RESPONSE *rsp)
25 {
26   BYTE *ptr;
27   UINT32 len;
28   UINT32 rimCertSize;
29   TPM_RIM_CERTIFICATE rimCertIn;
30   TPM_RIM_CERTIFICATE rimCertOut;
31   TPM_RESULT res;
32   /* compute parameter digest */
33   tpm_compute_in_param_digest(req);
34   /* unmarshal input */
35   ptr = req->param;
36   len = req->paramSize;
37   if (tpm_unmarshal_UINT32(&ptr, &len, &rimCertSize)
38       || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCertIn)
39       || len != 0) return TPM_BAD_PARAMETER;
40   /* execute command */
41   res = MTM_InstallRIM(&rimCertIn, &req->auth1, &rimCertOut);
42   if (res != TPM_SUCCESS) return res;
43   /* marshal output */
44   rsp->paramSize = len = 4 + sizeof_TPM_RIM_CERTIFICATE(rimCertOut);
45   rsp->param = ptr = tpm_malloc(len);
46   if (ptr == NULL
47       || tpm_marshal_UINT32(&ptr, &len, sizeof_TPM_RIM_CERTIFICATE(rimCertOut))
48       || tpm_marshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCertOut)) {
49     tpm_free(rsp->param);
50     res = TPM_FAIL;
51   }
52   free_TPM_RIM_CERTIFICATE(rimCertOut);
53   return res;
54 }
55 
execute_MTM_LoadVerificationKey(TPM_REQUEST * req,TPM_RESPONSE * rsp)56 static TPM_RESULT execute_MTM_LoadVerificationKey(TPM_REQUEST *req, TPM_RESPONSE *rsp)
57 {
58   BYTE *ptr;
59   UINT32 len;
60   TPM_VERIFICATION_KEY_HANDLE parentKey;
61   UINT32 verificationKeySize;
62   TPM_VERIFICATION_KEY verificationKey;
63   TPM_VERIFICATION_KEY_HANDLE verificationKeyHandle;
64   BYTE loadMethod;
65   TPM_RESULT res;
66   /* compute parameter digest */
67   tpm_compute_in_param_digest(req);
68   /* unmarshal input */
69   ptr = req->param;
70   len = req->paramSize;
71   if (tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &parentKey)
72       || tpm_unmarshal_UINT32(&ptr, &len, &verificationKeySize)
73       || tpm_unmarshal_TPM_VERIFICATION_KEY(&ptr, &len, &verificationKey)
74       || len != 0) return TPM_BAD_PARAMETER;
75   /* execute command  */
76   res = MTM_LoadVerificationKey(parentKey, &verificationKey, &req->auth1,
77     &verificationKeyHandle, &loadMethod);
78   if (res != TPM_SUCCESS) return res;
79   /* marshal output */
80   rsp->paramSize = len = 4 + 1;
81   rsp->param = ptr = tpm_malloc(len);
82   if (ptr == NULL
83       || tpm_marshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, verificationKeyHandle)
84       || tpm_marshal_BYTE(&ptr, &len, loadMethod)) {
85     tpm_free(rsp->param);
86     res = TPM_FAIL;
87   }
88   return res;
89 }
90 
execute_MTM_LoadVerificationRootKeyDisable(TPM_REQUEST * req,TPM_RESPONSE * rsp)91 static TPM_RESULT execute_MTM_LoadVerificationRootKeyDisable(TPM_REQUEST *req, TPM_RESPONSE *rsp)
92 {
93   TPM_RESULT res;
94   /* compute parameter digest */
95   tpm_compute_in_param_digest(req);
96   /* execute command */
97   res = MTM_LoadVerificationRootKeyDisable();
98   /* marshal output */
99   rsp->paramSize = 0;
100   rsp->param = NULL;
101   return res;
102 }
103 
execute_MTM_VerifyRIMCert(TPM_REQUEST * req,TPM_RESPONSE * rsp)104 static TPM_RESULT execute_MTM_VerifyRIMCert(TPM_REQUEST *req, TPM_RESPONSE *rsp)
105 {
106   BYTE *ptr;
107   UINT32 len;
108   UINT32 rimCertSize;
109   TPM_RIM_CERTIFICATE rimCert;
110   TPM_VERIFICATION_KEY_HANDLE rimKey;
111   TPM_RESULT res;
112   /* compute parameter digest */
113   tpm_compute_in_param_digest(req);
114   /* unmarshal input */
115   ptr = req->param;
116   len = req->paramSize;
117   if (tpm_unmarshal_UINT32(&ptr, &len, &rimCertSize)
118       || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCert)
119       || tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &rimKey)
120       || len != 0) return TPM_BAD_PARAMETER;
121   /* execute command */
122   res = MTM_VerifyRIMCert(&rimCert, rimKey);
123   /* marshal output */
124   rsp->paramSize = len = 0;
125   rsp->param = ptr = NULL;
126   return res;
127 }
128 
execute_MTM_VerifyRIMCertAndExtend(TPM_REQUEST * req,TPM_RESPONSE * rsp)129 static TPM_RESULT execute_MTM_VerifyRIMCertAndExtend(TPM_REQUEST *req, TPM_RESPONSE *rsp)
130 {
131   BYTE *ptr;
132   UINT32 len;
133   UINT32 rimCertSize;
134   TPM_RIM_CERTIFICATE rimCert;
135   TPM_VERIFICATION_KEY_HANDLE rimKey;
136   TPM_PCRVALUE outDigest;
137   TPM_RESULT res;
138   /* compute parameter digest */
139   tpm_compute_in_param_digest(req);
140   /* unmarshal input */
141   ptr = req->param;
142   len = req->paramSize;
143   if (tpm_unmarshal_UINT32(&ptr, &len, &rimCertSize)
144       || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCert)
145       || tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &rimKey)
146       || len != 0) return TPM_BAD_PARAMETER;
147   /* execute command */
148   res = MTM_VerifyRIMCertAndExtend(&rimCert, rimKey, &outDigest);
149   /* marshal output */
150   rsp->paramSize = len = 20;
151   rsp->param = ptr = tpm_malloc(len);
152   if (ptr == NULL
153       || tpm_marshal_TPM_PCRVALUE(&ptr, &len, &outDigest)) {
154     tpm_free(rsp->param);
155     res = TPM_FAIL;
156   }
157   return res;
158 }
159 
execute_MTM_IncrementBootstrapCounter(TPM_REQUEST * req,TPM_RESPONSE * rsp)160 static TPM_RESULT execute_MTM_IncrementBootstrapCounter(TPM_REQUEST *req, TPM_RESPONSE *rsp)
161 {
162   BYTE *ptr;
163   UINT32 len;
164   UINT32 rimCertSize;
165   TPM_RIM_CERTIFICATE rimCert;
166   TPM_VERIFICATION_KEY_HANDLE rimKey;
167   TPM_RESULT res;
168   /* compute parameter digest */
169   tpm_compute_in_param_digest(req);
170   /* unmarshal input */
171   ptr = req->param;
172   len = req->paramSize;
173   if (tpm_unmarshal_UINT32(&ptr, &len, &rimCertSize)
174       || tpm_unmarshal_TPM_RIM_CERTIFICATE(&ptr, &len, &rimCert)
175       || tpm_unmarshal_TPM_VERIFICATION_KEY_HANDLE(&ptr, &len, &rimKey)
176       || len != 0) return TPM_BAD_PARAMETER;
177   /* execute command */
178   res = MTM_IncrementBootstrapCounter(&rimCert, rimKey);
179   /* marshal output */
180   rsp->paramSize = len = 0;
181   rsp->param = ptr = NULL;
182   return res;
183 }
184 
execute_MTM_SetVerifiedPCRSelection(TPM_REQUEST * req,TPM_RESPONSE * rsp)185 static TPM_RESULT execute_MTM_SetVerifiedPCRSelection(TPM_REQUEST *req, TPM_RESPONSE *rsp)
186 {
187   BYTE *ptr;
188   UINT32 len;
189   TPM_PCR_SELECTION verifiedSelection;
190   TPM_RESULT res;
191   /* compute parameter digest */
192   tpm_compute_in_param_digest(req);
193   /* unmarshal input */
194   ptr = req->param;
195   len = req->paramSize;
196   if (tpm_unmarshal_TPM_PCR_SELECTION(&ptr, &len, &verifiedSelection)
197       || len != 0) return TPM_BAD_PARAMETER;
198   /* execute command */
199   res = MTM_SetVerifiedPCRSelection(&verifiedSelection, &req->auth1);
200   /* marshal output */
201   rsp->paramSize = len = 0;
202   rsp->param = ptr = NULL;
203   return res;
204 }
205 
206 
mtm_execute_command(TPM_REQUEST * req,TPM_RESPONSE * rsp)207 TPM_RESULT mtm_execute_command(TPM_REQUEST *req, TPM_RESPONSE *rsp)
208 {
209   TPM_RESULT res;
210 
211   /* handle command ordinal */
212   switch (req->ordinal) {
213     case MTM_ORD_InstallRIM:
214       debug("[MTM_ORD_InstallRIM]");
215       res = execute_MTM_InstallRIM(req, rsp);
216       break;
217 
218     case MTM_ORD_LoadVerificationKey:
219       debug("[MTM_ORD_LoadVerificationKey]");
220       res = execute_MTM_LoadVerificationKey(req, rsp);
221       break;
222 
223     case MTM_ORD_LoadVerificationRootKeyDisable:
224       debug("[MTM_ORD_LoadVerificationRootKeyDisable]");
225       res = execute_MTM_LoadVerificationRootKeyDisable(req, rsp);
226       break;
227 
228     case MTM_ORD_VerifyRIMCert:
229       debug("[MTM_ORD_VerifyRIMCert]");
230       res = execute_MTM_VerifyRIMCert(req, rsp);
231       break;
232 
233     case MTM_ORD_VerifyRIMCertAndExtend:
234       debug("[MTM_ORD_VerifyRIMCertAndExtend]");
235       res = execute_MTM_VerifyRIMCertAndExtend(req, rsp);
236       break;
237 
238     case MTM_ORD_IncrementBootstrapCounter:
239       debug("[MTM_ORD_IncrementBootstrapCounter]");
240       res = execute_MTM_IncrementBootstrapCounter(req, rsp);
241       break;
242 
243     case MTM_ORD_SetVerifiedPCRSelection:
244       debug("[MTM_ORD_SetVerifiedPCRSelection]");
245       res = execute_MTM_SetVerifiedPCRSelection(req, rsp);
246       break;
247 
248     default:
249       res = TPM_BAD_ORDINAL;
250       break;
251   }
252   return res;
253 }
254