1 /* 2 * Copyright (c) 2018-2024 Yubico AB. All rights reserved. 3 * SPDX-License-Identifier: BSD-2-Clause 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in 13 * the documentation and/or other materials provided with the 14 * distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef _FIDO_TYPES_H 30 #define _FIDO_TYPES_H 31 32 #ifdef __MINGW32__ 33 #include <sys/types.h> 34 #endif 35 36 #include <signal.h> 37 #include <stddef.h> 38 #include <stdint.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif /* __cplusplus */ 43 44 struct fido_dev; 45 46 typedef void *fido_dev_io_open_t(const char *); 47 typedef void fido_dev_io_close_t(void *); 48 typedef int fido_dev_io_read_t(void *, unsigned char *, size_t, int); 49 typedef int fido_dev_io_write_t(void *, const unsigned char *, size_t); 50 typedef int fido_dev_rx_t(struct fido_dev *, uint8_t, unsigned char *, size_t, int); 51 typedef int fido_dev_tx_t(struct fido_dev *, uint8_t, const unsigned char *, size_t); 52 53 typedef struct fido_dev_io { 54 fido_dev_io_open_t *open; 55 fido_dev_io_close_t *close; 56 fido_dev_io_read_t *read; 57 fido_dev_io_write_t *write; 58 } fido_dev_io_t; 59 60 typedef struct fido_dev_transport { 61 fido_dev_rx_t *rx; 62 fido_dev_tx_t *tx; 63 } fido_dev_transport_t; 64 65 typedef enum { 66 FIDO_OPT_OMIT = 0, /* use authenticator's default */ 67 FIDO_OPT_FALSE, /* explicitly set option to false */ 68 FIDO_OPT_TRUE, /* explicitly set option to true */ 69 } fido_opt_t; 70 71 typedef void fido_log_handler_t(const char *); 72 73 #undef _FIDO_SIGSET_DEFINED 74 #define _FIDO_SIGSET_DEFINED 75 #ifdef _WIN32 76 typedef int fido_sigset_t; 77 #elif defined(SIG_BLOCK) 78 typedef sigset_t fido_sigset_t; 79 #else 80 #undef _FIDO_SIGSET_DEFINED 81 #endif 82 83 #ifdef _FIDO_INTERNAL 84 #include "packed.h" 85 #include "blob.h" 86 87 /* COSE ES256 (ECDSA over P-256 with SHA-256) public key */ 88 typedef struct es256_pk { 89 unsigned char x[32]; 90 unsigned char y[32]; 91 } es256_pk_t; 92 93 /* COSE ES256 (ECDSA over P-256 with SHA-256) (secret) key */ 94 typedef struct es256_sk { 95 unsigned char d[32]; 96 } es256_sk_t; 97 98 /* COSE ES384 (ECDSA over P-384 with SHA-384) public key */ 99 typedef struct es384_pk { 100 unsigned char x[48]; 101 unsigned char y[48]; 102 } es384_pk_t; 103 104 /* COSE RS256 (2048-bit RSA with PKCS1 padding and SHA-256) public key */ 105 typedef struct rs256_pk { 106 unsigned char n[256]; 107 unsigned char e[3]; 108 } rs256_pk_t; 109 110 /* COSE EDDSA (ED25519) */ 111 typedef struct eddsa_pk { 112 unsigned char x[32]; 113 } eddsa_pk_t; 114 115 PACKED_TYPE(fido_authdata_t, 116 struct fido_authdata { 117 unsigned char rp_id_hash[32]; /* sha256 of fido_rp.id */ 118 uint8_t flags; /* user present/verified */ 119 uint32_t sigcount; /* signature counter */ 120 /* actually longer */ 121 }) 122 123 PACKED_TYPE(fido_attcred_raw_t, 124 struct fido_attcred_raw { 125 unsigned char aaguid[16]; /* credential's aaguid */ 126 uint16_t id_len; /* credential id length */ 127 uint8_t body[]; /* credential id + pubkey */ 128 }) 129 130 typedef struct fido_attcred { 131 unsigned char aaguid[16]; /* credential's aaguid */ 132 fido_blob_t id; /* credential id */ 133 int type; /* credential's cose algorithm */ 134 union { /* credential's public key */ 135 es256_pk_t es256; 136 es384_pk_t es384; 137 rs256_pk_t rs256; 138 eddsa_pk_t eddsa; 139 } pubkey; 140 } fido_attcred_t; 141 142 typedef struct fido_attstmt { 143 fido_blob_t certinfo; /* tpm attestation TPMS_ATTEST structure */ 144 fido_blob_t pubarea; /* tpm attestation TPMT_PUBLIC structure */ 145 fido_blob_t cbor; /* cbor-encoded attestation statement */ 146 fido_blob_array_t x5c; /* attestation certificate chain */ 147 fido_blob_t sig; /* attestation signature */ 148 int alg; /* attestation algorithm (cose) */ 149 } fido_attstmt_t; 150 151 typedef struct fido_rp { 152 char *id; /* relying party id */ 153 char *name; /* relying party name */ 154 } fido_rp_t; 155 156 typedef struct fido_user { 157 fido_blob_t id; /* required */ 158 char *icon; /* optional */ 159 char *name; /* optional */ 160 char *display_name; /* required */ 161 } fido_user_t; 162 163 typedef struct fido_cred_ext { 164 int mask; /* enabled extensions */ 165 int prot; /* protection policy */ 166 size_t minpinlen; /* minimum pin length */ 167 } fido_cred_ext_t; 168 169 typedef struct fido_cred_ea { 170 int mode; 171 bool att; 172 } fido_cred_ea_t; 173 174 typedef struct fido_cred { 175 fido_blob_t cd; /* client data */ 176 fido_blob_t cdh; /* client data hash */ 177 fido_rp_t rp; /* relying party */ 178 fido_user_t user; /* user entity */ 179 fido_blob_array_t excl; /* list of credential ids to exclude */ 180 fido_opt_t rk; /* resident key */ 181 fido_opt_t uv; /* user verification */ 182 fido_cred_ext_t ext; /* extensions */ 183 int type; /* cose algorithm */ 184 char *fmt; /* credential format */ 185 fido_cred_ext_t authdata_ext; /* decoded extensions */ 186 fido_blob_t authdata_cbor; /* cbor-encoded payload */ 187 fido_blob_t authdata_raw; /* cbor-decoded payload */ 188 fido_authdata_t authdata; /* decoded authdata payload */ 189 fido_attcred_t attcred; /* returned credential (key + id) */ 190 fido_attstmt_t attstmt; /* attestation statement (x509 + sig) */ 191 fido_blob_t largeblob_key; /* decoded large blob key */ 192 fido_blob_t blob; /* CTAP 2.1 credBlob */ 193 fido_cred_ea_t ea; /* enterprise attestation */ 194 } fido_cred_t; 195 196 typedef struct fido_assert_extattr { 197 int mask; /* decoded extensions */ 198 fido_blob_t hmac_secret_enc; /* hmac secret, encrypted */ 199 fido_blob_t blob; /* decoded CTAP 2.1 credBlob */ 200 } fido_assert_extattr_t; 201 202 typedef struct _fido_assert_stmt { 203 fido_blob_t id; /* credential id */ 204 fido_user_t user; /* user attributes */ 205 fido_blob_t hmac_secret; /* hmac secret */ 206 fido_assert_extattr_t authdata_ext; /* decoded extensions */ 207 fido_blob_t authdata_cbor; /* raw cbor payload */ 208 fido_blob_t authdata_raw; /* raw authdata */ 209 fido_authdata_t authdata; /* decoded authdata payload */ 210 fido_blob_t sig; /* signature of cdh + authdata */ 211 fido_blob_t largeblob_key; /* decoded large blob key */ 212 } fido_assert_stmt; 213 214 typedef struct fido_assert_ext { 215 int mask; /* enabled extensions */ 216 fido_blob_t hmac_salt; /* optional hmac-secret salt */ 217 } fido_assert_ext_t; 218 219 typedef struct fido_assert { 220 char *rp_id; /* relying party id */ 221 char *appid; /* winhello u2f appid */ 222 fido_blob_t cd; /* client data */ 223 fido_blob_t cdh; /* client data hash */ 224 fido_blob_array_t allow_list; /* list of allowed credentials */ 225 fido_opt_t up; /* user presence */ 226 fido_opt_t uv; /* user verification */ 227 fido_assert_ext_t ext; /* enabled extensions */ 228 fido_assert_stmt *stmt; /* array of expected assertions */ 229 size_t stmt_cnt; /* number of allocated assertions */ 230 size_t stmt_len; /* number of received assertions */ 231 } fido_assert_t; 232 233 typedef struct fido_opt_array { 234 char **name; 235 bool *value; 236 size_t len; 237 } fido_opt_array_t; 238 239 typedef struct fido_str_array { 240 char **ptr; 241 size_t len; 242 } fido_str_array_t; 243 244 typedef struct fido_byte_array { 245 uint8_t *ptr; 246 size_t len; 247 } fido_byte_array_t; 248 249 typedef struct fido_algo { 250 char *type; 251 int cose; 252 } fido_algo_t; 253 254 typedef struct fido_algo_array { 255 fido_algo_t *ptr; 256 size_t len; 257 } fido_algo_array_t; 258 259 typedef struct fido_cert_array { 260 char **name; 261 uint64_t *value; 262 size_t len; 263 } fido_cert_array_t; 264 265 typedef struct fido_cbor_info { 266 fido_str_array_t versions; /* supported versions: fido2|u2f */ 267 fido_str_array_t extensions; /* list of supported extensions */ 268 fido_str_array_t transports; /* list of supported transports */ 269 unsigned char aaguid[16]; /* aaguid */ 270 fido_opt_array_t options; /* list of supported options */ 271 uint64_t maxmsgsiz; /* maximum message size */ 272 fido_byte_array_t protocols; /* supported pin protocols */ 273 fido_algo_array_t algorithms; /* list of supported algorithms */ 274 uint64_t maxcredcntlst; /* max credentials in list */ 275 uint64_t maxcredidlen; /* max credential ID length */ 276 uint64_t fwversion; /* firmware version */ 277 uint64_t maxcredbloblen; /* max credBlob length */ 278 uint64_t maxlargeblob; /* max largeBlob array length */ 279 uint64_t maxrpid_minlen; /* max rpid in set_pin_minlen_rpid */ 280 uint64_t minpinlen; /* min pin len enforced */ 281 uint64_t uv_attempts; /* platform uv attempts */ 282 uint64_t uv_modality; /* bitmask of supported uv types */ 283 int64_t rk_remaining; /* remaining resident credentials */ 284 bool new_pin_reqd; /* new pin required */ 285 fido_cert_array_t certs; /* associated certifications */ 286 } fido_cbor_info_t; 287 288 typedef struct fido_dev_info { 289 char *path; /* device path */ 290 int16_t vendor_id; /* 2-byte vendor id */ 291 int16_t product_id; /* 2-byte product id */ 292 char *manufacturer; /* manufacturer string */ 293 char *product; /* product string */ 294 fido_dev_io_t io; /* i/o functions */ 295 fido_dev_transport_t transport; /* transport functions */ 296 } fido_dev_info_t; 297 298 PACKED_TYPE(fido_ctap_info_t, 299 /* defined in section 8.1.9.1.3 (CTAPHID_INIT) of the fido2 ctap spec */ 300 struct fido_ctap_info { 301 uint64_t nonce; /* echoed nonce */ 302 uint32_t cid; /* channel id */ 303 uint8_t protocol; /* ctaphid protocol id */ 304 uint8_t major; /* major version number */ 305 uint8_t minor; /* minor version number */ 306 uint8_t build; /* build version number */ 307 uint8_t flags; /* capabilities flags; see FIDO_CAP_* */ 308 }) 309 310 typedef struct fido_dev { 311 uint64_t nonce; /* issued nonce */ 312 fido_ctap_info_t attr; /* device attributes */ 313 uint32_t cid; /* assigned channel id */ 314 char *path; /* device path */ 315 void *io_handle; /* abstract i/o handle */ 316 fido_dev_io_t io; /* i/o functions */ 317 bool io_own; /* device has own io/transport */ 318 size_t rx_len; /* length of HID input reports */ 319 size_t tx_len; /* length of HID output reports */ 320 int flags; /* internal flags; see FIDO_DEV_* */ 321 fido_dev_transport_t transport; /* transport functions */ 322 uint64_t maxmsgsize; /* max message size */ 323 int timeout_ms; /* read timeout in ms */ 324 } fido_dev_t; 325 326 #else 327 typedef struct fido_assert fido_assert_t; 328 typedef struct fido_cbor_info fido_cbor_info_t; 329 typedef struct fido_cred fido_cred_t; 330 typedef struct fido_dev fido_dev_t; 331 typedef struct fido_dev_info fido_dev_info_t; 332 typedef struct es256_pk es256_pk_t; 333 typedef struct es256_sk es256_sk_t; 334 typedef struct es384_pk es384_pk_t; 335 typedef struct rs256_pk rs256_pk_t; 336 typedef struct eddsa_pk eddsa_pk_t; 337 #endif /* _FIDO_INTERNAL */ 338 339 #ifdef __cplusplus 340 } /* extern "C" */ 341 #endif /* __cplusplus */ 342 343 #endif /* !_FIDO_TYPES_H */ 344