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 * SPDX-License-Identifier: BSD-2-Clause
14 #include "mutator_aux.h"
15 #include "wiredata_fido2.h"
18 #include "../openbsd-compat/openbsd-compat.h"
20 /* Parameter set defining a FIDO2 "large blob" operation. */
25 struct blob get_wiredata;
26 struct blob set_wiredata;
30 * Collection of HID reports from an authenticator issued with a FIDO2
31 * 'authenticatorLargeBlobs' 'get' command.
33 static const uint8_t dummy_get_wiredata[] = {
35 WIREDATA_CTAP_CBOR_INFO,
36 WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY
40 * Collection of HID reports from an authenticator issued with a FIDO2
41 * 'authenticatorLargeBlobs' 'set' command.
43 static const uint8_t dummy_set_wiredata[] = {
45 WIREDATA_CTAP_CBOR_INFO,
46 WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY,
47 WIREDATA_CTAP_CBOR_AUTHKEY,
48 WIREDATA_CTAP_CBOR_PINTOKEN,
49 WIREDATA_CTAP_CBOR_STATUS
53 * XXX this needs to match the encrypted blob embedded in
54 * WIREDATA_CTAP_CBOR_LARGEBLOB_GET_ARRAY.
56 static const uint8_t dummy_key[] = {
57 0xa9, 0x1b, 0xc4, 0xdd, 0xfc, 0x9a, 0x93, 0x79,
58 0x75, 0xba, 0xf7, 0x7f, 0x4d, 0x57, 0xfc, 0xa6,
59 0xe1, 0xf8, 0x06, 0x43, 0x23, 0x99, 0x51, 0x32,
60 0xce, 0x6e, 0x19, 0x84, 0x50, 0x13, 0x2d, 0x7b
64 unpack(const uint8_t *ptr, size_t len)
66 cbor_item_t *item = NULL, **v;
67 struct cbor_load_result cbor;
71 if ((p = calloc(1, sizeof(*p))) == NULL ||
72 (item = cbor_load(ptr, len, &cbor)) == NULL ||
74 cbor_isa_array(item) == false ||
75 cbor_array_is_definite(item) == false ||
76 cbor_array_size(item) != 5 ||
77 (v = cbor_array_handle(item)) == NULL)
80 if (unpack_int(v[0], &p->seed) < 0 ||
81 unpack_string(v[1], p->pin) < 0 ||
82 unpack_blob(v[2], &p->key) < 0 ||
83 unpack_blob(v[3], &p->get_wiredata) < 0 ||
84 unpack_blob(v[4], &p->set_wiredata) < 0)
101 pack(uint8_t *ptr, size_t len, const struct param *p)
103 cbor_item_t *argv[5], *array = NULL;
104 size_t cbor_alloc_len, cbor_len = 0;
105 unsigned char *cbor = NULL;
107 memset(argv, 0, sizeof(argv));
109 if ((array = cbor_new_definite_array(5)) == NULL ||
110 (argv[0] = pack_int(p->seed)) == NULL ||
111 (argv[1] = pack_string(p->pin)) == NULL ||
112 (argv[2] = pack_blob(&p->key)) == NULL ||
113 (argv[3] = pack_blob(&p->get_wiredata)) == NULL ||
114 (argv[4] = pack_blob(&p->set_wiredata)) == NULL)
117 for (size_t i = 0; i < 5; i++)
118 if (cbor_array_push(array, argv[i]) == false)
121 if ((cbor_len = cbor_serialize_alloc(array, &cbor,
122 &cbor_alloc_len)) == 0 || cbor_len > len) {
127 memcpy(ptr, cbor, cbor_len);
129 for (size_t i = 0; i < 5; i++)
131 cbor_decref(&argv[i]);
142 pack_dummy(uint8_t *ptr, size_t len)
145 uint8_t blob[MAXCORPUS];
148 memset(&dummy, 0, sizeof(dummy));
150 strlcpy(dummy.pin, dummy_pin, sizeof(dummy.pin));
152 dummy.get_wiredata.len = sizeof(dummy_get_wiredata);
153 dummy.set_wiredata.len = sizeof(dummy_set_wiredata);
154 dummy.key.len = sizeof(dummy_key);
156 memcpy(&dummy.get_wiredata.body, &dummy_get_wiredata,
157 dummy.get_wiredata.len);
158 memcpy(&dummy.set_wiredata.body, &dummy_set_wiredata,
159 dummy.set_wiredata.len);
160 memcpy(&dummy.key.body, &dummy_key, dummy.key.len);
162 assert((blob_len = pack(blob, sizeof(blob), &dummy)) != 0);
164 if (blob_len > len) {
165 memcpy(ptr, blob, len);
169 memcpy(ptr, blob, blob_len);
179 if ((dev = open_dev(0)) == NULL)
186 get_blob(const struct param *p, int array)
192 set_wire_data(p->get_wiredata.body, p->get_wiredata.len);
194 if ((dev = prepare_dev()) == NULL)
198 fido_dev_largeblob_get_array(dev, &ptr, &len);
200 fido_dev_largeblob_get(dev, p->key.body, p->key.len, &ptr, &len);
210 set_blob(const struct param *p, int op)
215 set_wire_data(p->set_wiredata.body, p->set_wiredata.len);
217 if ((dev = prepare_dev()) == NULL)
220 if (strlen(pin) == 0)
225 fido_dev_largeblob_remove(dev, p->key.body, p->key.len, pin);
228 /* XXX reuse p->get_wiredata as the blob to be set */
229 fido_dev_largeblob_set(dev, p->key.body, p->key.len,
230 p->get_wiredata.body, p->get_wiredata.len, pin);
233 /* XXX reuse p->get_wiredata as the body of the cbor array */
234 fido_dev_largeblob_set_array(dev, p->get_wiredata.body,
235 p->get_wiredata.len, pin);
243 test(const struct param *p)
245 prng_init((unsigned int)p->seed);
247 fido_init(FIDO_DEBUG);
248 fido_set_log_handler(consume_str);
258 mutate(struct param *p, unsigned int seed, unsigned int flags) NO_MSAN
260 if (flags & MUTATE_SEED)
263 if (flags & MUTATE_PARAM) {
264 mutate_blob(&p->key);
265 mutate_string(p->pin);
268 if (flags & MUTATE_WIREDATA) {
269 mutate_blob(&p->get_wiredata);
270 mutate_blob(&p->set_wiredata);