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 | |
32 | namespace keymaster { |
33 | |
34 | int 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 | |
75 | AmlogicKeymaster::AmlogicKeymaster() {} |
76 | |
77 | AmlogicKeymaster::~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 */ |
87 | void 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 |
97 | static 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 | |
108 | void AmlogicKeymaster::GetVersion(const GetVersionRequest& request, GetVersionResponse* response) { |
109 | ForwardCommand(KM_GET_VERSION, request, response); |
110 | } |
111 | |
112 | void AmlogicKeymaster::SupportedAlgorithms(const SupportedAlgorithmsRequest& request, |
113 | SupportedAlgorithmsResponse* response) { |
114 | ForwardCommand(KM_GET_SUPPORTED_ALGORITHMS, request, response); |
115 | } |
116 | |
117 | void AmlogicKeymaster::SupportedBlockModes(const SupportedBlockModesRequest& request, |
118 | SupportedBlockModesResponse* response) { |
119 | ForwardCommand(KM_GET_SUPPORTED_BLOCK_MODES, request, response); |
120 | } |
121 | |
122 | void AmlogicKeymaster::SupportedPaddingModes(const SupportedPaddingModesRequest& request, |
123 | SupportedPaddingModesResponse* response) { |
124 | ForwardCommand(KM_GET_SUPPORTED_PADDING_MODES, request, response); |
125 | } |
126 | |
127 | void AmlogicKeymaster::SupportedDigests(const SupportedDigestsRequest& request, |
128 | SupportedDigestsResponse* response) { |
129 | ForwardCommand(KM_GET_SUPPORTED_DIGESTS, request, response); |
130 | } |
131 | |
132 | void AmlogicKeymaster::SupportedImportFormats(const SupportedImportFormatsRequest& request, |
133 | SupportedImportFormatsResponse* response) { |
134 | ForwardCommand(KM_GET_SUPPORTED_IMPORT_FORMATS, request, response); |
135 | } |
136 | |
137 | void AmlogicKeymaster::SupportedExportFormats(const SupportedExportFormatsRequest& request, |
138 | SupportedExportFormatsResponse* response) { |
139 | ForwardCommand(KM_GET_SUPPORTED_EXPORT_FORMATS, request, response); |
140 | } |
141 | |
142 | void AmlogicKeymaster::AddRngEntropy(const AddEntropyRequest& request, |
143 | AddEntropyResponse* response) { |
144 | ForwardCommand(KM_ADD_RNG_ENTROPY, request, response); |
145 | } |
146 | |
147 | void AmlogicKeymaster::Configure(const ConfigureRequest& request, ConfigureResponse* response) { |
148 | ForwardCommand(KM_CONFIGURE, request, response); |
149 | } |
150 | |
151 | void 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 | |
163 | void AmlogicKeymaster::GetKeyCharacteristics(const GetKeyCharacteristicsRequest& request, |
164 | GetKeyCharacteristicsResponse* response) { |
165 | ForwardCommand(KM_GET_KEY_CHARACTERISTICS, request, response); |
166 | } |
167 | |
168 | void AmlogicKeymaster::ImportKey(const ImportKeyRequest& request, ImportKeyResponse* response) { |
169 | ForwardCommand(KM_IMPORT_KEY, request, response); |
170 | } |
171 | |
172 | void AmlogicKeymaster::ImportWrappedKey(const ImportWrappedKeyRequest& request, |
173 | ImportWrappedKeyResponse* response) { |
174 | ForwardCommand(KM_IMPORT_WRAPPED_KEY, request, response); |
175 | } |
176 | |
177 | void AmlogicKeymaster::ExportKey(const ExportKeyRequest& request, ExportKeyResponse* response) { |
178 | ForwardCommand(KM_EXPORT_KEY, request, response); |
179 | } |
180 | |
181 | void AmlogicKeymaster::AttestKey(const AttestKeyRequest& request, AttestKeyResponse* response) { |
182 | ForwardCommand(KM_ATTEST_KEY, request, response); |
183 | } |
184 | |
185 | void AmlogicKeymaster::UpgradeKey(const UpgradeKeyRequest& request, UpgradeKeyResponse* response) { |
186 | ForwardCommand(KM_UPGRADE_KEY, request, response); |
187 | } |
188 | |
189 | void AmlogicKeymaster::DeleteKey(const DeleteKeyRequest& request, DeleteKeyResponse* response) { |
190 | ForwardCommand(KM_DELETE_KEY, request, response); |
191 | } |
192 | |
193 | void AmlogicKeymaster::DeleteAllKeys(const DeleteAllKeysRequest& request, |
194 | DeleteAllKeysResponse* response) { |
195 | ForwardCommand(KM_DELETE_ALL_KEYS, request, response); |
196 | } |
197 | |
198 | void AmlogicKeymaster::BeginOperation(const BeginOperationRequest& request, |
199 | BeginOperationResponse* response) { |
200 | ForwardCommand(KM_BEGIN_OPERATION, request, response); |
201 | } |
202 | |
203 | void AmlogicKeymaster::UpdateOperation(const UpdateOperationRequest& request, |
204 | UpdateOperationResponse* response) { |
205 | ForwardCommand(KM_UPDATE_OPERATION, request, response); |
206 | } |
207 | |
208 | void AmlogicKeymaster::FinishOperation(const FinishOperationRequest& request, |
209 | FinishOperationResponse* response) { |
210 | ForwardCommand(KM_FINISH_OPERATION, request, response); |
211 | } |
212 | |
213 | void AmlogicKeymaster::AbortOperation(const AbortOperationRequest& request, |
214 | AbortOperationResponse* response) { |
215 | ForwardCommand(KM_ABORT_OPERATION, request, response); |
216 | } |
217 | |
218 | GetHmacSharingParametersResponse 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 | |
226 | ComputeSharedHmacResponse AmlogicKeymaster::ComputeSharedHmac( |
227 | const ComputeSharedHmacRequest& request) { |
228 | ComputeSharedHmacResponse response; |
229 | ForwardCommand(KM_COMPUTE_SHARED_HMAC, request, &response); |
230 | return response; |
231 | } |
232 | |
233 | VerifyAuthorizationResponse AmlogicKeymaster::VerifyAuthorization( |
234 | const VerifyAuthorizationRequest& request) { |
235 | VerifyAuthorizationResponse response; |
236 | ForwardCommand(KM_VERIFY_AUTHORIZATION, request, &response); |
237 | return response; |
238 | } |
239 | #if AMLOGIC_MODIFY |
240 | void 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 |
296 | bool 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 | |
315 | bool 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 | } |
337 | std::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 |