main.ino 3.25 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
#include "crypto_aead.h"
#include "api.h"
#include "uartp.h"

#define MAX_BYTES 100

//#define DEBUG
#define CRYPTO_BUSY 12

uint8_t npub[CRYPTO_NPUBBYTES];
uint8_t nsec[CRYPTO_NSECBYTES];
uint8_t k[CRYPTO_KEYBYTES];
uint8_t ad[MAX_BYTES];
unsigned long long int adlen;
uint8_t m[MAX_BYTES];
unsigned long long int mlen;
uint8_t c[MAX_BYTES];
unsigned long long int clen;

void setup();
void loop();

#ifdef __cplusplus
extern "C" {
#endif

void uart_write(uint8_t x) {
    Serial.write((uint8_t) (x));
}

uint8_t uart_read() {
    int r;
    do {
        r = Serial.read();
    } while (r == -1);
    return (uint8_t) (0xff & r);
}

#ifdef __cplusplus
}
#endif

#ifdef DEBUG
#define DEBUG_BUF_LEN 80
int dbg_printf(const char *format, ...) {
    char printbuf[DEBUG_BUF_LEN+2];

    va_list vargs;
    va_start(vargs, format);
    int r = vsnprintf(printbuf+1, DEBUG_BUF_LEN, format, vargs);
    va_end(vargs);

    if (r < 0) {
        memcpy(printbuf+1, "DEBUG ERROR\r\n", 13);
        r = 13;
    }

    r = r > DEBUG_BUF_LEN ? DEBUG_BUF_LEN : r;
    printbuf[0] = 0xde;  // Debug messages should start with "\xde"
    uartp_send(printbuf, r+1);
    return r;
}
#else
#define dbg_printf(...) (0)
#endif

void my_assert(bool b) {
    if (b)
        return;
    dbg_printf("Assertion failed\r\n");
    for(;;)
        yield();
}

void setup() {
    Serial.begin(115200);
    pinMode(CRYPTO_BUSY, OUTPUT);
    digitalWrite(CRYPTO_BUSY, HIGH);
    delay(100);
    Serial.print("Hello, World!");
}


void loop() {
    static uint8_t buf[256];
    int res;
    uint16_t len = uartp_recv(buf, 255);
    uint8_t action = buf[0];
    if (len == 0 || len > 255)
        return;

    uint16_t l = len - 1;
    uint16_t rl = 0;
    uint8_t *var = buf+1;
    switch (action) {
        case 'm': my_assert(l <= MAX_BYTES);        memcpy(m,    var, l); mlen = l; break;
        case 'c': my_assert(l <= MAX_BYTES);        memcpy(c,    var, l); clen = l; break;
        case 'a': my_assert(l <= MAX_BYTES);        memcpy(ad,   var, l); adlen = l; break;
        case 'k': my_assert(l == CRYPTO_KEYBYTES);  memcpy(k,    var, l); break;
        case 'p': my_assert(l == CRYPTO_NPUBBYTES); memcpy(npub, var, l); break;
        case 's': my_assert(l == CRYPTO_NSECBYTES); memcpy(nsec, var, l); break;
        case 'e':
			noInterrupts();
			asm("nop");
            digitalWrite(CRYPTO_BUSY, LOW);
            res = crypto_aead_encrypt(c, &clen, m, mlen, ad, adlen, nsec, npub, k);
            digitalWrite(CRYPTO_BUSY, HIGH);
			asm("nop");
			interrupts();
            break;
        case 'd':
			noInterrupts();
			asm("nop");
            digitalWrite(CRYPTO_BUSY, LOW);
            res = crypto_aead_decrypt(m, &mlen, nsec, c, clen, ad, adlen, npub, k);
            digitalWrite(CRYPTO_BUSY, HIGH);
			asm("nop");
			interrupts();
            break;
        case'M': var = m;    rl = mlen; break;
        case'C': var = c;    rl = clen; break;
        case'A': var = ad;   rl = adlen; break;
        case'K': var = k;    rl = CRYPTO_KEYBYTES; break;
        case'P': var = npub; rl = CRYPTO_NPUBBYTES; break;
        case'S': var = nsec; rl = CRYPTO_NSECBYTES; break;
        default:
            dbg_printf("Unknown command\r\n");
            my_assert(false);
    }
    buf[0] = action;
    memcpy(buf+1, var, rl);
    uartp_send(buf, rl+1);
}