Refactor signing backend (#690)
Cleaned up the AES driver and removed some cppcheck isues in the process.
This commit is contained in:
committed by
Henrik Ekblad
parent
61e6cecb3f
commit
1040fbebc5
+286
-247
@@ -36,6 +36,9 @@
|
||||
#if defined(MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL) && !defined(MY_SIGNING_REQUEST_SIGNATURES)
|
||||
#error You have to require signatures if you want to require signatures from all (also enable MY_SIGNING_REQUEST_SIGNATURES in your gateway)
|
||||
#endif
|
||||
#if defined(MY_SIGNING_SOFT) && defined(MY_SIGNING_ATSHA204)
|
||||
#error You have to pick one and only one signing backend
|
||||
#endif
|
||||
#ifdef MY_SIGNING_FEATURE
|
||||
uint8_t _doSign[32]; // Bitfield indicating which sensors require signed communication
|
||||
uint8_t _doWhitelist[32]; // Bitfield indicating which sensors require serial salted signatures
|
||||
@@ -47,23 +50,17 @@ static uint8_t nof_nonce_requests = 0;
|
||||
static uint8_t nof_failed_verifications = 0;
|
||||
#endif
|
||||
|
||||
// Status when waiting for signing nonce in signerProcessInternal
|
||||
// Status when waiting for signing nonce in signerSignMsg
|
||||
enum { SIGN_WAITING_FOR_NONCE = 0, SIGN_OK = 1 };
|
||||
|
||||
// Macros for manipulating signing requirement table
|
||||
// Macros for manipulating signing requirement tables
|
||||
#define DO_SIGN(node) (~_doSign[node>>3]&(1<<node%8))
|
||||
#define SET_SIGN(node) (_doSign[node>>3]&=~(1<<node%8))
|
||||
#define CLEAR_SIGN(node) (_doSign[node>>3]|=(1<<node%8))
|
||||
#define DO_WHITELIST(node) (~_doWhitelist[node>>3]&(1<<node%8))
|
||||
#define SET_WHITELIST(node) (_doWhitelist[node>>3]&=~(1<<node%8))
|
||||
#define CLEAR_WHITELIST(node) (_doWhitelist[node>>3]|=(1<<node%8))
|
||||
|
||||
/*
|
||||
* Stores signing identifier and a new nonce in provided message for signing operations.
|
||||
*
|
||||
* All space in message payload buffer is used for signing identifier and nonce.
|
||||
* Returns false if subsystem is busy processing an ongoing signing operation.
|
||||
* If successful, this marks the start of a signing operation at the receiving side so
|
||||
* implementation is expected to do any necessary initializations within this call.
|
||||
* This function is typically called as action when receiving a I_NONCE_REQUEST message.
|
||||
*/
|
||||
#if defined(MY_SIGNING_SOFT)
|
||||
extern void signerAtsha204SoftInit(void);
|
||||
extern bool signerAtsha204SoftCheckTimer(void);
|
||||
@@ -71,53 +68,34 @@ extern bool signerAtsha204SoftGetNonce(MyMessage &msg);
|
||||
extern void signerAtsha204SoftPutNonce(MyMessage &msg);
|
||||
extern bool signerAtsha204SoftVerifyMsg(MyMessage &msg);
|
||||
extern bool signerAtsha204SoftSignMsg(MyMessage &msg);
|
||||
#endif
|
||||
#if defined(MY_SIGNING_ATSHA204)
|
||||
#define signerBackendInit signerAtsha204SoftInit
|
||||
#define signerBackendCheckTimer signerAtsha204SoftCheckTimer
|
||||
#define signerBackendGetNonce signerAtsha204SoftGetNonce
|
||||
#define signerBackendPutNonce signerAtsha204SoftPutNonce
|
||||
#define signerBackendVerifyMsg signerAtsha204SoftVerifyMsg
|
||||
#define signerBackendSignMsg signerAtsha204SoftSignMsg
|
||||
#elif defined(MY_SIGNING_ATSHA204)
|
||||
extern void signerAtsha204Init(void);
|
||||
extern bool signerAtsha204CheckTimer(void);
|
||||
extern bool signerAtsha204GetNonce(MyMessage &msg);
|
||||
extern void signerAtsha204PutNonce(MyMessage &msg);
|
||||
extern bool signerAtsha204VerifyMsg(MyMessage &msg);
|
||||
extern bool signerAtsha204SignMsg(MyMessage &msg);
|
||||
#define signerBackendInit signerAtsha204Init
|
||||
#define signerBackendCheckTimer signerAtsha204CheckTimer
|
||||
#define signerBackendGetNonce signerAtsha204GetNonce
|
||||
#define signerBackendPutNonce signerAtsha204PutNonce
|
||||
#define signerBackendVerifyMsg signerAtsha204VerifyMsg
|
||||
#define signerBackendSignMsg signerAtsha204SignMsg
|
||||
#endif
|
||||
|
||||
// Helper function to centralize signing/verification exceptions
|
||||
static bool skipSign(MyMessage &msg)
|
||||
{
|
||||
if mGetAck(msg) {
|
||||
SIGN_DEBUG(PSTR("Skipping security for ACK on command %d type %d\n"), mGetCommand(msg), msg.type);
|
||||
return true;
|
||||
} else if (mGetCommand(msg) == C_INTERNAL &&
|
||||
(msg.type == I_NONCE_REQUEST || msg.type == I_NONCE_RESPONSE ||
|
||||
msg.type == I_SIGNING_PRESENTATION ||
|
||||
msg.type == I_ID_REQUEST || msg.type == I_ID_RESPONSE ||
|
||||
msg.type == I_FIND_PARENT_REQUEST || msg.type == I_FIND_PARENT_RESPONSE ||
|
||||
msg.type == I_HEARTBEAT_REQUEST || msg.type == I_HEARTBEAT_RESPONSE ||
|
||||
msg.type == I_PING || msg.type == I_PONG ||
|
||||
msg.type == I_REGISTRATION_REQUEST )) {
|
||||
SIGN_DEBUG(PSTR("Skipping security for command %d type %d\n"), mGetCommand(msg), msg.type);
|
||||
return true;
|
||||
} else if (mGetCommand(msg) == C_STREAM &&
|
||||
(msg.type == ST_FIRMWARE_REQUEST || msg.type == ST_FIRMWARE_RESPONSE ||
|
||||
msg.type == ST_SOUND || msg.type == ST_IMAGE)) {
|
||||
SIGN_DEBUG(PSTR("Skipping security for command %d type %d\n"), mGetCommand(msg), msg.type);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
static bool skipSign(MyMessage &msg);
|
||||
#else // not MY_SIGNING_FEATURE
|
||||
#define signerBackendCheckTimer() true
|
||||
#endif // MY_SIGNING_FEATURE
|
||||
|
||||
// Helper to prepare a signing presentation message
|
||||
static void prepareSigningPresentation(MyMessage &msg, uint8_t destination)
|
||||
{
|
||||
// Only supports version 1 for now
|
||||
(void)build(msg, destination, NODE_SENSOR_ID, C_INTERNAL, I_SIGNING_PRESENTATION).set("");
|
||||
mSetLength(msg, 2);
|
||||
mSetPayloadType(msg, P_CUSTOM); // displayed as hex
|
||||
msg.data[0] = SIGNING_PRESENTATION_VERSION_1;
|
||||
msg.data[1] = 0;
|
||||
}
|
||||
static void prepareSigningPresentation(MyMessage &msg, uint8_t destination);
|
||||
static bool signerInternalProcessPresentation(MyMessage &msg);
|
||||
static bool signerInternalProcessNonceRequest(MyMessage &msg);
|
||||
static bool signerInternalProcessNonceResponse(MyMessage &msg);
|
||||
|
||||
void signerInit(void)
|
||||
{
|
||||
@@ -130,12 +108,7 @@ void signerInit(void)
|
||||
hwReadConfigBlock((void*)_doWhitelist, (void*)EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS,
|
||||
sizeof(_doWhitelist));
|
||||
|
||||
#if defined(MY_SIGNING_SOFT)
|
||||
signerAtsha204SoftInit();
|
||||
#endif
|
||||
#if defined(MY_SIGNING_ATSHA204)
|
||||
signerAtsha204Init();
|
||||
#endif
|
||||
signerBackendInit();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -164,212 +137,92 @@ void signerPresentation(MyMessage &msg, uint8_t destination)
|
||||
|
||||
bool signerProcessInternal(MyMessage &msg)
|
||||
{
|
||||
uint8_t sender = msg.sender;
|
||||
(void)sender;
|
||||
#if !defined(MY_SIGNING_FEATURE)
|
||||
if (msg.type == I_SIGNING_PRESENTATION) {
|
||||
#if defined(MY_GATEWAY_FEATURE)
|
||||
// If we act as gateway and do not have the signing feature and receive a signing request we still
|
||||
// need to do make sure the requester does not believe the gateway still require signatures
|
||||
prepareSigningPresentation(msg, sender);
|
||||
SIGN_DEBUG(
|
||||
PSTR("Informing node %d that we do not require signatures because we do not support it\n"),
|
||||
sender);
|
||||
if (!_sendRoute(msg)) {
|
||||
SIGN_DEBUG(PSTR("Failed to transmit signing presentation!\n"));
|
||||
}
|
||||
return true; // No need to further process I_SIGNING_PRESENTATION in this case
|
||||
#else
|
||||
// If we act as a node and do not have the signing feature then we just silently drop any signing
|
||||
// presentation messages received
|
||||
SIGN_DEBUG(PSTR("Received signing presentation, but signing is not supported (message ignored)\n"));
|
||||
return true;
|
||||
#endif
|
||||
bool ret;
|
||||
switch (msg.type) {
|
||||
case I_SIGNING_PRESENTATION:
|
||||
ret = signerInternalProcessPresentation(msg);
|
||||
break;
|
||||
case I_NONCE_REQUEST:
|
||||
ret = signerInternalProcessNonceRequest(msg);
|
||||
break;
|
||||
case I_NONCE_RESPONSE:
|
||||
ret = signerInternalProcessNonceResponse(msg);
|
||||
break;
|
||||
default:
|
||||
ret = false; // Let the transport process this message further as it is not related to signing
|
||||
break;
|
||||
}
|
||||
#elif defined(MY_SIGNING_FEATURE)
|
||||
if (msg.type == I_NONCE_REQUEST) {
|
||||
#if defined(MY_NODE_LOCK_FEATURE)
|
||||
nof_nonce_requests++;
|
||||
SIGN_DEBUG(PSTR("Nonce requests left until lockdown: %d\n"),
|
||||
MY_NODE_LOCK_COUNTER_MAX-nof_nonce_requests);
|
||||
if (nof_nonce_requests >= MY_NODE_LOCK_COUNTER_MAX) {
|
||||
_nodeLock("TMNR"); //Too many nonces requested
|
||||
}
|
||||
#endif
|
||||
#if defined(MY_SIGNING_SOFT)
|
||||
if (signerAtsha204SoftGetNonce(msg)) {
|
||||
#endif
|
||||
#if defined(MY_SIGNING_ATSHA204)
|
||||
if (signerAtsha204GetNonce(msg)) {
|
||||
#endif
|
||||
if (!_sendRoute(build(msg, msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_NONCE_RESPONSE))) {
|
||||
SIGN_DEBUG(PSTR("Failed to transmit nonce!\n"));
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Transmitted nonce\n"));
|
||||
}
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Failed to generate nonce!\n"));
|
||||
}
|
||||
return true; // No need to further process I_NONCE_REQUEST
|
||||
} else if (msg.type == I_SIGNING_PRESENTATION) {
|
||||
if (msg.data[0] != SIGNING_PRESENTATION_VERSION_1) {
|
||||
SIGN_DEBUG(PSTR("Unsupported signing presentation version (%d)!\n"), msg.data[0]);
|
||||
return true; // Just drop this presentation message
|
||||
}
|
||||
// We only handle version 1 here...
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) {
|
||||
// We received an indicator that the sender require us to sign all messages we send to it
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that require signed messages\n"), msg.sender);
|
||||
SET_SIGN(msg.sender);
|
||||
} else {
|
||||
// We received an indicator that the sender does not require us to sign all messages we send to it
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that do not require signed messages\n"), msg.sender);
|
||||
CLEAR_SIGN(msg.sender);
|
||||
}
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) {
|
||||
// We received an indicator that the sender require us to salt signatures with serial
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that require whitelisting\n"), msg.sender);
|
||||
SET_WHITELIST(msg.sender);
|
||||
} else {
|
||||
// We received an indicator that the sender does not require us to sign all messages we send to it
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that do not require whitelisting\n"), msg.sender);
|
||||
CLEAR_WHITELIST(msg.sender);
|
||||
}
|
||||
|
||||
// Save updated tables
|
||||
hwWriteConfigBlock((void*)_doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS,
|
||||
sizeof(_doSign));
|
||||
hwWriteConfigBlock((void*)_doWhitelist, (void*)EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS,
|
||||
sizeof(_doWhitelist));
|
||||
|
||||
// Inform sender about our preference if we are a gateway, but only require signing if the sender
|
||||
// required signing unless we explicitly configure it to
|
||||
// We do not want a gateway to require signing from all nodes in a network just because it wants one node
|
||||
// to sign it's messages unless we explicitly configure it to
|
||||
#if defined(MY_GATEWAY_FEATURE)
|
||||
prepareSigningPresentation(msg, sender);
|
||||
#if defined(MY_SIGNING_REQUEST_SIGNATURES)
|
||||
if (DO_SIGN(sender)) {
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES;
|
||||
}
|
||||
#if defined(MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL)
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES;
|
||||
#endif
|
||||
#endif
|
||||
#if defined(MY_SIGNING_NODE_WHITELISTING)
|
||||
if (DO_WHITELIST(sender)) {
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING;
|
||||
}
|
||||
#if defined(MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL)
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING;
|
||||
#endif
|
||||
#endif
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we require signatures\n"), sender);
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we do not require signatures\n"), sender);
|
||||
}
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we require whitelisting\n"), sender);
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we do not require whitelisting\n"), sender);
|
||||
}
|
||||
if (!_sendRoute(msg)) {
|
||||
SIGN_DEBUG(PSTR("Failed to transmit signing presentation!\n"));
|
||||
}
|
||||
#endif // MY_GATEWAY_FEATURE
|
||||
return true; // No need to further process I_SIGNING_PRESENTATION
|
||||
} else if (msg.type == I_NONCE_RESPONSE) {
|
||||
// Proceed with signing if nonce has been received
|
||||
SIGN_DEBUG(PSTR("Nonce received from %d. Proceeding with signing...\n"), sender);
|
||||
if (sender != _msgSign.destination) {
|
||||
SIGN_DEBUG(PSTR("Nonce did not come from the destination (%d) of the message to be signed! "
|
||||
"It came from %d.\n"), _msgSign.destination, sender);
|
||||
SIGN_DEBUG(PSTR("Silently discarding this nonce\n"));
|
||||
return true; // No need to further process I_NONCE_RESPONSE
|
||||
}
|
||||
#if defined(MY_SIGNING_SOFT)
|
||||
signerAtsha204SoftPutNonce(msg);
|
||||
#endif
|
||||
#if defined(MY_SIGNING_ATSHA204)
|
||||
signerAtsha204PutNonce(msg);
|
||||
#endif
|
||||
#if defined(MY_SIGNING_SOFT)
|
||||
if (!signerAtsha204SoftSignMsg(_msgSign)) {
|
||||
#endif
|
||||
#if defined(MY_SIGNING_ATSHA204)
|
||||
if (!signerAtsha204SignMsg(_msgSign)) {
|
||||
#endif
|
||||
SIGN_DEBUG(PSTR("Failed to sign message!\n"));
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Message signed\n"));
|
||||
_signingNonceStatus = SIGN_OK; // _msgSign now contains the signed message pending transmission
|
||||
}
|
||||
return true; // No need to further process I_NONCE_RESPONSE
|
||||
}
|
||||
#endif // MY_SIGNING_FEATURE
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool signerCheckTimer(void) {
|
||||
#if defined(MY_SIGNING_SOFT)
|
||||
return signerAtsha204SoftCheckTimer();
|
||||
#elif defined(MY_SIGNING_ATSHA204)
|
||||
return signerAtsha204CheckTimer();
|
||||
#else
|
||||
return true; // Without a configured backend, we always give "positive" results
|
||||
#endif
|
||||
bool signerCheckTimer(void)
|
||||
{
|
||||
return signerBackendCheckTimer();
|
||||
}
|
||||
|
||||
bool signerSignMsg(MyMessage &msg) {
|
||||
bool signerSignMsg(MyMessage &msg)
|
||||
{
|
||||
bool ret;
|
||||
#if defined(MY_SIGNING_FEATURE)
|
||||
// If destination is known to require signed messages and we are the sender,
|
||||
// sign this message unless it is a handshake message
|
||||
// sign this message unless it is identified as an exception
|
||||
if (DO_SIGN(msg.destination) && msg.sender == getNodeId()) {
|
||||
if (skipSign(msg)) {
|
||||
return true;
|
||||
ret = true;
|
||||
} else {
|
||||
// Send nonce-request
|
||||
_signingNonceStatus=SIGN_WAITING_FOR_NONCE;
|
||||
if (!_sendRoute(build(_msgSign, msg.destination, msg.sensor, C_INTERNAL,
|
||||
I_NONCE_REQUEST).set(""))) {
|
||||
SIGN_DEBUG(PSTR("Failed to transmit nonce request!\n"));
|
||||
return false;
|
||||
}
|
||||
SIGN_DEBUG(PSTR("Nonce requested from %d. Waiting...\n"), msg.destination);
|
||||
// We have to wait for the nonce to arrive before we can sign our original message
|
||||
// Other messages could come in-between. We trust _process() takes care of them
|
||||
unsigned long enter = hwMillis();
|
||||
_msgSign = msg; // Copy the message to sign since message buffer might be touched in _process()
|
||||
while (hwMillis() - enter < MY_VERIFICATION_TIMEOUT_MS &&
|
||||
_signingNonceStatus==SIGN_WAITING_FOR_NONCE) {
|
||||
_process();
|
||||
}
|
||||
if (hwMillis() - enter > MY_VERIFICATION_TIMEOUT_MS) {
|
||||
SIGN_DEBUG(PSTR("Timeout waiting for nonce!\n"));
|
||||
return false;
|
||||
}
|
||||
if (_signingNonceStatus == SIGN_OK) {
|
||||
// process() received a nonce and signerProcessInternal successfully signed the message
|
||||
msg = _msgSign; // Write the signed message back
|
||||
SIGN_DEBUG(PSTR("Message to send has been signed\n"));
|
||||
ret = false;
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Message to send could not be signed!\n"));
|
||||
return false;
|
||||
SIGN_DEBUG(PSTR("Nonce requested from %d. Waiting...\n"), msg.destination);
|
||||
// We have to wait for the nonce to arrive before we can sign our original message
|
||||
// Other messages could come in-between. We trust _process() takes care of them
|
||||
unsigned long enter = hwMillis();
|
||||
_msgSign = msg; // Copy the message to sign since message buffer might be touched in _process()
|
||||
while (hwMillis() - enter < MY_VERIFICATION_TIMEOUT_MS &&
|
||||
_signingNonceStatus==SIGN_WAITING_FOR_NONCE) {
|
||||
_process();
|
||||
}
|
||||
if (hwMillis() - enter > MY_VERIFICATION_TIMEOUT_MS) {
|
||||
SIGN_DEBUG(PSTR("Timeout waiting for nonce!\n"));
|
||||
ret = false;
|
||||
} else {
|
||||
if (_signingNonceStatus == SIGN_OK) {
|
||||
// process() received a nonce and signerProcessInternal successfully signed the message
|
||||
msg = _msgSign; // Write the signed message back
|
||||
SIGN_DEBUG(PSTR("Message to send has been signed\n"));
|
||||
ret = true;
|
||||
// After this point, only the 'last' member of the message structure is allowed to be altered if the
|
||||
// message has been signed, or signature will become invalid and the message rejected by the receiver
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Message to send could not be signed!\n"));
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// After this point, only the 'last' member of the message structure is allowed to be altered if the
|
||||
// message has been signed, or signature will become invalid and the message rejected by the receiver
|
||||
}
|
||||
} else if (getNodeId() == msg.sender) {
|
||||
mSetSigned(msg, 0); // Message is not supposed to be signed, make sure it is marked unsigned
|
||||
SIGN_DEBUG(PSTR("Will not sign message for destination %d as it does not require it\n"),
|
||||
msg.destination);
|
||||
ret = true;
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Will not sign message since it was from %d and we are %d\n"), msg.sender,
|
||||
getNodeId());
|
||||
ret = true;
|
||||
}
|
||||
#else
|
||||
(void)msg;
|
||||
ret = true;
|
||||
#endif // MY_SIGNING_FEATURE
|
||||
return true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool signerVerifyMsg(MyMessage &msg) {
|
||||
bool signerVerifyMsg(MyMessage &msg)
|
||||
{
|
||||
bool verificationResult = true;
|
||||
// Before processing message, reject unsigned messages if signing is required and check signature
|
||||
// (if it is signed and addressed to us)
|
||||
@@ -390,14 +243,9 @@ bool signerVerifyMsg(MyMessage &msg) {
|
||||
SIGN_DEBUG(PSTR("Message is not signed, but it should have been!\n"));
|
||||
verificationResult = false;
|
||||
} else {
|
||||
#if defined(MY_SIGNING_SOFT)
|
||||
verificationResult = signerAtsha204SoftVerifyMsg(msg);
|
||||
#endif
|
||||
#if defined(MY_SIGNING_ATSHA204)
|
||||
verificationResult = signerAtsha204VerifyMsg(msg);
|
||||
#endif
|
||||
if (!verificationResult) {
|
||||
if (!signerBackendVerifyMsg(msg)) {
|
||||
SIGN_DEBUG(PSTR("Signature verification failed!\n"));
|
||||
verificationResult = false;
|
||||
}
|
||||
#if defined(MY_NODE_LOCK_FEATURE)
|
||||
if (verificationResult) {
|
||||
@@ -425,23 +273,27 @@ bool signerVerifyMsg(MyMessage &msg) {
|
||||
static uint8_t sha256_hash[32];
|
||||
Sha256Class _soft_sha256;
|
||||
|
||||
void signerSha256Init(void) {
|
||||
void signerSha256Init(void)
|
||||
{
|
||||
memset(sha256_hash, 0, 32);
|
||||
_soft_sha256.init();
|
||||
}
|
||||
|
||||
void signerSha256Update(const uint8_t* data, size_t sz) {
|
||||
void signerSha256Update(const uint8_t* data, size_t sz)
|
||||
{
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
_soft_sha256.write(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* signerSha256Final(void) {
|
||||
uint8_t* signerSha256Final(void)
|
||||
{
|
||||
memcpy(sha256_hash, _soft_sha256.result(), 32);
|
||||
return sha256_hash;
|
||||
}
|
||||
|
||||
int signerMemcmp(const void* a, const void* b, size_t sz) {
|
||||
int signerMemcmp(const void* a, const void* b, size_t sz)
|
||||
{
|
||||
int retVal;
|
||||
size_t i;
|
||||
int done = 0;
|
||||
@@ -469,3 +321,190 @@ int signerMemcmp(const void* a, const void* b, size_t sz) {
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#if defined(MY_SIGNING_FEATURE)
|
||||
// Helper function to centralize signing/verification exceptions
|
||||
static bool skipSign(MyMessage &msg)
|
||||
{
|
||||
bool ret;
|
||||
if (mGetAck(msg)) {
|
||||
SIGN_DEBUG(PSTR("Skipping security for ACK on command %d type %d\n"), mGetCommand(msg), msg.type);
|
||||
ret = true;
|
||||
} else if (mGetCommand(msg) == C_INTERNAL &&
|
||||
(msg.type == I_NONCE_REQUEST || msg.type == I_NONCE_RESPONSE ||
|
||||
msg.type == I_SIGNING_PRESENTATION ||
|
||||
msg.type == I_ID_REQUEST || msg.type == I_ID_RESPONSE ||
|
||||
msg.type == I_FIND_PARENT_REQUEST || msg.type == I_FIND_PARENT_RESPONSE ||
|
||||
msg.type == I_HEARTBEAT_REQUEST || msg.type == I_HEARTBEAT_RESPONSE ||
|
||||
msg.type == I_PING || msg.type == I_PONG ||
|
||||
msg.type == I_REGISTRATION_REQUEST )) {
|
||||
SIGN_DEBUG(PSTR("Skipping security for command %d type %d\n"), mGetCommand(msg), msg.type);
|
||||
ret = true;
|
||||
} else if (mGetCommand(msg) == C_STREAM &&
|
||||
(msg.type == ST_FIRMWARE_REQUEST || msg.type == ST_FIRMWARE_RESPONSE ||
|
||||
msg.type == ST_SOUND || msg.type == ST_IMAGE)) {
|
||||
SIGN_DEBUG(PSTR("Skipping security for command %d type %d\n"), mGetCommand(msg), msg.type);
|
||||
ret = true;
|
||||
} else {
|
||||
ret = false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Helper to prepare a signing presentation message
|
||||
static void prepareSigningPresentation(MyMessage &msg, uint8_t destination)
|
||||
{
|
||||
// Only supports version 1 for now
|
||||
(void)build(msg, destination, NODE_SENSOR_ID, C_INTERNAL, I_SIGNING_PRESENTATION).set("");
|
||||
mSetLength(msg, 2);
|
||||
mSetPayloadType(msg, P_CUSTOM); // displayed as hex
|
||||
msg.data[0] = SIGNING_PRESENTATION_VERSION_1;
|
||||
msg.data[1] = 0;
|
||||
}
|
||||
|
||||
// Helper to process presentation mesages
|
||||
static bool signerInternalProcessPresentation(MyMessage &msg)
|
||||
{
|
||||
#if defined(MY_SIGNING_FEATURE)
|
||||
if (msg.data[0] != SIGNING_PRESENTATION_VERSION_1) {
|
||||
SIGN_DEBUG(PSTR("Unsupported signing presentation version (%d)!\n"), msg.data[0]);
|
||||
return true; // Just drop this presentation message
|
||||
}
|
||||
// We only handle version 1 here...
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) {
|
||||
// We received an indicator that the sender require us to sign all messages we send to it
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that require signed messages\n"), msg.sender);
|
||||
SET_SIGN(msg.sender);
|
||||
} else {
|
||||
// We received an indicator that the sender does not require us to sign all messages we send to it
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that do not require signed messages\n"), msg.sender);
|
||||
CLEAR_SIGN(msg.sender);
|
||||
}
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) {
|
||||
// We received an indicator that the sender require us to salt signatures with serial
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that require whitelisting\n"), msg.sender);
|
||||
SET_WHITELIST(msg.sender);
|
||||
} else {
|
||||
// We received an indicator that the sender does not require us to sign all messages we send to it
|
||||
SIGN_DEBUG(PSTR("Mark node %d as one that do not require whitelisting\n"), msg.sender);
|
||||
CLEAR_WHITELIST(msg.sender);
|
||||
}
|
||||
|
||||
// Save updated tables
|
||||
hwWriteConfigBlock((void*)_doSign, (void*)EEPROM_SIGNING_REQUIREMENT_TABLE_ADDRESS,
|
||||
sizeof(_doSign));
|
||||
hwWriteConfigBlock((void*)_doWhitelist, (void*)EEPROM_WHITELIST_REQUIREMENT_TABLE_ADDRESS,
|
||||
sizeof(_doWhitelist));
|
||||
|
||||
// Inform sender about our preference if we are a gateway, but only require signing if the sender
|
||||
// required signing unless we explicitly configure it to
|
||||
#if defined(MY_GATEWAY_FEATURE)
|
||||
prepareSigningPresentation(msg, msg.sender);
|
||||
#if defined(MY_SIGNING_REQUEST_SIGNATURES)
|
||||
#if defined(MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL)
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES;
|
||||
#else
|
||||
if (DO_SIGN(msg.sender)) {
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_SIGNATURES;
|
||||
}
|
||||
#endif
|
||||
#endif // MY_SIGNING_REQUEST_SIGNATURES
|
||||
#if defined(MY_SIGNING_NODE_WHITELISTING)
|
||||
#if defined(MY_SIGNING_GW_REQUEST_SIGNATURES_FROM_ALL)
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING;
|
||||
#else
|
||||
if (DO_WHITELIST(msg.sender)) {
|
||||
msg.data[1] |= SIGNING_PRESENTATION_REQUIRE_WHITELISTING;
|
||||
}
|
||||
#endif
|
||||
#endif // MY_SIGNING_NODE_WHITELISTING
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_SIGNATURES) {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we require signatures\n"), msg.sender);
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we do not require signatures\n"), msg.sender);
|
||||
}
|
||||
if (msg.data[1] & SIGNING_PRESENTATION_REQUIRE_WHITELISTING) {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we require whitelisting\n"), msg.sender);
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Informing node %d that we do not require whitelisting\n"), msg.sender);
|
||||
}
|
||||
if (!_sendRoute(msg)) {
|
||||
SIGN_DEBUG(PSTR("Failed to transmit signing presentation!\n"));
|
||||
}
|
||||
#endif // MY_GATEWAY_FEATURE
|
||||
#else // not MY_SIGNING_FEATURE
|
||||
#if defined(MY_GATEWAY_FEATURE)
|
||||
// If we act as gateway and do not have the signing feature and receive a signing request we still
|
||||
// need to do make sure the requester does not believe the gateway still require signatures
|
||||
prepareSigningPresentation(msg, msg.sender);
|
||||
SIGN_DEBUG(
|
||||
PSTR("Informing node %d that we do not require signatures because we do not support it\n"),
|
||||
msg.sender);
|
||||
if (!_sendRoute(msg)) {
|
||||
SIGN_DEBUG(PSTR("Failed to transmit signing presentation!\n"));
|
||||
}
|
||||
#else // not MY_GATEWAY_FEATURE
|
||||
// If we act as a node and do not have the signing feature then we just silently drop any signing
|
||||
// presentation messages received
|
||||
(void)msg;
|
||||
SIGN_DEBUG(PSTR("Received signing presentation, but signing is not supported (message ignored)\n"));
|
||||
#endif // not MY_GATEWAY_FEATURE
|
||||
#endif // not MY_SIGNING_FEATURE
|
||||
return true; // No need to further process I_SIGNING_PRESENTATION
|
||||
}
|
||||
|
||||
// Helper to process nonce request mesages
|
||||
static bool signerInternalProcessNonceRequest(MyMessage &msg)
|
||||
{
|
||||
#if defined(MY_SIGNING_FEATURE)
|
||||
#if defined(MY_NODE_LOCK_FEATURE)
|
||||
nof_nonce_requests++;
|
||||
SIGN_DEBUG(PSTR("Nonce requests left until lockdown: %d\n"),
|
||||
MY_NODE_LOCK_COUNTER_MAX-nof_nonce_requests);
|
||||
if (nof_nonce_requests >= MY_NODE_LOCK_COUNTER_MAX) {
|
||||
_nodeLock("TMNR"); //Too many nonces requested
|
||||
}
|
||||
#endif // MY_NODE_LOCK_FEATURE
|
||||
if (signerBackendGetNonce(msg)) {
|
||||
if (!_sendRoute(build(msg, msg.sender, NODE_SENSOR_ID, C_INTERNAL, I_NONCE_RESPONSE))) {
|
||||
SIGN_DEBUG(PSTR("Failed to transmit nonce!\n"));
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Transmitted nonce\n"));
|
||||
}
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Failed to generate nonce!\n"));
|
||||
}
|
||||
#else // not MY_SIGNING_FEATURE
|
||||
(void)msg;
|
||||
SIGN_DEBUG(PSTR("Received nonce request, but signing is not supported (message ignored)\n"));
|
||||
#endif // MY_SIGNING_FEATURE
|
||||
return true; // No need to further process I_NONCE_REQUEST
|
||||
}
|
||||
|
||||
// Helper to process nonce response mesages
|
||||
static bool signerInternalProcessNonceResponse(MyMessage &msg)
|
||||
{
|
||||
#if defined(MY_SIGNING_FEATURE)
|
||||
// Proceed with signing if nonce has been received
|
||||
SIGN_DEBUG(PSTR("Nonce received from %d.\n"), msg.sender);
|
||||
if (msg.sender != _msgSign.destination) {
|
||||
SIGN_DEBUG(PSTR("Nonce did not come from the destination (%d) of the message to be signed! "
|
||||
"It came from %d.\n"), _msgSign.destination, msg.sender);
|
||||
SIGN_DEBUG(PSTR("Silently discarding this nonce\n"));
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Proceeding with signing...\n"));
|
||||
signerBackendPutNonce(msg);
|
||||
if (!signerBackendSignMsg(_msgSign)) {
|
||||
SIGN_DEBUG(PSTR("Failed to sign message!\n"));
|
||||
} else {
|
||||
SIGN_DEBUG(PSTR("Message signed\n"));
|
||||
_signingNonceStatus = SIGN_OK; // _msgSign now contains the signed message pending transmission
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)msg;
|
||||
SIGN_DEBUG(PSTR("Received nonce response, but signing is not supported (message ignored)\n"));
|
||||
#endif
|
||||
return true; // No need to further process I_NONCE_RESPONSE
|
||||
}
|
||||
|
||||
@@ -490,14 +490,6 @@ typedef struct {
|
||||
/** @brief Helper macro to determine the number of elements in a array */
|
||||
#define NUM_OF(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
/** @brief Helper macro to determine if node require serial salted signatures */
|
||||
#define DO_WHITELIST(node) (~_doWhitelist[node>>3]&(1<<node%8))
|
||||
/** @brief Helper macro to set that node require serial salted signatures */
|
||||
#define SET_WHITELIST(node) (_doWhitelist[node>>3]&=~(1<<node%8))
|
||||
/** @brief Helper macro to set that node does not require serial salted signatures */
|
||||
#define CLEAR_WHITELIST(node) (_doWhitelist[node>>3]|=(1<<node%8))
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes signing infrastructure and associated backend.
|
||||
*
|
||||
|
||||
@@ -62,6 +62,9 @@ static char i2h(uint8_t i)
|
||||
static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, uint8_t sz)
|
||||
{
|
||||
static char printBuffer[300];
|
||||
if (NULL == buf) {
|
||||
return;
|
||||
}
|
||||
#ifdef MY_GATEWAY_FEATURE
|
||||
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
|
||||
snprintf_P(printBuffer, 299, PSTR("0;255;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE);
|
||||
|
||||
@@ -64,25 +64,17 @@ static char i2h(uint8_t i)
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
static void DEBUG_SIGNING_PRINTBUF(const char *str, uint8_t* buf, uint8_t sz)
|
||||
{
|
||||
static char printBuffer[300];
|
||||
#define __FlashStringHelper char
|
||||
#define MY_SERIALDEVICE.print debug
|
||||
#endif
|
||||
|
||||
for (int i=0; i<sz; i++) {
|
||||
printBuffer[i * 2] = i2h(buf[i] >> 4);
|
||||
printBuffer[(i * 2) + 1] = i2h(buf[i]);
|
||||
}
|
||||
printBuffer[sz * 2] = '\0';
|
||||
debug(str);
|
||||
if (sz > 0) {
|
||||
debug(printBuffer);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf, uint8_t sz)
|
||||
{
|
||||
static char printBuffer[300];
|
||||
#ifdef MY_GATEWAY_FEATURE
|
||||
if (NULL == buf) {
|
||||
return;
|
||||
}
|
||||
#if defined(MY_GATEWAY_FEATURE) && !defined(__linux__)
|
||||
// prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
|
||||
snprintf_P(printBuffer, 299, PSTR("0;255;%d;0;%d;"), C_INTERNAL, I_LOG_MESSAGE);
|
||||
MY_SERIALDEVICE.print(printBuffer);
|
||||
@@ -92,7 +84,7 @@ static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf,
|
||||
printBuffer[(i * 2) + 1] = i2h(buf[i]);
|
||||
}
|
||||
printBuffer[sz * 2] = '\0';
|
||||
#ifdef MY_GATEWAY_FEATURE
|
||||
#if defined(MY_GATEWAY_FEATURE) && !defined(__linux__)
|
||||
// Truncate message if this is gateway node
|
||||
printBuffer[MY_GATEWAY_MAX_SEND_LENGTH-1-strlen_P((const char*)str)] = '\0';
|
||||
#endif
|
||||
@@ -100,9 +92,10 @@ static void DEBUG_SIGNING_PRINTBUF(const __FlashStringHelper* str, uint8_t* buf,
|
||||
if (sz > 0) {
|
||||
MY_SERIALDEVICE.print(printBuffer);
|
||||
}
|
||||
#if !defined(__linux__)
|
||||
MY_SERIALDEVICE.println("");
|
||||
#endif
|
||||
}
|
||||
#endif /* __linux__ */
|
||||
#else
|
||||
#define DEBUG_SIGNING_PRINTBUF(str, buf, sz)
|
||||
#endif
|
||||
|
||||
+6
-1
@@ -104,7 +104,7 @@ const static byte s_inv [0x100] PROGMEM = {
|
||||
} ;
|
||||
|
||||
// times 2 in the GF(2^8)
|
||||
#define f2(x) ((x) & 0x80 ? (x << 1) ^ WPOLY : x << 1)
|
||||
#define f2(x) (((x) & 0x80) ? (x << 1) ^ WPOLY : x << 1)
|
||||
#define d2(x) (((x) >> 1) ^ ((x) & 1 ? DPOLY : 0))
|
||||
|
||||
static byte s_box (byte x)
|
||||
@@ -248,6 +248,11 @@ static void inv_mix_sub_columns (byte dt[N_BLOCK], byte st[N_BLOCK])
|
||||
AES::AES()
|
||||
{
|
||||
byte ar_iv[8] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 };
|
||||
IVC = 0x01;
|
||||
round = 0;
|
||||
pad = 0;
|
||||
size = 0;
|
||||
memset(key_sched, 0, KEY_SCHEDULE_BYTES);
|
||||
memcpy(iv,ar_iv,8);
|
||||
memcpy(iv+8,ar_iv,8);
|
||||
arr_pad[0] = 0x01;
|
||||
|
||||
@@ -312,42 +312,6 @@ private:
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @example aes.pde
|
||||
* <b>For Arduino</b><br>
|
||||
* <b>Updated: spaniakos 2015 </b><br>
|
||||
*
|
||||
* This is an example of how to use AES in CBC mode easily.
|
||||
* The text and keys can be either in HEX or String format.<br />
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example aes.cpp
|
||||
* <b>For Rasberry pi</b><br>
|
||||
* <b>Updated: spaniakos 2015 </b><br>
|
||||
*
|
||||
* This is an example of how to use AES in CBC mode easily.
|
||||
* The text and keys can be either in HEX or String format.<br />
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example test_vectors.pde
|
||||
* <b>For Arduino</b><br>
|
||||
* <b>Updated: spaniakos 2015 </b><br>
|
||||
*
|
||||
* This is an example of monte carlo test vectors, in order to justify the effectiveness of the algorithm.<br />
|
||||
* plus is a classical approach to the AES encryption library with out the easy to use add-on modifications.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @example test_vectors.cpp
|
||||
* <b>For Rasberry pi</b><br>
|
||||
* <b>Updated: spaniakos 2015 </b><br>
|
||||
*
|
||||
* This is an example of monte carlo test vectors, in order to justify the effectiveness of the algorithm.<br />
|
||||
* plus is a classical approach to the AES encryption library with out the easy to use add-on modifications.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup aeslib AES library for Arduino and Raspberry pi
|
||||
* @ingroup internals
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
||||
#############################################################################
|
||||
#
|
||||
# Makefile for AES on Raspberry Pi
|
||||
#
|
||||
# License: GPL (General Public License)
|
||||
# Author: Georgios Spanos (spaniakos) <spaniakos@gmail.com>
|
||||
# Date: 02/12/2014
|
||||
#
|
||||
# Description:
|
||||
# ------------
|
||||
# use make all and mak install to install the library
|
||||
# You can change the install directory by editing the LIBDIR line
|
||||
#
|
||||
PREFIX=/usr/local
|
||||
|
||||
# Library parameters
|
||||
# where to put the lib
|
||||
LIBDIR=$(PREFIX)/lib
|
||||
# lib name
|
||||
LIB=libAES
|
||||
# shared library name
|
||||
LIBNAME=$(LIB).so.1.0
|
||||
|
||||
# Where to put the header files
|
||||
HEADER_DIR=${PREFIX}/include/AES
|
||||
|
||||
# The recommended compiler flags for the Raspberry Pi
|
||||
CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
|
||||
|
||||
# make all
|
||||
# reinstall the library after each recompilation
|
||||
all: libAES
|
||||
|
||||
# Make the library
|
||||
libAES: AES.o
|
||||
g++ -shared -Wl,-soname,$@.so.1 ${CCFLAGS} -o ${LIBNAME} $^
|
||||
|
||||
# Library parts
|
||||
AES.o: AES.cpp
|
||||
g++ -Wall -fPIC ${CCFLAGS} -c $^
|
||||
|
||||
# clear build files
|
||||
clean:
|
||||
rm -rf *.o ${LIB}.*
|
||||
rm -rf ${LIBDIR}/${LIB}.*
|
||||
rm -rf ${HEADER_DIR}
|
||||
|
||||
install: all install-libs install-headers
|
||||
|
||||
# Install the library to LIBPATH
|
||||
install-libs:
|
||||
@echo "[Installing Libs]"
|
||||
@if ( test ! -d $(PREFIX)/lib ) ; then mkdir -p $(PREFIX)/lib ; fi
|
||||
@install -m 0755 ${LIBNAME} ${LIBDIR}
|
||||
@ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so.1
|
||||
@ln -sf ${LIBDIR}/${LIBNAME} ${LIBDIR}/${LIB}.so
|
||||
@ldconfig
|
||||
|
||||
install-headers:
|
||||
@echo "[Installing Headers]"
|
||||
@if ( test ! -d ${HEADER_DIR} ) ; then mkdir -p ${HEADER_DIR} ; fi
|
||||
@install -m 0644 *.h ${HEADER_DIR}
|
||||
@@ -1,63 +0,0 @@
|
||||
#include <AES.h>
|
||||
#include "./printf.h"
|
||||
|
||||
AES aes ;
|
||||
|
||||
byte *key = (unsigned char*)"0123456789010123";
|
||||
|
||||
byte plain[] = "Add NodeAdd NodeAdd NodeAdd NodeAdd Node";
|
||||
|
||||
//real iv = iv x2 ex: 01234567 = 0123456701234567
|
||||
unsigned long long int my_iv = 36753562;
|
||||
|
||||
void setup ()
|
||||
{
|
||||
Serial.begin (57600) ;
|
||||
printf_begin();
|
||||
delay(500);
|
||||
printf("\n===testng mode\n") ;
|
||||
|
||||
// otfly_test () ;
|
||||
// otfly_test256 () ;
|
||||
}
|
||||
|
||||
void loop ()
|
||||
{
|
||||
prekey_test () ;
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
void prekey (int bits)
|
||||
{
|
||||
aes.iv_inc();
|
||||
byte iv [N_BLOCK] ;
|
||||
byte plain_p[48];
|
||||
byte cipher [48] ;
|
||||
byte check [48] ;
|
||||
unsigned long ms = micros ();
|
||||
aes.set_IV(my_iv);
|
||||
aes.get_IV(iv);
|
||||
aes.do_aes_encrypt(plain,41,cipher,key,bits,iv);
|
||||
Serial.print("Encryption took: ");
|
||||
Serial.println(micros() - ms);
|
||||
ms = micros ();
|
||||
aes.set_IV(my_iv);
|
||||
aes.get_IV(iv);
|
||||
aes.do_aes_decrypt(cipher,48,check,key,bits,iv);
|
||||
Serial.print("Decryption took: ");
|
||||
Serial.println(micros() - ms);
|
||||
printf("\n\nPLAIN :");
|
||||
aes.printArray(plain,(bool)true);
|
||||
printf("\nCIPHER:");
|
||||
aes.printArray(cipher,(bool)false);
|
||||
printf("\nCHECK :");
|
||||
aes.printArray(check,(bool)true);
|
||||
printf("\nIV :");
|
||||
aes.printArray(iv,16);
|
||||
printf("\n============================================================\n");
|
||||
}
|
||||
|
||||
void prekey_test ()
|
||||
{
|
||||
prekey (128) ;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
Monte Carlo test vectors:
|
||||
http://csrc.nist.gov/groups/STM/cavp/documents/aes/aesmct.zip
|
||||
|
||||
(Compare the Monte Carlo output to the ECBMCT128.rsp file)
|
||||
|
||||
Known Answer Tests:
|
||||
http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
|
||||
|
||||
- Compare the other test outputs to
|
||||
ECBVarTxt128.rsp
|
||||
ECBVarKey128.rsp
|
||||
ECBVarTxt192.rsp
|
||||
ECBVarKey192.rsp
|
||||
ECBVarTxt256.rsp
|
||||
ECBVarKey256.rsp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,191 +0,0 @@
|
||||
#include <AES.h>
|
||||
|
||||
AES aes ;
|
||||
|
||||
byte key [2*N_BLOCK] ;
|
||||
byte plain [N_BLOCK] ;
|
||||
byte iv [N_BLOCK] ;
|
||||
byte cipher [N_BLOCK] ;
|
||||
byte check [N_BLOCK] ;
|
||||
|
||||
void loop ()
|
||||
{}
|
||||
|
||||
|
||||
void setup ()
|
||||
{
|
||||
Serial.begin (57600) ;
|
||||
Serial.print ("AES library test vectors") ;
|
||||
|
||||
monte_carlo (128) ;
|
||||
|
||||
for (int keysize = 128 ; keysize <= 256 ; keysize += 64)
|
||||
{
|
||||
prekey_test_var_plaintext (keysize) ;
|
||||
prekey_test_var_key (keysize) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void prekey_test_var_plaintext (int bits)
|
||||
{
|
||||
Serial.println () ;
|
||||
Serial.print ("ECB Varying Plaintext ") ;
|
||||
Serial.print (bits) ;
|
||||
Serial.println (" bits") ;
|
||||
Serial.println () ;
|
||||
|
||||
byte succ ;
|
||||
set_bits (bits, key, 0) ; // all zero key
|
||||
succ = aes.set_key (key, bits) ;
|
||||
if (succ != SUCCESS)
|
||||
Serial.println ("Failure set_key") ;
|
||||
|
||||
|
||||
for (int bitcount = 1 ; bitcount <= 128 ; bitcount++)
|
||||
{
|
||||
Serial.print ("COUNT = ") ; Serial.println (bitcount-1) ;
|
||||
print_value ("KEY = ", key, bits) ;
|
||||
set_bits (128, plain, bitcount) ;
|
||||
|
||||
print_value ("PLAINTEXT = ", plain, 128) ;
|
||||
|
||||
succ = aes.encrypt (plain, cipher) ;
|
||||
if (succ != SUCCESS)
|
||||
Serial.println ("Failure encrypt") ;
|
||||
|
||||
print_value ("CIPHERTEXT = ", cipher, 128) ;
|
||||
|
||||
succ = aes.decrypt (cipher, check) ;
|
||||
if (succ != SUCCESS)
|
||||
Serial.println ("Failure decrypt") ;
|
||||
|
||||
//print_value ("CHECK = ", check, 128) ;
|
||||
check_same (plain, check, 128) ;
|
||||
Serial.println () ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void prekey_test_var_key (int bits)
|
||||
{
|
||||
Serial.println () ;
|
||||
Serial.print ("ECB Varying Key ") ;
|
||||
Serial.print (bits) ;
|
||||
Serial.println (" bits") ;
|
||||
Serial.println () ;
|
||||
|
||||
byte succ ;
|
||||
set_bits (128, plain, 0) ;
|
||||
|
||||
for (int bitcount = 1 ; bitcount <= bits ; bitcount++)
|
||||
{
|
||||
set_bits (bits, key, bitcount) ; // all zero key
|
||||
succ = aes.set_key (key, bits) ;
|
||||
if (succ != SUCCESS)
|
||||
Serial.println ("Failure set_key") ;
|
||||
Serial.print ("COUNT = ") ; Serial.println (bitcount-1) ;
|
||||
print_value ("KEY = ", key, bits) ;
|
||||
|
||||
print_value ("PLAINTEXT = ", plain, 128) ;
|
||||
|
||||
succ = aes.encrypt (plain, cipher) ;
|
||||
if (succ != SUCCESS)
|
||||
Serial.println ("Failure encrypt") ;
|
||||
|
||||
print_value ("CIPHERTEXT = ", cipher, 128) ;
|
||||
|
||||
succ = aes.decrypt (cipher, check) ;
|
||||
if (succ != SUCCESS)
|
||||
Serial.println ("Failure decrypt") ;
|
||||
|
||||
check_same (plain, check, 128) ;
|
||||
Serial.println () ;
|
||||
}
|
||||
}
|
||||
|
||||
void set_bits (int bits, byte * a, int count)
|
||||
{
|
||||
bits >>= 3 ;
|
||||
byte bcount = count >> 3 ;
|
||||
for (byte i = 0 ; i < bcount ; i++)
|
||||
a [i] = 0xFF ;
|
||||
if ((count & 7) != 0)
|
||||
a [bcount++] = 0xFF & (0xFF00 >> (count & 7)) ;
|
||||
for (byte i = bcount ; i < bits ; i++)
|
||||
a [i] = 0x00 ;
|
||||
}
|
||||
|
||||
void check_same (byte * a, byte * b, int bits)
|
||||
{
|
||||
bits >>= 3 ;
|
||||
for (byte i = 0 ; i < bits ; i++)
|
||||
if (a[i] != b[i])
|
||||
{
|
||||
Serial.println ("Failure plain != check") ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
char hex[] = "0123456789abcdef" ;
|
||||
|
||||
|
||||
void print_value (const char * str, byte * a, int bits)
|
||||
{
|
||||
Serial.print (str) ;
|
||||
bits >>= 3 ;
|
||||
for (int i = 0 ; i < bits ; i++)
|
||||
{
|
||||
byte b = a[i] ;
|
||||
Serial.print (hex [b >> 4]) ;
|
||||
Serial.print (hex [b & 15]) ;
|
||||
}
|
||||
Serial.println () ;
|
||||
}
|
||||
|
||||
byte monteplain [] =
|
||||
{ 0xb9, 0x14, 0x5a, 0x76, 0x8b, 0x7d, 0xc4, 0x89,
|
||||
0xa0, 0x96, 0xb5, 0x46, 0xf4, 0x3b, 0x23, 0x1f } ;
|
||||
byte montekey [] =
|
||||
{ 0x13, 0x9a, 0x35, 0x42, 0x2f, 0x1d, 0x61, 0xde,
|
||||
0x3c, 0x91, 0x78, 0x7f, 0xe0, 0x50, 0x7a, 0xfd } ;
|
||||
|
||||
void monte_carlo (int bits)
|
||||
{
|
||||
Serial.println () ;
|
||||
Serial.print ("Monte Carlo ") ;
|
||||
Serial.print (bits) ;
|
||||
Serial.println (" bits") ;
|
||||
Serial.println () ;
|
||||
byte succ ;
|
||||
for (int i = 0 ; i < 16 ; i++)
|
||||
{
|
||||
plain [i] = monteplain [i] ;
|
||||
key [i] = montekey [i] ;
|
||||
}
|
||||
for (int i = 0 ; i < 100 ; i++)
|
||||
{
|
||||
Serial.print ("COUNT = ") ; Serial.println (i) ;
|
||||
print_value ("KEY = ", key, bits) ;
|
||||
print_value ("PLAINTEXT = ", plain, 128) ;
|
||||
succ = aes.set_key (key, bits) ;
|
||||
for (int j = 0 ; j < 1000 ; j++)
|
||||
{
|
||||
succ = aes.encrypt (plain, cipher) ;
|
||||
aes.copy_n_bytes (plain, cipher, 16) ;
|
||||
}
|
||||
print_value ("CIPHERTEXT = ", cipher, 128) ;
|
||||
Serial.println () ;
|
||||
if (bits == 128)
|
||||
{
|
||||
for (byte k = 0 ; k < 16 ; k++)
|
||||
key [k] ^= cipher [k] ;
|
||||
}
|
||||
else if (bits == 192)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
#############################################################################
|
||||
#
|
||||
# Makefile for AES examples on Raspberry Pi
|
||||
#
|
||||
# License: GPL (General Public License)
|
||||
# Author: gnulnulf <arco@appeltaart.mine.nu>
|
||||
# Date: 2013/02/07 (version 1.0)
|
||||
#
|
||||
# Description:
|
||||
# ------------
|
||||
# use make all and make install to install the examples
|
||||
# You can change the install directory by editing the prefix line
|
||||
#
|
||||
prefix := /usr/local
|
||||
|
||||
# The recommended compiler flags for the Raspberry Pi
|
||||
CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=armv6zk -mtune=arm1176jzf-s
|
||||
#CCFLAGS=
|
||||
|
||||
# define all programs
|
||||
PROGRAMS = aes test_vectors
|
||||
SOURCES = ${PROGRAMS:=.cpp}
|
||||
|
||||
all: ${PROGRAMS}
|
||||
|
||||
${PROGRAMS}: ${SOURCES}
|
||||
g++ ${CCFLAGS} -Wall -I../ -lAES $@.cpp -o $@
|
||||
|
||||
clean:
|
||||
rm -rf $(PROGRAMS)
|
||||
|
||||
install: all
|
||||
test -d $(prefix) || mkdir $(prefix)
|
||||
test -d $(prefix)/bin || mkdir $(prefix)/bin
|
||||
for prog in $(PROGRAMS); do \
|
||||
install -m 0755 $$prog $(prefix)/bin; \
|
||||
done
|
||||
|
||||
.PHONY: install
|
||||
@@ -1,16 +0,0 @@
|
||||
Monte Carlo test vectors:
|
||||
http://csrc.nist.gov/groups/STM/cavp/documents/aes/aesmct.zip
|
||||
|
||||
(Compare the Monte Carlo output to the ECBMCT128.rsp file)
|
||||
|
||||
Known Answer Tests:
|
||||
http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
|
||||
|
||||
- Compare the other test outputs to
|
||||
ECBVarTxt128.rsp
|
||||
ECBVarKey128.rsp
|
||||
ECBVarTxt192.rsp
|
||||
ECBVarKey192.rsp
|
||||
ECBVarTxt256.rsp
|
||||
ECBVarKey256.rsp
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
#include <AES.h>
|
||||
#include "printf.h"
|
||||
|
||||
AES aes;
|
||||
|
||||
void prekey_test ();
|
||||
void prekey (int bits, int blocks);
|
||||
|
||||
byte key[] = "01234567899876543210012345678998";
|
||||
|
||||
byte plain[] = "TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTEST";
|
||||
|
||||
//real iv = iv x2 ex: 01234567 = 0123456701234567
|
||||
unsigned long long int my_iv = 01234567;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("\n===testng mode\n") ;
|
||||
|
||||
for (int i=0; i<1; i++) {
|
||||
prekey_test () ;
|
||||
}
|
||||
}
|
||||
|
||||
void prekey (int bits)
|
||||
{
|
||||
byte iv [N_BLOCK] ;
|
||||
byte plain_p[sizeof(plain) + (N_BLOCK - (sizeof(plain) % 16)) - 1];
|
||||
byte cipher[sizeof(plain_p)];
|
||||
aes.do_aes_encrypt(plain,sizeof(plain),cipher,key,bits);
|
||||
aes.get_IV(iv);
|
||||
aes.do_aes_dencrypt(cipher,aes.get_size(),plain_p,key,bits,iv);
|
||||
//normally u have sizeof(cipher) but if its in the same sketch you cannot determin it dynamically
|
||||
|
||||
printf("\n\nPLAIN :");
|
||||
aes.printArray(plain);
|
||||
printf("\nCIPHER:");
|
||||
aes.printArray(cipher);
|
||||
printf("\nPlain2:");
|
||||
aes.printArray(plain_p);
|
||||
printf("\n============================================================\n");
|
||||
}
|
||||
|
||||
void prekey_test ()
|
||||
{
|
||||
prekey (128) ;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,182 +0,0 @@
|
||||
#include <AES.h>
|
||||
#include "printf.h"
|
||||
|
||||
AES aes ;
|
||||
|
||||
byte key [2*N_BLOCK] ;
|
||||
byte plain [N_BLOCK] ;
|
||||
byte iv [N_BLOCK] ;
|
||||
byte cipher [N_BLOCK] ;
|
||||
byte check [N_BLOCK] ;
|
||||
|
||||
void print_value (const char * str, byte * a, int bits);
|
||||
void prekey_test_var_plaintext (int bits);
|
||||
void prekey_test_var_key (int bits);
|
||||
void set_bits (int bits, byte * a, int count);
|
||||
void check_same (byte * a, byte * b, int bits);
|
||||
void monte_carlo (int bits);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf ("AES library test vectors") ;
|
||||
|
||||
monte_carlo (128) ;
|
||||
|
||||
for (int keysize = 128 ; keysize <= 256 ; keysize += 64) {
|
||||
prekey_test_var_plaintext (keysize) ;
|
||||
prekey_test_var_key (keysize) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void prekey_test_var_plaintext (int bits)
|
||||
{
|
||||
printf ("\nECB Varying Plaintext %i bits\n",bits) ;
|
||||
|
||||
byte succ ;
|
||||
set_bits (bits, key, 0) ; // all zero key
|
||||
succ = aes.set_key (key, bits) ;
|
||||
if (succ != SUCCESS) {
|
||||
printf("Failure set_key\n") ;
|
||||
}
|
||||
|
||||
|
||||
for (int bitcount = 1 ; bitcount <= 128 ; bitcount++) {
|
||||
printf ("COUNT = %i \n",bitcount-1);
|
||||
print_value ("KEY = ", key, bits) ;
|
||||
set_bits (128, plain, bitcount) ;
|
||||
|
||||
print_value ("PLAINTEXT = ", plain, 128) ;
|
||||
|
||||
succ = aes.encrypt (plain, cipher) ;
|
||||
if (succ != SUCCESS) {
|
||||
printf ("Failure encrypt\n") ;
|
||||
}
|
||||
|
||||
print_value ("CIPHERTEXT = ", cipher, 128) ;
|
||||
|
||||
succ = aes.decrypt (cipher, check) ;
|
||||
if (succ != SUCCESS) {
|
||||
printf ("Failure decrypt\n") ;
|
||||
}
|
||||
|
||||
//print_value ("CHECK = ", check, 128) ;
|
||||
check_same (plain, check, 128) ;
|
||||
printf ("\n") ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void prekey_test_var_key (int bits)
|
||||
{
|
||||
printf ("\nECB Varying key %i bits\n",bits);
|
||||
|
||||
byte succ ;
|
||||
set_bits (128, plain, 0) ;
|
||||
|
||||
for (int bitcount = 1 ; bitcount <= bits ; bitcount++) {
|
||||
set_bits (bits, key, bitcount) ; // all zero key
|
||||
succ = aes.set_key (key, bits) ;
|
||||
if (succ != SUCCESS) {
|
||||
printf ("Failure set_key\n") ;
|
||||
}
|
||||
printf ("COUNT = %i\n",bitcount-1);
|
||||
print_value ("KEY = ", key, bits) ;
|
||||
|
||||
print_value ("PLAINTEXT = ", plain, 128) ;
|
||||
|
||||
succ = aes.encrypt (plain, cipher) ;
|
||||
if (succ != SUCCESS) {
|
||||
printf ("Failure encrypt\n") ;
|
||||
}
|
||||
|
||||
print_value ("CIPHERTEXT = ", cipher, 128) ;
|
||||
|
||||
succ = aes.decrypt (cipher, check) ;
|
||||
if (succ != SUCCESS) {
|
||||
printf ("Failure decrypt\n") ;
|
||||
}
|
||||
|
||||
check_same (plain, check, 128) ;
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void set_bits (int bits, byte * a, int count)
|
||||
{
|
||||
bits >>= 3 ;
|
||||
byte bcount = count >> 3 ;
|
||||
for (byte i = 0 ; i < bcount ; i++) {
|
||||
a [i] = 0xFF ;
|
||||
}
|
||||
if ((count & 7) != 0) {
|
||||
a [bcount++] = 0xFF & (0xFF00 >> (count & 7)) ;
|
||||
}
|
||||
for (byte i = bcount ; i < bits ; i++) {
|
||||
a [i] = 0x00 ;
|
||||
}
|
||||
}
|
||||
|
||||
void check_same (byte * a, byte * b, int bits)
|
||||
{
|
||||
bits >>= 3 ;
|
||||
for (byte i = 0 ; i < bits ; i++)
|
||||
if (a[i] != b[i]) {
|
||||
printf ("Failure plain != check\n") ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
char hex[] = "0123456789abcdef" ;
|
||||
|
||||
|
||||
void print_value (const char * str, byte * a, int bits)
|
||||
{
|
||||
printf ("%s",str) ;
|
||||
bits >>= 3 ;
|
||||
for (int i = 0 ; i < bits ; i++) {
|
||||
byte b = a[i] ;
|
||||
printf("%c%c",hex[b >> 4],hex [b & 15]);
|
||||
//Serial.print (hex [b >> 4]) ;
|
||||
//Serial.print (hex [b & 15]) ;
|
||||
}
|
||||
printf("\n") ;
|
||||
}
|
||||
|
||||
byte monteplain [] = {
|
||||
0xb9, 0x14, 0x5a, 0x76, 0x8b, 0x7d, 0xc4, 0x89,
|
||||
0xa0, 0x96, 0xb5, 0x46, 0xf4, 0x3b, 0x23, 0x1f
|
||||
} ;
|
||||
byte montekey [] = {
|
||||
0x13, 0x9a, 0x35, 0x42, 0x2f, 0x1d, 0x61, 0xde,
|
||||
0x3c, 0x91, 0x78, 0x7f, 0xe0, 0x50, 0x7a, 0xfd
|
||||
} ;
|
||||
|
||||
void monte_carlo (int bits)
|
||||
{
|
||||
printf ("\nMonte Carlo %i bits\n",bits);
|
||||
byte succ;
|
||||
for (int i = 0 ; i < 16 ; i++) {
|
||||
plain [i] = monteplain [i] ;
|
||||
key [i] = montekey [i] ;
|
||||
}
|
||||
for (int i = 0 ; i < 100 ; i++) {
|
||||
printf ("COUNT = %i\n",i);
|
||||
print_value ("KEY = ", key, bits) ;
|
||||
print_value ("PLAINTEXT = ", plain, 128) ;
|
||||
succ = aes.set_key (key, bits) ;
|
||||
for (int j = 0 ; j < 1000 ; j++) {
|
||||
succ = aes.encrypt (plain, cipher) ;
|
||||
aes.copy_n_bytes (plain, cipher, 16) ;
|
||||
}
|
||||
print_value ("CIPHERTEXT = ", cipher, 128) ;
|
||||
printf("\n");
|
||||
if (bits == 128) {
|
||||
for (byte k = 0 ; k < 16 ; k++) {
|
||||
key [k] ^= cipher [k] ;
|
||||
}
|
||||
} else if (bits == 192) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
*/
|
||||
/* Galileo support from spaniakos <spaniakos@gmail.com> */
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#if defined (ARDUINO) && !defined (__arm__) && !defined(__ARDUINO_X86__)
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#elif defined (__arm__)
|
||||
|
||||
void printf_begin(void) {}
|
||||
|
||||
#elif defined(__ARDUINO_X86__)
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
//JESUS - For reddirect stdout to /dev/ttyGS0 (Serial Monitor port)
|
||||
stdout = freopen("/dev/ttyGS0","w",stdout);
|
||||
delay(500);
|
||||
printf("redirecting to Serial...");
|
||||
|
||||
//JESUS -----------------------------------------------------------
|
||||
}
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -177,7 +177,6 @@ static uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer)
|
||||
|
||||
static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
|
||||
{
|
||||
uint8_t count_byte;
|
||||
uint8_t i;
|
||||
uint8_t ret_code;
|
||||
|
||||
@@ -189,6 +188,7 @@ static uint8_t sha204p_receive_response(uint8_t size, uint8_t *response)
|
||||
|
||||
ret_code = swi_receive_bytes(size, response);
|
||||
if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL) {
|
||||
uint8_t count_byte;
|
||||
count_byte = response[SHA204_BUFFER_POS_COUNT];
|
||||
if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) {
|
||||
return SHA204_INVALID_SIZE;
|
||||
|
||||
@@ -32,6 +32,16 @@ const uint8_t sha256InitState[] PROGMEM = {
|
||||
0x19,0xcd,0xe0,0x5b // H7
|
||||
};
|
||||
|
||||
Sha256Class::Sha256Class()
|
||||
{
|
||||
memset(keyBuffer, 0, BLOCK_LENGTH);
|
||||
memset(innerHash, 0, HASH_LENGTH);
|
||||
memset(buffer.b, 0, BLOCK_LENGTH);
|
||||
memset(state.b, 0, BLOCK_LENGTH);
|
||||
bufferOffset = 0;
|
||||
byteCount = 0;
|
||||
}
|
||||
|
||||
void Sha256Class::init(void)
|
||||
{
|
||||
memcpy_P(state.b,sha256InitState,32);
|
||||
|
||||
@@ -19,6 +19,7 @@ union _state {
|
||||
class Sha256Class
|
||||
{
|
||||
public:
|
||||
Sha256Class(); // Constructor
|
||||
void init(void);
|
||||
void initHmac(const uint8_t* secret, int secretLength);
|
||||
uint8_t* result(void);
|
||||
|
||||
@@ -121,4 +121,4 @@ void receive(const MyMessage &message)
|
||||
Serial.println(message.getBool());
|
||||
}
|
||||
}
|
||||
/** @}*/
|
||||
/** @}*/
|
||||
|
||||
@@ -261,7 +261,6 @@ uint8_t atsha204Class::sha204p_resync(uint8_t size, uint8_t *response)
|
||||
|
||||
uint8_t atsha204Class::sha204p_receive_response(uint8_t size, uint8_t *response)
|
||||
{
|
||||
uint8_t count_byte;
|
||||
uint8_t i;
|
||||
uint8_t ret_code;
|
||||
|
||||
@@ -273,6 +272,7 @@ uint8_t atsha204Class::sha204p_receive_response(uint8_t size, uint8_t *response)
|
||||
|
||||
ret_code = swi_receive_bytes(size, response);
|
||||
if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL) {
|
||||
uint8_t count_byte;
|
||||
count_byte = response[SHA204_BUFFER_POS_COUNT];
|
||||
if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) {
|
||||
return SHA204_INVALID_SIZE;
|
||||
|
||||
@@ -326,7 +326,7 @@ public:
|
||||
*
|
||||
* @param[in] pin The pin to use for communication
|
||||
*/
|
||||
atsha204Class(uint8_t pin);
|
||||
explicit atsha204Class(uint8_t pin);
|
||||
|
||||
/**
|
||||
* @brief Wake up device
|
||||
|
||||
@@ -32,12 +32,12 @@
|
||||
"autoformat_on_save": true,
|
||||
"options_c":
|
||||
{
|
||||
"additional_options_file": "$project_path/../../.tools/astyle/config/style.cfg",
|
||||
"additional_options_file": "$project_path/../../.mystools/astyle/config/style.cfg",
|
||||
"use_only_additional_options": true
|
||||
},
|
||||
"options_c++":
|
||||
{
|
||||
"additional_options_file": "$project_path/../../.astylerc",
|
||||
"additional_options_file": "$project_path/../../.mystools/astyle/config/style.cfg",
|
||||
"use_only_additional_options": true
|
||||
},
|
||||
},
|
||||
@@ -65,6 +65,8 @@
|
||||
// The project defines build targets for all Arduino based boards supported by MySensors.
|
||||
// The plugin needed to do the build (which require the Arduino IDE to be installed) is
|
||||
// available here: https://github.com/jacobrosenthal/arduino-cli
|
||||
// You also need to make sure you set up sketch book paths properly and that you can
|
||||
// build sketches and examples for the MySensors library in the IDE.
|
||||
"build_systems":
|
||||
[
|
||||
{
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2016 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <pins_arduino.h>
|
||||
#define MY_DEBUG
|
||||
#define MY_GATEWAY_SERIAL
|
||||
#define MY_DEBUG_VERBOSE_SIGNING
|
||||
//#define MY_SIGNING_SOFT
|
||||
#define MY_SIGNING_ATSHA204
|
||||
#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
|
||||
#define MY_SIGNING_REQUEST_SIGNATURES
|
||||
#ifndef MY_SIGNING_SOFT_RANDOMSEED_PIN
|
||||
#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
|
||||
#endif
|
||||
#ifndef MY_SIGNING_ATSHA204_PIN
|
||||
#define MY_SIGNING_ATSHA204_PIN 17
|
||||
#endif
|
||||
|
||||
#include <MySensors.h>
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* The MySensors Arduino library handles the wireless radio link and protocol
|
||||
* between your home built sensors/actuators and HA controller of choice.
|
||||
* The sensors forms a self healing radio network with optional repeaters. Each
|
||||
* repeater and gateway builds a routing tables in EEPROM which keeps track of the
|
||||
* network topology allowing messages to be routed to nodes.
|
||||
*
|
||||
* Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
|
||||
* Copyright (C) 2013-2016 Sensnology AB
|
||||
* Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
|
||||
*
|
||||
* Documentation: http://www.mysensors.org
|
||||
* Support Forum: http://forum.mysensors.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*******************************
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <pins_arduino.h>
|
||||
#define MY_DEBUG
|
||||
#define MY_GATEWAY_SERIAL
|
||||
#define MY_DEBUG_VERBOSE_SIGNING
|
||||
#define MY_SIGNING_SOFT
|
||||
//#define MY_SIGNING_ATSHA204
|
||||
#define MY_SIGNING_NODE_WHITELISTING {{.nodeId = GATEWAY_ADDRESS,.serial = {0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01}}}
|
||||
#define MY_SIGNING_REQUEST_SIGNATURES
|
||||
#ifndef MY_SIGNING_SOFT_RANDOMSEED_PIN
|
||||
#define MY_SIGNING_SOFT_RANDOMSEED_PIN 7
|
||||
#endif
|
||||
#ifndef MY_SIGNING_ATSHA204_PIN
|
||||
#define MY_SIGNING_ATSHA204_PIN 17
|
||||
#endif
|
||||
|
||||
#include <MySensors.h>
|
||||
Reference in New Issue
Block a user