#include #include static const size_t MAC_LEN = 8; static const size_t CHALLENGE_LEN = 16; static const uint8_t domain[] = "com.funkthat.lora.irrigation.shared.v0.0.1"; size_t _strobe_state_size() { return sizeof(strobe_s); } void comms_init(struct comms_state *cs, process_msgfunc_t pmf, struct pktbuf *shared) { *cs = (struct comms_state){ .cs_comm_state = COMMS_WAIT_REQUEST, .cs_procmsg = pmf, }; strobe_init(&cs->cs_start, domain, sizeof domain - 1); if (shared != NULL) strobe_key(&cs->cs_start, SYM_KEY, shared->pkt, shared->pktlen); /* copy starting state over to initial state */ cs->cs_state = cs->cs_start; } #define CONFIRMED_STR_BASE "confirmed" #define CONFIRMED_STR ((const uint8_t *)CONFIRMED_STR_BASE) #define CONFIRMED_STR_LEN (sizeof(CONFIRMED_STR_BASE) - 1) /* * encrypted data to be processed is passed in via pbin. * * The pktbuf pointed to by pbout contains the buffer that a [encrypted] * response will be written to. The length needs to be updated, where 0 * means no reply. */ void comms_process(struct comms_state *cs, struct pktbuf pbin, struct pktbuf *pbout) { uint8_t buf[64] = {}; struct pktbuf pbmsg, pbrep; ssize_t cnt, ret, msglen; strobe_attach_buffer(&cs->cs_state, pbin.pkt, pbin.pktlen); cnt = strobe_get(&cs->cs_state, APP_CIPHERTEXT, buf, pbin.pktlen - MAC_LEN); msglen = cnt; cnt = strobe_get(&cs->cs_state, MAC, pbin.pkt + (pbin.pktlen - MAC_LEN), MAC_LEN); /* XXX - cnt != MAC_LEN test case */ /* * if we have arrived here, MAC has been verified, and buf now * contains the data to operate upon. */ /* attach the buffer for output */ strobe_attach_buffer(&cs->cs_state, pbout->pkt, pbout->pktlen); ret = 0; switch (cs->cs_comm_state) { case COMMS_WAIT_REQUEST: /* XXX - reqreset check */ bare_strobe_randomize(buf, CHALLENGE_LEN); ret = strobe_put(&cs->cs_state, APP_CIPHERTEXT, buf, CHALLENGE_LEN); ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN); strobe_operate(&cs->cs_state, RATCHET, NULL, 32); cs->cs_comm_state = COMMS_WAIT_CONFIRM; break; case COMMS_WAIT_CONFIRM: /* XXX - confirm check */ ret = strobe_put(&cs->cs_state, APP_CIPHERTEXT, CONFIRMED_STR, CONFIRMED_STR_LEN); ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN); cs->cs_comm_state = COMMS_PROCESS_MSGS; break; case COMMS_PROCESS_MSGS: { uint8_t repbuf[pbout->pktlen - MAC_LEN]; memset(repbuf, '\x00', sizeof repbuf); pbmsg.pkt = buf; pbmsg.pktlen = msglen; pbrep.pkt = repbuf; pbrep.pktlen = sizeof repbuf; cs->cs_procmsg(pbmsg, &pbrep); ret = strobe_put(&cs->cs_state, APP_CIPHERTEXT, repbuf, pbrep.pktlen); ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN); break; } } pbout->pktlen = ret; }