-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
pkcs11_token.h
355 lines (316 loc) · 11.9 KB
/
pkcs11_token.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2017-2020, Linaro Limited
*/
#ifndef PKCS11_TA_PKCS11_TOKEN_H
#define PKCS11_TA_PKCS11_TOKEN_H
#include <sys/queue.h>
#include <tee_api_types.h>
#include <tee_internal_api.h>
#include <utee_defines.h>
#include "handle.h"
#include "object.h"
#include "pkcs11_attributes.h"
/* Hard coded description */
#define PKCS11_SLOT_DESCRIPTION "OP-TEE PKCS11 TA"
#define PKCS11_SLOT_MANUFACTURER "Linaro"
#define PKCS11_SLOT_HW_VERSION { 0, 0 }
#define PKCS11_SLOT_FW_VERSION { PKCS11_TA_VERSION_MAJOR, \
PKCS11_TA_VERSION_MINOR }
#define PKCS11_TOKEN_LABEL "OP-TEE PKCS#11 TA token"
#define PKCS11_TOKEN_MANUFACTURER PKCS11_SLOT_MANUFACTURER
#define PKCS11_TOKEN_MODEL "OP-TEE TA"
#define PKCS11_TOKEN_HW_VERSION PKCS11_SLOT_HW_VERSION
#define PKCS11_TOKEN_FW_VERSION PKCS11_SLOT_FW_VERSION
enum pkcs11_token_state {
PKCS11_TOKEN_RESET = 0,
PKCS11_TOKEN_READ_WRITE,
PKCS11_TOKEN_READ_ONLY,
};
TAILQ_HEAD(client_list, pkcs11_client);
TAILQ_HEAD(session_list, pkcs11_session);
struct pkcs11_client;
#define PKCS11_MAX_USERS 2
#define PKCS11_TOKEN_PIN_SIZE_MAX 128
#define PKCS11_TOKEN_PIN_SIZE_MIN 4
#define PKCS11_TOKEN_SO_PIN_COUNT_MAX 7
#define PKCS11_TOKEN_USER_PIN_COUNT_MAX 7
/*
* Persistent state of the token
*
* @version - currently unused...
* @label - pkcs11 formatted token label, set by client
* @flags - pkcs11 token flags
* @so_pin_count - counter on security officer login failure
* @so_pin_salt - stores salt in hash of SO PIN, 0 if not set
* @so_pin_hash - stores hash of SO PIN
* @user_pin_count - counter on user login failure
* @user_pin_salt - stores salt in hash of user PIN, 0 if not set
* @user_pin_hash - stores hash of user PIN
*/
struct token_persistent_main {
uint32_t version;
uint8_t label[PKCS11_TOKEN_LABEL_SIZE];
uint32_t flags;
uint32_t so_pin_count;
uint32_t so_pin_salt;
union {
uint8_t so_pin_hash[TEE_MAX_HASH_SIZE];
TEE_Identity so_identity;
};
uint32_t user_pin_count;
uint32_t user_pin_salt;
union {
uint8_t user_pin_hash[TEE_MAX_HASH_SIZE];
TEE_Identity user_identity;
};
};
/*
* Persistent objects in the token
*
* @count - number of objects stored in the token
* @uuids - array of object references/UUIDs (@count items)
*/
struct token_persistent_objs {
uint32_t count;
TEE_UUID uuids[];
};
/*
* Runtime state of the token, complies with pkcs11
*
* @state - Pkcs11 login is public, user, SO or custom
* @session_count - Counter for opened Pkcs11 sessions
* @rw_session_count - Count for opened Pkcs11 read/write sessions
* @object_list - List of the objects owned by the token
* @db_main - Volatile copy of the persistent main database
* @db_objs - Volatile copy of the persistent object database
*/
struct ck_token {
enum pkcs11_token_state state;
uint32_t session_count;
uint32_t rw_session_count;
struct object_list object_list;
/* Copy in RAM of the persistent database */
struct token_persistent_main *db_main;
struct token_persistent_objs *db_objs;
};
/*
* A session can enter a processing state (encrypt, decrypt, digest, ...)
* only from the initialized state. A session must return the initialized
* state (from a processing finalization request) before entering another
* processing state.
*/
enum pkcs11_proc_state {
PKCS11_SESSION_READY = 0, /* No active processing */
PKCS11_SESSION_ENCRYPTING,
PKCS11_SESSION_DECRYPTING,
PKCS11_SESSION_DIGESTING,
PKCS11_SESSION_DIGESTING_ENCRYPTING, /* case C_DigestEncryptUpdate */
PKCS11_SESSION_DECRYPTING_DIGESTING, /* case C_DecryptDigestUpdate */
PKCS11_SESSION_SIGNING,
PKCS11_SESSION_SIGNING_ENCRYPTING, /* case C_SignEncryptUpdate */
PKCS11_SESSION_VERIFYING,
PKCS11_SESSION_DECRYPTING_VERIFYING, /* case C_DecryptVerifyUpdate */
PKCS11_SESSION_SIGNING_RECOVER,
PKCS11_SESSION_VERIFYING_RECOVER,
PKCS11_SESSION_BUSY,
};
/*
* Context of the active processing in the session
*
* @state - ongoing active processing function or ready state
* @mecha_type - mechanism type of the active processing
* @always_authen - true if user need to login before each use
* @relogged - true once client logged since last operation update
* @op_step - last active operation step - update, final or one-shot
* @tee_op_handle - handle on active crypto operation or TEE_HANDLE_NULL
* @tee_op_handle2 - second handle for specific operations or TEE_HANDLE_NULL
* @tee_hash_algo - hash algorithm identifier.
* @extra_ctx - context for the active processing
*/
struct active_processing {
enum pkcs11_proc_state state;
uint32_t mecha_type;
enum processing_step step;
bool always_authen;
bool relogged;
TEE_OperationHandle tee_op_handle;
TEE_OperationHandle tee_op_handle2;
uint32_t tee_hash_algo;
void *extra_ctx;
};
/*
* Pkcs11 objects search context
*
* @attributes - matching attributes list searched (null if no search)
* @count - number of matching handle found
* @handles - array of handle of matching objects
* @next - index of the next object handle to return to C_FindObject
*/
struct pkcs11_find_objects {
void *attributes;
size_t count;
uint32_t *handles;
size_t next;
};
/*
* Structure tracking the PKCS#11 sessions
*
* @link - List of the session belonging to a client
* @client - Client the session belongs to
* @token - Token this session belongs to
* @handle - Identifier of the session published to the client
* @object_list - Entry of the session objects list
* @state - R/W SO, R/W user, RO user, R/W public, RO public.
* @processing - Reference to initialized processing context if any
* @find_ctx - Reference to active search context (null if no active search)
*/
struct pkcs11_session {
TAILQ_ENTRY(pkcs11_session) link;
struct pkcs11_client *client;
struct ck_token *token;
enum pkcs11_mechanism_id handle;
struct object_list object_list;
enum pkcs11_session_state state;
struct active_processing *processing;
struct pkcs11_find_objects *find_ctx;
};
/* Initialize static token instance(s) from default/persistent database */
TEE_Result pkcs11_init(void);
void pkcs11_deinit(void);
/* Speculation safe lookup of token instance from token identifier */
struct ck_token *get_token(unsigned int token_id);
/* Return token identified from token instance address */
unsigned int get_token_id(struct ck_token *token);
/* Return client's (shared) object handle database associated with session */
struct handle_db *get_object_handle_db(struct pkcs11_session *session);
/* Access to persistent database */
struct ck_token *init_persistent_db(unsigned int token_id);
void update_persistent_db(struct ck_token *token);
void close_persistent_db(struct ck_token *token);
/* Load and release persistent object attributes in memory */
enum pkcs11_rc load_persistent_object_attributes(struct pkcs11_object *obj);
void release_persistent_object_attributes(struct pkcs11_object *obj);
enum pkcs11_rc update_persistent_object_attributes(struct pkcs11_object *obj);
enum pkcs11_rc hash_pin(enum pkcs11_user_type user, const uint8_t *pin,
size_t pin_size, uint32_t *salt,
uint8_t hash[TEE_MAX_HASH_SIZE]);
enum pkcs11_rc verify_pin(enum pkcs11_user_type user, const uint8_t *pin,
size_t pin_size, uint32_t salt,
const uint8_t hash[TEE_MAX_HASH_SIZE]);
#if defined(CFG_PKCS11_TA_AUTH_TEE_IDENTITY)
enum pkcs11_rc setup_so_identity_auth_from_client(struct ck_token *token);
enum pkcs11_rc setup_identity_auth_from_pin(struct ck_token *token,
enum pkcs11_user_type user_type,
const uint8_t *pin,
size_t pin_size);
enum pkcs11_rc verify_identity_auth(struct ck_token *token,
enum pkcs11_user_type user_type);
#else
static inline enum pkcs11_rc
setup_so_identity_auth_from_client(struct ck_token *token __unused)
{
return PKCS11_CKR_PIN_INVALID;
}
static inline enum pkcs11_rc
setup_identity_auth_from_pin(struct ck_token *token __unused,
enum pkcs11_user_type user_type __unused,
const uint8_t *pin __unused,
size_t pin_size __unused)
{
return PKCS11_CKR_PIN_INVALID;
}
static inline enum pkcs11_rc
verify_identity_auth(struct ck_token *token __unused,
enum pkcs11_user_type user_type __unused)
{
return PKCS11_CKR_PIN_INCORRECT;
}
#endif /* CFG_PKCS11_TA_AUTH_TEE_IDENTITY */
/* Token persistent objects */
enum pkcs11_rc create_object_uuid(struct ck_token *token,
struct pkcs11_object *obj);
void destroy_object_uuid(struct ck_token *token, struct pkcs11_object *obj);
enum pkcs11_rc unregister_persistent_object(struct ck_token *token,
TEE_UUID *uuid);
enum pkcs11_rc register_persistent_object(struct ck_token *token,
TEE_UUID *uuid);
enum pkcs11_rc get_persistent_objects_list(struct ck_token *token,
TEE_UUID *array, size_t *size);
/*
* Pkcs11 session support
*/
struct session_list *get_session_list(struct pkcs11_session *session);
struct pkcs11_client *tee_session2client(void *tee_session);
struct pkcs11_client *register_client(void);
void unregister_client(struct pkcs11_client *client);
struct pkcs11_session *pkcs11_handle2session(uint32_t handle,
struct pkcs11_client *client);
static inline bool session_is_active(struct pkcs11_session *session)
{
return session->processing;
}
enum pkcs11_rc set_processing_state(struct pkcs11_session *session,
enum processing_func function,
struct pkcs11_object *obj1,
struct pkcs11_object *obj2);
static inline bool pkcs11_session_is_read_write(struct pkcs11_session *session)
{
return session->state == PKCS11_CKS_RW_PUBLIC_SESSION ||
session->state == PKCS11_CKS_RW_USER_FUNCTIONS ||
session->state == PKCS11_CKS_RW_SO_FUNCTIONS;
}
static inline bool pkcs11_session_is_public(struct pkcs11_session *session)
{
return session->state == PKCS11_CKS_RO_PUBLIC_SESSION ||
session->state == PKCS11_CKS_RW_PUBLIC_SESSION;
}
static inline bool pkcs11_session_is_user(struct pkcs11_session *session)
{
return session->state == PKCS11_CKS_RO_USER_FUNCTIONS ||
session->state == PKCS11_CKS_RW_USER_FUNCTIONS;
}
static inline bool pkcs11_session_is_so(struct pkcs11_session *session)
{
return session->state == PKCS11_CKS_RW_SO_FUNCTIONS;
}
static inline
struct object_list *pkcs11_get_session_objects(struct pkcs11_session *session)
{
return &session->object_list;
}
static inline
struct ck_token *pkcs11_session2token(struct pkcs11_session *session)
{
return session->token;
}
/* Invalidate any handle referring the object since the object no more exists */
void token_invalidate_object_handles(struct pkcs11_object *obj);
/* Entry point for the TA commands */
enum pkcs11_rc entry_ck_slot_list(uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_slot_info(uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_token_info(uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_token_mecha_ids(uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_token_mecha_info(uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_open_session(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_close_session(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_close_all_sessions(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_session_info(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_token_initialize(uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_init_pin(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_set_pin(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_login(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_logout(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_seed_random(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
enum pkcs11_rc entry_ck_generate_random(struct pkcs11_client *client,
uint32_t ptypes, TEE_Param *params);
#endif /*PKCS11_TA_PKCS11_TOKEN_H*/