M5Unit-CRYPTO 0.0.1 git rev:e7369a6
Loading...
Searching...
No Matches
atecc608.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_CRYPTO_ATECC608_HPP
11#define M5_UNIT_CRYPTO_ATECC608_HPP
12
13#include <cstdint>
14
15namespace m5 {
16namespace unit {
21namespace atecc608 {
43
48enum class Source : uint8_t {
49 TempKey,
53};
58using Destination = Source;
59
62constexpr uint8_t ZONE_CONFIG{0x00};
63constexpr uint8_t ZONE_OTP{0x01};
64constexpr uint8_t ZONE_DATA{0x02};
66
71enum Error : uint8_t {
72 CHECK_MAC_OR_VERIFY_ERROR = 0x01,
73 PARSE_ERROR = 0x03,
74 ECC_FAULT = 0x05,
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,
81};
82
86constexpr uint32_t DELAY_READ{3};
87constexpr uint32_t DELAY_WRITE{4};
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{105};
99
102constexpr uint8_t WORD_VALUE_RESET{0x00};
103constexpr uint8_t WORD_ADRESS_VALUE_SLEEP{0x01};
104constexpr uint8_t WORD_ADRESS_VALUE_IDLE{0x02};
105constexpr uint8_t WORD_ADRESS_VALUE_COMMAND{0x03};
107
110constexpr uint8_t OPCODE_READ{0x02};
111// constexpr uint8_t OPCODE_WRITE{0x12};
112constexpr uint8_t OPCODE_NONCE{0x16};
113// constexpr uint8_t OPCODE_LOCK{0x17};
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};
124
127constexpr uint8_t INFO_MODE_REVISION{0x00};
128constexpr uint8_t INFO_MODE_KEYVALID{0x01};
129constexpr uint8_t INFO_MODE_DEVICE_STATE{0x02};
131
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};
138
139constexpr uint8_t NONCE_MODE_TARGET_TEMPKEY{0x00};
140constexpr uint8_t NONCE_MODE_TARGET_DIGEST{0x40};
141constexpr uint8_t NONCE_MODE_TARGET_ALTKEY{0x80};
142
143constexpr uint16_t NONCE_USE_TRNG{0x0000};
144constexpr uint16_t NONCE_USE_TEMPKEY{0x8000};
146
149constexpr uint8_t RANDOM_MODE_UPDATE_SEED{0x00};
150constexpr uint8_t RANDOM_MODE_NOT_UPDATE_SEED{0x01};
152
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};
162
165// constexpr uint8_t ECDH_MODE_SLOT{0x04};
166constexpr uint8_t ECDH_MODE_SRC_SLOT{0x00};
167constexpr uint8_t ECDH_MODE_SRC_TEMPKEY{0x01};
168
169constexpr uint8_t ECDH_MODE_ENCRYPT{0x02};
170
171constexpr uint8_t ECDH_MODE_OUTPUT_TEMPKEY{0x08};
172constexpr uint8_t ECDH_MODE_OUTPUT_BUFFER{0x0C};
173constexpr uint8_t ECDH_MODE_OUTPUT_SLOT{0x04};
175
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};
183
186constexpr uint8_t SIGN_MODE_INTERNAL{0x00};
187constexpr uint8_t SIGN_MODE_INCLUDE_SN{0x40};
188constexpr uint8_t SIGN_MODE_EXTERNAL{0x80};
189
190constexpr uint8_t SIGN_MODE_TEMPKEY{0x00};
191constexpr uint8_t SIGN_MODE_DIGEST{0x20};
192
195constexpr uint8_t VERIFY_MODE_STORED{0x00};
196constexpr uint8_t VERIFY_MODE_EXTERNAL{0x02};
197
198constexpr uint8_t VERIFY_MODE_TEMPKEY{0x00};
199constexpr uint8_t VERIFY_MODE_DIGEST{0x20};
200
201constexpr uint8_t VERIFY_MODE_MAC{0x80};
204
206inline uint16_t offset_to_param2_for_config(const uint8_t offset)
207{
208 const uint8_t block = (offset >> 5) & 0x03; // 0〜3
209 const uint8_t index = ((offset & 31) >> 2) & 0x07; // 0〜7
210 return (block << 3) | index;
211}
213inline uint16_t slot_block_to_param2(const uint8_t slot, const uint8_t offset)
214{
215 const uint8_t block = offset >> 5; // 0〜2
216 const uint8_t word_offset = (offset & 31) >> 2; // 0〜7
217 return (slot << 3) | (block << 8) | word_offset;
218}
219
221constexpr inline uint32_t encoded_base64_length(const uint32_t ilen)
222{
223 return ((ilen + 2) / 3) * 4;
224}
225
227bool convertToPEM(char* out, const uint32_t out_len, const uint8_t* der, uint32_t dlen,
228 const char* header = "CERTIFICATE", const char* footer = "CERTIFICATE");
229
231extern const uint8_t template_for_device[];
232extern const uint8_t template_for_signer[];
233extern const uint32_t template_for_device_size;
234extern const uint32_t template_for_signer_size;
236
237/*1
238 @class m5::unit::atecc608::CompCertAccessor
239 @brief Compressed certificate accessor
240 */
242public:
243 struct DateTime {
244 int tm_sec; // 0 to 59
245 int tm_min; // 0 to 59
246 int tm_hour; // 0 to 23
247 int tm_mday; // 1 to 31
248 int tm_mon; // 0 to 11
249 int tm_year; // years since 1900
250 };
251
252 explicit CompCertAccessor(const uint8_t* data) : _data(data)
253 {
254 if (_data) {
255 _issue_date = get_issue_date();
256 _expire_date = get_expire_date();
257 }
258 }
259
260 inline uint8_t format_version() const
261 {
262 return _data[70] & 0x0F;
263 }
264 inline uint8_t template_id() const
265 {
266 return (_data[69] >> 4) & 0x0F;
267 }
268 inline uint8_t chain_id() const
269 {
270 return _data[69] & 0x0F;
271 }
272 inline uint8_t sn_source() const
273 {
274 return (_data[70] >> 4) & 0x0F;
275 }
276
277 inline const uint8_t* signer_id() const
278 {
279 return _data + 67;
280 }
281
282 inline const uint8_t* signature() const
283 {
284 return _data + 0;
285 }
286 inline const uint8_t* signature_r() const
287 {
288 return _data + 0;
289 }
290 inline const uint8_t* signature_s() const
291 {
292 return _data + 32;
293 }
294
295 inline DateTime issue_date() const
296 {
297 return _issue_date;
298 }
299 inline DateTime expire_date() const
300 {
301 return _expire_date;
302 }
303
304private:
305 const uint8_t* _data{};
306 DateTime _issue_date{}, _expire_date{};
307
308 DateTime get_issue_date() const
309 {
310 DateTime dt{};
311 uint8_t b64 = _data[64];
312 uint8_t b65 = _data[65];
313 uint8_t b66 = _data[66];
314 uint8_t b71 = _data[71];
315 uint8_t fmt_ver = format_version();
316
317 if (fmt_ver == 1 || fmt_ver == 2) {
318 dt.tm_year = ((((b71 & 0xC0) >> 1) | ((b64 >> 3) & 0x1F)) + 100);
319 } else {
320 dt.tm_year = ((b64 >> 3) + 100);
321 }
322 dt.tm_mon = (((b64 & 0x07) << 1) | ((b65 & 0x80) >> 7)) - 1;
323 dt.tm_mday = (b65 & 0x7C) >> 2;
324 dt.tm_hour = ((b65 & 0x03) << 3) | ((b66 & 0xE0) >> 5);
325 dt.tm_min = 0;
326 dt.tm_sec = 0;
327 return dt;
328 }
329
330 DateTime get_expire_date() const
331 {
332 DateTime dt = issue_date();
333 uint8_t b66 = _data[66];
334 uint8_t b71 = _data[71];
335 uint8_t fmt_ver = format_version();
336 uint8_t expire_years{};
337
338 if (fmt_ver == 1 || fmt_ver == 2) {
339 expire_years = (b66 & 0x1F) | ((b71 & 0x30) << 1);
340 } else {
341 expire_years = b66 & 0x1F;
342 }
343
344 if (expire_years != 0) {
345 dt.tm_year += expire_years;
346 } else {
347 // indefinite
348 dt.tm_year = 9999 - 1900;
349 dt.tm_mon = 11;
350 dt.tm_mday = 31;
351 dt.tm_hour = 23;
352 dt.tm_min = 59;
353 dt.tm_sec = 59;
354 }
355 return dt;
356 }
357};
358
359} // namespace atecc608
360} // namespace unit
361} // namespace m5
362#endif
Source
Data source.
Definition atecc608.hpp:48
@ AlternateKeyBuffer
Alternate Key Buffer.
@ MsgDigestBuffer
Message digest buffer.
Slot
Slot configuration summay.
Definition atecc608.hpp:26
@ SecondaryPrivateKey1
Secondary private key for other uses.
@ 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 uint8_t offset)
Conversion slot and block to address for Data zone.
Definition atecc608.hpp:213
constexpr uint32_t encoded_base64_length(const uint32_t ilen)
Calculate encoded size (no line break)
Definition atecc608.hpp:221
uint16_t offset_to_param2_for_config(const uint8_t offset)
Conversion offset to address for Config,OTP zone.
Definition atecc608.hpp:206
Error
Error status.
Definition atecc608.hpp:71
Definition atecc608.hpp:241
For ATECC608.
Top level namespace of M5stack.
Unit-related namespace.