1 /* 2 * Copyright (c) 2020 Yubico AB. All rights reserved. 3 * Use of this source code is governed by a BSD-style 4 * license that can be found in the LICENSE file. 5 */ 6 7 #include <assert.h> 8 #include <stdint.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <stdio.h> 12 13 #include "../openbsd-compat/openbsd-compat.h" 14 #include "mutator_aux.h" 15 16 extern int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *); 17 extern int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *); 18 19 struct param { 20 int seed; 21 struct blob report_descriptor; 22 }; 23 24 /* 25 * Sample HID report descriptor from the FIDO HID interface of a YubiKey 5. 26 */ 27 static const uint8_t dummy_report_descriptor[] = { 28 0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, 29 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 30 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 31 0x26, 0xff, 0x00, 0x75, 0x08, 0x95, 0x40, 0x91, 32 0x02, 0xc0 33 }; 34 35 struct param * 36 unpack(const uint8_t *ptr, size_t len) 37 { 38 cbor_item_t *item = NULL, **v; 39 struct cbor_load_result cbor; 40 struct param *p; 41 int ok = -1; 42 43 if ((p = calloc(1, sizeof(*p))) == NULL || 44 (item = cbor_load(ptr, len, &cbor)) == NULL || 45 cbor.read != len || 46 cbor_isa_array(item) == false || 47 cbor_array_is_definite(item) == false || 48 cbor_array_size(item) != 2 || 49 (v = cbor_array_handle(item)) == NULL) 50 goto fail; 51 52 if (unpack_int(v[0], &p->seed) < 0 || 53 unpack_blob(v[1], &p->report_descriptor) < 0) 54 goto fail; 55 56 ok = 0; 57 fail: 58 if (ok < 0) { 59 free(p); 60 p = NULL; 61 } 62 63 if (item) 64 cbor_decref(&item); 65 66 return p; 67 } 68 69 size_t 70 pack(uint8_t *ptr, size_t len, const struct param *p) 71 { 72 cbor_item_t *argv[2], *array = NULL; 73 size_t cbor_alloc_len, cbor_len = 0; 74 unsigned char *cbor = NULL; 75 76 memset(argv, 0, sizeof(argv)); 77 78 if ((array = cbor_new_definite_array(2)) == NULL || 79 (argv[0] = pack_int(p->seed)) == NULL || 80 (argv[1] = pack_blob(&p->report_descriptor)) == NULL) 81 goto fail; 82 83 for (size_t i = 0; i < 2; i++) 84 if (cbor_array_push(array, argv[i]) == false) 85 goto fail; 86 87 if ((cbor_len = cbor_serialize_alloc(array, &cbor, 88 &cbor_alloc_len)) > len) { 89 cbor_len = 0; 90 goto fail; 91 } 92 93 memcpy(ptr, cbor, cbor_len); 94 fail: 95 for (size_t i = 0; i < 2; i++) 96 if (argv[i]) 97 cbor_decref(&argv[i]); 98 99 if (array) 100 cbor_decref(&array); 101 102 free(cbor); 103 104 return cbor_len; 105 } 106 107 size_t 108 pack_dummy(uint8_t *ptr, size_t len) 109 { 110 struct param dummy; 111 uint8_t blob[4096]; 112 size_t blob_len; 113 114 memset(&dummy, 0, sizeof(dummy)); 115 116 dummy.report_descriptor.len = sizeof(dummy_report_descriptor); 117 memcpy(&dummy.report_descriptor.body, &dummy_report_descriptor, 118 dummy.report_descriptor.len); 119 120 assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0); 121 122 if (blob_len > len) { 123 memcpy(ptr, blob, len); 124 return len; 125 } 126 127 memcpy(ptr, blob, blob_len); 128 129 return blob_len; 130 } 131 132 static void 133 get_usage(const struct param *p) 134 { 135 uint32_t usage_page = 0; 136 137 fido_hid_get_usage(p->report_descriptor.body, p->report_descriptor.len, 138 &usage_page); 139 consume(&usage_page, sizeof(usage_page)); 140 } 141 142 static void 143 get_report_len(const struct param *p) 144 { 145 size_t report_in_len = 0; 146 size_t report_out_len = 0; 147 148 fido_hid_get_report_len(p->report_descriptor.body, 149 p->report_descriptor.len, &report_in_len, &report_out_len); 150 consume(&report_in_len, sizeof(report_in_len)); 151 consume(&report_out_len, sizeof(report_out_len)); 152 } 153 154 void 155 test(const struct param *p) 156 { 157 prng_init((unsigned int)p->seed); 158 fido_init(FIDO_DEBUG); 159 fido_set_log_handler(consume_str); 160 161 get_usage(p); 162 get_report_len(p); 163 } 164 165 void 166 mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN 167 { 168 if (flags & MUTATE_SEED) 169 p->seed = (int)seed; 170 171 if (flags & MUTATE_PARAM) 172 mutate_blob(&p->report_descriptor); 173 } 174