xref: /freebsd/contrib/libfido2/fuzz/fuzz_credman.c (revision 2ccfa855b2fc331819953e3de1b1c15ce5b95a7e)
10afa8e06SEd Maste /*
20afa8e06SEd Maste  * Copyright (c) 2019-2021 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 
200afa8e06SEd Maste /* Parameter set defining a FIDO2 credential management operation. */
210afa8e06SEd Maste struct param {
220afa8e06SEd Maste 	char pin[MAXSTR];
230afa8e06SEd Maste 	char rp_id[MAXSTR];
240afa8e06SEd Maste 	int seed;
250afa8e06SEd Maste 	struct blob cred_id;
260afa8e06SEd Maste 	struct blob del_wire_data;
270afa8e06SEd Maste 	struct blob meta_wire_data;
280afa8e06SEd Maste 	struct blob rk_wire_data;
290afa8e06SEd Maste 	struct blob rp_wire_data;
300afa8e06SEd Maste };
310afa8e06SEd Maste 
320afa8e06SEd Maste /*
330afa8e06SEd Maste  * Collection of HID reports from an authenticator issued with a FIDO2
340afa8e06SEd Maste  * 'getCredsMetadata' credential management command.
350afa8e06SEd Maste  */
360afa8e06SEd Maste static const uint8_t dummy_meta_wire_data[] = {
370afa8e06SEd Maste 	WIREDATA_CTAP_INIT,
380afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_INFO,
390afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_AUTHKEY,
400afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_PINTOKEN,
410afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_CREDMAN_META,
420afa8e06SEd Maste };
430afa8e06SEd Maste 
440afa8e06SEd Maste /*
450afa8e06SEd Maste  * Collection of HID reports from an authenticator issued with a FIDO2
460afa8e06SEd Maste  * 'enumerateRPsBegin' credential management command.
470afa8e06SEd Maste  */
480afa8e06SEd Maste static const uint8_t dummy_rp_wire_data[] = {
490afa8e06SEd Maste 	WIREDATA_CTAP_INIT,
500afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_INFO,
510afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_AUTHKEY,
520afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_PINTOKEN,
530afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_CREDMAN_RPLIST,
540afa8e06SEd Maste };
550afa8e06SEd Maste 
560afa8e06SEd Maste /*
570afa8e06SEd Maste  * Collection of HID reports from an authenticator issued with a FIDO2
580afa8e06SEd Maste  * 'enumerateCredentialsBegin' credential management command.
590afa8e06SEd Maste  */
600afa8e06SEd Maste static const uint8_t dummy_rk_wire_data[] = {
610afa8e06SEd Maste 	WIREDATA_CTAP_INIT,
620afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_INFO,
630afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_AUTHKEY,
640afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_PINTOKEN,
650afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_CREDMAN_RKLIST,
660afa8e06SEd Maste };
670afa8e06SEd Maste 
680afa8e06SEd Maste /*
690afa8e06SEd Maste  * Collection of HID reports from an authenticator issued with a FIDO2
700afa8e06SEd Maste  * 'deleteCredential' credential management command.
710afa8e06SEd Maste  */
720afa8e06SEd Maste static const uint8_t dummy_del_wire_data[] = {
730afa8e06SEd Maste 	WIREDATA_CTAP_INIT,
740afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_INFO,
750afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_AUTHKEY,
760afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_PINTOKEN,
770afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_STATUS,
780afa8e06SEd Maste };
790afa8e06SEd Maste 
800afa8e06SEd Maste struct param *
unpack(const uint8_t * ptr,size_t len)810afa8e06SEd Maste unpack(const uint8_t *ptr, size_t len)
820afa8e06SEd Maste {
830afa8e06SEd Maste 	cbor_item_t *item = NULL, **v;
840afa8e06SEd Maste 	struct cbor_load_result cbor;
850afa8e06SEd Maste 	struct param *p;
860afa8e06SEd Maste 	int ok = -1;
870afa8e06SEd Maste 
880afa8e06SEd Maste 	if ((p = calloc(1, sizeof(*p))) == NULL ||
890afa8e06SEd Maste 	    (item = cbor_load(ptr, len, &cbor)) == NULL ||
900afa8e06SEd Maste 	    cbor.read != len ||
910afa8e06SEd Maste 	    cbor_isa_array(item) == false ||
920afa8e06SEd Maste 	    cbor_array_is_definite(item) == false ||
930afa8e06SEd Maste 	    cbor_array_size(item) != 8 ||
940afa8e06SEd Maste 	    (v = cbor_array_handle(item)) == NULL)
950afa8e06SEd Maste 		goto fail;
960afa8e06SEd Maste 
970afa8e06SEd Maste 	if (unpack_int(v[0], &p->seed) < 0 ||
980afa8e06SEd Maste 	    unpack_string(v[1], p->pin) < 0 ||
990afa8e06SEd Maste 	    unpack_string(v[2], p->rp_id) < 0 ||
1000afa8e06SEd Maste 	    unpack_blob(v[3], &p->cred_id) < 0 ||
1010afa8e06SEd Maste 	    unpack_blob(v[4], &p->meta_wire_data) < 0 ||
1020afa8e06SEd Maste 	    unpack_blob(v[5], &p->rp_wire_data) < 0 ||
1030afa8e06SEd Maste 	    unpack_blob(v[6], &p->rk_wire_data) < 0 ||
1040afa8e06SEd Maste 	    unpack_blob(v[7], &p->del_wire_data) < 0)
1050afa8e06SEd Maste 		goto fail;
1060afa8e06SEd Maste 
1070afa8e06SEd Maste 	ok = 0;
1080afa8e06SEd Maste fail:
1090afa8e06SEd Maste 	if (ok < 0) {
1100afa8e06SEd Maste 		free(p);
1110afa8e06SEd Maste 		p = NULL;
1120afa8e06SEd Maste 	}
1130afa8e06SEd Maste 
1140afa8e06SEd Maste 	if (item)
1150afa8e06SEd Maste 		cbor_decref(&item);
1160afa8e06SEd Maste 
1170afa8e06SEd Maste 	return p;
1180afa8e06SEd Maste }
1190afa8e06SEd Maste 
1200afa8e06SEd Maste size_t
pack(uint8_t * ptr,size_t len,const struct param * p)1210afa8e06SEd Maste pack(uint8_t *ptr, size_t len, const struct param *p)
1220afa8e06SEd Maste {
1230afa8e06SEd Maste 	cbor_item_t *argv[8], *array = NULL;
1240afa8e06SEd Maste 	size_t cbor_alloc_len, cbor_len = 0;
1250afa8e06SEd Maste 	unsigned char *cbor = NULL;
1260afa8e06SEd Maste 
1270afa8e06SEd Maste 	memset(argv, 0, sizeof(argv));
1280afa8e06SEd Maste 
1290afa8e06SEd Maste 	if ((array = cbor_new_definite_array(8)) == NULL ||
1300afa8e06SEd Maste 	    (argv[0] = pack_int(p->seed)) == NULL ||
1310afa8e06SEd Maste 	    (argv[1] = pack_string(p->pin)) == NULL ||
1320afa8e06SEd Maste 	    (argv[2] = pack_string(p->rp_id)) == NULL ||
1330afa8e06SEd Maste 	    (argv[3] = pack_blob(&p->cred_id)) == NULL ||
1340afa8e06SEd Maste 	    (argv[4] = pack_blob(&p->meta_wire_data)) == NULL ||
1350afa8e06SEd Maste 	    (argv[5] = pack_blob(&p->rp_wire_data)) == NULL ||
1360afa8e06SEd Maste 	    (argv[6] = pack_blob(&p->rk_wire_data)) == NULL ||
1370afa8e06SEd Maste 	    (argv[7] = pack_blob(&p->del_wire_data)) == NULL)
1380afa8e06SEd Maste 		goto fail;
1390afa8e06SEd Maste 
1400afa8e06SEd Maste 	for (size_t i = 0; i < 8; i++)
1410afa8e06SEd Maste 		if (cbor_array_push(array, argv[i]) == false)
1420afa8e06SEd Maste 			goto fail;
1430afa8e06SEd Maste 
1440afa8e06SEd Maste 	if ((cbor_len = cbor_serialize_alloc(array, &cbor,
145*2ccfa855SEd Maste 	    &cbor_alloc_len)) == 0 || cbor_len > len) {
1460afa8e06SEd Maste 		cbor_len = 0;
1470afa8e06SEd Maste 		goto fail;
1480afa8e06SEd Maste 	}
1490afa8e06SEd Maste 
1500afa8e06SEd Maste 	memcpy(ptr, cbor, cbor_len);
1510afa8e06SEd Maste fail:
1520afa8e06SEd Maste 	for (size_t i = 0; i < 8; i++)
1530afa8e06SEd Maste 		if (argv[i])
1540afa8e06SEd Maste 			cbor_decref(&argv[i]);
1550afa8e06SEd Maste 
1560afa8e06SEd Maste 	if (array)
1570afa8e06SEd Maste 		cbor_decref(&array);
1580afa8e06SEd Maste 
1590afa8e06SEd Maste 	free(cbor);
1600afa8e06SEd Maste 
1610afa8e06SEd Maste 	return cbor_len;
1620afa8e06SEd Maste }
1630afa8e06SEd Maste 
1640afa8e06SEd Maste size_t
pack_dummy(uint8_t * ptr,size_t len)1650afa8e06SEd Maste pack_dummy(uint8_t *ptr, size_t len)
1660afa8e06SEd Maste {
1670afa8e06SEd Maste 	struct param dummy;
168*2ccfa855SEd Maste 	uint8_t blob[MAXCORPUS];
1690afa8e06SEd Maste 	size_t blob_len;
1700afa8e06SEd Maste 
1710afa8e06SEd Maste 	memset(&dummy, 0, sizeof(dummy));
1720afa8e06SEd Maste 
1730afa8e06SEd Maste 	strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin));
1740afa8e06SEd Maste 	strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id));
1750afa8e06SEd Maste 
1760afa8e06SEd Maste 	dummy.meta_wire_data.len = sizeof(dummy_meta_wire_data);
1770afa8e06SEd Maste 	dummy.rp_wire_data.len = sizeof(dummy_rp_wire_data);
1780afa8e06SEd Maste 	dummy.rk_wire_data.len = sizeof(dummy_rk_wire_data);
1790afa8e06SEd Maste 	dummy.del_wire_data.len = sizeof(dummy_del_wire_data);
1800afa8e06SEd Maste 	dummy.cred_id.len = sizeof(dummy_cred_id);
1810afa8e06SEd Maste 
1820afa8e06SEd Maste 	memcpy(&dummy.meta_wire_data.body, &dummy_meta_wire_data,
1830afa8e06SEd Maste 	    dummy.meta_wire_data.len);
1840afa8e06SEd Maste 	memcpy(&dummy.rp_wire_data.body, &dummy_rp_wire_data,
1850afa8e06SEd Maste 	    dummy.rp_wire_data.len);
1860afa8e06SEd Maste 	memcpy(&dummy.rk_wire_data.body, &dummy_rk_wire_data,
1870afa8e06SEd Maste 	    dummy.rk_wire_data.len);
1880afa8e06SEd Maste 	memcpy(&dummy.del_wire_data.body, &dummy_del_wire_data,
1890afa8e06SEd Maste 	    dummy.del_wire_data.len);
1900afa8e06SEd Maste 	memcpy(&dummy.cred_id.body, &dummy_cred_id, dummy.cred_id.len);
1910afa8e06SEd Maste 
1920afa8e06SEd Maste 	assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
1930afa8e06SEd Maste 
1940afa8e06SEd Maste 	if (blob_len > len) {
1950afa8e06SEd Maste 		memcpy(ptr, blob, len);
1960afa8e06SEd Maste 		return len;
1970afa8e06SEd Maste 	}
1980afa8e06SEd Maste 
1990afa8e06SEd Maste 	memcpy(ptr, blob, blob_len);
2000afa8e06SEd Maste 
2010afa8e06SEd Maste 	return blob_len;
2020afa8e06SEd Maste }
2030afa8e06SEd Maste 
2040afa8e06SEd Maste static fido_dev_t *
prepare_dev(void)2050afa8e06SEd Maste prepare_dev(void)
2060afa8e06SEd Maste {
2070afa8e06SEd Maste 	fido_dev_t *dev;
2080afa8e06SEd Maste 	bool x;
2090afa8e06SEd Maste 
2100afa8e06SEd Maste 	if ((dev = open_dev(0)) == NULL)
2110afa8e06SEd Maste 		return NULL;
2120afa8e06SEd Maste 
2130afa8e06SEd Maste 	x = fido_dev_is_fido2(dev);
2140afa8e06SEd Maste 	consume(&x, sizeof(x));
2150afa8e06SEd Maste 	x = fido_dev_supports_cred_prot(dev);
2160afa8e06SEd Maste 	consume(&x, sizeof(x));
2170afa8e06SEd Maste 	x = fido_dev_supports_credman(dev);
2180afa8e06SEd Maste 	consume(&x, sizeof(x));
2190afa8e06SEd Maste 
2200afa8e06SEd Maste 	return dev;
2210afa8e06SEd Maste }
2220afa8e06SEd Maste 
2230afa8e06SEd Maste static void
get_metadata(const struct param * p)2240afa8e06SEd Maste get_metadata(const struct param *p)
2250afa8e06SEd Maste {
2260afa8e06SEd Maste 	fido_dev_t *dev;
2270afa8e06SEd Maste 	fido_credman_metadata_t *metadata;
2280afa8e06SEd Maste 	uint64_t existing;
2290afa8e06SEd Maste 	uint64_t remaining;
2300afa8e06SEd Maste 
2310afa8e06SEd Maste 	set_wire_data(p->meta_wire_data.body, p->meta_wire_data.len);
2320afa8e06SEd Maste 
2330afa8e06SEd Maste 	if ((dev = prepare_dev()) == NULL)
2340afa8e06SEd Maste 		return;
2350afa8e06SEd Maste 
2360afa8e06SEd Maste 	if ((metadata = fido_credman_metadata_new()) == NULL) {
2370afa8e06SEd Maste 		fido_dev_close(dev);
2380afa8e06SEd Maste 		fido_dev_free(&dev);
2390afa8e06SEd Maste 		return;
2400afa8e06SEd Maste 	}
2410afa8e06SEd Maste 
2420afa8e06SEd Maste 	fido_credman_get_dev_metadata(dev, metadata, p->pin);
2430afa8e06SEd Maste 
2440afa8e06SEd Maste 	existing = fido_credman_rk_existing(metadata);
2450afa8e06SEd Maste 	remaining = fido_credman_rk_remaining(metadata);
2460afa8e06SEd Maste 	consume(&existing, sizeof(existing));
2470afa8e06SEd Maste 	consume(&remaining, sizeof(remaining));
2480afa8e06SEd Maste 
2490afa8e06SEd Maste 	fido_credman_metadata_free(&metadata);
2500afa8e06SEd Maste 	fido_dev_close(dev);
2510afa8e06SEd Maste 	fido_dev_free(&dev);
2520afa8e06SEd Maste }
2530afa8e06SEd Maste 
2540afa8e06SEd Maste static void
get_rp_list(const struct param * p)2550afa8e06SEd Maste get_rp_list(const struct param *p)
2560afa8e06SEd Maste {
2570afa8e06SEd Maste 	fido_dev_t *dev;
2580afa8e06SEd Maste 	fido_credman_rp_t *rp;
2590afa8e06SEd Maste 
2600afa8e06SEd Maste 	set_wire_data(p->rp_wire_data.body, p->rp_wire_data.len);
2610afa8e06SEd Maste 
2620afa8e06SEd Maste 	if ((dev = prepare_dev()) == NULL)
2630afa8e06SEd Maste 		return;
2640afa8e06SEd Maste 
2650afa8e06SEd Maste 	if ((rp = fido_credman_rp_new()) == NULL) {
2660afa8e06SEd Maste 		fido_dev_close(dev);
2670afa8e06SEd Maste 		fido_dev_free(&dev);
2680afa8e06SEd Maste 		return;
2690afa8e06SEd Maste 	}
2700afa8e06SEd Maste 
2710afa8e06SEd Maste 	fido_credman_get_dev_rp(dev, rp, p->pin);
2720afa8e06SEd Maste 
2730afa8e06SEd Maste 	/* +1 on purpose */
2740afa8e06SEd Maste 	for (size_t i = 0; i < fido_credman_rp_count(rp) + 1; i++) {
2750afa8e06SEd Maste 		consume(fido_credman_rp_id_hash_ptr(rp, i),
2760afa8e06SEd Maste 		    fido_credman_rp_id_hash_len(rp, i));
2770afa8e06SEd Maste 		consume_str(fido_credman_rp_id(rp, i));
2780afa8e06SEd Maste 		consume_str(fido_credman_rp_name(rp, i));
2790afa8e06SEd Maste 	}
2800afa8e06SEd Maste 
2810afa8e06SEd Maste 	fido_credman_rp_free(&rp);
2820afa8e06SEd Maste 	fido_dev_close(dev);
2830afa8e06SEd Maste 	fido_dev_free(&dev);
2840afa8e06SEd Maste }
2850afa8e06SEd Maste 
2860afa8e06SEd Maste static void
get_rk_list(const struct param * p)2870afa8e06SEd Maste get_rk_list(const struct param *p)
2880afa8e06SEd Maste {
2890afa8e06SEd Maste 	fido_dev_t *dev;
2900afa8e06SEd Maste 	fido_credman_rk_t *rk;
2910afa8e06SEd Maste 	const fido_cred_t *cred;
2920afa8e06SEd Maste 	int val;
2930afa8e06SEd Maste 
2940afa8e06SEd Maste 	set_wire_data(p->rk_wire_data.body, p->rk_wire_data.len);
2950afa8e06SEd Maste 
2960afa8e06SEd Maste 	if ((dev = prepare_dev()) == NULL)
2970afa8e06SEd Maste 		return;
2980afa8e06SEd Maste 
2990afa8e06SEd Maste 	if ((rk = fido_credman_rk_new()) == NULL) {
3000afa8e06SEd Maste 		fido_dev_close(dev);
3010afa8e06SEd Maste 		fido_dev_free(&dev);
3020afa8e06SEd Maste 		return;
3030afa8e06SEd Maste 	}
3040afa8e06SEd Maste 
3050afa8e06SEd Maste 	fido_credman_get_dev_rk(dev, p->rp_id, rk, p->pin);
3060afa8e06SEd Maste 
3070afa8e06SEd Maste 	/* +1 on purpose */
3080afa8e06SEd Maste 	for (size_t i = 0; i < fido_credman_rk_count(rk) + 1; i++) {
3090afa8e06SEd Maste 		if ((cred = fido_credman_rk(rk, i)) == NULL) {
3100afa8e06SEd Maste 			assert(i >= fido_credman_rk_count(rk));
3110afa8e06SEd Maste 			continue;
3120afa8e06SEd Maste 		}
3130afa8e06SEd Maste 		val = fido_cred_type(cred);
3140afa8e06SEd Maste 		consume(&val, sizeof(val));
3150afa8e06SEd Maste 		consume(fido_cred_id_ptr(cred), fido_cred_id_len(cred));
3160afa8e06SEd Maste 		consume(fido_cred_pubkey_ptr(cred), fido_cred_pubkey_len(cred));
3170afa8e06SEd Maste 		consume(fido_cred_user_id_ptr(cred),
3180afa8e06SEd Maste 		    fido_cred_user_id_len(cred));
3190afa8e06SEd Maste 		consume_str(fido_cred_user_name(cred));
3200afa8e06SEd Maste 		consume_str(fido_cred_display_name(cred));
3210afa8e06SEd Maste 		val = fido_cred_prot(cred);
3220afa8e06SEd Maste 		consume(&val, sizeof(val));
3230afa8e06SEd Maste 	}
3240afa8e06SEd Maste 
3250afa8e06SEd Maste 	fido_credman_rk_free(&rk);
3260afa8e06SEd Maste 	fido_dev_close(dev);
3270afa8e06SEd Maste 	fido_dev_free(&dev);
3280afa8e06SEd Maste }
3290afa8e06SEd Maste 
3300afa8e06SEd Maste static void
del_rk(const struct param * p)3310afa8e06SEd Maste del_rk(const struct param *p)
3320afa8e06SEd Maste {
3330afa8e06SEd Maste 	fido_dev_t *dev;
3340afa8e06SEd Maste 
3350afa8e06SEd Maste 	set_wire_data(p->del_wire_data.body, p->del_wire_data.len);
3360afa8e06SEd Maste 
3370afa8e06SEd Maste 	if ((dev = prepare_dev()) == NULL)
3380afa8e06SEd Maste 		return;
3390afa8e06SEd Maste 
3400afa8e06SEd Maste 	fido_credman_del_dev_rk(dev, p->cred_id.body, p->cred_id.len, p->pin);
3410afa8e06SEd Maste 	fido_dev_close(dev);
3420afa8e06SEd Maste 	fido_dev_free(&dev);
3430afa8e06SEd Maste }
3440afa8e06SEd Maste 
3450afa8e06SEd Maste static void
set_rk(const struct param * p)3460afa8e06SEd Maste set_rk(const struct param *p)
3470afa8e06SEd Maste {
3480afa8e06SEd Maste 	fido_dev_t *dev = NULL;
3490afa8e06SEd Maste 	fido_cred_t *cred = NULL;
3500afa8e06SEd Maste 	const char *pin = p->pin;
3510afa8e06SEd Maste 	int r0, r1, r2;
3520afa8e06SEd Maste 
3530afa8e06SEd Maste 	set_wire_data(p->del_wire_data.body, p->del_wire_data.len);
3540afa8e06SEd Maste 
3550afa8e06SEd Maste 	if ((dev = prepare_dev()) == NULL)
3560afa8e06SEd Maste 		return;
3570afa8e06SEd Maste 	if ((cred = fido_cred_new()) == NULL)
3580afa8e06SEd Maste 		goto out;
3590afa8e06SEd Maste 	r0 = fido_cred_set_id(cred, p->cred_id.body, p->cred_id.len);
3600afa8e06SEd Maste 	r1 = fido_cred_set_user(cred, p->cred_id.body, p->cred_id.len, p->rp_id,
3610afa8e06SEd Maste 	    NULL, NULL);
3620afa8e06SEd Maste 	if (strlen(pin) == 0)
3630afa8e06SEd Maste 		pin = NULL;
3640afa8e06SEd Maste 	r2 = fido_credman_set_dev_rk(dev, cred, pin);
3650afa8e06SEd Maste 	consume(&r0, sizeof(r0));
3660afa8e06SEd Maste 	consume(&r1, sizeof(r1));
3670afa8e06SEd Maste 	consume(&r2, sizeof(r2));
3680afa8e06SEd Maste out:
3690afa8e06SEd Maste 	fido_dev_close(dev);
3700afa8e06SEd Maste 	fido_dev_free(&dev);
3710afa8e06SEd Maste 	fido_cred_free(&cred);
3720afa8e06SEd Maste }
3730afa8e06SEd Maste 
3740afa8e06SEd Maste void
test(const struct param * p)3750afa8e06SEd Maste test(const struct param *p)
3760afa8e06SEd Maste {
3770afa8e06SEd Maste 	prng_init((unsigned int)p->seed);
378f540a430SEd Maste 	fuzz_clock_reset();
3790afa8e06SEd Maste 	fido_init(FIDO_DEBUG);
3800afa8e06SEd Maste 	fido_set_log_handler(consume_str);
3810afa8e06SEd Maste 
3820afa8e06SEd Maste 	get_metadata(p);
3830afa8e06SEd Maste 	get_rp_list(p);
3840afa8e06SEd Maste 	get_rk_list(p);
3850afa8e06SEd Maste 	del_rk(p);
3860afa8e06SEd Maste 	set_rk(p);
3870afa8e06SEd Maste }
3880afa8e06SEd Maste 
3890afa8e06SEd Maste void
mutate(struct param * p,unsigned int seed,unsigned int flags)3900afa8e06SEd Maste mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
3910afa8e06SEd Maste {
3920afa8e06SEd Maste 	if (flags & MUTATE_SEED)
3930afa8e06SEd Maste 		p->seed = (int)seed;
3940afa8e06SEd Maste 
3950afa8e06SEd Maste 	if (flags & MUTATE_PARAM) {
3960afa8e06SEd Maste 		mutate_blob(&p->cred_id);
3970afa8e06SEd Maste 		mutate_string(p->pin);
3980afa8e06SEd Maste 		mutate_string(p->rp_id);
3990afa8e06SEd Maste 	}
4000afa8e06SEd Maste 
4010afa8e06SEd Maste 	if (flags & MUTATE_WIREDATA) {
4020afa8e06SEd Maste 		mutate_blob(&p->meta_wire_data);
4030afa8e06SEd Maste 		mutate_blob(&p->rp_wire_data);
4040afa8e06SEd Maste 		mutate_blob(&p->rk_wire_data);
4050afa8e06SEd Maste 		mutate_blob(&p->del_wire_data);
4060afa8e06SEd Maste 	}
4070afa8e06SEd Maste }
408