1 /*
2  * Copyright 2018 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 #define LOG_TAG "trusty_keymaster_hal"
18 #include <android-base/logging.h>
19 
20 #include <keymaster/android_keymaster_messages.h>
21 #include <keymaster/keymaster_configuration.h>
22 #include <trusty_keymaster/TrustyKeymaster.h>
23 #include <trusty_keymaster/ipc/trusty_keymaster_ipc.h>
24 
25 namespace keymaster {
26 
Initialize(KmVersion version)27 int TrustyKeymaster::Initialize(KmVersion version) {
28     int err;
29 
30     LOG(INFO) << "Initializing TrustyKeymaster as KmVersion: " << (int)version;
31 
32     err = trusty_keymaster_connect();
33     if (err) {
34         LOG(ERROR) << "Failed to connect to trusty keymaster (1st try)" << err;
35         return err;
36     }
37 
38     // Try GetVersion2 first.
39     GetVersion2Request versionReq;
40     versionReq.max_message_version = MessageVersion(version);
41     GetVersion2Response versionRsp = GetVersion2(versionReq);
42     if (versionRsp.error != KM_ERROR_OK) {
43         LOG(WARNING) << "TA appears not to support GetVersion2, falling back (err = "
44                      << versionRsp.error << ")";
45 
46         err = trusty_keymaster_connect();
47         if (err) {
48             LOG(FATAL) << "Failed to connect to trusty keymaster (2nd try) " << err;
49             return err;
50         }
51 
52         GetVersionRequest versionReq;
53         GetVersionResponse versionRsp;
54         GetVersion(versionReq, &versionRsp);
55         if (versionRsp.error != KM_ERROR_OK) {
56             LOG(FATAL) << "Failed to get TA version " << versionRsp.error;
57             return -1;
58         } else {
59             keymaster_error_t error;
60             message_version_ = NegotiateMessageVersion(versionRsp, &error);
61             if (error != KM_ERROR_OK) {
62                 LOG(FATAL) << "Failed to negotiate message version " << error;
63                 return -1;
64             }
65         }
66     } else {
67         message_version_ = NegotiateMessageVersion(versionReq, versionRsp);
68     }
69 
70     ConfigureRequest req(message_version());
71     req.os_version = GetOsVersion();
72     req.os_patchlevel = GetOsPatchlevel();
73 
74     ConfigureResponse rsp(message_version());
75     Configure(req, &rsp);
76 
77     if (rsp.error != KM_ERROR_OK) {
78         LOG(FATAL) << "Failed to configure keymaster " << rsp.error;
79         return -1;
80     }
81 
82     // Set the vendor patchlevel to value retrieved from system property (which
83     // requires SELinux permission).
84     ConfigureVendorPatchlevelRequest vendor_req(message_version());
85     vendor_req.vendor_patchlevel = GetVendorPatchlevel();
86     ConfigureVendorPatchlevelResponse vendor_rsp = ConfigureVendorPatchlevel(vendor_req);
87     if (vendor_rsp.error != KM_ERROR_OK) {
88         LOG(ERROR) << "Failed to configure keymaster vendor patchlevel: " << vendor_rsp.error;
89         // Don't fail if this message isn't understood.
90     }
91 
92     return 0;
93 }
94 
TrustyKeymaster()95 TrustyKeymaster::TrustyKeymaster() {}
96 
~TrustyKeymaster()97 TrustyKeymaster::~TrustyKeymaster() {
98     trusty_keymaster_disconnect();
99 }
100 
ForwardCommand(enum keymaster_command command,const KeymasterMessage & req,KeymasterResponse * rsp)101 static void ForwardCommand(enum keymaster_command command, const KeymasterMessage& req,
102                            KeymasterResponse* rsp) {
103     keymaster_error_t err;
104     err = trusty_keymaster_send(command, req, rsp);
105     if (err != KM_ERROR_OK) {
106         LOG(ERROR) << "Cmd " << command << " returned error: " << err;
107         rsp->error = err;
108     }
109 }
110 
GetVersion(const GetVersionRequest & request,GetVersionResponse * response)111 void TrustyKeymaster::GetVersion(const GetVersionRequest& request, GetVersionResponse* response) {
112     ForwardCommand(KM_GET_VERSION, request, response);
113 }
114 
SupportedAlgorithms(const SupportedAlgorithmsRequest & request,SupportedAlgorithmsResponse * response)115 void TrustyKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& request,
116                                           SupportedAlgorithmsResponse* response) {
117     ForwardCommand(KM_GET_SUPPORTED_ALGORITHMS, request, response);
118 }
119 
SupportedBlockModes(const SupportedBlockModesRequest & request,SupportedBlockModesResponse * response)120 void TrustyKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
121                                           SupportedBlockModesResponse* response) {
122     ForwardCommand(KM_GET_SUPPORTED_BLOCK_MODES, request, response);
123 }
124 
SupportedPaddingModes(const SupportedPaddingModesRequest & request,SupportedPaddingModesResponse * response)125 void TrustyKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
126                                             SupportedPaddingModesResponse* response) {
127     ForwardCommand(KM_GET_SUPPORTED_PADDING_MODES, request, response);
128 }
129 
SupportedDigests(const SupportedDigestsRequest & request,SupportedDigestsResponse * response)130 void TrustyKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
131                                        SupportedDigestsResponse* response) {
132     ForwardCommand(KM_GET_SUPPORTED_DIGESTS, request, response);
133 }
134 
SupportedImportFormats(const SupportedImportFormatsRequest & request,SupportedImportFormatsResponse * response)135 void TrustyKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request,
136                                              SupportedImportFormatsResponse* response) {
137     ForwardCommand(KM_GET_SUPPORTED_IMPORT_FORMATS, request, response);
138 }
139 
SupportedExportFormats(const SupportedExportFormatsRequest & request,SupportedExportFormatsResponse * response)140 void TrustyKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request,
141                                              SupportedExportFormatsResponse* response) {
142     ForwardCommand(KM_GET_SUPPORTED_EXPORT_FORMATS, request, response);
143 }
144 
AddRngEntropy(const AddEntropyRequest & request,AddEntropyResponse * response)145 void TrustyKeymaster::AddRngEntropy(const AddEntropyRequest& request,
146                                     AddEntropyResponse* response) {
147     ForwardCommand(KM_ADD_RNG_ENTROPY, request, response);
148 }
149 
Configure(const ConfigureRequest & request,ConfigureResponse * response)150 void TrustyKeymaster::Configure(const ConfigureRequest& request, ConfigureResponse* response) {
151     ForwardCommand(KM_CONFIGURE, request, response);
152 }
153 
GenerateKey(const GenerateKeyRequest & request,GenerateKeyResponse * response)154 void TrustyKeymaster::GenerateKey(const GenerateKeyRequest& request,
155                                   GenerateKeyResponse* response) {
156     if (message_version_ < 4) {
157         // Pre-KeyMint we need to add TAG_CREATION_DATETIME if not provided by the caller.
158         GenerateKeyRequest datedRequest(request.message_version);
159         datedRequest.key_description = request.key_description;
160 
161         if (!request.key_description.Contains(TAG_CREATION_DATETIME)) {
162             datedRequest.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL)));
163         }
164 
165         ForwardCommand(KM_GENERATE_KEY, datedRequest, response);
166     } else {
167         ForwardCommand(KM_GENERATE_KEY, request, response);
168     }
169 }
170 
GenerateRkpKey(const GenerateRkpKeyRequest & request,GenerateRkpKeyResponse * response)171 void TrustyKeymaster::GenerateRkpKey(const GenerateRkpKeyRequest& request,
172                                      GenerateRkpKeyResponse* response) {
173     ForwardCommand(KM_GENERATE_RKP_KEY, request, response);
174 }
175 
GenerateCsr(const GenerateCsrRequest & request,GenerateCsrResponse * response)176 void TrustyKeymaster::GenerateCsr(const GenerateCsrRequest& request,
177                                   GenerateCsrResponse* response) {
178     ForwardCommand(KM_GENERATE_CSR, request, response);
179 }
180 
GetKeyCharacteristics(const GetKeyCharacteristicsRequest & request,GetKeyCharacteristicsResponse * response)181 void TrustyKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
182                                             GetKeyCharacteristicsResponse* response) {
183     ForwardCommand(KM_GET_KEY_CHARACTERISTICS, request, response);
184 }
185 
ImportKey(const ImportKeyRequest & request,ImportKeyResponse * response)186 void TrustyKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
187     ForwardCommand(KM_IMPORT_KEY, request, response);
188 }
189 
ImportWrappedKey(const ImportWrappedKeyRequest & request,ImportWrappedKeyResponse * response)190 void TrustyKeymaster::ImportWrappedKey(const ImportWrappedKeyRequest& request,
191                                        ImportWrappedKeyResponse* response) {
192     ForwardCommand(KM_IMPORT_WRAPPED_KEY, request, response);
193 }
194 
ExportKey(const ExportKeyRequest & request,ExportKeyResponse * response)195 void TrustyKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
196     ForwardCommand(KM_EXPORT_KEY, request, response);
197 }
198 
AttestKey(const AttestKeyRequest & request,AttestKeyResponse * response)199 void TrustyKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) {
200     ForwardCommand(KM_ATTEST_KEY, request, response);
201 }
202 
UpgradeKey(const UpgradeKeyRequest & request,UpgradeKeyResponse * response)203 void TrustyKeymaster::UpgradeKey(const UpgradeKeyRequest& request, UpgradeKeyResponse* response) {
204     ForwardCommand(KM_UPGRADE_KEY, request, response);
205 }
206 
DeleteKey(const DeleteKeyRequest & request,DeleteKeyResponse * response)207 void TrustyKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
208     ForwardCommand(KM_DELETE_KEY, request, response);
209 }
210 
DeleteAllKeys(const DeleteAllKeysRequest & request,DeleteAllKeysResponse * response)211 void TrustyKeymaster::DeleteAllKeys(const DeleteAllKeysRequest& request,
212                                     DeleteAllKeysResponse* response) {
213     ForwardCommand(KM_DELETE_ALL_KEYS, request, response);
214 }
215 
BeginOperation(const BeginOperationRequest & request,BeginOperationResponse * response)216 void TrustyKeymaster::BeginOperation(const BeginOperationRequest& request,
217                                      BeginOperationResponse* response) {
218     ForwardCommand(KM_BEGIN_OPERATION, request, response);
219 }
220 
UpdateOperation(const UpdateOperationRequest & request,UpdateOperationResponse * response)221 void TrustyKeymaster::UpdateOperation(const UpdateOperationRequest& request,
222                                       UpdateOperationResponse* response) {
223     ForwardCommand(KM_UPDATE_OPERATION, request, response);
224 }
225 
FinishOperation(const FinishOperationRequest & request,FinishOperationResponse * response)226 void TrustyKeymaster::FinishOperation(const FinishOperationRequest& request,
227                                       FinishOperationResponse* response) {
228     ForwardCommand(KM_FINISH_OPERATION, request, response);
229 }
230 
AbortOperation(const AbortOperationRequest & request,AbortOperationResponse * response)231 void TrustyKeymaster::AbortOperation(const AbortOperationRequest& request,
232                                      AbortOperationResponse* response) {
233     ForwardCommand(KM_ABORT_OPERATION, request, response);
234 }
235 
GetHmacSharingParameters()236 GetHmacSharingParametersResponse TrustyKeymaster::GetHmacSharingParameters() {
237     GetHmacSharingParametersRequest request(message_version());
238     GetHmacSharingParametersResponse response(message_version());
239     ForwardCommand(KM_GET_HMAC_SHARING_PARAMETERS, request, &response);
240     return response;
241 }
242 
ComputeSharedHmac(const ComputeSharedHmacRequest & request)243 ComputeSharedHmacResponse TrustyKeymaster::ComputeSharedHmac(
244         const ComputeSharedHmacRequest& request) {
245     ComputeSharedHmacResponse response(message_version());
246     ForwardCommand(KM_COMPUTE_SHARED_HMAC, request, &response);
247     return response;
248 }
249 
VerifyAuthorization(const VerifyAuthorizationRequest & request)250 VerifyAuthorizationResponse TrustyKeymaster::VerifyAuthorization(
251         const VerifyAuthorizationRequest& request) {
252     VerifyAuthorizationResponse response(message_version());
253     ForwardCommand(KM_VERIFY_AUTHORIZATION, request, &response);
254     return response;
255 }
256 
GetVersion2(const GetVersion2Request & request)257 GetVersion2Response TrustyKeymaster::GetVersion2(const GetVersion2Request& request) {
258     GetVersion2Response response(message_version());
259     ForwardCommand(KM_GET_VERSION_2, request, &response);
260     return response;
261 }
262 
EarlyBootEnded()263 EarlyBootEndedResponse TrustyKeymaster::EarlyBootEnded() {
264     EarlyBootEndedResponse response(message_version());
265     ForwardCommand(KM_EARLY_BOOT_ENDED, EarlyBootEndedRequest(message_version()), &response);
266     return response;
267 }
268 
DeviceLocked(const DeviceLockedRequest & request)269 DeviceLockedResponse TrustyKeymaster::DeviceLocked(const DeviceLockedRequest& request) {
270     DeviceLockedResponse response(message_version());
271     ForwardCommand(KM_DEVICE_LOCKED, request, &response);
272     return response;
273 }
274 
ConfigureVendorPatchlevel(const ConfigureVendorPatchlevelRequest & request)275 ConfigureVendorPatchlevelResponse TrustyKeymaster::ConfigureVendorPatchlevel(
276         const ConfigureVendorPatchlevelRequest& request) {
277     ConfigureVendorPatchlevelResponse response(message_version());
278     ForwardCommand(KM_CONFIGURE_VENDOR_PATCHLEVEL, request, &response);
279     return response;
280 }
281 
282 }  // namespace keymaster
283