Skip to content

Commit d200e94

Browse files
committed
CryptoUtil: extend class in order to abstract hardware crypto
1 parent 40f2a97 commit d200e94

File tree

4 files changed

+180
-41
lines changed

4 files changed

+180
-41
lines changed

src/ArduinoIoTCloudTCP.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -204,30 +204,30 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
204204
#endif /* OTA_ENABLED */
205205

206206
#ifdef BOARD_HAS_OFFLOADED_ECCX08
207-
if (!ECCX08.begin())
207+
if (!_crypto.begin())
208208
{
209-
DEBUG_ERROR("ECCX08.begin() failed.");
209+
DEBUG_ERROR("_crypto.begin() failed.");
210210
return 0;
211211
}
212-
if (!CryptoUtil::readDeviceId(ECCX08, getDeviceId(), ECCX08Slot::DeviceId))
212+
if (!_crypto.readDeviceId(getDeviceId(), CryptoSlot::DeviceId))
213213
{
214-
DEBUG_ERROR("CryptoUtil::readDeviceId(...) failed.");
214+
DEBUG_ERROR("_crypto.readDeviceId(...) failed.");
215215
return 0;
216216
}
217217
#endif
218218

219219
#ifdef BOARD_HAS_ECCX08
220-
if (!ECCX08.begin())
220+
if (!_crypto::beginCrypto())
221221
{
222222
DEBUG_ERROR("Cryptography processor failure. Make sure you have a compatible board.");
223223
return 0;
224224
}
225-
if (!CryptoUtil::readDeviceId(ECCX08, getDeviceId(), ECCX08Slot::DeviceId))
225+
if (!_crypto.readDeviceId(getDeviceId(), CryptoSlot::DeviceId))
226226
{
227227
DEBUG_ERROR("Cryptography processor read failure.");
228228
return 0;
229229
}
230-
if (!CryptoUtil::reconstructCertificate(_eccx08_cert, getDeviceId(), ECCX08Slot::Key, ECCX08Slot::CompressedCertificate, ECCX08Slot::SerialNumberAndAuthorityKeyIdentifier))
230+
if (!_crypto.readCert(_cert, CryptoSlot::CompressedCertificate))
231231
{
232232
DEBUG_ERROR("Cryptography certificate reconstruction failure.");
233233
return 0;

src/ArduinoIoTCloudTCP.h

+4
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@
2929
#ifdef BOARD_HAS_ECCX08
3030
#include "tls/BearSSLClient.h"
3131
#include "tls/utility/ECCX08Cert.h"
32+
#include "tls/utility/CryptoUtil.h"
3233
#elif defined(BOARD_ESP)
3334
#include <WiFiClientSecure.h>
3435
#endif
3536

3637
#ifdef BOARD_HAS_OFFLOADED_ECCX08
3738
#include "tls/utility/ECCX08Cert.h"
39+
#include "tls/utility/CryptoUtil.h"
3840
#include <WiFiSSLClient.h>
3941
#endif
4042

@@ -135,9 +137,11 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
135137
#if defined(BOARD_HAS_ECCX08)
136138
ECCX08CertClass _eccx08_cert;
137139
BearSSLClient _sslClient;
140+
CryptoUtil _crypto;
138141
#elif defined(BOARD_HAS_OFFLOADED_ECCX08)
139142
ECCX08CertClass _eccx08_cert;
140143
WiFiBearSSLClient _sslClient;
144+
CryptoUtil _crypto;
141145
#elif defined(BOARD_ESP)
142146
WiFiClientSecure _sslClient;
143147
String _password;

src/tls/utility/CryptoUtil.cpp

+151-23
Original file line numberDiff line numberDiff line change
@@ -19,43 +19,171 @@
1919
* INCLUDE
2020
******************************************************************************/
2121

22+
#include <AIoTC_Config.h>
23+
24+
#if defined(BOARD_HAS_ECCX08) || defined(BOARD_HAS_OFFLOADED_ECCX08)
25+
2226
#include "CryptoUtil.h"
27+
#include "SHA256.h"
28+
29+
/******************************************************************************
30+
* DEFINE
31+
******************************************************************************/
32+
#define CRYPTO_SHA256_BUFFER_LENGTH 32
33+
#define CRYPTO_CERT_BUFFER_LENGTH 1024
34+
35+
/**************************************************************************************
36+
* CTOR/DTOR
37+
**************************************************************************************/
38+
CryptoUtil::CryptoUtil()
39+
: _crypto {ECCX08}
40+
{
2341

24-
#if defined(BOARD_HAS_ECCX08) || defined (BOARD_HAS_OFFLOADED_ECCX08)
42+
}
2543

2644
/******************************************************************************
2745
* PUBLIC MEMBER FUNCTIONS
2846
******************************************************************************/
2947

30-
bool CryptoUtil::readDeviceId(ECCX08Class & eccx08, String & device_id, ECCX08Slot const device_id_slot)
48+
int CryptoUtil::buildCSR(ArduinoIoTCloudCertClass & cert, const CryptoSlot keySlot, bool newPrivateKey)
49+
{
50+
byte publicKey[CERT_PUBLIC_KEY_LENGTH];
51+
byte signature[CERT_SIGNATURE_LENGTH];
52+
53+
if (newPrivateKey) {
54+
if (!_crypto.generatePrivateKey(static_cast<int>(keySlot), publicKey)) {
55+
return 0;
56+
}
57+
} else {
58+
if (!_crypto.generatePublicKey(static_cast<int>(keySlot), publicKey)) {
59+
return 0;
60+
}
61+
}
62+
63+
/* Store public key in csr */
64+
if (!cert.setPublicKey(publicKey, CERT_PUBLIC_KEY_LENGTH)) {
65+
return 0;
66+
}
67+
68+
/* Build CSR */
69+
if (!cert.buildCSR()) {
70+
return 0;
71+
}
72+
73+
/* compute CSR SHA256 */
74+
SHA256 sha256;
75+
byte sha256buf[CRYPTO_SHA256_BUFFER_LENGTH];
76+
sha256.begin();
77+
sha256.update(cert.bytes(), cert.length());
78+
sha256.finalize(sha256buf);
79+
80+
if (!_crypto.ecSign(static_cast<int>(keySlot), sha256buf, signature)) {
81+
return 0;
82+
}
83+
84+
/* sign CSR */
85+
return cert.signCSR(signature);
86+
}
87+
88+
int CryptoUtil::buildCert(ArduinoIoTCloudCertClass & cert, const CryptoSlot keySlot)
89+
{
90+
byte publicKey[CERT_PUBLIC_KEY_LENGTH];
91+
92+
if (!_crypto.generatePublicKey(static_cast<int>(keySlot), publicKey)) {
93+
return 0;
94+
}
95+
96+
/* Store public key in csr */
97+
if (!cert.setPublicKey(publicKey, CERT_PUBLIC_KEY_LENGTH)) {
98+
return 0;
99+
}
100+
101+
/* Build CSR */
102+
if (!cert.buildCert()) {
103+
return 0;
104+
}
105+
106+
/* sign CSR */
107+
return cert.signCert();
108+
}
109+
110+
int CryptoUtil::readDeviceId(String & device_id, const CryptoSlot device_id_slot)
111+
{
112+
byte device_id_bytes[CERT_COMPRESSED_CERT_SLOT_LENGTH] = {0};
113+
114+
if (!_crypto.readSlot(static_cast<int>(device_id_slot), device_id_bytes, sizeof(device_id_bytes))) {
115+
return 0;
116+
}
117+
118+
device_id = String(reinterpret_cast<char *>(device_id_bytes));
119+
return 1;
120+
}
121+
122+
int CryptoUtil::writeDeviceId(String & device_id, const CryptoSlot device_id_slot)
31123
{
32-
byte device_id_bytes[72] = {0};
124+
byte device_id_bytes[CERT_COMPRESSED_CERT_SLOT_LENGTH] = {0};
125+
126+
device_id.getBytes(device_id_bytes, sizeof(device_id_bytes));
33127

34-
if (eccx08.readSlot(static_cast<int>(device_id_slot), device_id_bytes, sizeof(device_id_bytes))) {
35-
device_id = String(reinterpret_cast<char *>(device_id_bytes));
36-
return true;
128+
if (!_crypto.writeSlot(static_cast<int>(device_id_slot), device_id_bytes, sizeof(device_id_bytes))) {
129+
return 0;
37130
}
38-
else
39-
{
40-
return false;
131+
return 1;
132+
}
133+
134+
int CryptoUtil::writeCert(ArduinoIoTCloudCertClass & cert, const CryptoSlot certSlot)
135+
{
136+
if (!_crypto.writeSlot(static_cast<int>(certSlot), cert.compressedCertSignatureAndDatesBytes(), cert.compressedCertSignatureAndDatesLength())) {
137+
return 0;
41138
}
139+
140+
if (!_crypto.writeSlot(static_cast<int>(certSlot) + 1, cert.compressedCertSerialAndAuthorityKeyIdBytes(), cert.compressedCertSerialAndAuthorityKeyIdLenght())) {
141+
return 0;
142+
}
143+
return 1;
42144
}
43145

44-
bool CryptoUtil::reconstructCertificate(ECCX08CertClass & cert, String const & device_id, ECCX08Slot const key, ECCX08Slot const compressed_certificate, ECCX08Slot const serial_number_and_authority_key)
146+
int CryptoUtil::readCert(ArduinoIoTCloudCertClass & cert, const CryptoSlot certSlot)
45147
{
46-
if (cert.beginReconstruction(static_cast<int>(key), static_cast<int>(compressed_certificate), static_cast<int>(serial_number_and_authority_key)))
47-
{
48-
cert.setSubjectCommonName(device_id);
49-
cert.setIssuerCountryName("US");
50-
cert.setIssuerOrganizationName("Arduino LLC US");
51-
cert.setIssuerOrganizationalUnitName("IT");
52-
cert.setIssuerCommonName("Arduino");
53-
return cert.endReconstruction();
54-
}
55-
else
56-
{
57-
return false;
148+
String deviceId;
149+
byte publicKey[CERT_PUBLIC_KEY_LENGTH];
150+
151+
cert.begin();
152+
153+
if (!readDeviceId(deviceId, CryptoSlot::DeviceId)) {
154+
return 0;
155+
}
156+
157+
if (!_crypto.readSlot(static_cast<int>(certSlot), cert.compressedCertSignatureAndDatesBytes(), cert.compressedCertSignatureAndDatesLength())) {
158+
return 0;
159+
}
160+
161+
if (!_crypto.readSlot(static_cast<int>(certSlot) + 1, cert.compressedCertSerialAndAuthorityKeyIdBytes(), cert.compressedCertSerialAndAuthorityKeyIdLenght())) {
162+
return 0;
163+
}
164+
165+
if (!_crypto.generatePublicKey(static_cast<int>(CryptoSlot::Key), publicKey)) {
166+
return 0;
167+
}
168+
169+
cert.setSubjectCommonName(deviceId);
170+
cert.setIssuerCountryName("US");
171+
cert.setIssuerOrganizationName("Arduino LLC US");
172+
cert.setIssuerOrganizationalUnitName("IT");
173+
cert.setIssuerCommonName("Arduino");
174+
175+
if (!cert.setPublicKey(publicKey, CERT_PUBLIC_KEY_LENGTH)) {
176+
return 0;
177+
}
178+
179+
if (!cert.buildCert()) {
180+
return 0;
181+
}
182+
183+
if (!cert.signCert()) {
184+
return 0;
58185
}
186+
return 1;
59187
}
60188

61-
#endif /* BOARD_HAS_ECCX08 */
189+
#endif /* (BOARD_HAS_ECCX08) || defined(BOARD_HAS_OFFLOADED_ECCX08) */

src/tls/utility/CryptoUtil.h

+18-11
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,15 @@
2424

2525
#include <AIoTC_Config.h>
2626

27-
#if defined(BOARD_HAS_ECCX08) || defined (BOARD_HAS_OFFLOADED_ECCX08)
28-
27+
#if defined(BOARD_HAS_ECCX08) || defined(BOARD_HAS_OFFLOADED_ECCX08)
2928
#include <Arduino.h>
29+
#include "Cert.h"
3030
#include <ArduinoECCX08.h>
31-
#include "ECCX08Cert.h"
3231

3332
/******************************************************************************
3433
TYPEDEF
3534
******************************************************************************/
36-
37-
enum class ECCX08Slot : int
35+
enum class CryptoSlot : int
3836
{
3937
Key = 0,
4038
CompressedCertificate = 10,
@@ -50,17 +48,26 @@ class CryptoUtil
5048
{
5149
public:
5250

53-
static bool readDeviceId(ECCX08Class & eccx08, String & device_id, ECCX08Slot const device_id_slot);
54-
static bool reconstructCertificate(ECCX08CertClass & cert, String const & device_id, ECCX08Slot const key, ECCX08Slot const compressed_certificate, ECCX08Slot const serial_number_and_authority_key);
51+
CryptoUtil();
5552

53+
inline int begin() { return _crypto.begin(); }
54+
inline int locked() { return _crypto.locked(); }
55+
inline int writeConfiguration(const byte config[]) { return _crypto.writeConfiguration(config); }
56+
inline int lock() { return _crypto.lock(); }
5657

57-
private:
58+
int buildCSR(ArduinoIoTCloudCertClass & cert, const CryptoSlot keySlot, bool newPrivateKey);
59+
int buildCert(ArduinoIoTCloudCertClass & cert, const CryptoSlot keySlot);
5860

59-
CryptoUtil() { }
60-
CryptoUtil(CryptoUtil const & other) { }
61+
int readDeviceId(String & device_id, const CryptoSlot device_id_slot);
62+
int writeDeviceId(String & device_id, const CryptoSlot device_id_slot);
63+
int writeCert(ArduinoIoTCloudCertClass & cert, const CryptoSlot certSlot);
64+
int readCert(ArduinoIoTCloudCertClass & cert, const CryptoSlot certSlot);
65+
66+
private:
67+
ECCX08Class & _crypto;
6168

6269
};
6370

64-
#endif /* BOARD_HAS_ECCX08 */
71+
#endif /* BOARD_HAS_ECCX08 || BOARD_HAS_OFFLOADED_ECCX08 */
6572

6673
#endif /* ARDUINO_IOT_CLOUD_UTILITY_CRYPTO_CRYPTO_UTIL_H_ */

0 commit comments

Comments
 (0)