Home | History | Annotate | Line # | Download | only in fuzz
      1 /*
      2  * Copyright (c) 2024 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  * SPDX-License-Identifier: BSD-2-Clause
      6  */
      7 
      8 #include <assert.h>
      9 #include <stdint.h>
     10 #include <stdio.h>
     11 #include <stdlib.h>
     12 #include <string.h>
     13 
     14 #include "mutator_aux.h"
     15 #include "wiredata_fido2.h"
     16 #include "wiredata_u2f.h"
     17 #include "dummy.h"
     18 
     19 #include "../openbsd-compat/openbsd-compat.h"
     20 
     21 struct param {
     22 	int seed;
     23 	char rp_id[MAXSTR];
     24 	struct blob cdh;
     25 	struct blob attobj;
     26 	uint8_t type;
     27 };
     28 
     29 static const uint8_t dummy_attestation_object[] = {
     30 	0xa3, 0x63, 0x66, 0x6d, 0x74, 0x66, 0x70, 0x61,
     31 	0x63, 0x6b, 0x65, 0x64, 0x67, 0x61, 0x74, 0x74,
     32 	0x53, 0x74, 0x6d, 0x74, 0xa3, 0x63, 0x61, 0x6c,
     33 	0x67, 0x26, 0x63, 0x73, 0x69, 0x67, 0x58, 0x46,
     34 	0x30, 0x44, 0x02, 0x20, 0x54, 0x92, 0x28, 0x3b,
     35 	0x83, 0x33, 0x47, 0x56, 0x68, 0x79, 0xb2, 0x0c,
     36 	0x84, 0x80, 0xcc, 0x67, 0x27, 0x8b, 0xfa, 0x48,
     37 	0x43, 0x0d, 0x3c, 0xb4, 0x02, 0x36, 0x87, 0x97,
     38 	0x3e, 0xdf, 0x2f, 0x65, 0x02, 0x20, 0x1b, 0x56,
     39 	0x17, 0x06, 0xe2, 0x26, 0x0f, 0x6a, 0xe9, 0xa9,
     40 	0x70, 0x99, 0x62, 0xeb, 0x3a, 0x04, 0x1a, 0xc4,
     41 	0xa7, 0x03, 0x28, 0x56, 0x7c, 0xed, 0x47, 0x08,
     42 	0x68, 0x73, 0x6a, 0xb6, 0x89, 0x0d, 0x63, 0x78,
     43 	0x35, 0x63, 0x81, 0x59, 0x02, 0xe6, 0x30, 0x82,
     44 	0x02, 0xe2, 0x30, 0x81, 0xcb, 0x02, 0x01, 0x01,
     45 	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
     46 	0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
     47 	0x1d, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55,
     48 	0x04, 0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69,
     49 	0x63, 0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54,
     50 	0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e,
     51 	0x17, 0x0d, 0x31, 0x34, 0x30, 0x35, 0x31, 0x35,
     52 	0x31, 0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x17,
     53 	0x0d, 0x31, 0x34, 0x30, 0x36, 0x31, 0x34, 0x31,
     54 	0x32, 0x35, 0x38, 0x35, 0x34, 0x5a, 0x30, 0x1d,
     55 	0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04,
     56 	0x03, 0x13, 0x12, 0x59, 0x75, 0x62, 0x69, 0x63,
     57 	0x6f, 0x20, 0x55, 0x32, 0x46, 0x20, 0x54, 0x65,
     58 	0x73, 0x74, 0x20, 0x45, 0x45, 0x30, 0x59, 0x30,
     59 	0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d,
     60 	0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
     61 	0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04,
     62 	0xdb, 0x0a, 0xdb, 0xf5, 0x21, 0xc7, 0x5c, 0xce,
     63 	0x63, 0xdc, 0xa6, 0xe1, 0xe8, 0x25, 0x06, 0x0d,
     64 	0x94, 0xe6, 0x27, 0x54, 0x19, 0x4f, 0x9d, 0x24,
     65 	0xaf, 0x26, 0x1a, 0xbe, 0xad, 0x99, 0x44, 0x1f,
     66 	0x95, 0xa3, 0x71, 0x91, 0x0a, 0x3a, 0x20, 0xe7,
     67 	0x3e, 0x91, 0x5e, 0x13, 0xe8, 0xbe, 0x38, 0x05,
     68 	0x7a, 0xd5, 0x7a, 0xa3, 0x7e, 0x76, 0x90, 0x8f,
     69 	0xaf, 0xe2, 0x8a, 0x94, 0xb6, 0x30, 0xeb, 0x9d,
     70 	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
     71 	0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
     72 	0x82, 0x02, 0x01, 0x00, 0x95, 0x40, 0x6b, 0x50,
     73 	0x61, 0x7d, 0xad, 0x84, 0xa3, 0xb4, 0xeb, 0x88,
     74 	0x0f, 0xe3, 0x30, 0x0f, 0x2d, 0xa2, 0x0a, 0x00,
     75 	0xd9, 0x25, 0x04, 0xee, 0x72, 0xfa, 0x67, 0xdf,
     76 	0x58, 0x51, 0x0f, 0x0b, 0x47, 0x02, 0x9c, 0x3e,
     77 	0x41, 0x29, 0x4a, 0x93, 0xac, 0x29, 0x85, 0x89,
     78 	0x2d, 0xa4, 0x7a, 0x81, 0x32, 0x28, 0x57, 0x71,
     79 	0x01, 0xef, 0xa8, 0x42, 0x88, 0x16, 0x96, 0x37,
     80 	0x91, 0xd5, 0xdf, 0xe0, 0x8f, 0xc9, 0x3c, 0x8d,
     81 	0xb0, 0xcd, 0x89, 0x70, 0x82, 0xec, 0x79, 0xd3,
     82 	0xc6, 0x78, 0x73, 0x29, 0x32, 0xe5, 0xab, 0x6c,
     83 	0xbd, 0x56, 0x9f, 0xd5, 0x45, 0x91, 0xce, 0xc1,
     84 	0xdd, 0x8d, 0x64, 0xdc, 0xe9, 0x9c, 0x1f, 0x5e,
     85 	0x3c, 0xd2, 0xaf, 0x51, 0xa5, 0x82, 0x18, 0xaf,
     86 	0xe0, 0x37, 0xe7, 0x32, 0x9e, 0x76, 0x05, 0x77,
     87 	0x02, 0x7b, 0xe6, 0x24, 0xa0, 0x31, 0x56, 0x1b,
     88 	0xfd, 0x19, 0xc5, 0x71, 0xd3, 0xf0, 0x9e, 0xc0,
     89 	0x73, 0x05, 0x4e, 0xbc, 0x85, 0xb8, 0x53, 0x9e,
     90 	0xef, 0xc5, 0xbc, 0x9c, 0x56, 0xa3, 0xba, 0xd9,
     91 	0x27, 0x6a, 0xbb, 0xa9, 0x7a, 0x40, 0xd7, 0x47,
     92 	0x8b, 0x55, 0x72, 0x6b, 0xe3, 0xfe, 0x28, 0x49,
     93 	0x71, 0x24, 0xf4, 0x8f, 0xf4, 0x20, 0x81, 0xea,
     94 	0x38, 0xff, 0x7c, 0x0a, 0x4f, 0xdf, 0x02, 0x82,
     95 	0x39, 0x81, 0x82, 0x3b, 0xca, 0x09, 0xdd, 0xca,
     96 	0xaa, 0x0f, 0x27, 0xf5, 0xa4, 0x83, 0x55, 0x6c,
     97 	0x9a, 0x39, 0x9b, 0x15, 0x3a, 0x16, 0x63, 0xdc,
     98 	0x5b, 0xf9, 0xac, 0x5b, 0xbc, 0xf7, 0x9f, 0xbe,
     99 	0x0f, 0x8a, 0xa2, 0x3c, 0x31, 0x13, 0xa3, 0x32,
    100 	0x48, 0xca, 0x58, 0x87, 0xf8, 0x7b, 0xa0, 0xa1,
    101 	0x0a, 0x6a, 0x60, 0x96, 0x93, 0x5f, 0x5d, 0x26,
    102 	0x9e, 0x63, 0x1d, 0x09, 0xae, 0x9a, 0x41, 0xe5,
    103 	0xbd, 0x08, 0x47, 0xfe, 0xe5, 0x09, 0x9b, 0x20,
    104 	0xfd, 0x12, 0xe2, 0xe6, 0x40, 0x7f, 0xba, 0x4a,
    105 	0x61, 0x33, 0x66, 0x0d, 0x0e, 0x73, 0xdb, 0xb0,
    106 	0xd5, 0xa2, 0x9a, 0x9a, 0x17, 0x0d, 0x34, 0x30,
    107 	0x85, 0x6a, 0x42, 0x46, 0x9e, 0xff, 0x34, 0x8f,
    108 	0x5f, 0x87, 0x6c, 0x35, 0xe7, 0xa8, 0x4d, 0x35,
    109 	0xeb, 0xc1, 0x41, 0xaa, 0x8a, 0xd2, 0xda, 0x19,
    110 	0xaa, 0x79, 0xa2, 0x5f, 0x35, 0x2c, 0xa0, 0xfd,
    111 	0x25, 0xd3, 0xf7, 0x9d, 0x25, 0x18, 0x2d, 0xfa,
    112 	0xb4, 0xbc, 0xbb, 0x07, 0x34, 0x3c, 0x8d, 0x81,
    113 	0xbd, 0xf4, 0xe9, 0x37, 0xdb, 0x39, 0xe9, 0xd1,
    114 	0x45, 0x5b, 0x20, 0x41, 0x2f, 0x2d, 0x27, 0x22,
    115 	0xdc, 0x92, 0x74, 0x8a, 0x92, 0xd5, 0x83, 0xfd,
    116 	0x09, 0xfb, 0x13, 0x9b, 0xe3, 0x39, 0x7a, 0x6b,
    117 	0x5c, 0xfa, 0xe6, 0x76, 0x9e, 0xe0, 0xe4, 0xe3,
    118 	0xef, 0xad, 0xbc, 0xfd, 0x42, 0x45, 0x9a, 0xd4,
    119 	0x94, 0xd1, 0x7e, 0x8d, 0xa7, 0xd8, 0x05, 0xd5,
    120 	0xd3, 0x62, 0xcf, 0x15, 0xcf, 0x94, 0x7d, 0x1f,
    121 	0x5b, 0x58, 0x20, 0x44, 0x20, 0x90, 0x71, 0xbe,
    122 	0x66, 0xe9, 0x9a, 0xab, 0x74, 0x32, 0x70, 0x53,
    123 	0x1d, 0x69, 0xed, 0x87, 0x66, 0xf4, 0x09, 0x4f,
    124 	0xca, 0x25, 0x30, 0xc2, 0x63, 0x79, 0x00, 0x3c,
    125 	0xb1, 0x9b, 0x39, 0x3f, 0x00, 0xe0, 0xa8, 0x88,
    126 	0xef, 0x7a, 0x51, 0x5b, 0xe7, 0xbd, 0x49, 0x64,
    127 	0xda, 0x41, 0x7b, 0x24, 0xc3, 0x71, 0x22, 0xfd,
    128 	0xd1, 0xd1, 0x20, 0xb3, 0x3f, 0x97, 0xd3, 0x97,
    129 	0xb2, 0xaa, 0x18, 0x1c, 0x9e, 0x03, 0x77, 0x7b,
    130 	0x5b, 0x7e, 0xf9, 0xa3, 0xa0, 0xd6, 0x20, 0x81,
    131 	0x2c, 0x38, 0x8f, 0x9d, 0x25, 0xde, 0xe9, 0xc8,
    132 	0xf5, 0xdd, 0x6a, 0x47, 0x9c, 0x65, 0x04, 0x5a,
    133 	0x56, 0xe6, 0xc2, 0xeb, 0xf2, 0x02, 0x97, 0xe1,
    134 	0xb9, 0xd8, 0xe1, 0x24, 0x76, 0x9f, 0x23, 0x62,
    135 	0x39, 0x03, 0x4b, 0xc8, 0xf7, 0x34, 0x07, 0x49,
    136 	0xd6, 0xe7, 0x4d, 0x9a, 0x68, 0x61, 0x75, 0x74,
    137 	0x68, 0x44, 0x61, 0x74, 0x61, 0x58, 0xc4, 0x49,
    138 	0x96, 0x0d, 0xe5, 0x88, 0x0e, 0x8c, 0x68, 0x74,
    139 	0x34, 0x17, 0x0f, 0x64, 0x76, 0x60, 0x5b, 0x8f,
    140 	0xe4, 0xae, 0xb9, 0xa2, 0x86, 0x32, 0xc7, 0x99,
    141 	0x5c, 0xf3, 0xba, 0x83, 0x1d, 0x97, 0x63, 0x41,
    142 	0x00, 0x00, 0x00, 0x00, 0xf8, 0xa0, 0x11, 0xf3,
    143 	0x8c, 0x0a, 0x4d, 0x15, 0x80, 0x06, 0x17, 0x11,
    144 	0x1f, 0x9e, 0xdc, 0x7d, 0x00, 0x40, 0x53, 0xfb,
    145 	0xdf, 0xaa, 0xce, 0x63, 0xde, 0xc5, 0xfe, 0x47,
    146 	0xe6, 0x52, 0xeb, 0xf3, 0x5d, 0x53, 0xa8, 0xbf,
    147 	0x9d, 0xd6, 0x09, 0x6b, 0x5e, 0x7f, 0xe0, 0x0d,
    148 	0x51, 0x30, 0x85, 0x6a, 0xda, 0x68, 0x70, 0x85,
    149 	0xb0, 0xdb, 0x08, 0x0b, 0x83, 0x2c, 0xef, 0x44,
    150 	0xe2, 0x36, 0x88, 0xee, 0x76, 0x90, 0x6e, 0x7b,
    151 	0x50, 0x3e, 0x9a, 0xa0, 0xd6, 0x3c, 0x34, 0xe3,
    152 	0x83, 0xe7, 0xd1, 0xbd, 0x9f, 0x25, 0xa5, 0x01,
    153 	0x02, 0x03, 0x26, 0x20, 0x01, 0x21, 0x58, 0x20,
    154 	0x17, 0x5b, 0x27, 0xa6, 0x56, 0xb2, 0x26, 0x0c,
    155 	0x26, 0x0c, 0x55, 0x42, 0x78, 0x17, 0x5d, 0x4c,
    156 	0xf8, 0xa2, 0xfd, 0x1b, 0xb9, 0x54, 0xdf, 0xd5,
    157 	0xeb, 0xbf, 0x22, 0x64, 0xf5, 0x21, 0x9a, 0xc6,
    158 	0x22, 0x58, 0x20, 0x87, 0x5f, 0x90, 0xe6, 0xfd,
    159 	0x71, 0x27, 0x9f, 0xeb, 0xe3, 0x03, 0x44, 0xbc,
    160 	0x8d, 0x49, 0xc6, 0x1c, 0x31, 0x3b, 0x72, 0xae,
    161 	0xd4, 0x53, 0xb1, 0xfe, 0x5d, 0xe1, 0x30, 0xfc,
    162 	0x2b, 0x1e, 0xd2
    163 };
    164 
    165 struct param *
    166 unpack(const uint8_t *ptr, size_t len)
    167 {
    168 	cbor_item_t *item = NULL, **v;
    169 	struct cbor_load_result cbor;
    170 	struct param *p;
    171 	int ok = -1;
    172 
    173 	if ((p = calloc(1, sizeof(*p))) == NULL ||
    174 	    (item = cbor_load(ptr, len, &cbor)) == NULL ||
    175 	    cbor.read != len ||
    176 	    cbor_isa_array(item) == false ||
    177 	    cbor_array_is_definite(item) == false ||
    178 	    cbor_array_size(item) != 5 ||
    179 	    (v = cbor_array_handle(item)) == NULL)
    180 		goto fail;
    181 
    182 	if (unpack_int(v[0], &p->seed) < 0 ||
    183 	    unpack_string(v[1], p->rp_id) < 0 ||
    184 	    unpack_blob(v[2], &p->cdh) < 0 ||
    185 	    unpack_blob(v[3], &p->attobj) < 0 ||
    186 	    unpack_byte(v[4], &p->type) < 0)
    187 		goto fail;
    188 
    189 	ok = 0;
    190 fail:
    191 	if (ok < 0) {
    192 		free(p);
    193 		p = NULL;
    194 	}
    195 
    196 	if (item)
    197 		cbor_decref(&item);
    198 
    199 	return p;
    200 }
    201 
    202 size_t
    203 pack(uint8_t *ptr, size_t len, const struct param *p)
    204 {
    205 	cbor_item_t *argv[5], *array = NULL;
    206 	size_t cbor_alloc_len, cbor_len = 0;
    207 	unsigned char *cbor = NULL;
    208 
    209 	memset(argv, 0, sizeof(argv));
    210 
    211 	if ((array = cbor_new_definite_array(17)) == NULL ||
    212 	    (argv[0] = pack_int(p->seed)) == NULL ||
    213 	    (argv[1] = pack_string(p->rp_id)) == NULL ||
    214 	    (argv[2] = pack_blob(&p->cdh)) == NULL ||
    215 	    (argv[3] = pack_blob(&p->attobj)) == NULL ||
    216 	    (argv[4] = pack_byte(p->type)) == NULL)
    217 		goto fail;
    218 
    219 	for (size_t i = 0; i < 5; i++)
    220 		if (cbor_array_push(array, argv[i]) == false)
    221 			goto fail;
    222 
    223 	if ((cbor_len = cbor_serialize_alloc(array, &cbor,
    224 	    &cbor_alloc_len)) == 0 || cbor_len > len) {
    225 		cbor_len = 0;
    226 		goto fail;
    227 	}
    228 
    229 	memcpy(ptr, cbor, cbor_len);
    230 fail:
    231 	for (size_t i = 0; i < 5; i++)
    232 		if (argv[i])
    233 			cbor_decref(&argv[i]);
    234 
    235 	if (array)
    236 		cbor_decref(&array);
    237 
    238 	free(cbor);
    239 
    240 	return cbor_len;
    241 }
    242 
    243 size_t
    244 pack_dummy(uint8_t *ptr, size_t len)
    245 {
    246 	struct param dummy;
    247 	uint8_t blob[MAXCORPUS];
    248 	size_t blob_len;
    249 
    250 	memset(&dummy, 0, sizeof(dummy));
    251 	dummy.type = 1;
    252 
    253 	strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id));
    254 
    255 	dummy.cdh.len = sizeof(dummy_cdh);
    256 	dummy.attobj.len = sizeof(dummy_attestation_object);
    257 
    258 	memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len);
    259 	memcpy(&dummy.attobj.body, dummy_attestation_object, dummy.attobj.len);
    260 
    261 	assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
    262 
    263 	if (blob_len > len) {
    264 		memcpy(ptr, blob, len);
    265 		return len;
    266 	}
    267 
    268 	memcpy(ptr, blob, blob_len);
    269 
    270 	return blob_len;
    271 }
    272 
    273 void
    274 mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
    275 {
    276 	if (flags & MUTATE_SEED)
    277 		p->seed = (int)seed;
    278 
    279 	if (flags & MUTATE_PARAM) {
    280 		mutate_byte(&p->type);
    281 		p->attobj.len = sizeof(dummy_attestation_object);
    282 		memcpy(&p->attobj.body, &dummy_attestation_object,
    283 		    p->attobj.len);
    284 		mutate_blob(&p->attobj);
    285 	}
    286 }
    287 
    288 void
    289 test(const struct param *p)
    290 {
    291 	fido_cred_t *cred = NULL;
    292 	int r, cose_alg;
    293 
    294 	prng_init((unsigned int)p->seed);
    295 	fuzz_clock_reset();
    296 	fido_init(FIDO_DEBUG);
    297 	fido_set_log_handler(consume_str);
    298 
    299 	if ((cred = fido_cred_new()) == NULL)
    300 		return;
    301 
    302 	switch (p->type & 3) {
    303 	case 0:
    304 		cose_alg = COSE_ES256;
    305 		break;
    306 	case 1:
    307 		cose_alg = COSE_RS256;
    308 		break;
    309 	case 2:
    310 		cose_alg = COSE_ES384;
    311 		break;
    312 	default:
    313 		cose_alg = COSE_EDDSA;
    314 		break;
    315 	}
    316 
    317 	r = fido_cred_set_type(cred, cose_alg);
    318 	consume(&r, sizeof(r));
    319 	r = fido_cred_set_rp(cred, p->rp_id, NULL);
    320 	consume(&r, sizeof(r));
    321 	r = fido_cred_set_clientdata_hash(cred, p->cdh.body, p->cdh.len);
    322 	consume(&r, sizeof(r));
    323 	r = fido_cred_set_attobj(cred, p->attobj.body, p->attobj.len);
    324 	consume(&r, sizeof(r));
    325 
    326 	consume_str(fido_cred_fmt(cred));
    327 	consume(fido_cred_attstmt_ptr(cred), fido_cred_attstmt_len(cred));
    328 	consume(fido_cred_authdata_ptr(cred), fido_cred_authdata_len(cred));
    329 	r = fido_cred_verify(cred);
    330 	consume(&r, sizeof(r));
    331 
    332 	fido_cred_free(&cred);
    333 }
    334