xref: /freebsd-src/contrib/libfido2/fuzz/fuzz_assert.c (revision 60a517b66a69b8c011b04063ef63a938738719bd)
10afa8e06SEd Maste /*
2*60a517b6SEd Maste  * Copyright (c) 2019-2023 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.
52ccfa855SEd 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 "wiredata_u2f.h"
170afa8e06SEd Maste #include "dummy.h"
180afa8e06SEd Maste 
190afa8e06SEd Maste #include "../openbsd-compat/openbsd-compat.h"
200afa8e06SEd Maste 
210afa8e06SEd Maste /* Parameter set defining a FIDO2 get assertion operation. */
220afa8e06SEd Maste struct param {
230afa8e06SEd Maste 	char pin[MAXSTR];
240afa8e06SEd Maste 	char rp_id[MAXSTR];
250afa8e06SEd Maste 	int ext;
260afa8e06SEd Maste 	int seed;
270afa8e06SEd Maste 	struct blob cdh;
280afa8e06SEd Maste 	struct blob cred;
290afa8e06SEd Maste 	struct blob es256;
300afa8e06SEd Maste 	struct blob rs256;
310afa8e06SEd Maste 	struct blob eddsa;
320afa8e06SEd Maste 	struct blob wire_data;
330afa8e06SEd Maste 	uint8_t cred_count;
340afa8e06SEd Maste 	uint8_t type;
350afa8e06SEd Maste 	uint8_t opt;
360afa8e06SEd Maste 	uint8_t up;
370afa8e06SEd Maste 	uint8_t uv;
380afa8e06SEd Maste };
390afa8e06SEd Maste 
400afa8e06SEd Maste /*
410afa8e06SEd Maste  * Collection of HID reports from an authenticator issued with a FIDO2
420afa8e06SEd Maste  * get assertion using the example parameters above.
430afa8e06SEd Maste  */
440afa8e06SEd Maste static const uint8_t dummy_wire_data_fido[] = {
450afa8e06SEd Maste 	WIREDATA_CTAP_INIT,
460afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_INFO,
470afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_AUTHKEY,
480afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_PINTOKEN,
490afa8e06SEd Maste 	WIREDATA_CTAP_CBOR_ASSERT,
500afa8e06SEd Maste };
510afa8e06SEd Maste 
520afa8e06SEd Maste /*
530afa8e06SEd Maste  * Collection of HID reports from an authenticator issued with a U2F
540afa8e06SEd Maste  * authentication using the example parameters above.
550afa8e06SEd Maste  */
560afa8e06SEd Maste static const uint8_t dummy_wire_data_u2f[] = {
570afa8e06SEd Maste 	WIREDATA_CTAP_INIT,
580afa8e06SEd Maste 	WIREDATA_CTAP_U2F_6985,
590afa8e06SEd Maste 	WIREDATA_CTAP_U2F_6985,
600afa8e06SEd Maste 	WIREDATA_CTAP_U2F_6985,
610afa8e06SEd Maste 	WIREDATA_CTAP_U2F_6985,
620afa8e06SEd Maste 	WIREDATA_CTAP_U2F_AUTH,
630afa8e06SEd Maste };
640afa8e06SEd Maste 
650afa8e06SEd Maste struct param *
unpack(const uint8_t * ptr,size_t len)660afa8e06SEd Maste unpack(const uint8_t *ptr, size_t len)
670afa8e06SEd Maste {
680afa8e06SEd Maste 	cbor_item_t *item = NULL, **v;
690afa8e06SEd Maste 	struct cbor_load_result cbor;
700afa8e06SEd Maste 	struct param *p;
710afa8e06SEd Maste 	int ok = -1;
720afa8e06SEd Maste 
730afa8e06SEd Maste 	if ((p = calloc(1, sizeof(*p))) == NULL ||
740afa8e06SEd Maste 	    (item = cbor_load(ptr, len, &cbor)) == NULL ||
750afa8e06SEd Maste 	    cbor.read != len ||
760afa8e06SEd Maste 	    cbor_isa_array(item) == false ||
770afa8e06SEd Maste 	    cbor_array_is_definite(item) == false ||
780afa8e06SEd Maste 	    cbor_array_size(item) != 15 ||
790afa8e06SEd Maste 	    (v = cbor_array_handle(item)) == NULL)
800afa8e06SEd Maste 		goto fail;
810afa8e06SEd Maste 
820afa8e06SEd Maste 	if (unpack_byte(v[0], &p->uv) < 0 ||
830afa8e06SEd Maste 	    unpack_byte(v[1], &p->up) < 0 ||
840afa8e06SEd Maste 	    unpack_byte(v[2], &p->opt) < 0 ||
850afa8e06SEd Maste 	    unpack_byte(v[3], &p->type) < 0 ||
860afa8e06SEd Maste 	    unpack_byte(v[4], &p->cred_count) < 0 ||
870afa8e06SEd Maste 	    unpack_int(v[5], &p->ext) < 0 ||
880afa8e06SEd Maste 	    unpack_int(v[6], &p->seed) < 0 ||
890afa8e06SEd Maste 	    unpack_string(v[7], p->rp_id) < 0 ||
900afa8e06SEd Maste 	    unpack_string(v[8], p->pin) < 0 ||
910afa8e06SEd Maste 	    unpack_blob(v[9], &p->wire_data) < 0 ||
920afa8e06SEd Maste 	    unpack_blob(v[10], &p->rs256) < 0 ||
930afa8e06SEd Maste 	    unpack_blob(v[11], &p->es256) < 0 ||
940afa8e06SEd Maste 	    unpack_blob(v[12], &p->eddsa) < 0 ||
950afa8e06SEd Maste 	    unpack_blob(v[13], &p->cred) < 0 ||
960afa8e06SEd Maste 	    unpack_blob(v[14], &p->cdh) < 0)
970afa8e06SEd Maste 		goto fail;
980afa8e06SEd Maste 
990afa8e06SEd Maste 	ok = 0;
1000afa8e06SEd Maste fail:
1010afa8e06SEd Maste 	if (ok < 0) {
1020afa8e06SEd Maste 		free(p);
1030afa8e06SEd Maste 		p = NULL;
1040afa8e06SEd Maste 	}
1050afa8e06SEd Maste 
1060afa8e06SEd Maste 	if (item)
1070afa8e06SEd Maste 		cbor_decref(&item);
1080afa8e06SEd Maste 
1090afa8e06SEd Maste 	return p;
1100afa8e06SEd Maste }
1110afa8e06SEd Maste 
1120afa8e06SEd Maste size_t
pack(uint8_t * ptr,size_t len,const struct param * p)1130afa8e06SEd Maste pack(uint8_t *ptr, size_t len, const struct param *p)
1140afa8e06SEd Maste {
1150afa8e06SEd Maste 	cbor_item_t *argv[15], *array = NULL;
1160afa8e06SEd Maste 	size_t cbor_alloc_len, cbor_len = 0;
1170afa8e06SEd Maste 	unsigned char *cbor = NULL;
1180afa8e06SEd Maste 
1190afa8e06SEd Maste 	memset(argv, 0, sizeof(argv));
1200afa8e06SEd Maste 
1210afa8e06SEd Maste 	if ((array = cbor_new_definite_array(15)) == NULL ||
1220afa8e06SEd Maste 	    (argv[0] = pack_byte(p->uv)) == NULL ||
1230afa8e06SEd Maste 	    (argv[1] = pack_byte(p->up)) == NULL ||
1240afa8e06SEd Maste 	    (argv[2] = pack_byte(p->opt)) == NULL ||
1250afa8e06SEd Maste 	    (argv[3] = pack_byte(p->type)) == NULL ||
1260afa8e06SEd Maste 	    (argv[4] = pack_byte(p->cred_count)) == NULL ||
1270afa8e06SEd Maste 	    (argv[5] = pack_int(p->ext)) == NULL ||
1280afa8e06SEd Maste 	    (argv[6] = pack_int(p->seed)) == NULL ||
1290afa8e06SEd Maste 	    (argv[7] = pack_string(p->rp_id)) == NULL ||
1300afa8e06SEd Maste 	    (argv[8] = pack_string(p->pin)) == NULL ||
1310afa8e06SEd Maste 	    (argv[9] = pack_blob(&p->wire_data)) == NULL ||
1320afa8e06SEd Maste 	    (argv[10] = pack_blob(&p->rs256)) == NULL ||
1330afa8e06SEd Maste 	    (argv[11] = pack_blob(&p->es256)) == NULL ||
1340afa8e06SEd Maste 	    (argv[12] = pack_blob(&p->eddsa)) == NULL ||
1350afa8e06SEd Maste 	    (argv[13] = pack_blob(&p->cred)) == NULL ||
1360afa8e06SEd Maste 	    (argv[14] = pack_blob(&p->cdh)) == NULL)
1370afa8e06SEd Maste 		goto fail;
1380afa8e06SEd Maste 
1390afa8e06SEd Maste 	for (size_t i = 0; i < 15; i++)
1400afa8e06SEd Maste 		if (cbor_array_push(array, argv[i]) == false)
1410afa8e06SEd Maste 			goto fail;
1420afa8e06SEd Maste 
1430afa8e06SEd Maste 	if ((cbor_len = cbor_serialize_alloc(array, &cbor,
1442ccfa855SEd Maste 	    &cbor_alloc_len)) == 0 || cbor_len > len) {
1450afa8e06SEd Maste 		cbor_len = 0;
1460afa8e06SEd Maste 		goto fail;
1470afa8e06SEd Maste 	}
1480afa8e06SEd Maste 
1490afa8e06SEd Maste 	memcpy(ptr, cbor, cbor_len);
1500afa8e06SEd Maste fail:
1510afa8e06SEd Maste 	for (size_t i = 0; i < 15; i++)
1520afa8e06SEd Maste 		if (argv[i])
1530afa8e06SEd Maste 			cbor_decref(&argv[i]);
1540afa8e06SEd Maste 
1550afa8e06SEd Maste 	if (array)
1560afa8e06SEd Maste 		cbor_decref(&array);
1570afa8e06SEd Maste 
1580afa8e06SEd Maste 	free(cbor);
1590afa8e06SEd Maste 
1600afa8e06SEd Maste 	return cbor_len;
1610afa8e06SEd Maste }
1620afa8e06SEd Maste 
1630afa8e06SEd Maste size_t
pack_dummy(uint8_t * ptr,size_t len)1640afa8e06SEd Maste pack_dummy(uint8_t *ptr, size_t len)
1650afa8e06SEd Maste {
1660afa8e06SEd Maste 	struct param dummy;
1672ccfa855SEd Maste 	uint8_t blob[MAXCORPUS];
1680afa8e06SEd Maste 	size_t blob_len;
1690afa8e06SEd Maste 
1700afa8e06SEd Maste 	memset(&dummy, 0, sizeof(dummy));
1710afa8e06SEd Maste 
1720afa8e06SEd Maste 	dummy.type = 1; /* rsa */
1730afa8e06SEd Maste 	dummy.ext = FIDO_EXT_HMAC_SECRET;
1740afa8e06SEd Maste 
1750afa8e06SEd Maste 	strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin));
1760afa8e06SEd Maste 	strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id));
1770afa8e06SEd Maste 
1780afa8e06SEd Maste 	dummy.cred.len = sizeof(dummy_cdh); /* XXX */
1790afa8e06SEd Maste 	dummy.cdh.len = sizeof(dummy_cdh);
1800afa8e06SEd Maste 	dummy.es256.len = sizeof(dummy_es256);
1810afa8e06SEd Maste 	dummy.rs256.len = sizeof(dummy_rs256);
1820afa8e06SEd Maste 	dummy.eddsa.len = sizeof(dummy_eddsa);
1830afa8e06SEd Maste 	dummy.wire_data.len = sizeof(dummy_wire_data_fido);
1840afa8e06SEd Maste 
1850afa8e06SEd Maste 	memcpy(&dummy.cred.body, &dummy_cdh, dummy.cred.len); /* XXX */
1860afa8e06SEd Maste 	memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len);
1870afa8e06SEd Maste 	memcpy(&dummy.wire_data.body, &dummy_wire_data_fido,
1880afa8e06SEd Maste 	    dummy.wire_data.len);
1890afa8e06SEd Maste 	memcpy(&dummy.es256.body, &dummy_es256, dummy.es256.len);
1900afa8e06SEd Maste 	memcpy(&dummy.rs256.body, &dummy_rs256, dummy.rs256.len);
1910afa8e06SEd Maste 	memcpy(&dummy.eddsa.body, &dummy_eddsa, dummy.eddsa.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
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)2060afa8e06SEd Maste get_assert(fido_assert_t *assert, uint8_t opt, const struct blob *cdh,
2070afa8e06SEd Maste     const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin,
2080afa8e06SEd Maste     uint8_t cred_count, const struct blob *cred)
2090afa8e06SEd Maste {
2100afa8e06SEd Maste 	fido_dev_t *dev;
2110afa8e06SEd Maste 
2120afa8e06SEd Maste 	if ((dev = open_dev(opt & 2)) == NULL)
2130afa8e06SEd Maste 		return;
2140afa8e06SEd Maste 	if (opt & 1)
2150afa8e06SEd Maste 		fido_dev_force_u2f(dev);
2160afa8e06SEd Maste 	if (ext & FIDO_EXT_HMAC_SECRET)
2170afa8e06SEd Maste 		fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET);
2180afa8e06SEd Maste 	if (ext & FIDO_EXT_CRED_BLOB)
2190afa8e06SEd Maste 		fido_assert_set_extensions(assert, FIDO_EXT_CRED_BLOB);
2200afa8e06SEd Maste 	if (ext & FIDO_EXT_LARGEBLOB_KEY)
2210afa8e06SEd Maste 		fido_assert_set_extensions(assert, FIDO_EXT_LARGEBLOB_KEY);
2220afa8e06SEd Maste 	if (up & 1)
2230afa8e06SEd Maste 		fido_assert_set_up(assert, FIDO_OPT_TRUE);
2240afa8e06SEd Maste 	else if (opt & 1)
2250afa8e06SEd Maste 		fido_assert_set_up(assert, FIDO_OPT_FALSE);
2260afa8e06SEd Maste 	if (uv & 1)
2270afa8e06SEd Maste 		fido_assert_set_uv(assert, FIDO_OPT_TRUE);
2280afa8e06SEd Maste 
2290afa8e06SEd Maste 	for (uint8_t i = 0; i < cred_count; i++)
2300afa8e06SEd Maste 		fido_assert_allow_cred(assert, cred->body, cred->len);
2310afa8e06SEd Maste 
2320afa8e06SEd Maste 	fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len);
2330afa8e06SEd Maste 	fido_assert_set_rp(assert, rp_id);
2340afa8e06SEd Maste 	/* XXX reuse cred as hmac salt */
2350afa8e06SEd Maste 	fido_assert_set_hmac_salt(assert, cred->body, cred->len);
2360afa8e06SEd Maste 
2370afa8e06SEd Maste 	/* repeat memory operations to trigger reallocation paths */
2380afa8e06SEd Maste 	fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len);
2390afa8e06SEd Maste 	fido_assert_set_rp(assert, rp_id);
2400afa8e06SEd Maste 	fido_assert_set_hmac_salt(assert, cred->body, cred->len);
2410afa8e06SEd Maste 
2420afa8e06SEd Maste 	if (strlen(pin) == 0)
2430afa8e06SEd Maste 		pin = NULL;
2440afa8e06SEd Maste 
2450afa8e06SEd Maste 	fido_dev_get_assert(dev, assert, (opt & 1) ? NULL : pin);
2460afa8e06SEd Maste 
2470afa8e06SEd Maste 	fido_dev_cancel(dev);
2480afa8e06SEd Maste 	fido_dev_close(dev);
2490afa8e06SEd Maste 	fido_dev_free(&dev);
2500afa8e06SEd Maste }
2510afa8e06SEd Maste 
2520afa8e06SEd Maste 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)2530afa8e06SEd Maste verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len,
2540afa8e06SEd Maste     const char *rp_id, const unsigned char *authdata_ptr, size_t authdata_len,
2550afa8e06SEd Maste     const unsigned char *sig_ptr, size_t sig_len, uint8_t up, uint8_t uv,
2560afa8e06SEd Maste     int ext, void *pk)
2570afa8e06SEd Maste {
2580afa8e06SEd Maste 	fido_assert_t *assert = NULL;
259f540a430SEd Maste 	int r;
2600afa8e06SEd Maste 
2610afa8e06SEd Maste 	if ((assert = fido_assert_new()) == NULL)
2620afa8e06SEd Maste 		return;
2630afa8e06SEd Maste 
2640afa8e06SEd Maste 	fido_assert_set_clientdata_hash(assert, cdh_ptr, cdh_len);
2650afa8e06SEd Maste 	fido_assert_set_rp(assert, rp_id);
2660afa8e06SEd Maste 	fido_assert_set_count(assert, 1);
2670afa8e06SEd Maste 
2680afa8e06SEd Maste 	if (fido_assert_set_authdata(assert, 0, authdata_ptr,
2690afa8e06SEd Maste 	    authdata_len) != FIDO_OK) {
2700afa8e06SEd Maste 		fido_assert_set_authdata_raw(assert, 0, authdata_ptr,
2710afa8e06SEd Maste 		    authdata_len);
2720afa8e06SEd Maste 	}
2730afa8e06SEd Maste 
2740afa8e06SEd Maste 	if (up & 1)
2750afa8e06SEd Maste 		fido_assert_set_up(assert, FIDO_OPT_TRUE);
2760afa8e06SEd Maste 	if (uv & 1)
2770afa8e06SEd Maste 		fido_assert_set_uv(assert, FIDO_OPT_TRUE);
2780afa8e06SEd Maste 
2790afa8e06SEd Maste 	fido_assert_set_extensions(assert, ext);
2800afa8e06SEd Maste 	fido_assert_set_sig(assert, 0, sig_ptr, sig_len);
2810afa8e06SEd Maste 
2820afa8e06SEd Maste 	/* repeat memory operations to trigger reallocation paths */
2830afa8e06SEd Maste 	if (fido_assert_set_authdata(assert, 0, authdata_ptr,
2840afa8e06SEd Maste 	    authdata_len) != FIDO_OK) {
2850afa8e06SEd Maste 		fido_assert_set_authdata_raw(assert, 0, authdata_ptr,
2860afa8e06SEd Maste 		    authdata_len);
2870afa8e06SEd Maste 	}
2880afa8e06SEd Maste 	fido_assert_set_sig(assert, 0, sig_ptr, sig_len);
2890afa8e06SEd Maste 
290f540a430SEd Maste 	r = fido_assert_verify(assert, 0, type, pk);
291f540a430SEd Maste 	consume(&r, sizeof(r));
2920afa8e06SEd Maste 
2930afa8e06SEd Maste 	fido_assert_free(&assert);
2940afa8e06SEd Maste }
2950afa8e06SEd Maste 
2960afa8e06SEd Maste /*
297f540a430SEd Maste  * Do a dummy conversion to exercise es256_pk_from_EVP_PKEY().
298f540a430SEd Maste  */
299f540a430SEd Maste static void
es256_convert(const es256_pk_t * k)300f540a430SEd Maste es256_convert(const es256_pk_t *k)
301f540a430SEd Maste {
302f540a430SEd Maste 	EVP_PKEY *pkey = NULL;
303f540a430SEd Maste 	es256_pk_t *pk = NULL;
304f540a430SEd Maste 	int r;
305f540a430SEd Maste 
306f540a430SEd Maste 	if ((pkey = es256_pk_to_EVP_PKEY(k)) == NULL ||
307f540a430SEd Maste 	    (pk = es256_pk_new()) == NULL)
308f540a430SEd Maste 		goto out;
309f540a430SEd Maste 
310f540a430SEd Maste 	r = es256_pk_from_EVP_PKEY(pk, pkey);
311f540a430SEd Maste 	consume(&r, sizeof(r));
312f540a430SEd Maste out:
313f540a430SEd Maste 	es256_pk_free(&pk);
314f540a430SEd Maste 	EVP_PKEY_free(pkey);
315f540a430SEd Maste }
316f540a430SEd Maste 
317f540a430SEd Maste /*
3182ccfa855SEd Maste  * Do a dummy conversion to exercise es384_pk_from_EVP_PKEY().
3192ccfa855SEd Maste  */
3202ccfa855SEd Maste static void
es384_convert(const es384_pk_t * k)3212ccfa855SEd Maste es384_convert(const es384_pk_t *k)
3222ccfa855SEd Maste {
3232ccfa855SEd Maste 	EVP_PKEY *pkey = NULL;
3242ccfa855SEd Maste 	es384_pk_t *pk = NULL;
3252ccfa855SEd Maste 	int r;
3262ccfa855SEd Maste 
3272ccfa855SEd Maste 	if ((pkey = es384_pk_to_EVP_PKEY(k)) == NULL ||
3282ccfa855SEd Maste 	    (pk = es384_pk_new()) == NULL)
3292ccfa855SEd Maste 		goto out;
3302ccfa855SEd Maste 
3312ccfa855SEd Maste 	r = es384_pk_from_EVP_PKEY(pk, pkey);
3322ccfa855SEd Maste 	consume(&r, sizeof(r));
3332ccfa855SEd Maste out:
3342ccfa855SEd Maste 	es384_pk_free(&pk);
3352ccfa855SEd Maste 	EVP_PKEY_free(pkey);
3362ccfa855SEd Maste }
3372ccfa855SEd Maste 
3382ccfa855SEd Maste /*
339f540a430SEd Maste  * Do a dummy conversion to exercise rs256_pk_from_EVP_PKEY().
3400afa8e06SEd Maste  */
3410afa8e06SEd Maste static void
rs256_convert(const rs256_pk_t * k)3420afa8e06SEd Maste rs256_convert(const rs256_pk_t *k)
3430afa8e06SEd Maste {
3440afa8e06SEd Maste 	EVP_PKEY *pkey = NULL;
3450afa8e06SEd Maste 	rs256_pk_t *pk = NULL;
346f540a430SEd Maste 	int r;
3470afa8e06SEd Maste 
3480afa8e06SEd Maste 	if ((pkey = rs256_pk_to_EVP_PKEY(k)) == NULL ||
349f540a430SEd Maste 	    (pk = rs256_pk_new()) == NULL)
3500afa8e06SEd Maste 		goto out;
3510afa8e06SEd Maste 
352f540a430SEd Maste 	r = rs256_pk_from_EVP_PKEY(pk, pkey);
353f540a430SEd Maste 	consume(&r, sizeof(r));
3540afa8e06SEd Maste out:
3550afa8e06SEd Maste 	rs256_pk_free(&pk);
3560afa8e06SEd Maste 	EVP_PKEY_free(pkey);
3570afa8e06SEd Maste }
3580afa8e06SEd Maste 
3590afa8e06SEd Maste /*
3600afa8e06SEd Maste  * Do a dummy conversion to exercise eddsa_pk_from_EVP_PKEY().
3610afa8e06SEd Maste  */
3620afa8e06SEd Maste static void
eddsa_convert(const eddsa_pk_t * k)3630afa8e06SEd Maste eddsa_convert(const eddsa_pk_t *k)
3640afa8e06SEd Maste {
3650afa8e06SEd Maste 	EVP_PKEY *pkey = NULL;
3660afa8e06SEd Maste 	eddsa_pk_t *pk = NULL;
367f540a430SEd Maste 	int r;
3680afa8e06SEd Maste 
3690afa8e06SEd Maste 	if ((pkey = eddsa_pk_to_EVP_PKEY(k)) == NULL ||
3700afa8e06SEd Maste 	    (pk = eddsa_pk_new()) == NULL)
3710afa8e06SEd Maste 		goto out;
3720afa8e06SEd Maste 
3730afa8e06SEd Maste 	r = eddsa_pk_from_EVP_PKEY(pk, pkey);
374f540a430SEd Maste 	consume(&r, sizeof(r));
3750afa8e06SEd Maste out:
3760afa8e06SEd Maste 	if (pk)
3770afa8e06SEd Maste 		eddsa_pk_free(&pk);
3780afa8e06SEd Maste 	if (pkey)
3790afa8e06SEd Maste 		EVP_PKEY_free(pkey);
3800afa8e06SEd Maste }
3810afa8e06SEd Maste 
3820afa8e06SEd Maste void
test(const struct param * p)3830afa8e06SEd Maste test(const struct param *p)
3840afa8e06SEd Maste {
3850afa8e06SEd Maste 	fido_assert_t *assert = NULL;
3860afa8e06SEd Maste 	es256_pk_t *es256_pk = NULL;
3872ccfa855SEd Maste 	es384_pk_t *es384_pk = NULL;
3880afa8e06SEd Maste 	rs256_pk_t *rs256_pk = NULL;
3890afa8e06SEd Maste 	eddsa_pk_t *eddsa_pk = NULL;
3900afa8e06SEd Maste 	uint8_t flags;
3910afa8e06SEd Maste 	uint32_t sigcount;
3920afa8e06SEd Maste 	int cose_alg = 0;
3930afa8e06SEd Maste 	void *pk;
3940afa8e06SEd Maste 
3950afa8e06SEd Maste 	prng_init((unsigned int)p->seed);
396f540a430SEd Maste 	fuzz_clock_reset();
3970afa8e06SEd Maste 	fido_init(FIDO_DEBUG);
3980afa8e06SEd Maste 	fido_set_log_handler(consume_str);
3990afa8e06SEd Maste 
4000afa8e06SEd Maste 	switch (p->type & 3) {
4010afa8e06SEd Maste 	case 0:
4020afa8e06SEd Maste 		cose_alg = COSE_ES256;
4030afa8e06SEd Maste 
4040afa8e06SEd Maste 		if ((es256_pk = es256_pk_new()) == NULL)
4050afa8e06SEd Maste 			return;
4060afa8e06SEd Maste 
4070afa8e06SEd Maste 		es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len);
4080afa8e06SEd Maste 		pk = es256_pk;
4090afa8e06SEd Maste 
410f540a430SEd Maste 		es256_convert(pk);
411f540a430SEd Maste 
4120afa8e06SEd Maste 		break;
4130afa8e06SEd Maste 	case 1:
4140afa8e06SEd Maste 		cose_alg = COSE_RS256;
4150afa8e06SEd Maste 
4160afa8e06SEd Maste 		if ((rs256_pk = rs256_pk_new()) == NULL)
4170afa8e06SEd Maste 			return;
4180afa8e06SEd Maste 
4190afa8e06SEd Maste 		rs256_pk_from_ptr(rs256_pk, p->rs256.body, p->rs256.len);
4200afa8e06SEd Maste 		pk = rs256_pk;
4210afa8e06SEd Maste 
4220afa8e06SEd Maste 		rs256_convert(pk);
4230afa8e06SEd Maste 
4240afa8e06SEd Maste 		break;
4252ccfa855SEd Maste 	case 2:
4262ccfa855SEd Maste 		cose_alg = COSE_ES384;
4272ccfa855SEd Maste 
4282ccfa855SEd Maste 		if ((es384_pk = es384_pk_new()) == NULL)
4292ccfa855SEd Maste 			return;
4302ccfa855SEd Maste 
4312ccfa855SEd Maste 		/* XXX reuse p->es256 as es384 */
4322ccfa855SEd Maste 		es384_pk_from_ptr(es384_pk, p->es256.body, p->es256.len);
4332ccfa855SEd Maste 		pk = es384_pk;
4342ccfa855SEd Maste 
4352ccfa855SEd Maste 		es384_convert(pk);
4362ccfa855SEd Maste 
4372ccfa855SEd Maste 		break;
4380afa8e06SEd Maste 	default:
4390afa8e06SEd Maste 		cose_alg = COSE_EDDSA;
4400afa8e06SEd Maste 
4410afa8e06SEd Maste 		if ((eddsa_pk = eddsa_pk_new()) == NULL)
4420afa8e06SEd Maste 			return;
4430afa8e06SEd Maste 
4440afa8e06SEd Maste 		eddsa_pk_from_ptr(eddsa_pk, p->eddsa.body, p->eddsa.len);
4450afa8e06SEd Maste 		pk = eddsa_pk;
4460afa8e06SEd Maste 
4470afa8e06SEd Maste 		eddsa_convert(pk);
4480afa8e06SEd Maste 
4490afa8e06SEd Maste 		break;
4500afa8e06SEd Maste 	}
4510afa8e06SEd Maste 
4520afa8e06SEd Maste 	if ((assert = fido_assert_new()) == NULL)
4530afa8e06SEd Maste 		goto out;
4540afa8e06SEd Maste 
4550afa8e06SEd Maste 	set_wire_data(p->wire_data.body, p->wire_data.len);
4560afa8e06SEd Maste 
4570afa8e06SEd Maste 	get_assert(assert, p->opt, &p->cdh, p->rp_id, p->ext, p->up, p->uv,
4580afa8e06SEd Maste 	    p->pin, p->cred_count, &p->cred);
4590afa8e06SEd Maste 
4600afa8e06SEd Maste 	/* XXX +1 on purpose */
4610afa8e06SEd Maste 	for (size_t i = 0; i <= fido_assert_count(assert); i++) {
4620afa8e06SEd Maste 		verify_assert(cose_alg,
4630afa8e06SEd Maste 		    fido_assert_clientdata_hash_ptr(assert),
4640afa8e06SEd Maste 		    fido_assert_clientdata_hash_len(assert),
4650afa8e06SEd Maste 		    fido_assert_rp_id(assert),
4660afa8e06SEd Maste 		    fido_assert_authdata_ptr(assert, i),
4670afa8e06SEd Maste 		    fido_assert_authdata_len(assert, i),
4680afa8e06SEd Maste 		    fido_assert_sig_ptr(assert, i),
4690afa8e06SEd Maste 		    fido_assert_sig_len(assert, i), p->up, p->uv, p->ext, pk);
470*60a517b6SEd Maste 		consume(fido_assert_authdata_raw_ptr(assert, i),
471*60a517b6SEd Maste 		    fido_assert_authdata_raw_len(assert, i));
4720afa8e06SEd Maste 		consume(fido_assert_id_ptr(assert, i),
4730afa8e06SEd Maste 		    fido_assert_id_len(assert, i));
4740afa8e06SEd Maste 		consume(fido_assert_user_id_ptr(assert, i),
4750afa8e06SEd Maste 		    fido_assert_user_id_len(assert, i));
4760afa8e06SEd Maste 		consume(fido_assert_hmac_secret_ptr(assert, i),
4770afa8e06SEd Maste 		    fido_assert_hmac_secret_len(assert, i));
4780afa8e06SEd Maste 		consume_str(fido_assert_user_icon(assert, i));
4790afa8e06SEd Maste 		consume_str(fido_assert_user_name(assert, i));
4800afa8e06SEd Maste 		consume_str(fido_assert_user_display_name(assert, i));
4810afa8e06SEd Maste 		consume(fido_assert_blob_ptr(assert, i),
4820afa8e06SEd Maste 		    fido_assert_blob_len(assert, i));
4830afa8e06SEd Maste 		consume(fido_assert_largeblob_key_ptr(assert, i),
4840afa8e06SEd Maste 		    fido_assert_largeblob_key_len(assert, i));
4850afa8e06SEd Maste 		flags = fido_assert_flags(assert, i);
4860afa8e06SEd Maste 		consume(&flags, sizeof(flags));
4870afa8e06SEd Maste 		sigcount = fido_assert_sigcount(assert, i);
4880afa8e06SEd Maste 		consume(&sigcount, sizeof(sigcount));
4890afa8e06SEd Maste 	}
4900afa8e06SEd Maste 
4910afa8e06SEd Maste out:
4920afa8e06SEd Maste 	es256_pk_free(&es256_pk);
4932ccfa855SEd Maste 	es384_pk_free(&es384_pk);
4940afa8e06SEd Maste 	rs256_pk_free(&rs256_pk);
4950afa8e06SEd Maste 	eddsa_pk_free(&eddsa_pk);
4960afa8e06SEd Maste 
4970afa8e06SEd Maste 	fido_assert_free(&assert);
4980afa8e06SEd Maste }
4990afa8e06SEd Maste 
5000afa8e06SEd Maste void
mutate(struct param * p,unsigned int seed,unsigned int flags)5010afa8e06SEd Maste mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
5020afa8e06SEd Maste {
5030afa8e06SEd Maste 	if (flags & MUTATE_SEED)
5040afa8e06SEd Maste 		p->seed = (int)seed;
5050afa8e06SEd Maste 
5060afa8e06SEd Maste 	if (flags & MUTATE_PARAM) {
5070afa8e06SEd Maste 		mutate_byte(&p->uv);
5080afa8e06SEd Maste 		mutate_byte(&p->up);
5090afa8e06SEd Maste 		mutate_byte(&p->opt);
5100afa8e06SEd Maste 		mutate_byte(&p->type);
5110afa8e06SEd Maste 		mutate_byte(&p->cred_count);
5120afa8e06SEd Maste 		mutate_int(&p->ext);
5130afa8e06SEd Maste 		mutate_blob(&p->rs256);
5140afa8e06SEd Maste 		mutate_blob(&p->es256);
5150afa8e06SEd Maste 		mutate_blob(&p->eddsa);
5160afa8e06SEd Maste 		mutate_blob(&p->cred);
5170afa8e06SEd Maste 		mutate_blob(&p->cdh);
5180afa8e06SEd Maste 		mutate_string(p->rp_id);
5190afa8e06SEd Maste 		mutate_string(p->pin);
5200afa8e06SEd Maste 	}
5210afa8e06SEd Maste 
5220afa8e06SEd Maste 	if (flags & MUTATE_WIREDATA) {
5230afa8e06SEd Maste 		if (p->opt & 1) {
5240afa8e06SEd Maste 			p->wire_data.len = sizeof(dummy_wire_data_u2f);
5250afa8e06SEd Maste 			memcpy(&p->wire_data.body, &dummy_wire_data_u2f,
5260afa8e06SEd Maste 			    p->wire_data.len);
5270afa8e06SEd Maste 		} else {
5280afa8e06SEd Maste 			p->wire_data.len = sizeof(dummy_wire_data_fido);
5290afa8e06SEd Maste 			memcpy(&p->wire_data.body, &dummy_wire_data_fido,
5300afa8e06SEd Maste 			    p->wire_data.len);
5310afa8e06SEd Maste 		}
5320afa8e06SEd Maste 		mutate_blob(&p->wire_data);
5330afa8e06SEd Maste 	}
5340afa8e06SEd Maste }
535