
// uC includes
#include "../common/io.c"
#include "../common/lib.c"

int main () {
    char signature_buffer[64];              // >=> sp
    char *static_buffer = mem_get (0x2420); // >=> 0x2420

    puts ("Welcome to the secure program loader.");

    while (1) {
        unsigned short loadaddr;      // >=> r11
        unsigned char signature_type; // >=> r9
        unsigned char payload_length; // >=> r10
        puts ("Please enter debug payload.");

        memset (static_buffer, 0, 0x400);
        getsn (static_buffer, 0x3ff);

        loadaddr       = (static_buffer[0] << 8) + (static_buffer[1]);
        signature_type = static_buffer[2];
        payload_length = static_buffer[3];
        if (0x8000 > loadaddr || loadaddr >= 0xf001) {
            puts ("Load address outside allowed range of 0x8000-0xF000");
            continue;
        }
        if (payload_length - 6 > 0x3bb) {
            puts ("Invalid payload length");
            continue;
        }
        char *payload_signature = static_buffer + payload_length;
        int result;
        memcpy (signature_buffer, payload_signature, 0x40);
        if (signature_type == 0x1) {
            sha512 (static_buffer, payload_length, signature_buffer);
            result = memcmp (signature_buffer, payload_signature, 0x40);
        }
        if (signature_type != 0x0) {
            puts ("Invalid signature type");
            continue;
        } else {
            result = verify_ed25519 (mem_get (0x2400), static_buffer, payload_length, signature_buffer);
        }
        if (result != 0x1) {
            puts ("Incorrect signature, continuing");
            continue;
        }
        puts ("Signature valid, executing payload");
        memcpy (mem_get (loadaddr), static_buffer + 0x4, payload_length);
        puts ((char *) mem_get (loadaddr));
    }
}
