CryptoHeader.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #ifndef CryptoHeader_H
  16. #define CryptoHeader_H
  17. #include "util/Assert.h"
  18. #include "util/Endian.h"
  19. #include <stdint.h>
  20. /**
  21. * Header for nodes authenticating to one another.
  22. *
  23. * 1 2 3
  24. * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
  25. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  26. * 0 | Auth Type | |
  27. * +-+-+-+-+-+-+-+-+ Hash Code +
  28. * 4 | |
  29. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  30. * 8 |A| Derivations |S| Additional |
  31. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  32. *
  33. * If the 'A' bit is set, the packets in the connection are to be authenticated with Poly1305.
  34. * The Auth Type and Hash Code combined make a lookup key which can be used to scan a hashtable
  35. * to see if the given password is known. It can be thought of as the "username" although it is
  36. * a derivative of the password.
  37. * The number of derivations represents how many times the hash of the password has been hashed
  38. * again. Assuming Alice and Bob have a secure shared secret and Bob and Charlie have a secure
  39. * shared secret, Bob can provide Charlie with a hash of his password with Alice which will allow
  40. * Charlie to then establish a secure connection with Alice, without relying exclusively on
  41. * asymmetrical cryptography.
  42. *
  43. * If the packet has 0 length and the 'S' bit is set then the packet is only intended for helping
  44. * to setup the Cryptoauth session and should be dropped rather than being passed to the user.
  45. */
  46. union CryptoHeader_Challenge
  47. {
  48. struct {
  49. uint8_t type;
  50. uint8_t lookup[7];
  51. /**
  52. * High 1 bit is whether to require poly1305 packet authentication.
  53. * low 15 bits is number of derivations.
  54. */
  55. uint16_t requirePacketAuthAndDerivationCount;
  56. uint16_t additional;
  57. } challenge;
  58. uint8_t bytes[12];
  59. uint32_t ints[3];
  60. };
  61. /** Total size of the auth structure. */
  62. #define CryptoHeader_Challenge_SIZE 12
  63. Assert_compileTime(sizeof(union CryptoHeader_Challenge) == CryptoHeader_Challenge_SIZE);
  64. /** The number of bytes from the beginning which identify the auth for looking up the secret. */
  65. #define CryptoHeader_Challenge_KEYSIZE 8
  66. static inline int CryptoHeader_isSetupPacket(union CryptoHeader_Challenge* ac)
  67. {
  68. return ac->challenge.additional & Endian_hostToBigEndian16(1<<15);
  69. }
  70. static inline void CryptoHeader_setPacketAuthRequired(union CryptoHeader_Challenge* ac,
  71. int require)
  72. {
  73. if (require) {
  74. ac->challenge.requirePacketAuthAndDerivationCount |=
  75. Endian_hostToBigEndian16(1<<15);
  76. } else {
  77. ac->challenge.requirePacketAuthAndDerivationCount &=
  78. Endian_hostToBigEndian16(~(1<<15));
  79. }
  80. }
  81. static inline void CryptoHeader_setSetupPacket(union CryptoHeader_Challenge* ac, int empty)
  82. {
  83. if (empty) {
  84. ac->challenge.additional |= Endian_hostToBigEndian16(1<<15);
  85. } else {
  86. ac->challenge.additional &= Endian_hostToBigEndian16(~(1<<15));
  87. }
  88. }
  89. static inline uint16_t CryptoHeader_getAuthChallengeDerivations(union CryptoHeader_Challenge* ac)
  90. {
  91. return Endian_bigEndianToHost16(ac->challenge.requirePacketAuthAndDerivationCount)
  92. & (((uint16_t)~0)>>1);
  93. }
  94. static inline void CryptoHeader_setAuthChallengeDerivations(union CryptoHeader_Challenge* ac,
  95. uint16_t derivations)
  96. {
  97. ac->challenge.requirePacketAuthAndDerivationCount &=
  98. Endian_hostToBigEndian16(1<<15);
  99. ac->challenge.requirePacketAuthAndDerivationCount |=
  100. Endian_hostToBigEndian16(derivations & ~(1<<15));
  101. }
  102. /**
  103. * This is a handshake header packet, there are 2 required to begin an encrypted connection.
  104. *
  105. * 1 2 3
  106. * 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
  107. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  108. * 0 | Session State |
  109. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  110. * 4 | |
  111. * + +
  112. * 8 | Auth Challenge |
  113. * + +
  114. * 12 | |
  115. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  116. * 16 | |
  117. * + +
  118. * 20 | |
  119. * + +
  120. * 24 | |
  121. * + Random Nonce +
  122. * 28 | |
  123. * + +
  124. * 32 | |
  125. * + +
  126. * 36 | |
  127. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  128. * 40 | |
  129. * + +
  130. * 44 | |
  131. * + +
  132. * 48 | |
  133. * + +
  134. * 52 | |
  135. * + Permanent Public Key +
  136. * 56 | |
  137. * + +
  138. * 60 | |
  139. * + +
  140. * 64 | |
  141. * + +
  142. * 68 | |
  143. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  144. * 72 | |
  145. * + +
  146. * 76 | |
  147. * + Poly1305 Authenticator +
  148. * 80 | |
  149. * + +
  150. * 84 | |
  151. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  152. * 88 | |
  153. * + +
  154. * 92 | |
  155. * + +
  156. * 96 | |
  157. * + +
  158. * 100 | |
  159. * + Encrypted/Authenticated Temporary Public Key +
  160. * 104 | |
  161. * + +
  162. * 108 | |
  163. * + +
  164. * 112 | |
  165. * + +
  166. * 116 | |
  167. * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  168. * | |
  169. * + Variable Length Encrypted/Authenticated Content +
  170. * | |
  171. *
  172. * If "Session State" is equal to the bitwise complement of zero, the sender is requesting
  173. * that the recipient begin a connection with him, this is done in cases when the initiator
  174. * of the connection does not know the key for the recipient. If the entire header is not
  175. * present the recipient MUST drop the packet silently, the only field which is read in the
  176. * packet is the "Permanent Public Key" field, all others SHOULD be ignored, specifically,
  177. * content MUST not be passed on because it cannot be authenticated. The recipient of such a
  178. * packet SHOULD send back a "hello" packet if there is no established connection.
  179. * If there is already a connection over the interface, the recipient SHOULD NOT respond
  180. * but MAY allow the connection to time out faster.
  181. *
  182. * If the "Session State" field is equal to the one or two, the packet is a "hello" packet.
  183. * or a repeated hello packet. If no connection is present, one should be established and the
  184. * recipient MAY send a "key" packet in response but it is RECOMMENDED that he wait until
  185. * he has data to send first. A node who has sent a hello packet and gotten no response and
  186. * now wishes to send more data MUST send that data as more (repeat) hello packets.
  187. *
  188. * If the "Session State" field is equal to two or three, the packet is a "key" packet.
  189. * Key packets are responses to hello packets. Once a node receives a key packet it may begin
  190. * sending data packets. A node who has received a hello packet, sent a key packet and gotten
  191. * no further response who now wishes to send more data MUST send that data as more (repeat)
  192. * key packets.
  193. */
  194. union CryptoHeader
  195. {
  196. uint32_t nonce;
  197. struct {
  198. /**
  199. * Numbers one through three are interpreted as handshake packets, UINT32_MAX is
  200. * a connectToMe packet and anything else is a nonce in a traffic packet.
  201. */
  202. uint32_t handshakeStage;
  203. /** Used for authenticating routers to one another. */
  204. union CryptoHeader_Challenge auth;
  205. /** Random nonce for the handshake. */
  206. uint8_t nonce[24];
  207. /** This node's permanent public key. */
  208. uint8_t publicKey[32];
  209. /** This is filled in when the tempKey is encrypted. */
  210. uint8_t authenticator[16];
  211. /** The public key to use for this session, encrypted with the private key. */
  212. uint8_t encryptedTempKey[32];
  213. } handshake;
  214. };
  215. #define CryptoHeader_SIZE 120
  216. Assert_compileTime(sizeof(union CryptoHeader) == CryptoHeader_SIZE);
  217. #endif