Implement interfaces for ESP32

This commit is contained in:
Christoph Hagen 2023-12-13 13:21:29 +01:00
parent 0fc3efc0ec
commit 9f8d9a9f51
7 changed files with 219 additions and 1 deletions

View File

@ -0,0 +1,62 @@
#pragma once
#include "relay/interface/CryptoSource.h"
#include "ESP32NoiseSource.h"
class ESP32CryptoSource: CryptoSource {
public:
ESP32CryptoSource(const char* rngInitTag);
bool isAvailable() override {
return true;
}
/**
* @brief Create a new random private key
*
* @param key The output buffer where the key will be stored
* @return true The key was created
* @return false The key could not be created
*/
bool createPrivateKey(PrivateKey* key) override;
/**
* @brief Create a the public key corresponding to a private key
*
* @param privateKey The private key to use
* @param publicKey The output buffer where the public key will be stored
* @return true The key was created
* @return false The key could not be created
*/
bool createPublicKey(const PrivateKey* privateKey, PublicKey* publicKey) override;
/**
* @brief Sign a message
*
* @param message The message payload to include in the message
* @param length The length of the payload
* @param signature The output buffer where the signature is written
* @return true The signature was created
* @return false The signature creation failed
*/
bool sign(const uint8_t *message, uint16_t length, Signature* signature, const PrivateKey* privateKey, const PublicKey* publicKey) override;
/**
* @brief Verify a message
*
* @param signature The message signature
* @param publicKey The public key with which the message was signed
* @param message The pointer to the message data
* @param length The length of the message
* @return true The signature is valid
* @return false The signature is invalid
*/
bool
verify(const Signature* signature, const PublicKey* publicKey, const void *message, uint16_t length) override;
private:
ESP32NoiseSource noise{};
};

View File

@ -0,0 +1,64 @@
#pragma once
#include <NoiseSource.h>
/// @brief The size of the internal buffer when generating entropy
constexpr size_t randomNumberBatchSize = 32;
/**
* @brief A noise source for crypto operations specifically for the ESP32.
*
*/
class ESP32NoiseSource: public NoiseSource {
public:
/**
* \brief Constructs a new random noise source.
*/
ESP32NoiseSource();
/**
* \brief Destroys this random noise source.
*/
~ESP32NoiseSource() {}
/**
* @brief Determine if the noise source is still calibrating itself.
*
* Noise sources that require calibration start doing so at system startup
* and then switch over to random data generation once calibration is complete.
* Since no random data is being generated during calibration, the output
* from `RNGClass::rand()` and `RNG.rand()` may be predictable.
* Use `RNGClass::available()` or `RNG.available()` to determine
* when sufficient entropy is available to generate good random values.
*
* It is possible that the noise source never exits calibration. This can
* happen if the input voltage is insufficient to trigger noise or if the
* noise source is not connected. Noise sources may also periodically
* recalibrate themselves.
*
* @return Returns true if calibration is in progress; false if the noise
* source is generating valid random data.
*
*/
bool calibrating() const override;
/**
* @brief Stirs entropy from this noise source into the global random
* number pool.
*
* This function should call `output()` to add the entropy from this noise
* source to the global random number pool.
*
* The noise source should batch up the entropy data, providing between
* 16 and 48 bytes of data each time. If the noise source does not have
* sufficient entropy data at the moment, it should return without stiring
* the current data in.
*/
void stir() override;
private:
/// @brief Temporary buffer to hold random bytes before handing them to the crypto module
uint8_t data[randomNumberBatchSize];
};

View File

@ -0,0 +1,17 @@
#include "relay/interface/StorageSource.h"
class ESP32StorageSource: StorageSource {
bool writeByteAtIndex(uint8_t byte, uint16_t index) override;
bool canProvideStorageWithSize(uint16_t size) override;
bool commitData();
uint8_t readByteAtIndex(uint16_t index) override;
uint16_t readBytes(uint16_t startIndex, uint16_t count, uint8_t* output) override;
uint16_t writeBytes(uint8_t* bytes, uint16_t count, uint16_t startIndex) override;
};

View File

@ -18,6 +18,6 @@ lib_deps =
ottowinter/ESPAsyncWebServer-esphome@^3.0.0
arduino-libraries/Ethernet@^2.0.2
https://github.com/christophhagen/arduinoWebSockets#master
rweather/Crypto@^0.4.0
monitor_speed = 115200
build_flags= -D WEBSOCKETS_NETWORK_TYPE=NETWORK_W5100

View File

@ -0,0 +1,29 @@
#include "interface/ESP32CryptoSource.h"
#include <Ed25519.h>
#include <RNG.h>
#include <NoiseSource.h>
ESP32CryptoSource::ESP32CryptoSource(const char* rngInitTag) {
RNG.begin(rngInitTag);
RNG.addNoiseSource(noise);
}
bool ESP32CryptoSource::createPrivateKey(PrivateKey* key) {
Ed25519::generatePrivateKey(key->bytes);
return true;
}
bool ESP32CryptoSource::createPublicKey(const PrivateKey* privateKey, PublicKey* publicKey) {
Ed25519::derivePublicKey(publicKey->bytes, privateKey->bytes);
return true;
}
bool ESP32CryptoSource::sign(const uint8_t *message, uint16_t length, Signature* signature, const PrivateKey* privateKey, const PublicKey* publicKey) {
Ed25519::sign(signature->bytes, privateKey->bytes, publicKey->bytes, message, length);
return true;
}
bool ESP32CryptoSource::verify(const Signature* signature, const PublicKey* publicKey, const void *message, uint16_t length) {
return Ed25519::verify(signature->bytes, publicKey->bytes, message, length);
}

View File

@ -0,0 +1,18 @@
#include "interface/ESP32NoiseSource.h"
#include <esp_random.h>
#include <bootloader_random.h>
ESP32NoiseSource::ESP32NoiseSource() {
// Ensure that there is randomness even if Bluetooth and WiFi are disabled
bootloader_random_enable();
}
bool ESP32NoiseSource::calibrating() const {
return false;
}
void ESP32NoiseSource::stir() {
esp_fill_random(data, randomNumberBatchSize);
output(data, randomNumberBatchSize, randomNumberBatchSize * 8);
}

View File

@ -0,0 +1,28 @@
#include "interface/ESP32StorageSource.h"
#include <EEPROM.h>
bool ESP32StorageSource::writeByteAtIndex(uint8_t byte, uint16_t index) {
// TODO: What does return value mean?
EEPROM.writeByte((int) index, byte);
return true;
}
bool ESP32StorageSource::canProvideStorageWithSize(uint16_t size) {
return EEPROM.begin(size);
}
bool ESP32StorageSource::commitData() {
return EEPROM.commit();
}
uint8_t ESP32StorageSource::readByteAtIndex(uint16_t index) {
return EEPROM.readByte((int) index);
}
uint16_t ESP32StorageSource::readBytes(uint16_t startIndex, uint16_t count, uint8_t* output) {
return EEPROM.readBytes(startIndex, output, count);
}
uint16_t ESP32StorageSource::writeBytes(uint8_t* bytes, uint16_t count, uint16_t startIndex) {
return EEPROM.writeBytes(startIndex, bytes, count);
}