xform_aes_icm.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /* $OpenBSD: xform.c,v 1.16 2001/08/28 12:20:43 ben Exp $ */
  2. /*-
  3. * The authors of this code are John Ioannidis (ji@tla.org),
  4. * Angelos D. Keromytis (kermit@csd.uch.gr),
  5. * Niels Provos (provos@physnet.uni-hamburg.de) and
  6. * Damien Miller (djm@mindrot.org).
  7. *
  8. * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
  9. * in November 1995.
  10. *
  11. * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
  12. * by Angelos D. Keromytis.
  13. *
  14. * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
  15. * and Niels Provos.
  16. *
  17. * Additional features in 1999 by Angelos D. Keromytis.
  18. *
  19. * AES XTS implementation in 2008 by Damien Miller
  20. *
  21. * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
  22. * Angelos D. Keromytis and Niels Provos.
  23. *
  24. * Copyright (C) 2001, Angelos D. Keromytis.
  25. *
  26. * Copyright (C) 2008, Damien Miller
  27. * Copyright (c) 2014 The FreeBSD Foundation
  28. * All rights reserved.
  29. *
  30. * Portions of this software were developed by John-Mark Gurney
  31. * under sponsorship of the FreeBSD Foundation and
  32. * Rubicon Communications, LLC (Netgate).
  33. *
  34. * Permission to use, copy, and modify this software with or without fee
  35. * is hereby granted, provided that this entire notice is included in
  36. * all copies of any software which is or includes a copy or
  37. * modification of this software.
  38. * You may use this code under the GNU public license if you so wish. Please
  39. * contribute changes back to the authors under this freer than GPL license
  40. * so that we may further the use of strong encryption without limitations to
  41. * all.
  42. *
  43. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  44. * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  45. * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  46. * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  47. * PURPOSE.
  48. */
  49. #include <sys/cdefs.h>
  50. #include <opencrypto/cbc_mac.h>
  51. #include <opencrypto/gmac.h>
  52. #include <opencrypto/xform_enc.h>
  53. struct aes_gcm_ctx {
  54. struct aes_icm_ctx cipher;
  55. struct aes_gmac_ctx gmac;
  56. };
  57. struct aes_ccm_ctx {
  58. struct aes_icm_ctx cipher;
  59. struct aes_cbc_mac_ctx cbc_mac;
  60. };
  61. static int aes_icm_setkey(void *, const uint8_t *, int);
  62. static void aes_icm_crypt(void *, const uint8_t *, uint8_t *);
  63. static void aes_icm_crypt_multi(void *, const uint8_t *, uint8_t *, size_t);
  64. static void aes_icm_crypt_last(void *, const uint8_t *, uint8_t *, size_t);
  65. static void aes_icm_reinit(void *, const uint8_t *, size_t);
  66. static int aes_gcm_setkey(void *, const uint8_t *, int);
  67. static void aes_gcm_reinit(void *, const uint8_t *, size_t);
  68. static int aes_gcm_update(void *, const void *, u_int);
  69. static void aes_gcm_final(uint8_t *, void *);
  70. static int aes_ccm_setkey(void *, const uint8_t *, int);
  71. static void aes_ccm_reinit(void *, const uint8_t *, size_t);
  72. static int aes_ccm_update(void *, const void *, u_int);
  73. static void aes_ccm_final(uint8_t *, void *);
  74. /* Encryption instances */
  75. const struct enc_xform enc_xform_aes_icm = {
  76. .type = CRYPTO_AES_ICM,
  77. .name = "AES-ICM",
  78. .ctxsize = sizeof(struct aes_icm_ctx),
  79. .blocksize = 1,
  80. .native_blocksize = AES_BLOCK_LEN,
  81. .ivsize = AES_BLOCK_LEN,
  82. .minkey = AES_MIN_KEY,
  83. .maxkey = AES_MAX_KEY,
  84. .setkey = aes_icm_setkey,
  85. .reinit = aes_icm_reinit,
  86. .encrypt = aes_icm_crypt,
  87. .decrypt = aes_icm_crypt,
  88. .encrypt_multi = aes_icm_crypt_multi,
  89. .decrypt_multi = aes_icm_crypt_multi,
  90. .encrypt_last = aes_icm_crypt_last,
  91. .decrypt_last = aes_icm_crypt_last,
  92. };
  93. const struct enc_xform enc_xform_aes_nist_gcm = {
  94. .type = CRYPTO_AES_NIST_GCM_16,
  95. .name = "AES-GCM",
  96. .ctxsize = sizeof(struct aes_gcm_ctx),
  97. .blocksize = 1,
  98. .native_blocksize = AES_BLOCK_LEN,
  99. .ivsize = AES_GCM_IV_LEN,
  100. .minkey = AES_MIN_KEY,
  101. .maxkey = AES_MAX_KEY,
  102. .macsize = AES_GMAC_HASH_LEN,
  103. .setkey = aes_gcm_setkey,
  104. .reinit = aes_gcm_reinit,
  105. .encrypt = aes_icm_crypt,
  106. .decrypt = aes_icm_crypt,
  107. .encrypt_multi = aes_icm_crypt_multi,
  108. .decrypt_multi = aes_icm_crypt_multi,
  109. .encrypt_last = aes_icm_crypt_last,
  110. .decrypt_last = aes_icm_crypt_last,
  111. .update = aes_gcm_update,
  112. .final = aes_gcm_final,
  113. };
  114. const struct enc_xform enc_xform_ccm = {
  115. .type = CRYPTO_AES_CCM_16,
  116. .name = "AES-CCM",
  117. .ctxsize = sizeof(struct aes_ccm_ctx),
  118. .blocksize = 1,
  119. .native_blocksize = AES_BLOCK_LEN,
  120. .ivsize = AES_CCM_IV_LEN,
  121. .minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY,
  122. .macsize = AES_CBC_MAC_HASH_LEN,
  123. .setkey = aes_ccm_setkey,
  124. .reinit = aes_ccm_reinit,
  125. .encrypt = aes_icm_crypt,
  126. .decrypt = aes_icm_crypt,
  127. .encrypt_multi = aes_icm_crypt_multi,
  128. .decrypt_multi = aes_icm_crypt_multi,
  129. .encrypt_last = aes_icm_crypt_last,
  130. .decrypt_last = aes_icm_crypt_last,
  131. .update = aes_ccm_update,
  132. .final = aes_ccm_final,
  133. };
  134. /*
  135. * Encryption wrapper routines.
  136. */
  137. static void
  138. aes_icm_reinit(void *key, const uint8_t *iv, size_t ivlen)
  139. {
  140. struct aes_icm_ctx *ctx;
  141. ctx = key;
  142. KASSERT(ivlen <= sizeof(ctx->ac_block),
  143. ("%s: ivlen too large", __func__));
  144. bcopy(iv, ctx->ac_block, ivlen);
  145. }
  146. static void
  147. aes_gcm_reinit(void *vctx, const uint8_t *iv, size_t ivlen)
  148. {
  149. struct aes_gcm_ctx *ctx = vctx;
  150. KASSERT(ivlen == AES_GCM_IV_LEN,
  151. ("%s: invalid IV length", __func__));
  152. aes_icm_reinit(&ctx->cipher, iv, ivlen);
  153. /* GCM starts with 2 as counter 1 is used for final xor of tag. */
  154. bzero(&ctx->cipher.ac_block[AESICM_BLOCKSIZE - 4], 4);
  155. ctx->cipher.ac_block[AESICM_BLOCKSIZE - 1] = 2;
  156. AES_GMAC_Reinit(&ctx->gmac, iv, ivlen);
  157. }
  158. static void
  159. aes_ccm_reinit(void *vctx, const uint8_t *iv, size_t ivlen)
  160. {
  161. struct aes_ccm_ctx *ctx = vctx;
  162. KASSERT(ivlen >= 7 && ivlen <= 13,
  163. ("%s: invalid IV length", __func__));
  164. /* CCM has flags, then the IV, then the counter, which starts at 1 */
  165. bzero(ctx->cipher.ac_block, sizeof(ctx->cipher.ac_block));
  166. ctx->cipher.ac_block[0] = (15 - ivlen) - 1;
  167. bcopy(iv, ctx->cipher.ac_block + 1, ivlen);
  168. ctx->cipher.ac_block[AESICM_BLOCKSIZE - 1] = 1;
  169. AES_CBC_MAC_Reinit(&ctx->cbc_mac, iv, ivlen);
  170. }
  171. static void
  172. aes_icm_crypt(void *key, const uint8_t *in, uint8_t *out)
  173. {
  174. struct aes_icm_ctx *ctx;
  175. int i;
  176. ctx = key;
  177. aes_icm_crypt_last(key, in, out, AESICM_BLOCKSIZE);
  178. /* increment counter */
  179. for (i = AESICM_BLOCKSIZE - 1;
  180. i >= 0; i--)
  181. if (++ctx->ac_block[i]) /* continue on overflow */
  182. break;
  183. }
  184. static void
  185. aes_icm_crypt_multi(void *key, const uint8_t *in, uint8_t *out, size_t len)
  186. {
  187. struct aes_icm_ctx *ctx = key;
  188. uint8_t keystream[AESICM_BLOCKSIZE];
  189. int i;
  190. KASSERT(len % AESICM_BLOCKSIZE == 0, ("%s: invalid length", __func__));
  191. while (len > 0) {
  192. rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
  193. for (i = 0; i < AESICM_BLOCKSIZE; i++)
  194. out[i] = in[i] ^ keystream[i];
  195. /* increment counter */
  196. for (i = AESICM_BLOCKSIZE - 1; i >= 0; i--)
  197. if (++ctx->ac_block[i]) /* continue on overflow */
  198. break;
  199. out += AESICM_BLOCKSIZE;
  200. in += AESICM_BLOCKSIZE;
  201. len -= AESICM_BLOCKSIZE;
  202. }
  203. explicit_bzero(keystream, sizeof(keystream));
  204. }
  205. static void
  206. aes_icm_crypt_last(void *key, const uint8_t *in, uint8_t *out, size_t len)
  207. {
  208. struct aes_icm_ctx *ctx;
  209. uint8_t keystream[AESICM_BLOCKSIZE];
  210. int i;
  211. ctx = key;
  212. rijndaelEncrypt(ctx->ac_ek, ctx->ac_nr, ctx->ac_block, keystream);
  213. for (i = 0; i < len; i++)
  214. out[i] = in[i] ^ keystream[i];
  215. explicit_bzero(keystream, sizeof(keystream));
  216. }
  217. static int
  218. aes_icm_setkey(void *sched, const uint8_t *key, int len)
  219. {
  220. struct aes_icm_ctx *ctx;
  221. if (len != 16 && len != 24 && len != 32)
  222. return (EINVAL);
  223. ctx = sched;
  224. ctx->ac_nr = rijndaelKeySetupEnc(ctx->ac_ek, key, len * 8);
  225. return (0);
  226. }
  227. static int
  228. aes_gcm_setkey(void *vctx, const uint8_t *key, int len)
  229. {
  230. struct aes_gcm_ctx *ctx = vctx;
  231. int error;
  232. error = aes_icm_setkey(&ctx->cipher, key, len);
  233. if (error != 0)
  234. return (error);
  235. AES_GMAC_Setkey(&ctx->gmac, key, len);
  236. return (0);
  237. }
  238. static int
  239. aes_ccm_setkey(void *vctx, const uint8_t *key, int len)
  240. {
  241. struct aes_ccm_ctx *ctx = vctx;
  242. int error;
  243. error = aes_icm_setkey(&ctx->cipher, key, len);
  244. if (error != 0)
  245. return (error);
  246. AES_CBC_MAC_Setkey(&ctx->cbc_mac, key, len);
  247. return (0);
  248. }
  249. static int
  250. aes_gcm_update(void *vctx, const void *buf, u_int len)
  251. {
  252. struct aes_gcm_ctx *ctx = vctx;
  253. return (AES_GMAC_Update(&ctx->gmac, buf, len));
  254. }
  255. static int
  256. aes_ccm_update(void *vctx, const void *buf, u_int len)
  257. {
  258. struct aes_ccm_ctx *ctx = vctx;
  259. return (AES_CBC_MAC_Update(&ctx->cbc_mac, buf, len));
  260. }
  261. static void
  262. aes_gcm_final(uint8_t *tag, void *vctx)
  263. {
  264. struct aes_gcm_ctx *ctx = vctx;
  265. AES_GMAC_Final(tag, &ctx->gmac);
  266. }
  267. static void
  268. aes_ccm_final(uint8_t *tag, void *vctx)
  269. {
  270. struct aes_ccm_ctx *ctx = vctx;
  271. AES_CBC_MAC_Final(tag, &ctx->cbc_mac);
  272. }