diff --git a/hardware/Crypto.c b/hardware/Crypto.c index faaaad2..05b32b6 100644 --- a/hardware/Crypto.c +++ b/hardware/Crypto.c @@ -1,29 +1,54 @@ #include "Crypto.h" -uint8_t active_key[16]; -uint8_t active_iv[16]; +bool encryption_enabled = false; +uint8_t active_key[CRYPTO_KEY_SIZE]; +uint8_t active_iv[CRYPTO_KEY_SIZE]; aes_128_context_t context; -uint8_t current_vector[16]; +uint8_t current_vector[CRYPTO_KEY_SIZE]; +uint32_t entropy; +uint32_t entropy_index = 0; +bool entropy_loaded = false; +uint8_t ivs_generated = 0; + +FIL crypto_fp; // File buffer +char crypto_fb[CRYPTO_KEY_SIZE]; // File read buffer +FRESULT crypto_fr; // Result codes void crypto_init(void) { - crypto_test(); - return; + encryption_enabled = false; + + if (load_key()) { + if (load_entropy_index() && load_entropy()) { + encryption_enabled = true; + } + } + + if (encryption_enabled) { + // TODO: Set flags for crypto enabled + + // TODO: Remove + // for (uint8_t i = 0; i < 130; i++) { + // crypto_test(); + // } + } else { + LED_indicate_error_crypto(); + } } -void crypto_prepare(uint8_t key[16], uint8_t initialization_vector[16]) { +void crypto_prepare(uint8_t key[CRYPTO_KEY_SIZE], uint8_t initialization_vector[CRYPTO_KEY_SIZE]) { // Initialise the context with the key aes_128_init(&context, key); // Copy the IV into the current vector array - memcpy(current_vector, initialization_vector, 16); + memcpy(current_vector, initialization_vector, CRYPTO_KEY_SIZE); } -void crypto_encrypt_block(uint8_t block[16]) { +void crypto_encrypt_block(uint8_t block[CRYPTO_KEY_SIZE]) { int i; // XOR the current vector with the block before encrypting - for (i = 0; i < 16; i++) { + for (i = 0; i < CRYPTO_KEY_SIZE; i++) { block[i] ^= current_vector[i]; } @@ -31,36 +56,208 @@ void crypto_encrypt_block(uint8_t block[16]) { aes_128_encrypt(&context, block); // Copy the cipher output to the current vector - memcpy(current_vector, block, 16); + memcpy(current_vector, block, CRYPTO_KEY_SIZE); } -void crypto_decrypt_block(uint8_t block[16]) { - uint8_t temp_vector[16]; +void crypto_decrypt_block(uint8_t block[CRYPTO_KEY_SIZE]) { + uint8_t temp_vector[CRYPTO_KEY_SIZE]; int i; // Copy the cipher output to the temporary vector - memcpy(temp_vector, block, 16); + memcpy(temp_vector, block, CRYPTO_KEY_SIZE); // Decrypt the block aes_128_decrypt(&context, block); // XOR the output with the current vector to fully decrypt - for (i = 0; i < 16; i++) { + for (i = 0; i < CRYPTO_KEY_SIZE; i++) { block[i] ^= current_vector[i]; } // Copy the temporary vector to the current vector - memcpy(current_vector, temp_vector, 16); + memcpy(current_vector, temp_vector, CRYPTO_KEY_SIZE); } -void load_key(void) { - // TODO: implement +bool load_entropy_index(void) { + if (sd_mounted()) { + crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_INDEX, FA_READ); + if (crypto_fr == FR_NO_FILE) { + //printf("Entropy index file does not exist\r\n"); + f_close(&crypto_fp); + crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_INDEX, FA_CREATE_NEW | FA_WRITE); + + if (crypto_fr == FR_OK) { + entropy_index = 0x00000000; + memcpy(crypto_fb, &entropy_index, sizeof(entropy_index)); + + UINT written = 0; + crypto_fr = f_write(&crypto_fp, crypto_fb, sizeof(entropy_index), &written); + f_close(&crypto_fp); + + if (crypto_fr == FR_OK && written == sizeof(entropy_index)) { + //printf("Wrote new index to index file\r\n"); + } else { + //printf("Could not write index to index file\r\n"); + } + } else { + //printf("Could not create index file\r\n"); + } + + crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_INDEX, FA_READ); + } + + if (crypto_fr == FR_OK) { + //printf("Opened entropy index file\r\n"); + UINT read = 0; + crypto_fr = f_read(&crypto_fp, crypto_fb, sizeof(entropy_index), &read); + f_close(&crypto_fp); + if (crypto_fr == FR_OK && read == sizeof(entropy_index)) { + memcpy(&entropy_index, crypto_fb, sizeof(entropy_index)); + //printf("Entropy index is now: %lX\r\n", entropy_index); + return true; + } + } else { + //printf("Error opening entropy index file\r\n"); + } + + } + + f_close(&crypto_fp); + return false; } -void generate_iv(void) { - // TODO: implement +bool update_entropy_index(void) { + crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_INDEX, FA_WRITE); + if (crypto_fr == FR_OK) { + entropy_index += sizeof(entropy); + memcpy(crypto_fb, &entropy_index, sizeof(entropy_index)); + + UINT written = 0; + crypto_fr = f_write(&crypto_fp, crypto_fb, sizeof(entropy_index), &written); + + if (crypto_fr == FR_OK && written == sizeof(entropy_index)) { + return true; + } + } + return false; } +bool load_entropy(void) { + if (sd_mounted()) { + if (update_entropy_index()) { + crypto_fr = f_open(&crypto_fp, PATH_ENTROPY_SOURCE, FA_READ); + if (crypto_fr == FR_OK) { + uint32_t fsize = f_size(&crypto_fp); + //uint32_t fpoint = crypto_fp.fptr; + + //printf("Opened entropy file\r\n\tSize is %lu\r\n\tPointer is at %lX \r\n\tSeeking to index: %lX\r\n", fsize, fpoint, entropy_index); + + crypto_fr = f_lseek(&crypto_fp, entropy_index); + + //fpoint = crypto_fp.fptr; + //printf("After seek, pointer is now at %lX\r\n", fpoint); + + if (crypto_fr == FR_OK && crypto_fp.fptr < fsize-sizeof(entropy)) { + UINT read = 0; + crypto_fr = f_read(&crypto_fp, crypto_fb, sizeof(entropy), &read); + f_close(&crypto_fp); + + if (crypto_fr == FR_OK) { + memcpy(&entropy, crypto_fb, sizeof(entropy)); + //printf("Read entropy from SD: %lX\r\n", entropy); + srandom(entropy); + entropy_loaded = true; + ivs_generated = 0; + return true; + } else { + //printf("Could not read entropy data from SD\r\n"); + } + + } else { + f_close(&crypto_fp); + //printf("Could not seek in index file, entropy exhausted\r\n"); + LED_indicate_error_crypto(); + } + } + } + } + + f_close(&crypto_fp); + return false; +} + +bool load_key(void) { + if (sd_mounted()) { + crypto_fr = f_open(&crypto_fp, PATH_AES_128_KEY, FA_READ); + if (crypto_fr == FR_OK) { + //printf("File open\r\n"); + UINT read = 0; + crypto_fr = f_read(&crypto_fp, crypto_fb, CRYPTO_KEY_SIZE, &read); + f_close(&crypto_fp); + + if (crypto_fr == FR_OK && read == CRYPTO_KEY_SIZE) { + //printf("Loaded AES-128 Key: "); + for (uint8_t i = 0; i < 16; i++) { + active_key[i] = crypto_fb[i]; + //printf("%X ", crypto_fb[i]); + } + //printf("\r\n"); + return true; + } else { + //printf("Error %d reading file, read %d bytes.\r\n", crypto_fr, read); + } + } else { + //printf("Could not open file\r\n"); + } + } else { + //printf("SD not mounted\r\n"); + } + + return false; +} + +bool generate_iv(void) { + if (entropy_loaded) { + for (uint8_t i = 0; i < 16; i++) { + active_iv[i] = (uint8_t)random(); + } + ivs_generated++; + + // TODO: remove + /*printf("Generated IV: "); + for (uint8_t i = 0; i < 16; i++) { + printf("%X ", active_iv[i]); + } + printf("\r\n");*/ + + if (ivs_generated >= MAX_IVS_PER_ENTROPY_BLOCK) { + load_entropy(); + } + + return true; + } else { + return false; + } +} + +// TODO: Remove this void crypto_test(void) { + generate_iv(); + + uint8_t work_block[16]; + memset(work_block, 0x70, 16); + work_block[15] = 0x00; + + //printf("Work block plaintext: ===%s===\r\n", work_block); -} \ No newline at end of file + crypto_prepare(active_key, active_iv); + crypto_encrypt_block(work_block); + //printf("Work block ciphertext: ===%s===\r\n", work_block); + + crypto_prepare(active_key, active_iv); + crypto_decrypt_block(work_block); + printf("Work block plaintext: ===%s===\r\n", work_block); + +} + +// TODO: test entropy exhaustion \ No newline at end of file diff --git a/hardware/Crypto.h b/hardware/Crypto.h index afdc4bb..703a03a 100644 --- a/hardware/Crypto.h +++ b/hardware/Crypto.h @@ -5,10 +5,24 @@ #include #include #include -#include "crypto/aes.h" +#include "hardware/crypto/aes.h" +#include "hardware/LED.h" +#include "hardware/SD.h" + +#define PATH_ENTROPY_INDEX "OpenModem/entropy.index" +#define PATH_ENTROPY_SOURCE "OpenModem/entropy.source" +#define PATH_AES_128_KEY "OpenModem/aes128.key" + +#define CRYPTO_KEY_SIZE_BITS 128 +#define CRYPTO_KEY_SIZE (CRYPTO_KEY_SIZE_BITS/8) +#define MAX_IVS_PER_ENTROPY_BLOCK 128 void crypto_init(void); void crypto_test(void); +bool load_key(void); +bool load_entropy(void); +bool load_entropy_index(void); + #endif diff --git a/hardware/LED.c b/hardware/LED.c index d6790ca..f573a5a 100644 --- a/hardware/LED.c +++ b/hardware/LED.c @@ -52,4 +52,15 @@ void update_led_status(void) { } else { led_status_ticks++; } +} + +void LED_indicate_error_crypto(void) { + while (true) { + LED_COM_ON(); + LED_STATUS_OFF(); + delay_ms(500); + LED_COM_OFF(); + LED_STATUS_ON(); + delay_ms(500); + } } \ No newline at end of file diff --git a/hardware/LED.h b/hardware/LED.h index 341626b..3b5d7b6 100644 --- a/hardware/LED.h +++ b/hardware/LED.h @@ -19,4 +19,6 @@ void LED_COM_ON(void); void LED_COM_OFF(void); void update_led_status(void); +void LED_indicate_error_crypto(void); + #endif \ No newline at end of file diff --git a/hardware/SD.c b/hardware/SD.c index 64becaf..ae53222 100644 --- a/hardware/SD.c +++ b/hardware/SD.c @@ -1,4 +1,5 @@ #include "SD.h" +#include "hardware/Crypto.h" FATFS sdfs; @@ -24,6 +25,7 @@ void sd_init(void) { void sd_automounted_hook(void) { sd_statuschange_indication(1); + crypto_init(); } void sd_autounmounted_hook(void) { diff --git a/hardware/SD.h b/hardware/SD.h index f56c80c..a2ef809 100644 --- a/hardware/SD.h +++ b/hardware/SD.h @@ -23,4 +23,6 @@ void sd_automount(void); void sd_autounmount(void); void sd_statuschange_indication(uint8_t pattern); +bool sd_mounted(void); + #endif \ No newline at end of file diff --git a/main.c b/main.c index a92adc6..8b27440 100755 --- a/main.c +++ b/main.c @@ -70,7 +70,6 @@ void init(void) { ax25_init(&AX25, &modem, &modem.fd, ax25_callback); kiss_init(&AX25, &modem, &serial); sd_init(); - crypto_init(); bluetooth_init(); gps_init(&serial); usrio_init();