diff options
author | Colin Watson <cjwatson@debian.org> | 2020-09-20 17:48:15 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2020-09-20 17:48:15 +0100 |
commit | 05fa6dd7724ccfd1c183e6e4bf9d22eb12abea8c (patch) | |
tree | 71d3eccc33c93c230b021c72f1fb9cf2247bf6c0 /fuzz/fuzz_assert.c | |
parent | b77d6ed4d47acbc836f05be0e9f4abeb104e21ff (diff) | |
parent | 173bfbf7886608a4a7abbfac6a42ac4bf4a3432d (diff) |
Update upstream source from tag 'upstream/1.5.0'
Update to upstream version '1.5.0'
with Debian dir 102fd7ed15b138200444754d256b136933185ec2
Diffstat (limited to 'fuzz/fuzz_assert.c')
-rw-r--r-- | fuzz/fuzz_assert.c | 455 |
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. */ |
43 | struct param { | 27 | struct 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 | ||
86 | int LLVMFuzzerTestOneInput(const uint8_t *, size_t); | 70 | struct param * |
87 | size_t LLVMFuzzerCustomMutator(uint8_t *, size_t, size_t, unsigned int); | 71 | unpack(const uint8_t *ptr, size_t len) |
88 | |||
89 | static int | ||
90 | unpack(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; | ||
105 | fail: | ||
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 | ||
114 | static size_t | 117 | size_t |
115 | pack(uint8_t *ptr, size_t len, const struct param *p) | 118 | pack(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); | ||
155 | fail: | ||
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 | ||
139 | static size_t | 168 | size_t |
140 | input_len(int max) | 169 | pack_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 | ||
146 | static void | 210 | static void |
147 | get_assert(fido_assert_t *assert, uint8_t u2f, const struct blob *cdh, | 211 | get_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 | ||
265 | int | 353 | void |
266 | LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | 354 | test(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 | ||
372 | static size_t | 450 | void |
373 | pack_dummy(uint8_t *ptr, size_t len) | 451 | mutate(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); | |
415 | size_t | 477 | } else { |
416 | LLVMFuzzerCustomMutator(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 | } |