10#ifndef M5_UNIT_CRYPTO_ATECC608_HPP
11#define M5_UNIT_CRYPTO_ATECC608_HPP
58using Destination = Source;
62constexpr uint8_t ZONE_CONFIG{0x00};
63constexpr uint8_t ZONE_OTP{0x01};
64constexpr uint8_t ZONE_DATA{0x02};
72 CHECK_MAC_OR_VERIFY_ERROR = 0x01,
75 SELF_TEST_ERROR = 0x07,
76 HEALTH_TEST_ERROR = 0x08,
77 EXECUTION_ERROR = 0x0F,
78 AFTER_WAKE_PRIOR_ERROR = 0X11,
79 WATCH_DOG_ERROR = 0xEE,
80 CRC_OR_COMMUNICATION_ERROR = 0XFF,
86constexpr uint32_t DELAY_READ{3};
87constexpr uint32_t DELAY_WRITE{45};
88constexpr uint32_t DELAY_INFO{2};
89constexpr uint32_t DELAY_NONCE{16};
90constexpr uint32_t DELAY_SELFTEST{200};
91constexpr uint32_t DELAY_RANDOM{23};
92constexpr uint32_t DELAY_COUNTER{20};
93constexpr uint32_t DELAY_GENKEY{115};
94constexpr uint32_t DELAY_SIGN{70};
95constexpr uint32_t DELAY_SHA{9};
96constexpr uint32_t DELAY_ECDH{58};
97constexpr uint32_t DELAY_VERIFY{120};
102constexpr uint8_t WORD_VALUE_RESET{0x00};
103constexpr uint8_t WORD_ADDRESS_VALUE_SLEEP{0x01};
104constexpr uint8_t WORD_ADDRESS_VALUE_IDLE{0x02};
105constexpr uint8_t WORD_ADDRESS_VALUE_COMMAND{0x03};
110constexpr uint8_t OPCODE_READ{0x02};
111constexpr uint8_t OPCODE_WRITE{0x12};
112constexpr uint8_t OPCODE_NONCE{0x16};
114constexpr uint8_t OPCODE_RANDOM{0x1B};
115constexpr uint8_t OPCODE_COUNTER{0x24};
116constexpr uint8_t OPCODE_INFO{0x30};
117constexpr uint8_t OPCODE_GENKEY{0x40};
118constexpr uint8_t OPCODE_SIGN{0x41};
119constexpr uint8_t OPCODE_ECDH{0x43};
120constexpr uint8_t OPCODE_VERIFY{0x45};
121constexpr uint8_t OPCODE_SHA{0x47};
122constexpr uint8_t OPCODE_SELFTEST{0x77};
127constexpr uint8_t INFO_MODE_REVISION{0x00};
128constexpr uint8_t INFO_MODE_KEYVALID{0x01};
129constexpr uint8_t INFO_MODE_DEVICE_STATE{0x02};
134constexpr uint8_t NONCE_MODE_RANDOM_UPDATE_SEED{0x00};
135constexpr uint8_t NONCE_MODE_RANDOM_NOT_UPDATE_SEED{0x01};
136constexpr uint8_t NONCE_MODE_PASSTHROUGH{0x03};
137constexpr uint8_t NONCE_MODE_INPUT_64{0x20};
139constexpr uint8_t NONCE_MODE_TARGET_TEMPKEY{0x00};
140constexpr uint8_t NONCE_MODE_TARGET_DIGEST{0x40};
141constexpr uint8_t NONCE_MODE_TARGET_ALTKEY{0x80};
143constexpr uint16_t NONCE_USE_TRNG{0x0000};
144constexpr uint16_t NONCE_USE_TEMPKEY{0x8000};
149constexpr uint8_t RANDOM_MODE_UPDATE_SEED{0x00};
150constexpr uint8_t RANDOM_MODE_NOT_UPDATE_SEED{0x01};
155constexpr uint8_t SHA_MODE_START{0x00};
156constexpr uint8_t SHA_MODE_UPDATE{0x01};
157constexpr uint8_t SHA_MODE_FINALIZE{0x02};
158constexpr uint8_t SHA_MODE_OUTPUT_TEMPKEY{0x00};
159constexpr uint8_t SHA_MODE_OUTPUT_DIGEST{0x40};
160constexpr uint8_t SHA_MODE_OUTPUT_BUFFER{0xC0};
166constexpr uint8_t ECDH_MODE_SRC_SLOT{0x00};
167constexpr uint8_t ECDH_MODE_SRC_TEMPKEY{0x01};
169constexpr uint8_t ECDH_MODE_ENCRYPT{0x02};
171constexpr uint8_t ECDH_MODE_OUTPUT_TEMPKEY{0x08};
172constexpr uint8_t ECDH_MODE_OUTPUT_BUFFER{0x0C};
173constexpr uint8_t ECDH_MODE_OUTPUT_SLOT{0x04};
178constexpr uint8_t GENKEY_MODE_PUBLIC{0x00};
179constexpr uint8_t GENKEY_MODE_PRIVATE{0x04};
180constexpr uint8_t GENKEY_MODE_DIGEST{0x08};
181constexpr uint8_t GENKEY_MODE_PUBLIC_DIGEST{0x10};
186constexpr uint8_t SIGN_MODE_INTERNAL{0x00};
187constexpr uint8_t SIGN_MODE_INCLUDE_SN{0x40};
188constexpr uint8_t SIGN_MODE_EXTERNAL{0x80};
190constexpr uint8_t SIGN_MODE_TEMPKEY{0x00};
191constexpr uint8_t SIGN_MODE_DIGEST{0x20};
196constexpr uint8_t VERIFY_MODE_STORED{0x00};
197constexpr uint8_t VERIFY_MODE_EXTERNAL{0x02};
199constexpr uint8_t VERIFY_MODE_TEMPKEY{0x00};
200constexpr uint8_t VERIFY_MODE_DIGEST{0x20};
202constexpr uint8_t VERIFY_MODE_MAC{0x80};
209 const uint8_t block = (offset >> 5) & 0x03;
210 const uint8_t index = ((offset & 31) >> 2) & 0x07;
211 return (block << 3) | index;
216 const uint8_t block = offset >> 5;
217 const uint8_t word_offset = (offset & 31) >> 2;
218 return (slot << 3) | (block << 8) | word_offset;
224 return ((ilen + 2) / 3) * 4;
228bool convertToPEM(
char* out,
const uint32_t out_len,
const uint8_t* der, uint32_t dlen,
229 const char* header =
"CERTIFICATE",
const char* footer =
"CERTIFICATE");
232extern const uint8_t template_for_device[];
233extern const uint8_t template_for_signer[];
234extern const uint32_t template_for_device_size;
235extern const uint32_t template_for_signer_size;
242class CompCertAccessor {
256 _issue_date = get_issue_date();
257 _expire_date = get_expire_date();
261 inline uint8_t format_version()
const
263 return _data[70] & 0x0F;
265 inline uint8_t template_id()
const
267 return (_data[69] >> 4) & 0x0F;
269 inline uint8_t chain_id()
const
271 return _data[69] & 0x0F;
273 inline uint8_t sn_source()
const
275 return (_data[70] >> 4) & 0x0F;
278 inline const uint8_t* signer_id()
const
283 inline const uint8_t* signature()
const
287 inline const uint8_t* signature_r()
const
291 inline const uint8_t* signature_s()
const
296 inline DateTime issue_date()
const
300 inline DateTime expire_date()
const
306 const uint8_t* _data{};
307 DateTime _issue_date{}, _expire_date{};
309 DateTime get_issue_date()
const
312 uint8_t b64 = _data[64];
313 uint8_t b65 = _data[65];
314 uint8_t b66 = _data[66];
315 uint8_t b71 = _data[71];
316 uint8_t fmt_ver = format_version();
318 if (fmt_ver == 1 || fmt_ver == 2) {
319 dt.tm_year = ((((b71 & 0xC0) >> 1) | ((b64 >> 3) & 0x1F)) + 100);
321 dt.tm_year = ((b64 >> 3) + 100);
323 dt.tm_mon = (((b64 & 0x07) << 1) | ((b65 & 0x80) >> 7)) - 1;
324 dt.tm_mday = (b65 & 0x7C) >> 2;
325 dt.tm_hour = ((b65 & 0x03) << 3) | ((b66 & 0xE0) >> 5);
331 DateTime get_expire_date()
const
333 DateTime dt = issue_date();
334 uint8_t b66 = _data[66];
335 uint8_t b71 = _data[71];
336 uint8_t fmt_ver = format_version();
337 uint8_t expire_years{};
339 if (fmt_ver == 1 || fmt_ver == 2) {
340 expire_years = (b66 & 0x1F) | ((b71 & 0x30) << 1);
342 expire_years = b66 & 0x1F;
345 if (expire_years != 0) {
346 dt.tm_year += expire_years;
349 dt.tm_year = 9999 - 1900;
3667:01:52.557 > [ 899][E][unit_ATECC608B.cpp:1186] receive_response(): CRC error: C76B != FFFF (count:35 max_read:35)
36717:01:52.563 > DUMP:0x3ffb2080 35 bytes
36817:01:52.572 > 0x3ffb2080| 23 8F 0F 8F 8F 0F 0F 8F 0F 0F 8F 0F 8F 0F 8F 8F |#...............
36917:01:52.578 > 0x3ffb2090| 8F 8F 8F 9F FF FF FF FF FF FF FF FF FF FF FF FF |................
37017:01:52.583 > 0x3ffb20a0| FF FF FF |...
37117:01:52.589 > [ 923][E][PlotToSerial.cpp:237] setup(): readConfigZone NG
37217:01:52.590 > [ 936][E][unit_ATECC608B.cpp:1210] read_data(): Failed send_command:01 0002
37317:01:52.596 > [ 941][E][PlotToSerial.cpp:242] setup(): readOTPZone NG
37417:01:52.607 > [ 941][W][unit_ATECC608B.cpp:596] wakeup_i2c_class(): Wakeup retry 0 err:-5 resp:00,00,00,00
37517:01:52.620 > [ 962][W][unit_ATECC608B.cpp:596] wakeup_i2c_class(): Wakeup retry 1 err:-5 resp:00,00,00,00
37617:01:52.631 > [ 972][E][unit_ATECC608B.cpp:1186] receive_response(): CRC error: 2C9E != FFFF (count:35 max_read:35)
37717:01:52.637 > DUMP:0x3ffb1ed0 35 bytes
37817:01:52.646 > 0x3ffb1ed0| 23 07 31 00 64 FE AF 6E A0 7A 2F F5 96 55 AA 6B |#.1.d..n.z/..U.k
37917:01:52.652 > 0x3ffb1ee0| 11 AF 44 A3 1E DF DD 2E 57 E3 96 F0 FF FF FF FF |..D.....W.......
38017:01:52.657 > 0x3ffb1ef0| FF FF FF |...
38117:01:52.663 > [ 997][E][PlotToSerial.cpp:247] setup(): readDataZone NG
38217:01:52.671 > [ 1013][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
38317:01:52.677 > [ 1018][E][PlotToSerial.cpp:253] setup(): readKeyValid[1] NG
38417:01:52.682 > [ 1022][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
38517:01:52.688 > [ 1027][E][PlotToSerial.cpp:253] setup(): readKeyValid[2] NG
38617:01:52.693 > [ 1040][W][unit_ATECC608B.cpp:596] wakeup_i2c_class(): Wakeup retry 0 err:-5 resp:00,00,00,00
38717:01:52.705 > [ 1048][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
38817:01:52.710 > [ 1053][E][PlotToSerial.cpp:253] setup(): readKeyValid[4] NG
38917:01:52.716 > [ 1057][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
39017:01:52.727 > [ 1062][E][PlotToSerial.cpp:253] setup(): readKeyValid[5] NG
39117:01:52.732 > [ 1071][E][unit_ATECC608B.cpp:1186] receive_response(): CRC error: 0F0E != FFFF (count:7 max_read:7)
39217:01:52.738 > DUMP:0x3ffb1f30 7 bytes
39317:01:52.747 > 0x3ffb1f30| 07 00 00 0F FF FF FF |.......
39417:01:52.753 > [ 1086][E][PlotToSerial.cpp:253] setup(): readKeyValid[6] NG
39517:01:52.760 > [ 1104][E][PlotToSerial.cpp:253] setup(): readKeyValid[8] NG
39617:01:52.765 > [ 1104][W][unit_ATECC608B.cpp:596] wakeup_i2c_class(): Wakeup retry 0 err:-5 resp:00,00,00,00
39717:01:52.771 > [ 1113][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
39817:01:52.776 > [ 1118][E][PlotToSerial.cpp:253] setup(): readKeyValid[9] NG
39917:01:52.787 > [ 1129][W][unit_ATECC608B.cpp:596] wakeup_i2c_class(): Wakeup retry 0 err:-5 resp:00,00,00,00
40017:01:52.793 > [ 1138][E][PlotToSerial.cpp:253] setup(): readKeyValid[11] NG
40117:01:52.798 > [ 1138][W][unit_ATECC608B.cpp:596] wakeup_i2c_class(): Wakeup retry 0 err:-5 resp:00,00,00,00
40217:01:52.810 > [ 1150][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
40317:01:52.815 > [ 1155][E][PlotToSerial.cpp:253] setup(): readKeyValid[12] NG
40417:01:52.821 > [ 1162][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
40517:01:52.832 > [ 1167][E][PlotToSerial.cpp:253] setup(): readKeyValid[13] NG
40617:01:52.837 > [ 1176][E][unit_ATECC608B.cpp:1186] receive_response(): CRC error: 2552 != 0000 (count:31 max_read:7)
40717:01:52.843 > DUMP:0x3ffb1f30 7 bytes
40817:01:52.852 > 0x3ffb1f30| 1F FF FF FF FF FF FF |.......
40917:01:52.858 > [ 1191][E][PlotToSerial.cpp:253] setup(): readKeyValid[14] NG
41017:01:52.866 > [ 1208][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
41117:01:52.872 > [ 1213][E][PlotToSerial.cpp:259] setup(): readCounter(0) NG
41217:01:52.877 > [ 1218][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
41317:01:52.883 > [ 1223][E][PlotToSerial.cpp:262] setup(): readCounter(1) NG
41417:01:52.888 > [ 1230][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
41517:01:52.900 > [ 1235][E][PlotToSerial.cpp:267] setup(): readDeviceState NG
41617:01:53.099 > [ 1441][E][unit_ATECC608B.cpp:1173] receive_response(): Failed to read response
41717:01:53.105 > [ 1446][E][PlotToSerial.cpp:272] setup(): selfTest NG
Source
Data source.
Definition atecc608.hpp:48
@ AlternateKeyBuffer
Alternate Key Buffer.
@ ExternalBuffer
Any buffer.
@ MsgDigestBuffer
Message digest buffer.
Slot
Slot configuration summary.
Definition atecc608.hpp:26
@ SecondaryPrivateKey1
Secondary private key for other uses.
@ SignerCompressedCertificate
@ MACAddress
IEEE EUI-48 MAC Address.
@ PrimaryPrivateKey
Primary authentication key.
@ SignerPublicKey
Public key for the CA (signer) that signed the device cert.
@ SecondaryPrivateKey3
Secondary private key for other uses.
@ DeviceCompressedCertificate
Certificate primary public key in the CryptoAuthentication compressed format.
@ IOProtectionKey
Key used to protect the I2C bus communication (IO) of certain commands.
@ SecondaryPrivateKey2
Secondary private key for other uses.
@ GeneralData
General purpose data storage (416 bytes)
@ AESKey
Intermediate key storage for ECDH and KDF output.
uint16_t slot_block_to_param2(const uint8_t slot, const uint16_t offset)
Conversion slot and block to address for Data zone.
Definition atecc608.hpp:214
constexpr uint32_t encoded_base64_length(const uint32_t ilen)
Calculate encoded size (no line break)
Definition atecc608.hpp:222
uint16_t offset_to_param2_for_config(const uint8_t offset)
Conversion offset to address for Config,OTP zone.
Definition atecc608.hpp:207
Error
Error status.
Definition atecc608.hpp:71
Compressed certificate accessor.
Top level namespace of M5stack.
Definition atecc608.hpp:244