cryptnox-sdk-arduino 1.0.0
Arduino library for Cryptnox Hardware Wallet
Loading...
Searching...
No Matches
ArduinoCryptoProvider.cpp
Go to the documentation of this file.
1/*
2 * SPDX-License-Identifier: LGPL-3.0-or-later
3 * Copyright (c) 2026 Cryptnox SA
4 */
5
15
17#include <trng.h>
18#if CW_VERIFY_CERT
19#include <SHA256.h>
20#endif
21#include <SHA512.h>
22#include <AES.h>
23
30
41const uECC_Curve_t* ArduinoCryptoProvider::toUEccCurve(CW_Curve curve) {
42 switch (curve) {
43 case CW_CURVE_SECP256R1: return uECC_secp256r1();
44#if uECC_SUPPORTS_secp256k1
45 case CW_CURVE_SECP256K1: return uECC_secp256k1();
46#endif
47 default: return NULL;
48 }
49}
50
55 /* Lazy init: the RA4M1 TRNG peripheral is enabled on first read so
56 * the constructor stays cheap and order-of-construction-safe with
57 * other global objects in the sketch. */
58 static bool initialized = false;
59 if (!initialized) {
60 TRNG.begin();
61 initialized = true;
62 }
63 uint8_t out = 0U;
64 TRNG.random8(&out);
65 return out;
66}
67
71int ArduinoCryptoProvider::trngCallback(uint8_t* dest, unsigned size) {
72 int ret = 0;
73 if ((dest != NULL) && (size > 0U)) {
74 for (unsigned i = 0U; i < size; i++) {
75 dest[i] = trngByte();
76 }
77 ret = 1;
78 }
79 return ret;
80}
81
85bool ArduinoCryptoProvider::sha256(const uint8_t* data, size_t len, uint8_t* out) {
86 if (out == NULL) { return false; }
87#if CW_VERIFY_CERT
88 if ((data == NULL) && (len > 0U)) { return false; }
89 SHA256 sha;
90 sha.update(data, len);
91 sha.finalize(out, 32U);
92#else
93 /* Card-certificate verification compiled out: keep the symbol but skip
94 * the work so the SHA256 dependency is not pulled in by the linker. */
95 (void)data; (void)len; (void)out;
96#endif
97 return true;
98}
99
103bool ArduinoCryptoProvider::sha512(const uint8_t* data, size_t len, uint8_t* out) {
104 if (out == NULL) { return false; }
105 if ((data == NULL) && (len > 0U)) { return false; }
106 SHA512 sha;
107 sha.update(data, len);
108 sha.finalize(out, 64U);
109 return true;
110}
111
115uint16_t ArduinoCryptoProvider::aesCbcEncrypt(const uint8_t* in, uint16_t len, uint8_t* out,
116 const uint8_t* key, uint8_t keyLen,
117 uint8_t* iv, bool bitPadding) {
118 _aes.set_paddingmode(bitPadding ? paddingMode::Bit : paddingMode::Null);
119 return _aes.encrypt(reinterpret_cast<const byte*>(in), len, out,
120 reinterpret_cast<const byte*>(key), static_cast<int>(keyLen), iv);
121}
122
126uint16_t ArduinoCryptoProvider::aesCbcDecrypt(uint8_t* in, uint16_t len, uint8_t* out,
127 const uint8_t* key, uint8_t keyLen,
128 uint8_t* iv, bool bitPadding) {
129 _aes.set_paddingmode(bitPadding ? paddingMode::Bit : paddingMode::Null);
130 return _aes.decrypt(in, len, out,
131 reinterpret_cast<const byte*>(key), static_cast<int>(keyLen), iv);
132}
133
137bool ArduinoCryptoProvider::ecdh(const uint8_t* pubKey, const uint8_t* privKey,
138 uint8_t* secret, CW_Curve curve) {
139 const uECC_Curve_t* uc = toUEccCurve(curve);
140 if (uc == NULL) { return false; }
141 return (uECC_shared_secret(pubKey, privKey, secret, uc) != 0);
142}
143
147bool ArduinoCryptoProvider::makeKey(uint8_t* pubKey, uint8_t* privKey,
148 CW_Curve curve) {
149 const uECC_Curve_t* uc = toUEccCurve(curve);
150 if (uc == NULL) { return false; }
151 return (uECC_make_key(pubKey, privKey, uc) != 0);
152}
153
157bool ArduinoCryptoProvider::random(uint8_t* dest, unsigned size) {
158 return (trngCallback(dest, size) == 1);
159}
160
164bool ArduinoCryptoProvider::ecdsaVerify(const uint8_t* pubKey64,
165 const uint8_t* hash, size_t hashLen,
166 const uint8_t* sig, CW_Curve curve) {
167 const uECC_Curve_t* uc = toUEccCurve(curve);
168 if (uc == NULL) { return false; }
169 return (uECC_verify(pubKey64, hash, static_cast<unsigned>(hashLen), sig, uc) != 0);
170}
Concrete CW_CryptoProvider for the Arduino UNO R4 (RA4M1).
@ CW_CURVE_SECP256K1
Definition CW_Defs.h:153
@ CW_CURVE_SECP256R1
Definition CW_Defs.h:152
uint16_t aesCbcDecrypt(uint8_t *in, uint16_t len, uint8_t *out, const uint8_t *key, uint8_t keyLen, uint8_t *iv, bool bitPadding) override
AES-CBC decrypt (selectable bit / null padding).
static uint8_t trngByte()
Generate one random byte from the RA4M1 hardware TRNG.
bool makeKey(uint8_t *pubKey, uint8_t *privKey, CW_Curve curve) override
Generate a fresh EC keypair via micro-ecc.
static const uECC_Curve_t * toUEccCurve(CW_Curve curve)
Translate a portable CW_Curve to the matching micro-ecc descriptor.
uint16_t aesCbcEncrypt(const uint8_t *in, uint16_t len, uint8_t *out, const uint8_t *key, uint8_t keyLen, uint8_t *iv, bool bitPadding) override
AES-CBC encrypt (selectable bit / null padding).
bool sha512(const uint8_t *data, size_t len, uint8_t *out) override
Compute SHA-512 over a contiguous buffer.
bool ecdsaVerify(const uint8_t *pubKey64, const uint8_t *hash, size_t hashLen, const uint8_t *sig, CW_Curve curve) override
Verify a raw r||s ECDSA signature against a message hash.
AESLib _aes
AESLib engine instance reused across all aesCbc* calls.
bool sha256(const uint8_t *data, size_t len, uint8_t *out) override
Compute SHA-256 over a contiguous buffer.
static int trngCallback(uint8_t *dest, unsigned size)
Static RNG callback registered with uECC_set_rng().
ArduinoCryptoProvider()
Construct the provider and install the RA4M1 TRNG into micro-ecc.
bool random(uint8_t *dest, unsigned size) override
Fill a buffer with random bytes from the RA4M1 hardware TRNG.
bool ecdh(const uint8_t *pubKey, const uint8_t *privKey, uint8_t *secret, CW_Curve curve) override
Compute the ECDH shared secret on a portable curve identifier.
CW_Curve
Portable curve identifier used throughout the SDK.
Definition CW_Defs.h:151