-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
sys/fido2: improve & simplify flash handling #21110
base: master
Are you sure you want to change the base?
sys/fido2: improve & simplify flash handling #21110
Conversation
771229a
to
8fdb7a6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, some comments below. I'm not very familiar with the mtd API, maybe @benpicco could have a look as well?
sys/fido2/ctap/ctap.c
Outdated
@@ -15,6 +15,7 @@ | |||
* @} | |||
*/ | |||
|
|||
#include "fido2/ctap/ctap.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is there fido2/ctap/ctap.h
and fido2/ctap.h
below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The file fido2/ctap/ctap.h
contains definitions that are internal to the CTAP module, while fido2/ctap.h
provides definitions intended for external modules that interact with the FIDO2 API.
sys/fido2/ctap/ctap.c
Outdated
#define ENABLE_DEBUG (0) | ||
#include "debug.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define ENABLE_DEBUG (0) | |
#include "debug.h" | |
#define ENABLE_DEBUG 0 | |
#include "debug.h" |
@@ -424,10 +425,12 @@ static uint32_t get_id(void) | |||
|
|||
static int _reset(void) | |||
{ | |||
int ret = fido2_ctap_mem_erase_flash(); | |||
if (_state.initialized_marker == CTAP_INITIALIZED_MARKER) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (_state.initialized_marker == CTAP_INITIALIZED_MARKER) { | |
if (_state.initialized_marker != CTAP_INITIALIZED_MARKER) { |
or could you explain the semantics of CTAP_INITIALIZED_MARKER
, maybe with a comment?
sys/fido2/ctap/ctap_mem.c
Outdated
#include "mtd_flashpage.h" | ||
|
||
#include "fido2/ctap/ctap_mem.h" | ||
#include "fido2/ctap/ctap_utils.h" | ||
|
||
#define ENABLE_DEBUG (0) | ||
#define ENABLE_DEBUG (0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#define ENABLE_DEBUG (0) | |
#define ENABLE_DEBUG 0 |
(as suggested by the static tests)
|
||
ctap_status_code_t fido2_ctap_mem_init(void) | ||
{ | ||
#ifdef BOARD_NATIVE | ||
_mtd_dev = mtd_default_get_dev(0); | ||
#else | ||
_mtd_dev = mtd_aux; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does mtd_aux
come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This device comes from the periph_flashpage_aux
feature which allows to reserve flash memory by using the auxiliary flash slot
|
||
int ret = mtd_erase(_mtd_dev, addr, sector_size * CONFIG_FIDO2_CTAP_NUM_FLASHPAGES); | ||
int ret = mtd_erase_sector(_mtd_dev, 0, sector_cnt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we sure this would not clash with other usages of the same mtd device?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I think this would happen. Hence also the question to @benpicco if there is a way to divide the aux slot somehow such that two applications can use it without risking to corrupt each others data
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have such mechanism for MTD, I'd say this is out of scope for this PR.
I think there really can't be an automatic solution for this - a concrete application would depend on the MTD device (and size) used anyway.
One could use mtd_mapper
to share a MTD device, but again this is out of scope - using the MTD abstraction already helps a lot with flexibility.
uint32_t *addr) | ||
ctap_status_code_t fido2_ctap_mem_read_rk_from_flash(ctap_resident_key_t *key, | ||
const uint8_t *rp_id_hash, | ||
uint32_t *off) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason you don't pass the off by value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done to enable going through all the stored fido2 credentials one by one as done here.
I could also change the function to use callback but this would increase complexity I think.
end = amt_stored; | ||
*addr = _flash_start_addr() + FLASHPAGE_SIZE; | ||
/* skip ctap_state_t struct */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am skipping the ctap_state_t
struct since i am reading resident keys from flash in this function and it doesn't make sense to read the state struct for this
* | ||
* @param[in] key pointer to authenticator state | ||
* @param[in] rp_id_hash pointer to hash of rp domain string | ||
* @param[in] addr pointer to address where to read from | ||
* @param[in] absolute_offset pointer to a variable holding the total offset from the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the parameter is called off
in the implementation. Would be nice to align both.
From an API perspective, I would be nicer to have some iterator struct, that hides the offset information from the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, do you have an example for an iterator struct somewhere in RIOT ?
@@ -5,14 +5,11 @@ ifneq (,$(filter fido2_ctap_%,$(USEMODULE))) | |||
USEMODULE += ztimer64_msec | |||
USEMODULE += usbus_hid | |||
DISABLE_MODULE += auto_init_usbus | |||
FEATURES_REQUIRED += periph_flashpage_aux |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd put that into the application and make the MTD device configurable for the module.
#include "debug.h" | ||
|
||
static mtd_dev_t *_mtd_dev; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
static mtd_dev_t *_mtd_dev; | |
static mtd_dev_t *_mtd_dev = CONFIG_FIDO2_MTD_DEV; |
We should make the application select this
uint32_t used_pages = (CTAP_FLASH_STATE_SZ + state->rk_amount_stored * CTAP_FLASH_RK_SZ + | ||
_mtd_dev->page_size - 1) / _mtd_dev->page_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uint32_t used_pages = (CTAP_FLASH_STATE_SZ + state->rk_amount_stored * CTAP_FLASH_RK_SZ + | |
_mtd_dev->page_size - 1) / _mtd_dev->page_size; | |
uint32_t used_pages = DIV_ROUND_UP(CTAP_FLASH_STATE_SZ + state->rk_amount_stored * CTAP_FLASH_RK_SZ, _mtd_dev->page_size); |
return CTAP1_ERR_OTHER; | ||
} | ||
|
||
if (*off > CTAP_FLASH_STATE_SZ && (*off - CTAP_FLASH_STATE_SZ) % CTAP_FLASH_RK_SZ != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could need an explanation
Contribution description
This PR tries to improve the flash handling done by the FIDO2 implementation. Specifically this entails:
mtd_aux
device to reserve flash memory for the FIDO2 data_flash_is_erased
function)mtd_flashpage
apiSince the AUX slot approach is integrated into the
mtd
API, which is the recommended method for working with flash, I wonder if theperiph_flashpage_in_address_space
feature I added to reserve flash memory for FIDO2 can now be deprecated ?@benpicco, with the
mtd_aux
approach, how can two different applications reserve flash memory without risking corruption of each other's data? Is it possible to divide the AUX slot into multiple smaller slots, that can be allocated for use by different applications?Testing procedure
/tests/sys/fido2_ctap
with bothnative
andnrf52840dk
as target/tests/sys/fido2_ctap_hid