1 /*
2  * Copyright (C) 2016 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 #pragma once
17 
18 #include <interface/hwkey/hwkey.h>
19 #include <lib/tipc/tipc.h>
20 #include <lib/tipc/tipc_srv.h>
21 #include <lk/compiler.h>
22 #include <stdbool.h>
23 #include <sys/types.h>
24 #include <uapi/trusty_uuid.h>
25 
26 struct hwkey_keyslot {
27     const char* key_id;
28     const uuid_t* uuid;
29     const void* priv;
30     uint32_t (*handler)(const struct hwkey_keyslot* slot,
31                         uint8_t* kbuf,
32                         size_t kbuf_len,
33                         size_t* klen);
34 };
35 
36 /**
37  * struct hwkey_derived_keyslot_data - data for a keyslot which derives its key
38  * by decrypting a fixed key
39  *
40  * This slot data is used by hwkey_get_derived_key() which will decrypt the
41  * encrypted data using the key from retriever().
42  *
43  * @encrypted_key_data:
44  *     Block-sized IV followed by encrypted key data
45  */
46 struct hwkey_derived_keyslot_data {
47     const uint8_t* encrypted_key_data;
48     const unsigned int* encrypted_key_size_ptr;
49     const void* priv;
50     uint32_t (*retriever)(const struct hwkey_derived_keyslot_data* data,
51                           uint8_t* kbuf,
52                           size_t kbuf_len,
53                           size_t* klen);
54 };
55 
56 /*
57  * Max size (in bytes) of a key returned by &struct
58  * hwkey_derived_keyslot_data.retriever
59  */
60 #define HWKEY_DERIVED_KEY_MAX_SIZE 32
61 
62 #define HWKEY_OPAQUE_HANDLE_SIZE 32
63 STATIC_ASSERT(HWKEY_OPAQUE_HANDLE_SIZE <= HWKEY_OPAQUE_HANDLE_MAX_SIZE);
64 
65 /**
66  * struct hwkey_opaque_handle_data - Opaque handle data for keyslots that allow
67  * opaque usage in hwaes.
68  *
69  * Intended for use in the @hwkey_keyslot.priv field. The retriever function is
70  * equivalent to the generic &hwkey_keyslot->handler but is called only when a
71  * service allowed to unwrap opaque requests this handle.
72  *
73  * @token:             The access token used as an opaque handle to
74  *                     reference this keyslot
75  * @allowed_uuids:     Array of UUIDs that are allowed to retrieve the
76  *                     plaintext key corresponding to an opaque handle
77  *                     for this slot
78  * @allowed_uuids_len: Length of the @allowed_reader_uuids array
79  * @priv:              Opaque pointer to keyslot-specific data
80  * @retriever:         Keyslot-specific callback which retrieves the
81  *                     actual key corresponding to this opaque handle.
82  */
83 struct hwkey_opaque_handle_data {
84     const uuid_t** allowed_uuids;
85     size_t allowed_uuids_len;
86     const void* priv;
87     uint32_t (*retriever)(const struct hwkey_opaque_handle_data* data,
88                           uint8_t* kbuf,
89                           size_t kbuf_len,
90                           size_t* klen);
91 };
92 
93 __BEGIN_CDECLS
94 
95 /**
96  * hwkey_get_derived_key() - Return a slot-specific key using the key data from
97  * hwkey_derived_keyslot_data
98  *
99  * Some devices may store a shared encryption key in hardware. However, we do
100  * not want to alllow multiple clients to directly use this key, as they would
101  * then be able to decrypt each other's data. To solve this, we want to be able
102  * to derive unique, client-specific keys from the shared encryption key.
103  *
104  * To use this handler for key derivation from a common shared key, the
105  * encrypting entity should generate a unique, random key for a particular
106  * client, then encrypt that unique key using the common shared key resulting in
107  * a wrapped, client-specific key. This wrapped key can then be safely embedded
108  * in the hwkey service in the &struct
109  * hwkey_derived_keyslot_data.encrypted_key_data field and will only be
110  * accessible using the shared key which is retrieved via the &struct
111  * hwkey_derived_keyslot_data.retriever callback.
112  */
113 uint32_t hwkey_get_derived_key(const struct hwkey_derived_keyslot_data* data,
114                                uint8_t* kbuf,
115                                size_t kbuf_len,
116                                size_t* klen);
117 
118 /**
119  * get_key_handle() - Handler for opaque keys
120  *
121  * Create and return an access token for a key slot. This key slot must contain
122  * a pointer to a &struct hwkey_opaque_handle_data in the &hwkey_keyslot.priv
123  * field.
124  */
125 uint32_t get_key_handle(const struct hwkey_keyslot* slot,
126                         uint8_t* kbuf,
127                         size_t kbuf_len,
128                         size_t* klen);
129 
130 /**
131  * get_opaque_key() - Get an opaque key given an access handle
132  *
133  * @access_token: pointer to an access_token_t
134  */
135 uint32_t get_opaque_key(const uuid_t* uuid,
136                         const char* access_token,
137                         uint8_t* kbuf,
138                         size_t kbuf_len,
139                         size_t* klen);
140 
141 int hwkey_init_srv_provider(struct tipc_hset* hset);
142 
143 void hwkey_install_keys(const struct hwkey_keyslot* keys, unsigned int kcnt);
144 
145 int hwkey_chan_handle_msg(const struct tipc_port* _port,
146                           handle_t _chan,
147                           void* _received_ctx);
148 
149 int hwkey_chan_ctx_create(const struct tipc_port* port,
150                           handle_t chan,
151                           const struct uuid* peer,
152                           void** ctx);
153 
154 void hwkey_chan_ctx_close(void* ctx);
155 
156 uint32_t derive_key_v1(const uuid_t* uuid,
157                        const uint8_t* ikm_data,
158                        size_t ikm_len,
159                        uint8_t* key_data,
160                        size_t key_len);
161 
162 /**
163  * get_current_os_rollback_versions() - Get the current OS rollback version
164  * @source: Source of the rollback version, one of &enum
165  *          hwkey_rollback_version_source.
166  *
167  * Return: Negative error code on failure, current rollback version otherwise
168  */
169 int32_t get_current_os_rollback_version(uint32_t source);
170 
171 /*
172  * This sample service supports only the first version element in the
173  * rollback_versions array in struct hwkey_derive_versioned_msg.
174  */
175 #define HWKEY_ROLLBACK_VERSION_SUPPORTED_COUNT 1
176 
177 uint32_t derive_key_versioned_v1(
178         const uuid_t* uuid,
179         bool shared,
180         uint32_t rollback_version_source,
181         int32_t rollback_versions[HWKEY_ROLLBACK_VERSION_INDEX_COUNT],
182         const uint8_t* context,
183         size_t context_len,
184         uint8_t* key_data,
185         size_t key_len);
186 
187 __END_CDECLS
188