mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
157 lines
3.1 KiB
C
157 lines
3.1 KiB
C
/*
|
|
* Copyright (C) 2021 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup fido2_ctap_mem
|
|
* @{
|
|
* @file
|
|
*
|
|
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
|
|
* @}
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "mtd.h"
|
|
#include "mtd_flashpage.h"
|
|
|
|
#include "fido2/ctap/ctap_mem.h"
|
|
|
|
#define ENABLE_DEBUG (0)
|
|
#include "debug.h"
|
|
|
|
/**
|
|
* @brief MTD device descriptor initialized with flash-page driver
|
|
*/
|
|
static mtd_dev_t _mtd_dev = MTD_FLASHPAGE_INIT_VAL(CTAP_FLASH_PAGES_PER_SECTOR);
|
|
|
|
/**
|
|
* @brief Max amount of resident keys that can be stored
|
|
*/
|
|
static uint16_t _max_rk_amnt;
|
|
|
|
/**
|
|
* @brief Check if flash region is erased
|
|
*/
|
|
static bool _flash_is_erased(int page, int offset, size_t len);
|
|
|
|
/**
|
|
* @brief Get amount of flashpages
|
|
*/
|
|
static unsigned _amount_of_flashpages(void);
|
|
|
|
int fido2_ctap_mem_init(void)
|
|
{
|
|
int ret;
|
|
|
|
ret = mtd_init(&_mtd_dev);
|
|
|
|
if (ret < 0) {
|
|
return ret;
|
|
}
|
|
|
|
for (unsigned i = CTAP_FLASH_RK_START_PAGE; i < _amount_of_flashpages(); i++) {
|
|
_max_rk_amnt += flashpage_size(i) / CTAP_FLASH_RK_SZ;
|
|
}
|
|
|
|
return CTAP2_OK;
|
|
}
|
|
|
|
static unsigned _amount_of_flashpages(void)
|
|
{
|
|
return _mtd_dev.sector_count * _mtd_dev.pages_per_sector;
|
|
}
|
|
|
|
int fido2_ctap_mem_read(void *buf, uint32_t page, uint32_t offset, uint32_t len)
|
|
{
|
|
assert(buf);
|
|
|
|
int ret;
|
|
|
|
ret = mtd_read_page(&_mtd_dev, buf, page, offset, len);
|
|
|
|
if (ret < 0) {
|
|
return CTAP1_ERR_OTHER;
|
|
}
|
|
|
|
return CTAP2_OK;
|
|
}
|
|
|
|
int fido2_ctap_mem_write(const void *buf, uint32_t page, uint32_t offset, uint32_t len)
|
|
{
|
|
assert(buf);
|
|
|
|
int ret;
|
|
|
|
if (!_flash_is_erased(page, offset, len)) {
|
|
ret = mtd_write_page(&_mtd_dev, buf, page, offset, len);
|
|
|
|
if (ret < 0) {
|
|
return CTAP1_ERR_OTHER;
|
|
}
|
|
}
|
|
else {
|
|
ret = mtd_write_page_raw(&_mtd_dev, buf, page, offset, len);
|
|
|
|
if (ret < 0) {
|
|
return CTAP1_ERR_OTHER;
|
|
}
|
|
}
|
|
|
|
return CTAP2_OK;
|
|
}
|
|
|
|
static bool _flash_is_erased(int page, int offset, size_t len)
|
|
{
|
|
uint8_t *addr = ((uint8_t *)flashpage_addr(page) + offset);
|
|
|
|
for (size_t i = 0; i < len; i++) {
|
|
if (addr[i] != FLASHPAGE_ERASE_STATE) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
uint16_t fido2_ctap_mem_get_max_rk_amount(void)
|
|
{
|
|
return _max_rk_amnt;
|
|
}
|
|
|
|
int fido2_ctap_mem_get_flashpage_number_of_rk(uint16_t rk_idx)
|
|
{
|
|
uint16_t idx = 0;
|
|
|
|
for (unsigned i = CTAP_FLASH_RK_START_PAGE; i < _amount_of_flashpages(); i++) {
|
|
idx += flashpage_size(i) / CTAP_FLASH_RK_SZ;
|
|
|
|
if (idx >= rk_idx) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int fido2_ctap_mem_get_offset_of_rk_into_flashpage(uint16_t rk_idx)
|
|
{
|
|
uint16_t idx = 0;
|
|
|
|
for (unsigned i = CTAP_FLASH_RK_START_PAGE; i < _amount_of_flashpages(); i++) {
|
|
uint16_t old_idx = idx;
|
|
idx += flashpage_size(i) / CTAP_FLASH_RK_SZ;
|
|
|
|
if (idx >= rk_idx) {
|
|
return CTAP_FLASH_RK_SZ * (rk_idx - old_idx);
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|