diff --git a/drivers/entropy/CMakeLists.txt b/drivers/entropy/CMakeLists.txt index 11e361517c25128..6f58ada6ec29620 100644 --- a/drivers/entropy/CMakeLists.txt +++ b/drivers/entropy/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/entropy.h) zephyr_library() +zephyr_library_sources_ifdef(CONFIG_ENTROPY_ATECCX08 entropy_ateccx08.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_TELINK_B91_TRNG entropy_b91_trng.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_CC13XX_CC26XX_RNG entropy_cc13xx_cc26xx.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_ESP32_RNG entropy_esp32.c) diff --git a/drivers/entropy/Kconfig b/drivers/entropy/Kconfig index e932f62c6bff7b1..b0712c3cc60dfd4 100644 --- a/drivers/entropy/Kconfig +++ b/drivers/entropy/Kconfig @@ -20,6 +20,7 @@ config ENTROPY_INIT_PRIORITY help Entropy driver device initialization priority. +source "drivers/entropy/Kconfig.ateccx08" source "drivers/entropy/Kconfig.b91" source "drivers/entropy/Kconfig.cc13xx_cc26xx" source "drivers/entropy/Kconfig.mcux" diff --git a/drivers/entropy/Kconfig.ateccx08 b/drivers/entropy/Kconfig.ateccx08 new file mode 100644 index 000000000000000..bdaa2e04041f6b5 --- /dev/null +++ b/drivers/entropy/Kconfig.ateccx08 @@ -0,0 +1,13 @@ +# Microchip ATECCx08 entropy generator driver configuration + +# Copyright (c) 2024 Vogl Electronic GmbH +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_ATECCX08 + bool "Microchip ATECCx08 RNG driver" + default y + depends on DT_HAS_MICROCHIP_ATECCX08_ENTROPY_ENABLED + depends on EEPROM_ATECCX08 + select ENTROPY_HAS_DRIVER + help + This option enables the Microchip ATECCx08 RNG driver. diff --git a/drivers/entropy/entropy_ateccx08.c b/drivers/entropy/entropy_ateccx08.c new file mode 100644 index 000000000000000..07c98db680f7fb1 --- /dev/null +++ b/drivers/entropy/entropy_ateccx08.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024 Vogl Electronic GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT microchip_ateccx08_entropy + +#include +#include +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(entropy_ateccx08, CONFIG_ENTROPY_LOG_LEVEL); + +#define ATECCX08_RANDOM_SIZE 32 + +struct entropy_ateccx08_config { + const struct device *parent; +}; + +struct entropy_ateccx08_data { + uint8_t random_buffer[ATECCX08_RANDOM_SIZE]; + size_t buffer_remaining; + struct k_sem sem_lock; +}; + +static int entropy_ateccx08_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) +{ + const struct entropy_ateccx08_config *config = dev->config; + struct entropy_ateccx08_data *dev_data = dev->data; + + int ret = 0; + + if (atecc_is_locked_config(config->parent) == false) { + LOG_ERR("Config not locked, no random data available."); + return -EPERM; + } + + k_sem_take(&dev_data->sem_lock, K_FOREVER); + + if (dev_data->buffer_remaining > 0) { + size_t to_copy = MIN(length, dev_data->buffer_remaining); + uint8_t *pos = dev_data->random_buffer + sizeof(dev_data->random_buffer) - + dev_data->buffer_remaining; + + memcpy(buffer, pos, to_copy); + buffer += to_copy; + length -= to_copy; + dev_data->buffer_remaining -= to_copy; + } + + while (length > 0) { + size_t to_copy; + + ret = atecc_random(config->parent, dev_data->random_buffer, true); + if (ret < 0) { + goto exit; + } + + to_copy = MIN(length, sizeof(dev_data->random_buffer)); + + memcpy(buffer, dev_data->random_buffer, to_copy); + buffer += to_copy; + length -= to_copy; + dev_data->buffer_remaining = sizeof(dev_data->random_buffer) - to_copy; + } + +exit: + k_sem_give(&dev_data->sem_lock); + return ret; +} + +static int entropy_ateccx08_init(const struct device *dev) +{ + const struct entropy_ateccx08_config *config = dev->config; + struct entropy_ateccx08_data *dev_data = dev->data; + + if (!device_is_ready(config->parent)) { + return -ENODEV; + } + + k_sem_init(&dev_data->sem_lock, 1, 1); + + return 0; +} + +static const struct entropy_driver_api entropy_ateccx08_api = { + .get_entropy = entropy_ateccx08_get_entropy}; + +#define DEFINE_ATECCX08_ENTROPY(_num) \ + static const struct entropy_ateccx08_config entropy_ateccx08_config##_num = { \ + .parent = DEVICE_DT_GET(DT_INST_BUS(_num))}; \ + static struct entropy_ateccx08_data entropy_ateccx08_data##_num; \ + DEVICE_DT_INST_DEFINE(_num, entropy_ateccx08_init, NULL, &entropy_ateccx08_data##_num, \ + &entropy_ateccx08_config##_num, POST_KERNEL, \ + CONFIG_EEPROM_INIT_PRIORITY, &entropy_ateccx08_api); + +DT_INST_FOREACH_STATUS_OKAY(DEFINE_ATECCX08_ENTROPY); diff --git a/dts/bindings/mtd/microchip,ateccx08-base.yaml b/dts/bindings/mtd/microchip,ateccx08-base.yaml index 0b18fc03bf5028b..1a503d6d4a91f48 100644 --- a/dts/bindings/mtd/microchip,ateccx08-base.yaml +++ b/dts/bindings/mtd/microchip,ateccx08-base.yaml @@ -3,6 +3,8 @@ include: ["eeprom-base.yaml", i2c-device.yaml] +bus: ateccx08 + properties: wake-delay: type: int diff --git a/dts/bindings/rng/microchip,ateccx08-entropy.yaml b/dts/bindings/rng/microchip,ateccx08-entropy.yaml new file mode 100644 index 000000000000000..4ec0ef2c1f7a94b --- /dev/null +++ b/dts/bindings/rng/microchip,ateccx08-entropy.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Vogl Electronic GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip ATECCx08 entropy binding + +compatible: "microchip,ateccx08-entropy" + +include: base.yaml + +on-bus: ateccx08