summaryrefslogtreecommitdiff
path: root/AmlogicKeymaster.cpp (plain)
blob: e5a8132d4d95b2091914505cd9a0ad94a53e9910
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 "AmlogicKeymaster"
18
19#include <log/log.h>
20#include <keymaster/android_keymaster_messages.h>
21#include <keymaster/keymaster_configuration.h>
22#include <amlogic_keymaster/AmlogicKeymaster.h>
23#include <amlogic_keymaster/ipc/amlogic_keymaster_ipc.h>
24
25#if AMLOGIC_MODIFY
26#include <amlogic_keymaster/amlogic_keymaster_messages.h>
27
28#include <android-base/properties.h>
29#include <sys/system_properties.h>
30#endif
31
32namespace keymaster {
33
34int AmlogicKeymaster::Initialize() {
35 int err;
36
37#if AMLOGIC_MODIFY
38 KM_context.fd = 0;
39 KM_session.ctx = NULL;
40 KM_session.session_id = 0;
41
42 err = aml_keymaster_connect(&KM_context, &KM_session);
43#else
44 err = trusty_keymaster_connect();
45#endif
46 if (err) {
47 ALOGE("Failed to connect to amlogic keymaster %d", err);
48 return err;
49 }
50#if AMLOGIC_MODIFY
51 // Set boot parameters before configure
52 SetBootParamsRequest setBootParamReq;
53 SetBootParamsResponse setBootParamRsp;
54 SetBootParams(setBootParamReq, &setBootParamRsp);
55 if (setBootParamRsp.error != KM_ERROR_OK) {
56 ALOGE("Failed to set boot params to keymaster %d", setBootParamRsp.error);
57 //return -1;
58 }
59#endif
60 ConfigureRequest req;
61 req.os_version = GetOsVersion();
62 req.os_patchlevel = GetOsPatchlevel();
63
64 ConfigureResponse rsp;
65 Configure(req, &rsp);
66
67 if (rsp.error != KM_ERROR_OK) {
68 ALOGE("Failed to configure keymaster %d", rsp.error);
69 return -1;
70 }
71
72 return 0;
73}
74
75AmlogicKeymaster::AmlogicKeymaster() {}
76
77AmlogicKeymaster::~AmlogicKeymaster() {
78#if AMLOGIC_MODIFY
79 if (KM_session.ctx != NULL)
80 aml_keymaster_disconnect(&KM_context, &KM_session);
81#else
82 trusty_keymaster_disconnect();
83#endif
84}
85#if AMLOGIC_MODIFY
86/* Move this method into class */
87void AmlogicKeymaster::ForwardCommand(enum keymaster_command command, const Serializable& req,
88 KeymasterResponse* rsp) {
89 keymaster_error_t err;
90 err = aml_keymaster_send(&KM_session, command, req, rsp);
91 if (err != KM_ERROR_OK) {
92 ALOGE("Failed to send cmd %d err: %d", command, err);
93 rsp->error = err;
94 }
95}
96#else
97static void ForwardCommand(enum keymaster_command command, const Serializable& req,
98 KeymasterResponse* rsp) {
99 keymaster_error_t err;
100 err = trusty_keymaster_send(command, req, rsp);
101 if (err != KM_ERROR_OK) {
102 ALOGE("Failed to send cmd %d err: %d", command, err);
103 rsp->error = err;
104 }
105}
106#endif
107
108void AmlogicKeymaster::GetVersion(const GetVersionRequest& request, GetVersionResponse* response) {
109 ForwardCommand(KM_GET_VERSION, request, response);
110}
111
112void AmlogicKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& request,
113 SupportedAlgorithmsResponse* response) {
114 ForwardCommand(KM_GET_SUPPORTED_ALGORITHMS, request, response);
115}
116
117void AmlogicKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request,
118 SupportedBlockModesResponse* response) {
119 ForwardCommand(KM_GET_SUPPORTED_BLOCK_MODES, request, response);
120}
121
122void AmlogicKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request,
123 SupportedPaddingModesResponse* response) {
124 ForwardCommand(KM_GET_SUPPORTED_PADDING_MODES, request, response);
125}
126
127void AmlogicKeymaster::SupportedDigests(const SupportedDigestsRequest& request,
128 SupportedDigestsResponse* response) {
129 ForwardCommand(KM_GET_SUPPORTED_DIGESTS, request, response);
130}
131
132void AmlogicKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request,
133 SupportedImportFormatsResponse* response) {
134 ForwardCommand(KM_GET_SUPPORTED_IMPORT_FORMATS, request, response);
135}
136
137void AmlogicKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request,
138 SupportedExportFormatsResponse* response) {
139 ForwardCommand(KM_GET_SUPPORTED_EXPORT_FORMATS, request, response);
140}
141
142void AmlogicKeymaster::AddRngEntropy(const AddEntropyRequest& request,
143 AddEntropyResponse* response) {
144 ForwardCommand(KM_ADD_RNG_ENTROPY, request, response);
145}
146
147void AmlogicKeymaster::Configure(const ConfigureRequest& request, ConfigureResponse* response) {
148 ForwardCommand(KM_CONFIGURE, request, response);
149}
150
151void AmlogicKeymaster::GenerateKey(const GenerateKeyRequest& request,
152 GenerateKeyResponse* response) {
153 GenerateKeyRequest datedRequest(request.message_version);
154 datedRequest.key_description = request.key_description;
155
156 if (!request.key_description.Contains(TAG_CREATION_DATETIME)) {
157 datedRequest.key_description.push_back(TAG_CREATION_DATETIME, java_time(time(NULL)));
158 }
159
160 ForwardCommand(KM_GENERATE_KEY, datedRequest, response);
161}
162
163void AmlogicKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request,
164 GetKeyCharacteristicsResponse* response) {
165 ForwardCommand(KM_GET_KEY_CHARACTERISTICS, request, response);
166}
167
168void AmlogicKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) {
169 ForwardCommand(KM_IMPORT_KEY, request, response);
170}
171
172void AmlogicKeymaster::ImportWrappedKey(const ImportWrappedKeyRequest& request,
173 ImportWrappedKeyResponse* response) {
174 ForwardCommand(KM_IMPORT_WRAPPED_KEY, request, response);
175}
176
177void AmlogicKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) {
178 ForwardCommand(KM_EXPORT_KEY, request, response);
179}
180
181void AmlogicKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) {
182 ForwardCommand(KM_ATTEST_KEY, request, response);
183}
184
185void AmlogicKeymaster::UpgradeKey(const UpgradeKeyRequest& request, UpgradeKeyResponse* response) {
186 ForwardCommand(KM_UPGRADE_KEY, request, response);
187}
188
189void AmlogicKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) {
190 ForwardCommand(KM_DELETE_KEY, request, response);
191}
192
193void AmlogicKeymaster::DeleteAllKeys(const DeleteAllKeysRequest& request,
194 DeleteAllKeysResponse* response) {
195 ForwardCommand(KM_DELETE_ALL_KEYS, request, response);
196}
197
198void AmlogicKeymaster::BeginOperation(const BeginOperationRequest& request,
199 BeginOperationResponse* response) {
200 ForwardCommand(KM_BEGIN_OPERATION, request, response);
201}
202
203void AmlogicKeymaster::UpdateOperation(const UpdateOperationRequest& request,
204 UpdateOperationResponse* response) {
205 ForwardCommand(KM_UPDATE_OPERATION, request, response);
206}
207
208void AmlogicKeymaster::FinishOperation(const FinishOperationRequest& request,
209 FinishOperationResponse* response) {
210 ForwardCommand(KM_FINISH_OPERATION, request, response);
211}
212
213void AmlogicKeymaster::AbortOperation(const AbortOperationRequest& request,
214 AbortOperationResponse* response) {
215 ForwardCommand(KM_ABORT_OPERATION, request, response);
216}
217
218GetHmacSharingParametersResponse AmlogicKeymaster::GetHmacSharingParameters() {
219 // Dummy empty buffer to allow ForwardCommand to have something to serialize
220 Buffer request;
221 GetHmacSharingParametersResponse response;
222 ForwardCommand(KM_GET_HMAC_SHARING_PARAMETERS, request, &response);
223 return response;
224}
225
226ComputeSharedHmacResponse AmlogicKeymaster::ComputeSharedHmac(
227 const ComputeSharedHmacRequest& request) {
228 ComputeSharedHmacResponse response;
229 ForwardCommand(KM_COMPUTE_SHARED_HMAC, request, &response);
230 return response;
231}
232
233VerifyAuthorizationResponse AmlogicKeymaster::VerifyAuthorization(
234 const VerifyAuthorizationRequest& request) {
235 VerifyAuthorizationResponse response;
236 ForwardCommand(KM_VERIFY_AUTHORIZATION, request, &response);
237 return response;
238}
239#if AMLOGIC_MODIFY
240void AmlogicKeymaster::SetBootParams(SetBootParamsRequest& req, SetBootParamsResponse *rsp) {
241#if 0
242 std::string prop_val;
243 // SHA256
244 uint8_t bootkey_hash[32];
245 uint8_t vbmeta_digest[32];
246
247 const uint8_t empty_hash_bin[32] = {0x0};
248 std::string empty_hash_hex_str(64, '0');
249
250 req.os_version = GetOsVersion();
251 req.os_patchlevel = GetOsPatchlevel();
252
253 // device_locked
254 prop_val = android::base::GetProperty("ro.boot.vbmeta.device_state", "unlocked");
255 req.device_locked = !prop_val.compare("locked")? 1: 0;
256
257 // verified_boot_state
258 prop_val = android::base::GetProperty("ro.boot.verifiedbootstate", "red");
259 req.verified_boot_state = KM_VERIFIED_BOOT_FAILED;
260 if (!prop_val.compare("green"))
261 req.verified_boot_state = KM_VERIFIED_BOOT_VERIFIED;
262 else if (!prop_val.compare("yellow"))
263 req.verified_boot_state = KM_VERIFIED_BOOT_SELF_SIGNED;
264 else if (!prop_val.compare("orange"))
265 req.verified_boot_state = KM_VERIFIED_BOOT_UNVERIFIED;
266 else if (!prop_val.compare("red"))
267 req.verified_boot_state = KM_VERIFIED_BOOT_FAILED;
268
269 // verified_boot_key
270 prop_val = android::base::GetProperty("ro.boot.vbmeta.bootkey_hash", empty_hash_hex_str);
271 //ALOGE("bootkey_hash = %s", prop_val.c_str());
272 //bootkey_hash = hex2bin(prop_val);
273 if (HexToBytes(bootkey_hash, sizeof(bootkey_hash), prop_val))
274 req.verified_boot_key.Reinitialize(bootkey_hash, sizeof(bootkey_hash));
275 else
276 req.verified_boot_key.Reinitialize(empty_hash_bin, sizeof(empty_hash_bin));
277
278 // verified_boot_hash
279 prop_val = android::base::GetProperty("ro.boot.vbmeta.digest", empty_hash_hex_str);
280 //ALOGE("vbmeta.digest = %s", prop_val.c_str());
281
282 //vbmeta_digest = hex2bin(prop_val);
283 if (HexToBytes(vbmeta_digest, sizeof(vbmeta_digest), prop_val))
284 req.verified_boot_hash.Reinitialize(vbmeta_digest, sizeof(vbmeta_digest));
285 else
286 req.verified_boot_hash.Reinitialize(empty_hash_bin, sizeof(empty_hash_bin));
287#endif
288 ALOGE("send empty boot params");
289
290 req.os_version = GetOsVersion();
291 req.os_patchlevel = GetOsPatchlevel();
292
293 ForwardCommand(KM_SET_BOOT_PARAMS, req, rsp);
294}
295#if 0
296bool AmlogicKeymaster::NibbleValue(const char& c, uint8_t* value) {
297 //CHECK(value != nullptr);
298 switch (c) {
299 case '0' ... '9':
300 *value = c - '0';
301 break;
302 case 'a' ... 'f':
303 *value = c - 'a' + 10;
304 break;
305 case 'A' ... 'F':
306 *value = c - 'A' + 10;
307 break;
308 default:
309 return false;
310 }
311
312 return true;
313}
314
315bool AmlogicKeymaster::HexToBytes(uint8_t* bytes, size_t bytes_len, const std::string& hex) {
316 //CHECK(bytes != nullptr);
317
318 if (hex.size() % 2 != 0) {
319 return false;
320 }
321 if (hex.size() / 2 > bytes_len) {
322 return false;
323 }
324 for (size_t i = 0, j = 0, n = hex.size(); i < n; i += 2, ++j) {
325 uint8_t high;
326 if (!NibbleValue(hex[i], &high)) {
327 return false;
328 }
329 uint8_t low;
330 if (!NibbleValue(hex[i + 1], &low)) {
331 return false;
332 }
333 bytes[j] = (high << 4) | low;
334 }
335 return true;
336}
337std::string AmlogicKeymaster::hex2bin(std::string const& s) {
338 //assert(s.length() % 2 == 0);
339 std::string sOut;
340 sOut.reserve(s.length()/2);
341
342 std::string extract;
343 for (std::string::const_iterator pos = s.begin(); pos<s.end(); pos += 2)
344 {
345 extract.assign(pos, pos+2);
346 sOut.push_back(std::stoi(extract, nullptr, 16));
347 }
348 return sOut;
349}
350#endif
351#endif
352} // namespace keymaster
353