10#ifndef M5_UNIT_CRYPTO_UNIT_ATECC608B_HPP
11#define M5_UNIT_CRYPTO_UNIT_ATECC608B_HPP
14#include <M5UnitComponent.hpp>
15#include <m5_utility/container/circular_buffer.hpp>
26class UnitATECC608B :
public Component {
27 M5_UNIT_COMPONENT_HPP_BUILDER(UnitATECC608B, 0x35);
39 explicit UnitATECC608B(
const uint8_t addr = DEFAULT_ADDRESS) : Component(addr)
41 auto ccfg = component_config();
42 ccfg.clock = 400 * 1000U;
44 component_config(ccfg);
46 virtual ~UnitATECC608B()
50 virtual bool begin()
override;
73 return _revision.data();
79 return _slotSize[m5::stl::to_underlying(slot)];
116 return counter(value, target, 0 );
127 return counter(value, target, 1 );
180 bool createNonce(uint8_t output[32],
const uint8_t input[20],
const bool useRNG =
true,
181 const bool updateSeed =
true);
191 return write_nonce(dest, input, 32);
201 return write_nonce(dest, input, 64);
213 virtual bool readRandomArray(uint8_t data[32],
const bool updateSeed =
true);
223 template <typename T, typename std::enable_if<std::is_integral<T>::value, std::nullptr_t>::type =
nullptr>
226 static_assert(
sizeof(T) <= 32,
"readRandom only supports types up to 32 bytes");
228 if (upper <= lower) {
229 M5_LIB_LOGE(
"lower must be less than upper");
233 using U =
typename std::make_unsigned<T>::type;
234 const U range =
static_cast<U
>(
static_cast<U
>(upper) -
static_cast<U
>(lower));
235 const U limit = std::numeric_limits<U>::max() - (std::numeric_limits<U>::max() % range);
237 uint_fast8_t offset{};
243 while (offset +
sizeof(U) <= 32) {
245 memcpy(&raw, rv + offset,
sizeof(U));
251 value =
static_cast<T
>(lower + (raw % range));
267 template <typename T, typename std::enable_if<std::is_floating_point<T>::value, std::nullptr_t>::type =
nullptr>
270 value = std::numeric_limits<T>::quiet_NaN();
271 if (upper <= lower) {
272 M5_LIB_LOGE(
"lower must be less than upper");
280 memcpy(&raw, rv,
sizeof(uint32_t));
283 constexpr double norm = 1.0 / (
static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0);
284 double r =
static_cast<double>(raw) * norm;
285 value =
static_cast<T
>(lower + r *
static_cast<double>(upper - lower));
286 return std::isfinite(value);
295 template <typename T, typename std::enable_if<std::is_integral<T>::value, std::nullptr_t>::type =
nullptr>
298 return readRandom(value, std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
307 template <typename T, typename std::enable_if<std::is_floating_point<T>::value, std::nullptr_t>::type =
nullptr>
310 return readRandom(value, std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
356 constexpr uint8_t SLOT_CONFIG_BASE{20};
357 return read_slot_config_word(cfg, SLOT_CONFIG_BASE, slot);
367 constexpr uint8_t KEY_CONFIG_BASE{96};
368 return read_slot_config_word(cfg, KEY_CONFIG_BASE, slot);
390 bool writeGeneralData(
const uint8_t* data,
const uint16_t len,
const uint16_t offset = 0);
399 bool readGeneralData(uint8_t* data,
const uint16_t len,
const uint16_t offset = 0);
422 bool updateSHA256(
const uint8_t* msg,
const uint32_t mlen);
456 using namespace m5::unit::atecc608;
457 return ecdh_receive32(out, ECDH_MODE_SRC_SLOT | ECDH_MODE_OUTPUT_BUFFER, m5::stl::to_underlying(slot), pubKey);
469 using namespace m5::unit::atecc608;
470 return ecdh_receive32x2(out, nonce, ECDH_MODE_SRC_SLOT | ECDH_MODE_OUTPUT_BUFFER | ECDH_MODE_ENCRYPT,
471 m5::stl::to_underlying(slot), pubKey);
481 using namespace m5::unit::atecc608;
482 return ecdh_no_output(ECDH_MODE_SRC_SLOT | ECDH_MODE_OUTPUT_TEMPKEY, m5::stl::to_underlying(slot), pubKey);
491 inline bool ECDHTempKey(uint8_t out[32],
const uint8_t pubKey[64])
493 using namespace m5::unit::atecc608;
494 return ecdh_receive32(out, ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_BUFFER, 0x0000, pubKey);
504 inline bool ECDHTempKey(uint8_t out[32], uint8_t nonce[32],
const uint8_t pubKey[64])
506 using namespace m5::unit::atecc608;
507 return ecdh_receive32x2(out, nonce, ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_BUFFER | ECDH_MODE_ENCRYPT, 0x0000,
518 using namespace m5::unit::atecc608;
519 return ecdh_no_output(ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_TEMPKEY, 0x0000, pubKey);
530 using namespace m5::unit::atecc608;
531 return ecdh_no_output(ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_SLOT, m5::stl::to_underlying(slot), pubKey);
547 using namespace m5::unit::atecc608;
548 return generate_key(pubKey, GENKEY_MODE_PRIVATE | (digest ? GENKEY_MODE_DIGEST : 0x00),
549 m5::stl::to_underlying(slot));
566 using namespace m5::unit::atecc608;
567 return generate_key(pubKey, GENKEY_MODE_PUBLIC | (digest ? GENKEY_MODE_DIGEST : 0x00),
568 m5::stl::to_underlying(slot));
592 const bool includeSerial =
false)
594 using namespace m5::unit::atecc608;
595 return sign(signature, (SIGN_MODE_INTERNAL | (includeSerial ? SIGN_MODE_INCLUDE_SN : 0x00)),
596 m5::stl::to_underlying(slot), src);
608 const bool includeSerial =
false)
610 using namespace m5::unit::atecc608;
611 return sign(signature, (SIGN_MODE_EXTERNAL | (includeSerial ? SIGN_MODE_INCLUDE_SN : 0x00)),
612 m5::stl::to_underlying(slot), src);
626 inline bool verifyExternal(uint8_t mac[32],
const uint8_t signature[64],
const uint8_t pubKey[64],
629 using namespace m5::unit::atecc608;
630 return verify(mac, VERIFY_MODE_EXTERNAL | (mac ? VERIFY_MODE_MAC : 0x00), 0x0004 , signature, pubKey,
644 using namespace m5::unit::atecc608;
645 return verify(mac, VERIFY_MODE_STORED | (mac ? VERIFY_MODE_MAC : 0x00), m5::stl::to_underlying(slot), signature,
662 bool selfTest(uint8_t& resultBits,
const uint8_t testBits = 0x3D );
668 virtual bool begin_impl();
670 bool send_command(
const uint8_t opcode,
const uint8_t param1 = 0,
const uint16_t param2 = 0,
671 const uint8_t* data =
nullptr, uint32_t dlen = 0);
672 bool receive_response(uint8_t* data,
const uint32_t dlen);
674 bool counter(uint32_t& value,
const uint8_t counter,
const uint8_t mode);
678 bool read_data(uint8_t* rbuf,
const uint32_t rlen,
const uint8_t zone,
const uint16_t address,
679 const uint32_t delayMs = 3 );
680 bool read_slot_config_word(uint16_t& cfg,
const uint8_t baseOffset,
const atecc608::Slot slot);
682 virtual bool ecdh_receive32(uint8_t out[32],
const uint8_t mode,
const uint16_t param2,
const uint8_t pubKey[64]);
683 virtual bool ecdh_receive32x2(uint8_t out[32], uint8_t nonce[32],
const uint8_t mode,
const uint16_t param2,
684 const uint8_t pubKey[64]);
685 virtual bool ecdh_no_output(
const uint8_t mode,
const uint16_t param2,
const uint8_t pubKey[64]);
687 virtual bool generate_key(uint8_t pubKey[64],
const uint8_t mode,
const uint16_t param2 = 0x0000,
688 const uint8_t* data =
nullptr,
const uint32_t dlen = 0);
689 virtual bool sign(uint8_t signature[64],
const uint8_t mode,
const uint16_t param2,
const atecc608::Source src);
691 bool verify(uint8_t mac[32],
const uint8_t mode,
const uint16_t param2,
const uint8_t signature[64],
696 std::array<uint8_t, 4> _revision{};
697 std::array<uint16_t, 16> _slotSize{
698 36, 36, 36, 36, 36, 36, 36, 36,
700 72, 72, 72, 72, 72, 72, 72
Source
Data source.
Definition atecc608.hpp:48
Slot
Slot configuration summary.
Definition atecc608.hpp:26
bool ECDHStoredKey(const atecc608::Slot slot, const uint8_t pubKey[64])
ECDH (Stored in TempKey)
Definition unit_ATECC608B.hpp:479
virtual bool readRandomArray(uint8_t data[32], const bool updateSeed=true)
Read TRNG output.
Definition unit_ATECC608B.cpp:227
bool incrementCounter(uint32_t &value, const uint8_t target)
Increment counter.
Definition unit_ATECC608B.hpp:125
bool readOTPZone(uint8_t otp[64])
Read the OTP zone.
Definition unit_ATECC608B.cpp:463
bool updateSHA256(const uint8_t *msg, const uint32_t mlen)
Update calculate SHA256.
Definition unit_ATECC608B.cpp:621
bool writeNonce32(const atecc608::Destination dest, const uint8_t input[32])
write nonce 32 bytes
Definition unit_ATECC608B.hpp:189
bool readSerialNumber(uint8_t sn[9])
Read the serial number.
Definition unit_ATECC608B.cpp:245
bool readSlotConfig(uint16_t &cfg, const atecc608::Slot slot)
Read the SlotConfig.
Definition unit_ATECC608B.hpp:354
uint16_t getSlotSize(const atecc608::Slot slot) const
Gets the size of the specified data slot in bytes.
Definition unit_ATECC608B.hpp:77
bool generatePublicKey(uint8_t pubKey[64], const atecc608::Slot slot, const bool digest=false)
Generate the public key from private key in slot.
Definition unit_ATECC608B.hpp:564
bool ECDHTempKey(uint8_t out[32], uint8_t nonce[32], const uint8_t pubKey[64])
ECDH (Encrypted)
Definition unit_ATECC608B.hpp:504
bool readGeneralData(uint8_t *data, const uint16_t len, const uint16_t offset=0)
Read data from GeneralData slot (Slot 8)
Definition unit_ATECC608B.cpp:416
bool ECDHTempKey(const atecc608::Slot slot, const uint8_t pubKey[64])
ECDH(Stored in slot)
Definition unit_ATECC608B.hpp:528
config_t config()
Gets the configuration.
Definition unit_ATECC608B.hpp:55
bool readKeyConfig(uint16_t &cfg, const atecc608::Slot slot)
Read the KeyConfig.
Definition unit_ATECC608B.hpp:365
bool writeNonce64(const atecc608::Destination dest, const uint8_t input[64])
write nonce 64 bytes
Definition unit_ATECC608B.hpp:199
bool wakeup()
Device to active.
Definition unit_ATECC608B.cpp:109
bool writeGeneralData(const uint8_t *data, const uint16_t len, const uint16_t offset=0)
Write data to GeneralData slot (Slot 8, clear text)
Definition unit_ATECC608B.cpp:359
bool ECDHTempKey(const uint8_t pubKey[64])
ECDH (Stored in TempKey)
Definition unit_ATECC608B.hpp:516
bool readKeyValid(bool &valid, const atecc608::Slot slot)
Read the KeyValid.
Definition unit_ATECC608B.cpp:193
bool idle()
Device to idle.
Definition unit_ATECC608B.cpp:169
bool ECDHStoredKey(uint8_t out[32], uint8_t nonce[32], const atecc608::Slot slot, const uint8_t pubKey[64])
ECDH (Encrypted)
Definition unit_ATECC608B.hpp:467
bool generateKey(uint8_t pubKey[64])
Make disposable private key to TempKey and output public key.
Definition unit_ATECC608B.cpp:563
bool ECDHTempKey(uint8_t out[32], const uint8_t pubKey[64])
ECDH (Plain text)
Definition unit_ATECC608B.hpp:491
bool selfTest(uint8_t &resultBits, const uint8_t testBits=0x3D)
Self test.
Definition unit_ATECC608B.cpp:501
bool readDataZone(uint8_t *data, const uint16_t len, const atecc608::Slot slot)
Read the data zone.
Definition unit_ATECC608B.cpp:330
bool finalizeSHA256(const atecc608::Destination dest, uint8_t digest[32])
Finalize calculate SHA256.
Definition unit_ATECC608B.cpp:669
bool readZoneLocked(bool &configLocked, bool &dataLocked)
Read the lock state for zone.
Definition unit_ATECC608B.cpp:282
bool generatePrivateKey(const atecc608::Slot slot, uint8_t pubKey[64], const bool digest=false)
Generate the private key stored in slot.
Definition unit_ATECC608B.hpp:545
bool signInternal(uint8_t signature[64], const atecc608::Slot slot, const atecc608::Source src, const bool includeSerial=false)
Sign internal message.
Definition unit_ATECC608B.hpp:591
bool sleep()
Device to sleep.
Definition unit_ATECC608B.cpp:163
bool SHA256(const atecc608::Destination dest, uint8_t digest[32], const uint8_t *msg, const uint32_t mlen)
Calculate SHA256.
Definition unit_ATECC608B.hpp:438
void config(const config_t &cfg)
Set the configuration.
Definition unit_ATECC608B.hpp:60
bool readDeviceState(uint16_t &state)
Read the device state.
Definition unit_ATECC608B.cpp:210
bool readRandom(T &value)
Generate a random integral value covering the entire valid range of type T.
Definition unit_ATECC608B.hpp:296
bool createNonce(uint8_t output[32], const uint8_t input[20], const bool useRNG=true, const bool updateSeed=true)
Create nonce to TempKey by input data with RNG or TempKey.
Definition unit_ATECC608B.cpp:520
bool readRandom(T &value, const T lower, const T upper)
Generate a random value of type T in the specified range.
Definition unit_ATECC608B.hpp:224
bool generatePublicKeyDigest(const atecc608::Slot slot, const uint8_t otherData[3]=nullptr)
Generate digest of a public key and stored in TempKey.
Definition unit_ATECC608B.cpp:569
bool readConfigZone(uint8_t config[128])
Read the config zone.
Definition unit_ATECC608B.cpp:310
const uint8_t * revision() const
Get the revision.
Definition unit_ATECC608B.hpp:71
bool ECDHStoredKey(uint8_t out[32], const atecc608::Slot slot, const uint8_t pubKey[64])
ECDH (Plain text)
Definition unit_ATECC608B.hpp:454
bool readSlotLocked(uint16_t &slotLockedBits)
Read the lock state for data zone.
Definition unit_ATECC608B.cpp:295
bool verifyStored(uint8_t mac[32], const uint8_t signature[64], const atecc608::Slot slot, const atecc608::Source src)
Verify the stored public key.
Definition unit_ATECC608B.hpp:641
bool readCounter(uint32_t &value, const uint8_t target)
Read the counter value.
Definition unit_ATECC608B.hpp:114
bool startSHA256()
Start calculate SHA256.
Definition unit_ATECC608B.cpp:607
bool verifyExternal(uint8_t mac[32], const uint8_t signature[64], const uint8_t pubKey[64], const atecc608::Source src)
Verify the external public key.
Definition unit_ATECC608B.hpp:626
bool readRevision(uint8_t data[4])
Read the revision.
Definition unit_ATECC608B.cpp:175
bool signExternal(uint8_t signature[64], const atecc608::Slot slot, const atecc608::Source src, const bool includeSerial=false)
Sign external message.
Definition unit_ATECC608B.hpp:607
Top level namespace of M5stack.
Settings for begin.
Definition unit_ATECC608B.hpp:34
bool idle
Device to idle on begin?
Definition unit_ATECC608B.hpp:36