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;
43 component_config(ccfg);
45 virtual ~UnitATECC608B()
49 virtual bool begin()
override;
72 return _revision.data();
78 return _slotSize[m5::stl::to_underlying(slot)];
115 return counter(value, target, 0 );
126 return counter(value, target, 1 );
179 bool createNonce(uint8_t output[32],
const uint8_t input[20],
const bool useRNG =
true,
180 const bool updateSeed =
true);
190 return write_nonce(dest, input, 32);
200 return write_nonce(dest, input, 64);
221 template <typename T, typename std::enable_if<std::is_integral<T>::value, std::nullptr_t>::type =
nullptr>
224 static_assert(
sizeof(T) <= 32,
"readRandom only supports types up to 32 bytes");
226 if (upper <= lower) {
227 M5_LIB_LOGE(
"lower must be less than upper");
231 using U =
typename std::make_unsigned<T>::type;
232 const U range =
static_cast<U
>(upper - lower);
233 const U limit = std::numeric_limits<U>::max() - (std::numeric_limits<U>::max() % range);
235 uint_fast8_t offset{};
241 while (offset +
sizeof(U) <= 32) {
243 memcpy(&raw, rv + offset,
sizeof(U));
249 value =
static_cast<T
>(lower + (raw % range));
265 template <typename T, typename std::enable_if<std::is_floating_point<T>::value, std::nullptr_t>::type =
nullptr>
268 value = std::numeric_limits<T>::quiet_NaN();
269 if (upper <= lower) {
270 M5_LIB_LOGE(
"lower must be less than upper");
278 memcpy(&raw, rv,
sizeof(uint32_t));
281 constexpr double norm = 1.0 /
static_cast<double>(std::numeric_limits<uint32_t>::max());
282 double r =
static_cast<double>(raw) * norm;
283 value =
static_cast<T
>(lower + r *
static_cast<double>(upper - lower));
284 return std::isfinite(value);
293 template <typename T, typename std::enable_if<std::is_integral<T>::value, std::nullptr_t>::type =
nullptr>
296 return readRandom(value, std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
305 template <typename T, typename std::enable_if<std::is_floating_point<T>::value, std::nullptr_t>::type =
nullptr>
308 return readRandom(value, std::numeric_limits<T>::lowest(), std::numeric_limits<T>::max());
354 constexpr uint8_t SLOT_CONFIG_BASE{20};
355 return read_slot_config_word(cfg, SLOT_CONFIG_BASE, slot);
365 constexpr uint8_t KEY_CONFIG_BASE{96};
366 return read_slot_config_word(cfg, KEY_CONFIG_BASE, slot);
399 bool selfTest(uint8_t resultBits,
const uint8_t testBits = 0x3D );
415 bool updateSHA256(
const uint8_t* msg,
const uint32_t mlen);
449 using namespace m5::unit::atecc608;
450 return ecdh_receive32(out, ECDH_MODE_SRC_SLOT | ECDH_MODE_OUTPUT_BUFFER, m5::stl::to_underlying(slot), pubKey);
462 using namespace m5::unit::atecc608;
463 return ecdh_receive32x2(out, nonce, ECDH_MODE_SRC_SLOT | ECDH_MODE_OUTPUT_BUFFER | ECDH_MODE_ENCRYPT,
464 m5::stl::to_underlying(slot), pubKey);
474 using namespace m5::unit::atecc608;
475 return ecdh_no_output(ECDH_MODE_SRC_SLOT | ECDH_MODE_OUTPUT_TEMPKEY, m5::stl::to_underlying(slot), pubKey);
484 inline bool ECDHTempKey(uint8_t out[32],
const uint8_t pubKey[64])
486 using namespace m5::unit::atecc608;
487 return ecdh_receive32(out, ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_BUFFER, 0x0000, pubKey);
497 inline bool ECDHTempKey(uint8_t out[32], uint8_t nonce[32],
const uint8_t pubKey[64])
499 using namespace m5::unit::atecc608;
500 return ecdh_receive32x2(out, nonce, ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_BUFFER | ECDH_MODE_ENCRYPT, 0x0000,
511 using namespace m5::unit::atecc608;
512 return ecdh_no_output(ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_TEMPKEY, 0x0000, pubKey);
523 using namespace m5::unit::atecc608;
524 return ecdh_no_output(ECDH_MODE_SRC_TEMPKEY | ECDH_MODE_OUTPUT_SLOT, m5::stl::to_underlying(slot), pubKey);
540 using namespace m5::unit::atecc608;
541 return generate_key(pubKey, GENKEY_MODE_PRIVATE | (digest ? GENKEY_MODE_DIGEST : 0x00),
542 m5::stl::to_underlying(slot));
559 using namespace m5::unit::atecc608;
560 return generate_key(pubKey, GENKEY_MODE_PUBLIC | (digest ? GENKEY_MODE_DIGEST : 0x00),
561 m5::stl::to_underlying(slot));
585 const bool includeSerial =
false)
587 using namespace m5::unit::atecc608;
588 return sign(signature, (SIGN_MODE_INTERNAL | (includeSerial ? SIGN_MODE_INCLUDE_SN : 0x00)),
589 m5::stl::to_underlying(slot), src);
601 const bool includeSerial =
false)
603 using namespace m5::unit::atecc608;
604 return sign(signature, (SIGN_MODE_EXTERNAL | (includeSerial ? SIGN_MODE_INCLUDE_SN : 0x00)),
605 m5::stl::to_underlying(slot), src);
619 inline bool verifyExternal(uint8_t mac[32],
const uint8_t signature[64],
const uint8_t pubKey[64],
622 using namespace m5::unit::atecc608;
623 return verify(mac, VERIFY_MODE_EXTERNAL | (mac ? VERIFY_MODE_MAC : 0x00), 0x0004 , signature, pubKey,
637 using namespace m5::unit::atecc608;
638 return verify(mac, VERIFY_MODE_STORED | (mac ? VERIFY_MODE_MAC : 0x00), m5::stl::to_underlying(slot), signature,
646 virtual bool begin_impl();
648 bool send_command(
const uint8_t opcode,
const uint8_t param1 = 0,
const uint16_t param2 = 0,
649 const uint8_t* data =
nullptr, uint32_t dlen = 0);
650 bool receive_response(uint8_t* data,
const uint32_t dlen);
652 bool counter(uint32_t& value,
const uint8_t counter,
const uint8_t mode);
656 bool read_data(uint8_t* rbuf,
const uint32_t rlen,
const uint8_t zone,
const uint16_t address,
657 const uint32_t delayMs = 3 );
658 bool read_slot_config_word(uint16_t& cfg,
const uint8_t baseOffset,
const atecc608::Slot slot);
660 virtual bool ecdh_receive32(uint8_t out[32],
const uint8_t mode,
const uint16_t param2,
const uint8_t pubKey[64]);
661 virtual bool ecdh_receive32x2(uint8_t out[32], uint8_t nonce[32],
const uint8_t mode,
const uint16_t param2,
662 const uint8_t pubKey[64]);
663 virtual bool ecdh_no_output(
const uint8_t mode,
const uint16_t param2,
const uint8_t pubKey[64]);
665 virtual bool generate_key(uint8_t pubKey[64],
const uint8_t mode,
const uint16_t param2 = 0x0000,
666 const uint8_t* data =
nullptr,
const uint32_t dlen = 0);
667 virtual bool sign(uint8_t signature[64],
const uint8_t mode,
const uint16_t param2,
const atecc608::Source src);
669 bool verify(uint8_t mac[32],
const uint8_t mode,
const uint16_t param2,
const uint8_t signature[64],
674 std::array<uint8_t, 4> _revision{};
675 std::array<uint16_t, 16> _slotSize{
676 36, 36, 36, 36, 36, 36, 36, 36,
678 72, 72, 72, 72, 72, 72, 72
Source
Data source.
Definition atecc608.hpp:48
Slot
Slot configuration summay.
Definition atecc608.hpp:26
bool ECDHStoredKey(const atecc608::Slot slot, const uint8_t pubKey[64])
ECDH (Stored in TempKey)
Definition unit_ATECC608B.hpp:472
bool readRandomArray(uint8_t data[32], const bool updateSeed=true)
Read TRNG output.
Definition unit_ATECC608B.cpp:172
bool incrementCounter(uint32_t &value, const uint8_t target)
Increment counter.
Definition unit_ATECC608B.hpp:124
bool readOTPZone(uint8_t otp[64])
Read the OTP zone @paran[out] Output buffer at least 64 bytes.
Definition unit_ATECC608B.cpp:298
bool updateSHA256(const uint8_t *msg, const uint32_t mlen)
Update calculate SHA256.
Definition unit_ATECC608B.cpp:442
bool writeNonce32(const atecc608::Destination dest, const uint8_t input[32])
write nonce 32 bytes
Definition unit_ATECC608B.hpp:188
bool readSerialNumber(uint8_t sn[9])
Read the serial number.
Definition unit_ATECC608B.cpp:190
bool readSlotConfig(uint16_t &cfg, const atecc608::Slot slot)
Read the SlotConfig.
Definition unit_ATECC608B.hpp:352
uint16_t getSlotSize(const atecc608::Slot slot) const
Gets the size of the specified data slot in bytes.
Definition unit_ATECC608B.hpp:76
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:557
bool ECDHTempKey(uint8_t out[32], uint8_t nonce[32], const uint8_t pubKey[64])
ECDH (Encrypted)
Definition unit_ATECC608B.hpp:497
bool ECDHTempKey(const atecc608::Slot slot, const uint8_t pubKey[64])
ECDH(Stored in slot)
Definition unit_ATECC608B.hpp:521
config_t config()
Gets the configration.
Definition unit_ATECC608B.hpp:54
bool readKeyConfig(uint16_t &cfg, const atecc608::Slot slot)
Read the KeyConfig.
Definition unit_ATECC608B.hpp:363
bool writeNonce64(const atecc608::Destination dest, const uint8_t input[64])
write nonce 64 bytes
Definition unit_ATECC608B.hpp:198
bool wakeup()
Device to active.
Definition unit_ATECC608B.cpp:81
bool ECDHTempKey(const uint8_t pubKey[64])
ECDH (Stored in to TempKey)
Definition unit_ATECC608B.hpp:509
bool readKeyValid(bool &valid, const atecc608::Slot slot)
Read the KeyValid.
Definition unit_ATECC608B.cpp:138
bool idle()
Device to idle.
Definition unit_ATECC608B.cpp:115
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:460
bool generateKey(uint8_t pubKey[64])
Make disposable private key to TempKey and output public key.
Definition unit_ATECC608B.cpp:384
bool ECDHTempKey(uint8_t out[32], const uint8_t pubKey[64])
ECDH (Plane text)
Definition unit_ATECC608B.hpp:484
bool readDataZone(uint8_t *data, const uint16_t len, const atecc608::Slot slot)
Read the data zone.
Definition unit_ATECC608B.cpp:269
bool finalizeSHA256(const atecc608::Destination dest, uint8_t digest[32])
Finalize calculate SHA256.
Definition unit_ATECC608B.cpp:491
bool readZoneLocked(bool &configLocked, bool &dataLocked)
Read the lock state for zone.
Definition unit_ATECC608B.cpp:222
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:538
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:584
bool sleep()
Device to sleep.
Definition unit_ATECC608B.cpp:110
bool SHA256(const atecc608::Destination dest, uint8_t digest[32], const uint8_t *msg, const uint32_t mlen)
Calculate SHA256.
Definition unit_ATECC608B.hpp:431
void config(const config_t &cfg)
Set the configration.
Definition unit_ATECC608B.hpp:59
bool readDeviceState(uint16_t &state)
Read the device state.
Definition unit_ATECC608B.cpp:155
bool selfTest(uint8_t resultBits, const uint8_t testBits=0x3D)
Self test.
Definition unit_ATECC608B.cpp:322
bool readRandom(T &value)
Generate a random integral value covering the entire valid range of type T.
Definition unit_ATECC608B.hpp:294
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:341
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:222
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:390
bool readConfigZone(uint8_t config[128])
Read the config zone.
Definition unit_ATECC608B.cpp:250
const uint8_t * revision() const
Get the revison.
Definition unit_ATECC608B.hpp:70
bool ECDHStoredKey(uint8_t out[32], const atecc608::Slot slot, const uint8_t pubKey[64])
ECDH (Plane text)
Definition unit_ATECC608B.hpp:447
bool readSlotLocked(uint16_t &slotLockedBits)
Read the lock state for data zone.
Definition unit_ATECC608B.cpp:235
bool verifyStored(uint8_t mac[32], const uint8_t signature[64], const atecc608::Slot slot, const atecc608::Source src)
Verify the stored publick key.
Definition unit_ATECC608B.hpp:634
bool readCounter(uint32_t &value, const uint8_t target)
Read the counter value.
Definition unit_ATECC608B.hpp:113
bool startSHA256()
Start calculate SHA256.
Definition unit_ATECC608B.cpp:428
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:619
bool readRevision(uint8_t data[4])
Read the revision.
Definition unit_ATECC608B.cpp:120
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:600
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