xref: /freebsd-src/contrib/libfido2/fuzz/mutator_aux.c (revision 2ccfa855b2fc331819953e3de1b1c15ce5b95a7e)
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 <cbor.h>
100afa8e06SEd Maste #include <errno.h>
110afa8e06SEd Maste #include <stddef.h>
120afa8e06SEd Maste #include <stdint.h>
130afa8e06SEd Maste #include <stdio.h>
140afa8e06SEd Maste #include <stdlib.h>
150afa8e06SEd Maste #include <string.h>
160afa8e06SEd Maste 
170afa8e06SEd Maste #include "mutator_aux.h"
180afa8e06SEd Maste 
190afa8e06SEd Maste int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
200afa8e06SEd Maste int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
210afa8e06SEd Maste size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t);
220afa8e06SEd Maste 
23*2ccfa855SEd Maste extern int prng_up;
240afa8e06SEd Maste static const uint8_t *wire_data_ptr = NULL;
250afa8e06SEd Maste static size_t wire_data_len = 0;
260afa8e06SEd Maste 
270afa8e06SEd Maste void
consume(const void * body,size_t len)280afa8e06SEd Maste consume(const void *body, size_t len)
290afa8e06SEd Maste {
300afa8e06SEd Maste 	const volatile uint8_t *ptr = body;
310afa8e06SEd Maste 	volatile uint8_t x = 0;
320afa8e06SEd Maste 
330afa8e06SEd Maste #ifdef WITH_MSAN
340afa8e06SEd Maste 	__msan_check_mem_is_initialized(body, len);
350afa8e06SEd Maste #endif
360afa8e06SEd Maste 
370afa8e06SEd Maste 	while (len--)
380afa8e06SEd Maste 		x ^= *ptr++;
39f540a430SEd Maste 
40f540a430SEd Maste 	(void)x;
410afa8e06SEd Maste }
420afa8e06SEd Maste 
430afa8e06SEd Maste void
consume_str(const char * str)440afa8e06SEd Maste consume_str(const char *str)
450afa8e06SEd Maste {
460afa8e06SEd Maste 	if (str != NULL)
470afa8e06SEd Maste 		consume(str, strlen(str) + 1);
480afa8e06SEd Maste }
490afa8e06SEd Maste 
500afa8e06SEd Maste int
unpack_int(cbor_item_t * item,int * v)510afa8e06SEd Maste unpack_int(cbor_item_t *item, int *v)
520afa8e06SEd Maste {
530afa8e06SEd Maste 	if (cbor_is_int(item) == false ||
540afa8e06SEd Maste 	    cbor_int_get_width(item) != CBOR_INT_64)
550afa8e06SEd Maste 		return -1;
560afa8e06SEd Maste 
570afa8e06SEd Maste 	if (cbor_isa_uint(item))
580afa8e06SEd Maste 		*v = (int)cbor_get_uint64(item);
590afa8e06SEd Maste 	else
600afa8e06SEd Maste 		*v = (int)(-cbor_get_uint64(item) - 1);
610afa8e06SEd Maste 
620afa8e06SEd Maste 	return 0;
630afa8e06SEd Maste }
640afa8e06SEd Maste 
650afa8e06SEd Maste int
unpack_string(cbor_item_t * item,char * v)660afa8e06SEd Maste unpack_string(cbor_item_t *item, char *v)
670afa8e06SEd Maste {
680afa8e06SEd Maste 	size_t len;
690afa8e06SEd Maste 
700afa8e06SEd Maste 	if (cbor_isa_bytestring(item) == false ||
710afa8e06SEd Maste 	    (len = cbor_bytestring_length(item)) >= MAXSTR)
720afa8e06SEd Maste 		return -1;
730afa8e06SEd Maste 
740afa8e06SEd Maste 	memcpy(v, cbor_bytestring_handle(item), len);
750afa8e06SEd Maste 	v[len] = '\0';
760afa8e06SEd Maste 
770afa8e06SEd Maste 	return 0;
780afa8e06SEd Maste }
790afa8e06SEd Maste 
800afa8e06SEd Maste int
unpack_byte(cbor_item_t * item,uint8_t * v)810afa8e06SEd Maste unpack_byte(cbor_item_t *item, uint8_t *v)
820afa8e06SEd Maste {
830afa8e06SEd Maste 	if (cbor_isa_uint(item) == false ||
840afa8e06SEd Maste 	    cbor_int_get_width(item) != CBOR_INT_8)
850afa8e06SEd Maste 		return -1;
860afa8e06SEd Maste 
870afa8e06SEd Maste 	*v = cbor_get_uint8(item);
880afa8e06SEd Maste 
890afa8e06SEd Maste 	return 0;
900afa8e06SEd Maste }
910afa8e06SEd Maste 
920afa8e06SEd Maste int
unpack_blob(cbor_item_t * item,struct blob * v)930afa8e06SEd Maste unpack_blob(cbor_item_t *item, struct blob *v)
940afa8e06SEd Maste {
950afa8e06SEd Maste 	if (cbor_isa_bytestring(item) == false ||
960afa8e06SEd Maste 	    (v->len = cbor_bytestring_length(item)) > sizeof(v->body))
970afa8e06SEd Maste 		return -1;
980afa8e06SEd Maste 
990afa8e06SEd Maste 	memcpy(v->body, cbor_bytestring_handle(item), v->len);
1000afa8e06SEd Maste 
1010afa8e06SEd Maste 	return 0;
1020afa8e06SEd Maste }
1030afa8e06SEd Maste 
1040afa8e06SEd Maste cbor_item_t *
pack_int(int v)1050afa8e06SEd Maste pack_int(int v) NO_MSAN
1060afa8e06SEd Maste {
1070afa8e06SEd Maste 	if (v < 0)
1080afa8e06SEd Maste 		return cbor_build_negint64((uint64_t)(-(int64_t)v - 1));
1090afa8e06SEd Maste 	else
1100afa8e06SEd Maste 		return cbor_build_uint64((uint64_t)v);
1110afa8e06SEd Maste }
1120afa8e06SEd Maste 
1130afa8e06SEd Maste cbor_item_t *
pack_string(const char * v)1140afa8e06SEd Maste pack_string(const char *v) NO_MSAN
1150afa8e06SEd Maste {
1160afa8e06SEd Maste 	if (strlen(v) >= MAXSTR)
1170afa8e06SEd Maste 		return NULL;
1180afa8e06SEd Maste 
1190afa8e06SEd Maste 	return cbor_build_bytestring((const unsigned char *)v, strlen(v));
1200afa8e06SEd Maste }
1210afa8e06SEd Maste 
1220afa8e06SEd Maste cbor_item_t *
pack_byte(uint8_t v)1230afa8e06SEd Maste pack_byte(uint8_t v) NO_MSAN
1240afa8e06SEd Maste {
1250afa8e06SEd Maste 	return cbor_build_uint8(v);
1260afa8e06SEd Maste }
1270afa8e06SEd Maste 
1280afa8e06SEd Maste cbor_item_t *
pack_blob(const struct blob * v)1290afa8e06SEd Maste pack_blob(const struct blob *v) NO_MSAN
1300afa8e06SEd Maste {
1310afa8e06SEd Maste 	return cbor_build_bytestring(v->body, v->len);
1320afa8e06SEd Maste }
1330afa8e06SEd Maste 
1340afa8e06SEd Maste void
mutate_byte(uint8_t * b)1350afa8e06SEd Maste mutate_byte(uint8_t *b)
1360afa8e06SEd Maste {
1370afa8e06SEd Maste 	LLVMFuzzerMutate(b, sizeof(*b), sizeof(*b));
1380afa8e06SEd Maste }
1390afa8e06SEd Maste 
1400afa8e06SEd Maste void
mutate_int(int * i)1410afa8e06SEd Maste mutate_int(int *i)
1420afa8e06SEd Maste {
1430afa8e06SEd Maste 	LLVMFuzzerMutate((uint8_t *)i, sizeof(*i), sizeof(*i));
1440afa8e06SEd Maste }
1450afa8e06SEd Maste 
1460afa8e06SEd Maste void
mutate_blob(struct blob * blob)1470afa8e06SEd Maste mutate_blob(struct blob *blob)
1480afa8e06SEd Maste {
1490afa8e06SEd Maste 	blob->len = LLVMFuzzerMutate((uint8_t *)blob->body, blob->len,
1500afa8e06SEd Maste 	    sizeof(blob->body));
1510afa8e06SEd Maste }
1520afa8e06SEd Maste 
1530afa8e06SEd Maste void
mutate_string(char * s)1540afa8e06SEd Maste mutate_string(char *s)
1550afa8e06SEd Maste {
1560afa8e06SEd Maste 	size_t n;
1570afa8e06SEd Maste 
1580afa8e06SEd Maste 	n = LLVMFuzzerMutate((uint8_t *)s, strlen(s), MAXSTR - 1);
1590afa8e06SEd Maste 	s[n] = '\0';
1600afa8e06SEd Maste }
1610afa8e06SEd Maste 
1620afa8e06SEd Maste static int
buf_read(unsigned char * ptr,size_t len,int ms)1630afa8e06SEd Maste buf_read(unsigned char *ptr, size_t len, int ms)
1640afa8e06SEd Maste {
1650afa8e06SEd Maste 	size_t n;
1660afa8e06SEd Maste 
1670afa8e06SEd Maste 	(void)ms;
1680afa8e06SEd Maste 
169*2ccfa855SEd Maste 	if (prng_up && uniform_random(400) < 1) {
170*2ccfa855SEd Maste 		errno = EIO;
171*2ccfa855SEd Maste 		return -1;
172*2ccfa855SEd Maste 	}
173*2ccfa855SEd Maste 
1740afa8e06SEd Maste 	if (wire_data_len < len)
1750afa8e06SEd Maste 		n = wire_data_len;
1760afa8e06SEd Maste 	else
1770afa8e06SEd Maste 		n = len;
1780afa8e06SEd Maste 
1790afa8e06SEd Maste 	memcpy(ptr, wire_data_ptr, n);
1800afa8e06SEd Maste 
1810afa8e06SEd Maste 	wire_data_ptr += n;
1820afa8e06SEd Maste 	wire_data_len -= n;
1830afa8e06SEd Maste 
1840afa8e06SEd Maste 	return (int)n;
1850afa8e06SEd Maste }
1860afa8e06SEd Maste 
1870afa8e06SEd Maste static int
buf_write(const unsigned char * ptr,size_t len)1880afa8e06SEd Maste buf_write(const unsigned char *ptr, size_t len)
1890afa8e06SEd Maste {
1900afa8e06SEd Maste 	consume(ptr, len);
1910afa8e06SEd Maste 
192*2ccfa855SEd Maste 	if (prng_up && uniform_random(400) < 1) {
1930afa8e06SEd Maste 		errno = EIO;
1940afa8e06SEd Maste 		return -1;
1950afa8e06SEd Maste 	}
1960afa8e06SEd Maste 
1970afa8e06SEd Maste 	return (int)len;
1980afa8e06SEd Maste }
1990afa8e06SEd Maste 
2000afa8e06SEd Maste static void *
hid_open(const char * path)2010afa8e06SEd Maste hid_open(const char *path)
2020afa8e06SEd Maste {
2030afa8e06SEd Maste 	(void)path;
2040afa8e06SEd Maste 
2050afa8e06SEd Maste 	return (void *)HID_DEV_HANDLE;
2060afa8e06SEd Maste }
2070afa8e06SEd Maste 
2080afa8e06SEd Maste static void
hid_close(void * handle)2090afa8e06SEd Maste hid_close(void *handle)
2100afa8e06SEd Maste {
2110afa8e06SEd Maste 	assert(handle == (void *)HID_DEV_HANDLE);
2120afa8e06SEd Maste }
2130afa8e06SEd Maste 
2140afa8e06SEd Maste static int
hid_read(void * handle,unsigned char * ptr,size_t len,int ms)2150afa8e06SEd Maste hid_read(void *handle, unsigned char *ptr, size_t len, int ms)
2160afa8e06SEd Maste {
2170afa8e06SEd Maste 	assert(handle == (void *)HID_DEV_HANDLE);
2180afa8e06SEd Maste 	assert(len >= CTAP_MIN_REPORT_LEN && len <= CTAP_MAX_REPORT_LEN);
2190afa8e06SEd Maste 
2200afa8e06SEd Maste 	return buf_read(ptr, len, ms);
2210afa8e06SEd Maste }
2220afa8e06SEd Maste 
2230afa8e06SEd Maste static int
hid_write(void * handle,const unsigned char * ptr,size_t len)2240afa8e06SEd Maste hid_write(void *handle, const unsigned char *ptr, size_t len)
2250afa8e06SEd Maste {
2260afa8e06SEd Maste 	assert(handle == (void *)HID_DEV_HANDLE);
2270afa8e06SEd Maste 	assert(len >= CTAP_MIN_REPORT_LEN + 1 &&
2280afa8e06SEd Maste 	    len <= CTAP_MAX_REPORT_LEN + 1);
2290afa8e06SEd Maste 
2300afa8e06SEd Maste 	return buf_write(ptr, len);
2310afa8e06SEd Maste }
2320afa8e06SEd Maste 
2330afa8e06SEd Maste static void *
nfc_open(const char * path)2340afa8e06SEd Maste nfc_open(const char *path)
2350afa8e06SEd Maste {
2360afa8e06SEd Maste 	(void)path;
2370afa8e06SEd Maste 
2380afa8e06SEd Maste 	return (void *)NFC_DEV_HANDLE;
2390afa8e06SEd Maste }
2400afa8e06SEd Maste 
2410afa8e06SEd Maste static void
nfc_close(void * handle)2420afa8e06SEd Maste nfc_close(void *handle)
2430afa8e06SEd Maste {
2440afa8e06SEd Maste 	assert(handle == (void *)NFC_DEV_HANDLE);
2450afa8e06SEd Maste }
2460afa8e06SEd Maste 
247*2ccfa855SEd Maste int
nfc_read(void * handle,unsigned char * ptr,size_t len,int ms)2480afa8e06SEd Maste nfc_read(void *handle, unsigned char *ptr, size_t len, int ms)
2490afa8e06SEd Maste {
2500afa8e06SEd Maste 	assert(handle == (void *)NFC_DEV_HANDLE);
251*2ccfa855SEd Maste 	assert(len > 0 && len <= 264);
2520afa8e06SEd Maste 
2530afa8e06SEd Maste 	return buf_read(ptr, len, ms);
2540afa8e06SEd Maste }
2550afa8e06SEd Maste 
256*2ccfa855SEd Maste int
nfc_write(void * handle,const unsigned char * ptr,size_t len)2570afa8e06SEd Maste nfc_write(void *handle, const unsigned char *ptr, size_t len)
2580afa8e06SEd Maste {
2590afa8e06SEd Maste 	assert(handle == (void *)NFC_DEV_HANDLE);
2600afa8e06SEd Maste 	assert(len > 0 && len <= 256 + 2);
2610afa8e06SEd Maste 
2620afa8e06SEd Maste 	return buf_write(ptr, len);
2630afa8e06SEd Maste }
2640afa8e06SEd Maste 
2650afa8e06SEd Maste ssize_t
fd_read(int fd,void * ptr,size_t len)2660afa8e06SEd Maste fd_read(int fd, void *ptr, size_t len)
2670afa8e06SEd Maste {
2680afa8e06SEd Maste 	assert(fd != -1);
2690afa8e06SEd Maste 
2700afa8e06SEd Maste 	return buf_read(ptr, len, -1);
2710afa8e06SEd Maste }
2720afa8e06SEd Maste 
2730afa8e06SEd Maste ssize_t
fd_write(int fd,const void * ptr,size_t len)2740afa8e06SEd Maste fd_write(int fd, const void *ptr, size_t len)
2750afa8e06SEd Maste {
2760afa8e06SEd Maste 	assert(fd != -1);
2770afa8e06SEd Maste 
2780afa8e06SEd Maste 	return buf_write(ptr, len);
2790afa8e06SEd Maste }
2800afa8e06SEd Maste 
2810afa8e06SEd Maste fido_dev_t *
open_dev(int nfc)2820afa8e06SEd Maste open_dev(int nfc)
2830afa8e06SEd Maste {
2840afa8e06SEd Maste 	fido_dev_t *dev;
2850afa8e06SEd Maste 	fido_dev_io_t io;
2860afa8e06SEd Maste 	fido_dev_transport_t t;
2870afa8e06SEd Maste 
2880afa8e06SEd Maste 	memset(&io, 0, sizeof(io));
2890afa8e06SEd Maste 	memset(&t, 0, sizeof(t));
2900afa8e06SEd Maste 
2910afa8e06SEd Maste 	if ((dev = fido_dev_new()) == NULL)
2920afa8e06SEd Maste 		return NULL;
2930afa8e06SEd Maste 
2940afa8e06SEd Maste 	if (nfc) {
2950afa8e06SEd Maste 		io.open = nfc_open;
2960afa8e06SEd Maste 		io.close = nfc_close;
2970afa8e06SEd Maste 		io.read = nfc_read;
2980afa8e06SEd Maste 		io.write = nfc_write;
2990afa8e06SEd Maste 	} else {
3000afa8e06SEd Maste 		io.open = hid_open;
3010afa8e06SEd Maste 		io.close = hid_close;
3020afa8e06SEd Maste 		io.read = hid_read;
3030afa8e06SEd Maste 		io.write = hid_write;
3040afa8e06SEd Maste 	}
3050afa8e06SEd Maste 
3060afa8e06SEd Maste 	if (fido_dev_set_io_functions(dev, &io) != FIDO_OK)
3070afa8e06SEd Maste 		goto fail;
3080afa8e06SEd Maste 
3090afa8e06SEd Maste 	if (nfc) {
3100afa8e06SEd Maste 		t.rx = fido_nfc_rx;
3110afa8e06SEd Maste 		t.tx = fido_nfc_tx;
3120afa8e06SEd Maste 		if (fido_dev_set_transport_functions(dev, &t) != FIDO_OK)
3130afa8e06SEd Maste 			goto fail;
3140afa8e06SEd Maste 	}
3150afa8e06SEd Maste 
316f540a430SEd Maste 	if (fido_dev_set_timeout(dev, 300) != FIDO_OK ||
317f540a430SEd Maste 	    fido_dev_open(dev, "nodev") != FIDO_OK)
3180afa8e06SEd Maste 		goto fail;
3190afa8e06SEd Maste 
3200afa8e06SEd Maste 	return dev;
3210afa8e06SEd Maste fail:
3220afa8e06SEd Maste 	fido_dev_free(&dev);
3230afa8e06SEd Maste 
3240afa8e06SEd Maste 	return NULL;
3250afa8e06SEd Maste }
3260afa8e06SEd Maste 
3270afa8e06SEd Maste void
set_wire_data(const uint8_t * ptr,size_t len)3280afa8e06SEd Maste set_wire_data(const uint8_t *ptr, size_t len)
3290afa8e06SEd Maste {
3300afa8e06SEd Maste 	wire_data_ptr = ptr;
3310afa8e06SEd Maste 	wire_data_len = len;
3320afa8e06SEd Maste }
333