diff --git a/fido2/device.h b/fido2/device.h index b85deee..e0919ea 100644 --- a/fido2/device.h +++ b/fido2/device.h @@ -9,65 +9,159 @@ #include "storage.h" - +/** Return a millisecond timestamp. Does not need to be synchronized to anything. + * *Optional* to compile, but will not calculate delays correctly without a correct implementation. +*/ uint32_t millis(); -// HID message size in bytes -#define HID_MESSAGE_SIZE 64 - -void usbhid_init(); - -int usbhid_recv(uint8_t * msg); +/** Called by HIDUSB layer to write bytes to the USB HID interface endpoint. + * Will write 64 bytes at a time. + * + * @param msg Pointer to a 64 byte buffer containing a payload to be sent via USB HID. + * + * **Required** to compile and work for FIDO application. +*/ void usbhid_send(uint8_t * msg); -void usbhid_close(); - +/** Reboot / power reset the device. + * **Optional** this is not used for FIDO2, and simply won't do anything if not implemented. +*/ void device_reboot(); -void authenticator_read_state(AuthenticatorState * ); - -void authenticator_read_backup_state(AuthenticatorState * ); - -// Return 1 yes backup is init'd, else 0 -//void authenticator_initialize() -int authenticator_is_backup_initialized(); - -void authenticator_write_state(AuthenticatorState *, int backup); - +/** Read AuthenticatorState from nonvolatile memory. + * @param s pointer to AuthenticatorState buffer to be overwritten with contents from NV memory. + * @return 0 - state stored is NOT initialized. + * 1 - state stored is initialized. + * + * *Optional* this is required to make persistant updates to FIDO2 State (PIN and device master secret). + * Without it, changes simply won't be persistant. +*/ +int authenticator_read_state(AuthenticatorState * s); +/** Store changes in the authenticator state to nonvolatile memory. + * @param s pointer to valid Authenticator state to write to NV memory. + * + * *Optional* this is required to make persistant updates to FIDO2 State (PIN and device master secret). + * Without it, changes simply won't be persistant. + */ +void authenticator_write_state(AuthenticatorState * s); // sets status that's uses for sending status updates ~100ms. // A timer should be set up to call `ctaphid_update_status` + +/** Updates status of the status of the FIDO2 layer application, which + * can be used for polling updates in the USBHID layer. + * + * @param status is one of the following, which can be used appropriately by USB HID layer. + #define CTAPHID_STATUS_IDLE 0 + #define CTAPHID_STATUS_PROCESSING 1 + #define CTAPHID_STATUS_UPNEEDED 2 + * + * *Optional* to compile and run, but will be required to be used for proper FIDO2 operation with some platforms. +*/ void device_set_status(uint32_t status); -// Returns if button is currently pressed +/** Returns true if button is currently pressed. Debouncing does not need to be handled. Should not block. + * @return 1 if button is currently pressed. + * + * *Optional* to compile and run, but just returns one by default. +*/ int device_is_button_pressed(); -// Test for user presence +// // Return 2 for disabled, 1 for user is present, 0 user not present, -1 if cancel is requested. +/** Test for user presence. + * Perform test that user is present. Returns status on user presence. This is used by FIDO and U2F layer + * to check if an operation should continue, or if the UP flag should be set. + * + * @param delay number of milliseconds to delay waiting for user before timeout. + * + * @return 2 - User presence is disabled. Operation should continue, but UP flag not set. + * 1 - User presence confirmed. Operation should continue, and UP flag is set. + * 0 - User presence is not confirmed. Operation should be denied. + * -1 - Operation was canceled. Do not continue, reset transaction state. + * + * *Optional*, the default implementation will return 1, unless a FIDO2 operation calls for no UP, where this will then return 2. +*/ int ctap_user_presence_test(uint32_t delay); -// Generate @num bytes of random numbers to @dest -// return 1 if success, error otherwise +/** Disable the next user presence test. This is called by FIDO2 layer when a transaction + * requests UP to be disabled. The next call to ctap_user_presence_test should return 2, + * and then UP should be enabled again. + * + * @param request_active indicate to activate (true) or disable (false) UP. + * + * *Optional*, the default implementation will provide expected behaviour with the default ctap_user_presence_test(...). +*/ +void device_disable_up(bool request_active); + +/** Generate random numbers. Random numbers should be good enough quality for + * cryptographic use. + * + * @param dst the buffer to write into. + * @param num the number of bytes to generate and write to dst. + * + * @return 1 if successful, or else the RNG failed. + * + * *Optional*, if not implemented, the random numbers will be from rand() and an error will be logged. +*/ int ctap_generate_rng(uint8_t * dst, size_t num); -// Increment atomic counter and return it. -// @param amount the amount to increase the counter by. +/** Increment an atomic (non-volatile) counter and return the value. + * + * @param amount a non-zero amount to increment the counter by. + * + * *Optional*, if not implemented, the counter will not be persistant. +*/ uint32_t ctap_atomic_count(uint32_t amount); - -// Resident key +/** Delete all resident keys. + * + * *Optional*, if not implemented, operates on non-persistant RK's. +*/ void ctap_reset_rk(); + +/** Return the maximum amount of resident keys that can be stored. + * @return max number of resident keys that can be stored, including already stored RK's. + * + * *Optional*, if not implemented, returns 50. +*/ uint32_t ctap_rk_size(); + +/** Store a resident key into an index between [ 0, ctap_rk_size() ). + * Storage should be in non-volatile memory. + * + * @param index between RK index range. + * @param rk pointer to valid rk structure that should be written to NV memory. + * + * *Optional*, if not implemented, operates on non-persistant RK's. +*/ void ctap_store_rk(int index,CTAP_residentKey * rk); + +/** Read a resident key from an index into memory + * @param index to read resident key from. + * @param rk pointer to resident key structure to write into with RK. + * + * *Optional*, if not implemented, operates on non-persistant RK's. +*/ void ctap_load_rk(int index,CTAP_residentKey * rk); + +/** Overwrite the RK located in index with a new RK. + * @param index to write resident key to. + * @param rk pointer to valid rk structure that should be written to NV memory, and replace existing RK there. + * + * *Optional*, if not implemented, operates on non-persistant RK's. +*/ void ctap_overwrite_rk(int index,CTAP_residentKey * rk); - -// HID wink command +/** Called by HID layer to indicate that a wink behavior should be performed. + * Should not block, and the wink behavior should occur in parallel to FIDO operations. + * + * *Optional*. +*/ void device_wink(); typedef enum { @@ -76,27 +170,42 @@ typedef enum { DEVICE_FAST = 2, } DEVICE_CLOCK_RATE; -// Set the clock rate for the device. -// Three modes are targetted for Solo. -// 0: Lowest clock rate for NFC. -// 1: fastest clock rate supported at a low power setting for NFC FIDO. -// 2: fastest clock rate. Generally for USB interface. +/** + * Set the clock rate for the device. This gets called only when the device is running in NFC mode. + * Before Register and authenticate operations, the clock rate will be set to (1), and otherwise back to (0). + * @param param + 0: Lowest clock rate for NFC. + 1: fastest clock rate supported at a low power setting for NFC FIDO. + 2: fastest clock rate. Generally for USB interface. +* *Optional*, by default nothing happens. +*/ void device_set_clock_rate(DEVICE_CLOCK_RATE param); // Returns NFC_IS_NA, NFC_IS_ACTIVE, or NFC_IS_AVAILABLE #define NFC_IS_NA 0 #define NFC_IS_ACTIVE 1 #define NFC_IS_AVAILABLE 2 -int device_is_nfc(); -void device_disable_up(bool request_active); +/** Returns NFC status of the device. + * @return 0 - NFC is not available. + * 1 - NFC is active, and is powering the chip for a transaction. + * 2 - NFC is available, but not currently being used. +*/ +int device_is_nfc(); /** Return pointer to attestation key. + * @return pointer to attestation private key, raw encoded. For P256, this is 32 bytes. */ uint8_t * device_get_attestation_key(); + +/** Pointer to a ASN.1/DER encoded byte array of the attestation certificate. +*/ extern const uint8_t * attestation_cert_der; +/** Returns the size in bytes of attestation_cert_der. + * @return number of bytes in attestation_cert_der, not including any C string null byte. +*/ uint16_t device_attestation_cert_der_get_size(); #endif