diff options
Diffstat (limited to 'controller/fw/src')
-rw-r--r-- | controller/fw/src/crypto.c | 80 | ||||
-rw-r--r-- | controller/fw/src/crypto.h | 20 |
2 files changed, 64 insertions, 36 deletions
diff --git a/controller/fw/src/crypto.c b/controller/fw/src/crypto.c index 73ad783..db35745 100644 --- a/controller/fw/src/crypto.c +++ b/controller/fw/src/crypto.c @@ -1,16 +1,22 @@ +#include <assert.h> #include <unistd.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> -#include <aes.h> +#include <sodium.h> #include "crypto.h" #include "simulation.h" -void debug_hexdump(const char *name, uint8_t *buf, size_t len); -void debug_hexdump(const char *name, uint8_t *buf, size_t len) { + +void debug_hexdump(const char *name, const uint8_t *buf, size_t len); +int verify_trigger_dom(const uint8_t inkey[PRESIG_MSG_LEN], + const char *domain_string, const uint8_t refkey[PRESIG_MSG_LEN]); + + +void debug_hexdump(const char *name, const uint8_t *buf, size_t len) { DEBUG_PRINTN("%20s: ", name); for (size_t i=0; i<len;) { for (size_t j=0; j<8 && i<len; i++, j++) @@ -20,29 +26,55 @@ void debug_hexdump(const char *name, uint8_t *buf, size_t len) { DEBUG_PRINTN("\n"); } -int oob_message_received(uint8_t msg[static OOB_TRIGGER_LEN]) { - struct AES_ctx ctx; - uint8_t buf[crypto_sign_BYTES]; - - for (size_t serial=0; serial<PRESIG_STORE_SIZE; serial++) { - for (size_t dom=0; dom<_TRIGGER_DOMAIN_COUNT; dom++) { - - DEBUG_PRINT("Trying domain %zd serial %zd", dom, serial); - debug_hexdump("oob_presig_iv", oob_presig_iv, sizeof(oob_presig_iv)); - - memcpy(buf, presig_store[dom][serial], crypto_sign_BYTES); - debug_hexdump("presig", buf, sizeof(buf)); - AES_init_ctx_iv(&ctx, msg, oob_presig_iv); - AES_CBC_decrypt_buffer(&ctx, buf, crypto_sign_BYTES); - debug_hexdump("decrypted", buf, sizeof(buf)); - - if (!crypto_sign_verify_detached(buf, presig_messages[dom][serial], PRESIG_MSG_LEN, oob_trigger_pubkey)) { - oob_trigger_activated(dom, presig_first_serial + serial); - return 1; - } - DEBUG_PRINTN("\n"); +/* Returns 1 for correct trigger */ +int verify_trigger_dom(const uint8_t inkey[PRESIG_MSG_LEN], + const char *domain_string, const uint8_t refkey[PRESIG_MSG_LEN]) { + uint8_t key[crypto_auth_hmacsha512_KEYBYTES]; + uint8_t key_out[crypto_auth_hmacsha512_BYTES]; + + static_assert(PRESIG_MSG_LEN <= crypto_auth_hmacsha512_KEYBYTES); + memcpy(key, inkey, PRESIG_MSG_LEN); + memset(key + PRESIG_MSG_LEN, 0, sizeof(key) - PRESIG_MSG_LEN); + DEBUG_PRINT("ds \"%s\"", domain_string); + debug_hexdump("ref", refkey, PRESIG_MSG_LEN); + + for (int i=0; i<presig_height; i++) { + DEBUG_PRINT("Verifying height rel %d abs %d", i, presig_height-i); + debug_hexdump("key", key, sizeof(key)); + (void)crypto_auth_hmacsha512(key_out, (uint8_t *)domain_string, strlen(domain_string), key); + debug_hexdump("out", key_out, sizeof(key_out)); + memcpy(key, key_out, PRESIG_MSG_LEN); + memset(key + PRESIG_MSG_LEN, 0, sizeof(key) - PRESIG_MSG_LEN); + + if (!memcmp(key, refkey, PRESIG_MSG_LEN)) + return presig_height-i; + } + + return 0; +} + +int verify_trigger(const uint8_t inkey[PRESIG_MSG_LEN], int *height_out, int *domain_out) { + int res; + for (int i=0; i<_TRIGGER_DOMAIN_COUNT; i++) { + DEBUG_PRINT("Verifying domain %d", i); + if ((res = verify_trigger_dom(inkey, presig_domain_strings[i], presig_keys[i]))) { + DEBUG_PRINT("Match!"); + if (height_out) + *height_out = res - 1; + if (domain_out) + *domain_out = i; + return 1; } } + return 0; +} + +int oob_message_received(uint8_t msg[static OOB_TRIGGER_LEN]) { + int height, domain; + if (verify_trigger(msg, &height, &domain)) { + oob_trigger_activated(domain, height); + return 1; + } return 0; } diff --git a/controller/fw/src/crypto.h b/controller/fw/src/crypto.h index 61a0da8..05a3c0d 100644 --- a/controller/fw/src/crypto.h +++ b/controller/fw/src/crypto.h @@ -3,12 +3,8 @@ #include <stdint.h> -#include <sodium.h> - - -#define OOB_TRIGGER_LEN 16 #define PRESIG_MSG_LEN 16 - +#define OOB_TRIGGER_LEN PRESIG_MSG_LEN enum trigger_domain { TRIGGER_DOMAIN_ALL, @@ -19,15 +15,15 @@ enum trigger_domain { _TRIGGER_DOMAIN_COUNT }; -extern uint8_t presig_store[_TRIGGER_DOMAIN_COUNT][PRESIG_STORE_SIZE][crypto_sign_BYTES]; -extern uint8_t oob_trigger_pubkey[crypto_sign_PUBLICKEYBYTES]; -extern uint8_t presig_messages[_TRIGGER_DOMAIN_COUNT][PRESIG_STORE_SIZE][PRESIG_MSG_LEN]; -extern uint8_t oob_presig_iv[16]; -extern int presig_first_serial; - +extern const char *presig_domain_strings[_TRIGGER_DOMAIN_COUNT]; +extern uint8_t presig_keys[_TRIGGER_DOMAIN_COUNT][PRESIG_MSG_LEN]; +extern int presig_height; +extern uint8_t presig_bundle_id[16]; +extern uint64_t bundle_timestamp; -extern void oob_trigger_activated(enum trigger_domain domain, int serial); +extern void oob_trigger_activated(enum trigger_domain domain, int height); int oob_message_received(uint8_t msg[static OOB_TRIGGER_LEN]); +int verify_trigger(const uint8_t inkey[PRESIG_MSG_LEN], int *height_out, int *domain_out); #endif /* __CRYPTO_H__ */ |