ptlsbcrypt.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. /*
  2. * Copyright (c) 2016 DeNA Co., Ltd., Kazuho Oku
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to
  6. * deal in the Software without restriction, including without limitation the
  7. * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. * sell copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. * IN THE SOFTWARE.
  21. */
  22. #ifndef _WINDOWS
  23. /* This module is only defined for windows.
  24. * It is an implementation of the main crypto algorithms
  25. * using windows crypto libraries */
  26. int ptls_bcrypt_init()
  27. {
  28. return -1;
  29. }
  30. void ptlc_bcrypt_dispose()
  31. {
  32. }
  33. #else
  34. #include "wincompat.h"
  35. #include <bcrypt.h>
  36. #include "picotls.h"
  37. /**
  38. * Initialize the brcrypt libraries, creates the
  39. * required common variables, etc. */
  40. int ptls_bcrypt_init()
  41. {
  42. return 0;
  43. }
  44. /**
  45. * Clear the initialization of the bcrypt libraries */
  46. void ptlc_bcrypt_dispose()
  47. {
  48. }
  49. /**
  50. * Random number generation */
  51. void ptls_bcrypt_random_bytes(void *buf, size_t len)
  52. {
  53. /* TODO: Crypto gen random */
  54. }
  55. /*
  56. * Support for symmetric ciphers
  57. */
  58. struct ptls_bcrypt_symmetric_param_t {
  59. HANDLE hKey;
  60. DWORD dwFlags;
  61. ULONG cbKeyObject;
  62. uint8_t iv[PTLS_MAX_IV_SIZE];
  63. uint8_t *key_object;
  64. int is_enc;
  65. };
  66. struct ptls_bcrypt_symmetric_context_t {
  67. ptls_cipher_context_t super;
  68. struct ptls_bcrypt_symmetric_param_t bctx;
  69. };
  70. static void ptls_bcrypt_cipher_init_ctr(ptls_cipher_context_t *_ctx, const void *iv)
  71. {
  72. struct ptls_bcrypt_symmetric_context_t *ctx = (struct ptls_bcrypt_symmetric_context_t *)_ctx;
  73. /* Copy the IV to inside structure */
  74. if (iv != NULL) {
  75. memcpy(ctx->bctx.iv, iv, ctx->super.algo->block_size);
  76. } else {
  77. memset(ctx->bctx.iv, 0, ctx->super.algo->block_size);
  78. }
  79. }
  80. static void ptls_bcrypt_cipher_dispose(ptls_cipher_context_t *_ctx)
  81. {
  82. struct ptls_bcrypt_symmetric_context_t *ctx = (struct ptls_bcrypt_symmetric_context_t *)_ctx;
  83. if (ctx->bctx.hKey != NULL) {
  84. (void)BCryptDestroyKey(ctx->bctx.hKey);
  85. }
  86. if (ctx->bctx.key_object != NULL) {
  87. free(ctx->bctx.key_object);
  88. }
  89. memset(&ctx->bctx, 0, sizeof(struct ptls_bcrypt_symmetric_param_t));
  90. }
  91. static void ptls_bcrypt_cipher_transform_ecb(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len)
  92. {
  93. struct ptls_bcrypt_symmetric_context_t *ctx = (struct ptls_bcrypt_symmetric_context_t *)_ctx;
  94. ULONG cbResult;
  95. NTSTATUS ret;
  96. assert((len % ctx->super.algo->block_size) == 0);
  97. /* Call the encryption */
  98. if (ctx->bctx.is_enc) {
  99. ret = BCryptEncrypt(ctx->bctx.hKey, (PUCHAR)input, (ULONG)len, NULL, NULL, 0, output, (ULONG)len, &cbResult, 0);
  100. } else {
  101. ret = BCryptDecrypt(ctx->bctx.hKey, (PUCHAR)input, (ULONG)len, NULL, NULL, 0, output, (ULONG)len, &cbResult, 0);
  102. }
  103. assert(BCRYPT_SUCCESS(ret));
  104. if (!BCRYPT_SUCCESS(ret)) {
  105. memset(output, 0, cbResult);
  106. }
  107. }
  108. static void ptls_bcrypt_cipher_transform_ctr(ptls_cipher_context_t *_ctx, void *output, const void *input, size_t len)
  109. {
  110. struct ptls_bcrypt_symmetric_context_t *ctx = (struct ptls_bcrypt_symmetric_context_t *)_ctx;
  111. ULONG cbResult;
  112. NTSTATUS ret;
  113. uint8_t eiv[PTLS_MAX_IV_SIZE];
  114. size_t i;
  115. uint64_t seq = 0;
  116. size_t processed = 0;
  117. uint8_t const *v_in = input;
  118. uint8_t *v_out = output;
  119. assert(ctx->super.algo->block_size > 0);
  120. assert(ctx->super.algo->block_size <= PTLS_MAX_IV_SIZE);
  121. while (processed < len) {
  122. ret = BCryptEncrypt(ctx->bctx.hKey, (PUCHAR)ctx->bctx.iv, (ULONG)ctx->super.algo->block_size, NULL, NULL, 0, eiv,
  123. (ULONG)(ULONG)ctx->super.algo->block_size, &cbResult, 0);
  124. assert(BCRYPT_SUCCESS(ret));
  125. if (BCRYPT_SUCCESS(ret)) {
  126. for (i = 0; processed < len && i < ctx->super.algo->block_size; i++, processed++) {
  127. v_out[processed] = v_in[processed] ^ eiv[i];
  128. }
  129. /* Increment the iv block */
  130. i = (int)ctx->super.algo->block_size - 1;
  131. while (i >= 0) {
  132. ctx->bctx.iv[i] += 1;
  133. if (ctx->bctx.iv[i] > 0) {
  134. break;
  135. }
  136. i--;
  137. }
  138. }
  139. }
  140. }
  141. static int ptls_bcrypt_cipher_setup_crypto(ptls_cipher_context_t *_ctx, int is_enc, const void *key, wchar_t const *bcrypt_name,
  142. int is_ctr)
  143. {
  144. struct ptls_bcrypt_symmetric_context_t *ctx = (struct ptls_bcrypt_symmetric_context_t *)_ctx;
  145. HANDLE hAlgorithm = NULL;
  146. NTSTATUS ret;
  147. memset(&ctx->bctx, 0, sizeof(struct ptls_bcrypt_symmetric_param_t));
  148. ret = BCryptOpenAlgorithmProvider(&hAlgorithm, bcrypt_name, NULL, 0);
  149. if (BCRYPT_SUCCESS(ret)) {
  150. DWORD ko_size = 0;
  151. ULONG cbResult = 0;
  152. ret = BCryptGetProperty(hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&ko_size, (ULONG)sizeof(ko_size), &cbResult, 0);
  153. if (BCRYPT_SUCCESS(ret)) {
  154. ctx->bctx.key_object = (uint8_t *)malloc(ko_size);
  155. if (ctx->bctx.key_object == NULL) {
  156. ret = STATUS_NO_MEMORY;
  157. } else {
  158. ctx->bctx.cbKeyObject = ko_size;
  159. }
  160. }
  161. }
  162. if (BCRYPT_SUCCESS(ret)) {
  163. ret = BCryptSetProperty(hAlgorithm, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_ECB, sizeof(BCRYPT_CHAIN_MODE_ECB), 0);
  164. }
  165. if (BCRYPT_SUCCESS(ret)) {
  166. ret = BCryptGenerateSymmetricKey(hAlgorithm, &ctx->bctx.hKey, ctx->bctx.key_object, ctx->bctx.cbKeyObject, (PUCHAR)key,
  167. (ULONG)ctx->super.algo->key_size, 0);
  168. }
  169. if (hAlgorithm != NULL) {
  170. BCryptCloseAlgorithmProvider(hAlgorithm, 0);
  171. }
  172. if (BCRYPT_SUCCESS(ret)) {
  173. ctx->super.do_dispose = ptls_bcrypt_cipher_dispose;
  174. if (is_ctr) {
  175. ctx->super.do_init = ptls_bcrypt_cipher_init_ctr;
  176. ctx->super.do_transform = ptls_bcrypt_cipher_transform_ctr;
  177. } else {
  178. ctx->super.do_init = NULL;
  179. ctx->super.do_transform = ptls_bcrypt_cipher_transform_ecb;
  180. }
  181. ctx->bctx.is_enc = is_enc;
  182. return 0;
  183. } else {
  184. ptls_bcrypt_cipher_dispose(_ctx);
  185. return PTLS_ERROR_LIBRARY;
  186. }
  187. }
  188. static int ptls_bcrypt_cipher_setup_crypto_aes_ecb(ptls_cipher_context_t *_ctx, int is_enc, const void *key)
  189. {
  190. return ptls_bcrypt_cipher_setup_crypto(_ctx, is_enc, key, BCRYPT_AES_ALGORITHM, 0);
  191. }
  192. static int ptls_bcrypt_cipher_setup_crypto_aes_ctr(ptls_cipher_context_t *_ctx, int is_enc, const void *key)
  193. {
  194. return ptls_bcrypt_cipher_setup_crypto(_ctx, is_enc, key, BCRYPT_AES_ALGORITHM, 1);
  195. }
  196. /* Picotls assumes that AEAD encryption works as:
  197. * - an "init" call that prepares the encryption context.
  198. * - a series of "update" calls that encrypt segments of the message
  199. * - a "final" call that completes the encryption.
  200. *
  201. * In Bcrypt, the update calls will be implemented as a series of calls
  202. * to BCryptEncrypt. The state necessary to pass these calls is provided
  203. * to the Bcrypt function in two parameters:
  204. * - the "padding info" points to a BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO
  205. * structure
  206. * - the "IV" parameter points to a buffer holding intermediate updates
  207. * of the IV. That buffer shall be initialize to zero before the
  208. * first call.
  209. * The documentation of the AEAD mode on MSDN is slightly obscure, and
  210. * also slightly wrong. After trial and errors and web searches, we find
  211. * that:
  212. * - the Nonce parameter (pbNonce, cbNonce) points to the initial
  213. * vector for the encryption, as passed by Picotls. Picotls combines
  214. * per session IV and sequence number in that nonce prior to the call.
  215. * - The Authdata parameter (pbAuthData, cbAuthData) points to the
  216. * authenticated data passed to the API as aad, aadlen.
  217. * - The cbAAd parameter contains the length of auth data that needs
  218. * to be processed. It is initialized before the first call.
  219. * - The tag parameter (pbTag, cbTag) points to a buffer that
  220. * holds intermediate tag values during chaining. The size must be
  221. * the size of the tag for the algorithm. It must be
  222. * initialized to zero before first call.
  223. * - The Mac Context parameter (pbMacContext, cbMacContext) contains
  224. * a working buffer for the computation of the tag. The size
  225. * must be the maxLength parameter returned retrieved in the
  226. * BCRYPT_AUTH_TAG_LENGTH property of the algorithm. It must be
  227. * initialized to zero before first call.
  228. * - The dwflag parameters must be set to
  229. * BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG on first call. (The
  230. * MSDN documentation says BCRYPT_AUTH_MODE_IN_PROGRESS_FLAG,
  231. * but that's an error.)
  232. *
  233. * The members of the BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO struct
  234. * should not be modified between calls, except for:
  235. * - the BCRYPT_AUTH_MODE_IN_PROGRESS_FLAG should be cleared
  236. * before the final call.
  237. *
  238. * The Picotls API does not constrain the length of the segments
  239. * passed in the "update" calls, but BCryptEncrypt will fail with
  240. * error STATUS_INVALID_BUFFER_SIZE if the length passed in the
  241. * chained calls is not an integer multiple of block size. This forces
  242. * us to maintain an intermediate buffer of "extra bytes".
  243. *
  244. */
  245. struct ptls_bcrypt_aead_param_t {
  246. HANDLE hKey;
  247. ULONG cbKeyObject;
  248. ULONG maxTagLength;
  249. ULONG nbExtraBytes;
  250. uint8_t *key_object;
  251. uint8_t iv_static[PTLS_MAX_IV_SIZE];
  252. uint8_t extraBytes[PTLS_MAX_DIGEST_SIZE];
  253. uint8_t iv[PTLS_MAX_IV_SIZE];
  254. uint8_t ivbuf[PTLS_MAX_IV_SIZE];
  255. uint8_t tag[PTLS_MAX_DIGEST_SIZE];
  256. uint8_t auth_tag[PTLS_MAX_DIGEST_SIZE];
  257. BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO aead_params;
  258. };
  259. struct ptls_bcrypt_aead_context_t {
  260. struct st_ptls_aead_context_t super;
  261. struct ptls_bcrypt_aead_param_t bctx;
  262. };
  263. static void ptls_bcrypt_aead_dispose_crypto(struct st_ptls_aead_context_t *_ctx)
  264. {
  265. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  266. if (ctx->bctx.hKey != NULL) {
  267. (void)BCryptDestroyKey(ctx->bctx.hKey);
  268. }
  269. if (ctx->bctx.key_object != NULL) {
  270. free(ctx->bctx.key_object);
  271. }
  272. memset(&ctx->bctx, 0, sizeof(struct ptls_bcrypt_aead_param_t));
  273. }
  274. static void ptls_bcrypt_aead_do_encrypt_init(struct st_ptls_aead_context_t *_ctx, uint64_t seq, const void *aad, size_t aadlen)
  275. {
  276. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  277. /* Build the IV for this encryption */
  278. ptls_aead__build_iv(ctx->super.algo, ctx->bctx.iv, ctx->bctx.iv_static, seq);
  279. /* Auth tag to NULL */
  280. memset(ctx->bctx.tag, 0, sizeof(ctx->super.algo->tag_size));
  281. BCRYPT_INIT_AUTH_MODE_INFO(ctx->bctx.aead_params);
  282. assert(ctx->super.algo->iv_size <= sizeof(ctx->bctx.ivbuf));
  283. assert(ctx->super.algo->tag_size <= sizeof(ctx->bctx.tag));
  284. assert(ctx->bctx.maxTagLength <= sizeof(ctx->bctx.auth_tag));
  285. memset(ctx->bctx.ivbuf, 0, ctx->super.algo->iv_size);
  286. memset(ctx->bctx.tag, 0, ctx->super.algo->tag_size);
  287. memset(ctx->bctx.auth_tag, 0, sizeof(ctx->bctx.auth_tag));
  288. ctx->bctx.nbExtraBytes = 0;
  289. ctx->bctx.aead_params.pbNonce = (PUCHAR)&ctx->bctx.iv;
  290. ctx->bctx.aead_params.cbNonce = (ULONG)ctx->super.algo->iv_size;
  291. ctx->bctx.aead_params.pbAuthData = (PUCHAR)aad;
  292. ctx->bctx.aead_params.cbAuthData = (ULONG)aadlen;
  293. ctx->bctx.aead_params.pbTag = (PUCHAR)ctx->bctx.tag;
  294. ctx->bctx.aead_params.cbTag = (ULONG)ctx->super.algo->tag_size;
  295. // ctx->bctx.aead_params.cbAAD = (ULONG)aadlen;
  296. ctx->bctx.aead_params.pbMacContext = (PUCHAR)ctx->bctx.auth_tag;
  297. ctx->bctx.aead_params.cbMacContext = (ULONG)ctx->bctx.maxTagLength;
  298. ctx->bctx.aead_params.dwFlags = BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG;
  299. }
  300. static size_t ptls_bcrypt_aead_do_encrypt_update(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen)
  301. {
  302. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  303. size_t outlenMax = inlen + ctx->super.algo->tag_size + ctx->bctx.nbExtraBytes;
  304. ULONG cbResult1 = 0;
  305. ULONG cbResult2 = 0;
  306. NTSTATUS ret;
  307. /* If there are extra bytes, complement and encrypt */
  308. if (ctx->bctx.nbExtraBytes > 0) {
  309. ULONG requiredBytes = (ULONG)(ctx->super.algo->ecb_cipher->block_size - ctx->bctx.nbExtraBytes);
  310. if (inlen < requiredBytes) {
  311. memcpy(&ctx->bctx.extraBytes[ctx->bctx.nbExtraBytes], input, inlen);
  312. ctx->bctx.nbExtraBytes += (ULONG)inlen;
  313. inlen = 0;
  314. } else {
  315. memcpy(&ctx->bctx.extraBytes[ctx->bctx.nbExtraBytes], input, requiredBytes);
  316. inlen -= requiredBytes;
  317. input = (void *)(((uint8_t *)input) + requiredBytes);
  318. ret = BCryptEncrypt(ctx->bctx.hKey, (PUCHAR)ctx->bctx.extraBytes, (ULONG)ctx->super.algo->ecb_cipher->block_size,
  319. (void *)&ctx->bctx.aead_params, ctx->bctx.ivbuf, (ULONG)ctx->super.algo->iv_size, output,
  320. (ULONG)outlenMax, &cbResult1, 0);
  321. assert(BCRYPT_SUCCESS(ret));
  322. if (!BCRYPT_SUCCESS(ret)) {
  323. memset(output, 0, cbResult1);
  324. }
  325. outlenMax -= cbResult1;
  326. output = (void *)(((uint8_t *)output) + cbResult1);
  327. }
  328. }
  329. /* If there are trailing bytes, store them in the extra bytes */
  330. ctx->bctx.nbExtraBytes = (ULONG)(inlen % ctx->super.algo->ecb_cipher->block_size);
  331. if (ctx->bctx.nbExtraBytes > 0) {
  332. inlen -= ctx->bctx.nbExtraBytes;
  333. memcpy(&ctx->bctx.extraBytes, (void *)(((uint8_t *)input) + inlen), ctx->bctx.nbExtraBytes);
  334. }
  335. if (inlen > 0) {
  336. ret = BCryptEncrypt(ctx->bctx.hKey, (PUCHAR)input, (ULONG)inlen, (void *)&ctx->bctx.aead_params, ctx->bctx.ivbuf,
  337. (ULONG)ctx->super.algo->iv_size, output, (ULONG)outlenMax, &cbResult2, 0);
  338. assert(BCRYPT_SUCCESS(ret));
  339. if (!BCRYPT_SUCCESS(ret)) {
  340. memset(output, 0, cbResult2);
  341. }
  342. }
  343. return (size_t)cbResult1 + cbResult2;
  344. }
  345. static size_t ptls_bcrypt_aead_do_encrypt_final(struct st_ptls_aead_context_t *_ctx, void *output)
  346. {
  347. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  348. size_t outlenMax = ctx->super.algo->tag_size + ctx->bctx.nbExtraBytes;
  349. ULONG cbResult = 0;
  350. NTSTATUS ret;
  351. ctx->bctx.aead_params.dwFlags &= ~BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG;
  352. ret = BCryptEncrypt(ctx->bctx.hKey, (PUCHAR)ctx->bctx.extraBytes, (ULONG)ctx->bctx.nbExtraBytes, (void *)&ctx->bctx.aead_params,
  353. ctx->bctx.ivbuf, (ULONG)ctx->super.algo->iv_size, output, (ULONG)outlenMax, &cbResult, 0);
  354. assert(BCRYPT_SUCCESS(ret));
  355. if (BCRYPT_SUCCESS(ret)) {
  356. /* Find the tag in the aead parameters and append it to the output */
  357. assert(cbResult + ctx->bctx.aead_params.cbTag <= outlenMax);
  358. memcpy(((uint8_t *)output) + cbResult, ctx->bctx.aead_params.pbTag, ctx->bctx.aead_params.cbTag);
  359. cbResult += ctx->bctx.aead_params.cbTag;
  360. }
  361. return cbResult;
  362. }
  363. void ptls_bcrypt_do_encrypt(ptls_aead_context_t *ctx, void *output, const void *input, size_t inlen, uint64_t seq, const void *aad,
  364. size_t aadlen, ptls_aead_supplementary_encryption_t *supp)
  365. {
  366. size_t after_update;
  367. ctx->do_encrypt_init(ctx, seq, aad, aadlen);
  368. after_update = ctx->do_encrypt_update(ctx, output, input, inlen);
  369. ctx->do_encrypt_final(ctx, (uint8_t *)output + after_update);
  370. if (supp != NULL) {
  371. ptls_cipher_init(supp->ctx, supp->input);
  372. memset(supp->output, 0, sizeof(supp->output));
  373. ptls_cipher_encrypt(supp->ctx, supp->output, supp->output, sizeof(supp->output));
  374. }
  375. }
  376. static size_t ptls_bcrypt_aead_do_decrypt(struct st_ptls_aead_context_t *_ctx, void *output, const void *input, size_t inlen,
  377. uint64_t seq, const void *aad, size_t aadlen)
  378. {
  379. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  380. ULONG cbResult;
  381. size_t textLen = inlen - ctx->super.algo->tag_size;
  382. NTSTATUS ret;
  383. /* Build the IV for this decryption */
  384. ptls_aead__build_iv(ctx->super.algo, ctx->bctx.iv, ctx->bctx.iv_static, seq);
  385. /* TODO: pPaddingInfo must point to BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO structure. */
  386. BCRYPT_INIT_AUTH_MODE_INFO(ctx->bctx.aead_params);
  387. /* TODO: find clarity on handling of ivbuf */
  388. memset(ctx->bctx.tag, 0, sizeof(ctx->super.algo->tag_size));
  389. ctx->bctx.aead_params.pbNonce = (PUCHAR)&ctx->bctx.iv;
  390. ctx->bctx.aead_params.cbNonce = (ULONG)ctx->super.algo->iv_size;
  391. ctx->bctx.aead_params.pbAuthData = (PUCHAR)aad;
  392. ctx->bctx.aead_params.cbAuthData = (ULONG)aadlen;
  393. ctx->bctx.aead_params.pbTag = (PUCHAR)(((uint8_t *)input) + textLen);
  394. ctx->bctx.aead_params.cbTag = (ULONG)(ULONG)ctx->super.algo->tag_size;
  395. /* Call the decryption */
  396. ret = BCryptDecrypt(ctx->bctx.hKey, (PUCHAR)input, (ULONG)textLen, (void *)&ctx->bctx.aead_params, NULL, 0, (PUCHAR)output,
  397. (ULONG)textLen, &cbResult, 0);
  398. if (BCRYPT_SUCCESS(ret)) {
  399. return (size_t)cbResult;
  400. } else {
  401. return SIZE_MAX;
  402. }
  403. }
  404. static void ptls_bcrypt_aead_get_iv(ptls_aead_context_t *_ctx, void *iv)
  405. {
  406. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  407. memcpy(iv, ctx->bctx.iv, ctx->super.algo->iv_size);
  408. }
  409. static void ptls_bcrypt_aead_set_iv(ptls_aead_context_t *_ctx, const void *iv)
  410. {
  411. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  412. memcpy(ctx->bctx.iv, iv, ctx->super.algo->iv_size);
  413. }
  414. static int ptls_bcrypt_aead_setup_crypto(ptls_aead_context_t *_ctx, int is_enc, const void *key, const void *iv,
  415. wchar_t const *bcrypt_name, wchar_t const *bcrypt_mode, size_t bcrypt_mode_size)
  416. {
  417. struct ptls_bcrypt_aead_context_t *ctx = (struct ptls_bcrypt_aead_context_t *)_ctx;
  418. HANDLE hAlgorithm = NULL;
  419. NTSTATUS ret;
  420. memset(&ctx->bctx, 0, sizeof(struct ptls_bcrypt_symmetric_param_t));
  421. ret = BCryptOpenAlgorithmProvider(&hAlgorithm, bcrypt_name, NULL, 0);
  422. if (BCRYPT_SUCCESS(ret)) {
  423. ret = BCryptSetProperty(hAlgorithm, BCRYPT_CHAINING_MODE, (PBYTE)bcrypt_mode, (ULONG)bcrypt_mode_size, 0);
  424. }
  425. if (BCRYPT_SUCCESS(ret)) {
  426. DWORD ko_size = 0;
  427. ULONG cbResult = 0;
  428. ret = BCryptGetProperty(hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&ko_size, (ULONG)sizeof(ko_size), &cbResult, 0);
  429. if (BCRYPT_SUCCESS(ret)) {
  430. ctx->bctx.key_object = (uint8_t *)malloc(ko_size);
  431. if (ctx->bctx.key_object == NULL) {
  432. ret = STATUS_NO_MEMORY;
  433. } else {
  434. ctx->bctx.cbKeyObject = ko_size;
  435. }
  436. }
  437. }
  438. if (BCRYPT_SUCCESS(ret)) {
  439. BCRYPT_KEY_LENGTHS_STRUCT atl_st;
  440. ULONG cbResult = 0;
  441. ret = BCryptGetProperty(hAlgorithm, BCRYPT_AUTH_TAG_LENGTH, (PUCHAR)&atl_st, (ULONG)sizeof(atl_st), &cbResult, 0);
  442. if (BCRYPT_SUCCESS(ret)) {
  443. ctx->bctx.maxTagLength = atl_st.dwMaxLength;
  444. }
  445. }
  446. if (BCRYPT_SUCCESS(ret)) {
  447. ret = BCryptGenerateSymmetricKey(hAlgorithm, &ctx->bctx.hKey, ctx->bctx.key_object, ctx->bctx.cbKeyObject, (PUCHAR)key,
  448. (ULONG)ctx->super.algo->key_size, 0);
  449. }
  450. if (hAlgorithm != NULL) {
  451. BCryptCloseAlgorithmProvider(hAlgorithm, 0);
  452. }
  453. if (BCRYPT_SUCCESS(ret)) {
  454. memcpy(ctx->bctx.iv_static, iv, ctx->super.algo->iv_size);
  455. if (is_enc) {
  456. ctx->super.dispose_crypto = ptls_bcrypt_aead_dispose_crypto;
  457. ctx->super.do_get_iv = ptls_bcrypt_aead_get_iv;
  458. ctx->super.do_set_iv = ptls_bcrypt_aead_set_iv;
  459. ctx->super.do_decrypt = NULL;
  460. ctx->super.do_encrypt_init = ptls_bcrypt_aead_do_encrypt_init;
  461. ctx->super.do_encrypt_update = ptls_bcrypt_aead_do_encrypt_update;
  462. ctx->super.do_encrypt_final = ptls_bcrypt_aead_do_encrypt_final;
  463. ctx->super.do_encrypt = ptls_bcrypt_do_encrypt;
  464. ctx->super.do_encrypt_v = ptls_aead__do_encrypt_v;
  465. } else {
  466. ctx->super.dispose_crypto = ptls_bcrypt_aead_dispose_crypto;
  467. ctx->super.do_decrypt = ptls_bcrypt_aead_do_decrypt;
  468. ctx->super.do_encrypt_init = NULL;
  469. ctx->super.do_encrypt_update = NULL;
  470. ctx->super.do_encrypt_final = NULL;
  471. ctx->super.do_encrypt = NULL;
  472. ctx->super.do_encrypt_v = NULL;
  473. }
  474. return 0;
  475. } else {
  476. ptls_bcrypt_aead_dispose_crypto(_ctx);
  477. return PTLS_ERROR_LIBRARY;
  478. }
  479. }
  480. static int ptls_bcrypt_aead_setup_crypto_aesgcm(ptls_aead_context_t *_ctx, int is_enc, const void *key, const void *iv)
  481. {
  482. return ptls_bcrypt_aead_setup_crypto(_ctx, is_enc, key, iv, BCRYPT_AES_ALGORITHM, BCRYPT_CHAIN_MODE_GCM,
  483. sizeof(BCRYPT_CHAIN_MODE_GCM));
  484. }
  485. /* Hash algorithms */
  486. struct st_ptls_bcrypt_hash_param_t {
  487. wchar_t const *bcrypt_name;
  488. BCRYPT_HASH_HANDLE hHash;
  489. PUCHAR pbHashObject;
  490. ULONG cbHashObject;
  491. ULONG hash_size;
  492. int has_error;
  493. };
  494. struct st_ptls_bcrypt_hash_context_t {
  495. ptls_hash_context_t super;
  496. struct st_ptls_bcrypt_hash_param_t ctx;
  497. };
  498. static void ptls_bcrypt_hash_update(struct st_ptls_hash_context_t *_ctx, const void *src, size_t len)
  499. {
  500. struct st_ptls_bcrypt_hash_context_t *ctx = (struct st_ptls_bcrypt_hash_context_t *)_ctx;
  501. NTSTATUS ret = BCryptHashData(ctx->ctx.hHash, (PUCHAR)src, (ULONG)len, 0);
  502. assert(BCRYPT_SUCCESS(ret));
  503. if (!BCRYPT_SUCCESS(ret)) {
  504. ctx->ctx.has_error = 1;
  505. }
  506. }
  507. static struct st_ptls_bcrypt_hash_context_t *ptls_bcrypt_hash_context_free(struct st_ptls_bcrypt_hash_context_t *ctx)
  508. {
  509. if (ctx->ctx.pbHashObject != NULL) {
  510. ptls_clear_memory(ctx->ctx.pbHashObject, ctx->ctx.cbHashObject);
  511. free(ctx->ctx.pbHashObject);
  512. }
  513. ptls_clear_memory(&ctx->ctx, sizeof(ctx->ctx));
  514. return NULL;
  515. }
  516. static ptls_hash_context_t *ptls_bcrypt_hash_clone(struct st_ptls_hash_context_t *_ctx);
  517. static void ptls_bcrypt_hash_final(struct st_ptls_hash_context_t *_ctx, void *md, ptls_hash_final_mode_t mode)
  518. {
  519. if (mode == PTLS_HASH_FINAL_MODE_SNAPSHOT) {
  520. /* TODO: Copying handle does not change the handle! */
  521. struct st_ptls_hash_context_t *clone_ctx = ptls_bcrypt_hash_clone(_ctx);
  522. if (clone_ctx != NULL) {
  523. ptls_bcrypt_hash_final(clone_ctx, md, PTLS_HASH_FINAL_MODE_FREE);
  524. } else {
  525. assert(clone_ctx != NULL);
  526. }
  527. } else {
  528. NTSTATUS ret;
  529. struct st_ptls_bcrypt_hash_context_t *ctx = (struct st_ptls_bcrypt_hash_context_t *)_ctx;
  530. if (md != NULL) {
  531. ret = BCryptFinishHash(ctx->ctx.hHash, md, ctx->ctx.hash_size, 0);
  532. assert(BCRYPT_SUCCESS(ret));
  533. if (!BCRYPT_SUCCESS(ret) || ctx->ctx.has_error) {
  534. memset(md, 0, ctx->ctx.hash_size);
  535. }
  536. }
  537. ret = BCryptDestroyHash(ctx->ctx.hHash);
  538. assert(BCRYPT_SUCCESS(ret));
  539. switch (mode) {
  540. case PTLS_HASH_FINAL_MODE_FREE:
  541. ctx = ptls_bcrypt_hash_context_free(ctx);
  542. break;
  543. case PTLS_HASH_FINAL_MODE_RESET: {
  544. BCRYPT_ALG_HANDLE hAlgorithm = NULL;
  545. ret = BCryptOpenAlgorithmProvider(&hAlgorithm, ctx->ctx.bcrypt_name, NULL, 0);
  546. if (BCRYPT_SUCCESS(ret)) {
  547. ctx->ctx.hHash = NULL;
  548. ret = BCryptCreateHash(hAlgorithm, &ctx->ctx.hHash, ctx->ctx.pbHashObject, ctx->ctx.cbHashObject, NULL, 0, 0);
  549. BCryptCloseAlgorithmProvider(hAlgorithm, 0);
  550. }
  551. assert(BCRYPT_SUCCESS(ret));
  552. if (!BCRYPT_SUCCESS(ret)) {
  553. ctx->ctx.hHash = NULL;
  554. }
  555. break;
  556. }
  557. default:
  558. assert(!"FIXME");
  559. break;
  560. }
  561. }
  562. }
  563. static ptls_hash_context_t *ptls_bcrypt_hash_clone(struct st_ptls_hash_context_t *_ctx)
  564. {
  565. struct st_ptls_bcrypt_hash_context_t *ctx = (struct st_ptls_bcrypt_hash_context_t *)_ctx;
  566. struct st_ptls_bcrypt_hash_context_t *clone_ctx;
  567. if ((clone_ctx = (struct st_ptls_bcrypt_hash_context_t *)malloc(sizeof(*ctx))) != NULL) {
  568. NTSTATUS ret;
  569. ptls_clear_memory(&clone_ctx->ctx, sizeof(clone_ctx->ctx));
  570. clone_ctx->super = (ptls_hash_context_t){ptls_bcrypt_hash_update, ptls_bcrypt_hash_final, ptls_bcrypt_hash_clone};
  571. clone_ctx->ctx.pbHashObject = (uint8_t *)malloc(ctx->ctx.cbHashObject);
  572. clone_ctx->ctx.cbHashObject = ctx->ctx.cbHashObject;
  573. clone_ctx->ctx.bcrypt_name = ctx->ctx.bcrypt_name;
  574. clone_ctx->ctx.hash_size = ctx->ctx.hash_size;
  575. clone_ctx->ctx.has_error = ctx->ctx.has_error;
  576. if (clone_ctx->ctx.pbHashObject == NULL) {
  577. ret = STATUS_NO_MEMORY;
  578. } else {
  579. clone_ctx->ctx.hHash = NULL;
  580. ptls_clear_memory(&clone_ctx->ctx.pbHashObject, clone_ctx->ctx.cbHashObject);
  581. ret = BCryptDuplicateHash(ctx->ctx.hHash, &clone_ctx->ctx.hHash, clone_ctx->ctx.pbHashObject,
  582. clone_ctx->ctx.cbHashObject, 0);
  583. }
  584. if (!BCRYPT_SUCCESS(ret)) {
  585. clone_ctx = ptls_bcrypt_hash_context_free(clone_ctx);
  586. }
  587. }
  588. return (ptls_hash_context_t *)clone_ctx;
  589. }
  590. static ptls_hash_context_t *ptls_bcrypt_hash_create(wchar_t const *bcrypt_name, ULONG hash_size)
  591. {
  592. BCRYPT_ALG_HANDLE hAlgorithm = NULL;
  593. NTSTATUS ret;
  594. struct st_ptls_bcrypt_hash_context_t *ctx;
  595. if ((ctx = (struct st_ptls_bcrypt_hash_context_t *)malloc(sizeof(*ctx))) != NULL) {
  596. ctx->super = (ptls_hash_context_t){ptls_bcrypt_hash_update, ptls_bcrypt_hash_final, ptls_bcrypt_hash_clone};
  597. memset(&ctx->ctx, 0, sizeof(struct st_ptls_bcrypt_hash_param_t));
  598. ctx->ctx.hash_size = hash_size;
  599. ctx->ctx.bcrypt_name = bcrypt_name;
  600. ret = BCryptOpenAlgorithmProvider(&hAlgorithm, bcrypt_name, NULL, 0);
  601. if (BCRYPT_SUCCESS(ret)) {
  602. DWORD hb_length = 0;
  603. ULONG cbResult = 0;
  604. ret = BCryptGetProperty(hAlgorithm, BCRYPT_OBJECT_LENGTH, (PUCHAR)&hb_length, (ULONG)sizeof(hb_length), &cbResult, 0);
  605. if (BCRYPT_SUCCESS(ret)) {
  606. ctx->ctx.pbHashObject = (uint8_t *)malloc(hb_length);
  607. if (ctx->ctx.pbHashObject == NULL) {
  608. ret = STATUS_NO_MEMORY;
  609. } else {
  610. ctx->ctx.cbHashObject = hb_length;
  611. }
  612. }
  613. }
  614. if (BCRYPT_SUCCESS(ret)) {
  615. ret = BCryptCreateHash(hAlgorithm, &ctx->ctx.hHash, ctx->ctx.pbHashObject, ctx->ctx.cbHashObject, NULL, 0, 0);
  616. }
  617. if (!BCRYPT_SUCCESS(ret)) {
  618. ctx = ptls_bcrypt_hash_context_free(ctx);
  619. }
  620. }
  621. if (hAlgorithm != NULL) {
  622. BCryptCloseAlgorithmProvider(hAlgorithm, 0);
  623. }
  624. return (ptls_hash_context_t *)ctx;
  625. }
  626. static ptls_hash_context_t *ptls_bcrypt_sha256_create(void)
  627. {
  628. return ptls_bcrypt_hash_create(BCRYPT_SHA256_ALGORITHM, PTLS_SHA256_DIGEST_SIZE);
  629. }
  630. static ptls_hash_context_t *ptls_bcrypt_sha384_create(void)
  631. {
  632. return ptls_bcrypt_hash_create(BCRYPT_SHA384_ALGORITHM, PTLS_SHA384_DIGEST_SIZE);
  633. }
  634. /* Declaration of algorithms
  635. */
  636. ptls_cipher_algorithm_t ptls_bcrypt_aes128ecb = {"AES128-ECB",
  637. PTLS_AES128_KEY_SIZE,
  638. PTLS_AES_BLOCK_SIZE,
  639. 0 /* iv size */,
  640. sizeof(struct ptls_bcrypt_symmetric_context_t),
  641. ptls_bcrypt_cipher_setup_crypto_aes_ecb};
  642. ptls_cipher_algorithm_t ptls_bcrypt_aes256ecb = {"AES256-ECB",
  643. PTLS_AES256_KEY_SIZE,
  644. PTLS_AES_BLOCK_SIZE,
  645. 0 /* iv size */,
  646. sizeof(struct ptls_bcrypt_symmetric_context_t),
  647. ptls_bcrypt_cipher_setup_crypto_aes_ecb};
  648. ptls_cipher_algorithm_t ptls_bcrypt_aes128ctr = {"AES128-CTR",
  649. PTLS_AES128_KEY_SIZE,
  650. PTLS_AES_BLOCK_SIZE,
  651. 0 /* iv size */,
  652. sizeof(struct ptls_bcrypt_symmetric_context_t),
  653. ptls_bcrypt_cipher_setup_crypto_aes_ctr};
  654. ptls_cipher_algorithm_t ptls_bcrypt_aes256ctr = {"AES256-CTR",
  655. PTLS_AES256_KEY_SIZE,
  656. PTLS_AES_BLOCK_SIZE,
  657. 0 /* iv size */,
  658. sizeof(struct ptls_bcrypt_symmetric_context_t),
  659. ptls_bcrypt_cipher_setup_crypto_aes_ctr};
  660. ptls_aead_algorithm_t ptls_bcrypt_aes128gcm = {"AES128-GCM",
  661. PTLS_AESGCM_CONFIDENTIALITY_LIMIT,
  662. PTLS_AESGCM_INTEGRITY_LIMIT,
  663. &ptls_bcrypt_aes128ecb,
  664. &ptls_bcrypt_aes128ctr,
  665. PTLS_AES128_KEY_SIZE,
  666. PTLS_AESGCM_IV_SIZE,
  667. PTLS_AESGCM_TAG_SIZE,
  668. {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE},
  669. 0,
  670. 0,
  671. sizeof(struct ptls_bcrypt_aead_context_t),
  672. ptls_bcrypt_aead_setup_crypto_aesgcm};
  673. ptls_aead_algorithm_t ptls_bcrypt_aes256gcm = {"AES256-GCM",
  674. PTLS_AESGCM_CONFIDENTIALITY_LIMIT,
  675. PTLS_AESGCM_INTEGRITY_LIMIT,
  676. &ptls_bcrypt_aes256ecb,
  677. &ptls_bcrypt_aes256ctr,
  678. PTLS_AES256_KEY_SIZE,
  679. PTLS_AESGCM_IV_SIZE,
  680. PTLS_AESGCM_TAG_SIZE,
  681. {PTLS_TLS12_AESGCM_FIXED_IV_SIZE, PTLS_TLS12_AESGCM_RECORD_IV_SIZE},
  682. 0,
  683. 0,
  684. sizeof(struct ptls_bcrypt_aead_context_t),
  685. ptls_bcrypt_aead_setup_crypto_aesgcm};
  686. ptls_hash_algorithm_t ptls_bcrypt_sha256 = {"sha256", PTLS_SHA256_BLOCK_SIZE, PTLS_SHA256_DIGEST_SIZE, ptls_bcrypt_sha256_create,
  687. PTLS_ZERO_DIGEST_SHA256};
  688. ptls_hash_algorithm_t ptls_bcrypt_sha384 = {"sha384", PTLS_SHA384_BLOCK_SIZE, PTLS_SHA384_DIGEST_SIZE, ptls_bcrypt_sha384_create,
  689. PTLS_ZERO_DIGEST_SHA384};
  690. ptls_cipher_suite_t ptls_bcrypt_aes128gcmsha256 = {.id = PTLS_CIPHER_SUITE_AES_128_GCM_SHA256,
  691. .name = PTLS_CIPHER_SUITE_NAME_AES_128_GCM_SHA256,
  692. .aead = &ptls_bcrypt_aes128gcm,
  693. .hash = &ptls_bcrypt_sha256};
  694. ptls_cipher_suite_t ptls_bcrypt_aes256gcmsha384 = {.id = PTLS_CIPHER_SUITE_AES_256_GCM_SHA384,
  695. .name = PTLS_CIPHER_SUITE_NAME_AES_256_GCM_SHA384,
  696. .aead = &ptls_bcrypt_aes256gcm,
  697. .hash = &ptls_bcrypt_sha384};
  698. #ifdef PRLS_BCRYPT_TODO
  699. /* TODO: develp these bcrypt functions */
  700. ptls_key_exchange_algorithm_t ptls_bcrypt_secp256r1 = {PTLS_GROUP_SECP256R1, x9_62_create_key_exchange, secp_key_exchange,
  701. NID_X9_62_prime256v1};
  702. #if ptls_bcrypt_HAVE_SECP384R1
  703. ptls_key_exchange_algorithm_t ptls_bcrypt_secp384r1 = {PTLS_GROUP_SECP384R1, x9_62_create_key_exchange, secp_key_exchange,
  704. NID_secp384r1};
  705. #endif
  706. #if ptls_bcrypt_HAVE_SECP521R1
  707. ptls_key_exchange_algorithm_t ptls_bcrypt_secp521r1 = {PTLS_GROUP_SECP521R1, x9_62_create_key_exchange, secp_key_exchange,
  708. NID_secp521r1};
  709. #endif
  710. #if ptls_bcrypt_HAVE_X25519
  711. ptls_key_exchange_algorithm_t ptls_bcrypt_x25519 = {PTLS_GROUP_X25519, evp_keyex_create, evp_keyex_exchange, NID_X25519};
  712. #endif
  713. ptls_key_exchange_algorithm_t *ptls_bcrypt_key_exchanges[] = {&ptls_bcrypt_secp256r1, NULL};
  714. #endif
  715. #endif /* _WINDOWS */