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