Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

116 lines
2.7 KiB

  1. #include <comms.h>
  2. #include <strobe_rng_init.h>
  3. static const size_t MAC_LEN = 8;
  4. static const size_t CHALLENGE_LEN = 16;
  5. static const uint8_t domain[] = "com.funkthat.lora.irrigation.shared.v0.0.1";
  6. size_t
  7. _strobe_state_size()
  8. {
  9. return sizeof(strobe_s);
  10. }
  11. void
  12. comms_init(struct comms_state *cs, process_msgfunc_t pmf, struct pktbuf *shared)
  13. {
  14. *cs = (struct comms_state){
  15. .cs_comm_state = COMMS_WAIT_REQUEST,
  16. .cs_procmsg = pmf,
  17. };
  18. strobe_init(&cs->cs_start, domain, sizeof domain - 1);
  19. if (shared != NULL)
  20. strobe_key(&cs->cs_start, SYM_KEY, shared->pkt, shared->pktlen);
  21. /* copy starting state over to initial state */
  22. cs->cs_state = cs->cs_start;
  23. }
  24. #define CONFIRMED_STR_BASE "confirmed"
  25. #define CONFIRMED_STR ((const uint8_t *)CONFIRMED_STR_BASE)
  26. #define CONFIRMED_STR_LEN (sizeof(CONFIRMED_STR_BASE) - 1)
  27. /*
  28. * encrypted data to be processed is passed in via pbin.
  29. *
  30. * The pktbuf pointed to by pbout contains the buffer that a [encrypted]
  31. * response will be written to. The length needs to be updated, where 0
  32. * means no reply.
  33. */
  34. void
  35. comms_process(struct comms_state *cs, struct pktbuf pbin, struct pktbuf *pbout)
  36. {
  37. uint8_t buf[64] = {};
  38. struct pktbuf pbmsg, pbrep;
  39. ssize_t cnt, ret, msglen;
  40. strobe_attach_buffer(&cs->cs_state, pbin.pkt, pbin.pktlen);
  41. cnt = strobe_get(&cs->cs_state, APP_CIPHERTEXT, buf, pbin.pktlen -
  42. MAC_LEN);
  43. msglen = cnt;
  44. cnt = strobe_get(&cs->cs_state, MAC, pbin.pkt +
  45. (pbin.pktlen - MAC_LEN), MAC_LEN);
  46. /* XXX - cnt != MAC_LEN test case */
  47. /*
  48. * if we have arrived here, MAC has been verified, and buf now
  49. * contains the data to operate upon.
  50. */
  51. /* attach the buffer for output */
  52. strobe_attach_buffer(&cs->cs_state, pbout->pkt, pbout->pktlen);
  53. ret = 0;
  54. switch (cs->cs_comm_state) {
  55. case COMMS_WAIT_REQUEST:
  56. /* XXX - reqreset check */
  57. bare_strobe_randomize(buf, CHALLENGE_LEN);
  58. ret = strobe_put(&cs->cs_state, APP_CIPHERTEXT, buf,
  59. CHALLENGE_LEN);
  60. ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN);
  61. strobe_operate(&cs->cs_state, RATCHET, NULL, 32);
  62. cs->cs_comm_state = COMMS_WAIT_CONFIRM;
  63. break;
  64. case COMMS_WAIT_CONFIRM:
  65. /* XXX - confirm check */
  66. ret = strobe_put(&cs->cs_state, APP_CIPHERTEXT, CONFIRMED_STR,
  67. CONFIRMED_STR_LEN);
  68. ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN);
  69. cs->cs_comm_state = COMMS_PROCESS_MSGS;
  70. break;
  71. case COMMS_PROCESS_MSGS: {
  72. uint8_t repbuf[pbout->pktlen - MAC_LEN];
  73. memset(repbuf, '\x00', sizeof repbuf);
  74. pbmsg.pkt = buf;
  75. pbmsg.pktlen = msglen;
  76. pbrep.pkt = repbuf;
  77. pbrep.pktlen = sizeof repbuf;
  78. cs->cs_procmsg(pbmsg, &pbrep);
  79. ret = strobe_put(&cs->cs_state, APP_CIPHERTEXT, repbuf,
  80. pbrep.pktlen);
  81. ret += strobe_put(&cs->cs_state, MAC, NULL, MAC_LEN);
  82. break;
  83. }
  84. }
  85. pbout->pktlen = ret;
  86. }