xref: /netbsd-src/external/bsd/libfido2/dist/fuzz/fuzz_assert.c (revision 2d40c4512a84c0d064ec30a492c5e2a14d230bc3)
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