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