summaryrefslogtreecommitdiff
path: root/fuzz/fuzz_assert.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2020-09-20 16:14:20 +0100
committerColin Watson <cjwatson@debian.org>2020-09-20 16:14:20 +0100
commit173bfbf7886608a4a7abbfac6a42ac4bf4a3432d (patch)
treeb97833d8754f257f92d99dd2f5c9e9d557e3f689 /fuzz/fuzz_assert.c
parent75073d0a8478441cc97a6efa10b566c5fb1dac81 (diff)
New upstream version 1.5.0
Diffstat (limited to 'fuzz/fuzz_assert.c')
-rw-r--r--fuzz/fuzz_assert.c455
1 files changed, 236 insertions, 219 deletions
diff --git a/fuzz/fuzz_assert.c b/fuzz/fuzz_assert.c
index 5b72658..3ae54eb 100644
--- a/fuzz/fuzz_assert.c
+++ b/fuzz/fuzz_assert.c
@@ -23,39 +23,23 @@
23 23
24#include "../openbsd-compat/openbsd-compat.h" 24#include "../openbsd-compat/openbsd-compat.h"
25 25
26#define TAG_U2F 0x01
27#define TAG_TYPE 0x02
28#define TAG_CDH 0x03
29#define TAG_RP_ID 0x04
30#define TAG_EXT 0x05
31#define TAG_SEED 0x06
32#define TAG_UP 0x07
33#define TAG_UV 0x08
34#define TAG_WIRE_DATA 0x09
35#define TAG_CRED_COUNT 0x0a
36#define TAG_CRED 0x0b
37#define TAG_ES256 0x0c
38#define TAG_RS256 0x0d
39#define TAG_PIN 0x0e
40#define TAG_EDDSA 0x0f
41
42/* Parameter set defining a FIDO2 get assertion operation. */ 26/* Parameter set defining a FIDO2 get assertion operation. */
43struct param { 27struct param {
44 char pin[MAXSTR]; 28 char pin[MAXSTR];
45 char rp_id[MAXSTR]; 29 char rp_id[MAXSTR];
46 int ext; 30 int ext;
47 int seed; 31 int seed;
48 struct blob cdh; 32 struct blob cdh;
49 struct blob cred; 33 struct blob cred;
50 struct blob es256; 34 struct blob es256;
51 struct blob rs256; 35 struct blob rs256;
52 struct blob eddsa; 36 struct blob eddsa;
53 struct blob wire_data; 37 struct blob wire_data;
54 uint8_t cred_count; 38 uint8_t cred_count;
55 uint8_t type; 39 uint8_t type;
56 uint8_t u2f; 40 uint8_t u2f;
57 uint8_t up; 41 uint8_t up;
58 uint8_t uv; 42 uint8_t uv;
59}; 43};
60 44
61/* 45/*
@@ -83,73 +67,153 @@ static const uint8_t dummy_wire_data_u2f[] = {
83 WIREDATA_CTAP_U2F_AUTH, 67 WIREDATA_CTAP_U2F_AUTH,
84}; 68};
85 69
86int LLVMFuzzerTestOneInput(const uint8_t *, size_t); 70struct param *
87size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); 71unpack(const uint8_t *ptr, size_t len)
88
89static int
90unpack(const uint8_t *ptr, size_t len, struct param *p) NO_MSAN
91{ 72{
92 uint8_t **pp = (void *)&ptr; 73 cbor_item_t *item = NULL, **v;
93 74 struct cbor_load_result cbor;
94 if (unpack_byte(TAG_UV, pp, &len, &p->uv) < 0 || 75 struct param *p;
95 unpack_byte(TAG_UP, pp, &len, &p->up) < 0 || 76 int ok = -1;
96 unpack_byte(TAG_U2F, pp, &len, &p->u2f) < 0 || 77
97 unpack_byte(TAG_TYPE, pp, &len, &p->type) < 0 || 78 if ((p = calloc(1, sizeof(*p))) == NULL ||
98 unpack_byte(TAG_CRED_COUNT, pp, &len, &p->cred_count) < 0 || 79 (item = cbor_load(ptr, len, &cbor)) == NULL ||
99 unpack_int(TAG_EXT, pp, &len, &p->ext) < 0 || 80 cbor.read != len ||
100 unpack_int(TAG_SEED, pp, &len, &p->seed) < 0 || 81 cbor_isa_array(item) == false ||
101 unpack_string(TAG_RP_ID, pp, &len, p->rp_id) < 0 || 82 cbor_array_is_definite(item) == false ||
102 unpack_string(TAG_PIN, pp, &len, p->pin) < 0 || 83 cbor_array_size(item) != 15 ||
103 unpack_blob(TAG_WIRE_DATA, pp, &len, &p->wire_data) < 0 || 84 (v = cbor_array_handle(item)) == NULL)
104 unpack_blob(TAG_RS256, pp, &len, &p->rs256) < 0 || 85 goto fail;
105 unpack_blob(TAG_ES256, pp, &len, &p->es256) < 0 || 86
106 unpack_blob(TAG_EDDSA, pp, &len, &p->eddsa) < 0 || 87 if (unpack_byte(v[0], &p->uv) < 0 ||
107 unpack_blob(TAG_CRED, pp, &len, &p->cred) < 0 || 88 unpack_byte(v[1], &p->up) < 0 ||
108 unpack_blob(TAG_CDH, pp, &len, &p->cdh) < 0) 89 unpack_byte(v[2], &p->u2f) < 0 ||
109 return (-1); 90 unpack_byte(v[3], &p->type) < 0 ||
110 91 unpack_byte(v[4], &p->cred_count) < 0 ||
111 return (0); 92 unpack_int(v[5], &p->ext) < 0 ||
93 unpack_int(v[6], &p->seed) < 0 ||
94 unpack_string(v[7], p->rp_id) < 0 ||
95 unpack_string(v[8], p->pin) < 0 ||
96 unpack_blob(v[9], &p->wire_data) < 0 ||
97 unpack_blob(v[10], &p->rs256) < 0 ||
98 unpack_blob(v[11], &p->es256) < 0 ||
99 unpack_blob(v[12], &p->eddsa) < 0 ||
100 unpack_blob(v[13], &p->cred) < 0 ||
101 unpack_blob(v[14], &p->cdh) < 0)
102 goto fail;
103
104 ok = 0;
105fail:
106 if (ok < 0) {
107 free(p);
108 p = NULL;
109 }
110
111 if (item)
112 cbor_decref(&item);
113
114 return p;
112} 115}
113 116
114static size_t 117size_t
115pack(uint8_t *ptr, size_t len, const struct param *p) 118pack(uint8_t *ptr, size_t len, const struct param *p)
116{ 119{
117 const size_t max = len; 120 cbor_item_t *argv[15], *array = NULL;
118 121 size_t cbor_alloc_len, cbor_len = 0;
119 if (pack_byte(TAG_UV, &ptr, &len, p->uv) < 0 || 122 unsigned char *cbor = NULL;
120 pack_byte(TAG_UP, &ptr, &len, p->up) < 0 || 123
121 pack_byte(TAG_U2F, &ptr, &len, p->u2f) < 0 || 124 memset(argv, 0, sizeof(argv));
122 pack_byte(TAG_TYPE, &ptr, &len, p->type) < 0 || 125
123 pack_byte(TAG_CRED_COUNT, &ptr, &len, p->cred_count) < 0 || 126 if ((array = cbor_new_definite_array(15)) == NULL ||
124 pack_int(TAG_EXT, &ptr, &len, p->ext) < 0 || 127 (argv[0] = pack_byte(p->uv)) == NULL ||
125 pack_int(TAG_SEED, &ptr, &len, p->seed) < 0 || 128 (argv[1] = pack_byte(p->up)) == NULL ||
126 pack_string(TAG_RP_ID, &ptr, &len, p->rp_id) < 0 || 129 (argv[2] = pack_byte(p->u2f)) == NULL ||
127 pack_string(TAG_PIN, &ptr, &len, p->pin) < 0 || 130 (argv[3] = pack_byte(p->type)) == NULL ||
128 pack_blob(TAG_WIRE_DATA, &ptr, &len, &p->wire_data) < 0 || 131 (argv[4] = pack_byte(p->cred_count)) == NULL ||
129 pack_blob(TAG_RS256, &ptr, &len, &p->rs256) < 0 || 132 (argv[5] = pack_int(p->ext)) == NULL ||
130 pack_blob(TAG_ES256, &ptr, &len, &p->es256) < 0 || 133 (argv[6] = pack_int(p->seed)) == NULL ||
131 pack_blob(TAG_EDDSA, &ptr, &len, &p->eddsa) < 0 || 134 (argv[7] = pack_string(p->rp_id)) == NULL ||
132 pack_blob(TAG_CRED, &ptr, &len, &p->cred) < 0 || 135 (argv[8] = pack_string(p->pin)) == NULL ||
133 pack_blob(TAG_CDH, &ptr, &len, &p->cdh) < 0) 136 (argv[9] = pack_blob(&p->wire_data)) == NULL ||
134 return (0); 137 (argv[10] = pack_blob(&p->rs256)) == NULL ||
135 138 (argv[11] = pack_blob(&p->es256)) == NULL ||
136 return (max - len); 139 (argv[12] = pack_blob(&p->eddsa)) == NULL ||
140 (argv[13] = pack_blob(&p->cred)) == NULL ||
141 (argv[14] = pack_blob(&p->cdh)) == NULL)
142 goto fail;
143
144 for (size_t i = 0; i < 15; i++)
145 if (cbor_array_push(array, argv[i]) == false)
146 goto fail;
147
148 if ((cbor_len = cbor_serialize_alloc(array, &cbor,
149 &cbor_alloc_len)) > len) {
150 cbor_len = 0;
151 goto fail;
152 }
153
154 memcpy(ptr, cbor, cbor_len);
155fail:
156 for (size_t i = 0; i < 15; i++)
157 if (argv[i])
158 cbor_decref(&argv[i]);
159
160 if (array)
161 cbor_decref(&array);
162
163 free(cbor);
164
165 return cbor_len;
137} 166}
138 167
139static size_t 168size_t
140input_len(int max) 169pack_dummy(uint8_t *ptr, size_t len)
141{ 170{
142 return (5 * len_byte() + 2 * len_int() + 2 * len_string(max) + 171 struct param dummy;
143 6 * len_blob(max)); 172 uint8_t blob[4096];
173 size_t blob_len;
174
175 memset(&dummy, 0, sizeof(dummy));
176
177 dummy.type = 1; /* rsa */
178 dummy.ext = FIDO_EXT_HMAC_SECRET;
179
180 strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin));
181 strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id));
182
183 dummy.cred.len = sizeof(dummy_cdh); /* XXX */
184 dummy.cdh.len = sizeof(dummy_cdh);
185 dummy.es256.len = sizeof(dummy_es256);
186 dummy.rs256.len = sizeof(dummy_rs256);
187 dummy.eddsa.len = sizeof(dummy_eddsa);
188 dummy.wire_data.len = sizeof(dummy_wire_data_fido);
189
190 memcpy(&dummy.cred.body, &dummy_cdh, dummy.cred.len); /* XXX */
191 memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len);
192 memcpy(&dummy.wire_data.body, &dummy_wire_data_fido,
193 dummy.wire_data.len);
194 memcpy(&dummy.es256.body, &dummy_es256, dummy.es256.len);
195 memcpy(&dummy.rs256.body, &dummy_rs256, dummy.rs256.len);
196 memcpy(&dummy.eddsa.body, &dummy_eddsa, dummy.eddsa.len);
197
198 assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
199
200 if (blob_len > len) {
201 memcpy(ptr, blob, len);
202 return len;
203 }
204
205 memcpy(ptr, blob, blob_len);
206
207 return blob_len;
144} 208}
145 209
146static void 210static void
147get_assert(fido_assert_t *assert, uint8_t u2f, const struct blob *cdh, 211get_assert(fido_assert_t *assert, uint8_t u2f, const struct blob *cdh,
148 const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin, 212 const char *rp_id, int ext, uint8_t up, uint8_t uv, const char *pin,
149 uint8_t cred_count, struct blob *cred) 213 uint8_t cred_count, const struct blob *cred)
150{ 214{
151 fido_dev_t *dev; 215 fido_dev_t *dev;
152 fido_dev_io_t io; 216 fido_dev_io_t io;
153 217
154 memset(&io, 0, sizeof(io)); 218 memset(&io, 0, sizeof(io));
155 219
@@ -166,21 +230,31 @@ get_assert(fido_assert_t *assert, uint8_t u2f, const struct blob *cdh,
166 230
167 if (u2f & 1) 231 if (u2f & 1)
168 fido_dev_force_u2f(dev); 232 fido_dev_force_u2f(dev);
169
170 for (uint8_t i = 0; i < cred_count; i++)
171 fido_assert_allow_cred(assert, cred->body, cred->len);
172
173 fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len);
174 fido_assert_set_rp(assert, rp_id);
175 if (ext & 1) 233 if (ext & 1)
176 fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET); 234 fido_assert_set_extensions(assert, FIDO_EXT_HMAC_SECRET);
177 if (up & 1) 235 if (up & 1)
178 fido_assert_set_up(assert, FIDO_OPT_TRUE); 236 fido_assert_set_up(assert, FIDO_OPT_TRUE);
237 else if (u2f &1)
238 fido_assert_set_up(assert, FIDO_OPT_FALSE);
179 if (uv & 1) 239 if (uv & 1)
180 fido_assert_set_uv(assert, FIDO_OPT_TRUE); 240 fido_assert_set_uv(assert, FIDO_OPT_TRUE);
181 /* XXX reuse cred as hmac salt to keep struct param small */ 241
242 for (uint8_t i = 0; i < cred_count; i++)
243 fido_assert_allow_cred(assert, cred->body, cred->len);
244
245 fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len);
246 fido_assert_set_rp(assert, rp_id);
247 /* XXX reuse cred as hmac salt */
182 fido_assert_set_hmac_salt(assert, cred->body, cred->len); 248 fido_assert_set_hmac_salt(assert, cred->body, cred->len);
183 249
250 /* repeat memory operations to trigger reallocation paths */
251 fido_assert_set_clientdata_hash(assert, cdh->body, cdh->len);
252 fido_assert_set_rp(assert, rp_id);
253 fido_assert_set_hmac_salt(assert, cred->body, cred->len);
254
255 if (strlen(pin) == 0)
256 pin = NULL;
257
184 fido_dev_get_assert(dev, assert, u2f & 1 ? NULL : pin); 258 fido_dev_get_assert(dev, assert, u2f & 1 ? NULL : pin);
185 259
186 fido_dev_cancel(dev); 260 fido_dev_cancel(dev);
@@ -194,7 +268,7 @@ verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len,
194 const unsigned char *sig_ptr, size_t sig_len, uint8_t up, uint8_t uv, 268 const unsigned char *sig_ptr, size_t sig_len, uint8_t up, uint8_t uv,
195 int ext, void *pk) 269 int ext, void *pk)
196{ 270{
197 fido_assert_t *assert = NULL; 271 fido_assert_t *assert = NULL;
198 272
199 if ((assert = fido_assert_new()) == NULL) 273 if ((assert = fido_assert_new()) == NULL)
200 return; 274 return;
@@ -202,16 +276,30 @@ verify_assert(int type, const unsigned char *cdh_ptr, size_t cdh_len,
202 fido_assert_set_clientdata_hash(assert, cdh_ptr, cdh_len); 276 fido_assert_set_clientdata_hash(assert, cdh_ptr, cdh_len);
203 fido_assert_set_rp(assert, rp_id); 277 fido_assert_set_rp(assert, rp_id);
204 fido_assert_set_count(assert, 1); 278 fido_assert_set_count(assert, 1);
279
205 if (fido_assert_set_authdata(assert, 0, authdata_ptr, 280 if (fido_assert_set_authdata(assert, 0, authdata_ptr,
206 authdata_len) != FIDO_OK) { 281 authdata_len) != FIDO_OK) {
207 fido_assert_set_authdata_raw(assert, 0, authdata_ptr, 282 fido_assert_set_authdata_raw(assert, 0, authdata_ptr,
208 authdata_len); 283 authdata_len);
209 } 284 }
285
286 if (up & 1)
287 fido_assert_set_up(assert, FIDO_OPT_TRUE);
288 if (uv & 1)
289 fido_assert_set_uv(assert, FIDO_OPT_TRUE);
290
210 fido_assert_set_extensions(assert, ext); 291 fido_assert_set_extensions(assert, ext);
211 if (up & 1) fido_assert_set_up(assert, FIDO_OPT_TRUE);
212 if (uv & 1) fido_assert_set_uv(assert, FIDO_OPT_TRUE);
213 fido_assert_set_sig(assert, 0, sig_ptr, sig_len); 292 fido_assert_set_sig(assert, 0, sig_ptr, sig_len);
214 fido_assert_verify(assert, 0, type, pk); 293
294 /* repeat memory operations to trigger reallocation paths */
295 if (fido_assert_set_authdata(assert, 0, authdata_ptr,
296 authdata_len) != FIDO_OK) {
297 fido_assert_set_authdata_raw(assert, 0, authdata_ptr,
298 authdata_len);
299 }
300 fido_assert_set_sig(assert, 0, sig_ptr, sig_len);
301
302 assert(fido_assert_verify(assert, 0, type, pk) != FIDO_OK);
215 303
216 fido_assert_free(&assert); 304 fido_assert_free(&assert);
217} 305}
@@ -262,38 +350,30 @@ out:
262 EVP_PKEY_free(pkey); 350 EVP_PKEY_free(pkey);
263} 351}
264 352
265int 353void
266LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) 354test(const struct param *p)
267{ 355{
268 struct param p; 356 fido_assert_t *assert = NULL;
269 fido_assert_t *assert = NULL; 357 es256_pk_t *es256_pk = NULL;
270 es256_pk_t *es256_pk = NULL; 358 rs256_pk_t *rs256_pk = NULL;
271 rs256_pk_t *rs256_pk = NULL; 359 eddsa_pk_t *eddsa_pk = NULL;
272 eddsa_pk_t *eddsa_pk = NULL; 360 uint8_t flags;
273 uint8_t flags; 361 uint32_t sigcount;
274 uint32_t sigcount; 362 int cose_alg = 0;
275 int cose_alg = 0; 363 void *pk;
276 void *pk; 364
277 365 prng_init((unsigned int)p->seed);
278 memset(&p, 0, sizeof(p));
279
280 if (size < input_len(GETLEN_MIN) || size > input_len(GETLEN_MAX) ||
281 unpack(data, size, &p) < 0)
282 return (0);
283
284 prng_init((unsigned int)p.seed);
285
286 fido_init(FIDO_DEBUG); 366 fido_init(FIDO_DEBUG);
287 fido_set_log_handler(consume_str); 367 fido_set_log_handler(consume_str);
288 368
289 switch (p.type & 3) { 369 switch (p->type & 3) {
290 case 0: 370 case 0:
291 cose_alg = COSE_ES256; 371 cose_alg = COSE_ES256;
292 372
293 if ((es256_pk = es256_pk_new()) == NULL) 373 if ((es256_pk = es256_pk_new()) == NULL)
294 return (0); 374 return;
295 375
296 es256_pk_from_ptr(es256_pk, p.es256.body, p.es256.len); 376 es256_pk_from_ptr(es256_pk, p->es256.body, p->es256.len);
297 pk = es256_pk; 377 pk = es256_pk;
298 378
299 break; 379 break;
@@ -301,9 +381,9 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
301 cose_alg = COSE_RS256; 381 cose_alg = COSE_RS256;
302 382
303 if ((rs256_pk = rs256_pk_new()) == NULL) 383 if ((rs256_pk = rs256_pk_new()) == NULL)
304 return (0); 384 return;
305 385
306 rs256_pk_from_ptr(rs256_pk, p.rs256.body, p.rs256.len); 386 rs256_pk_from_ptr(rs256_pk, p->rs256.body, p->rs256.len);
307 pk = rs256_pk; 387 pk = rs256_pk;
308 388
309 rs256_convert(pk); 389 rs256_convert(pk);
@@ -313,9 +393,9 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
313 cose_alg = COSE_EDDSA; 393 cose_alg = COSE_EDDSA;
314 394
315 if ((eddsa_pk = eddsa_pk_new()) == NULL) 395 if ((eddsa_pk = eddsa_pk_new()) == NULL)
316 return (0); 396 return;
317 397
318 eddsa_pk_from_ptr(eddsa_pk, p.eddsa.body, p.eddsa.len); 398 eddsa_pk_from_ptr(eddsa_pk, p->eddsa.body, p->eddsa.len);
319 pk = eddsa_pk; 399 pk = eddsa_pk;
320 400
321 eddsa_convert(pk); 401 eddsa_convert(pk);
@@ -326,10 +406,10 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
326 if ((assert = fido_assert_new()) == NULL) 406 if ((assert = fido_assert_new()) == NULL)
327 goto out; 407 goto out;
328 408
329 set_wire_data(p.wire_data.body, p.wire_data.len); 409 set_wire_data(p->wire_data.body, p->wire_data.len);
330 410
331 get_assert(assert, p.u2f, &p.cdh, p.rp_id, p.ext, p.up, p.uv, p.pin, 411 get_assert(assert, p->u2f, &p->cdh, p->rp_id, p->ext, p->up, p->uv,
332 p.cred_count, &p.cred); 412 p->pin, p->cred_count, &p->cred);
333 413
334 /* XXX +1 on purpose */ 414 /* XXX +1 on purpose */
335 for (size_t i = 0; i <= fido_assert_count(assert); i++) { 415 for (size_t i = 0; i <= fido_assert_count(assert); i++) {
@@ -340,7 +420,7 @@ LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
340 fido_assert_authdata_ptr(assert, i), 420 fido_assert_authdata_ptr(assert, i),
341 fido_assert_authdata_len(assert, i), 421 fido_assert_authdata_len(assert, i),
342 fido_assert_sig_ptr(assert, i), 422 fido_assert_sig_ptr(assert, i),
343 fido_assert_sig_len(assert, i), p.up, p.uv, p.ext, pk); 423 fido_assert_sig_len(assert, i), p->up, p->uv, p->ext, pk);
344 consume(fido_assert_id_ptr(assert, i), 424 consume(fido_assert_id_ptr(assert, i),
345 fido_assert_id_len(assert, i)); 425 fido_assert_id_len(assert, i));
346 consume(fido_assert_user_id_ptr(assert, i), 426 consume(fido_assert_user_id_ptr(assert, i),
@@ -365,103 +445,40 @@ out:
365 eddsa_pk_free(&eddsa_pk); 445 eddsa_pk_free(&eddsa_pk);
366 446
367 fido_assert_free(&assert); 447 fido_assert_free(&assert);
368
369 return (0);
370} 448}
371 449
372static size_t 450void
373pack_dummy(uint8_t *ptr, size_t len) 451mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
374{ 452{
375 struct param dummy; 453 if (flags & MUTATE_SEED)
376 uint8_t blob[16384]; 454 p->seed = (int)seed;
377 size_t blob_len; 455
378 456 if (flags & MUTATE_PARAM) {
379 memset(&dummy, 0, sizeof(dummy)); 457 mutate_byte(&p->uv);
380 458 mutate_byte(&p->up);
381 dummy.type = 1; /* rsa */ 459 mutate_byte(&p->u2f);
382 dummy.ext = FIDO_EXT_HMAC_SECRET; 460 mutate_byte(&p->type);
383 461 mutate_byte(&p->cred_count);
384 strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin)); 462 mutate_int(&p->ext);
385 strlcpy(dummy.rp_id, dummy_rp_id, sizeof(dummy.rp_id)); 463 mutate_blob(&p->rs256);
386 464 mutate_blob(&p->es256);
387 dummy.cred.len = sizeof(dummy_cdh); /* XXX */ 465 mutate_blob(&p->eddsa);
388 dummy.cdh.len = sizeof(dummy_cdh); 466 mutate_blob(&p->cred);
389 dummy.es256.len = sizeof(dummy_es256); 467 mutate_blob(&p->cdh);
390 dummy.rs256.len = sizeof(dummy_rs256); 468 mutate_string(p->rp_id);
391 dummy.eddsa.len = sizeof(dummy_eddsa); 469 mutate_string(p->pin);
392 dummy.wire_data.len = sizeof(dummy_wire_data_fido);
393
394 memcpy(&dummy.cred.body, &dummy_cdh, dummy.cred.len); /* XXX */
395 memcpy(&dummy.cdh.body, &dummy_cdh, dummy.cdh.len);
396 memcpy(&dummy.wire_data.body, &dummy_wire_data_fido,
397 dummy.wire_data.len);
398 memcpy(&dummy.es256.body, &dummy_es256, dummy.es256.len);
399 memcpy(&dummy.rs256.body, &dummy_rs256, dummy.rs256.len);
400 memcpy(&dummy.eddsa.body, &dummy_eddsa, dummy.eddsa.len);
401
402 blob_len = pack(blob, sizeof(blob), &dummy);
403 assert(blob_len != 0);
404
405 if (blob_len > len) {
406 memcpy(ptr, blob, len);
407 return (len);
408 } 470 }
409 471
410 memcpy(ptr, blob, blob_len); 472 if (flags & MUTATE_WIREDATA) {
411 473 if (p->u2f & 1) {
412 return (blob_len); 474 p->wire_data.len = sizeof(dummy_wire_data_u2f);
413} 475 memcpy(&p->wire_data.body, &dummy_wire_data_u2f,
414 476 p->wire_data.len);
415size_t 477 } else {
416LLVMFuzzerCustomMutator(uint8_t *data, size_t size, size_t maxsize, 478 p->wire_data.len = sizeof(dummy_wire_data_fido);
417 unsigned int seed) NO_MSAN 479 memcpy(&p->wire_data.body, &dummy_wire_data_fido,
418{ 480 p->wire_data.len);
419 struct param p; 481 }
420 uint8_t blob[16384]; 482 mutate_blob(&p->wire_data);
421 size_t blob_len;
422
423 (void)seed;
424
425 memset(&p, 0, sizeof(p));
426
427 if (unpack(data, size, &p) < 0)
428 return (pack_dummy(data, maxsize));
429
430 mutate_byte(&p.uv);
431 mutate_byte(&p.up);
432 mutate_byte(&p.u2f);
433 mutate_byte(&p.type);
434 mutate_byte(&p.cred_count);
435
436 mutate_int(&p.ext);
437 p.seed = (int)seed;
438
439 if (p.u2f & 1) {
440 p.wire_data.len = sizeof(dummy_wire_data_u2f);
441 memcpy(&p.wire_data.body, &dummy_wire_data_u2f,
442 p.wire_data.len);
443 } else {
444 p.wire_data.len = sizeof(dummy_wire_data_fido);
445 memcpy(&p.wire_data.body, &dummy_wire_data_fido,
446 p.wire_data.len);
447 } 483 }
448
449 mutate_blob(&p.wire_data);
450 mutate_blob(&p.rs256);
451 mutate_blob(&p.es256);
452 mutate_blob(&p.eddsa);
453 mutate_blob(&p.cred);
454 mutate_blob(&p.cdh);
455
456 mutate_string(p.rp_id);
457 mutate_string(p.pin);
458
459 blob_len = pack(blob, sizeof(blob), &p);
460
461 if (blob_len == 0 || blob_len > maxsize)
462 return (0);
463
464 memcpy(data, blob, blob_len);
465
466 return (blob_len);
467} 484}