Refactor signing backend (#690)

Cleaned up the AES driver and removed some cppcheck isues
in the process.
This commit is contained in:
Patrick Fallberg
2016-12-25 16:12:40 +01:00
committed by Henrik Ekblad
parent 61e6cecb3f
commit 1040fbebc5
27 changed files with 398 additions and 14004 deletions
+286 -247
View File
@@ -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
}
-8
View File
@@ -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.
*
+3
View File
@@ -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);
+10 -17
View File
@@ -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
View File
@@ -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;
-36
View File
@@ -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
-2372
View File
File diff suppressed because it is too large Load Diff
-62
View File
@@ -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}
-63
View File
@@ -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
{
}
}
}
-39
View File
@@ -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
-16
View File
@@ -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
-47
View File
@@ -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
-182
View File
@@ -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 {
}
}
}
-59
View File
@@ -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__
+1 -1
View File
@@ -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;
+10
View File
@@ -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);
+1
View File
@@ -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);
+1 -1
View File
@@ -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":
[
{
@@ -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>
@@ -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>