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.
 
 
 
 
 
 

421 lines
15 KiB

  1. /**
  2. * @file strobe.h
  3. * @copyright
  4. * Copyright (c) 2015-2016 Cryptography Research, Inc. \n
  5. * Released under the MIT License. See LICENSE.txt for license information.
  6. * @author Mike Hamburg
  7. * @brief Strobe lite protocol instances.
  8. */
  9. #ifndef __STROBE_H__
  10. #define __STROBE_H__
  11. /* TODO: Implement state compaction, particularly for PRNG state */
  12. /* TODO: Test this against the Python reference. */
  13. #include <stdint.h>
  14. #include <stdlib.h>
  15. #include <assert.h>
  16. #include <string.h>
  17. #include <sys/types.h>
  18. #include "strobe_config.h"
  19. /**
  20. * A control word holds flags and other information that control a STROBE operation.
  21. * Defined below.
  22. */
  23. typedef uint32_t control_word_t;
  24. /* Strobe object, below */
  25. struct strobe_s;
  26. /** Initialize a STROBE object, using the description as a domain separator. */
  27. void strobe_init (
  28. struct strobe_s *__restrict__ strobe,
  29. const uint8_t *description,
  30. size_t desclen
  31. );
  32. /** Underlying duplex primitive. */
  33. ssize_t strobe_duplex (
  34. struct strobe_s *__restrict__ strobe,
  35. control_word_t flags,
  36. uint8_t *inside,
  37. ssize_t len
  38. );
  39. /**
  40. * More complex duplex primitive.
  41. * First reads/writes metadata based on control_flags, then data. Can pass
  42. * -len instead of len when reading. This means any length up to len.
  43. * Returns the number of data bytes read, or <0 on error.
  44. */
  45. ssize_t strobe_operate (
  46. struct strobe_s *__restrict__ strobe,
  47. control_word_t control_flags,
  48. uint8_t *inside,
  49. ssize_t len
  50. );
  51. #if STROBE_SUPPORT_PRNG
  52. /** Seed the generator with len bytes of randomness. */
  53. void strobe_seed_prng(const uint8_t *data, ssize_t len);
  54. /**
  55. * Fill *data with len bytes of randomness.
  56. * Return <0 if the generator is not seeded.
  57. */
  58. int __attribute__((warn_unused_result))
  59. strobe_randomize(uint8_t *data, ssize_t len);
  60. #endif /* STROBE_SUPPORT_PRNG */
  61. /* Flags as defined in the paper */
  62. #define FLAG_I (1<<0) /**< Inbound */
  63. #define FLAG_A (1<<1) /**< Has application-side data (eg, not a MAC) */
  64. #define FLAG_C (1<<2) /**< Uses encryption or rekeying. */
  65. #define FLAG_T (1<<3) /**< Send or receive data via transport */
  66. #define FLAG_M (1<<4) /**< Operation carries metadata. */
  67. #define FLAG_META_I (1<<20) /**< Metadata has I */
  68. #define FLAG_META_A (1<<21) /**< Metadata has A (always set) */
  69. #define FLAG_META_C (1<<22) /**< Metadata has C */
  70. #define FLAG_META_T (1<<23) /**< Metadata has T */
  71. #define FLAG_META_M (1<<24) /**< Metadata has M (always set) */
  72. #define GET_META_FLAGS(cw) (((cw) >> 20) & 0x3F)
  73. #define FLAG_MORE (1<<28) /**< Continue a streaming operation. */
  74. #define FLAG_NO_DATA (1<<29) /**< Just send/recv the metadata, not the data. */
  75. #if STROBE_SUPPORT_FLAG_POST
  76. /**
  77. * Post-op ratchet and/or MAC.
  78. *
  79. * TODO: I might want to remove these, because some details of how this is
  80. * done might be application-specific. In particular, some applications will
  81. * want to frame their MACs on the wire, and some will not.
  82. */
  83. #define FLAG_POST_RATCHET (1<<30) /**< Ratchet state after */
  84. #define FLAG_POST_MAC (1<<31) /**< Send/receive MAC after */
  85. #endif
  86. /* Operation types as defined in the paper */
  87. #define TYPE_AD FLAG_A /**< Context data, not sent to trensport */
  88. #define TYPE_KEY (FLAG_A | FLAG_C) /**< Symmetric key, not sent to transport */
  89. #define TYPE_CLR (FLAG_T | FLAG_A) /**< Data to be sent in the clear */
  90. #define TYPE_ENC (FLAG_T | FLAG_A | FLAG_C) /**< Data sent encrypted */
  91. #define TYPE_MAC (FLAG_T | FLAG_C) /**< Message authentication code */
  92. #define TYPE_RATCHET FLAG_C /**< Erase data to prevent rollback */
  93. #define TYPE_PRF (FLAG_I | FLAG_A | FLAG_C) /**< Return pseudorandom hash */
  94. /** For operate, have (n)-byte little-endian length field. */
  95. #define CW_LENGTH_BYTES(n) ((uint32_t)(n)<<16)
  96. #define STROBE_CW_GET_LENGTH_BYTES(cw) ((cw)>>16 & 0xF)
  97. #define MAKE_IMPLICIT(cw) ((cw) &~ (FLAG_T | FLAG_META_T))
  98. #define MAKE_LENGTHLESS(cw) ((cw) &~ CW_LENGTH_BYTES(0x0F))
  99. #define GET_CONTROL_TAG(cw) (((cw)>>8)&0xFF)
  100. #define CONTROL_WORD(w,value,flags) enum { w=value<<8|flags|FLAG_META_A|FLAG_META_M }
  101. /* Recommended control words */
  102. /* 0x00-0x0F: symmetric cryptography */
  103. CONTROL_WORD(SYM_SCHEME , 0x00, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  104. CONTROL_WORD(SYM_KEY , 0x01, TYPE_KEY );
  105. CONTROL_WORD(APP_PLAINTEXT , 0x02, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  106. CONTROL_WORD(APP_CIPHERTEXT , 0x03, TYPE_ENC | CW_LENGTH_BYTES(2) | FLAG_META_T );
  107. CONTROL_WORD(NONCE , 0x04, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  108. CONTROL_WORD(AUTH_DATA , 0x05, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  109. CONTROL_WORD(MAC , 0x06, TYPE_MAC | CW_LENGTH_BYTES(2) );
  110. CONTROL_WORD(HASH , 0x07, TYPE_PRF | CW_LENGTH_BYTES(2) );
  111. CONTROL_WORD(DERIVE_KEY , 0x08, TYPE_PRF | CW_LENGTH_BYTES(2) );
  112. CONTROL_WORD(BE_SLOW , 0x0C, TYPE_RATCHET | CW_LENGTH_BYTES(4) );
  113. CONTROL_WORD(SIV_PT_INNER , 0x0D, TYPE_CLR ); /* FUTURE: implement SIV */
  114. CONTROL_WORD(SIV_MAC_OUTER , 0x0E, TYPE_CLR );
  115. CONTROL_WORD(RATCHET , 0x0F, TYPE_RATCHET );
  116. /* 0x10-0x1F: Asymmetric key exchange and encryption */
  117. CONTROL_WORD(KEM_SCHEME , 0x10, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  118. CONTROL_WORD(PUBLIC_KEY , 0x11, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  119. CONTROL_WORD(KEM_EPH , 0x12, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  120. CONTROL_WORD(KEM_RESULT , 0x13, TYPE_KEY );
  121. /* 0x18-0x1F: Signatures */
  122. CONTROL_WORD(SIG_SCHEME , 0x18, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  123. CONTROL_WORD(SIG_EPH , 0x19, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  124. CONTROL_WORD(SIG_CHALLENGE , 0x1A, TYPE_PRF | CW_LENGTH_BYTES(2) );
  125. CONTROL_WORD(SIG_RESPONSE , 0x1B, TYPE_ENC | CW_LENGTH_BYTES(2) | FLAG_META_T );
  126. CONTROL_WORD(SIG_DETERM , 0x1C, TYPE_PRF | CW_LENGTH_BYTES(2) );
  127. /* 0x20-0x2F: header and other metadata */
  128. CONTROL_WORD(HANDSHAKE , 0x20, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  129. CONTROL_WORD(VERSION , 0x21, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  130. CONTROL_WORD(CIPHERSUITE , 0x22, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  131. CONTROL_WORD(META_PLAINTEXT , 0x24, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  132. CONTROL_WORD(META_CIPHERTEXT, 0x25, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  133. CONTROL_WORD(CERTIFICATE , 0x26, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  134. CONTROL_WORD(ENCRYPTED_CERT , 0x27, TYPE_ENC | CW_LENGTH_BYTES(2) | FLAG_META_T );
  135. CONTROL_WORD(OVER , 0x2E, TYPE_MAC | CW_LENGTH_BYTES(2) | FLAG_META_T );
  136. CONTROL_WORD(CLOSE , 0x2F, TYPE_MAC | CW_LENGTH_BYTES(2) | FLAG_META_T );
  137. /* 0x30-0x3F: Certificates.
  138. *
  139. * These are still experimental and unimplemented, and will probably change.
  140. * The intention is that certs should look something like this:
  141. *
  142. * CERT_VERSION 1
  143. * CERT_SERIAL .{0,32} ? # for revocation, else omitted
  144. * CERT_VALIDITY? # omitted if your devices aren't tracking time or can't update
  145. * CERT_PURPOSE .*? # if your application makes such a distinction
  146. * ((CERT_REC_PRE .* CERT_REC_POST .*) | (CERT_NAME .*))
  147. * ^ if the cert is an intermediate ^ if it isn't an intermediate
  148. * (CERT_PK_SCHEME PUBLIC_KEY)+ # Limited to 1? Could have multiple? Dunno.
  149. *
  150. * CERT_COMMENT *
  151. * (SIG_SCHEME SIG_CHAL SIG_EPH SIG_RESPONSE)+ # or similar depending on sig scheme
  152. * ^ Possibly this should be limited to 1.
  153. *
  154. * If your application uses cert chains, they would be given in separate CERTIFICATE
  155. * (or ENCRYPTED_CERT) messages, in order from CA to leaf. At any time, the client
  156. * could track "what's the most recent trusted intermediate which has authority over
  157. * the name I'm trying to contact." Then if there are multiple certifying chains, the
  158. * untrusted ones would be ignored.
  159. */
  160. CONTROL_WORD(CERT_VERSION , 0x30, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  161. CONTROL_WORD(CERT_SERIAL , 0x31, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  162. CONTROL_WORD(CERT_VALIDITY , 0x32, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  163. CONTROL_WORD(CERT_PURPOSE , 0x33, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  164. CONTROL_WORD(CERT_REC_PRE , 0x34, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  165. CONTROL_WORD(CERT_REC_POST , 0x35, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  166. CONTROL_WORD(CERT_NAME , 0x36, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  167. CONTROL_WORD(CERT_PK_SCHEME , 0x37, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  168. CONTROL_WORD(CERT_COMMENT , 0x3F, TYPE_CLR | CW_LENGTH_BYTES(2) | FLAG_META_T );
  169. #if STROBE_INTEROP_F_BITS == 1600
  170. #define kword_t uint64_t
  171. #elif STROBE_INTEROP_F_BITS == 800
  172. #define kword_t uint32_t
  173. #elif STROBE_INTEROP_F_BITS == 400
  174. #define kword_t uint16_t
  175. #else
  176. #error "Strobe supports only Keccak-F{400,800,1600}"
  177. #endif
  178. /* IO callback context. Opaque to STROBE. */
  179. typedef struct {
  180. void *a, *b; /**< Two pointers for use by the callback context. */
  181. #if STROBE_IO_CTX_HAS_FD
  182. int fd; /**< A file descriptor, or whatever. */
  183. #endif
  184. } strobe_io_ctx_s;
  185. /** Callback context */
  186. typedef struct {
  187. // FUTURE: make these return two values?
  188. /**
  189. * Read up to [size] bytes of data. Set the buffer to where it
  190. * points, and return how many bytes were actually read.
  191. */
  192. ssize_t (*read) (strobe_io_ctx_s *ctx, const uint8_t **buffer, ssize_t size);
  193. /**
  194. * The write callback is trickier.
  195. *
  196. * The first call returns a buffer to write the data to.
  197. *
  198. * The next call writes that data out, and returns a new (or more likely,
  199. * the same) buffer.
  200. */
  201. ssize_t (*write) (strobe_io_ctx_s *ctx, uint8_t **buffer, ssize_t size);
  202. } strobe_io_callbacks_s;
  203. extern const strobe_io_callbacks_s strobe_io_cb_buffer, strobe_io_cb_const_buffer;
  204. /** Keccak's domain: 25 words of size b/25, or b/8 bytes. */
  205. typedef union {
  206. kword_t w[25]; uint8_t b[25*sizeof(kword_t)/sizeof(uint8_t)];
  207. } kdomain_s;
  208. /** The main strobe state object. */
  209. typedef struct strobe_s {
  210. kdomain_s state;
  211. uint8_t position, pos_begin, flags;
  212. const strobe_io_callbacks_s *io;
  213. strobe_io_ctx_s io_ctx;
  214. } strobe_s, strobe_t[1];
  215. #if STROBE_CW_MAX_LENGTH_BYTES <= 1
  216. typedef uint8_t strobe_length_t;
  217. #elif STROBE_CW_MAX_LENGTH_BYTES <= 2
  218. typedef uint16_t strobe_length_t;
  219. #elif STROBE_CW_MAX_LENGTH_BYTES <= 4
  220. typedef uint32_t strobe_length_t;
  221. #elif STROBE_CW_MAX_LENGTH_BYTES <= 8
  222. typedef uint64_t strobe_length_t;
  223. #elif STROBE_CW_MAX_LENGTH_BYTES <= 16
  224. typedef uint128_t strobe_length_t;
  225. #else
  226. #error "Can't deal with >128-bit length fields'"
  227. #endif
  228. typedef struct {
  229. uint8_t control;
  230. strobe_length_t len;
  231. } __attribute__((packed)) strobe_serialized_control_t;
  232. /* Protocol building blocks */
  233. #define TRY(foo) do { ssize_t _ret = (foo); if (_ret < 0) return _ret; } while(0)
  234. /**
  235. * Destroy a STROBE object by writing zeros over it.
  236. * NB: if you don't have C11's memset_s, the compiler might optimize this call
  237. * away!
  238. */
  239. static inline void strobe_destroy(strobe_t strobe) {
  240. #ifdef __STDC_LIB_EXT1__
  241. memset_s(strobe,sizeof(*strobe),0,sizeof(*strobe));
  242. #else
  243. memset(strobe,0,sizeof(*strobe));
  244. #endif
  245. }
  246. /**
  247. * Detach the I/O from a STROBE object.
  248. */
  249. static inline void strobe_detach(strobe_t strobe) {
  250. strobe->io = NULL;
  251. /* Not really relevant: */
  252. // strobe->io_ctx.a = strobe->io_ctx.b = NULL;
  253. }
  254. /** Reverse the role of a STROBE object (i.e. to emulate the other guy). */
  255. static inline void strobe_reverse(strobe_t strobe) {
  256. strobe->flags ^= FLAG_I;
  257. }
  258. /** Attach a buffer to a strobe object. */
  259. static inline void strobe_attach_buffer(strobe_t strobe, uint8_t *start, size_t length) {
  260. strobe->io = &strobe_io_cb_buffer;
  261. strobe->io_ctx.a = start;
  262. strobe->io_ctx.b = start+length;
  263. }
  264. /** Attach a buffer to a strobe object. */
  265. static inline void strobe_attach_const_buffer(strobe_t strobe, uint8_t *start, size_t length) {
  266. strobe->io = &strobe_io_cb_const_buffer;
  267. strobe->io_ctx.a = start;
  268. strobe->io_ctx.b = start+length;
  269. }
  270. /** Same as operate, but only for sending data or putting it into the sponge. */
  271. static inline ssize_t strobe_put (
  272. strobe_s *__restrict__ strobe,
  273. control_word_t control_flags,
  274. const uint8_t *inside,
  275. ssize_t len
  276. ) {
  277. assert(!(control_flags & (FLAG_M|FLAG_I|FLAG_META_I)));
  278. return strobe_operate(strobe,control_flags,(uint8_t *)inside,len);
  279. }
  280. /** Receive data or extract it from the sponge. */
  281. static inline ssize_t strobe_get (
  282. strobe_s *__restrict__ strobe,
  283. control_word_t control_flags,
  284. uint8_t *inside,
  285. ssize_t len
  286. ) {
  287. assert(!(control_flags & FLAG_M));
  288. assert((control_flags & (FLAG_T|FLAG_C)) != 0);
  289. control_flags |= FLAG_I;
  290. if (control_flags & FLAG_META_T) control_flags |= FLAG_META_I;
  291. return strobe_operate(strobe,control_flags,(uint8_t *)inside,len);
  292. }
  293. /* Endian swaps */
  294. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  295. static inline kword_t eswap_letoh(kword_t w) { return w; }
  296. static inline kword_t eswap_htole(kword_t w) { return w; }
  297. static inline uint16_t eswap_letoh_16(uint16_t w) { return w; }
  298. static inline uint16_t eswap_htole_16(uint16_t w) { return w; }
  299. static inline uint32_t eswap_letoh_32(uint32_t w) { return w; }
  300. static inline uint32_t eswap_htole_32(uint32_t w) { return w; }
  301. static inline uint64_t eswap_letoh_64(uint64_t w) { return w; }
  302. static inline uint64_t eswap_htole_64(uint64_t w) { return w; }
  303. static inline strobe_length_t eswap_letoh_sl(strobe_length_t w) { return w; }
  304. static inline strobe_length_t eswap_htole_sl(strobe_length_t w) { return w; }
  305. #else
  306. #error "Fix eswap() on non-little-endian machine"
  307. #endif
  308. /**
  309. * Receive just control/metadata from the other party.
  310. * This is for complex protocols where you may not know what will come next.
  311. */
  312. static inline ssize_t strobe_get_control (
  313. strobe_s *__restrict__ strobe,
  314. strobe_serialized_control_t *cw,
  315. uint32_t flags
  316. ) {
  317. unsigned int length_bytes = STROBE_CW_GET_LENGTH_BYTES(flags);
  318. control_word_t cwf = GET_META_FLAGS(flags) | FLAG_I | FLAG_T;
  319. cw->len = 0;
  320. ssize_t ret = strobe_duplex(strobe, cwf, (uint8_t *)cw, sizeof(cw->control) + length_bytes);
  321. /* Probably a nop, allowing tailcall, except we're inline anyway */
  322. cw->len = eswap_letoh_sl(cw->len);
  323. return ret;
  324. }
  325. static inline ssize_t strobe_put_mac( strobe_t strobe ) {
  326. return strobe_operate(strobe, MAC, NULL, STROBE_INTEROP_MAC_BYTES);
  327. }
  328. static inline ssize_t strobe_get_mac(strobe_t strobe ) {
  329. return strobe_operate(strobe, MAC|FLAG_I, NULL, STROBE_INTEROP_MAC_BYTES);
  330. }
  331. static inline ssize_t strobe_key (
  332. strobe_t strobe,
  333. control_word_t cw,
  334. const uint8_t *data,
  335. uint16_t len
  336. ) {
  337. assert(!(cw & FLAG_T));
  338. return strobe_put(strobe, cw, data, len);
  339. }
  340. #if STROBE_CONVENIENCE_ECDH
  341. int strobe_eph_ecdh (
  342. strobe_t strobe,
  343. int i_go_first
  344. );
  345. #endif
  346. #if X25519_SUPPORT_SIGN
  347. int strobe_session_sign (
  348. strobe_t strobe,
  349. const uint8_t my_seckey[32],
  350. const uint8_t my_pubkey[32]
  351. );
  352. #endif
  353. #if X25519_SUPPORT_VERIFY
  354. int strobe_session_verify (
  355. strobe_t strobe,
  356. const uint8_t their_pubkey[32]
  357. );
  358. #if STROBE_SUPPORT_CERT_VERIFY
  359. /* Parse a signature but don't verify it.
  360. * Useful for intermediate certs we don't trust.
  361. */
  362. int strobe_session_dont_verify (
  363. strobe_t strobe,
  364. const uint8_t their_pubkey[32]
  365. );
  366. #endif
  367. #endif
  368. #endif /* __STROBE_H__ */