Coverage Report

Created: 2025-10-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/tests/fuzzing/fuzz_pkcs11.c
Line
Count
Source
1
/*
2
 * fuzz_pkcs11.c: Fuzz target for PKCS #11 API
3
 *
4
 * Copyright (C) 2022 Red Hat, Inc.
5
 *
6
 * Author: Veronika Hanulikova <vhanulik@redhat.com>
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
26
#include "pkcs11/pkcs11.h"
27
#include "pkcs11/pkcs11-opensc.h"
28
#include "pkcs11/sc-pkcs11.h"
29
#include "fuzzer_reader.h"
30
#include "fuzzer_tool.h"
31
32
#define SIG_LEN 512
33
34
/* If disabled, card is connected only via C_Initialize */
35
#define FUZZING 1
36
37
extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0;
38
static CK_FUNCTION_LIST_3_0_PTR p11 = NULL;
39
40
/* Values used for key template*/
41
static CK_BBOOL _true = TRUE;
42
static CK_BBOOL _false = FALSE;
43
44
/* Global parameters for key template */
45
CK_ULONG key_type = 0;
46
unsigned char ecparams[256];
47
unsigned char *opt_object_label[256];
48
CK_BYTE opt_object_id[100];
49
CK_MECHANISM_TYPE opt_allowed_mechanisms[20];
50
51
#if FUZZING 
52
static int fuzz_card_connect(const uint8_t *data, size_t size, sc_pkcs11_slot_t **slot_out)
53
15.4k
{
54
  /* Works in the same manner as card_detect() for only one slot and card with virtual reader */
55
15.4k
  struct sc_pkcs11_card *p11card = NULL;
56
15.4k
  struct sc_reader *reader = NULL;
57
15.4k
  struct sc_app_info *app_generic = NULL;
58
15.4k
  sc_pkcs11_slot_t *slot = NULL;
59
15.4k
  int rv = CKR_OK, free_p11card = 0;
60
61
  /* Erase possible virtual slots*/
62
15.4k
  list_clear(&virtual_slots);
63
64
  /* Erase possible readers from context */
65
15.4k
  while (list_size(&context->readers)) {
66
0
    sc_reader_t *rdr = (sc_reader_t *) list_get_at(&context->readers, 0);
67
0
    _sc_delete_reader(context, rdr);
68
0
  }
69
15.4k
  if (context->reader_driver->ops->finish != NULL)
70
15.4k
    context->reader_driver->ops->finish(context);
71
72
  /* Create virtual reader */
73
15.4k
  context->reader_driver = sc_get_fuzz_driver();
74
15.4k
  fuzz_add_reader(context, data, size);
75
15.4k
  reader = sc_ctx_get_reader(context, 0);
76
77
  /* Add slot for reader */
78
15.4k
  if (create_slot(reader) != CKR_OK) {
79
0
    goto fail;
80
0
  }
81
82
  /* Locate a slot related to the reader */
83
15.4k
  for (size_t i = 0; i < list_size(&virtual_slots); i++) {
84
15.4k
    slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
85
15.4k
    if (slot->reader == reader) {
86
15.4k
      p11card = slot->p11card;
87
15.4k
      break;
88
15.4k
    }
89
15.4k
  }
90
91
  /* Create p11card */
92
15.4k
  p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card));
93
15.4k
  p11card->reader = reader;
94
15.4k
  free_p11card = 1;
95
96
  /* Connect card to reader */
97
15.4k
  if ((rv = sc_connect_card(reader, &p11card->card)) != SC_SUCCESS) {
98
3.00k
    goto fail;
99
3.00k
  }
100
12.4k
  init_slot_info(&slot->slot_info, reader);
101
102
  /* Instead of detecting framework*/
103
12.4k
  p11card->framework = &framework_pkcs15;
104
105
  /* Bind 'generic' application or (emulated?) card without applications */
106
12.4k
  app_generic = sc_pkcs15_get_application_by_type(p11card->card, "generic");
107
12.4k
  if (app_generic || !p11card->card->app_count) {
108
11.0k
    scconf_block *conf_block = NULL;
109
110
11.0k
    conf_block = sc_match_atr_block(p11card->card->ctx, NULL, &p11card->reader->atr);
111
11.0k
    if (!conf_block) /* check default block */
112
11.0k
      conf_block = sc_get_conf_block(context, "framework", "pkcs15", 1);
113
114
11.0k
    rv = p11card->framework->bind(p11card, app_generic);
115
11.0k
    if (rv != CKR_TOKEN_NOT_RECOGNIZED && rv != CKR_OK)
116
1.06k
      goto fail;
117
118
9.94k
    rv = p11card->framework->create_tokens(p11card, app_generic);
119
9.94k
    if (rv != CKR_OK)
120
0
      goto fail;
121
9.94k
    free_p11card = 0;
122
9.94k
  }
123
  
124
  /* Bind rest of application*/
125
15.0k
  for (int j = 0; j < p11card->card->app_count; j++)   {
126
3.71k
    struct sc_app_info *app_info = p11card->card->app[j];
127
128
3.71k
    if (app_generic && app_generic == p11card->card->app[j])
129
0
      continue;
130
131
3.71k
    if (p11card->framework->bind(p11card, app_info) != CKR_OK) {
132
3.09k
      continue;
133
3.09k
    }
134
626
    rv = p11card->framework->create_tokens(p11card, app_info);
135
626
    if (rv != CKR_OK) {
136
0
      goto fail;
137
0
    }
138
626
    free_p11card = 0;
139
626
  }
140
11.3k
  if (slot_out)
141
254
    *slot_out = slot;
142
15.4k
fail:
143
15.4k
  if (free_p11card) {
144
5.21k
    sc_pkcs11_card_free(p11card);
145
5.21k
  }
146
15.4k
  return rv;
147
11.3k
}
148
#endif
149
150
static int fuzz_pkcs11_initialize(const uint8_t *data, size_t size, sc_pkcs11_slot_t **slot_out, CK_SESSION_HANDLE *session)
151
15.4k
{
152
15.4k
  p11 = &pkcs11_function_list_3_0;
153
154
15.4k
  context = NULL;
155
15.4k
  memset(&sc_pkcs11_conf, 0, sizeof(struct sc_pkcs11_config));
156
157
15.4k
  p11->C_Initialize(NULL);
158
159
15.4k
  #if FUZZING
160
  /* fuzz target can connect to real card via C_Initialize */
161
15.4k
  if (fuzz_card_connect(data, size, slot_out) != CKR_OK) {
162
4.06k
    p11->C_Finalize(NULL);
163
4.06k
    return CKR_GENERAL_ERROR;
164
4.06k
  }
165
11.3k
  #endif
166
167
11.3k
  if (p11->C_OpenSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, session) != CKR_OK) {
168
1.14k
    p11->C_Finalize(NULL);
169
1.14k
    return CKR_GENERAL_ERROR;
170
1.14k
  }
171
10.2k
  return CKR_OK;
172
11.3k
}
173
174
static int set_mechanism(const uint8_t **data, size_t *size, CK_MECHANISM *mech)
175
1.75k
{
176
1.75k
  if (*size < sizeof(unsigned long int))
177
0
    return 1;
178
179
1.75k
  memset(mech, 0, sizeof(*mech));
180
1.75k
  (*mech).mechanism = *((unsigned long int *)*data);
181
1.75k
  *data += sizeof(unsigned long int);
182
1.75k
  *size -= sizeof(unsigned long int);
183
1.75k
  return 0;
184
1.75k
}
185
186
static void test_change_pin(const unsigned char *data, size_t size)
187
1.02k
{
188
1.02k
  CK_SESSION_HANDLE session;
189
1.02k
  CK_TOKEN_INFO     info;
190
1.02k
  char             *pin = NULL;
191
1.02k
  char             *new_pin = NULL;
192
1.02k
  int               login_type = data[0];
193
1.02k
  data++; size--;
194
195
1.02k
  if (!(pin = extract_word(&data, &size)))
196
2
    goto end;
197
1.02k
  if (!(new_pin = extract_word(&data, &size)))
198
1
    goto end;
199
200
1.02k
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
201
153
    goto end;
202
870
  p11->C_GetTokenInfo(0, &info);
203
870
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin));
204
870
  p11->C_SetPIN(session,
205
870
    (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin),
206
870
    (CK_UTF8CHAR *) new_pin, new_pin == NULL ? 0 : strlen(new_pin));
207
208
870
  p11->C_CloseSession(session);
209
870
  p11->C_Finalize(NULL);
210
1.02k
end:
211
1.02k
  free(new_pin);
212
1.02k
  free(pin);
213
1.02k
}
214
215
static void test_init_pin(const unsigned char *data, size_t size)
216
450
{
217
450
  CK_SESSION_HANDLE session;
218
450
  CK_TOKEN_INFO     info;
219
450
  char             *pin = NULL;
220
450
  char             *so_pin = NULL;
221
450
  int               login_type = data[0];
222
450
  data++; size--;
223
224
450
  if (!(pin = extract_word(&data, &size)))
225
1
    goto end;
226
449
  if (!(so_pin = extract_word(&data, &size)))
227
2
    goto end;
228
229
447
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
230
108
    goto end;
231
339
  p11->C_GetTokenInfo(0, &info);
232
339
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) so_pin, so_pin == NULL ? 0 : strlen(so_pin));
233
339
  p11->C_InitPIN(session, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin));
234
235
339
  p11->C_CloseSession(session);
236
339
  p11->C_Finalize(NULL);
237
450
end:
238
450
  free(pin);
239
450
  free(so_pin);
240
450
}
241
242
static void test_init_token(const unsigned char *data, size_t size)
243
375
{
244
375
  CK_SESSION_HANDLE session;
245
375
  char             *pin = NULL;
246
375
  unsigned char    *label = NULL;
247
375
  size_t            label_len = 0;
248
375
  unsigned char     token_label[33];
249
375
  sc_pkcs11_slot_t *slot = NULL;
250
  /* token label must be padded with blank characters, and which must not be null-terminated*/
251
375
  memset(token_label, ' ', sizeof(token_label));
252
253
375
  if (!(pin = extract_word(&data, &size)))
254
1
    goto end;
255
374
  if (!(label = (unsigned char *) extract_word(&data, &size)))
256
1
    goto end;
257
373
  label_len = strlen((char *) label);
258
373
  memcpy(token_label, label, label_len < 33 ? label_len : 32);
259
260
373
  if (fuzz_pkcs11_initialize(data, size, &slot, &session) != CKR_OK)
261
120
    goto end;
262
253
  p11->C_InitToken(slot->id, (CK_UTF8CHAR *) pin, pin == NULL ? 0 : strlen(pin), token_label);
263
264
253
  p11->C_CloseSession(session);
265
253
  p11->C_Finalize(NULL);
266
375
end:
267
375
  free(pin);
268
375
  free(label);
269
375
}
270
271
static void test_random(const unsigned char *data, size_t size)
272
11.5k
{
273
11.5k
  CK_SESSION_HANDLE session;
274
11.5k
  size_t            random_len = data[0];
275
11.5k
  CK_BYTE           buf[256];
276
11.5k
  data++; size--;
277
278
11.5k
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
279
4.55k
    return;
280
281
6.97k
  p11->C_GenerateRandom(session, buf, random_len);
282
283
6.97k
  p11->C_CloseSession(session);
284
6.97k
  p11->C_Finalize(NULL);
285
6.97k
}
286
287
static void test_digest_update(const uint8_t *data, size_t size)
288
238
{
289
238
  CK_SESSION_HANDLE session;
290
238
  const uint8_t    *dig_data = NULL;
291
238
  size_t            dig_size = 0;
292
238
  CK_MECHANISM      mech = {0, NULL_PTR, 0};
293
238
  unsigned char     buffer[64] = {0};
294
238
  CK_ULONG          hash_len = sizeof(buffer);
295
238
  int               to_process = 0, rv = 0;
296
297
238
  if (set_mechanism(&data, &size, &mech))
298
0
    return;
299
300
  /* Copy data for hashing*/
301
238
  dig_data = data;
302
238
  if ((dig_size = get_buffer(&dig_data, size, &data, &size, 6000)) == 0)
303
2
    return;
304
305
236
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
306
10
    return;
307
308
226
  if (p11->C_DigestInit(session, &mech) != CKR_OK)
309
217
    goto end;
310
311
122
  while (dig_size > 0) {
312
113
    to_process = dig_size > sizeof(buffer) ? sizeof(buffer) : dig_size;
313
113
    dig_size -= to_process;
314
113
    memcpy(buffer, dig_data, to_process);
315
113
    dig_data += to_process;
316
317
113
    rv = p11->C_DigestUpdate(session, buffer, to_process);
318
113
    if (rv != CKR_OK)
319
0
      goto end;
320
113
  }
321
9
  hash_len = sizeof(buffer);
322
9
  p11->C_DigestFinal(session, buffer, &hash_len);
323
324
226
end:
325
226
  p11->C_CloseSession(session);
326
226
  p11->C_Finalize(NULL);
327
226
}
328
329
void test_digest(const uint8_t *data, size_t size)
330
81
{
331
81
  CK_SESSION_HANDLE session;
332
81
  const uint8_t    *ptr = NULL;
333
81
  unsigned char    *dig_data = NULL;
334
81
  size_t            dig_size = 0;
335
81
  CK_MECHANISM      mech = {0, NULL_PTR, 0};
336
81
  unsigned char     buffer[64] = {0};
337
81
  CK_ULONG          hash_len = sizeof(buffer);
338
339
81
  if (set_mechanism(&data, &size, &mech))
340
0
    return;
341
342
  /* Copy data for hashing*/
343
81
  ptr = data;
344
81
  if ((dig_size = get_buffer(&ptr, size, &data, &size, 6000)) == 0)
345
2
    return;
346
79
  if (!(dig_data = malloc(dig_size)))
347
0
    return;
348
79
  memcpy(dig_data, ptr, dig_size);
349
350
79
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
351
20
    goto end;
352
353
59
  if (p11->C_DigestInit(session, &mech) == CKR_OK)
354
1
    p11->C_Digest(session, dig_data, dig_size, buffer, &hash_len);
355
356
59
  p11->C_CloseSession(session);
357
59
  p11->C_Finalize(NULL);
358
79
end:
359
79
  free(dig_data);
360
79
}
361
362
static int fuzz_find_object(CK_SESSION_HANDLE sess, CK_OBJECT_CLASS cls,
363
    CK_OBJECT_HANDLE_PTR ret, const unsigned char *id, size_t id_len)
364
995
{
365
  /* taken from tools/pkcs11-tool.c */
366
995
  CK_ATTRIBUTE attrs[2];
367
995
  unsigned int nattrs = 0;
368
995
  CK_ULONG     count = 0;
369
370
995
  attrs[0].type = CKA_CLASS;
371
995
  attrs[0].pValue = &cls;
372
995
  attrs[0].ulValueLen = sizeof(cls);
373
995
  nattrs++;
374
995
  if (id) {
375
171
    attrs[nattrs].type = CKA_ID;
376
171
    attrs[nattrs].pValue = (void *) id;
377
171
    attrs[nattrs].ulValueLen = id_len;
378
171
    nattrs++;
379
171
  }
380
381
995
  if (p11->C_FindObjectsInit(sess, attrs, nattrs) != CKR_OK)
382
0
    return -1;
383
384
995
  if (p11->C_FindObjects(sess, ret, 1, &count) != CKR_OK)
385
0
    return -1;
386
387
995
  if (count == 0)
388
366
    *ret = CK_INVALID_HANDLE;
389
995
  p11->C_FindObjectsFinal(sess);
390
995
  return count;
391
995
}
392
393
static void test_sign(const uint8_t *data, size_t size)
394
353
{
395
353
  CK_SESSION_HANDLE    session;
396
353
  uint8_t              login_type = CKU_USER;
397
353
  char                *pin = NULL;
398
353
  const unsigned char *opt_id;
399
353
  size_t               opt_id_len = 0;
400
353
  const uint8_t       *sign_data = NULL;
401
353
  size_t               sign_data_size = 0;
402
353
  CK_OBJECT_HANDLE     key = CK_INVALID_HANDLE;
403
353
  unsigned char        in_buffer[1025], sig_buffer[512];
404
353
  CK_MECHANISM         mech = {0, NULL_PTR, 0};
405
353
  CK_ULONG             sig_len = sizeof(sig_buffer);
406
353
  size_t               to_process = 0;
407
353
  CK_TOKEN_INFO        info;
408
409
  /* Process options*/
410
353
  if (set_mechanism(&data, &size, &mech) || size < 3)
411
2
    return;
412
351
  login_type = data[0];
413
351
  data++; size--;
414
351
  if (!(pin = extract_word(&data, &size)))
415
3
    return;
416
348
  opt_id = data;
417
348
  opt_id_len = get_buffer(&opt_id, size, &data, &size, 256);
418
419
  /* Prepare buffer for signing */
420
348
  sign_data = data;
421
348
  if ((sign_data_size = get_buffer(&sign_data, size, &data, &size, 6000)) == 0)
422
2
    goto end;
423
424
  /* Initialize */
425
346
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
426
18
    goto end;
427
328
  p11->C_GetTokenInfo(0, &info);
428
328
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
429
328
  fuzz_find_object(session, CKO_PRIVATE_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len);
430
431
328
  if (p11->C_SignInit(session, &mech, key) != CKR_OK)
432
73
    goto fin;
433
255
  p11->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_UTF8CHAR *) pin, strlen(pin));
434
435
255
  if (sign_data_size <= sizeof(in_buffer)) {
436
241
    memcpy(in_buffer, sign_data, sign_data_size);
437
241
    p11->C_Sign(session, in_buffer, sign_data_size, sig_buffer, &sig_len);
438
241
  } else {
439
46
    while (sign_data_size > 0) {
440
32
      to_process = sign_data_size < sizeof(in_buffer) ? sign_data_size : sizeof(in_buffer);
441
32
      sign_data_size -= to_process;
442
32
      memcpy(in_buffer, sign_data, to_process);
443
32
      sign_data += to_process;
444
445
32
      if (p11->C_SignUpdate(session, in_buffer, to_process) != CKR_OK)
446
0
        goto fin;
447
32
    }
448
449
14
    sig_len = sizeof(sig_buffer);
450
14
    p11->C_SignFinal(session, sig_buffer, &sig_len);
451
14
  }
452
453
328
fin:
454
328
  p11->C_CloseSession(session);
455
328
  p11->C_Finalize(NULL);
456
348
end:
457
348
  free(pin);
458
348
}
459
460
static void test_verify(const uint8_t *data, size_t size)
461
150
{
462
150
  CK_SESSION_HANDLE    session;
463
150
  CK_MECHANISM         mech = {0, NULL_PTR, 0};
464
150
  uint8_t              login_type = CKU_USER;
465
150
  char                *pin = NULL;
466
150
  const unsigned char *opt_id = NULL;
467
150
  size_t               opt_id_len = 0;
468
150
  const uint8_t       *verify_data = NULL, *sig_data = NULL;
469
150
  size_t               verify_data_size = 0;
470
150
  CK_OBJECT_HANDLE     key = CK_INVALID_HANDLE;
471
150
  unsigned char        in_buffer[1025], sig_buffer[512];
472
150
  CK_ULONG             sig_len = sizeof(sig_buffer);
473
150
  size_t               to_process = 0;
474
475
  /* Process options*/
476
150
  if (set_mechanism(&data, &size, &mech) || size < 3)
477
2
    return;
478
148
  login_type = data[0];
479
148
  data++; size--;
480
148
  if (!(pin = extract_word(&data, &size)))
481
1
    return;
482
147
  opt_id = data;
483
147
  opt_id_len = get_buffer(&opt_id, size, &data, &size, 256);
484
485
  /* Prepare buffer with data */
486
147
  verify_data = data;
487
147
  if ((verify_data_size = get_buffer(&verify_data, size, &data, &size, 6000)) == 0)
488
6
    goto end;
489
  /* Get buffer with signature */
490
141
  sig_data = data;
491
141
  if ((sig_len = get_buffer(&sig_data, size, &data, &size, 512)) == 0)
492
3
    goto end;
493
138
  memcpy(sig_buffer, sig_data, sig_len);
494
495
  /* Initialize */
496
138
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
497
16
    goto end;
498
499
122
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
500
501
122
  if (!fuzz_find_object(session, CKO_PUBLIC_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len)
502
56
    && !fuzz_find_object(session, CKO_CERTIFICATE, &key, opt_id_len ? opt_id : NULL, opt_id_len))
503
56
    goto fin;
504
505
66
  if (p11->C_VerifyInit(session, &mech, key) != CKR_OK)
506
16
    goto fin;
507
508
50
  if (verify_data_size <= sizeof(in_buffer)) {
509
50
    memcpy(in_buffer, verify_data, verify_data_size);
510
50
    p11->C_Verify(session, in_buffer, verify_data_size, sig_buffer, sig_len);
511
50
  } else {
512
0
    while (verify_data_size > 0) {
513
0
      to_process = verify_data_size < sizeof(in_buffer) ? verify_data_size : sizeof(in_buffer);
514
0
      verify_data_size -= to_process;
515
0
      memcpy(in_buffer, verify_data, to_process);
516
0
      verify_data += to_process;
517
518
0
      if (p11->C_VerifyUpdate(session, in_buffer, to_process) != CKR_OK)
519
0
        goto fin;
520
0
    }
521
522
0
    p11->C_VerifyFinal(session, sig_buffer, sig_len);
523
0
  }
524
122
fin:
525
122
  p11->C_CloseSession(session);
526
122
  p11->C_Finalize(NULL);
527
147
end:
528
147
  free(pin);
529
147
}
530
531
static void test_decrypt(const uint8_t *data, size_t size)
532
402
{
533
402
  CK_SESSION_HANDLE    session;
534
402
  uint8_t              login_type = CKU_USER;
535
402
  char                *pin = NULL;
536
402
  const unsigned char *opt_id;
537
402
  size_t               opt_id_len = 0;
538
402
  const uint8_t       *dec_data = NULL;
539
402
  size_t               dec_data_size = 0;
540
402
  CK_OBJECT_HANDLE     key = CK_INVALID_HANDLE;
541
402
  unsigned char        in_buffer[1024], out_buffer[1024];
542
402
  CK_MECHANISM         mech = {0, NULL_PTR, 0};
543
402
  size_t               out_len = 0;
544
545
  /* Process options*/
546
402
  if (set_mechanism(&data, &size, &mech) || size < 3)
547
2
    return;
548
400
  login_type = data[0];
549
400
  data++; size--;
550
400
  if (!(pin = extract_word(&data, &size)))
551
2
    return;
552
398
  opt_id = data;
553
398
  opt_id_len = get_buffer(&opt_id, size, &data, &size, 256);
554
555
  /* Prepare buffer for signing */
556
398
  dec_data = data;
557
398
  if ((dec_data_size = get_buffer(&dec_data, size, &data, &size, 1024)) == 0)
558
3
    goto end;
559
560
  /* Initialize */
561
395
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
562
28
    goto end;
563
564
367
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
565
367
  if (!fuzz_find_object(session, CKO_PRIVATE_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len)
566
82
    && !fuzz_find_object(session, CKO_SECRET_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len))
567
82
    goto fin;
568
569
285
  if (p11->C_DecryptInit(session, &mech, key) != CKR_OK)
570
100
    goto fin;
571
572
185
  p11->C_Login(session, CKU_CONTEXT_SPECIFIC, (CK_UTF8CHAR *) pin, strlen(pin));
573
185
  out_len = sizeof(out_buffer);
574
575
185
  memcpy(in_buffer, dec_data, dec_data_size);
576
185
  p11->C_Decrypt(session, in_buffer, dec_data_size, out_buffer, &out_len);
577
367
fin:
578
367
  p11->C_CloseSession(session);
579
367
  p11->C_Finalize(NULL);
580
398
end:
581
398
  free(pin);
582
398
}
583
584
static void test_wrap(const uint8_t *data, size_t size)
585
29
{
586
29
  CK_SESSION_HANDLE    session;
587
29
  uint8_t              login_type = CKU_USER;
588
29
  char                *pin = NULL;
589
29
  CK_BYTE              pWrappedKey[4096];
590
29
  CK_ULONG             pulWrappedKeyLen = sizeof(pWrappedKey);
591
29
  CK_MECHANISM         mech = {0, NULL_PTR, 0};
592
29
  CK_OBJECT_HANDLE     hWrappingKey;
593
29
  CK_OBJECT_HANDLE     hkey;
594
29
  const unsigned char *hkey_id;
595
29
  const unsigned char *opt_id;
596
29
  size_t               opt_id_len = 0, hkey_id_len = 0;
597
598
  /* Set options */
599
29
  if (set_mechanism(&data, &size, &mech) || size < 3)
600
2
    return;
601
27
  login_type = data[0];
602
27
  data++; size--;
603
27
  if (!(pin = extract_word(&data, &size)))
604
2
    return;
605
25
  opt_id = data;
606
25
  opt_id_len = get_buffer(&opt_id, size, &data, &size, 256);
607
25
  hkey_id = data;
608
25
  hkey_id_len = get_buffer(&hkey_id, size, &data, &size, 256);
609
610
  /* Initialize */
611
25
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
612
11
    goto end;
613
614
14
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
615
14
  if (!fuzz_find_object(session, CKO_SECRET_KEY, &hkey, hkey_id_len ? hkey_id : NULL, hkey_id_len))
616
14
    goto fin;
617
0
  if (!fuzz_find_object(session, CKO_PUBLIC_KEY, &hWrappingKey, opt_id_len ? opt_id : NULL, opt_id_len))
618
0
    if (!fuzz_find_object(session, CKO_SECRET_KEY, &hWrappingKey, opt_id_len ? opt_id : NULL, opt_id_len))
619
0
      goto fin;
620
0
  p11->C_WrapKey(session, &mech, hWrappingKey, hkey, pWrappedKey, &pulWrappedKeyLen);
621
622
14
fin:
623
14
  p11->C_CloseSession(session);
624
14
  p11->C_Finalize(NULL);
625
25
end:
626
25
  free(pin);
627
25
}
628
629
6.42k
#define FILL_ATTR(attr, typ, val, len) do { \
630
6.42k
  (attr).type=(typ); \
631
6.42k
  (attr).pValue=(val); \
632
6.42k
  (attr).ulValueLen=len; \
633
6.42k
} while(0)
634
635
void fill_bool_attr(CK_ATTRIBUTE **keyTemplate, int *n_attr, int type, int value)
636
4.21k
{
637
4.21k
  if (value) {
638
2.85k
    FILL_ATTR((*keyTemplate)[*n_attr], type, &_true, sizeof(_true));
639
2.85k
  }
640
1.35k
  else {
641
1.35k
    FILL_ATTR((*keyTemplate)[*n_attr], type, &_false, sizeof(_false));
642
1.35k
  }
643
  
644
4.21k
  ++(*n_attr);
645
4.21k
}
646
647
int fill_key_template(CK_ATTRIBUTE **keyTemplate, int *n_attr, const uint8_t **data, size_t *size, CK_OBJECT_CLASS *class, int token)
648
1.15k
{
649
1.15k
  const unsigned char *ptr = NULL;
650
1.15k
  size_t               ecparams_size = 0;
651
1.15k
  size_t               opt_object_label_size = 0;
652
1.15k
  size_t               opt_object_id_len = 0;
653
1.15k
  size_t               opt_allowed_mechanisms_len = 0;
654
1.15k
  int bool_types[] = {CKA_MODULUS_BITS, CKA_PUBLIC_EXPONENT, CKA_VERIFY, CKA_SENSITIVE,
655
1.15k
            CKA_SIGN, CKA_ENCRYPT, CKA_DECRYPT, CKA_WRAP, CKA_UNWRAP,
656
1.15k
            CKA_DERIVE, CKA_PRIVATE, CKA_ALWAYS_AUTHENTICATE, CKA_EXTRACTABLE};
657
658
1.15k
  if (!(*keyTemplate = malloc(20 * sizeof(CK_ATTRIBUTE))))
659
0
    return 1;
660
1.15k
  memset(*keyTemplate, 0, 20 * sizeof(CK_ATTRIBUTE));
661
1.15k
  FILL_ATTR((*keyTemplate)[0], CKA_CLASS, class, sizeof(CKA_CLASS));
662
1.15k
  *n_attr = 1;
663
1.15k
  fill_bool_attr(keyTemplate, n_attr, CKA_TOKEN, token);
664
665
15.9k
  for (int i = 0; i < 13; i++) {
666
    /* ... | present -> 0/1 | value | ...*/
667
14.8k
    if (*size < 3)
668
28
      return 1;
669
14.7k
    if ((*data)[0] % 2) {
670
2.64k
      fill_bool_attr(keyTemplate, n_attr, bool_types[i], (*data)[1] % 2);
671
2.64k
      (*data)++; (*size)--;
672
2.64k
    }
673
14.7k
    (*data)++; (*size)--;
674
14.7k
  }
675
676
1.13k
  if (*size > 2 && (*data)[0] % 2 && *n_attr < 20){
677
    /* ... | present -> 0/1 | value | ...*/
678
163
    key_type = (CK_ULONG) (*data)[1];
679
163
    FILL_ATTR((*keyTemplate)[*n_attr], CKA_KEY_TYPE, &key_type, sizeof(key_type));
680
163
    ++(*n_attr);
681
163
    (*data) += 2;
682
163
    (*size) -= 2;
683
163
  }
684
685
1.13k
  if (*size > 3 && (*data)[0] % 2 && *n_attr < 20){
686
    /* ... | present -> 0/1 | len | len | data | ... */
687
108
    (*data)++; (*size)--;
688
108
    ptr = *data;
689
108
    if ((ecparams_size = get_buffer(&ptr, *size, data, size, 256)) == 0)
690
6
      return 1;
691
102
    memcpy(ecparams, ptr, ecparams_size);
692
102
    FILL_ATTR((*keyTemplate)[*n_attr], CKA_EC_PARAMS, ecparams, ecparams_size);
693
102
    ++(*n_attr);
694
102
  }
695
696
1.12k
  if (*size > 3 && (*data)[0] % 2 && *n_attr < 20){
697
    /* ... | present -> 0/1 | len | len | data | ... */
698
86
    (*data)++; (*size)--;
699
86
    ptr = *data;
700
86
    if ((opt_object_label_size = get_buffer(&ptr, *size, data, size, 128)) == 0)
701
2
      return 1;
702
84
    memcpy(opt_object_label, ptr, opt_object_label_size);
703
84
    FILL_ATTR((*keyTemplate)[*n_attr], CKA_LABEL, opt_object_label, opt_object_label_size);
704
84
    ++(*n_attr);
705
84
  }
706
707
1.12k
  if (*size > 3 && (*data)[0] % 2 && *n_attr < 20){
708
    /* ... | present -> 0/1 | len | len | data | ... */
709
68
    (*data)++; (*size)--;
710
68
    ptr = *data;
711
68
    if ((opt_object_id_len = get_buffer(&ptr, *size, data, size, 100)) == 0)
712
5
      return 1;
713
63
    memcpy(opt_object_id, ptr, opt_object_id_len);
714
63
    FILL_ATTR((*keyTemplate)[*n_attr], CKA_ID, opt_object_id, opt_object_id_len);
715
63
    ++(*n_attr);
716
63
  }
717
1.11k
  if (*size > 4 && (*data)[0]  % 2 && *n_attr < 20){
718
    /* ... | present -> 0/1 | len | mech1 | mech2 | ... | mechn | ... */
719
54
    opt_allowed_mechanisms_len = (*data)[1] > 20 ? 20 : (*data)[1];
720
54
    (*data) += 2;
721
54
    (*size) -= 2;
722
566
    for (size_t i = 0; i < opt_allowed_mechanisms_len; i++) {
723
524
      if (*size <= sizeof(unsigned int))
724
12
        return 1;
725
512
      opt_allowed_mechanisms[i] = *((unsigned int *)data);
726
512
      (*data) += sizeof(unsigned int);
727
512
      (*size) -= sizeof(unsigned int);
728
512
    }
729
42
    FILL_ATTR((*keyTemplate)[*n_attr], CKA_ALLOWED_MECHANISMS, opt_allowed_mechanisms, opt_allowed_mechanisms_len);
730
42
    ++(*n_attr);
731
42
  }
732
1.10k
  if (*size == 0)
733
0
    return 1;
734
1.10k
  return 0;
735
1.10k
}
736
737
static void test_unwrap(const uint8_t *data, size_t size)
738
24
{
739
24
  CK_SESSION_HANDLE    session;
740
24
  CK_MECHANISM         mech = {0, NULL_PTR, 0};
741
24
  uint8_t              login_type = CKU_USER;
742
24
  char                *pin = NULL;
743
24
  const unsigned char *opt_id, *wrapped_key;
744
24
  size_t               opt_id_len;
745
24
  CK_OBJECT_HANDLE     hUnwrappingKey;
746
24
  CK_ULONG             wrapped_key_length;
747
24
  CK_BYTE_PTR          pWrappedKey;
748
24
  unsigned char        in_buffer[1024];
749
24
  CK_OBJECT_CLASS      secret_key_class = CKO_SECRET_KEY;
750
24
  CK_ATTRIBUTE        *keyTemplate = NULL;
751
24
  int                  n_attr = 2;
752
24
  CK_OBJECT_HANDLE     hSecretKey;
753
754
  /* Set options */
755
24
  if (set_mechanism(&data, &size, &mech) || size < 3)
756
1
    goto end;
757
23
  login_type = data[0];
758
23
  data++; size--;
759
23
  if (!(pin = extract_word(&data, &size)))
760
3
    goto end;
761
20
  opt_id = data;
762
20
  opt_id_len = get_buffer(&opt_id, size, &data, &size, 256);
763
20
  wrapped_key = data;
764
20
  if ((wrapped_key_length = get_buffer(&wrapped_key, size, &data, &size, 1024)) == 0)
765
2
    goto end;
766
18
  memcpy(in_buffer, wrapped_key, wrapped_key_length);
767
18
  pWrappedKey = in_buffer;
768
769
18
  if (fill_key_template((CK_ATTRIBUTE **) &keyTemplate, &n_attr, &data, &size, &secret_key_class, true))
770
6
    goto end;
771
772
  /* Initialize */
773
12
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
774
6
    goto end;
775
776
6
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
777
  /* Find keys*/
778
6
  if (!fuzz_find_object(session, CKO_PRIVATE_KEY, &hUnwrappingKey, opt_id_len ? opt_id : NULL, opt_id_len))
779
4
    if (!fuzz_find_object(session, CKO_SECRET_KEY, &hUnwrappingKey, opt_id_len ? opt_id : NULL, opt_id_len))
780
4
      goto fin;
781
2
  p11->C_UnwrapKey(session, &mech, hUnwrappingKey, pWrappedKey, wrapped_key_length, keyTemplate, n_attr, &hSecretKey);
782
783
6
fin:
784
6
  p11->C_CloseSession(session);
785
6
  p11->C_Finalize(NULL);
786
24
end:
787
24
  free(pin);
788
24
  free(keyTemplate);
789
24
}
790
791
static void test_derive(const uint8_t *data, size_t size)
792
30
{
793
30
  CK_SESSION_HANDLE    session;
794
30
  CK_OBJECT_HANDLE     key;
795
30
  CK_MECHANISM         mech = {0, NULL_PTR, 0};
796
30
  uint8_t              login_type = CKU_USER;
797
30
  char                *pin = NULL;
798
30
  const unsigned char *opt_id = NULL;
799
30
  size_t               opt_id_len;
800
30
  CK_OBJECT_HANDLE     newkey = 0;
801
30
  CK_OBJECT_CLASS      newkey_class = CKO_SECRET_KEY;
802
30
  CK_ATTRIBUTE        *keyTemplate = NULL;
803
30
  int                  n_attrs = 2;
804
805
  /* Set options */
806
30
  if (set_mechanism(&data, &size, &mech) || size < 3)
807
1
    goto end;
808
29
  login_type = data[0];
809
29
  data++; size--;
810
29
  if (!(pin = extract_word(&data, &size)))
811
1
    goto end;
812
28
  opt_id = data;
813
28
  opt_id_len = get_buffer(&opt_id, size, &data, &size, 256);
814
28
  if (fill_key_template((CK_ATTRIBUTE **) &keyTemplate, &n_attrs, &data, &size, &newkey_class, false))
815
1
    goto end;
816
817
  /* Initialize */
818
27
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
819
11
    goto end;
820
821
16
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
822
16
  if (fuzz_find_object(session, CKO_PRIVATE_KEY, &key, opt_id_len ? opt_id : NULL, opt_id_len))
823
4
    p11->C_DeriveKey(session, &mech, key, keyTemplate, n_attrs, &newkey);
824
825
16
  p11->C_CloseSession(session);
826
16
  p11->C_Finalize(NULL);
827
30
end:
828
30
  free(pin);
829
30
  free(keyTemplate);
830
30
}
831
832
static void test_genkeypair(const uint8_t *data, size_t size)
833
452
{
834
452
  CK_SESSION_HANDLE session;
835
452
  CK_OBJECT_HANDLE  hPublicKey;
836
452
  CK_OBJECT_HANDLE  hPrivateKey;
837
452
  CK_MECHANISM      mech = {0, NULL_PTR, 0};
838
452
  uint8_t           login_type = CKU_USER;
839
452
  char             *pin = NULL;
840
452
  CK_OBJECT_CLASS   pubkey_class = CKO_PUBLIC_KEY;
841
452
  CK_OBJECT_CLASS   privkey_class = CKO_PRIVATE_KEY;
842
452
  int               n_pubkey_attr = 2;
843
452
  int               n_privkey_attr = 2;
844
452
  CK_ATTRIBUTE     *publicKeyTemplate = NULL;
845
452
  CK_ATTRIBUTE     *privateKeyTemplate = NULL;
846
847
  /* Process options*/
848
452
  if (set_mechanism(&data, &size, &mech) || size < 3)
849
1
    goto end;
850
451
  login_type = data[0];
851
451
  data++; size--;
852
451
  if (!(pin = extract_word(&data, &size)))
853
3
    goto end;
854
855
448
  if (fill_key_template(&publicKeyTemplate, &n_pubkey_attr, &data, &size, &pubkey_class, true) != 0
856
446
    || fill_key_template(&privateKeyTemplate, &n_privkey_attr, &data, &size, &privkey_class, true) != 0)
857
10
    goto end;
858
859
  /* Initialize */
860
438
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
861
70
    goto end;
862
863
368
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
864
368
  p11->C_GenerateKeyPair(session, &mech, publicKeyTemplate, n_pubkey_attr,
865
368
               privateKeyTemplate, n_privkey_attr,
866
368
               &hPublicKey, &hPrivateKey);
867
368
  p11->C_CloseSession(session);
868
368
  p11->C_Finalize(NULL);
869
870
452
end:
871
452
  free(pin);
872
452
  free(privateKeyTemplate);
873
452
  free(publicKeyTemplate);
874
452
}
875
876
static void test_store_data(const uint8_t *data, size_t size)
877
112
{
878
112
  CK_SESSION_HANDLE session;
879
112
  CK_OBJECT_HANDLE  data_obj;
880
112
  CK_OBJECT_CLASS   class = CKO_DATA;
881
112
  uint8_t           login_type = CKU_USER;
882
112
  unsigned char     contents[5001];
883
112
  int               contents_len = 0;
884
112
  const uint8_t    *ptr = NULL;
885
112
  CK_ATTRIBUTE     *data_templ = NULL;
886
112
  int               n_data_attr = 0;
887
112
  char             *pin = NULL;
888
112
  unsigned char     app_id[256];
889
112
  int               app_id_len = 0;
890
891
  /* Create data template */
892
112
  if (!(data_templ = malloc(20 * sizeof(CK_ATTRIBUTE))))
893
0
    return;
894
112
  memset(data_templ, 0, 20 * sizeof(CK_ATTRIBUTE));
895
896
  /* Get PIN */
897
112
  if (!(pin = extract_word(&data, &size)))
898
1
    goto end;
899
900
  /* Extract content from fuzzing input*/
901
111
  memset(contents, 0, sizeof(contents));
902
111
  ptr = data;
903
111
  if ((contents_len = get_buffer(&ptr, size, &data, &size, 5000)) == 0)  
904
4
    goto end;
905
107
  memcpy(contents, ptr, contents_len);
906
107
  contents[contents_len] = '\0';
907
908
  /* Fill attributes to data template */
909
107
  if (size < 4)
910
3
    goto end;
911
104
  FILL_ATTR(data_templ[n_data_attr], CKA_CLASS, &class, sizeof(class));
912
104
  n_data_attr++;
913
104
  FILL_ATTR(data_templ[n_data_attr], CKA_VALUE, &contents, contents_len);
914
104
  n_data_attr++;
915
104
  fill_bool_attr(&data_templ, &n_data_attr, CKA_TOKEN, *data % 2);
916
104
  data++; size--;
917
104
  fill_bool_attr(&data_templ, &n_data_attr, CKA_PRIVATE, *data % 2);
918
104
  data++; size--;
919
920
  /* Get application id*/
921
104
  if (data[0] % 2){
922
51
    data++; size--;
923
51
    ptr = data;
924
51
    if ((app_id_len = get_buffer(&ptr, size, &data, &size, 256)) == 0)
925
2
      goto end;
926
49
    memcpy(app_id, ptr, app_id_len);
927
49
    FILL_ATTR(data_templ[n_data_attr], CKA_OBJECT_ID, app_id, app_id_len);
928
49
    n_data_attr++;
929
49
  }
930
931
  /* Initialize */
932
102
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
933
7
    goto end;
934
935
95
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
936
95
  p11->C_CreateObject(session, data_templ, n_data_attr, &data_obj);
937
95
  p11->C_CloseSession(session);
938
95
  p11->C_Finalize(NULL);
939
112
end:
940
112
  free(data_templ);
941
112
  free(pin);
942
112
}
943
944
static void test_store_cert(const uint8_t *data, size_t size)
945
116
{
946
116
  CK_SESSION_HANDLE   session;
947
116
  CK_OBJECT_CLASS     class = CKO_CERTIFICATE;
948
116
  uint8_t             login_type = CKU_USER;
949
116
  unsigned char       contents[5000];
950
116
  int                 contents_len = 0;
951
116
  const uint8_t      *ptr = NULL;
952
116
  CK_ATTRIBUTE       *cert_templ = NULL;
953
116
  int                 n_cert_attr = 0;
954
116
  char               *pin = NULL;
955
116
  CK_OBJECT_HANDLE    cert_obj;
956
116
  CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
957
958
  /* Create certificate template */
959
116
  if (!(cert_templ = malloc(20 * sizeof(CK_ATTRIBUTE))))
960
0
    return;
961
116
  memset(cert_templ, 0, 20 * sizeof(CK_ATTRIBUTE));
962
963
  /* Get PIN */
964
116
  if (!(pin = extract_word(&data, &size)))
965
1
    goto end;
966
967
  /* Extract content from fuzzing input */
968
115
  memset(contents, 0, sizeof(contents));
969
115
  ptr = data;
970
115
  if ((contents_len = get_buffer(&ptr, size, &data, &size, 5000)) == 0)  
971
7
    goto end;
972
108
  memcpy(contents, ptr, contents_len);
973
108
  contents[contents_len] = '\0';
974
975
  /* Fill attributes to certificate template */
976
108
  if (size < 4)
977
6
    goto end;
978
102
  FILL_ATTR(cert_templ[n_cert_attr], CKA_CLASS, &class, sizeof(class));
979
102
  n_cert_attr++;
980
102
  FILL_ATTR(cert_templ[n_cert_attr], CKA_VALUE, contents, contents_len);
981
102
  n_cert_attr++;
982
102
  FILL_ATTR(cert_templ[n_cert_attr], CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));
983
102
  n_cert_attr++;
984
102
  fill_bool_attr(&cert_templ, &n_cert_attr, CKA_TOKEN, *data % 2);
985
102
  data++; size--;
986
102
  fill_bool_attr(&cert_templ, &n_cert_attr, CKA_PRIVATE, *data % 2);
987
102
  data++; size--;
988
989
  /* Initialize */
990
102
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
991
41
    goto end;
992
993
61
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
994
61
  p11->C_CreateObject(session, cert_templ, n_cert_attr, &cert_obj);
995
61
  p11->C_CloseSession(session);
996
61
  p11->C_Finalize(NULL);
997
116
end:
998
116
  free(pin);
999
116
  free(cert_templ);
1000
116
}
1001
1002
static void test_store_key(const uint8_t *data, size_t size)
1003
221
{
1004
221
  CK_SESSION_HANDLE session;
1005
221
  CK_OBJECT_CLASS   class = CKO_SECRET_KEY;
1006
221
  uint8_t           login_type = CKU_USER;
1007
221
  unsigned char     contents[5000];
1008
221
  int               contents_len = 0;
1009
221
  const uint8_t    *ptr = NULL;
1010
221
  CK_ATTRIBUTE     *key_template = NULL;
1011
221
  int               n_key_attr = 0;
1012
221
  char             *pin = NULL;
1013
221
  CK_OBJECT_HANDLE  key_obj;
1014
1015
221
  memset(contents, 0, sizeof(contents));
1016
221
  if (size < 3)
1017
0
    return;
1018
221
  class = *data;
1019
221
  data++; size--;
1020
1021
  /* Get PIN */
1022
221
  if (!(pin = extract_word(&data, &size)))
1023
2
    goto end;
1024
1025
219
  if (fill_key_template(&key_template, &n_key_attr, &data, &size, &class, true) != 0)
1026
36
    goto end;
1027
1028
183
  if (size < 3)
1029
13
    goto end;
1030
170
  if (data[0] && n_key_attr < 20) {
1031
51
    data++; size--;
1032
51
    ptr = data;
1033
51
    if ((contents_len = get_buffer(&ptr, size, &data, &size, 5000)) == 0)  
1034
17
      goto end;
1035
34
    memcpy(contents, ptr, contents_len);
1036
34
    FILL_ATTR(key_template[n_key_attr], CKA_VALUE, contents, contents_len);
1037
34
    n_key_attr++;
1038
34
  }
1039
1040
  /* Initialize */
1041
153
  if (fuzz_pkcs11_initialize(data, size, NULL, &session) != CKR_OK)
1042
47
    goto end;
1043
1044
106
  p11->C_Login(session, login_type, (CK_UTF8CHAR *) pin, strlen(pin));
1045
106
  p11->C_CreateObject(session, key_template, n_key_attr, &key_obj);
1046
106
  p11->C_CloseSession(session);
1047
106
  p11->C_Finalize(NULL);
1048
221
end:
1049
221
  free(pin);
1050
221
  free(key_template);
1051
221
}
1052
1053
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
1054
15.5k
{
1055
15.5k
  uint8_t operation = 0;
1056
15.5k
  void (*func_ptr[])(const uint8_t*, size_t) = {
1057
15.5k
    test_change_pin,
1058
15.5k
    test_init_pin,
1059
15.5k
    test_init_token,
1060
15.5k
    test_random,
1061
15.5k
    test_digest_update,
1062
15.5k
    test_digest,
1063
15.5k
    test_sign,
1064
15.5k
    test_verify,
1065
15.5k
    test_decrypt,
1066
15.5k
    test_wrap,
1067
15.5k
    test_unwrap,
1068
15.5k
    test_derive,
1069
15.5k
    test_genkeypair,
1070
15.5k
    test_store_data,
1071
15.5k
    test_store_cert,
1072
15.5k
    test_store_key
1073
15.5k
  };
1074
1075
15.5k
  if (size < 10)
1076
6
    return 0;
1077
1078
15.5k
  operation = *data % 16;
1079
15.5k
  data++;
1080
15.5k
  size--;
1081
1082
15.5k
  func_ptr[operation](data, size);
1083
1084
15.5k
  return 0;
1085
15.5k
}