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