10afa8e06SEd Maste /* 2*2ccfa855SEd Maste * Copyright (c) 2018-2022 Yubico AB. All rights reserved. 30afa8e06SEd Maste * Use of this source code is governed by a BSD-style 40afa8e06SEd Maste * license that can be found in the LICENSE file. 5*2ccfa855SEd Maste * SPDX-License-Identifier: BSD-2-Clause 60afa8e06SEd Maste */ 70afa8e06SEd Maste 80afa8e06SEd Maste #ifndef _EXTERN_H 90afa8e06SEd Maste #define _EXTERN_H 100afa8e06SEd Maste 110afa8e06SEd Maste #ifdef __MINGW32__ 120afa8e06SEd Maste #include <sys/types.h> 130afa8e06SEd Maste #endif 140afa8e06SEd Maste 150afa8e06SEd Maste #ifdef HAVE_SIGNAL_H 160afa8e06SEd Maste #include <signal.h> 170afa8e06SEd Maste #endif 180afa8e06SEd Maste 190afa8e06SEd Maste #include <stdint.h> 200afa8e06SEd Maste 210afa8e06SEd Maste #include "fido/types.h" 220afa8e06SEd Maste #include "blob.h" 230afa8e06SEd Maste 240afa8e06SEd Maste #ifdef __cplusplus 250afa8e06SEd Maste extern "C" { 260afa8e06SEd Maste #endif /* __cplusplus */ 270afa8e06SEd Maste 280afa8e06SEd Maste /* aes256 */ 290afa8e06SEd Maste int aes256_cbc_dec(const fido_dev_t *dev, const fido_blob_t *, 300afa8e06SEd Maste const fido_blob_t *, fido_blob_t *); 310afa8e06SEd Maste int aes256_cbc_enc(const fido_dev_t *dev, const fido_blob_t *, 320afa8e06SEd Maste const fido_blob_t *, fido_blob_t *); 330afa8e06SEd Maste int aes256_gcm_dec(const fido_blob_t *, const fido_blob_t *, 340afa8e06SEd Maste const fido_blob_t *, const fido_blob_t *, fido_blob_t *); 350afa8e06SEd Maste int aes256_gcm_enc(const fido_blob_t *, const fido_blob_t *, 360afa8e06SEd Maste const fido_blob_t *, const fido_blob_t *, fido_blob_t *); 370afa8e06SEd Maste 380afa8e06SEd Maste /* cbor encoding functions */ 390afa8e06SEd Maste cbor_item_t *cbor_build_uint(const uint64_t); 400afa8e06SEd Maste cbor_item_t *cbor_flatten_vector(cbor_item_t **, size_t); 410afa8e06SEd Maste cbor_item_t *cbor_encode_assert_opt(fido_opt_t, fido_opt_t); 420afa8e06SEd Maste cbor_item_t *cbor_encode_change_pin_auth(const fido_dev_t *, 430afa8e06SEd Maste const fido_blob_t *, const fido_blob_t *, const fido_blob_t *); 440afa8e06SEd Maste cbor_item_t *cbor_encode_cred_ext(const fido_cred_ext_t *, const fido_blob_t *); 450afa8e06SEd Maste cbor_item_t *cbor_encode_assert_ext(fido_dev_t *, 460afa8e06SEd Maste const fido_assert_ext_t *, const fido_blob_t *, const es256_pk_t *); 470afa8e06SEd Maste cbor_item_t *cbor_encode_cred_opt(fido_opt_t, fido_opt_t); 480afa8e06SEd Maste cbor_item_t *cbor_encode_pin_auth(const fido_dev_t *, const fido_blob_t *, 490afa8e06SEd Maste const fido_blob_t *); 500afa8e06SEd Maste cbor_item_t *cbor_encode_pin_opt(const fido_dev_t *); 510afa8e06SEd Maste cbor_item_t *cbor_encode_pubkey(const fido_blob_t *); 520afa8e06SEd Maste cbor_item_t *cbor_encode_pubkey_list(const fido_blob_array_t *); 530afa8e06SEd Maste cbor_item_t *cbor_encode_pubkey_param(int); 540afa8e06SEd Maste cbor_item_t *cbor_encode_rp_entity(const fido_rp_t *); 55f540a430SEd Maste cbor_item_t *cbor_encode_str_array(const fido_str_array_t *); 560afa8e06SEd Maste cbor_item_t *cbor_encode_user_entity(const fido_user_t *); 570afa8e06SEd Maste cbor_item_t *es256_pk_encode(const es256_pk_t *, int); 580afa8e06SEd Maste 590afa8e06SEd Maste /* cbor decoding functions */ 600afa8e06SEd Maste int cbor_decode_attstmt(const cbor_item_t *, fido_attstmt_t *); 61*2ccfa855SEd Maste int cbor_decode_bool(const cbor_item_t *, bool *); 620afa8e06SEd Maste int cbor_decode_cred_authdata(const cbor_item_t *, int, fido_blob_t *, 630afa8e06SEd Maste fido_authdata_t *, fido_attcred_t *, fido_cred_ext_t *); 640afa8e06SEd Maste int cbor_decode_assert_authdata(const cbor_item_t *, fido_blob_t *, 650afa8e06SEd Maste fido_authdata_t *, fido_assert_extattr_t *); 660afa8e06SEd Maste int cbor_decode_cred_id(const cbor_item_t *, fido_blob_t *); 670afa8e06SEd Maste int cbor_decode_fmt(const cbor_item_t *, char **); 680afa8e06SEd Maste int cbor_decode_pubkey(const cbor_item_t *, int *, void *); 690afa8e06SEd Maste int cbor_decode_rp_entity(const cbor_item_t *, fido_rp_t *); 700afa8e06SEd Maste int cbor_decode_uint64(const cbor_item_t *, uint64_t *); 710afa8e06SEd Maste int cbor_decode_user(const cbor_item_t *, fido_user_t *); 720afa8e06SEd Maste int es256_pk_decode(const cbor_item_t *, es256_pk_t *); 73*2ccfa855SEd Maste int es384_pk_decode(const cbor_item_t *, es384_pk_t *); 740afa8e06SEd Maste int rs256_pk_decode(const cbor_item_t *, rs256_pk_t *); 750afa8e06SEd Maste int eddsa_pk_decode(const cbor_item_t *, eddsa_pk_t *); 760afa8e06SEd Maste 770afa8e06SEd Maste /* auxiliary cbor routines */ 780afa8e06SEd Maste int cbor_add_bool(cbor_item_t *, const char *, fido_opt_t); 790afa8e06SEd Maste int cbor_add_bytestring(cbor_item_t *, const char *, const unsigned char *, 800afa8e06SEd Maste size_t); 810afa8e06SEd Maste int cbor_add_string(cbor_item_t *, const char *, const char *); 820afa8e06SEd Maste int cbor_array_iter(const cbor_item_t *, void *, int(*)(const cbor_item_t *, 830afa8e06SEd Maste void *)); 840afa8e06SEd Maste int cbor_build_frame(uint8_t, cbor_item_t *[], size_t, fido_blob_t *); 850afa8e06SEd Maste int cbor_bytestring_copy(const cbor_item_t *, unsigned char **, size_t *); 860afa8e06SEd Maste int cbor_map_iter(const cbor_item_t *, void *, int(*)(const cbor_item_t *, 870afa8e06SEd Maste const cbor_item_t *, void *)); 880afa8e06SEd Maste int cbor_string_copy(const cbor_item_t *, char **); 890afa8e06SEd Maste int cbor_parse_reply(const unsigned char *, size_t, void *, 900afa8e06SEd Maste int(*)(const cbor_item_t *, const cbor_item_t *, void *)); 910afa8e06SEd Maste int cbor_add_uv_params(fido_dev_t *, uint8_t, const fido_blob_t *, 920afa8e06SEd Maste const es256_pk_t *, const fido_blob_t *, const char *, const char *, 93f540a430SEd Maste cbor_item_t **, cbor_item_t **, int *); 940afa8e06SEd Maste void cbor_vector_free(cbor_item_t **, size_t); 950afa8e06SEd Maste int cbor_array_append(cbor_item_t **, cbor_item_t *); 960afa8e06SEd Maste int cbor_array_drop(cbor_item_t **, size_t); 970afa8e06SEd Maste 980afa8e06SEd Maste /* deflate */ 990afa8e06SEd Maste int fido_compress(fido_blob_t *, const fido_blob_t *); 1000afa8e06SEd Maste int fido_uncompress(fido_blob_t *, const fido_blob_t *, size_t); 1010afa8e06SEd Maste 1020afa8e06SEd Maste #ifndef nitems 1030afa8e06SEd Maste #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 1040afa8e06SEd Maste #endif 1050afa8e06SEd Maste 1060afa8e06SEd Maste /* buf */ 1070afa8e06SEd Maste int fido_buf_read(const unsigned char **, size_t *, void *, size_t); 1080afa8e06SEd Maste int fido_buf_write(unsigned char **, size_t *, const void *, size_t); 1090afa8e06SEd Maste 1100afa8e06SEd Maste /* hid i/o */ 1110afa8e06SEd Maste void *fido_hid_open(const char *); 1120afa8e06SEd Maste void fido_hid_close(void *); 1130afa8e06SEd Maste int fido_hid_read(void *, unsigned char *, size_t, int); 1140afa8e06SEd Maste int fido_hid_write(void *, const unsigned char *, size_t); 1150afa8e06SEd Maste int fido_hid_get_usage(const uint8_t *, size_t, uint32_t *); 1160afa8e06SEd Maste int fido_hid_get_report_len(const uint8_t *, size_t, size_t *, size_t *); 1170afa8e06SEd Maste int fido_hid_unix_open(const char *); 1180afa8e06SEd Maste int fido_hid_unix_wait(int, int, const fido_sigset_t *); 1190afa8e06SEd Maste int fido_hid_set_sigmask(void *, const fido_sigset_t *); 1200afa8e06SEd Maste size_t fido_hid_report_in_len(void *); 1210afa8e06SEd Maste size_t fido_hid_report_out_len(void *); 1220afa8e06SEd Maste 1230afa8e06SEd Maste /* nfc i/o */ 124*2ccfa855SEd Maste bool fido_is_nfc(const char *); 125*2ccfa855SEd Maste bool nfc_is_fido(const char *); 1260afa8e06SEd Maste void *fido_nfc_open(const char *); 1270afa8e06SEd Maste void fido_nfc_close(void *); 1280afa8e06SEd Maste int fido_nfc_read(void *, unsigned char *, size_t, int); 1290afa8e06SEd Maste int fido_nfc_write(void *, const unsigned char *, size_t); 1300afa8e06SEd Maste int fido_nfc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int); 1310afa8e06SEd Maste int fido_nfc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t); 1320afa8e06SEd Maste int fido_nfc_set_sigmask(void *, const fido_sigset_t *); 133*2ccfa855SEd Maste int fido_dev_set_nfc(fido_dev_t *); 134*2ccfa855SEd Maste 135*2ccfa855SEd Maste /* pcsc i/o */ 136*2ccfa855SEd Maste bool fido_is_pcsc(const char *); 137*2ccfa855SEd Maste void *fido_pcsc_open(const char *); 138*2ccfa855SEd Maste void fido_pcsc_close(void *); 139*2ccfa855SEd Maste int fido_pcsc_read(void *, unsigned char *, size_t, int); 140*2ccfa855SEd Maste int fido_pcsc_write(void *, const unsigned char *, size_t); 141*2ccfa855SEd Maste int fido_pcsc_rx(fido_dev_t *, uint8_t, unsigned char *, size_t, int); 142*2ccfa855SEd Maste int fido_pcsc_tx(fido_dev_t *, uint8_t, const unsigned char *, size_t); 143*2ccfa855SEd Maste int fido_dev_set_pcsc(fido_dev_t *); 1440afa8e06SEd Maste 1450afa8e06SEd Maste /* windows hello */ 1460afa8e06SEd Maste int fido_winhello_manifest(fido_dev_info_t *, size_t, size_t *); 1470afa8e06SEd Maste int fido_winhello_open(fido_dev_t *); 1480afa8e06SEd Maste int fido_winhello_close(fido_dev_t *); 1490afa8e06SEd Maste int fido_winhello_cancel(fido_dev_t *); 150f540a430SEd Maste int fido_winhello_get_assert(fido_dev_t *, fido_assert_t *, const char *, int); 1510afa8e06SEd Maste int fido_winhello_get_cbor_info(fido_dev_t *, fido_cbor_info_t *); 152f540a430SEd Maste int fido_winhello_make_cred(fido_dev_t *, fido_cred_t *, const char *, int); 1530afa8e06SEd Maste 1540afa8e06SEd Maste /* generic i/o */ 155f540a430SEd Maste int fido_rx_cbor_status(fido_dev_t *, int *); 156f540a430SEd Maste int fido_rx(fido_dev_t *, uint8_t, void *, size_t, int *); 157f540a430SEd Maste int fido_tx(fido_dev_t *, uint8_t, const void *, size_t, int *); 1580afa8e06SEd Maste 1590afa8e06SEd Maste /* log */ 1600afa8e06SEd Maste #ifdef FIDO_NO_DIAGNOSTIC 1610afa8e06SEd Maste #define fido_log_init(...) do { /* nothing */ } while (0) 1620afa8e06SEd Maste #define fido_log_debug(...) do { /* nothing */ } while (0) 1630afa8e06SEd Maste #define fido_log_xxd(...) do { /* nothing */ } while (0) 1640afa8e06SEd Maste #define fido_log_error(...) do { /* nothing */ } while (0) 1650afa8e06SEd Maste #else 1660afa8e06SEd Maste #ifdef __GNUC__ 1670afa8e06SEd Maste void fido_log_init(void); 1680afa8e06SEd Maste void fido_log_debug(const char *, ...) 1690afa8e06SEd Maste __attribute__((__format__ (printf, 1, 2))); 1700afa8e06SEd Maste void fido_log_xxd(const void *, size_t, const char *, ...) 1710afa8e06SEd Maste __attribute__((__format__ (printf, 3, 4))); 1720afa8e06SEd Maste void fido_log_error(int, const char *, ...) 1730afa8e06SEd Maste __attribute__((__format__ (printf, 2, 3))); 1740afa8e06SEd Maste #else 1750afa8e06SEd Maste void fido_log_init(void); 1760afa8e06SEd Maste void fido_log_debug(const char *, ...); 1770afa8e06SEd Maste void fido_log_xxd(const void *, size_t, const char *, ...); 1780afa8e06SEd Maste void fido_log_error(int, const char *, ...); 1790afa8e06SEd Maste #endif /* __GNUC__ */ 1800afa8e06SEd Maste #endif /* FIDO_NO_DIAGNOSTIC */ 1810afa8e06SEd Maste 1820afa8e06SEd Maste /* u2f */ 183f540a430SEd Maste int u2f_register(fido_dev_t *, fido_cred_t *, int *); 184f540a430SEd Maste int u2f_authenticate(fido_dev_t *, fido_assert_t *, int *); 185f540a430SEd Maste int u2f_get_touch_begin(fido_dev_t *, int *); 186f540a430SEd Maste int u2f_get_touch_status(fido_dev_t *, int *, int *); 1870afa8e06SEd Maste 1880afa8e06SEd Maste /* unexposed fido ops */ 1890afa8e06SEd Maste uint8_t fido_dev_get_pin_protocol(const fido_dev_t *); 190f540a430SEd Maste int fido_dev_authkey(fido_dev_t *, es256_pk_t *, int *); 191f540a430SEd Maste int fido_dev_get_cbor_info_wait(fido_dev_t *, fido_cbor_info_t *, int *); 1920afa8e06SEd Maste int fido_dev_get_uv_token(fido_dev_t *, uint8_t, const char *, 193f540a430SEd Maste const fido_blob_t *, const es256_pk_t *, const char *, fido_blob_t *, 194f540a430SEd Maste int *); 1950afa8e06SEd Maste uint64_t fido_dev_maxmsgsize(const fido_dev_t *); 196f540a430SEd Maste int fido_do_ecdh(fido_dev_t *, es256_pk_t **, fido_blob_t **, int *); 1970afa8e06SEd Maste 198f540a430SEd Maste /* types */ 199f540a430SEd Maste void fido_algo_array_free(fido_algo_array_t *); 200f540a430SEd Maste void fido_byte_array_free(fido_byte_array_t *); 201*2ccfa855SEd Maste void fido_cert_array_free(fido_cert_array_t *); 202f540a430SEd Maste void fido_opt_array_free(fido_opt_array_t *); 203f540a430SEd Maste void fido_str_array_free(fido_str_array_t *); 204f540a430SEd Maste void fido_algo_free(fido_algo_t *); 205f540a430SEd Maste int fido_str_array_pack(fido_str_array_t *, const char * const *, size_t); 206f540a430SEd Maste 2070afa8e06SEd Maste /* misc */ 2080afa8e06SEd Maste void fido_assert_reset_rx(fido_assert_t *); 2090afa8e06SEd Maste void fido_assert_reset_tx(fido_assert_t *); 2100afa8e06SEd Maste void fido_cred_reset_rx(fido_cred_t *); 2110afa8e06SEd Maste void fido_cred_reset_tx(fido_cred_t *); 2120afa8e06SEd Maste void fido_cbor_info_reset(fido_cbor_info_t *); 2130afa8e06SEd Maste int fido_blob_serialise(fido_blob_t *, const cbor_item_t *); 2140afa8e06SEd Maste int fido_check_flags(uint8_t, fido_opt_t, fido_opt_t); 2150afa8e06SEd Maste int fido_check_rp_id(const char *, const unsigned char *); 2160afa8e06SEd Maste int fido_get_random(void *, size_t); 2170afa8e06SEd Maste int fido_sha256(fido_blob_t *, const u_char *, size_t); 218f540a430SEd Maste int fido_time_now(struct timespec *); 219f540a430SEd Maste int fido_time_delta(const struct timespec *, int *); 220*2ccfa855SEd Maste int fido_to_uint64(const char *, int, uint64_t *); 2210afa8e06SEd Maste 2220afa8e06SEd Maste /* crypto */ 223f540a430SEd Maste int es256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); 224*2ccfa855SEd Maste int es384_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); 225f540a430SEd Maste int rs256_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); 226f540a430SEd Maste int eddsa_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); 227f540a430SEd Maste int rs1_verify_sig(const fido_blob_t *, EVP_PKEY *, const fido_blob_t *); 228f540a430SEd Maste int es256_pk_verify_sig(const fido_blob_t *, const es256_pk_t *, 2290afa8e06SEd Maste const fido_blob_t *); 230*2ccfa855SEd Maste int es384_pk_verify_sig(const fido_blob_t *, const es384_pk_t *, 231*2ccfa855SEd Maste const fido_blob_t *); 232f540a430SEd Maste int rs256_pk_verify_sig(const fido_blob_t *, const rs256_pk_t *, 2330afa8e06SEd Maste const fido_blob_t *); 234f540a430SEd Maste int eddsa_pk_verify_sig(const fido_blob_t *, const eddsa_pk_t *, 2350afa8e06SEd Maste const fido_blob_t *); 2360afa8e06SEd Maste int fido_get_signed_hash(int, fido_blob_t *, const fido_blob_t *, 2370afa8e06SEd Maste const fido_blob_t *); 238f540a430SEd Maste int fido_get_signed_hash_tpm(fido_blob_t *, const fido_blob_t *, 239f540a430SEd Maste const fido_blob_t *, const fido_attstmt_t *, const fido_attcred_t *); 2400afa8e06SEd Maste 2410afa8e06SEd Maste /* device manifest functions */ 2420afa8e06SEd Maste int fido_hid_manifest(fido_dev_info_t *, size_t, size_t *); 2430afa8e06SEd Maste int fido_nfc_manifest(fido_dev_info_t *, size_t, size_t *); 244*2ccfa855SEd Maste int fido_pcsc_manifest(fido_dev_info_t *, size_t, size_t *); 2450afa8e06SEd Maste 2460afa8e06SEd Maste /* fuzzing instrumentation */ 2470afa8e06SEd Maste #ifdef FIDO_FUZZ 2480afa8e06SEd Maste uint32_t uniform_random(uint32_t); 2490afa8e06SEd Maste #endif 2500afa8e06SEd Maste 2510afa8e06SEd Maste /* internal device capability flags */ 2520afa8e06SEd Maste #define FIDO_DEV_PIN_SET 0x001 2530afa8e06SEd Maste #define FIDO_DEV_PIN_UNSET 0x002 2540afa8e06SEd Maste #define FIDO_DEV_CRED_PROT 0x004 2550afa8e06SEd Maste #define FIDO_DEV_CREDMAN 0x008 2560afa8e06SEd Maste #define FIDO_DEV_PIN_PROTOCOL1 0x010 2570afa8e06SEd Maste #define FIDO_DEV_PIN_PROTOCOL2 0x020 2580afa8e06SEd Maste #define FIDO_DEV_UV_SET 0x040 2590afa8e06SEd Maste #define FIDO_DEV_UV_UNSET 0x080 2600afa8e06SEd Maste #define FIDO_DEV_TOKEN_PERMS 0x100 2610afa8e06SEd Maste #define FIDO_DEV_WINHELLO 0x200 2620afa8e06SEd Maste 2630afa8e06SEd Maste /* miscellanea */ 2640afa8e06SEd Maste #define FIDO_DUMMY_CLIENTDATA "" 2650afa8e06SEd Maste #define FIDO_DUMMY_RP_ID "localhost" 2660afa8e06SEd Maste #define FIDO_DUMMY_USER_NAME "dummy" 2670afa8e06SEd Maste #define FIDO_DUMMY_USER_ID 1 2680afa8e06SEd Maste #define FIDO_WINHELLO_PATH "windows://hello" 269f540a430SEd Maste #define FIDO_NFC_PREFIX "nfc:" 270*2ccfa855SEd Maste #define FIDO_PCSC_PREFIX "pcsc:" 2710afa8e06SEd Maste 2720afa8e06SEd Maste #ifdef __cplusplus 2730afa8e06SEd Maste } /* extern "C" */ 2740afa8e06SEd Maste #endif /* __cplusplus */ 2750afa8e06SEd Maste 2760afa8e06SEd Maste #endif /* !_EXTERN_H */ 277