1 /*
2 * Copyright (C) 2022 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 TLOG_TAG "apploader_policy_engine"
18
19 #include <lib/apploader_policy_engine/apploader_policy_engine.h>
20
21 #include <interface/hwkey/hwkey.h>
22 #include <inttypes.h>
23 #include <lib/hwkey/hwkey.h>
24 #include <stddef.h>
25 #include <trusty_log.h>
26 #include <uapi/err.h>
27 #include <uapi/trusty_uuid.h>
28 #include <string>
29
30 /*
31 * Copied from apploader.c
32 */
33 /*
34 * Maximum size of any key we could possibly get from hwkey.
35 * If the latter returns a key larger than this, validation fails.
36 * For now, 128 bytes should be enough since the apploader only
37 * supports 256-bit (P-256) ECDSA signatures which only need
38 * about 90 bytes for their public keys. If other curves or algorithms
39 * e.g., P-521 or RSS, are supported by the apploader at a later time,
40 * this value will need to increase.
41 */
42 constexpr uint32_t kMaximumKeySize =
43 std::max(128, HWKEY_OPAQUE_HANDLE_MAX_SIZE);
44
get_key(hwkey_session_t hwkey_session,std::string_view op,uint8_t key_id,const uint8_t ** public_key,unsigned int * public_key_size)45 static int get_key(hwkey_session_t hwkey_session,
46 std::string_view op,
47 uint8_t key_id,
48 const uint8_t** public_key,
49 unsigned int* public_key_size) {
50 std::string key_slot{"com.android.trusty.apploader."};
51 key_slot += op;
52 key_slot += ".key.";
53 key_slot += std::to_string(static_cast<unsigned>(key_id));
54
55 unsigned int key_size = kMaximumKeySize;
56 uint8_t* key_bytes = (uint8_t*)malloc(key_size * sizeof(uint8_t));
57 if (!key_bytes) {
58 TLOGE("Failed to allocate memory for key\n");
59 return ERR_NO_MEMORY;
60 }
61
62 long rc = hwkey_get_keyslot_data(hwkey_session, key_slot.c_str(), key_bytes,
63 &key_size);
64 if (rc < 0) {
65 TLOGE("Failed to get key %" PRIu8 " from hwkey (%ld)\n", key_id, rc);
66 free(key_bytes);
67 return rc;
68 }
69
70 *public_key = key_bytes;
71 *public_key_size = key_size;
72
73 return NO_ERROR;
74 }
75
get_sign_key(uint8_t key_id,const uint8_t ** public_key,unsigned int * public_key_size)76 static int get_sign_key(uint8_t key_id,
77 const uint8_t** public_key,
78 unsigned int* public_key_size) {
79 long rc = hwkey_open();
80 if (rc < 0) {
81 TLOGE("Failed to connect to hwkey (%ld)\n", rc);
82 return rc;
83 }
84
85 hwkey_session_t hwkey_session = static_cast<hwkey_session_t>(rc);
86
87 rc = get_key(hwkey_session, "sign", key_id, public_key, public_key_size);
88 hwkey_close(hwkey_session);
89
90 return rc;
91 }
92
apploader_policy_engine_get_key(uint8_t kid,const uint8_t ** public_key_ptr,unsigned int * public_key_size_ptr)93 int apploader_policy_engine_get_key(uint8_t kid,
94 const uint8_t** public_key_ptr,
95 unsigned int* public_key_size_ptr) {
96 return get_sign_key(kid, public_key_ptr, public_key_size_ptr);
97 }
98
apploader_policy_engine_put_key(const uint8_t * public_key)99 void apploader_policy_engine_put_key(const uint8_t* public_key) {
100 if (public_key) {
101 free((void*)public_key);
102 }
103 }
104
apploader_policy_engine_validate(struct apploader_policy_data * data)105 bool apploader_policy_engine_validate(struct apploader_policy_data* data) {
106 return true;
107 }
108