1ba9bdd8bSchristos /*
2*2d40c451Schristos * Copyright (c) 2019-2022 Yubico AB. All rights reserved.
3ba9bdd8bSchristos * Use of this source code is governed by a BSD-style
4ba9bdd8bSchristos * license that can be found in the LICENSE file.
5*2d40c451Schristos * SPDX-License-Identifier: BSD-2-Clause
6ba9bdd8bSchristos */
7ba9bdd8bSchristos
8ba9bdd8bSchristos #include <assert.h>
9ba9bdd8bSchristos #include <stdint.h>
1095dbdf32Schristos #include <stdio.h>
11ba9bdd8bSchristos #include <stdlib.h>
12ba9bdd8bSchristos #include <string.h>
13ba9bdd8bSchristos
14ba9bdd8bSchristos #include "mutator_aux.h"
15ba9bdd8bSchristos #include "wiredata_fido2.h"
16ba9bdd8bSchristos #include "wiredata_u2f.h"
17ba9bdd8bSchristos #include "dummy.h"
18ba9bdd8bSchristos
19ba9bdd8bSchristos #include "../openbsd-compat/openbsd-compat.h"
20ba9bdd8bSchristos
21ba9bdd8bSchristos /* Parameter set defining a FIDO2 get assertion operation. */
22ba9bdd8bSchristos struct param {
23ba9bdd8bSchristos char pin[MAXSTR];
24ba9bdd8bSchristos char rp_id[MAXSTR];
25ba9bdd8bSchristos int ext;
26ba9bdd8bSchristos int seed;
27ba9bdd8bSchristos struct blob cdh;
28ba9bdd8bSchristos struct blob cred;
29ba9bdd8bSchristos struct blob es256;
30ba9bdd8bSchristos struct blob rs256;
31ba9bdd8bSchristos struct blob eddsa;
32ba9bdd8bSchristos struct blob wire_data;
33ba9bdd8bSchristos uint8_t cred_count;
34ba9bdd8bSchristos uint8_t type;
3595dbdf32Schristos uint8_t opt;
36ba9bdd8bSchristos uint8_t up;
37ba9bdd8bSchristos uint8_t uv;
38ba9bdd8bSchristos };
39ba9bdd8bSchristos
40ba9bdd8bSchristos /*
41ba9bdd8bSchristos * Collection of HID reports from an authenticator issued with a FIDO2
42ba9bdd8bSchristos * get assertion using the example parameters above.
43ba9bdd8bSchristos */
44ba9bdd8bSchristos static const uint8_t dummy_wire_data_fido[] = {
45ba9bdd8bSchristos WIREDATA_CTAP_INIT,
46ba9bdd8bSchristos WIREDATA_CTAP_CBOR_INFO,
47ba9bdd8bSchristos WIREDATA_CTAP_CBOR_AUTHKEY,
48ba9bdd8bSchristos WIREDATA_CTAP_CBOR_PINTOKEN,
49ba9bdd8bSchristos WIREDATA_CTAP_CBOR_ASSERT,
50ba9bdd8bSchristos };
51ba9bdd8bSchristos
52ba9bdd8bSchristos /*
53ba9bdd8bSchristos * Collection of HID reports from an authenticator issued with a U2F
54ba9bdd8bSchristos * authentication using the example parameters above.
55ba9bdd8bSchristos */
56ba9bdd8bSchristos static const uint8_t dummy_wire_data_u2f[] = {
57ba9bdd8bSchristos WIREDATA_CTAP_INIT,
58ba9bdd8bSchristos WIREDATA_CTAP_U2F_6985,
59ba9bdd8bSchristos WIREDATA_CTAP_U2F_6985,
60ba9bdd8bSchristos WIREDATA_CTAP_U2F_6985,
61ba9bdd8bSchristos WIREDATA_CTAP_U2F_6985,
62ba9bdd8bSchristos WIREDATA_CTAP_U2F_AUTH,
63ba9bdd8bSchristos };
64ba9bdd8bSchristos
651fc1e710Schristos struct param *
unpack(const uint8_t * ptr,size_t len)661fc1e710Schristos unpack(const uint8_t *ptr, size_t len)
67ba9bdd8bSchristos {
681fc1e710Schristos cbor_item_t *item = NULL, **v;
691fc1e710Schristos struct cbor_load_result cbor;
701fc1e710Schristos struct param *p;
711fc1e710Schristos int ok = -1;
72ba9bdd8bSchristos
731fc1e710Schristos if ((p = calloc(1, sizeof(*p))) == NULL ||
741fc1e710Schristos (item = cbor_load(ptr, len, &cbor)) == NULL ||
751fc1e710Schristos cbor.read != len ||
761fc1e710Schristos cbor_isa_array(item) == false ||
771fc1e710Schristos cbor_array_is_definite(item) == false ||
781fc1e710Schristos cbor_array_size(item) != 15 ||
791fc1e710Schristos (v = cbor_array_handle(item)) == NULL)
801fc1e710Schristos goto fail;
81ba9bdd8bSchristos
821fc1e710Schristos if (unpack_byte(v[0], &p->uv) < 0 ||
831fc1e710Schristos unpack_byte(v[1], &p->up) < 0 ||
8495dbdf32Schristos unpack_byte(v[2], &p->opt) < 0 ||
851fc1e710Schristos unpack_byte(v[3], &p->type) < 0 ||
861fc1e710Schristos unpack_byte(v[4], &p->cred_count) < 0 ||
871fc1e710Schristos unpack_int(v[5], &p->ext) < 0 ||
881fc1e710Schristos unpack_int(v[6], &p->seed) < 0 ||
891fc1e710Schristos unpack_string(v[7], p->rp_id) < 0 ||
901fc1e710Schristos unpack_string(v[8], p->pin) < 0 ||
911fc1e710Schristos unpack_blob(v[9], &p->wire_data) < 0 ||
921fc1e710Schristos unpack_blob(v[10], &p->rs256) < 0 ||
931fc1e710Schristos unpack_blob(v[11], &p->es256) < 0 ||
941fc1e710Schristos unpack_blob(v[12], &p->eddsa) < 0 ||
951fc1e710Schristos unpack_blob(v[13], &p->cred) < 0 ||
961fc1e710Schristos unpack_blob(v[14], &p->cdh) < 0)
971fc1e710Schristos goto fail;
981fc1e710Schristos
991fc1e710Schristos ok = 0;
1001fc1e710Schristos fail:
1011fc1e710Schristos if (ok < 0) {
1021fc1e710Schristos free(p);
1031fc1e710Schristos p = NULL;
104ba9bdd8bSchristos }
105ba9bdd8bSchristos
1061fc1e710Schristos if (item)
1071fc1e710Schristos cbor_decref(&item);
1081fc1e710Schristos
1091fc1e710Schristos return p;
1101fc1e710Schristos }
1111fc1e710Schristos
1121fc1e710Schristos size_t
pack(uint8_t * ptr,size_t len,const struct param * p)113ba9bdd8bSchristos pack(uint8_t *ptr, size_t len, const struct param *p)
114ba9bdd8bSchristos {
1151fc1e710Schristos cbor_item_t *argv[15], *array = NULL;
1161fc1e710Schristos size_t cbor_alloc_len, cbor_len = 0;
1171fc1e710Schristos unsigned char *cbor = NULL;
118ba9bdd8bSchristos
1191fc1e710Schristos memset(argv, 0, sizeof(argv));
120ba9bdd8bSchristos
1211fc1e710Schristos if ((array = cbor_new_definite_array(15)) == NULL ||
1221fc1e710Schristos (argv[0] = pack_byte(p->uv)) == NULL ||
1231fc1e710Schristos (argv[1] = pack_byte(p->up)) == NULL ||
12495dbdf32Schristos (argv[2] = pack_byte(p->opt)) == NULL ||
1251fc1e710Schristos (argv[3] = pack_byte(p->type)) == NULL ||
1261fc1e710Schristos (argv[4] = pack_byte(p->cred_count)) == NULL ||
1271fc1e710Schristos (argv[5] = pack_int(p->ext)) == NULL ||
1281fc1e710Schristos (argv[6] = pack_int(p->seed)) == NULL ||
1291fc1e710Schristos (argv[7] = pack_string(p->rp_id)) == NULL ||
1301fc1e710Schristos (argv[8] = pack_string(p->pin)) == NULL ||
1311fc1e710Schristos (argv[9] = pack_blob(&p->wire_data)) == NULL ||
1321fc1e710Schristos (argv[10] = pack_blob(&p->rs256)) == NULL ||
1331fc1e710Schristos (argv[11] = pack_blob(&p->es256)) == NULL ||
1341fc1e710Schristos (argv[12] = pack_blob(&p->eddsa)) == NULL ||
1351fc1e710Schristos (argv[13] = pack_blob(&p->cred)) == NULL ||
1361fc1e710Schristos (argv[14] = pack_blob(&p->cdh)) == NULL)
1371fc1e710Schristos goto fail;
1381fc1e710Schristos
1391fc1e710Schristos for (size_t i = 0; i < 15; i++)
1401fc1e710Schristos if (cbor_array_push(array, argv[i]) == false)
1411fc1e710Schristos goto fail;
1421fc1e710Schristos
1431fc1e710Schristos if ((cbor_len = cbor_serialize_alloc(array, &cbor,
144*2d40c451Schristos &cbor_alloc_len)) == 0 || cbor_len > len) {
1451fc1e710Schristos cbor_len = 0;
1461fc1e710Schristos goto fail;
147ba9bdd8bSchristos }
148ba9bdd8bSchristos
1491fc1e710Schristos memcpy(ptr, cbor, cbor_len);
1501fc1e710Schristos fail:
1511fc1e710Schristos for (size_t i = 0; i < 15; i++)
1521fc1e710Schristos if (argv[i])
1531fc1e710Schristos cbor_decref(&argv[i]);
1541fc1e710Schristos
1551fc1e710Schristos if (array)
1561fc1e710Schristos cbor_decref(&array);
1571fc1e710Schristos
1581fc1e710Schristos free(cbor);
1591fc1e710Schristos
1601fc1e710Schristos return cbor_len;
1611fc1e710Schristos }
1621fc1e710Schristos
1631fc1e710Schristos size_t
pack_dummy(uint8_t * ptr,size_t len)1641fc1e710Schristos pack_dummy(uint8_t *ptr, size_t len)
165ba9bdd8bSchristos {
1661fc1e710Schristos struct param dummy;
167*2d40c451Schristos uint8_t blob[MAXCORPUS];
1681fc1e710Schristos size_t blob_len;
1691fc1e710Schristos
1701fc1e710Schristos memset(&dummy, 0, sizeof(dummy));
1711fc1e710Schristos
1721fc1e710Schristos dummy.type = 1; /* rsa */
1731fc1e710Schristos dummy.ext = FIDO_EXT_HMAC_SECRET;
1741fc1e710Schristos
1751fc1e710Schristos strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin));
1761fc1e710Schristos strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id));
1771fc1e710Schristos
1781fc1e710Schristos dummy.cred.len = sizeof(dummy_cdh); /* XXX */
1791fc1e710Schristos dummy.cdh.len = sizeof(dummy_cdh);
1801fc1e710Schristos dummy.es256.len = sizeof(dummy_es256);
1811fc1e710Schristos dummy.rs256.len = sizeof(dummy_rs256);
1821fc1e710Schristos dummy.eddsa.len = sizeof(dummy_eddsa);
1831fc1e710Schristos dummy.wire_data.len = sizeof(dummy_wire_data_fido);
1841fc1e710Schristos
1851fc1e710Schristos memcpy(&dummy.cred.body, &dummy_cdh, dummy.cred.len); /* XXX */
1861fc1e710Schristos memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len);
1871fc1e710Schristos memcpy(&dummy.wire_data.body, &dummy_wire_data_fido,
1881fc1e710Schristos dummy.wire_data.len);
1891fc1e710Schristos memcpy(&dummy.es256.body, &dummy_es256, dummy.es256.len);
1901fc1e710Schristos memcpy(&dummy.rs256.body, &dummy_rs256, dummy.rs256.len);
1911fc1e710Schristos memcpy(&dummy.eddsa.body, &dummy_eddsa, dummy.eddsa.len);
1921fc1e710Schristos
1931fc1e710Schristos assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
1941fc1e710Schristos
1951fc1e710Schristos if (blob_len > len) {
1961fc1e710Schristos memcpy(ptr, blob, len);
1971fc1e710Schristos return len;
1981fc1e710Schristos }
1991fc1e710Schristos
2001fc1e710Schristos memcpy(ptr, blob, blob_len);
2011fc1e710Schristos
2021fc1e710Schristos return blob_len;
203ba9bdd8bSchristos }
204ba9bdd8bSchristos
205ba9bdd8bSchristos static void
get_assert(fido_assert_t * assert,uint8_t opt,const struct blob * cdh,const char * rp_id,int ext,uint8_t up,uint8_t uv,const char * pin,uint8_t cred_count,const struct blob * cred)20695dbdf32Schristos get_assert(fido_assert_t *assert, uint8_t opt, const struct blob *cdh,
207ba9bdd8bSchristos const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin,
2081fc1e710Schristos uint8_t cred_count, const struct blob *cred)
209ba9bdd8bSchristos {
210ba9bdd8bSchristos fido_dev_t *dev;
211ba9bdd8bSchristos
21295dbdf32Schristos if ((dev = open_dev(opt & 2)) == NULL)
213ba9bdd8bSchristos return;
21495dbdf32Schristos if (opt & 1)
215ba9bdd8bSchristos fido_dev_force_u2f(dev);
21695dbdf32Schristos if (ext & FIDO_EXT_HMAC_SECRET)
2171fc1e710Schristos fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET);
21895dbdf32Schristos if (ext & FIDO_EXT_CRED_BLOB)
21995dbdf32Schristos fido_assert_set_extensions(assert, FIDO_EXT_CRED_BLOB);
22095dbdf32Schristos if (ext & FIDO_EXT_LARGEBLOB_KEY)
22195dbdf32Schristos fido_assert_set_extensions(assert, FIDO_EXT_LARGEBLOB_KEY);
2221fc1e710Schristos if (up & 1)
2231fc1e710Schristos fido_assert_set_up(assert, FIDO_OPT_TRUE);
22495dbdf32Schristos else if (opt & 1)
2251fc1e710Schristos fido_assert_set_up(assert, FIDO_OPT_FALSE);
2261fc1e710Schristos if (uv & 1)
2271fc1e710Schristos fido_assert_set_uv(assert, FIDO_OPT_TRUE);
228ba9bdd8bSchristos
229ba9bdd8bSchristos for (uint8_t i = 0; i < cred_count; i++)
230ba9bdd8bSchristos fido_assert_allow_cred(assert, cred->body, cred->len);
231ba9bdd8bSchristos
232ba9bdd8bSchristos fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len);
233ba9bdd8bSchristos fido_assert_set_rp(assert, rp_id);
2341fc1e710Schristos /* XXX reuse cred as hmac salt */
235ba9bdd8bSchristos fido_assert_set_hmac_salt(assert, cred->body, cred->len);
236ba9bdd8bSchristos
2371fc1e710Schristos /* repeat memory operations to trigger reallocation paths */
2381fc1e710Schristos fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len);
2391fc1e710Schristos fido_assert_set_rp(assert, rp_id);
2401fc1e710Schristos fido_assert_set_hmac_salt(assert, cred->body, cred->len);
2411fc1e710Schristos
2421fc1e710Schristos if (strlen(pin) == 0)
2431fc1e710Schristos pin = NULL;
2441fc1e710Schristos
24595dbdf32Schristos fido_dev_get_assert(dev, assert, (opt & 1) ? NULL : pin);
246ba9bdd8bSchristos
247ba9bdd8bSchristos fido_dev_cancel(dev);
248ba9bdd8bSchristos fido_dev_close(dev);
249ba9bdd8bSchristos fido_dev_free(&dev);
250ba9bdd8bSchristos }
251ba9bdd8bSchristos
252ba9bdd8bSchristos static void
verify_assert(int type,const unsigned char * cdh_ptr,size_t cdh_len,const char * rp_id,const unsigned char * authdata_ptr,size_t authdata_len,const unsigned char * sig_ptr,size_t sig_len,uint8_t up,uint8_t uv,int ext,void * pk)253ba9bdd8bSchristos verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len,
254ba9bdd8bSchristos const char *rp_id, const unsigned char *authdata_ptr, size_t authdata_len,
255ba9bdd8bSchristos const unsigned char *sig_ptr, size_t sig_len, uint8_t up, uint8_t uv,
256ba9bdd8bSchristos int ext, void *pk)
257ba9bdd8bSchristos {
258ba9bdd8bSchristos fido_assert_t *assert = NULL;
259*2d40c451Schristos int r;
260ba9bdd8bSchristos
261ba9bdd8bSchristos if ((assert = fido_assert_new()) == NULL)
262ba9bdd8bSchristos return;
263ba9bdd8bSchristos
264ba9bdd8bSchristos fido_assert_set_clientdata_hash(assert, cdh_ptr, cdh_len);
265ba9bdd8bSchristos fido_assert_set_rp(assert, rp_id);
266ba9bdd8bSchristos fido_assert_set_count(assert, 1);
2671fc1e710Schristos
268ba9bdd8bSchristos if (fido_assert_set_authdata(assert, 0, authdata_ptr,
269ba9bdd8bSchristos authdata_len) != FIDO_OK) {
270ba9bdd8bSchristos fido_assert_set_authdata_raw(assert, 0, authdata_ptr,
271ba9bdd8bSchristos authdata_len);
272ba9bdd8bSchristos }
2731fc1e710Schristos
2741fc1e710Schristos if (up & 1)
2751fc1e710Schristos fido_assert_set_up(assert, FIDO_OPT_TRUE);
2761fc1e710Schristos if (uv & 1)
2771fc1e710Schristos fido_assert_set_uv(assert, FIDO_OPT_TRUE);
2781fc1e710Schristos
279ba9bdd8bSchristos fido_assert_set_extensions(assert, ext);
280ba9bdd8bSchristos fido_assert_set_sig(assert, 0, sig_ptr, sig_len);
2811fc1e710Schristos
2821fc1e710Schristos /* repeat memory operations to trigger reallocation paths */
2831fc1e710Schristos if (fido_assert_set_authdata(assert, 0, authdata_ptr,
2841fc1e710Schristos authdata_len) != FIDO_OK) {
2851fc1e710Schristos fido_assert_set_authdata_raw(assert, 0, authdata_ptr,
2861fc1e710Schristos authdata_len);
2871fc1e710Schristos }
2881fc1e710Schristos fido_assert_set_sig(assert, 0, sig_ptr, sig_len);
2891fc1e710Schristos
290*2d40c451Schristos r = fido_assert_verify(assert, 0, type, pk);
291*2d40c451Schristos consume(&r, sizeof(r));
292ba9bdd8bSchristos
293ba9bdd8bSchristos fido_assert_free(&assert);
294ba9bdd8bSchristos }
295ba9bdd8bSchristos
296ba9bdd8bSchristos /*
297*2d40c451Schristos * Do a dummy conversion to exercise es256_pk_from_EVP_PKEY().
298*2d40c451Schristos */
299*2d40c451Schristos static void
es256_convert(const es256_pk_t * k)300*2d40c451Schristos es256_convert(const es256_pk_t *k)
301*2d40c451Schristos {
302*2d40c451Schristos EVP_PKEY *pkey = NULL;
303*2d40c451Schristos es256_pk_t *pk = NULL;
304*2d40c451Schristos int r;
305*2d40c451Schristos
306*2d40c451Schristos if ((pkey = es256_pk_to_EVP_PKEY(k)) == NULL ||
307*2d40c451Schristos (pk = es256_pk_new()) == NULL)
308*2d40c451Schristos goto out;
309*2d40c451Schristos
310*2d40c451Schristos r = es256_pk_from_EVP_PKEY(pk, pkey);
311*2d40c451Schristos consume(&r, sizeof(r));
312*2d40c451Schristos out:
313*2d40c451Schristos es256_pk_free(&pk);
314*2d40c451Schristos EVP_PKEY_free(pkey);
315*2d40c451Schristos }
316*2d40c451Schristos
317*2d40c451Schristos /*
318*2d40c451Schristos * Do a dummy conversion to exercise es384_pk_from_EVP_PKEY().
319*2d40c451Schristos */
320*2d40c451Schristos static void
es384_convert(const es384_pk_t * k)321*2d40c451Schristos es384_convert(const es384_pk_t *k)
322*2d40c451Schristos {
323*2d40c451Schristos EVP_PKEY *pkey = NULL;
324*2d40c451Schristos es384_pk_t *pk = NULL;
325*2d40c451Schristos int r;
326*2d40c451Schristos
327*2d40c451Schristos if ((pkey = es384_pk_to_EVP_PKEY(k)) == NULL ||
328*2d40c451Schristos (pk = es384_pk_new()) == NULL)
329*2d40c451Schristos goto out;
330*2d40c451Schristos
331*2d40c451Schristos r = es384_pk_from_EVP_PKEY(pk, pkey);
332*2d40c451Schristos consume(&r, sizeof(r));
333*2d40c451Schristos out:
334*2d40c451Schristos es384_pk_free(&pk);
335*2d40c451Schristos EVP_PKEY_free(pkey);
336*2d40c451Schristos }
337*2d40c451Schristos
338*2d40c451Schristos /*
339*2d40c451Schristos * Do a dummy conversion to exercise rs256_pk_from_EVP_PKEY().
340ba9bdd8bSchristos */
341ba9bdd8bSchristos static void
rs256_convert(const rs256_pk_t * k)342ba9bdd8bSchristos rs256_convert(const rs256_pk_t *k)
343ba9bdd8bSchristos {
344ba9bdd8bSchristos EVP_PKEY *pkey = NULL;
345ba9bdd8bSchristos rs256_pk_t *pk = NULL;
346*2d40c451Schristos int r;
347ba9bdd8bSchristos
348ba9bdd8bSchristos if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL ||
349*2d40c451Schristos (pk = rs256_pk_new()) == NULL)
350ba9bdd8bSchristos goto out;
351ba9bdd8bSchristos
352*2d40c451Schristos r = rs256_pk_from_EVP_PKEY(pk, pkey);
353*2d40c451Schristos consume(&r, sizeof(r));
354ba9bdd8bSchristos out:
355ba9bdd8bSchristos rs256_pk_free(&pk);
356ba9bdd8bSchristos EVP_PKEY_free(pkey);
357ba9bdd8bSchristos }
358ba9bdd8bSchristos
359ba9bdd8bSchristos /*
360ba9bdd8bSchristos * Do a dummy conversion to exercise eddsa_pk_from_EVP_PKEY().
361ba9bdd8bSchristos */
362ba9bdd8bSchristos static void
eddsa_convert(const eddsa_pk_t * k)363ba9bdd8bSchristos eddsa_convert(const eddsa_pk_t *k)
364ba9bdd8bSchristos {
365ba9bdd8bSchristos EVP_PKEY *pkey = NULL;
366ba9bdd8bSchristos eddsa_pk_t *pk = NULL;
367*2d40c451Schristos int r;
368ba9bdd8bSchristos
369ba9bdd8bSchristos if ((pkey = eddsa_pk_to_EVP_PKEY(k)) == NULL ||
370ba9bdd8bSchristos (pk = eddsa_pk_new()) == NULL)
371ba9bdd8bSchristos goto out;
372ba9bdd8bSchristos
373ba9bdd8bSchristos r = eddsa_pk_from_EVP_PKEY(pk, pkey);
374*2d40c451Schristos consume(&r, sizeof(r));
375ba9bdd8bSchristos out:
376ba9bdd8bSchristos if (pk)
377ba9bdd8bSchristos eddsa_pk_free(&pk);
378ba9bdd8bSchristos if (pkey)
379ba9bdd8bSchristos EVP_PKEY_free(pkey);
380ba9bdd8bSchristos }
381ba9bdd8bSchristos
3821fc1e710Schristos void
test(const struct param * p)3831fc1e710Schristos test(const struct param *p)
384ba9bdd8bSchristos {
385ba9bdd8bSchristos fido_assert_t *assert = NULL;
386ba9bdd8bSchristos es256_pk_t *es256_pk = NULL;
387*2d40c451Schristos es384_pk_t *es384_pk = NULL;
388ba9bdd8bSchristos rs256_pk_t *rs256_pk = NULL;
389ba9bdd8bSchristos eddsa_pk_t *eddsa_pk = NULL;
390ba9bdd8bSchristos uint8_t flags;
391ba9bdd8bSchristos uint32_t sigcount;
392ba9bdd8bSchristos int cose_alg = 0;
393ba9bdd8bSchristos void *pk;
394ba9bdd8bSchristos
3951fc1e710Schristos prng_init((unsigned int)p->seed);
396*2d40c451Schristos fuzz_clock_reset();
397ba9bdd8bSchristos fido_init(FIDO_DEBUG);
398ba9bdd8bSchristos fido_set_log_handler(consume_str);
399ba9bdd8bSchristos
4001fc1e710Schristos switch (p->type & 3) {
401ba9bdd8bSchristos case 0:
402ba9bdd8bSchristos cose_alg = COSE_ES256;
403ba9bdd8bSchristos
404ba9bdd8bSchristos if ((es256_pk = es256_pk_new()) == NULL)
4051fc1e710Schristos return;
406ba9bdd8bSchristos
4071fc1e710Schristos es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len);
408ba9bdd8bSchristos pk = es256_pk;
409ba9bdd8bSchristos
410*2d40c451Schristos es256_convert(pk);
411*2d40c451Schristos
412ba9bdd8bSchristos break;
413ba9bdd8bSchristos case 1:
414ba9bdd8bSchristos cose_alg = COSE_RS256;
415ba9bdd8bSchristos
416ba9bdd8bSchristos if ((rs256_pk = rs256_pk_new()) == NULL)
4171fc1e710Schristos return;
418ba9bdd8bSchristos
4191fc1e710Schristos rs256_pk_from_ptr(rs256_pk, p->rs256.body, p->rs256.len);
420ba9bdd8bSchristos pk = rs256_pk;
421ba9bdd8bSchristos
422ba9bdd8bSchristos rs256_convert(pk);
423ba9bdd8bSchristos
424ba9bdd8bSchristos break;
425*2d40c451Schristos case 2:
426*2d40c451Schristos cose_alg = COSE_ES384;
427*2d40c451Schristos
428*2d40c451Schristos if ((es384_pk = es384_pk_new()) == NULL)
429*2d40c451Schristos return;
430*2d40c451Schristos
431*2d40c451Schristos /* XXX reuse p->es256 as es384 */
432*2d40c451Schristos es384_pk_from_ptr(es384_pk, p->es256.body, p->es256.len);
433*2d40c451Schristos pk = es384_pk;
434*2d40c451Schristos
435*2d40c451Schristos es384_convert(pk);
436*2d40c451Schristos
437*2d40c451Schristos break;
438ba9bdd8bSchristos default:
439ba9bdd8bSchristos cose_alg = COSE_EDDSA;
440ba9bdd8bSchristos
441ba9bdd8bSchristos if ((eddsa_pk = eddsa_pk_new()) == NULL)
4421fc1e710Schristos return;
443ba9bdd8bSchristos
4441fc1e710Schristos eddsa_pk_from_ptr(eddsa_pk, p->eddsa.body, p->eddsa.len);
445ba9bdd8bSchristos pk = eddsa_pk;
446ba9bdd8bSchristos
447ba9bdd8bSchristos eddsa_convert(pk);
448ba9bdd8bSchristos
449ba9bdd8bSchristos break;
450ba9bdd8bSchristos }
451ba9bdd8bSchristos
452ba9bdd8bSchristos if ((assert = fido_assert_new()) == NULL)
453ba9bdd8bSchristos goto out;
454ba9bdd8bSchristos
4551fc1e710Schristos set_wire_data(p->wire_data.body, p->wire_data.len);
456ba9bdd8bSchristos
45795dbdf32Schristos get_assert(assert, p->opt, &p->cdh, p->rp_id, p->ext, p->up, p->uv,
4581fc1e710Schristos p->pin, p->cred_count, &p->cred);
459ba9bdd8bSchristos
460ba9bdd8bSchristos /* XXX +1 on purpose */
461ba9bdd8bSchristos for (size_t i = 0; i <= fido_assert_count(assert); i++) {
462ba9bdd8bSchristos verify_assert(cose_alg,
463ba9bdd8bSchristos fido_assert_clientdata_hash_ptr(assert),
464ba9bdd8bSchristos fido_assert_clientdata_hash_len(assert),
465ba9bdd8bSchristos fido_assert_rp_id(assert),
466ba9bdd8bSchristos fido_assert_authdata_ptr(assert, i),
467ba9bdd8bSchristos fido_assert_authdata_len(assert, i),
468ba9bdd8bSchristos fido_assert_sig_ptr(assert, i),
4691fc1e710Schristos fido_assert_sig_len(assert, i), p->up, p->uv, p->ext, pk);
470ba9bdd8bSchristos consume(fido_assert_id_ptr(assert, i),
471ba9bdd8bSchristos fido_assert_id_len(assert, i));
472ba9bdd8bSchristos consume(fido_assert_user_id_ptr(assert, i),
473ba9bdd8bSchristos fido_assert_user_id_len(assert, i));
474ba9bdd8bSchristos consume(fido_assert_hmac_secret_ptr(assert, i),
475ba9bdd8bSchristos fido_assert_hmac_secret_len(assert, i));
476ede6d7f8Schristos consume_str(fido_assert_user_icon(assert, i));
477ede6d7f8Schristos consume_str(fido_assert_user_name(assert, i));
478ede6d7f8Schristos consume_str(fido_assert_user_display_name(assert, i));
47995dbdf32Schristos consume(fido_assert_blob_ptr(assert, i),
48095dbdf32Schristos fido_assert_blob_len(assert, i));
48195dbdf32Schristos consume(fido_assert_largeblob_key_ptr(assert, i),
48295dbdf32Schristos fido_assert_largeblob_key_len(assert, i));
483ba9bdd8bSchristos flags = fido_assert_flags(assert, i);
484ba9bdd8bSchristos consume(&flags, sizeof(flags));
485ba9bdd8bSchristos sigcount = fido_assert_sigcount(assert, i);
486ba9bdd8bSchristos consume(&sigcount, sizeof(sigcount));
487ba9bdd8bSchristos }
488ba9bdd8bSchristos
489ba9bdd8bSchristos out:
490ba9bdd8bSchristos es256_pk_free(&es256_pk);
491*2d40c451Schristos es384_pk_free(&es384_pk);
492ba9bdd8bSchristos rs256_pk_free(&rs256_pk);
493ba9bdd8bSchristos eddsa_pk_free(&eddsa_pk);
494ba9bdd8bSchristos
495ba9bdd8bSchristos fido_assert_free(&assert);
496ba9bdd8bSchristos }
497ba9bdd8bSchristos
4981fc1e710Schristos void
mutate(struct param * p,unsigned int seed,unsigned int flags)4991fc1e710Schristos mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
500ba9bdd8bSchristos {
5011fc1e710Schristos if (flags & MUTATE_SEED)
5021fc1e710Schristos p->seed = (int)seed;
503ba9bdd8bSchristos
5041fc1e710Schristos if (flags & MUTATE_PARAM) {
5051fc1e710Schristos mutate_byte(&p->uv);
5061fc1e710Schristos mutate_byte(&p->up);
50795dbdf32Schristos mutate_byte(&p->opt);
5081fc1e710Schristos mutate_byte(&p->type);
5091fc1e710Schristos mutate_byte(&p->cred_count);
5101fc1e710Schristos mutate_int(&p->ext);
5111fc1e710Schristos mutate_blob(&p->rs256);
5121fc1e710Schristos mutate_blob(&p->es256);
5131fc1e710Schristos mutate_blob(&p->eddsa);
5141fc1e710Schristos mutate_blob(&p->cred);
5151fc1e710Schristos mutate_blob(&p->cdh);
5161fc1e710Schristos mutate_string(p->rp_id);
5171fc1e710Schristos mutate_string(p->pin);
518ba9bdd8bSchristos }
519ba9bdd8bSchristos
5201fc1e710Schristos if (flags & MUTATE_WIREDATA) {
52195dbdf32Schristos if (p->opt & 1) {
5221fc1e710Schristos p->wire_data.len = sizeof(dummy_wire_data_u2f);
5231fc1e710Schristos memcpy(&p->wire_data.body, &dummy_wire_data_u2f,
5241fc1e710Schristos p->wire_data.len);
525ba9bdd8bSchristos } else {
5261fc1e710Schristos p->wire_data.len = sizeof(dummy_wire_data_fido);
5271fc1e710Schristos memcpy(&p->wire_data.body, &dummy_wire_data_fido,
5281fc1e710Schristos p->wire_data.len);
529ba9bdd8bSchristos }
5301fc1e710Schristos mutate_blob(&p->wire_data);
5311fc1e710Schristos }
532ba9bdd8bSchristos }
533