• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2014 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 // trunks_client is a command line tool that supports various TPM operations. It
18 // does not provide direct access to the trunksd D-Bus interface.
19 
20 #include <stdio.h>
21 #include <string>
22 
23 #include <base/command_line.h>
24 #include <base/logging.h>
25 #include <brillo/syslog_logging.h>
26 
27 #include "trunks/error_codes.h"
28 #include "trunks/hmac_session.h"
29 #include "trunks/password_authorization_delegate.h"
30 #include "trunks/policy_session.h"
31 #include "trunks/scoped_key_handle.h"
32 #include "trunks/tpm_state.h"
33 #include "trunks/tpm_utility.h"
34 #include "trunks/trunks_client_test.h"
35 #include "trunks/trunks_factory_impl.h"
36 
37 namespace {
38 
39 using trunks::CommandTransceiver;
40 using trunks::TrunksFactory;
41 
PrintUsage()42 void PrintUsage() {
43   puts("Options:");
44   puts("  --allocate_pcr - Configures PCR 0-15 under the SHA256 bank.");
45   puts("  --clear - Clears the TPM. Use before initializing the TPM.");
46   puts("  --help - Prints this message.");
47   puts("  --init_tpm - Initializes a TPM as CrOS firmware does.");
48   puts("  --own - Takes ownership of the TPM with the provided password.");
49   puts("  --owner_password - used to provide an owner password");
50   puts("  --regression_test - Runs some basic regression tests. If");
51   puts("                      owner_password is supplied, it runs tests that");
52   puts("                      need owner permissions.");
53   puts("  --startup - Performs startup and self-tests.");
54   puts("  --status - Prints TPM status information.");
55   puts("  --stress_test - Runs some basic stress tests.");
56 }
57 
Startup(TrunksFactory * factory)58 int Startup(TrunksFactory* factory) {
59   factory->GetTpmUtility()->Shutdown();
60   return factory->GetTpmUtility()->Startup();
61 }
62 
Clear(TrunksFactory * factory)63 int Clear(TrunksFactory* factory) {
64   return factory->GetTpmUtility()->Clear();
65 }
66 
InitializeTpm(TrunksFactory * factory)67 int InitializeTpm(TrunksFactory* factory) {
68   return factory->GetTpmUtility()->InitializeTpm();
69 }
70 
AllocatePCR(TrunksFactory * factory)71 int AllocatePCR(TrunksFactory* factory) {
72   trunks::TPM_RC result;
73   result = factory->GetTpmUtility()->AllocatePCR("");
74   if (result != trunks::TPM_RC_SUCCESS) {
75     LOG(ERROR) << "Error allocating PCR:" << trunks::GetErrorString(result);
76     return result;
77   }
78   factory->GetTpmUtility()->Shutdown();
79   return factory->GetTpmUtility()->Startup();
80 }
81 
TakeOwnership(const std::string & owner_password,TrunksFactory * factory)82 int TakeOwnership(const std::string& owner_password, TrunksFactory* factory) {
83   trunks::TPM_RC rc;
84   rc = factory->GetTpmUtility()->TakeOwnership(owner_password,
85                                                owner_password,
86                                                owner_password);
87   if (rc) {
88     LOG(ERROR) << "Error taking ownership: " << trunks::GetErrorString(rc);
89     return rc;
90   }
91   return 0;
92 }
93 
DumpStatus(TrunksFactory * factory)94 int DumpStatus(TrunksFactory* factory) {
95   scoped_ptr<trunks::TpmState> state = factory->GetTpmState();
96   trunks::TPM_RC result = state->Initialize();
97   if (result != trunks::TPM_RC_SUCCESS) {
98     LOG(ERROR) << "Failed to read TPM state: "
99                << trunks::GetErrorString(result);
100     return result;
101   }
102   printf("Owner password set: %s\n",
103          state->IsOwnerPasswordSet() ? "true" : "false");
104   printf("Endorsement password set: %s\n",
105          state->IsEndorsementPasswordSet() ? "true" : "false");
106   printf("Lockout password set: %s\n",
107          state->IsLockoutPasswordSet() ? "true" : "false");
108   printf("Ownership status: %s\n",
109          state->IsOwned() ? "true" : "false");
110   printf("In lockout: %s\n",
111          state->IsInLockout() ? "true" : "false");
112   printf("Platform hierarchy enabled: %s\n",
113          state->IsPlatformHierarchyEnabled() ? "true" : "false");
114   printf("Storage hierarchy enabled: %s\n",
115          state->IsStorageHierarchyEnabled() ? "true" : "false");
116   printf("Endorsement hierarchy enabled: %s\n",
117          state->IsEndorsementHierarchyEnabled() ? "true" : "false");
118   printf("Is Tpm enabled: %s\n",
119          state->IsEnabled() ? "true" : "false");
120   printf("Was shutdown orderly: %s\n",
121          state->WasShutdownOrderly() ? "true" : "false");
122   printf("Is RSA supported: %s\n",
123          state->IsRSASupported() ? "true" : "false");
124   printf("Is ECC supported: %s\n",
125          state->IsECCSupported() ? "true" : "false");
126   printf("Lockout Counter: %u\n", state->GetLockoutCounter());
127   printf("Lockout Threshold: %u\n", state->GetLockoutThreshold());
128   printf("Lockout Interval: %u\n", state->GetLockoutInterval());
129   printf("Lockout Recovery: %u\n", state->GetLockoutRecovery());
130   return 0;
131 }
132 
133 }  // namespace
134 
main(int argc,char ** argv)135 int main(int argc, char **argv) {
136   base::CommandLine::Init(argc, argv);
137   brillo::InitLog(brillo::kLogToStderr);
138   base::CommandLine *cl = base::CommandLine::ForCurrentProcess();
139   if (cl->HasSwitch("help")) {
140     puts("Trunks Client: A command line tool to access the TPM.");
141     PrintUsage();
142     return 0;
143   }
144 
145   scoped_ptr<TrunksFactory> factory = scoped_ptr<TrunksFactory>(
146       new trunks::TrunksFactoryImpl(true /* failure_is_fatal */));
147 
148   if (cl->HasSwitch("status")) {
149     return DumpStatus(factory.get());
150   }
151   if (cl->HasSwitch("startup")) {
152     return Startup(factory.get());
153   }
154   if (cl->HasSwitch("clear")) {
155     return Clear(factory.get());
156   }
157   if (cl->HasSwitch("init_tpm")) {
158     return InitializeTpm(factory.get());
159   }
160   if (cl->HasSwitch("allocate_pcr")) {
161     return AllocatePCR(factory.get());
162   }
163 
164   if (cl->HasSwitch("own")) {
165     return TakeOwnership(cl->GetSwitchValueASCII("owner_password"),
166                          factory.get());
167   }
168   if (cl->HasSwitch("regression_test")) {
169     trunks::TrunksClientTest test;
170     LOG(INFO) << "Running RNG test.";
171     if (!test.RNGTest()) {
172       LOG(ERROR) << "Error running RNGtest.";
173       return -1;
174     }
175     LOG(INFO) << "Running RSA key tests.";
176     if (!test.SignTest()) {
177       LOG(ERROR) << "Error running SignTest.";
178       return -1;
179     }
180     if (!test.DecryptTest()) {
181       LOG(ERROR) << "Error running DecryptTest.";
182       return -1;
183     }
184     if (!test.ImportTest()) {
185       LOG(ERROR) << "Error running ImportTest.";
186       return -1;
187     }
188     if (!test.AuthChangeTest()) {
189       LOG(ERROR) << "Error running AuthChangeTest.";
190       return -1;
191     }
192     if (!test.VerifyKeyCreationTest()) {
193       LOG(ERROR) << "Error running VerifyKeyCreationTest.";
194       return -1;
195     }
196     LOG(INFO) << "Running Sealed Data test.";
197     if (!test.SealedDataTest()) {
198       LOG(ERROR) << "Error running SealedDataTest.";
199       return -1;
200     }
201     LOG(INFO) << "Running PCR test.";
202     if (!test.PCRTest()) {
203       LOG(ERROR) << "Error running PCRTest.";
204       return -1;
205     }
206     LOG(INFO) << "Running policy tests.";
207     if (!test.PolicyAuthValueTest()) {
208       LOG(ERROR) << "Error running PolicyAuthValueTest.";
209       return -1;
210     }
211     if (!test.PolicyAndTest()) {
212       LOG(ERROR) << "Error running PolicyAndTest.";
213       return -1;
214     }
215     if (!test.PolicyOrTest()) {
216       LOG(ERROR) << "Error running PolicyOrTest.";
217       return -1;
218     }
219     if (cl->HasSwitch("owner_password")) {
220       std::string owner_password = cl->GetSwitchValueASCII("owner_password");
221       LOG(INFO) << "Running NVRAM test.";
222       if (!test.NvramTest(owner_password)) {
223         LOG(ERROR) << "Error running NvramTest.";
224         return -1;
225       }
226     }
227     LOG(INFO) << "All tests were run successfully.";
228     return 0;
229   }
230   if (cl->HasSwitch("stress_test")) {
231     LOG(INFO) << "Running stress tests.";
232     trunks::TrunksClientTest test;
233     if (!test.ManyKeysTest()) {
234       LOG(ERROR) << "Error running ManyKeysTest.";
235       return -1;
236     }
237     if (!test.ManySessionsTest()) {
238       LOG(ERROR) << "Error running ManySessionsTest.";
239       return -1;
240     }
241     return 0;
242   }
243   puts("Invalid options!");
244   PrintUsage();
245   return -1;
246 }
247