1/*
2 * Copyright (c) 2018-2022 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#ifndef _EXTERN_H
9#define _EXTERN_H
10
11#ifdef __MINGW32__
12#include <sys/types.h>
13#endif
14
15#ifdef HAVE_SIGNAL_H
16#include <signal.h>
17#endif
18
19#include <stdint.h>
20
21#include "fido/types.h"
22#include "blob.h"
23
24#ifdef __cplusplus
25extern "C" {
26#endif /* __cplusplus */
27
28/* aes256 */
29int aes256_cbc_dec(const fido_dev_t *dev, const fido_blob_t *,
30    const fido_blob_t *, fido_blob_t *);
31int aes256_cbc_enc(const fido_dev_t *dev, const fido_blob_t *,
32    const fido_blob_t *, fido_blob_t *);
33int aes256_gcm_dec(const fido_blob_t *, const fido_blob_t *,
34    const fido_blob_t *, const fido_blob_t *, fido_blob_t *);
35int aes256_gcm_enc(const fido_blob_t *, const fido_blob_t *,
36    const fido_blob_t *, const fido_blob_t *, fido_blob_t *);
37
38/* cbor encoding functions */
39cbor_item_t *cbor_build_uint(const uint64_t);
40cbor_item_t *cbor_flatten_vector(cbor_item_t **, size_t);
41cbor_item_t *cbor_encode_assert_opt(fido_opt_t, fido_opt_t);
42cbor_item_t *cbor_encode_change_pin_auth(const fido_dev_t *,
43    const fido_blob_t *, const fido_blob_t *, const fido_blob_t *);
44cbor_item_t *cbor_encode_cred_ext(const fido_cred_ext_t *, const fido_blob_t *);
45cbor_item_t *cbor_encode_assert_ext(fido_dev_t *,
46    const fido_assert_ext_t *, const fido_blob_t *, const es256_pk_t *);
47cbor_item_t *cbor_encode_cred_opt(fido_opt_t, fido_opt_t);
48cbor_item_t *cbor_encode_pin_auth(const fido_dev_t *, const fido_blob_t *,
49    const fido_blob_t *);
50cbor_item_t *cbor_encode_pin_opt(const fido_dev_t *);
51cbor_item_t *cbor_encode_pubkey(const fido_blob_t *);
52cbor_item_t *cbor_encode_pubkey_list(const fido_blob_array_t *);
53cbor_item_t *cbor_encode_pubkey_param(int);
54cbor_item_t *cbor_encode_rp_entity(const fido_rp_t *);
55cbor_item_t *cbor_encode_str_array(const fido_str_array_t *);
56cbor_item_t *cbor_encode_user_entity(const fido_user_t *);
57cbor_item_t *es256_pk_encode(const es256_pk_t *, int);
58
59/* cbor decoding functions */
60int cbor_decode_attstmt(const cbor_item_t *, fido_attstmt_t *);
61int cbor_decode_bool(const cbor_item_t *, bool *);
62int cbor_decode_cred_authdata(const cbor_item_t *, int, fido_blob_t *,
63    fido_authdata_t *, fido_attcred_t *, fido_cred_ext_t *);
64int cbor_decode_assert_authdata(const cbor_item_t *, fido_blob_t *,
65    fido_authdata_t *, fido_assert_extattr_t *);
66int cbor_decode_cred_id(const cbor_item_t *, fido_blob_t *);
67int cbor_decode_fmt(const cbor_item_t *, char **);
68int cbor_decode_pubkey(const cbor_item_t *, int *, void *);
69int cbor_decode_rp_entity(const cbor_item_t *, fido_rp_t *);
70int cbor_decode_uint64(const cbor_item_t *, uint64_t *);
71int cbor_decode_user(const cbor_item_t *, fido_user_t *);
72int es256_pk_decode(const cbor_item_t *, es256_pk_t *);
73int es384_pk_decode(const cbor_item_t *, es384_pk_t *);
74int rs256_pk_decode(const cbor_item_t *, rs256_pk_t *);
75int eddsa_pk_decode(const cbor_item_t *, eddsa_pk_t *);
76
77/* auxiliary cbor routines */
78int cbor_add_bool(cbor_item_t *, const char *, fido_opt_t);
79int cbor_add_bytestring(cbor_item_t *, const char *, const unsigned char *,
80    size_t);
81int cbor_add_string(cbor_item_t *, const char *, const char *);
82int cbor_array_iter(const cbor_item_t *, void *, int(*)(const cbor_item_t *,
83    void *));
84int cbor_build_frame(uint8_t, cbor_item_t *[], size_t, fido_blob_t *);
85int cbor_bytestring_copy(const cbor_item_t *, unsigned char **, size_t *);
86int cbor_map_iter(const cbor_item_t *, void *, int(*)(const cbor_item_t *,
87    const cbor_item_t *, void *));
88int cbor_string_copy(const cbor_item_t *, char **);
89int cbor_parse_reply(const unsigned char *, size_t, void *,
90    int(*)(const cbor_item_t *, const cbor_item_t *, void *));
91int cbor_add_uv_params(fido_dev_t *, uint8_t, const fido_blob_t *,
92    const es256_pk_t *, const fido_blob_t *, const char *, const char *,
93    cbor_item_t **, cbor_item_t **, int *);
94void cbor_vector_free(cbor_item_t **, size_t);
95int cbor_array_append(cbor_item_t **, cbor_item_t *);
96int cbor_array_drop(cbor_item_t **, size_t);
97
98/* deflate */
99int fido_compress(fido_blob_t *, const fido_blob_t *);
100int fido_uncompress(fido_blob_t *, const fido_blob_t *, size_t);
101
102#ifndef nitems
103#define nitems(_a)	(sizeof((_a)) / sizeof((_a)[0]))
104#endif
105
106/* buf */
107int fido_buf_read(const unsigned char **, size_t *, void *, size_t);
108int fido_buf_write(unsigned char **, size_t *, const void *, size_t);
109
110/* hid i/o */
111void *fido_hid_open(const char *);
112void  fido_hid_close(void *);
113int fido_hid_read(void *, unsigned char *, size_t, int);
114int fido_hid_write(void *, const unsigned char *, size_t);
115int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *);
116int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *);
117int fido_hid_unix_open(const char *);
118int fido_hid_unix_wait(int, int, const fido_sigset_t *);
119int fido_hid_set_sigmask(void *, const fido_sigset_t *);
120size_t fido_hid_report_in_len(void *);
121size_t fido_hid_report_out_len(void *);
122
123/* nfc i/o */
124bool fido_is_nfc(const char *);
125bool nfc_is_fido(const char *);
126void *fido_nfc_open(const char *);
127void  fido_nfc_close(void *);
128int fido_nfc_read(void *, unsigned char *, size_t, int);
129int fido_nfc_write(void *, const unsigned char *, size_t);
130int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
131int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
132int fido_nfc_set_sigmask(void *, const fido_sigset_t *);
133int fido_dev_set_nfc(fido_dev_t *);
134
135/* pcsc i/o */
136bool fido_is_pcsc(const char *);
137void *fido_pcsc_open(const char *);
138void  fido_pcsc_close(void *);
139int fido_pcsc_read(void *, unsigned char *, size_t, int);
140int fido_pcsc_write(void *, const unsigned char *, size_t);
141int fido_pcsc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int);
142int fido_pcsc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t);
143int fido_dev_set_pcsc(fido_dev_t *);
144
145/* windows hello */
146int fido_winhello_manifest(fido_dev_info_t *, size_t, size_t *);
147int fido_winhello_open(fido_dev_t *);
148int fido_winhello_close(fido_dev_t *);
149int fido_winhello_cancel(fido_dev_t *);
150int fido_winhello_get_assert(fido_dev_t *, fido_assert_t *, const char *, int);
151int fido_winhello_get_cbor_info(fido_dev_t *, fido_cbor_info_t *);
152int fido_winhello_make_cred(fido_dev_t *, fido_cred_t *, const char *, int);
153
154/* generic i/o */
155int fido_rx_cbor_status(fido_dev_t *, int *);
156int fido_rx(fido_dev_t *, uint8_t, void *, size_t, int *);
157int fido_tx(fido_dev_t *, uint8_t, const void *, size_t, int *);
158
159/* log */
160#ifdef FIDO_NO_DIAGNOSTIC
161#define fido_log_init(...)	do { /* nothing */ } while (0)
162#define fido_log_debug(...)	do { /* nothing */ } while (0)
163#define fido_log_xxd(...)	do { /* nothing */ } while (0)
164#define fido_log_error(...)	do { /* nothing */ } while (0)
165#else
166#ifdef __GNUC__
167void fido_log_init(void);
168void fido_log_debug(const char *, ...)
169    __attribute__((__format__ (printf, 1, 2)));
170void fido_log_xxd(const void *, size_t, const char *, ...)
171    __attribute__((__format__ (printf, 3, 4)));
172void fido_log_error(int, const char *, ...)
173    __attribute__((__format__ (printf, 2, 3)));
174#else
175void fido_log_init(void);
176void fido_log_debug(const char *, ...);
177void fido_log_xxd(const void *, size_t, const char *, ...);
178void fido_log_error(int, const char *, ...);
179#endif /* __GNUC__ */
180#endif /* FIDO_NO_DIAGNOSTIC */
181
182/* u2f */
183int u2f_register(fido_dev_t *, fido_cred_t *, int *);
184int u2f_authenticate(fido_dev_t *, fido_assert_t *, int *);
185int u2f_get_touch_begin(fido_dev_t *, int *);
186int u2f_get_touch_status(fido_dev_t *, int *, int *);
187
188/* unexposed fido ops */
189uint8_t fido_dev_get_pin_protocol(const fido_dev_t *);
190int fido_dev_authkey(fido_dev_t *, es256_pk_t *, int *);
191int fido_dev_get_cbor_info_wait(fido_dev_t *, fido_cbor_info_t *, int *);
192int fido_dev_get_uv_token(fido_dev_t *, uint8_t, const char *,
193    const fido_blob_t *, const es256_pk_t *, const char *, fido_blob_t *,
194    int *);
195uint64_t fido_dev_maxmsgsize(const fido_dev_t *);
196int fido_do_ecdh(fido_dev_t *, es256_pk_t **, fido_blob_t **, int *);
197
198/* types */
199void fido_algo_array_free(fido_algo_array_t *);
200void fido_byte_array_free(fido_byte_array_t *);
201void fido_cert_array_free(fido_cert_array_t *);
202void fido_opt_array_free(fido_opt_array_t *);
203void fido_str_array_free(fido_str_array_t *);
204void fido_algo_free(fido_algo_t *);
205int fido_str_array_pack(fido_str_array_t *, const char * const *, size_t);
206
207/* misc */
208void fido_assert_reset_rx(fido_assert_t *);
209void fido_assert_reset_tx(fido_assert_t *);
210void fido_cred_reset_rx(fido_cred_t *);
211void fido_cred_reset_tx(fido_cred_t *);
212void fido_cbor_info_reset(fido_cbor_info_t *);
213int fido_blob_serialise(fido_blob_t *, const cbor_item_t *);
214int fido_check_flags(uint8_t, fido_opt_t, fido_opt_t);
215int fido_check_rp_id(const char *, const unsigned char *);
216int fido_get_random(void *, size_t);
217int fido_sha256(fido_blob_t *, const u_char *, size_t);
218int fido_time_now(struct timespec *);
219int fido_time_delta(const struct timespec *, int *);
220int fido_to_uint64(const char *, int, uint64_t *);
221
222/* crypto */
223int es256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
224int es384_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
225int rs256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
226int eddsa_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
227int rs1_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *);
228int es256_pk_verify_sig(const fido_blob_t *, const es256_pk_t *,
229    const fido_blob_t *);
230int es384_pk_verify_sig(const fido_blob_t *, const es384_pk_t *,
231    const fido_blob_t *);
232int rs256_pk_verify_sig(const fido_blob_t *, const rs256_pk_t *,
233    const fido_blob_t *);
234int eddsa_pk_verify_sig(const fido_blob_t *, const eddsa_pk_t *,
235    const fido_blob_t *);
236int fido_get_signed_hash(int, fido_blob_t *, const fido_blob_t *,
237    const fido_blob_t *);
238int fido_get_signed_hash_tpm(fido_blob_t *, const fido_blob_t *,
239    const fido_blob_t *, const fido_attstmt_t *, const fido_attcred_t *);
240
241/* device manifest functions */
242int fido_hid_manifest(fido_dev_info_t *, size_t, size_t *);
243int fido_nfc_manifest(fido_dev_info_t *, size_t, size_t *);
244int fido_pcsc_manifest(fido_dev_info_t *, size_t, size_t *);
245
246/* fuzzing instrumentation */
247#ifdef FIDO_FUZZ
248uint32_t uniform_random(uint32_t);
249#endif
250
251/* internal device capability flags */
252#define FIDO_DEV_PIN_SET	0x001
253#define FIDO_DEV_PIN_UNSET	0x002
254#define FIDO_DEV_CRED_PROT	0x004
255#define FIDO_DEV_CREDMAN	0x008
256#define FIDO_DEV_PIN_PROTOCOL1	0x010
257#define FIDO_DEV_PIN_PROTOCOL2	0x020
258#define FIDO_DEV_UV_SET 	0x040
259#define FIDO_DEV_UV_UNSET	0x080
260#define FIDO_DEV_TOKEN_PERMS	0x100
261#define FIDO_DEV_WINHELLO	0x200
262
263/* miscellanea */
264#define FIDO_DUMMY_CLIENTDATA	""
265#define FIDO_DUMMY_RP_ID	"localhost"
266#define FIDO_DUMMY_USER_NAME	"dummy"
267#define FIDO_DUMMY_USER_ID	1
268#define FIDO_WINHELLO_PATH	"windows://hello"
269#define FIDO_NFC_PREFIX		"nfc:"
270#define FIDO_PCSC_PREFIX	"pcsc:"
271
272#ifdef __cplusplus
273} /* extern "C" */
274#endif /* __cplusplus */
275
276#endif /* !_EXTERN_H */
277