1 /*
2  * Copyright (C) 2014-2015 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 #pragma once
18 
19 #include <lk/compiler.h>
20 #include <stdbool.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #include <interface/hwkey/hwkey.h>
25 #include <trusty_ipc.h>
26 
27 __BEGIN_CDECLS
28 
29 typedef handle_t hwkey_session_t;
30 
31 /**
32  * hwkey_open() - Opens a trusty hwkey session.
33  *
34  * Return: a hwkey_session_t > 0 on success, * or an error code < 0 on
35  * failure.
36  */
37 long hwkey_open(void);
38 
39 /**
40  * hwkey_get_keyslot_data() - Gets the keyslot data referenced by slot_id.
41  * @session:    session handle retrieved from hwkey_open
42  * @slot_id:    string identifier for the requested keyslot
43  * @data:       buffer for retrieved data
44  * @data_size:  pointer to allocated size of data buffer. Updated to actual
45  *              retrieved size if different from allocated size.
46  *
47  * Fills *data with result if size is sufficient. If actual size is less than
48  * data_size, data_size is updated with the * actual returned size.
49  *
50  * Return: NO_ERROR on success, error code less than 0 on error. Possible error
51  * codes include:
52  * - ERR_NOT_VALID: if input is NULL
53  * - ERR_IO: if there's an issue communicating with the server
54  * - ERR_TOO_BIG: if keyslot does not fit in data buffer
55  * - ERR_NOT_FOUND: if keyslot is not found
56  */
57 long hwkey_get_keyslot_data(hwkey_session_t session,
58                             const char* slot_id,
59                             uint8_t* data,
60                             uint32_t* data_size);
61 
62 /**
63  * hwkey_derive() - Derives a cryptographic key based on input values.
64  * @session:        session handle retrieved from hwkey_open
65  * @kdf_version:    key derivation function version. If most recent supported
66  *                  version is desired, pass HWKEY_KDF_VERSION_BEST. Actual KDF
67  *                  used is written to field as out param.
68  * @src:            the input for the KDF (key-derivation function)
69  * @dest:           The result buffer into which the derived key is written.
70  *                  Must be at least *src_buf_len bytes.
71  * @buf_size:       The size of src and dest.
72  *
73  * Return: NO_ERROR on success, error code less than 0 on error. Possible error
74  * codes include:
75  * - ERR_NOT_VALID: if input is NULL or if kdf_version is not supported
76  * - ERR_IO: if there's an issue communicating with the server
77  * - ERR_BAD_LEN: if buf_size is not valid
78  *
79  */
80 long hwkey_derive(hwkey_session_t session,
81                   uint32_t* kdf_version,
82                   const uint8_t* src,
83                   uint8_t* dest,
84                   uint32_t buf_size);
85 
86 /**
87  * struct hwkey_versioned_key_options - Options that control how a versioned
88  *                                      key will be derived.
89  * @kdf_version:
90  *     (in/out) the version of the KDF to use. If set to %HWKEY_KDF_VERSION_BEST
91  *     the latest version will be used and will be written back to the struct.
92  * @shared_key:
93  *     if true, the derived key will be consistent and shared across the entire
94  *     family of devices, given the same input. If false, the derived key will
95  *     be unique to the particular device it was derived on.
96  * @rollback_version_source:
97  *     specifies whether the @rollback_version must have been committed. If
98  *     %HWKEY_ROLLBACK_COMMITTED_VERSION is specified, the system must guarantee
99  *     that software with a lower rollback version cannot ever run on a future
100  *     boot. (see &enum hwkey_rollback_version_source)
101  * @os_rollback_version:
102  *     (in/out) the OS rollback version to be incorporated into the key
103  *     derivation. Must be less than or equal to the current Trusty OS rollback
104  *     version from @rollback_version_source. If set to
105  *     %HWKEY_ROLLBACK_VERSION_CURRENT the latest available version will be used
106  *     and will be written back to the struct.
107  * @context:
108  *     an arbitrary set of bytes incorporated into the key derivation. May have
109  *     an implementation-specific maximum length, but it is guaranteed to accept
110  *     at least 32 bytes. May not be null unless @key_len is zero.
111  * @context_len:
112  *     length of @context. May not be zero unless @key_len is also zero.
113  * @key:
114  *     destination of the derived key. Contains the derived key on success. May
115  *     have an implementation-specific maximum length, but it is guaranteed to
116  *     produce at least 32 bytes. May be null if @key_len is zero.
117  * @key_len:
118  *     length of the @key buffer. @key_len bytes will be derived or an error
119  *     will be returned. May be zero to query the current OS rollback version
120  *     without deriving a key.
121  *
122  * Default field semantics (i.e. if zeroed):
123  * * @kdf_version: %HWKEY_KDF_VERSION_BEST, version used will be passed back in
124  *                 this field.
125  * * @shared_key: Device-unique key
126  * * @rollback_version_source: %HWKEY_ROLLBACK_COMMITTED_VERSION
127  * * @os_rollback_version: Version 0
128  * * @context: Null, i.e. no user-supplied context will be added. If null,
129  *             @context_len and @key_len must be 0.
130  * * @context_len: 0
131  * * @key: Null, i.e. no key will be generated, only the current versions may be
132  *         queried. If null, @key_len must be 0.
133  * * @key_len: 0
134  *
135  * Additional fields may be added in the future, e.g. rollback versions for
136  * additional system components. Additional future fields will not change the
137  * resulting key when set to zero, so they will not affect existing key
138  * derivations as long as any unspecified fields in the struct are zeroed.
139  */
140 struct hwkey_versioned_key_options {
141     uint32_t kdf_version;
142     bool shared_key;
143     enum hwkey_rollback_version_source rollback_version_source;
144     int32_t os_rollback_version;
145     const uint8_t* context;
146     size_t context_len;
147     uint8_t* key;
148     size_t key_len;
149 };
150 
151 /**
152  * hwkey_derive_versioned() - Derive a versioned, device-specific key from
153  *                            provided context.
154  * @session: session handle retrieved from hwkey_open
155  * @args:    arguments controlling key derivation, see &enum
156  *           hwkey_derive_versioned_key_args.
157  *
158  * Derives a versioned key from provided context input. Gates access to keys
159  * based on the rollback version of Trusty, so that an app may not derive keys
160  * for future rollback versions. The intent is that after an update, a previous,
161  * potentially compromised app cannot derive keys tied to the newly updated
162  * rollback version. These new keys may then be used to re-secure the device
163  * after the vulnerability has been fixed without danger of unpatched software
164  * being able to forward compromise the device.
165  *
166  * Changing any of the input parameters should result in a completely different
167  * key being derived. You will need to keep the parameters stable for
168  * compatibility with previously generated keys. You may need to prefix wrapped
169  * data blobs with the parameters used for key derivation (os_rollback_version,
170  * for example) so they can be unwrapped correctly. One exception is that
171  * different values of key_len may not change all of the derived key material. A
172  * shorter key may be the prefix of a longer key.
173  *
174  * Apps with different UUIDs will derive different keys, even with the same
175  * parameters.
176  *
177  * If @args->shared_key is false, a key unique to the specific device it was
178  * derived on will be generated. A device unique key should be considered the
179  * secure default and used if at all possible.
180  *
181  * If @args->shared_key is true, this function will generated the same key when
182  * invoked with the same input parameters across devices in the same family.
183  * This kind of key is useful when it is necessary to agree on a shared secret
184  * with a remote server and there is no channel to transfer the secret, e.g.,
185  * encryption key for OTAed data. Shared keys may not be available on all
186  * platforms, and are generally less secure than local keys. The definition of a
187  * device family is vendor-specific. If possible, set @args->shared_key to
188  * false.
189  *
190  * If @args->shared_key is false and @args->os_rollback_version is 0, this
191  * function will be backwards compatible with the key derivation in
192  * hwkey_derive(). This allows a client to migrate away from the old
193  * hwkey_derive() API without changing the derived key output. When backwards
194  * compatibility is required, @rollback_version_source is ignored and the same
195  * key is generated regardless of source, since that parameter is not available
196  * in the hwkey_derive() API.
197  *
198  * If @args->os_rollback_version is %HWKEY_ROLLBACK_VERSION_CURRENT and the
199  * current version is 0, compatibility will be provided as if 0 was passed
200  * explicitly.
201  *
202  * We plan to deprecate and remove hwkey_derive(); on devices that never
203  * supported hwkey_derive(), the versioned derive API will not support backwards
204  * compatibility.
205  *
206  * Return: NO_ERROR on success, error code less than 0 on error. Possible error
207  * codes (see &enum hwkey_err):
208  * * ERR_NOT_VALID - invalid parameters
209  * * ERR_BAD_LEN   - a buffer size was invalid
210  * * ERR_NOT_IMPLEMENTED - the requested version source or KDF mode is
211  *   not implemented
212  * * ERR_NOT_FOUND - requested key version does not exist
213  */
214 long hwkey_derive_versioned(hwkey_session_t session,
215                             struct hwkey_versioned_key_options* args);
216 
217 /**
218  * hwkey_close() - Closes the session.
219  */
220 void hwkey_close(hwkey_session_t session);
221 
222 __END_CDECLS
223