diff --git a/crypto.ino b/crypto.ino index 0e0965c..3a5926d 100644 --- a/crypto.ino +++ b/crypto.ino @@ -1,64 +1,31 @@ #include "tweetnacl.h" +#include "state_idle.h" + #define BUFF_SIZE 256+crypto_box_ZEROBYTES #define STATUS_LED 13 -uint8_t testKey[crypto_box_SECRETKEYBYTES]; -uint8_t nonce[crypto_box_NONCEBYTES]; -uint8_t serial_in_buff[BUFF_SIZE]; +crypto_state_t state_machine; -// Subtract one so that we store delimiting first -// char in padding space to be erased. -uint8_t char_insert_i = crypto_box_ZEROBYTES - 1; -uint8_t crypto_out_buff[BUFF_SIZE]; void setup() { // put your setup code here, to run once: Serial.begin(115200); pinMode(STATUS_LED, OUTPUT); - memset(serial_in_buff, 0, sizeof(serial_in_buff)); - memset(crypto_out_buff, 0, sizeof(crypto_out_buff)); + + transition_to_idle(&state_machine); } + void loop() { if(Serial.available()) { - serial_in_buff[char_insert_i++] = Serial.read(); - - if(serial_in_buff[char_insert_i-1] == '\n' || - char_insert_i >= BUFF_SIZE) { - char enc_or_dec = serial_in_buff[crypto_box_ZEROBYTES - 1]; - serial_in_buff[crypto_box_ZEROBYTES - 1] = 0; - - switch(enc_or_dec) { - case 'E': - { - crypto_secretbox(crypto_out_buff, serial_in_buff, char_insert_i - 1, nonce, testKey); - int crypto_len = char_insert_i - 1 - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; - Serial.write(&crypto_out_buff[crypto_box_BOXZEROBYTES], crypto_len); - } - break; - case 'D': - { - uint8_t * encrypted_start = serial_in_buff + (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES); - uint8_t encrypted_len = char_insert_i - 1 - crypto_box_ZEROBYTES + crypto_box_BOXZEROBYTES; - int success = crypto_secretbox_open(crypto_out_buff, encrypted_start, encrypted_len, nonce, testKey); - if(success == -1) { - digitalWrite(STATUS_LED, HIGH); - } else { - digitalWrite(STATUS_LED, LOW); - } - int crypto_len = encrypted_len - crypto_box_ZEROBYTES; - Serial.write(&crypto_out_buff[crypto_box_ZEROBYTES], crypto_len); - } - break; - } - - // Cleanup - memset(serial_in_buff, 0, sizeof(serial_in_buff)); - memset(crypto_out_buff, 0, sizeof(crypto_out_buff)); - char_insert_i = crypto_box_ZEROBYTES - 1; - } + state_machine.recv_char(&state_machine, Serial.read()); } + state_machine.fsm_step(&state_machine); } + +void print(const char * buf, uint16_t len) { + Serial.write(buf, len); +} \ No newline at end of file diff --git a/secrets.cpp b/secrets.cpp new file mode 100644 index 0000000..f2ad6a2 --- /dev/null +++ b/secrets.cpp @@ -0,0 +1,27 @@ + +#include "secrets.h" + +#include +#include "tweetnacl.h" + +static const uint8_t secretkey[crypto_secretbox_KEYBYTES] = { + 0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9, + 0,1 +}; + +static const uint8_t nonce[crypto_secretbox_NONCEBYTES] = { + 0,1,2,3,4,5,6,7,8,9, + 0,1,2,3,4,5,6,7,8,9, + 0,1,2,3 +}; + +const uint8_t * get_secret_key(void) { + return secretkey; +} + +const uint8_t * get_nonce(void) { + return nonce; +} + diff --git a/secrets.h b/secrets.h new file mode 100644 index 0000000..79f6c96 --- /dev/null +++ b/secrets.h @@ -0,0 +1,12 @@ + + +#ifndef SECRETS_H +#define SECRETS_H + +#include + +const uint8_t * get_secret_key(void); +const uint8_t * get_nonce(void); + +#endif // SECRETS_H + diff --git a/state.cpp b/state.cpp new file mode 100644 index 0000000..6df3eff --- /dev/null +++ b/state.cpp @@ -0,0 +1,19 @@ + + +#include "state.h" + +static void default_event_recv_char(crypto_state_t * state, char c) { + // Spin in same state + return; +} + +static void default_event_fsm_step(crypto_state_t * state) { + // Spin in same state + return; +} + +void state_init_default(crypto_state_t * state) { + state->recv_char = default_event_recv_char; + state->fsm_step = default_event_fsm_step; +} + diff --git a/state.h b/state.h index a126a6e..90c0410 100644 --- a/state.h +++ b/state.h @@ -1,23 +1,18 @@ -/** - * @file - * @author Riley Wood (riley@clearmotion.com) - * @copyright 2017 ClearMotion Inc., All Rights Reserved. * - * @defgroup state GROUP TITLE - * @addtogroup state - * @{ - * - * @brief DESCRIPTION HERE - * - */ - #ifndef STATE_H #define STATE_H +typedef struct crypto_state_struct crypto_state_t; -#endif // STATE_H +typedef void (*event_recv_char) (crypto_state_t * state, char c); +typedef void (*event_fsm_step) (crypto_state_t * state); + +struct crypto_state_struct { + event_recv_char recv_char; + event_fsm_step fsm_step; +}; +void state_init_default(crypto_state_t * state); -/// @} - \ No newline at end of file +#endif // STATE_H diff --git a/state_buffer.cpp b/state_buffer.cpp new file mode 100644 index 0000000..c3896bf --- /dev/null +++ b/state_buffer.cpp @@ -0,0 +1,43 @@ + +#include "state_buffer.h" + +#include +#include "tweetnacl.h" + +#include "state_encrypt.h" +#include "state_decrypt.h" +#include "state_idle.h" + +#define BUFFER_SIZE (256 + crypto_secretbox_ZEROBYTES) + +static uint8_t input_len = 0; +static uint8_t input_i = 0; +static char input_buffer[BUFFER_SIZE]; + +static void buffer_recv_char(crypto_state_t * state, char c) { + if(input_i < input_len) { + input_buffer[crypto_secretbox_ZEROBYTES + input_i++] = c; + } else { + if(c == 'D') { + char * decrypt_start = input_buffer + crypto_secretbox_ZEROBYTES - crypto_secretbox_BOXZEROBYTES; + uint16_t decrypt_len = input_len + crypto_secretbox_BOXZEROBYTES; + transition_to_decrypt(state, decrypt_start, decrypt_len); + } + else if(c == 'E') { + uint16_t encrypt_len = input_len + crypto_secretbox_ZEROBYTES; + transition_to_encrypt(state, input_buffer, encrypt_len); + } + else { + transition_to_idle(state); + } + } +} + +void transition_to_buffer(crypto_state_t * state, uint8_t input_l) { + input_len = input_l; + input_i = 0; + memset(input_buffer, 0, sizeof(input_buffer)); + + state_init_default(state); + state->recv_char = buffer_recv_char; +} diff --git a/state_buffer.h b/state_buffer.h index 4f6192d..d019d41 100644 --- a/state_buffer.h +++ b/state_buffer.h @@ -1,25 +1,12 @@ -/** - * @file - * @author Riley Wood (riley@clearmotion.com) - * @copyright 2017 ClearMotion Inc., All Rights Reserved. * - * @defgroup state_buffer GROUP TITLE - * @addtogroup state_buffer - * @{ - * - * @brief DESCRIPTION HERE - * - */ - #ifndef STATE_BUFFER_H #define STATE_BUFFER_H -#include -#include +#include "state.h" -#endif // STATE_BUFFER_H +#include +void transition_to_buffer(crypto_state_t * state, uint8_t input_l); -/// @} - \ No newline at end of file +#endif // STATE_BUFFER_H diff --git a/state_decrypt.cpp b/state_decrypt.cpp new file mode 100644 index 0000000..8e2193a --- /dev/null +++ b/state_decrypt.cpp @@ -0,0 +1,35 @@ + +#include "state_decrypt.h" + +#include +#include "tweetnacl.h" + +#include "state.h" +#include "secrets.h" +#include "state_send_result.h" + +static char * to_decrypt = NULL; +static uint16_t to_decrypt_len = 0; + +static void decrypt_fsm_step(crypto_state_t * state) { + const uint8_t * nonce = get_nonce(); + const uint8_t * secret_key = get_secret_key(); + crypto_secretbox_open((unsigned char *)to_decrypt, + (unsigned char *)to_decrypt, + to_decrypt_len, + nonce, + secret_key); + const char * result = &to_decrypt[crypto_secretbox_ZEROBYTES]; + const uint8_t result_len = to_decrypt_len - crypto_secretbox_ZEROBYTES; + transition_to_send_result(state, result, result_len); +} + +void transition_to_decrypt(crypto_state_t * state, char * input, uint16_t input_len){ + to_decrypt = input; + to_decrypt_len = input_len; + + state_init_default(state); + state->fsm_step = decrypt_fsm_step; +} + + diff --git a/state_decrypt.h b/state_decrypt.h index 6979a49..e99bfc0 100644 --- a/state_decrypt.h +++ b/state_decrypt.h @@ -1,25 +1,11 @@ -/** - * @file - * @author Riley Wood (riley@clearmotion.com) - * @copyright 2017 ClearMotion Inc., All Rights Reserved. * - * @defgroup state_decrypt GROUP TITLE - * @addtogroup state_decrypt - * @{ - * - * @brief DESCRIPTION HERE - * - */ - - #ifndef STATE_DECRYPT_H #define STATE_DECRYPT_H -#include -#include +#include "state.h" -#endif // STATE_DECRYPT_H +#include +void transition_to_decrypt(crypto_state_t * state, char * input, uint16_t input_len); -/// @} - \ No newline at end of file +#endif // STATE_DECRYPT_H diff --git a/state_encrypt.cpp b/state_encrypt.cpp new file mode 100644 index 0000000..837837c --- /dev/null +++ b/state_encrypt.cpp @@ -0,0 +1,33 @@ + +#include "state_encrypt.h" + +#include +#include "tweetnacl.h" + +#include "state.h" +#include "secrets.h" +#include "state_send_result.h" + +static char * to_encrypt = NULL; +static uint16_t to_encrypt_len = 0; + +static void encrypt_fsm_step(crypto_state_t * state) { + const uint8_t * nonce = get_nonce(); + const uint8_t * secret_key = get_secret_key(); + crypto_secretbox((unsigned char *)to_encrypt, + (unsigned char *)to_encrypt, + to_encrypt_len, + nonce, + secret_key); + const char * result = &to_encrypt[crypto_secretbox_BOXZEROBYTES]; + const uint8_t result_len = to_encrypt_len - crypto_secretbox_BOXZEROBYTES; + transition_to_send_result(state, result, result_len); +} + +void transition_to_encrypt(crypto_state_t * state, char * input, uint16_t input_len){ + to_encrypt = input; + to_encrypt_len = input_len; + + state_init_default(state); + state->fsm_step = encrypt_fsm_step; +} diff --git a/state_encrypt.h b/state_encrypt.h index 115511d..e313b56 100644 --- a/state_encrypt.h +++ b/state_encrypt.h @@ -1,25 +1,11 @@ -/** - * @file - * @author Riley Wood (riley@clearmotion.com) - * @copyright 2017 ClearMotion Inc., All Rights Reserved. * - * @defgroup state_encrypt GROUP TITLE - * @addtogroup state_encrypt - * @{ - * - * @brief DESCRIPTION HERE - * - */ - - - #ifndef STATE_ENCRYPT_H #define STATE_ENCRYPT_H -#include +#include "state.h" + #include -#endif // STATE_ENCRYPT_H +void transition_to_encrypt(crypto_state_t * state, char * input, uint16_t input_len); +#endif // STATE_ENCRYPT_H -/// @} - \ No newline at end of file diff --git a/state_idle.cpp b/state_idle.cpp new file mode 100644 index 0000000..c793129 --- /dev/null +++ b/state_idle.cpp @@ -0,0 +1,16 @@ + + +#include "state_idle.h" + +#include + +#include "state_buffer.h" + +static void idle_recv_char(crypto_state_t * state, char c) { + transition_to_buffer(state, (uint8_t)c); +} + +void transition_to_idle(crypto_state_t * state) { + state_init_default(state); + state->recv_char = idle_recv_char; +} diff --git a/state_idle.h b/state_idle.h index d742989..b8e2e90 100644 --- a/state_idle.h +++ b/state_idle.h @@ -1,25 +1,11 @@ -/** - * @file - * @author Riley Wood (riley@clearmotion.com) - * @copyright 2017 ClearMotion Inc., All Rights Reserved. * - * @defgroup state_idle GROUP TITLE - * @addtogroup state_idle - * @{ - * - * @brief DESCRIPTION HERE - * - */ - #ifndef STATE_IDLE_H #define STATE_IDLE_H -#include -#include +#include "state.h" -#endif // STATE_IDLE_H +void transition_to_idle(crypto_state_t * state); +#endif // STATE_IDLE_H -/// @} - \ No newline at end of file diff --git a/state_send_result.cpp b/state_send_result.cpp new file mode 100644 index 0000000..fe93747 --- /dev/null +++ b/state_send_result.cpp @@ -0,0 +1,26 @@ + +#include "state_send_result.h" + +#include +#include + +#include "state_idle.h" + +static const char * result = NULL; +static uint8_t result_len = 0; + +extern void print(const char * buf, uint16_t len); + +static void send_result_fsm_step(crypto_state_t * state) { + print(result, result_len); + transition_to_idle(state); +} + + +void transition_to_send_result(crypto_state_t * state, const char * res, uint16_t res_len) { + result = res; + result_len = res_len; + + state_init_default(state); + state->fsm_step = send_result_fsm_step; +} diff --git a/state_send_result.h b/state_send_result.h index 181d36b..ad6edcc 100644 --- a/state_send_result.h +++ b/state_send_result.h @@ -1,25 +1,12 @@ -/** - * @file - * @author Riley Wood (riley@clearmotion.com) - * @copyright 2017 ClearMotion Inc., All Rights Reserved. * - * @defgroup state_send_result GROUP TITLE - * @addtogroup state_send_result - * @{ - * - * @brief DESCRIPTION HERE - * - */ - - #ifndef STATE_SEND_RESULT_H #define STATE_SEND_RESULT_H -#include +#include "state.h" + #include -#endif // STATE_SEND_RESULT_H +void transition_to_send_result(crypto_state_t * state, const char * res, uint16_t res_len); -/// @} - \ No newline at end of file +#endif diff --git a/testme.py b/testme.py index 76597e4..f6036b8 100644 --- a/testme.py +++ b/testme.py @@ -6,7 +6,7 @@ import string RESET_DELAY = 2 -DELAY = 0.5 +DELAY = 0.1 def encrypt(serial_port, input): @@ -20,7 +20,8 @@ def encrypt(serial_port, input): @return The input, encrypted """ s = serial_port - s.write("E"+input+"\n") + input_fmtd = chr(len(input) & 0xFF)+input+"E" + s.write(input_fmtd) time.sleep(DELAY) response = "" while s.inWaiting(): @@ -39,7 +40,8 @@ def decrypt(serial_port, input): @return The input, decrypted """ s = serial_port - s.write("D"+input+"\n") + input_fmtd = chr(len(input) & 0xFF)+input+"D" + s.write(input_fmtd) time.sleep(DELAY) response = "" while s.inWaiting():