10afa8e06SEd Maste /*
2*2ccfa855SEd Maste * Copyright (c) 2019-2022 Yubico AB. All rights reserved.
30afa8e06SEd Maste * Use of this source code is governed by a BSD-style
40afa8e06SEd Maste * license that can be found in the LICENSE file.
5*2ccfa855SEd Maste * SPDX-License-Identifier: BSD-2-Clause
60afa8e06SEd Maste */
70afa8e06SEd Maste
80afa8e06SEd Maste #include <assert.h>
90afa8e06SEd Maste #include <stdint.h>
100afa8e06SEd Maste #include <stdio.h>
110afa8e06SEd Maste #include <stdlib.h>
120afa8e06SEd Maste #include <string.h>
130afa8e06SEd Maste
140afa8e06SEd Maste #include "mutator_aux.h"
150afa8e06SEd Maste #include "wiredata_fido2.h"
160afa8e06SEd Maste #include "dummy.h"
170afa8e06SEd Maste
180afa8e06SEd Maste #include "../openbsd-compat/openbsd-compat.h"
190afa8e06SEd Maste
20f540a430SEd Maste #define MAXRPID 64
21f540a430SEd Maste
220afa8e06SEd Maste struct param {
230afa8e06SEd Maste char pin1[MAXSTR];
240afa8e06SEd Maste char pin2[MAXSTR];
250afa8e06SEd Maste struct blob reset_wire_data;
260afa8e06SEd Maste struct blob info_wire_data;
270afa8e06SEd Maste struct blob set_pin_wire_data;
280afa8e06SEd Maste struct blob change_pin_wire_data;
290afa8e06SEd Maste struct blob retry_wire_data;
300afa8e06SEd Maste struct blob config_wire_data;
310afa8e06SEd Maste int seed;
320afa8e06SEd Maste };
330afa8e06SEd Maste
340afa8e06SEd Maste static const uint8_t dummy_reset_wire_data[] = {
350afa8e06SEd Maste WIREDATA_CTAP_INIT,
360afa8e06SEd Maste WIREDATA_CTAP_CBOR_INFO,
370afa8e06SEd Maste WIREDATA_CTAP_KEEPALIVE,
380afa8e06SEd Maste WIREDATA_CTAP_KEEPALIVE,
390afa8e06SEd Maste WIREDATA_CTAP_KEEPALIVE,
400afa8e06SEd Maste WIREDATA_CTAP_CBOR_STATUS,
410afa8e06SEd Maste };
420afa8e06SEd Maste
430afa8e06SEd Maste static const uint8_t dummy_info_wire_data[] = {
440afa8e06SEd Maste WIREDATA_CTAP_INIT,
450afa8e06SEd Maste WIREDATA_CTAP_CBOR_INFO,
460afa8e06SEd Maste WIREDATA_CTAP_CBOR_INFO,
470afa8e06SEd Maste };
480afa8e06SEd Maste
490afa8e06SEd Maste static const uint8_t dummy_set_pin_wire_data[] = {
500afa8e06SEd Maste WIREDATA_CTAP_INIT,
510afa8e06SEd Maste WIREDATA_CTAP_CBOR_INFO,
520afa8e06SEd Maste WIREDATA_CTAP_CBOR_AUTHKEY,
530afa8e06SEd Maste WIREDATA_CTAP_CBOR_STATUS,
540afa8e06SEd Maste };
550afa8e06SEd Maste
560afa8e06SEd Maste static const uint8_t dummy_change_pin_wire_data[] = {
570afa8e06SEd Maste WIREDATA_CTAP_INIT,
580afa8e06SEd Maste WIREDATA_CTAP_CBOR_INFO,
590afa8e06SEd Maste WIREDATA_CTAP_CBOR_AUTHKEY,
600afa8e06SEd Maste WIREDATA_CTAP_CBOR_STATUS,
610afa8e06SEd Maste };
620afa8e06SEd Maste
630afa8e06SEd Maste static const uint8_t dummy_retry_wire_data[] = {
640afa8e06SEd Maste WIREDATA_CTAP_INIT,
650afa8e06SEd Maste WIREDATA_CTAP_CBOR_INFO,
660afa8e06SEd Maste WIREDATA_CTAP_CBOR_RETRIES,
670afa8e06SEd Maste };
680afa8e06SEd Maste
690afa8e06SEd Maste static const uint8_t dummy_config_wire_data[] = {
700afa8e06SEd Maste WIREDATA_CTAP_INIT,
710afa8e06SEd Maste WIREDATA_CTAP_CBOR_INFO,
720afa8e06SEd Maste WIREDATA_CTAP_CBOR_STATUS,
730afa8e06SEd Maste };
740afa8e06SEd Maste
750afa8e06SEd Maste struct param *
unpack(const uint8_t * ptr,size_t len)760afa8e06SEd Maste unpack(const uint8_t *ptr, size_t len)
770afa8e06SEd Maste {
780afa8e06SEd Maste cbor_item_t *item = NULL, **v;
790afa8e06SEd Maste struct cbor_load_result cbor;
800afa8e06SEd Maste struct param *p;
810afa8e06SEd Maste int ok = -1;
820afa8e06SEd Maste
830afa8e06SEd Maste if ((p = calloc(1, sizeof(*p))) == NULL ||
840afa8e06SEd Maste (item = cbor_load(ptr, len, &cbor)) == NULL ||
850afa8e06SEd Maste cbor.read != len ||
860afa8e06SEd Maste cbor_isa_array(item) == false ||
870afa8e06SEd Maste cbor_array_is_definite(item) == false ||
880afa8e06SEd Maste cbor_array_size(item) != 9 ||
890afa8e06SEd Maste (v = cbor_array_handle(item)) == NULL)
900afa8e06SEd Maste goto fail;
910afa8e06SEd Maste
920afa8e06SEd Maste if (unpack_int(v[0], &p->seed) < 0 ||
930afa8e06SEd Maste unpack_string(v[1], p->pin1) < 0 ||
940afa8e06SEd Maste unpack_string(v[2], p->pin2) < 0 ||
950afa8e06SEd Maste unpack_blob(v[3], &p->reset_wire_data) < 0 ||
960afa8e06SEd Maste unpack_blob(v[4], &p->info_wire_data) < 0 ||
970afa8e06SEd Maste unpack_blob(v[5], &p->set_pin_wire_data) < 0 ||
980afa8e06SEd Maste unpack_blob(v[6], &p->change_pin_wire_data) < 0 ||
990afa8e06SEd Maste unpack_blob(v[7], &p->retry_wire_data) < 0 ||
1000afa8e06SEd Maste unpack_blob(v[8], &p->config_wire_data) < 0)
1010afa8e06SEd Maste goto fail;
1020afa8e06SEd Maste
1030afa8e06SEd Maste ok = 0;
1040afa8e06SEd Maste fail:
1050afa8e06SEd Maste if (ok < 0) {
1060afa8e06SEd Maste free(p);
1070afa8e06SEd Maste p = NULL;
1080afa8e06SEd Maste }
1090afa8e06SEd Maste
1100afa8e06SEd Maste if (item)
1110afa8e06SEd Maste cbor_decref(&item);
1120afa8e06SEd Maste
1130afa8e06SEd Maste return p;
1140afa8e06SEd Maste }
1150afa8e06SEd Maste
1160afa8e06SEd Maste size_t
pack(uint8_t * ptr,size_t len,const struct param * p)1170afa8e06SEd Maste pack(uint8_t *ptr, size_t len, const struct param *p)
1180afa8e06SEd Maste {
1190afa8e06SEd Maste cbor_item_t *argv[9], *array = NULL;
1200afa8e06SEd Maste size_t cbor_alloc_len, cbor_len = 0;
1210afa8e06SEd Maste unsigned char *cbor = NULL;
1220afa8e06SEd Maste
1230afa8e06SEd Maste memset(argv, 0, sizeof(argv));
1240afa8e06SEd Maste
1250afa8e06SEd Maste if ((array = cbor_new_definite_array(9)) == NULL ||
1260afa8e06SEd Maste (argv[0] = pack_int(p->seed)) == NULL ||
1270afa8e06SEd Maste (argv[1] = pack_string(p->pin1)) == NULL ||
1280afa8e06SEd Maste (argv[2] = pack_string(p->pin2)) == NULL ||
1290afa8e06SEd Maste (argv[3] = pack_blob(&p->reset_wire_data)) == NULL ||
1300afa8e06SEd Maste (argv[4] = pack_blob(&p->info_wire_data)) == NULL ||
1310afa8e06SEd Maste (argv[5] = pack_blob(&p->set_pin_wire_data)) == NULL ||
1320afa8e06SEd Maste (argv[6] = pack_blob(&p->change_pin_wire_data)) == NULL ||
1330afa8e06SEd Maste (argv[7] = pack_blob(&p->retry_wire_data)) == NULL ||
1340afa8e06SEd Maste (argv[8] = pack_blob(&p->config_wire_data)) == NULL)
1350afa8e06SEd Maste goto fail;
1360afa8e06SEd Maste
1370afa8e06SEd Maste for (size_t i = 0; i < 9; i++)
1380afa8e06SEd Maste if (cbor_array_push(array, argv[i]) == false)
1390afa8e06SEd Maste goto fail;
1400afa8e06SEd Maste
1410afa8e06SEd Maste if ((cbor_len = cbor_serialize_alloc(array, &cbor,
142*2ccfa855SEd Maste &cbor_alloc_len)) == 0 || cbor_len > len) {
1430afa8e06SEd Maste cbor_len = 0;
1440afa8e06SEd Maste goto fail;
1450afa8e06SEd Maste }
1460afa8e06SEd Maste
1470afa8e06SEd Maste memcpy(ptr, cbor, cbor_len);
1480afa8e06SEd Maste fail:
1490afa8e06SEd Maste for (size_t i = 0; i < 9; i++)
1500afa8e06SEd Maste if (argv[i])
1510afa8e06SEd Maste cbor_decref(&argv[i]);
1520afa8e06SEd Maste
1530afa8e06SEd Maste if (array)
1540afa8e06SEd Maste cbor_decref(&array);
1550afa8e06SEd Maste
1560afa8e06SEd Maste free(cbor);
1570afa8e06SEd Maste
1580afa8e06SEd Maste return cbor_len;
1590afa8e06SEd Maste }
1600afa8e06SEd Maste
1610afa8e06SEd Maste size_t
pack_dummy(uint8_t * ptr,size_t len)1620afa8e06SEd Maste pack_dummy(uint8_t *ptr, size_t len)
1630afa8e06SEd Maste {
1640afa8e06SEd Maste struct param dummy;
165*2ccfa855SEd Maste uint8_t blob[MAXCORPUS];
1660afa8e06SEd Maste size_t blob_len;
1670afa8e06SEd Maste
1680afa8e06SEd Maste memset(&dummy, 0, sizeof(dummy));
1690afa8e06SEd Maste
1700afa8e06SEd Maste strlcpy(dummy.pin1, dummy_pin1, sizeof(dummy.pin1));
1710afa8e06SEd Maste strlcpy(dummy.pin2, dummy_pin2, sizeof(dummy.pin2));
1720afa8e06SEd Maste
1730afa8e06SEd Maste dummy.reset_wire_data.len = sizeof(dummy_reset_wire_data);
1740afa8e06SEd Maste dummy.info_wire_data.len = sizeof(dummy_info_wire_data);
1750afa8e06SEd Maste dummy.set_pin_wire_data.len = sizeof(dummy_set_pin_wire_data);
1760afa8e06SEd Maste dummy.change_pin_wire_data.len = sizeof(dummy_change_pin_wire_data);
1770afa8e06SEd Maste dummy.retry_wire_data.len = sizeof(dummy_retry_wire_data);
1780afa8e06SEd Maste dummy.config_wire_data.len = sizeof(dummy_config_wire_data);
1790afa8e06SEd Maste
1800afa8e06SEd Maste memcpy(&dummy.reset_wire_data.body, &dummy_reset_wire_data,
1810afa8e06SEd Maste dummy.reset_wire_data.len);
1820afa8e06SEd Maste memcpy(&dummy.info_wire_data.body, &dummy_info_wire_data,
1830afa8e06SEd Maste dummy.info_wire_data.len);
1840afa8e06SEd Maste memcpy(&dummy.set_pin_wire_data.body, &dummy_set_pin_wire_data,
1850afa8e06SEd Maste dummy.set_pin_wire_data.len);
1860afa8e06SEd Maste memcpy(&dummy.change_pin_wire_data.body, &dummy_change_pin_wire_data,
1870afa8e06SEd Maste dummy.change_pin_wire_data.len);
1880afa8e06SEd Maste memcpy(&dummy.retry_wire_data.body, &dummy_retry_wire_data,
1890afa8e06SEd Maste dummy.retry_wire_data.len);
1900afa8e06SEd Maste memcpy(&dummy.config_wire_data.body, &dummy_config_wire_data,
1910afa8e06SEd Maste dummy.config_wire_data.len);
1920afa8e06SEd Maste
1930afa8e06SEd Maste assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
1940afa8e06SEd Maste
1950afa8e06SEd Maste if (blob_len > len) {
1960afa8e06SEd Maste memcpy(ptr, blob, len);
1970afa8e06SEd Maste return len;
1980afa8e06SEd Maste }
1990afa8e06SEd Maste
2000afa8e06SEd Maste memcpy(ptr, blob, blob_len);
2010afa8e06SEd Maste
2020afa8e06SEd Maste return blob_len;
2030afa8e06SEd Maste }
2040afa8e06SEd Maste
2050afa8e06SEd Maste static void
dev_reset(const struct param * p)2060afa8e06SEd Maste dev_reset(const struct param *p)
2070afa8e06SEd Maste {
2080afa8e06SEd Maste fido_dev_t *dev;
2090afa8e06SEd Maste
2100afa8e06SEd Maste set_wire_data(p->reset_wire_data.body, p->reset_wire_data.len);
2110afa8e06SEd Maste
2120afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
2130afa8e06SEd Maste return;
2140afa8e06SEd Maste
2150afa8e06SEd Maste fido_dev_reset(dev);
2160afa8e06SEd Maste fido_dev_close(dev);
2170afa8e06SEd Maste fido_dev_free(&dev);
2180afa8e06SEd Maste }
2190afa8e06SEd Maste
2200afa8e06SEd Maste static void
dev_get_cbor_info(const struct param * p)2210afa8e06SEd Maste dev_get_cbor_info(const struct param *p)
2220afa8e06SEd Maste {
2230afa8e06SEd Maste fido_dev_t *dev;
2240afa8e06SEd Maste fido_cbor_info_t *ci;
2250afa8e06SEd Maste uint64_t n;
2260afa8e06SEd Maste uint8_t proto, major, minor, build, flags;
227*2ccfa855SEd Maste bool v;
2280afa8e06SEd Maste
2290afa8e06SEd Maste set_wire_data(p->info_wire_data.body, p->info_wire_data.len);
2300afa8e06SEd Maste
2310afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
2320afa8e06SEd Maste return;
2330afa8e06SEd Maste
2340afa8e06SEd Maste proto = fido_dev_protocol(dev);
2350afa8e06SEd Maste major = fido_dev_major(dev);
2360afa8e06SEd Maste minor = fido_dev_minor(dev);
2370afa8e06SEd Maste build = fido_dev_build(dev);
2380afa8e06SEd Maste flags = fido_dev_flags(dev);
2390afa8e06SEd Maste
2400afa8e06SEd Maste consume(&proto, sizeof(proto));
2410afa8e06SEd Maste consume(&major, sizeof(major));
2420afa8e06SEd Maste consume(&minor, sizeof(minor));
2430afa8e06SEd Maste consume(&build, sizeof(build));
2440afa8e06SEd Maste consume(&flags, sizeof(flags));
2450afa8e06SEd Maste
2460afa8e06SEd Maste if ((ci = fido_cbor_info_new()) == NULL)
2470afa8e06SEd Maste goto out;
2480afa8e06SEd Maste
2490afa8e06SEd Maste fido_dev_get_cbor_info(dev, ci);
2500afa8e06SEd Maste
2510afa8e06SEd Maste for (size_t i = 0; i < fido_cbor_info_versions_len(ci); i++) {
2520afa8e06SEd Maste char * const *sa = fido_cbor_info_versions_ptr(ci);
2530afa8e06SEd Maste consume(sa[i], strlen(sa[i]));
2540afa8e06SEd Maste }
2550afa8e06SEd Maste
2560afa8e06SEd Maste for (size_t i = 0; i < fido_cbor_info_extensions_len(ci); i++) {
2570afa8e06SEd Maste char * const *sa = fido_cbor_info_extensions_ptr(ci);
2580afa8e06SEd Maste consume(sa[i], strlen(sa[i]));
2590afa8e06SEd Maste }
2600afa8e06SEd Maste
2610afa8e06SEd Maste for (size_t i = 0; i < fido_cbor_info_transports_len(ci); i++) {
2620afa8e06SEd Maste char * const *sa = fido_cbor_info_transports_ptr(ci);
2630afa8e06SEd Maste consume(sa[i], strlen(sa[i]));
2640afa8e06SEd Maste }
2650afa8e06SEd Maste
2660afa8e06SEd Maste for (size_t i = 0; i < fido_cbor_info_options_len(ci); i++) {
2670afa8e06SEd Maste char * const *sa = fido_cbor_info_options_name_ptr(ci);
2680afa8e06SEd Maste const bool *va = fido_cbor_info_options_value_ptr(ci);
2690afa8e06SEd Maste consume(sa[i], strlen(sa[i]));
2700afa8e06SEd Maste consume(&va[i], sizeof(va[i]));
2710afa8e06SEd Maste }
2720afa8e06SEd Maste
2730afa8e06SEd Maste /* +1 on purpose */
2740afa8e06SEd Maste for (size_t i = 0; i <= fido_cbor_info_algorithm_count(ci); i++) {
2750afa8e06SEd Maste const char *type = fido_cbor_info_algorithm_type(ci, i);
2760afa8e06SEd Maste int cose = fido_cbor_info_algorithm_cose(ci, i);
2770afa8e06SEd Maste consume_str(type);
2780afa8e06SEd Maste consume(&cose, sizeof(cose));
2790afa8e06SEd Maste }
2800afa8e06SEd Maste
281*2ccfa855SEd Maste for (size_t i = 0; i < fido_cbor_info_certs_len(ci); i++) {
282*2ccfa855SEd Maste char * const *na = fido_cbor_info_certs_name_ptr(ci);
283*2ccfa855SEd Maste const uint64_t *va = fido_cbor_info_certs_value_ptr(ci);
284*2ccfa855SEd Maste consume(na[i], strlen(na[i]));
285*2ccfa855SEd Maste consume(&va[i], sizeof(va[i]));
286*2ccfa855SEd Maste }
287*2ccfa855SEd Maste
2880afa8e06SEd Maste n = fido_cbor_info_maxmsgsiz(ci);
2890afa8e06SEd Maste consume(&n, sizeof(n));
2900afa8e06SEd Maste n = fido_cbor_info_maxcredbloblen(ci);
2910afa8e06SEd Maste consume(&n, sizeof(n));
2920afa8e06SEd Maste n = fido_cbor_info_maxcredcntlst(ci);
2930afa8e06SEd Maste consume(&n, sizeof(n));
2940afa8e06SEd Maste n = fido_cbor_info_maxcredidlen(ci);
2950afa8e06SEd Maste consume(&n, sizeof(n));
296*2ccfa855SEd Maste n = fido_cbor_info_maxlargeblob(ci);
297*2ccfa855SEd Maste consume(&n, sizeof(n));
2980afa8e06SEd Maste n = fido_cbor_info_fwversion(ci);
2990afa8e06SEd Maste consume(&n, sizeof(n));
300*2ccfa855SEd Maste n = fido_cbor_info_minpinlen(ci);
301*2ccfa855SEd Maste consume(&n, sizeof(n));
302*2ccfa855SEd Maste n = fido_cbor_info_maxrpid_minpinlen(ci);
303*2ccfa855SEd Maste consume(&n, sizeof(n));
304*2ccfa855SEd Maste n = fido_cbor_info_uv_attempts(ci);
305*2ccfa855SEd Maste consume(&n, sizeof(n));
306*2ccfa855SEd Maste n = fido_cbor_info_uv_modality(ci);
307*2ccfa855SEd Maste consume(&n, sizeof(n));
308*2ccfa855SEd Maste n = (uint64_t)fido_cbor_info_rk_remaining(ci);
309*2ccfa855SEd Maste consume(&n, sizeof(n));
3100afa8e06SEd Maste
3110afa8e06SEd Maste consume(fido_cbor_info_aaguid_ptr(ci), fido_cbor_info_aaguid_len(ci));
3120afa8e06SEd Maste consume(fido_cbor_info_protocols_ptr(ci),
3130afa8e06SEd Maste fido_cbor_info_protocols_len(ci));
3140afa8e06SEd Maste
315*2ccfa855SEd Maste v = fido_cbor_info_new_pin_required(ci);
316*2ccfa855SEd Maste consume(&v, sizeof(v));
317*2ccfa855SEd Maste
3180afa8e06SEd Maste out:
3190afa8e06SEd Maste fido_dev_close(dev);
3200afa8e06SEd Maste fido_dev_free(&dev);
3210afa8e06SEd Maste
3220afa8e06SEd Maste fido_cbor_info_free(&ci);
3230afa8e06SEd Maste }
3240afa8e06SEd Maste
3250afa8e06SEd Maste static void
dev_set_pin(const struct param * p)3260afa8e06SEd Maste dev_set_pin(const struct param *p)
3270afa8e06SEd Maste {
3280afa8e06SEd Maste fido_dev_t *dev;
3290afa8e06SEd Maste
3300afa8e06SEd Maste set_wire_data(p->set_pin_wire_data.body, p->set_pin_wire_data.len);
3310afa8e06SEd Maste
3320afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
3330afa8e06SEd Maste return;
3340afa8e06SEd Maste
3350afa8e06SEd Maste fido_dev_set_pin(dev, p->pin1, NULL);
3360afa8e06SEd Maste fido_dev_close(dev);
3370afa8e06SEd Maste fido_dev_free(&dev);
3380afa8e06SEd Maste }
3390afa8e06SEd Maste
3400afa8e06SEd Maste static void
dev_change_pin(const struct param * p)3410afa8e06SEd Maste dev_change_pin(const struct param *p)
3420afa8e06SEd Maste {
3430afa8e06SEd Maste fido_dev_t *dev;
3440afa8e06SEd Maste
3450afa8e06SEd Maste set_wire_data(p->change_pin_wire_data.body, p->change_pin_wire_data.len);
3460afa8e06SEd Maste
3470afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
3480afa8e06SEd Maste return;
3490afa8e06SEd Maste
3500afa8e06SEd Maste fido_dev_set_pin(dev, p->pin2, p->pin1);
3510afa8e06SEd Maste fido_dev_close(dev);
3520afa8e06SEd Maste fido_dev_free(&dev);
3530afa8e06SEd Maste }
3540afa8e06SEd Maste
3550afa8e06SEd Maste static void
dev_get_retry_count(const struct param * p)3560afa8e06SEd Maste dev_get_retry_count(const struct param *p)
3570afa8e06SEd Maste {
3580afa8e06SEd Maste fido_dev_t *dev;
3590afa8e06SEd Maste int n = 0;
3600afa8e06SEd Maste
3610afa8e06SEd Maste set_wire_data(p->retry_wire_data.body, p->retry_wire_data.len);
3620afa8e06SEd Maste
3630afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
3640afa8e06SEd Maste return;
3650afa8e06SEd Maste
3660afa8e06SEd Maste fido_dev_get_retry_count(dev, &n);
3670afa8e06SEd Maste consume(&n, sizeof(n));
3680afa8e06SEd Maste fido_dev_close(dev);
3690afa8e06SEd Maste fido_dev_free(&dev);
3700afa8e06SEd Maste }
3710afa8e06SEd Maste
3720afa8e06SEd Maste static void
dev_get_uv_retry_count(const struct param * p)3730afa8e06SEd Maste dev_get_uv_retry_count(const struct param *p)
3740afa8e06SEd Maste {
3750afa8e06SEd Maste fido_dev_t *dev;
3760afa8e06SEd Maste int n = 0;
3770afa8e06SEd Maste
3780afa8e06SEd Maste set_wire_data(p->retry_wire_data.body, p->retry_wire_data.len);
3790afa8e06SEd Maste
3800afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
3810afa8e06SEd Maste return;
3820afa8e06SEd Maste
3830afa8e06SEd Maste fido_dev_get_uv_retry_count(dev, &n);
3840afa8e06SEd Maste consume(&n, sizeof(n));
3850afa8e06SEd Maste fido_dev_close(dev);
3860afa8e06SEd Maste fido_dev_free(&dev);
3870afa8e06SEd Maste }
3880afa8e06SEd Maste
3890afa8e06SEd Maste static void
dev_enable_entattest(const struct param * p)3900afa8e06SEd Maste dev_enable_entattest(const struct param *p)
3910afa8e06SEd Maste {
3920afa8e06SEd Maste fido_dev_t *dev;
3930afa8e06SEd Maste const char *pin;
3940afa8e06SEd Maste int r;
3950afa8e06SEd Maste
3960afa8e06SEd Maste set_wire_data(p->config_wire_data.body, p->config_wire_data.len);
3970afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
3980afa8e06SEd Maste return;
3990afa8e06SEd Maste pin = p->pin1;
4000afa8e06SEd Maste if (strlen(pin) == 0)
4010afa8e06SEd Maste pin = NULL;
4020afa8e06SEd Maste r = fido_dev_enable_entattest(dev, pin);
4030afa8e06SEd Maste consume_str(fido_strerr(r));
4040afa8e06SEd Maste fido_dev_close(dev);
4050afa8e06SEd Maste fido_dev_free(&dev);
4060afa8e06SEd Maste }
4070afa8e06SEd Maste
4080afa8e06SEd Maste static void
dev_toggle_always_uv(const struct param * p)4090afa8e06SEd Maste dev_toggle_always_uv(const struct param *p)
4100afa8e06SEd Maste {
4110afa8e06SEd Maste fido_dev_t *dev;
4120afa8e06SEd Maste const char *pin;
4130afa8e06SEd Maste int r;
4140afa8e06SEd Maste
4150afa8e06SEd Maste set_wire_data(p->config_wire_data.body, p->config_wire_data.len);
4160afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
4170afa8e06SEd Maste return;
4180afa8e06SEd Maste pin = p->pin1;
4190afa8e06SEd Maste if (strlen(pin) == 0)
4200afa8e06SEd Maste pin = NULL;
4210afa8e06SEd Maste r = fido_dev_toggle_always_uv(dev, pin);
4220afa8e06SEd Maste consume_str(fido_strerr(r));
4230afa8e06SEd Maste fido_dev_close(dev);
4240afa8e06SEd Maste fido_dev_free(&dev);
4250afa8e06SEd Maste }
4260afa8e06SEd Maste
4270afa8e06SEd Maste static void
dev_force_pin_change(const struct param * p)4280afa8e06SEd Maste dev_force_pin_change(const struct param *p)
4290afa8e06SEd Maste {
4300afa8e06SEd Maste fido_dev_t *dev;
4310afa8e06SEd Maste const char *pin;
4320afa8e06SEd Maste int r;
4330afa8e06SEd Maste
4340afa8e06SEd Maste set_wire_data(p->config_wire_data.body, p->config_wire_data.len);
4350afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
4360afa8e06SEd Maste return;
4370afa8e06SEd Maste pin = p->pin1;
4380afa8e06SEd Maste if (strlen(pin) == 0)
4390afa8e06SEd Maste pin = NULL;
4400afa8e06SEd Maste r = fido_dev_force_pin_change(dev, pin);
4410afa8e06SEd Maste consume_str(fido_strerr(r));
4420afa8e06SEd Maste fido_dev_close(dev);
4430afa8e06SEd Maste fido_dev_free(&dev);
4440afa8e06SEd Maste }
4450afa8e06SEd Maste
4460afa8e06SEd Maste static void
dev_set_pin_minlen(const struct param * p)4470afa8e06SEd Maste dev_set_pin_minlen(const struct param *p)
4480afa8e06SEd Maste {
4490afa8e06SEd Maste fido_dev_t *dev;
4500afa8e06SEd Maste const char *pin;
4510afa8e06SEd Maste int r;
4520afa8e06SEd Maste
4530afa8e06SEd Maste set_wire_data(p->config_wire_data.body, p->config_wire_data.len);
4540afa8e06SEd Maste if ((dev = open_dev(0)) == NULL)
4550afa8e06SEd Maste return;
4560afa8e06SEd Maste pin = p->pin1;
4570afa8e06SEd Maste if (strlen(pin) == 0)
4580afa8e06SEd Maste pin = NULL;
4590afa8e06SEd Maste r = fido_dev_set_pin_minlen(dev, strlen(p->pin2), pin);
4600afa8e06SEd Maste consume_str(fido_strerr(r));
4610afa8e06SEd Maste fido_dev_close(dev);
4620afa8e06SEd Maste fido_dev_free(&dev);
4630afa8e06SEd Maste }
4640afa8e06SEd Maste
465f540a430SEd Maste static void
dev_set_pin_minlen_rpid(const struct param * p)466f540a430SEd Maste dev_set_pin_minlen_rpid(const struct param *p)
467f540a430SEd Maste {
468f540a430SEd Maste fido_dev_t *dev;
469f540a430SEd Maste const char *rpid[MAXRPID];
470f540a430SEd Maste const char *pin;
471f540a430SEd Maste size_t n;
472f540a430SEd Maste int r;
473f540a430SEd Maste
474f540a430SEd Maste set_wire_data(p->config_wire_data.body, p->config_wire_data.len);
475f540a430SEd Maste if ((dev = open_dev(0)) == NULL)
476f540a430SEd Maste return;
477f540a430SEd Maste n = uniform_random(MAXRPID);
478f540a430SEd Maste for (size_t i = 0; i < n; i++)
479f540a430SEd Maste rpid[i] = dummy_rp_id;
480f540a430SEd Maste pin = p->pin1;
481f540a430SEd Maste if (strlen(pin) == 0)
482f540a430SEd Maste pin = NULL;
483f540a430SEd Maste r = fido_dev_set_pin_minlen_rpid(dev, rpid, n, pin);
484f540a430SEd Maste consume_str(fido_strerr(r));
485f540a430SEd Maste fido_dev_close(dev);
486f540a430SEd Maste fido_dev_free(&dev);
487f540a430SEd Maste }
488f540a430SEd Maste
4890afa8e06SEd Maste void
test(const struct param * p)4900afa8e06SEd Maste test(const struct param *p)
4910afa8e06SEd Maste {
4920afa8e06SEd Maste prng_init((unsigned int)p->seed);
493f540a430SEd Maste fuzz_clock_reset();
4940afa8e06SEd Maste fido_init(FIDO_DEBUG);
4950afa8e06SEd Maste fido_set_log_handler(consume_str);
4960afa8e06SEd Maste
4970afa8e06SEd Maste dev_reset(p);
4980afa8e06SEd Maste dev_get_cbor_info(p);
4990afa8e06SEd Maste dev_set_pin(p);
5000afa8e06SEd Maste dev_change_pin(p);
5010afa8e06SEd Maste dev_get_retry_count(p);
5020afa8e06SEd Maste dev_get_uv_retry_count(p);
5030afa8e06SEd Maste dev_enable_entattest(p);
5040afa8e06SEd Maste dev_toggle_always_uv(p);
5050afa8e06SEd Maste dev_force_pin_change(p);
5060afa8e06SEd Maste dev_set_pin_minlen(p);
507f540a430SEd Maste dev_set_pin_minlen_rpid(p);
5080afa8e06SEd Maste }
5090afa8e06SEd Maste
5100afa8e06SEd Maste void
mutate(struct param * p,unsigned int seed,unsigned int flags)5110afa8e06SEd Maste mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
5120afa8e06SEd Maste {
5130afa8e06SEd Maste if (flags & MUTATE_SEED)
5140afa8e06SEd Maste p->seed = (int)seed;
5150afa8e06SEd Maste
5160afa8e06SEd Maste if (flags & MUTATE_PARAM) {
5170afa8e06SEd Maste mutate_string(p->pin1);
5180afa8e06SEd Maste mutate_string(p->pin2);
5190afa8e06SEd Maste }
5200afa8e06SEd Maste
5210afa8e06SEd Maste if (flags & MUTATE_WIREDATA) {
5220afa8e06SEd Maste mutate_blob(&p->reset_wire_data);
5230afa8e06SEd Maste mutate_blob(&p->info_wire_data);
5240afa8e06SEd Maste mutate_blob(&p->set_pin_wire_data);
5250afa8e06SEd Maste mutate_blob(&p->change_pin_wire_data);
5260afa8e06SEd Maste mutate_blob(&p->retry_wire_data);
5270afa8e06SEd Maste }
5280afa8e06SEd Maste }
529