1ca37791eSchristos /*
2ca37791eSchristos  * Copyright (c) 2019 Yubico AB. All rights reserved.
3ca37791eSchristos  * Use of this source code is governed by a BSD-style
4ca37791eSchristos  * license that can be found in the LICENSE file.
5ca37791eSchristos  */
6ca37791eSchristos 
7ca37791eSchristos #include <assert.h>
8ca37791eSchristos #include <stdint.h>
998a5e356Schristos #include <stdio.h>
10ca37791eSchristos #include <stdlib.h>
11ca37791eSchristos #include <string.h>
12ca37791eSchristos 
13ca37791eSchristos #include "mutator_aux.h"
14ca37791eSchristos #include "wiredata_fido2.h"
15ca37791eSchristos #include "dummy.h"
16ca37791eSchristos 
17ca37791eSchristos #include "../openbsd-compat/openbsd-compat.h"
18ca37791eSchristos 
19ca37791eSchristos /* Parameter set defining a FIDO2 credential management operation. */
20ca37791eSchristos struct param {
21ca37791eSchristos 	char pin[MAXSTR];
22ca37791eSchristos 	char name[MAXSTR];
23ca37791eSchristos 	int seed;
24ca37791eSchristos 	struct blob id;
25ca37791eSchristos 	struct blob info_wire_data;
26ca37791eSchristos 	struct blob enroll_wire_data;
27ca37791eSchristos 	struct blob list_wire_data;
28ca37791eSchristos 	struct blob set_name_wire_data;
29ca37791eSchristos 	struct blob remove_wire_data;
30ca37791eSchristos };
31ca37791eSchristos 
32ca37791eSchristos /*
33ca37791eSchristos  * Collection of HID reports from an authenticator issued with a FIDO2
34ca37791eSchristos  * 'getFingerprintSensorInfo' bio enrollment command.
35ca37791eSchristos  */
36ca37791eSchristos static const uint8_t dummy_info_wire_data[] = {
37ca37791eSchristos 	WIREDATA_CTAP_INIT,
38ca37791eSchristos 	WIREDATA_CTAP_CBOR_INFO,
39ca37791eSchristos 	WIREDATA_CTAP_CBOR_BIO_INFO,
40ca37791eSchristos };
41ca37791eSchristos 
42ca37791eSchristos /*
43ca37791eSchristos  * Collection of HID reports from an authenticator issued with FIDO2
44ca37791eSchristos  * 'enrollBegin' + 'enrollCaptureNextSample' bio enrollment commands.
45ca37791eSchristos  */
46ca37791eSchristos static const uint8_t dummy_enroll_wire_data[] = {
47ca37791eSchristos 	WIREDATA_CTAP_INIT,
48ca37791eSchristos 	WIREDATA_CTAP_CBOR_INFO,
49ca37791eSchristos 	WIREDATA_CTAP_CBOR_AUTHKEY,
50ca37791eSchristos 	WIREDATA_CTAP_CBOR_PINTOKEN,
51ca37791eSchristos 	WIREDATA_CTAP_CBOR_BIO_ENROLL,
52ca37791eSchristos };
53ca37791eSchristos 
54ca37791eSchristos /*
55ca37791eSchristos  * Collection of HID reports from an authenticator issued with a FIDO2
56ca37791eSchristos  * 'enumerateEnrollments' bio enrollment command.
57ca37791eSchristos  */
58ca37791eSchristos static const uint8_t dummy_list_wire_data[] = {
59ca37791eSchristos 	WIREDATA_CTAP_INIT,
60ca37791eSchristos 	WIREDATA_CTAP_CBOR_INFO,
61ca37791eSchristos 	WIREDATA_CTAP_CBOR_AUTHKEY,
62ca37791eSchristos 	WIREDATA_CTAP_CBOR_PINTOKEN,
63ca37791eSchristos 	WIREDATA_CTAP_CBOR_BIO_ENUM,
64ca37791eSchristos };
65ca37791eSchristos 
66ca37791eSchristos /*
67ca37791eSchristos  * Collection of HID reports from an authenticator issued with a FIDO2
68ca37791eSchristos  * 'setFriendlyName' bio enrollment command.
69ca37791eSchristos  */
70ca37791eSchristos static const uint8_t dummy_set_name_wire_data[] = {
71ca37791eSchristos 	WIREDATA_CTAP_INIT,
72ca37791eSchristos 	WIREDATA_CTAP_CBOR_INFO,
73ca37791eSchristos 	WIREDATA_CTAP_CBOR_AUTHKEY,
74ca37791eSchristos 	WIREDATA_CTAP_CBOR_PINTOKEN,
75ca37791eSchristos 	WIREDATA_CTAP_CBOR_STATUS,
76ca37791eSchristos };
77ca37791eSchristos 
78ca37791eSchristos /*
79ca37791eSchristos  * Collection of HID reports from an authenticator issued with a FIDO2
80ca37791eSchristos  * 'removeEnrollment' bio enrollment command.
81ca37791eSchristos  */
82ca37791eSchristos static const uint8_t dummy_remove_wire_data[] = {
83ca37791eSchristos 	WIREDATA_CTAP_INIT,
84ca37791eSchristos 	WIREDATA_CTAP_CBOR_INFO,
85ca37791eSchristos 	WIREDATA_CTAP_CBOR_AUTHKEY,
86ca37791eSchristos 	WIREDATA_CTAP_CBOR_PINTOKEN,
87ca37791eSchristos 	WIREDATA_CTAP_CBOR_STATUS,
88ca37791eSchristos };
89ca37791eSchristos 
905d97138dSchristos struct param *
unpack(const uint8_t * ptr,size_t len)915d97138dSchristos unpack(const uint8_t *ptr, size_t len)
92ca37791eSchristos {
935d97138dSchristos 	cbor_item_t *item = NULL, **v;
945d97138dSchristos 	struct cbor_load_result cbor;
955d97138dSchristos 	struct param *p;
965d97138dSchristos 	int ok = -1;
97ca37791eSchristos 
985d97138dSchristos 	if ((p = calloc(1, sizeof(*p))) == NULL ||
995d97138dSchristos 	    (item = cbor_load(ptr, len, &cbor)) == NULL ||
1005d97138dSchristos 	    cbor.read != len ||
1015d97138dSchristos 	    cbor_isa_array(item) == false ||
1025d97138dSchristos 	    cbor_array_is_definite(item) == false ||
1035d97138dSchristos 	    cbor_array_size(item) != 9 ||
1045d97138dSchristos 	    (v = cbor_array_handle(item)) == NULL)
1055d97138dSchristos 		goto fail;
106ca37791eSchristos 
1075d97138dSchristos 	if (unpack_int(v[0], &p->seed) < 0 ||
1085d97138dSchristos 	    unpack_string(v[1], p->pin) < 0 ||
1095d97138dSchristos 	    unpack_string(v[2], p->name) < 0 ||
1105d97138dSchristos 	    unpack_blob(v[3], &p->id) < 0 ||
1115d97138dSchristos 	    unpack_blob(v[4], &p->info_wire_data) < 0 ||
1125d97138dSchristos 	    unpack_blob(v[5], &p->enroll_wire_data) < 0 ||
1135d97138dSchristos 	    unpack_blob(v[6], &p->list_wire_data) < 0 ||
1145d97138dSchristos 	    unpack_blob(v[7], &p->set_name_wire_data) < 0 ||
1155d97138dSchristos 	    unpack_blob(v[8], &p->remove_wire_data) < 0)
1165d97138dSchristos 		goto fail;
1175d97138dSchristos 
1185d97138dSchristos 	ok = 0;
1195d97138dSchristos fail:
1205d97138dSchristos 	if (ok < 0) {
1215d97138dSchristos 		free(p);
1225d97138dSchristos 		p = NULL;
123ca37791eSchristos 	}
124ca37791eSchristos 
1255d97138dSchristos 	if (item)
1265d97138dSchristos 		cbor_decref(&item);
1275d97138dSchristos 
1285d97138dSchristos 	return p;
1295d97138dSchristos }
1305d97138dSchristos 
1315d97138dSchristos size_t
pack(uint8_t * ptr,size_t len,const struct param * p)132ca37791eSchristos pack(uint8_t *ptr, size_t len, const struct param *p)
133ca37791eSchristos {
1345d97138dSchristos 	cbor_item_t *argv[9], *array = NULL;
1355d97138dSchristos 	size_t cbor_alloc_len, cbor_len = 0;
1365d97138dSchristos 	unsigned char *cbor = NULL;
137ca37791eSchristos 
1385d97138dSchristos 	memset(argv, 0, sizeof(argv));
139ca37791eSchristos 
1405d97138dSchristos 	if ((array = cbor_new_definite_array(9)) == NULL ||
1415d97138dSchristos 	    (argv[0] = pack_int(p->seed)) == NULL ||
1425d97138dSchristos 	    (argv[1] = pack_string(p->pin)) == NULL ||
1435d97138dSchristos 	    (argv[2] = pack_string(p->name)) == NULL ||
1445d97138dSchristos 	    (argv[3] = pack_blob(&p->id)) == NULL ||
1455d97138dSchristos 	    (argv[4] = pack_blob(&p->info_wire_data)) == NULL ||
1465d97138dSchristos 	    (argv[5] = pack_blob(&p->enroll_wire_data)) == NULL ||
1475d97138dSchristos 	    (argv[6] = pack_blob(&p->list_wire_data)) == NULL ||
1485d97138dSchristos 	    (argv[7] = pack_blob(&p->set_name_wire_data)) == NULL ||
1495d97138dSchristos 	    (argv[8] = pack_blob(&p->remove_wire_data)) == NULL)
1505d97138dSchristos 		goto fail;
1515d97138dSchristos 
1525d97138dSchristos 	for (size_t i = 0; i < 9; i++)
1535d97138dSchristos 		if (cbor_array_push(array, argv[i]) == false)
1545d97138dSchristos 			goto fail;
1555d97138dSchristos 
1565d97138dSchristos 	if ((cbor_len = cbor_serialize_alloc(array, &cbor,
1575d97138dSchristos 	    &cbor_alloc_len)) > len) {
1585d97138dSchristos 		cbor_len = 0;
1595d97138dSchristos 		goto fail;
160ca37791eSchristos 	}
161ca37791eSchristos 
1625d97138dSchristos 	memcpy(ptr, cbor, cbor_len);
1635d97138dSchristos fail:
1645d97138dSchristos 	for (size_t i = 0; i < 9; i++)
1655d97138dSchristos 		if (argv[i])
1665d97138dSchristos 			cbor_decref(&argv[i]);
1675d97138dSchristos 
1685d97138dSchristos 	if (array)
1695d97138dSchristos 		cbor_decref(&array);
1705d97138dSchristos 
1715d97138dSchristos 	free(cbor);
1725d97138dSchristos 
1735d97138dSchristos 	return cbor_len;
1745d97138dSchristos }
1755d97138dSchristos 
1765d97138dSchristos size_t
pack_dummy(uint8_t * ptr,size_t len)1775d97138dSchristos pack_dummy(uint8_t *ptr, size_t len)
178ca37791eSchristos {
1795d97138dSchristos 	struct param dummy;
1805d97138dSchristos 	uint8_t	blob[4096];
1815d97138dSchristos 	size_t blob_len;
1825d97138dSchristos 
1835d97138dSchristos 	memset(&dummy, 0, sizeof(dummy));
1845d97138dSchristos 
1855d97138dSchristos 	strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin));
1865d97138dSchristos 	strlcpy(dummy.name, dummy_name, sizeof(dummy.name));
1875d97138dSchristos 
1885d97138dSchristos 	dummy.info_wire_data.len = sizeof(dummy_info_wire_data);
1895d97138dSchristos 	dummy.enroll_wire_data.len = sizeof(dummy_enroll_wire_data);
1905d97138dSchristos 	dummy.list_wire_data.len = sizeof(dummy_list_wire_data);
1915d97138dSchristos 	dummy.set_name_wire_data.len = sizeof(dummy_set_name_wire_data);
1925d97138dSchristos 	dummy.remove_wire_data.len = sizeof(dummy_remove_wire_data);
1935d97138dSchristos 	dummy.id.len = sizeof(dummy_id);
1945d97138dSchristos 
1955d97138dSchristos 	memcpy(&dummy.info_wire_data.body, &dummy_info_wire_data,
1965d97138dSchristos 	    dummy.info_wire_data.len);
1975d97138dSchristos 	memcpy(&dummy.enroll_wire_data.body, &dummy_enroll_wire_data,
1985d97138dSchristos 	    dummy.enroll_wire_data.len);
1995d97138dSchristos 	memcpy(&dummy.list_wire_data.body, &dummy_list_wire_data,
2005d97138dSchristos 	    dummy.list_wire_data.len);
2015d97138dSchristos 	memcpy(&dummy.set_name_wire_data.body, &dummy_set_name_wire_data,
2025d97138dSchristos 	    dummy.set_name_wire_data.len);
2035d97138dSchristos 	memcpy(&dummy.remove_wire_data.body, &dummy_remove_wire_data,
2045d97138dSchristos 	    dummy.remove_wire_data.len);
2055d97138dSchristos 	memcpy(&dummy.id.body, &dummy_id, dummy.id.len);
2065d97138dSchristos 
2075d97138dSchristos 	assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
2085d97138dSchristos 
2095d97138dSchristos 	if (blob_len > len) {
2105d97138dSchristos 		memcpy(ptr, blob, len);
2115d97138dSchristos 		return len;
2125d97138dSchristos 	}
2135d97138dSchristos 
2145d97138dSchristos 	memcpy(ptr, blob, blob_len);
2155d97138dSchristos 
2165d97138dSchristos 	return blob_len;
217ca37791eSchristos }
218ca37791eSchristos 
219ca37791eSchristos static fido_dev_t *
prepare_dev(void)2205d97138dSchristos prepare_dev(void)
221ca37791eSchristos {
222ca37791eSchristos 	fido_dev_t *dev;
2235d97138dSchristos 	bool x;
224ca37791eSchristos 
22598a5e356Schristos 	if ((dev = open_dev(0)) == NULL)
2265d97138dSchristos 		return NULL;
227ca37791eSchristos 
2285d97138dSchristos 	x = fido_dev_is_fido2(dev);
2295d97138dSchristos 	consume(&x, sizeof(x));
2305d97138dSchristos 	x = fido_dev_supports_pin(dev);
2315d97138dSchristos 	consume(&x, sizeof(x));
2325d97138dSchristos 	x = fido_dev_has_pin(dev);
2335d97138dSchristos 	consume(&x, sizeof(x));
23498a5e356Schristos 	x = fido_dev_supports_uv(dev);
23598a5e356Schristos 	consume(&x, sizeof(x));
23698a5e356Schristos 	x = fido_dev_has_uv(dev);
23798a5e356Schristos 	consume(&x, sizeof(x));
2385d97138dSchristos 
2395d97138dSchristos 	return dev;
240ca37791eSchristos }
241ca37791eSchristos 
242ca37791eSchristos static void
get_info(const struct param * p)2435d97138dSchristos get_info(const struct param *p)
244ca37791eSchristos {
245ca37791eSchristos 	fido_dev_t *dev = NULL;
246ca37791eSchristos 	fido_bio_info_t *i = NULL;
247ca37791eSchristos 	uint8_t type;
248ca37791eSchristos 	uint8_t max_samples;
2495d97138dSchristos 	int r;
250ca37791eSchristos 
251ca37791eSchristos 	set_wire_data(p->info_wire_data.body, p->info_wire_data.len);
252ca37791eSchristos 
253ca37791eSchristos 	if ((dev = prepare_dev()) == NULL || (i = fido_bio_info_new()) == NULL)
254ca37791eSchristos 		goto done;
255ca37791eSchristos 
2565d97138dSchristos 	r = fido_bio_dev_get_info(dev, i);
2575d97138dSchristos 	consume_str(fido_strerr(r));
258ca37791eSchristos 
259ca37791eSchristos 	type = fido_bio_info_type(i);
260ca37791eSchristos 	max_samples = fido_bio_info_max_samples(i);
261ca37791eSchristos 	consume(&type, sizeof(type));
262ca37791eSchristos 	consume(&max_samples, sizeof(max_samples));
263ca37791eSchristos 
264ca37791eSchristos done:
265ca37791eSchristos 	if (dev)
266ca37791eSchristos 		fido_dev_close(dev);
267ca37791eSchristos 
268ca37791eSchristos 	fido_dev_free(&dev);
269ca37791eSchristos 	fido_bio_info_free(&i);
270ca37791eSchristos }
271ca37791eSchristos 
272ca37791eSchristos static void
consume_template(const fido_bio_template_t * t)273ca37791eSchristos consume_template(const fido_bio_template_t *t)
274ca37791eSchristos {
275*b93b3e8cSchristos 	consume_str(fido_bio_template_name(t));
276ca37791eSchristos 	consume(fido_bio_template_id_ptr(t), fido_bio_template_id_len(t));
277ca37791eSchristos }
278ca37791eSchristos 
279ca37791eSchristos static void
consume_enroll(fido_bio_enroll_t * e)280ca37791eSchristos consume_enroll(fido_bio_enroll_t *e)
281ca37791eSchristos {
282ca37791eSchristos 	uint8_t last_status;
283ca37791eSchristos 	uint8_t remaining_samples;
284ca37791eSchristos 
285ca37791eSchristos 	last_status = fido_bio_enroll_last_status(e);
286ca37791eSchristos 	remaining_samples = fido_bio_enroll_remaining_samples(e);
287ca37791eSchristos 	consume(&last_status, sizeof(last_status));
288ca37791eSchristos 	consume(&remaining_samples, sizeof(remaining_samples));
289ca37791eSchristos }
290ca37791eSchristos 
291ca37791eSchristos static void
enroll(const struct param * p)2925d97138dSchristos enroll(const struct param *p)
293ca37791eSchristos {
294ca37791eSchristos 	fido_dev_t *dev = NULL;
295ca37791eSchristos 	fido_bio_template_t *t = NULL;
296ca37791eSchristos 	fido_bio_enroll_t *e = NULL;
297ca37791eSchristos 	size_t cnt = 0;
298ca37791eSchristos 
299ca37791eSchristos 	set_wire_data(p->enroll_wire_data.body, p->enroll_wire_data.len);
300ca37791eSchristos 
301ca37791eSchristos 	if ((dev = prepare_dev()) == NULL ||
302ca37791eSchristos 	    (t = fido_bio_template_new()) == NULL ||
303ca37791eSchristos 	    (e = fido_bio_enroll_new()) == NULL)
304ca37791eSchristos 		goto done;
305ca37791eSchristos 
30698a5e356Schristos 	fido_bio_dev_enroll_begin(dev, t, e, (uint32_t)p->seed, p->pin);
307ca37791eSchristos 
308ca37791eSchristos 	consume_template(t);
309ca37791eSchristos 	consume_enroll(e);
310ca37791eSchristos 
311ca37791eSchristos 	while (fido_bio_enroll_remaining_samples(e) > 0 && cnt++ < 5) {
312ca37791eSchristos 		fido_bio_dev_enroll_continue(dev, t, e, p->seed);
313ca37791eSchristos 		consume_template(t);
314ca37791eSchristos 		consume_enroll(e);
315ca37791eSchristos 	}
316ca37791eSchristos 
317ca37791eSchristos done:
318ca37791eSchristos 	if (dev)
319ca37791eSchristos 		fido_dev_close(dev);
320ca37791eSchristos 
321ca37791eSchristos 	fido_dev_free(&dev);
322ca37791eSchristos 	fido_bio_template_free(&t);
323ca37791eSchristos 	fido_bio_enroll_free(&e);
324ca37791eSchristos }
325ca37791eSchristos 
326ca37791eSchristos static void
list(const struct param * p)3275d97138dSchristos list(const struct param *p)
328ca37791eSchristos {
329ca37791eSchristos 	fido_dev_t *dev = NULL;
330ca37791eSchristos 	fido_bio_template_array_t *ta = NULL;
331ca37791eSchristos 	const fido_bio_template_t *t = NULL;
332ca37791eSchristos 
333ca37791eSchristos 	set_wire_data(p->list_wire_data.body, p->list_wire_data.len);
334ca37791eSchristos 
335ca37791eSchristos 	if ((dev = prepare_dev()) == NULL ||
336ca37791eSchristos 	    (ta = fido_bio_template_array_new()) == NULL)
337ca37791eSchristos 		goto done;
338ca37791eSchristos 
339ca37791eSchristos 	fido_bio_dev_get_template_array(dev, ta, p->pin);
340ca37791eSchristos 
341ca37791eSchristos 	/* +1 on purpose */
342ca37791eSchristos 	for (size_t i = 0; i < fido_bio_template_array_count(ta) + 1; i++)
343ca37791eSchristos 		if ((t = fido_bio_template(ta, i)) != NULL)
344ca37791eSchristos 			consume_template(t);
345ca37791eSchristos 
346ca37791eSchristos done:
347ca37791eSchristos 	if (dev)
348ca37791eSchristos 		fido_dev_close(dev);
349ca37791eSchristos 
350ca37791eSchristos 	fido_dev_free(&dev);
351ca37791eSchristos 	fido_bio_template_array_free(&ta);
352ca37791eSchristos }
353ca37791eSchristos 
354ca37791eSchristos static void
set_name(const struct param * p)3555d97138dSchristos set_name(const struct param *p)
356ca37791eSchristos {
357ca37791eSchristos 	fido_dev_t *dev = NULL;
358ca37791eSchristos 	fido_bio_template_t *t = NULL;
359ca37791eSchristos 
360ca37791eSchristos 	set_wire_data(p->set_name_wire_data.body, p->set_name_wire_data.len);
361ca37791eSchristos 
362ca37791eSchristos 	if ((dev = prepare_dev()) == NULL ||
363ca37791eSchristos 	    (t = fido_bio_template_new()) == NULL)
364ca37791eSchristos 		goto done;
365ca37791eSchristos 
366ca37791eSchristos 	fido_bio_template_set_name(t, p->name);
367ca37791eSchristos 	fido_bio_template_set_id(t, p->id.body, p->id.len);
368ca37791eSchristos 	consume_template(t);
369ca37791eSchristos 
370ca37791eSchristos 	fido_bio_dev_set_template_name(dev, t, p->pin);
371ca37791eSchristos 
372ca37791eSchristos done:
373ca37791eSchristos 	if (dev)
374ca37791eSchristos 		fido_dev_close(dev);
375ca37791eSchristos 
376ca37791eSchristos 	fido_dev_free(&dev);
377ca37791eSchristos 	fido_bio_template_free(&t);
378ca37791eSchristos }
379ca37791eSchristos 
380ca37791eSchristos static void
del(const struct param * p)3815d97138dSchristos del(const struct param *p)
382ca37791eSchristos {
383ca37791eSchristos 	fido_dev_t *dev = NULL;
384ca37791eSchristos 	fido_bio_template_t *t = NULL;
3855d97138dSchristos 	int r;
386ca37791eSchristos 
387ca37791eSchristos 	set_wire_data(p->remove_wire_data.body, p->remove_wire_data.len);
388ca37791eSchristos 
389ca37791eSchristos 	if ((dev = prepare_dev()) == NULL ||
390ca37791eSchristos 	    (t = fido_bio_template_new()) == NULL)
391ca37791eSchristos 		goto done;
392ca37791eSchristos 
3935d97138dSchristos 	r = fido_bio_template_set_id(t, p->id.body, p->id.len);
394ca37791eSchristos 	consume_template(t);
3955d97138dSchristos 	consume_str(fido_strerr(r));
396ca37791eSchristos 
397ca37791eSchristos 	fido_bio_dev_enroll_remove(dev, t, p->pin);
398ca37791eSchristos 
399ca37791eSchristos done:
400ca37791eSchristos 	if (dev)
401ca37791eSchristos 		fido_dev_close(dev);
402ca37791eSchristos 
403ca37791eSchristos 	fido_dev_free(&dev);
404ca37791eSchristos 	fido_bio_template_free(&t);
405ca37791eSchristos }
406ca37791eSchristos 
4075d97138dSchristos void
test(const struct param * p)4085d97138dSchristos test(const struct param *p)
409ca37791eSchristos {
4105d97138dSchristos 	prng_init((unsigned int)p->seed);
411ca37791eSchristos 	fido_init(FIDO_DEBUG);
412ca37791eSchristos 	fido_set_log_handler(consume_str);
413ca37791eSchristos 
4145d97138dSchristos 	get_info(p);
4155d97138dSchristos 	enroll(p);
4165d97138dSchristos 	list(p);
4175d97138dSchristos 	set_name(p);
4185d97138dSchristos 	del(p);
419ca37791eSchristos }
420ca37791eSchristos 
4215d97138dSchristos void
mutate(struct param * p,unsigned int seed,unsigned int flags)4225d97138dSchristos mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
423ca37791eSchristos {
4245d97138dSchristos 	if (flags & MUTATE_SEED)
4255d97138dSchristos 		p->seed = (int)seed;
426ca37791eSchristos 
4275d97138dSchristos 	if (flags & MUTATE_PARAM) {
4285d97138dSchristos 		mutate_blob(&p->id);
4295d97138dSchristos 		mutate_string(p->pin);
4305d97138dSchristos 		mutate_string(p->name);
431ca37791eSchristos 	}
432ca37791eSchristos 
4335d97138dSchristos 	if (flags & MUTATE_WIREDATA) {
4345d97138dSchristos 		mutate_blob(&p->info_wire_data);
4355d97138dSchristos 		mutate_blob(&p->enroll_wire_data);
4365d97138dSchristos 		mutate_blob(&p->list_wire_data);
4375d97138dSchristos 		mutate_blob(&p->set_name_wire_data);
4385d97138dSchristos 		mutate_blob(&p->remove_wire_data);
439ca37791eSchristos 	}
440ca37791eSchristos }
441