Path: blob/main/contrib/libfido2/fuzz/mutator_aux.c
39586 views
/*1* Copyright (c) 2019-2022 Yubico AB. All rights reserved.2* Use of this source code is governed by a BSD-style3* license that can be found in the LICENSE file.4* SPDX-License-Identifier: BSD-2-Clause5*/67#include <assert.h>8#include <cbor.h>9#include <errno.h>10#include <stddef.h>11#include <stdint.h>12#include <stdio.h>13#include <stdlib.h>14#include <string.h>1516#include "mutator_aux.h"1718int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);19int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);20size_t LLVMFuzzerMutate(uint8_t *, size_t, size_t);2122extern int prng_up;23static const uint8_t *wire_data_ptr = NULL;24static size_t wire_data_len = 0;2526void27consume(const void *body, size_t len)28{29const volatile uint8_t *ptr = body;30volatile uint8_t x = 0;3132#ifdef WITH_MSAN33__msan_check_mem_is_initialized(body, len);34#endif3536while (len--)37x ^= *ptr++;3839(void)x;40}4142void43consume_str(const char *str)44{45if (str != NULL)46consume(str, strlen(str) + 1);47}4849int50unpack_int(cbor_item_t *item, int *v)51{52if (cbor_is_int(item) == false ||53cbor_int_get_width(item) != CBOR_INT_64)54return -1;5556if (cbor_isa_uint(item))57*v = (int)cbor_get_uint64(item);58else59*v = (int)(-cbor_get_uint64(item) - 1);6061return 0;62}6364int65unpack_string(cbor_item_t *item, char *v)66{67size_t len;6869if (cbor_isa_bytestring(item) == false ||70(len = cbor_bytestring_length(item)) >= MAXSTR)71return -1;7273memcpy(v, cbor_bytestring_handle(item), len);74v[len] = '\0';7576return 0;77}7879int80unpack_byte(cbor_item_t *item, uint8_t *v)81{82if (cbor_isa_uint(item) == false ||83cbor_int_get_width(item) != CBOR_INT_8)84return -1;8586*v = cbor_get_uint8(item);8788return 0;89}9091int92unpack_blob(cbor_item_t *item, struct blob *v)93{94if (cbor_isa_bytestring(item) == false ||95(v->len = cbor_bytestring_length(item)) > sizeof(v->body))96return -1;9798memcpy(v->body, cbor_bytestring_handle(item), v->len);99100return 0;101}102103cbor_item_t *104pack_int(int v) NO_MSAN105{106if (v < 0)107return cbor_build_negint64((uint64_t)(-(int64_t)v - 1));108else109return cbor_build_uint64((uint64_t)v);110}111112cbor_item_t *113pack_string(const char *v) NO_MSAN114{115if (strlen(v) >= MAXSTR)116return NULL;117118return cbor_build_bytestring((const unsigned char *)v, strlen(v));119}120121cbor_item_t *122pack_byte(uint8_t v) NO_MSAN123{124return cbor_build_uint8(v);125}126127cbor_item_t *128pack_blob(const struct blob *v) NO_MSAN129{130return cbor_build_bytestring(v->body, v->len);131}132133void134mutate_byte(uint8_t *b)135{136LLVMFuzzerMutate(b, sizeof(*b), sizeof(*b));137}138139void140mutate_int(int *i)141{142LLVMFuzzerMutate((uint8_t *)i, sizeof(*i), sizeof(*i));143}144145void146mutate_blob(struct blob *blob)147{148blob->len = LLVMFuzzerMutate((uint8_t *)blob->body, blob->len,149sizeof(blob->body));150}151152void153mutate_string(char *s)154{155size_t n;156157n = LLVMFuzzerMutate((uint8_t *)s, strlen(s), MAXSTR - 1);158s[n] = '\0';159}160161static int162buf_read(unsigned char *ptr, size_t len, int ms)163{164size_t n;165166(void)ms;167168if (prng_up && uniform_random(400) < 1) {169errno = EIO;170return -1;171}172173if (wire_data_len < len)174n = wire_data_len;175else176n = len;177178memcpy(ptr, wire_data_ptr, n);179180wire_data_ptr += n;181wire_data_len -= n;182183return (int)n;184}185186static int187buf_write(const unsigned char *ptr, size_t len)188{189consume(ptr, len);190191if (prng_up && uniform_random(400) < 1) {192errno = EIO;193return -1;194}195196return (int)len;197}198199static void *200hid_open(const char *path)201{202(void)path;203204return (void *)HID_DEV_HANDLE;205}206207static void208hid_close(void *handle)209{210assert(handle == (void *)HID_DEV_HANDLE);211}212213static int214hid_read(void *handle, unsigned char *ptr, size_t len, int ms)215{216assert(handle == (void *)HID_DEV_HANDLE);217assert(len >= CTAP_MIN_REPORT_LEN && len <= CTAP_MAX_REPORT_LEN);218219return buf_read(ptr, len, ms);220}221222static int223hid_write(void *handle, const unsigned char *ptr, size_t len)224{225assert(handle == (void *)HID_DEV_HANDLE);226assert(len >= CTAP_MIN_REPORT_LEN + 1 &&227len <= CTAP_MAX_REPORT_LEN + 1);228229return buf_write(ptr, len);230}231232static void *233nfc_open(const char *path)234{235(void)path;236237return (void *)NFC_DEV_HANDLE;238}239240static void241nfc_close(void *handle)242{243assert(handle == (void *)NFC_DEV_HANDLE);244}245246int247nfc_read(void *handle, unsigned char *ptr, size_t len, int ms)248{249assert(handle == (void *)NFC_DEV_HANDLE);250assert(len > 0 && len <= 264);251252return buf_read(ptr, len, ms);253}254255int256nfc_write(void *handle, const unsigned char *ptr, size_t len)257{258assert(handle == (void *)NFC_DEV_HANDLE);259assert(len > 0 && len <= 256 + 2);260261return buf_write(ptr, len);262}263264ssize_t265fd_read(int fd, void *ptr, size_t len)266{267assert(fd != -1);268269return buf_read(ptr, len, -1);270}271272ssize_t273fd_write(int fd, const void *ptr, size_t len)274{275assert(fd != -1);276277return buf_write(ptr, len);278}279280fido_dev_t *281open_dev(int nfc)282{283fido_dev_t *dev;284fido_dev_io_t io;285fido_dev_transport_t t;286287memset(&io, 0, sizeof(io));288memset(&t, 0, sizeof(t));289290if ((dev = fido_dev_new()) == NULL)291return NULL;292293if (nfc) {294io.open = nfc_open;295io.close = nfc_close;296io.read = nfc_read;297io.write = nfc_write;298} else {299io.open = hid_open;300io.close = hid_close;301io.read = hid_read;302io.write = hid_write;303}304305if (fido_dev_set_io_functions(dev, &io) != FIDO_OK)306goto fail;307308if (nfc) {309t.rx = fido_nfc_rx;310t.tx = fido_nfc_tx;311if (fido_dev_set_transport_functions(dev, &t) != FIDO_OK)312goto fail;313}314315if (fido_dev_set_timeout(dev, 300) != FIDO_OK ||316fido_dev_open(dev, "nodev") != FIDO_OK)317goto fail;318319return dev;320fail:321fido_dev_free(&dev);322323return NULL;324}325326void327set_wire_data(const uint8_t *ptr, size_t len)328{329wire_data_ptr = ptr;330wire_data_len = len;331}332333334