aesgcm-footer.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*
  2. * Common footer included by every implementation of the AES-GCM MAC.
  3. *
  4. * The difficult part of AES-GCM, which is done differently depending
  5. * on what hardware acceleration is available, is the actual
  6. * evaluation of a polynomial over GF(2^128) whose coefficients are
  7. * 128-bit chunks of data. But preparing those chunks in the first
  8. * place (out of the ciphertext, associated data, and an
  9. * administrative block containing the lengths of both) is done in the
  10. * same way no matter what technique is used for the evaluation, so
  11. * that's centralised into this file, along with as much of the other
  12. * functionality as possible.
  13. *
  14. * This footer file is #included by each implementation, but each one
  15. * will define its own struct type for the state, so that each alloc
  16. * function will test sizeof() a different structure, and similarly
  17. * for free when it zeroes out the state on cleanup.
  18. *
  19. * The functions in the source file may be defined as 'inline' so that
  20. * the functions in here can inline them. The 'coeff' function in
  21. * particular probably should be, because that's called once per
  22. * 16-byte block, so eliminating function call overheads is especially
  23. * useful there.
  24. *
  25. * This footer has the following expectations from the source file
  26. * that #includes it:
  27. *
  28. * - define AESGCM_FLAVOUR to be a fragment of a C identifier that
  29. * will be included in all the function names (both the ones
  30. * defined in the implementation source file and those in here).
  31. * For example purposes below I'll suppose that this is 'foo'.
  32. *
  33. * - define AESGCM_NAME to be a string literal that will be included
  34. * in the display name of the implementation.
  35. *
  36. * - define a typedef 'aesgcm_foo' to be the state structure for the
  37. * implementation, and inside that structure, expand the macro
  38. * AESGCM_COMMON_FIELDS defined in aesgcm.h
  39. *
  40. * - define the following functions:
  41. *
  42. * // Determine whether this implementation is available at run time
  43. * static bool aesgcm_foo_available(void);
  44. *
  45. * // Set up the 'key' of the polynomial part of the MAC, that is,
  46. * // the value at which the polynomial will be evaluated. 'var' is
  47. * // a 16-byte data block in the byte order it comes out of AES.
  48. * static void aesgcm_foo_setkey_impl(aesgcm_foo *ctx,
  49. * const unsigned char *var);
  50. *
  51. * // Set up at the start of evaluating an individual polynomial.
  52. * // 'mask' is the 16-byte data block that will be XORed into the
  53. * // output value of the polynomial, also in AES byte order. This
  54. * // function should store 'mask' in whatever form is most
  55. * // convenient, and initialise an accumulator to zero.
  56. * static void aesgcm_foo_setup(aesgcm_foo *ctx,
  57. * const unsigned char *mask);
  58. *
  59. * // Fold in a coefficient of the polynomial, by means of XORing
  60. * // it into the accumulator and then multiplying the accumulator
  61. * // by the variable passed to setkey_impl() above.
  62. * //
  63. * // 'coeff' points to the 16-byte block of data that the
  64. * // polynomial coefficient will be made out of.
  65. * //
  66. * // You probably want to mark this function 'inline'.
  67. * static void aesgcm_foo_coeff(aesgcm_foo *ctx,
  68. * const unsigned char *coeff);
  69. *
  70. * // Generate the output MAC, by XORing the accumulator's final
  71. * // value with the mask passed to setup() above.
  72. * //
  73. * // 'output' points to a 16-byte region of memory to write the
  74. * // result to.
  75. * static void aesgcm_foo_output(aesgcm_foo *ctx,
  76. * unsigned char *output);
  77. *
  78. * - if allocation of the state structure must be done in a
  79. * non-standard way (e.g. x86 needs this to force greater alignment
  80. * than standard malloc provides), then #define SPECIAL_ALLOC and
  81. * define this additional function:
  82. *
  83. * // Allocate a state structure, zero out its contents, and return it.
  84. * static aesgcm_foo *aesgcm_foo_alloc(void);
  85. *
  86. * - if freeing must also be done in an unusual way, #define
  87. * SPECIAL_FREE and define this function:
  88. *
  89. * // Zero out the state structure to avoid information leaks if the
  90. * // memory is reused, and then free it.
  91. * static void aesgcm_foo_free(aesgcm_foo *ctx);
  92. */
  93. #ifndef AESGCM_FLAVOUR
  94. #error AESGCM_FLAVOUR must be defined by any module including this footer
  95. #endif
  96. #ifndef AESGCM_NAME
  97. #error AESGCM_NAME must be defined by any module including this footer
  98. #endif
  99. #define CONTEXT CAT(aesgcm_, AESGCM_FLAVOUR)
  100. #define PREFIX(name) CAT(CAT(aesgcm_, AESGCM_FLAVOUR), CAT(_, name))
  101. #include "aes.h" // for aes_encrypt_ecb_block
  102. static const char *PREFIX(mac_text_name)(ssh2_mac *mac)
  103. {
  104. return "AES-GCM (" AESGCM_NAME ")";
  105. }
  106. static void PREFIX(mac_next_message)(ssh2_mac *mac)
  107. {
  108. CONTEXT *ctx = container_of(mac, CONTEXT, mac);
  109. /*
  110. * Make the mask value for a single MAC instance, by encrypting
  111. * the all-zeroes word using the associated AES instance in its
  112. * ordinary GCM fashion. This consumes the first block of
  113. * keystream (with per-block counter equal to 1), leaving the
  114. * second block of keystream ready to be used on the first block
  115. * of plaintext.
  116. */
  117. unsigned char buf[16];
  118. memset(buf, 0, 16);
  119. ssh_cipher_encrypt(ctx->cipher, buf, 16);
  120. PREFIX(setup)(ctx, buf); /* give it to the implementation to store */
  121. smemclr(buf, sizeof(buf));
  122. }
  123. static void PREFIX(mac_setkey)(ssh2_mac *mac, ptrlen key)
  124. {
  125. CONTEXT *ctx = container_of(mac, CONTEXT, mac);
  126. /*
  127. * Make the value of the polynomial variable, by encrypting the
  128. * all-zeroes word using the associated AES instance in the
  129. * special ECB mode. This is done via the special AES-specific API
  130. * function encrypt_ecb_block, which doesn't touch the counter
  131. * state at all.
  132. */
  133. unsigned char var[16];
  134. memset(var, 0, 16);
  135. aes_encrypt_ecb_block(ctx->cipher, var);
  136. PREFIX(setkey_impl)(ctx, var);
  137. smemclr(var, sizeof(var));
  138. PREFIX(mac_next_message)(mac); /* set up mask */
  139. }
  140. static void PREFIX(mac_start)(ssh2_mac *mac)
  141. {
  142. CONTEXT *ctx = container_of(mac, CONTEXT, mac);
  143. ctx->skipgot = ctx->aadgot = ctx->ciphertextlen = ctx->partlen = 0;
  144. }
  145. /*
  146. * Handle receiving data via the BinarySink API and turning it into a
  147. * collection of 16-byte blocks to use as polynomial coefficients.
  148. *
  149. * This code is written in a fully general way, which is able to
  150. * handle an arbitrary number of bytes at the start of the data to
  151. * ignore completely (necessary for PuTTY integration), and an
  152. * arbitrary number to treat as associated data, and the rest will be
  153. * regarded as ciphertext. The stream can be interrupted at any byte
  154. * position and resumed later; a partial block will be stored as
  155. * necessary.
  156. *
  157. * At the time of writing this comment, in live use most of that
  158. * generality isn't required: the full data is passed to this function
  159. * in just one call. But there's no guarantee of that staying true in
  160. * future, so we do the full deal here just in case, and the test
  161. * vectors in cryptsuite.py will test it. (And they'll use
  162. * set_prefix_lengths to set up different configurations from the SSH
  163. * usage.)
  164. */
  165. static void PREFIX(mac_BinarySink_write)(
  166. BinarySink *bs, const void *blkv, size_t len)
  167. {
  168. CONTEXT *ctx = BinarySink_DOWNCAST(bs, CONTEXT);
  169. const unsigned char *blk = (const unsigned char *)blkv;
  170. /*
  171. * Skip the prefix sequence number used as implicit extra data in
  172. * SSH MACs. This is not included in the associated data field for
  173. * GCM, because the IV incrementation policy provides its own
  174. * sequence numbering.
  175. */
  176. if (ctx->skipgot < ctx->skiplen) {
  177. size_t n = ctx->skiplen - ctx->skipgot;
  178. if (n > len)
  179. n = len;
  180. blk += n;
  181. len -= n;
  182. ctx->skipgot += n;
  183. if (len == 0)
  184. return;
  185. }
  186. /*
  187. * Read additional authenticated data and fold it in to the MAC.
  188. */
  189. while (ctx->aadgot < ctx->aadlen) {
  190. size_t n = ctx->aadlen - ctx->aadgot;
  191. if (n > len)
  192. n = len;
  193. if (ctx->partlen || n < 16) {
  194. /*
  195. * Fold data into the partial block.
  196. */
  197. if (n > 16 - ctx->partlen)
  198. n = 16 - ctx->partlen;
  199. memcpy(ctx->partblk + ctx->partlen, blk, n);
  200. ctx->partlen += n;
  201. } else if (n >= 16) {
  202. /*
  203. * Consume a whole block of AAD.
  204. */
  205. PREFIX(coeff)(ctx, blk);
  206. n = 16;
  207. }
  208. blk += n;
  209. len -= n;
  210. ctx->aadgot += n;
  211. if (ctx->partlen == 16) {
  212. PREFIX(coeff)(ctx, ctx->partblk);
  213. ctx->partlen = 0;
  214. }
  215. if (ctx->aadgot == ctx->aadlen && ctx->partlen) {
  216. memset(ctx->partblk + ctx->partlen, 0, 16 - ctx->partlen);
  217. PREFIX(coeff)(ctx, ctx->partblk);
  218. ctx->partlen = 0;
  219. }
  220. if (len == 0)
  221. return;
  222. }
  223. /*
  224. * Read the main ciphertext and fold it in to the MAC.
  225. */
  226. while (len > 0) {
  227. size_t n = len;
  228. if (ctx->partlen || n < 16) {
  229. /*
  230. * Fold data into the partial block.
  231. */
  232. if (n > 16 - ctx->partlen)
  233. n = 16 - ctx->partlen;
  234. memcpy(ctx->partblk + ctx->partlen, blk, n);
  235. ctx->partlen += n;
  236. } else if (n >= 16) {
  237. /*
  238. * Consume a whole block of ciphertext.
  239. */
  240. PREFIX(coeff)(ctx, blk);
  241. n = 16;
  242. }
  243. blk += n;
  244. len -= n;
  245. ctx->ciphertextlen += n;
  246. if (ctx->partlen == 16) {
  247. PREFIX(coeff)(ctx, ctx->partblk);
  248. ctx->partlen = 0;
  249. }
  250. }
  251. }
  252. static void PREFIX(mac_genresult)(ssh2_mac *mac, unsigned char *output)
  253. {
  254. CONTEXT *ctx = container_of(mac, CONTEXT, mac);
  255. /*
  256. * Consume any partial block of ciphertext remaining.
  257. */
  258. if (ctx->partlen) {
  259. memset(ctx->partblk + ctx->partlen, 0, 16 - ctx->partlen);
  260. PREFIX(coeff)(ctx, ctx->partblk);
  261. }
  262. /*
  263. * Consume the final block giving the lengths of the AAD and ciphertext.
  264. */
  265. unsigned char blk[16];
  266. memset(blk, 0, 16);
  267. PUT_64BIT_MSB_FIRST(blk, ctx->aadlen * 8);
  268. PUT_64BIT_MSB_FIRST(blk + 8, ctx->ciphertextlen * 8);
  269. PREFIX(coeff)(ctx, blk);
  270. /*
  271. * And call the implementation's output function.
  272. */
  273. PREFIX(output)(ctx, output);
  274. smemclr(blk, sizeof(blk));
  275. smemclr(ctx->partblk, 16);
  276. }
  277. static ssh2_mac *PREFIX(mac_new)(const ssh2_macalg *alg, ssh_cipher *cipher)
  278. {
  279. const struct aesgcm_extra *extra = alg->extra;
  280. if (!check_aesgcm_availability(extra))
  281. return NULL;
  282. #ifdef SPECIAL_ALLOC
  283. CONTEXT *ctx = PREFIX(alloc)();
  284. #else
  285. CONTEXT *ctx = snew(CONTEXT);
  286. memset(ctx, 0, sizeof(CONTEXT));
  287. #endif
  288. ctx->mac.vt = alg;
  289. ctx->cipher = cipher;
  290. /* Default values for SSH-2, overridable by set_prefix_lengths for
  291. * testcrypt purposes */
  292. ctx->skiplen = 4;
  293. ctx->aadlen = 4;
  294. BinarySink_INIT(ctx, PREFIX(mac_BinarySink_write));
  295. BinarySink_DELEGATE_INIT(&ctx->mac, ctx);
  296. return &ctx->mac;
  297. }
  298. static void PREFIX(set_prefix_lengths)(ssh2_mac *mac, size_t skip, size_t aad)
  299. {
  300. CONTEXT *ctx = container_of(mac, CONTEXT, mac);
  301. ctx->skiplen = skip;
  302. ctx->aadlen = aad;
  303. }
  304. static void PREFIX(mac_free)(ssh2_mac *mac)
  305. {
  306. CONTEXT *ctx = container_of(mac, CONTEXT, mac);
  307. #ifdef SPECIAL_FREE
  308. PREFIX(free)(ctx);
  309. #else
  310. smemclr(ctx, sizeof(*ctx));
  311. sfree(ctx);
  312. #endif
  313. }
  314. static struct aesgcm_extra_mutable PREFIX(extra_mut);
  315. static const struct aesgcm_extra PREFIX(extra) = {
  316. .check_available = PREFIX(available),
  317. .mut = &PREFIX(extra_mut),
  318. .set_prefix_lengths = PREFIX(set_prefix_lengths),
  319. };
  320. const ssh2_macalg CAT(ssh2_aesgcm_mac_, AESGCM_FLAVOUR) = {
  321. .new = PREFIX(mac_new),
  322. .free = PREFIX(mac_free),
  323. .setkey = PREFIX(mac_setkey),
  324. .start = PREFIX(mac_start),
  325. .genresult = PREFIX(mac_genresult),
  326. .next_message = PREFIX(mac_next_message),
  327. .text_name = PREFIX(mac_text_name),
  328. .name = "",
  329. .etm_name = "", /* Not selectable independently */
  330. .len = 16,
  331. .keylen = 0,
  332. .extra = &PREFIX(extra),
  333. };