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