lws-genaes.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. /*
  2. * libwebsockets - small server side websockets and web server implementation
  3. *
  4. * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to
  8. * deal in the Software without restriction, including without limitation the
  9. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10. * sell copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22. * IN THE SOFTWARE.
  23. *
  24. * lws_genaes provides an abstraction api for AES in lws that works the
  25. * same whether you are using openssl or mbedtls hash functions underneath.
  26. */
  27. #include "private-lib-core.h"
  28. #if defined(LWS_WITH_JOSE)
  29. #include "private-lib-jose.h"
  30. #endif
  31. static int operation_map[] = { MBEDTLS_AES_ENCRYPT, MBEDTLS_AES_DECRYPT };
  32. static unsigned int
  33. _write_pkcs7_pad(uint8_t *p, int len)
  34. {
  35. unsigned int n = 0, padlen = LWS_AES_CBC_BLOCKLEN * (len /
  36. LWS_AES_CBC_BLOCKLEN + 1) - len;
  37. p += len;
  38. while (n++ < padlen)
  39. *p++ = (uint8_t)padlen;
  40. return padlen;
  41. }
  42. int
  43. lws_genaes_create(struct lws_genaes_ctx *ctx, enum enum_aes_operation op,
  44. enum enum_aes_modes mode, struct lws_gencrypto_keyelem *el,
  45. enum enum_aes_padding padding, void *engine)
  46. {
  47. int n = 0;
  48. ctx->mode = mode;
  49. ctx->k = el;
  50. ctx->op = operation_map[op];
  51. ctx->underway = 0;
  52. ctx->padding = padding == LWS_GAESP_WITH_PADDING;
  53. switch (ctx->mode) {
  54. case LWS_GAESM_XTS:
  55. #if defined(MBEDTLS_CIPHER_MODE_XTS)
  56. mbedtls_aes_xts_init(&ctx->u.ctx_xts);
  57. break;
  58. #else
  59. return -1;
  60. #endif
  61. case LWS_GAESM_GCM:
  62. mbedtls_gcm_init(&ctx->u.ctx_gcm);
  63. n = mbedtls_gcm_setkey(&ctx->u.ctx_gcm, MBEDTLS_CIPHER_ID_AES,
  64. ctx->k->buf, ctx->k->len * 8);
  65. if (n) {
  66. lwsl_notice("%s: mbedtls_gcm_setkey: -0x%x\n",
  67. __func__, -n);
  68. return n;
  69. }
  70. return n;
  71. default:
  72. mbedtls_aes_init(&ctx->u.ctx);
  73. break;
  74. }
  75. switch (op) {
  76. case LWS_GAESO_ENC:
  77. if (ctx->mode == LWS_GAESM_XTS)
  78. #if defined(MBEDTLS_CIPHER_MODE_XTS)
  79. n = mbedtls_aes_xts_setkey_enc(&ctx->u.ctx_xts,
  80. ctx->k->buf,
  81. ctx->k->len * 8);
  82. #else
  83. return -1;
  84. #endif
  85. else
  86. n = mbedtls_aes_setkey_enc(&ctx->u.ctx, ctx->k->buf,
  87. ctx->k->len * 8);
  88. break;
  89. case LWS_GAESO_DEC:
  90. switch (ctx->mode) {
  91. case LWS_GAESM_XTS:
  92. #if defined(MBEDTLS_CIPHER_MODE_XTS)
  93. n = mbedtls_aes_xts_setkey_dec(&ctx->u.ctx_xts,
  94. ctx->k->buf,
  95. ctx->k->len * 8);
  96. break;
  97. #else
  98. return -1;
  99. #endif
  100. case LWS_GAESM_CFB128:
  101. case LWS_GAESM_CFB8:
  102. case LWS_GAESM_CTR:
  103. case LWS_GAESM_OFB:
  104. n = mbedtls_aes_setkey_enc(&ctx->u.ctx, ctx->k->buf,
  105. ctx->k->len * 8);
  106. break;
  107. default:
  108. n = mbedtls_aes_setkey_dec(&ctx->u.ctx, ctx->k->buf,
  109. ctx->k->len * 8);
  110. break;
  111. }
  112. break;
  113. }
  114. if (n)
  115. lwsl_notice("%s: setting key: -0x%x\n", __func__, -n);
  116. return n;
  117. }
  118. int
  119. lws_genaes_destroy(struct lws_genaes_ctx *ctx, unsigned char *tag, size_t tlen)
  120. {
  121. int n;
  122. if (ctx->mode == LWS_GAESM_GCM) {
  123. n = mbedtls_gcm_finish(&ctx->u.ctx_gcm, tag, tlen);
  124. if (n)
  125. lwsl_notice("%s: mbedtls_gcm_finish: -0x%x\n",
  126. __func__, -n);
  127. if (tag && ctx->op == MBEDTLS_AES_DECRYPT && !n) {
  128. if (lws_timingsafe_bcmp(ctx->tag, tag, ctx->taglen)) {
  129. lwsl_err("%s: lws_genaes_crypt tag "
  130. "mismatch (bad first)\n",
  131. __func__);
  132. lwsl_hexdump_notice(tag, tlen);
  133. lwsl_hexdump_notice(ctx->tag, ctx->taglen);
  134. n = -1;
  135. }
  136. }
  137. mbedtls_gcm_free(&ctx->u.ctx_gcm);
  138. return n;
  139. }
  140. if (ctx->mode == LWS_GAESM_XTS)
  141. #if defined(MBEDTLS_CIPHER_MODE_XTS)
  142. mbedtls_aes_xts_free(&ctx->u.ctx_xts);
  143. #else
  144. return -1;
  145. #endif
  146. else
  147. mbedtls_aes_free(&ctx->u.ctx);
  148. return 0;
  149. }
  150. #if defined(LWS_HAVE_mbedtls_internal_aes_encrypt)
  151. static int
  152. lws_genaes_rfc3394_wrap(int wrap, int cek_bits, const uint8_t *kek,
  153. int kek_bits, const uint8_t *in, uint8_t *out)
  154. {
  155. int n, m, ret = -1, c64 = cek_bits / 64;
  156. mbedtls_aes_context ctx;
  157. uint8_t a[8], b[16];
  158. /*
  159. * notice the KEK key used to perform the wrapping or unwrapping is
  160. * always the size of the AES key used, eg, A128KW == 128 bits. The
  161. * key being wrapped or unwrapped may be larger and is set by the
  162. * 'bits' parameter.
  163. *
  164. * If it's larger than the KEK key size bits, we iterate over it
  165. */
  166. mbedtls_aes_init(&ctx);
  167. if (wrap) {
  168. /*
  169. * The inputs to the key wrapping process are the KEK and the
  170. * plaintext to be wrapped. The plaintext consists of n 64-bit
  171. * blocks, containing the key data being wrapped.
  172. *
  173. * Inputs: Plaintext, n 64-bit values {P1, P2, ..., Pn},
  174. * and Key, K (the KEK).
  175. * Outputs: Ciphertext, (n+1) 64-bit values
  176. * {C0, C1, ..., Cn}.
  177. *
  178. * The default initial value (IV) is defined to be the
  179. * hexadecimal constant:
  180. *
  181. * A[0] = IV = A6A6A6A6A6A6A6A6
  182. */
  183. memset(out, 0xa6, 8);
  184. memcpy(out + 8, in, 8 * c64);
  185. n = mbedtls_aes_setkey_enc(&ctx, kek, kek_bits);
  186. } else {
  187. /*
  188. * 2.2.2 Key Unwrap
  189. *
  190. * The inputs to the unwrap process are the KEK and (n+1)
  191. * 64-bit blocks of ciphertext consisting of previously
  192. * wrapped key. It returns n blocks of plaintext consisting
  193. * of the n 64-bit blocks of the decrypted key data.
  194. *
  195. * Inputs: Ciphertext, (n+1) 64-bit values {C0, C1, ..., Cn},
  196. * and Key, K (the KEK).
  197. *
  198. * Outputs: Plaintext, n 64-bit values {P1, P2, ..., Pn}.
  199. */
  200. memcpy(a, in, 8);
  201. memcpy(out, in + 8, 8 * c64);
  202. n = mbedtls_aes_setkey_dec(&ctx, kek, kek_bits);
  203. }
  204. if (n < 0) {
  205. lwsl_err("%s: setkey failed\n", __func__);
  206. goto bail;
  207. }
  208. if (wrap) {
  209. for (n = 0; n <= 5; n++) {
  210. uint8_t *r = out + 8;
  211. for (m = 1; m <= c64; m++) {
  212. memcpy(b, out, 8);
  213. memcpy(b + 8, r, 8);
  214. if (mbedtls_internal_aes_encrypt(&ctx, b, b))
  215. goto bail;
  216. memcpy(out, b, 8);
  217. out[7] ^= c64 * n + m;
  218. memcpy(r, b + 8, 8);
  219. r += 8;
  220. }
  221. }
  222. ret = 0;
  223. } else {
  224. /*
  225. *
  226. */
  227. for (n = 5; n >= 0; n--) {
  228. uint8_t *r = out + (c64 - 1) * 8;
  229. for (m = c64; m >= 1; m--) {
  230. memcpy(b, a, 8);
  231. b[7] ^= c64 * n + m;
  232. memcpy(b + 8, r, 8);
  233. if (mbedtls_internal_aes_decrypt(&ctx, b, b))
  234. goto bail;
  235. memcpy(a, b, 8);
  236. memcpy(r, b + 8, 8);
  237. r -= 8;
  238. }
  239. }
  240. ret = 0;
  241. for (n = 0; n < 8; n++)
  242. if (a[n] != 0xa6)
  243. ret = -1;
  244. }
  245. bail:
  246. if (ret)
  247. lwsl_notice("%s: failed\n", __func__);
  248. mbedtls_aes_free(&ctx);
  249. return ret;
  250. }
  251. #endif
  252. int
  253. lws_genaes_crypt(struct lws_genaes_ctx *ctx, const uint8_t *in, size_t len,
  254. uint8_t *out, uint8_t *iv_or_nonce_ctr_or_data_unit_16,
  255. uint8_t *stream_block_16, size_t *nc_or_iv_off, int taglen)
  256. {
  257. uint8_t iv[LWS_JWE_AES_IV_BYTES], sb[16];
  258. int n = 0;
  259. switch (ctx->mode) {
  260. case LWS_GAESM_KW:
  261. #if defined(LWS_HAVE_mbedtls_internal_aes_encrypt)
  262. /* a key of length ctx->k->len is wrapped by a 128-bit KEK */
  263. n = lws_genaes_rfc3394_wrap(ctx->op == MBEDTLS_AES_ENCRYPT,
  264. ctx->op == MBEDTLS_AES_ENCRYPT ? len * 8 :
  265. (len - 8) * 8, ctx->k->buf,
  266. ctx->k->len * 8,
  267. in, out);
  268. break;
  269. #else
  270. lwsl_err("%s: your mbedtls is too old\n", __func__);
  271. return -1;
  272. #endif
  273. case LWS_GAESM_CBC:
  274. memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
  275. /*
  276. * If encrypting, we do the PKCS#7 padding.
  277. * During decryption, the caller will need to unpad.
  278. */
  279. if (ctx->padding && ctx->op == MBEDTLS_AES_ENCRYPT) {
  280. /*
  281. * Since we don't want to burden the caller with
  282. * the over-allocation at the end of the input,
  283. * we have to allocate a temp with space for it
  284. */
  285. uint8_t *padin = (uint8_t *)lws_malloc(
  286. lws_gencrypto_padded_length(LWS_AES_CBC_BLOCKLEN, len),
  287. __func__);
  288. if (!padin)
  289. return -1;
  290. memcpy(padin, in, len);
  291. len += _write_pkcs7_pad((uint8_t *)padin, len);
  292. n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, ctx->op, len, iv,
  293. padin, out);
  294. lws_free(padin);
  295. } else
  296. n = mbedtls_aes_crypt_cbc(&ctx->u.ctx, ctx->op, len, iv,
  297. in, out);
  298. break;
  299. case LWS_GAESM_CFB128:
  300. memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
  301. n = mbedtls_aes_crypt_cfb128(&ctx->u.ctx, ctx->op, len,
  302. nc_or_iv_off, iv, in, out);
  303. break;
  304. case LWS_GAESM_CFB8:
  305. memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
  306. n = mbedtls_aes_crypt_cfb8(&ctx->u.ctx, ctx->op, len, iv,
  307. in, out);
  308. break;
  309. case LWS_GAESM_CTR:
  310. memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
  311. memcpy(sb, stream_block_16, 16);
  312. n = mbedtls_aes_crypt_ctr(&ctx->u.ctx, len, nc_or_iv_off,
  313. iv, sb, in, out);
  314. memcpy(iv_or_nonce_ctr_or_data_unit_16, iv, 16);
  315. memcpy(stream_block_16, sb, 16);
  316. break;
  317. case LWS_GAESM_ECB:
  318. n = mbedtls_aes_crypt_ecb(&ctx->u.ctx, ctx->op, in, out);
  319. break;
  320. case LWS_GAESM_OFB:
  321. #if defined(MBEDTLS_CIPHER_MODE_OFB)
  322. memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
  323. n = mbedtls_aes_crypt_ofb(&ctx->u.ctx, len, nc_or_iv_off, iv,
  324. in, out);
  325. break;
  326. #else
  327. return -1;
  328. #endif
  329. case LWS_GAESM_XTS:
  330. #if defined(MBEDTLS_CIPHER_MODE_XTS)
  331. memcpy(iv, iv_or_nonce_ctr_or_data_unit_16, 16);
  332. n = mbedtls_aes_crypt_xts(&ctx->u.ctx_xts, ctx->op, len, iv,
  333. in, out);
  334. break;
  335. #else
  336. return -1;
  337. #endif
  338. case LWS_GAESM_GCM:
  339. if (!ctx->underway) {
  340. ctx->underway = 1;
  341. memcpy(ctx->tag, stream_block_16, taglen);
  342. ctx->taglen = taglen;
  343. /*
  344. * iv: iv_or_nonce_ctr_or_data_unit_16
  345. * iv_len: *nc_or_iv_off
  346. * stream_block_16: pointer to tag
  347. * additional data: in
  348. * additional data len: len
  349. */
  350. n = mbedtls_gcm_starts(&ctx->u.ctx_gcm, ctx->op,
  351. iv_or_nonce_ctr_or_data_unit_16,
  352. *nc_or_iv_off, in, len);
  353. if (n) {
  354. lwsl_notice("%s: mbedtls_gcm_starts: -0x%x\n",
  355. __func__, -n);
  356. return -1;
  357. }
  358. break;
  359. }
  360. n = mbedtls_gcm_update(&ctx->u.ctx_gcm, len, in, out);
  361. if (n) {
  362. lwsl_notice("%s: mbedtls_gcm_update: -0x%x\n",
  363. __func__, -n);
  364. return -1;
  365. }
  366. break;
  367. }
  368. if (n) {
  369. lwsl_notice("%s: failed: -0x%x, len %d\n", __func__, -n, (int)len);
  370. return -1;
  371. }
  372. return 0;
  373. }