Skip to content

Commit c67e03d

Browse files
committed
Use ECC508 for entropy inject, if available
1 parent b654a10 commit c67e03d

File tree

3 files changed

+203
-5
lines changed

3 files changed

+203
-5
lines changed

src/BearSSLClient.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "ArduinoBearSSL.h"
22
#include "BearSSLTrustAnchors.h"
3+
#include "utility/ECC508.h"
34

45
#include "BearSSLClient.h"
56

@@ -155,13 +156,15 @@ int BearSSLClient::connectSSL(const char* host)
155156
*/
156157
br_ssl_engine_set_buffer(&_sc.eng, _iobuf, sizeof(_iobuf), 1);
157158

158-
// inject (pseudo) entropy in engine
159-
#warning "connectSSL: pseudo entropy injected!"
159+
// inject entropy in engine
160160
unsigned char entropy[32];
161161

162-
for (size_t i = 0; i < sizeof(entropy); i++) {
163-
entropy[i] = rand() % 256;
164-
}
162+
if (!ECC508.begin() || !ECC508.random(entropy, sizeof(entropy))) {
163+
// no ECC508 or random failed, fallback to pseudo random
164+
for (size_t i = 0; i < sizeof(entropy); i++) {
165+
entropy[i] = random(0, 255);
166+
}
167+
}
165168
br_ssl_engine_inject_entropy(&_sc.eng, entropy, sizeof(entropy));
166169

167170
/*

src/utility/ECC508.cpp

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
#include <Arduino.h>
2+
3+
#include "ECC508.h"
4+
5+
ECC508Class::ECC508Class(TwoWire& wire, uint8_t address) :
6+
_wire(&wire),
7+
_address(address)
8+
{
9+
}
10+
11+
ECC508Class::~ECC508Class()
12+
{
13+
}
14+
15+
int ECC508Class::begin()
16+
{
17+
_wire->begin();
18+
_wire->setClock(100000);
19+
20+
if (version() != 0x500000) {
21+
return 0;
22+
}
23+
24+
return 1;
25+
}
26+
27+
void ECC508Class::end()
28+
{
29+
_wire->end();
30+
}
31+
32+
int ECC508Class::random(byte data[], size_t length)
33+
{
34+
if (!wakeup()) {
35+
return 0;
36+
}
37+
38+
while (length) {
39+
_wire->beginTransmission(_address);
40+
_wire->write(0x03);
41+
_wire->write(0x07);
42+
_wire->write(0x1b);
43+
_wire->write(0x00);
44+
_wire->write(0x00);
45+
_wire->write(0x00);
46+
_wire->write(0x24);
47+
_wire->write(0xcd);
48+
_wire->endTransmission();
49+
50+
delay(23);
51+
52+
byte response[32];
53+
54+
if (!receiveResponse(response, sizeof(response))) {
55+
return 0;
56+
}
57+
58+
int copyLength = min(32, length);
59+
memcpy(data, response, copyLength);
60+
61+
length -= copyLength;
62+
data += copyLength;
63+
}
64+
65+
delay(1);
66+
67+
idle();
68+
69+
return 1;
70+
}
71+
72+
int ECC508Class::wakeup()
73+
{
74+
_wire->beginTransmission(0x00);
75+
_wire->endTransmission();
76+
77+
delayMicroseconds(800);
78+
79+
byte response;
80+
81+
if (!receiveResponse(&response, sizeof(response)) || response != 0x11) {
82+
return 0;
83+
}
84+
85+
return 1;
86+
}
87+
88+
int ECC508Class::sleep()
89+
{
90+
_wire->beginTransmission(_address);
91+
_wire->write(0x01);
92+
93+
if (_wire->endTransmission() != 0) {
94+
return 0;
95+
}
96+
97+
return 1;
98+
}
99+
100+
int ECC508Class::idle()
101+
{
102+
_wire->beginTransmission(_address);
103+
_wire->write(0x02);
104+
105+
if (_wire->endTransmission() != 0) {
106+
return 0;
107+
}
108+
109+
return 1;
110+
}
111+
112+
int ECC508Class::version()
113+
{
114+
uint32_t version = 0;
115+
116+
if (!wakeup()) {
117+
return 0;
118+
}
119+
120+
_wire->beginTransmission(_address);
121+
_wire->write(0x03);
122+
_wire->write(0x07);
123+
_wire->write(0x30);
124+
_wire->write(0x00);
125+
_wire->write(0x00);
126+
_wire->write(0x00);
127+
_wire->write(0x03);
128+
_wire->write(0x5d);
129+
_wire->endTransmission();
130+
131+
delay(2);
132+
133+
if (!receiveResponse(&version, sizeof(version))) {
134+
return 0;
135+
}
136+
137+
delay(1);
138+
idle();
139+
140+
return version;
141+
}
142+
143+
int ECC508Class::receiveResponse(void* response, size_t length)
144+
{
145+
int retries = 20;
146+
int responseSize = length + 3; // 1 for length header, 2 for CRC
147+
byte responseBuffer[responseSize];
148+
149+
while (_wire->requestFrom(_address, responseBuffer, responseSize) != responseSize && retries--);
150+
151+
if (responseBuffer[0] != responseSize) {
152+
return 0;
153+
}
154+
155+
// TODO: verify CRC
156+
157+
memcpy(response, &responseBuffer[1], length);
158+
159+
return 1;
160+
}
161+
162+
ECC508Class ECC508(Wire, 0x60);

src/utility/ECC508.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef _ECC508_H_
2+
#define _ECC508_H_
3+
4+
#include <Wire.h>
5+
6+
class ECC508Class
7+
{
8+
public:
9+
ECC508Class(TwoWire& wire, uint8_t address);
10+
virtual ~ECC508Class();
11+
12+
int begin();
13+
void end();
14+
15+
int random(byte data[], size_t length);
16+
17+
private:
18+
int wakeup();
19+
int sleep();
20+
int idle();
21+
22+
int version();
23+
24+
int receiveResponse(void* response, size_t length);
25+
26+
private:
27+
TwoWire* _wire;
28+
uint8_t _address;
29+
};
30+
31+
extern ECC508Class ECC508;
32+
33+
#endif

0 commit comments

Comments
 (0)