s2n_async_pkey.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. /*
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License").
  5. * You may not use this file except in compliance with the License.
  6. * A copy of the License is located at
  7. *
  8. * http://aws.amazon.com/apache2.0
  9. *
  10. * or in the "license" file accompanying this file. This file is distributed
  11. * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
  12. * express or implied. See the License for the specific language governing
  13. * permissions and limitations under the License.
  14. */
  15. #include "tls/s2n_async_pkey.h"
  16. #include "api/s2n.h"
  17. #include "crypto/s2n_hash.h"
  18. #include "crypto/s2n_signature.h"
  19. #include "error/s2n_errno.h"
  20. #include "tls/s2n_connection.h"
  21. #include "tls/s2n_handshake.h"
  22. #include "utils/s2n_blob.h"
  23. #include "utils/s2n_mem.h"
  24. #include "utils/s2n_result.h"
  25. #include "utils/s2n_safety.h"
  26. struct s2n_async_pkey_decrypt_data {
  27. s2n_async_pkey_decrypt_complete on_complete;
  28. struct s2n_blob encrypted;
  29. struct s2n_blob decrypted;
  30. unsigned rsa_failed : 1;
  31. };
  32. struct s2n_async_pkey_sign_data {
  33. s2n_async_pkey_sign_complete on_complete;
  34. struct s2n_hash_state digest;
  35. s2n_signature_algorithm sig_alg;
  36. struct s2n_blob signature;
  37. };
  38. struct s2n_async_pkey_op {
  39. s2n_async_pkey_op_type type;
  40. struct s2n_connection *conn;
  41. s2n_async_pkey_validation_mode validation_mode;
  42. unsigned complete : 1;
  43. unsigned applied : 1;
  44. union {
  45. struct s2n_async_pkey_decrypt_data decrypt;
  46. struct s2n_async_pkey_sign_data sign;
  47. } op;
  48. };
  49. struct s2n_async_pkey_op_actions {
  50. S2N_RESULT (*perform)(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
  51. S2N_RESULT (*apply)(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
  52. S2N_RESULT (*get_input_size)(struct s2n_async_pkey_op *op, uint32_t *data_len);
  53. S2N_RESULT (*get_input)(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len);
  54. S2N_RESULT (*set_output)(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len);
  55. S2N_RESULT (*free)(struct s2n_async_pkey_op *op);
  56. };
  57. static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions);
  58. static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op);
  59. static S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
  60. struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);
  61. static S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
  62. struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete);
  63. static S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
  64. struct s2n_blob *init_decrypted,
  65. s2n_async_pkey_decrypt_complete on_complete);
  66. static S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
  67. struct s2n_blob *init_decrypted,
  68. s2n_async_pkey_decrypt_complete on_complete);
  69. static S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
  70. static S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
  71. static S2N_RESULT s2n_async_pkey_get_input_size_decrypt(struct s2n_async_pkey_op *op, uint32_t *data_len);
  72. static S2N_RESULT s2n_async_pkey_get_input_decrypt(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len);
  73. static S2N_RESULT s2n_async_pkey_op_set_output_decrypt(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len);
  74. static S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op);
  75. static S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey);
  76. static S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn);
  77. static S2N_RESULT s2n_async_pkey_get_input_size_sign(struct s2n_async_pkey_op *op, uint32_t *data_len);
  78. static S2N_RESULT s2n_async_pkey_get_input_sign(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len);
  79. static S2N_RESULT s2n_async_pkey_op_set_output_sign(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len);
  80. static S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op);
  81. static const struct s2n_async_pkey_op_actions s2n_async_pkey_decrypt_op = {
  82. .perform = &s2n_async_pkey_decrypt_perform,
  83. .apply = &s2n_async_pkey_decrypt_apply,
  84. .get_input_size = &s2n_async_pkey_get_input_size_decrypt,
  85. .get_input = &s2n_async_pkey_get_input_decrypt,
  86. .set_output = &s2n_async_pkey_op_set_output_decrypt,
  87. .free = &s2n_async_pkey_decrypt_free
  88. };
  89. static const struct s2n_async_pkey_op_actions s2n_async_pkey_sign_op = {
  90. .perform = &s2n_async_pkey_sign_perform,
  91. .apply = &s2n_async_pkey_sign_apply,
  92. .get_input_size = &s2n_async_pkey_get_input_size_sign,
  93. .get_input = &s2n_async_pkey_get_input_sign,
  94. .set_output = &s2n_async_pkey_op_set_output_sign,
  95. .free = &s2n_async_pkey_sign_free
  96. };
  97. DEFINE_POINTER_CLEANUP_FUNC(struct s2n_async_pkey_op *, s2n_async_pkey_op_free);
  98. static S2N_RESULT s2n_async_get_actions(s2n_async_pkey_op_type type, const struct s2n_async_pkey_op_actions **actions)
  99. {
  100. RESULT_ENSURE_REF(actions);
  101. switch (type) {
  102. case S2N_ASYNC_DECRYPT:
  103. *actions = &s2n_async_pkey_decrypt_op;
  104. return S2N_RESULT_OK;
  105. case S2N_ASYNC_SIGN:
  106. *actions = &s2n_async_pkey_sign_op;
  107. return S2N_RESULT_OK;
  108. /* No default for compiler warnings */
  109. }
  110. return S2N_RESULT_ERROR;
  111. }
  112. static S2N_RESULT s2n_async_pkey_op_allocate(struct s2n_async_pkey_op **op)
  113. {
  114. RESULT_ENSURE_REF(op);
  115. RESULT_ENSURE(*op == NULL, S2N_ERR_SAFETY);
  116. /* allocate memory */
  117. DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free);
  118. RESULT_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_async_pkey_op)));
  119. RESULT_GUARD_POSIX(s2n_blob_zero(&mem));
  120. *op = (void *) mem.data;
  121. if (s2n_blob_init(&mem, NULL, 0) != S2N_SUCCESS) {
  122. *op = NULL;
  123. return S2N_RESULT_ERROR;
  124. }
  125. return S2N_RESULT_OK;
  126. }
  127. S2N_RESULT s2n_async_pkey_decrypt(struct s2n_connection *conn, struct s2n_blob *encrypted,
  128. struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
  129. {
  130. RESULT_ENSURE_REF(conn);
  131. RESULT_ENSURE_REF(encrypted);
  132. RESULT_ENSURE_REF(init_decrypted);
  133. RESULT_ENSURE_REF(on_complete);
  134. if (conn->config->async_pkey_cb) {
  135. RESULT_GUARD(s2n_async_pkey_decrypt_async(conn, encrypted, init_decrypted, on_complete));
  136. } else {
  137. RESULT_GUARD(s2n_async_pkey_decrypt_sync(conn, encrypted, init_decrypted, on_complete));
  138. }
  139. return S2N_RESULT_OK;
  140. }
  141. S2N_RESULT s2n_async_cb_execute(struct s2n_connection *conn, struct s2n_async_pkey_op **owned_op)
  142. {
  143. RESULT_ENSURE_REF(conn);
  144. RESULT_ENSURE_REF(owned_op);
  145. RESULT_ENSURE(conn->handshake.async_state == S2N_ASYNC_NOT_INVOKED, S2N_ERR_ASYNC_MORE_THAN_ONE);
  146. /* The callback now owns the operation, meaning we can't free it.
  147. * Wipe our version and pass a copy to the callback.
  148. */
  149. struct s2n_async_pkey_op *unowned_op = *owned_op;
  150. ZERO_TO_DISABLE_DEFER_CLEANUP(*owned_op);
  151. conn->handshake.async_state = S2N_ASYNC_INVOKED;
  152. RESULT_ENSURE(conn->config->async_pkey_cb(conn, unowned_op) == S2N_SUCCESS, S2N_ERR_ASYNC_CALLBACK_FAILED);
  153. /*
  154. * If the callback already completed the operation, continue.
  155. * Otherwise, we need to block s2n_negotiate and wait for the operation to complete.
  156. */
  157. if (conn->handshake.async_state == S2N_ASYNC_COMPLETE) {
  158. return S2N_RESULT_OK;
  159. }
  160. RESULT_BAIL(S2N_ERR_ASYNC_BLOCKED);
  161. }
  162. S2N_RESULT s2n_async_pkey_decrypt_async(struct s2n_connection *conn, struct s2n_blob *encrypted,
  163. struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
  164. {
  165. RESULT_ENSURE_REF(conn);
  166. RESULT_ENSURE_REF(encrypted);
  167. RESULT_ENSURE_REF(init_decrypted);
  168. RESULT_ENSURE_REF(on_complete);
  169. DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
  170. RESULT_GUARD(s2n_async_pkey_op_allocate(&op));
  171. op->type = S2N_ASYNC_DECRYPT;
  172. op->conn = conn;
  173. op->validation_mode = conn->config->async_pkey_validation_mode;
  174. struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
  175. decrypt->on_complete = on_complete;
  176. RESULT_GUARD_POSIX(s2n_dup(encrypted, &decrypt->encrypted));
  177. RESULT_GUARD_POSIX(s2n_dup(init_decrypted, &decrypt->decrypted));
  178. RESULT_GUARD(s2n_async_cb_execute(conn, &op));
  179. return S2N_RESULT_OK;
  180. }
  181. S2N_RESULT s2n_async_pkey_decrypt_sync(struct s2n_connection *conn, struct s2n_blob *encrypted,
  182. struct s2n_blob *init_decrypted, s2n_async_pkey_decrypt_complete on_complete)
  183. {
  184. RESULT_ENSURE_REF(conn);
  185. RESULT_ENSURE_REF(encrypted);
  186. RESULT_ENSURE_REF(init_decrypted);
  187. RESULT_ENSURE_REF(on_complete);
  188. const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;
  189. bool rsa_failed = s2n_pkey_decrypt(pkey, encrypted, init_decrypted) != S2N_SUCCESS;
  190. RESULT_GUARD_POSIX(on_complete(conn, rsa_failed, init_decrypted));
  191. return S2N_RESULT_OK;
  192. }
  193. S2N_RESULT s2n_async_pkey_sign(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
  194. struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
  195. {
  196. RESULT_ENSURE_REF(conn);
  197. RESULT_ENSURE_REF(digest);
  198. RESULT_ENSURE_REF(on_complete);
  199. if (conn->config->async_pkey_cb) {
  200. RESULT_GUARD(s2n_async_pkey_sign_async(conn, sig_alg, digest, on_complete));
  201. } else {
  202. RESULT_GUARD(s2n_async_pkey_sign_sync(conn, sig_alg, digest, on_complete));
  203. }
  204. return S2N_RESULT_OK;
  205. }
  206. S2N_RESULT s2n_async_pkey_sign_async(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
  207. struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
  208. {
  209. RESULT_ENSURE_REF(conn);
  210. RESULT_ENSURE_REF(digest);
  211. RESULT_ENSURE_REF(on_complete);
  212. DEFER_CLEANUP(struct s2n_async_pkey_op *op = NULL, s2n_async_pkey_op_free_pointer);
  213. RESULT_GUARD(s2n_async_pkey_op_allocate(&op));
  214. op->type = S2N_ASYNC_SIGN;
  215. op->conn = conn;
  216. op->validation_mode = conn->config->async_pkey_validation_mode;
  217. if (conn->config->verify_after_sign) {
  218. op->validation_mode = S2N_ASYNC_PKEY_VALIDATION_STRICT;
  219. }
  220. struct s2n_async_pkey_sign_data *sign = &op->op.sign;
  221. sign->on_complete = on_complete;
  222. sign->sig_alg = sig_alg;
  223. RESULT_GUARD_POSIX(s2n_hash_new(&sign->digest));
  224. RESULT_GUARD_POSIX(s2n_hash_copy(&sign->digest, digest));
  225. RESULT_GUARD(s2n_async_cb_execute(conn, &op));
  226. return S2N_RESULT_OK;
  227. }
  228. S2N_RESULT s2n_async_pkey_sign_sync(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
  229. struct s2n_hash_state *digest, s2n_async_pkey_sign_complete on_complete)
  230. {
  231. RESULT_ENSURE_REF(conn);
  232. RESULT_ENSURE_REF(digest);
  233. RESULT_ENSURE_REF(on_complete);
  234. const struct s2n_pkey *pkey = conn->handshake_params.our_chain_and_key->private_key;
  235. DEFER_CLEANUP(struct s2n_blob signed_content = { 0 }, s2n_free);
  236. uint32_t maximum_signature_length = 0;
  237. RESULT_GUARD(s2n_pkey_size(pkey, &maximum_signature_length));
  238. RESULT_GUARD_POSIX(s2n_alloc(&signed_content, maximum_signature_length));
  239. RESULT_ENSURE_REF(conn->config);
  240. if (conn->config->verify_after_sign) {
  241. DEFER_CLEANUP(struct s2n_hash_state digest_for_verify, s2n_hash_free);
  242. RESULT_GUARD_POSIX(s2n_hash_new(&digest_for_verify));
  243. RESULT_GUARD_POSIX(s2n_hash_copy(&digest_for_verify, digest));
  244. RESULT_GUARD_POSIX(s2n_pkey_sign(pkey, sig_alg, digest, &signed_content));
  245. RESULT_GUARD(s2n_async_pkey_verify_signature(conn, sig_alg, &digest_for_verify, &signed_content));
  246. } else {
  247. RESULT_GUARD_POSIX(s2n_pkey_sign(pkey, sig_alg, digest, &signed_content));
  248. }
  249. RESULT_GUARD_POSIX(on_complete(conn, &signed_content));
  250. return S2N_RESULT_OK;
  251. }
  252. int s2n_async_pkey_op_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *key)
  253. {
  254. POSIX_ENSURE_REF(op);
  255. POSIX_ENSURE_REF(key);
  256. POSIX_ENSURE(!op->complete, S2N_ERR_ASYNC_ALREADY_PERFORMED);
  257. const struct s2n_async_pkey_op_actions *actions = NULL;
  258. POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
  259. POSIX_ENSURE_REF(actions);
  260. POSIX_GUARD_RESULT(actions->perform(op, key));
  261. op->complete = true;
  262. return S2N_SUCCESS;
  263. }
  264. int s2n_async_pkey_op_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
  265. {
  266. POSIX_ENSURE_REF(op);
  267. POSIX_ENSURE_REF(conn);
  268. POSIX_ENSURE(op->complete, S2N_ERR_ASYNC_NOT_PERFORMED);
  269. POSIX_ENSURE(!op->applied, S2N_ERR_ASYNC_ALREADY_APPLIED);
  270. /* We could have just used op->conn and removed a conn argument, but we want caller
  271. * to be explicit about connection it wants to resume. Plus this gives more
  272. * protections in cases if caller frees connection object and then tries to resume
  273. * the connection. */
  274. POSIX_ENSURE(op->conn == conn, S2N_ERR_ASYNC_WRONG_CONNECTION);
  275. POSIX_ENSURE(conn->handshake.async_state == S2N_ASYNC_INVOKED, S2N_ERR_ASYNC_WRONG_CONNECTION);
  276. const struct s2n_async_pkey_op_actions *actions = NULL;
  277. POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
  278. POSIX_ENSURE_REF(actions);
  279. POSIX_GUARD_RESULT(actions->apply(op, conn));
  280. op->applied = true;
  281. conn->handshake.async_state = S2N_ASYNC_COMPLETE;
  282. /* Free up the decrypt/sign structs to avoid storing secrets for too long */
  283. POSIX_GUARD_RESULT(actions->free(op));
  284. return S2N_SUCCESS;
  285. }
  286. int s2n_async_pkey_op_free(struct s2n_async_pkey_op *op)
  287. {
  288. POSIX_ENSURE_REF(op);
  289. const struct s2n_async_pkey_op_actions *actions = NULL;
  290. POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
  291. POSIX_ENSURE_REF(actions);
  292. /* If applied the decrypt/sign structs were released in apply call */
  293. if (!op->applied) {
  294. POSIX_GUARD_RESULT(actions->free(op));
  295. }
  296. POSIX_GUARD(s2n_free_object((uint8_t **) &op, sizeof(struct s2n_async_pkey_op)));
  297. return S2N_SUCCESS;
  298. }
  299. S2N_RESULT s2n_async_pkey_decrypt_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
  300. {
  301. RESULT_ENSURE_REF(op);
  302. RESULT_ENSURE_REF(pkey);
  303. struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
  304. decrypt->rsa_failed = s2n_pkey_decrypt(pkey, &decrypt->encrypted, &decrypt->decrypted) != S2N_SUCCESS;
  305. return S2N_RESULT_OK;
  306. }
  307. S2N_RESULT s2n_async_pkey_decrypt_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
  308. {
  309. RESULT_ENSURE_REF(op);
  310. RESULT_ENSURE_REF(conn);
  311. struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
  312. RESULT_GUARD_POSIX(decrypt->on_complete(conn, decrypt->rsa_failed, &decrypt->decrypted));
  313. return S2N_RESULT_OK;
  314. }
  315. S2N_RESULT s2n_async_pkey_decrypt_free(struct s2n_async_pkey_op *op)
  316. {
  317. RESULT_ENSURE_REF(op);
  318. struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
  319. RESULT_GUARD_POSIX(s2n_blob_zero(&decrypt->decrypted));
  320. RESULT_GUARD_POSIX(s2n_blob_zero(&decrypt->encrypted));
  321. RESULT_GUARD_POSIX(s2n_free(&decrypt->decrypted));
  322. RESULT_GUARD_POSIX(s2n_free(&decrypt->encrypted));
  323. return S2N_RESULT_OK;
  324. }
  325. S2N_RESULT s2n_async_pkey_sign_perform(struct s2n_async_pkey_op *op, s2n_cert_private_key *pkey)
  326. {
  327. RESULT_ENSURE_REF(op);
  328. RESULT_ENSURE_REF(op->conn);
  329. RESULT_ENSURE_REF(op->conn->config);
  330. RESULT_ENSURE_REF(pkey);
  331. struct s2n_async_pkey_sign_data *sign = &op->op.sign;
  332. uint32_t maximum_signature_length = 0;
  333. RESULT_GUARD(s2n_pkey_size(pkey, &maximum_signature_length));
  334. RESULT_GUARD_POSIX(s2n_alloc(&sign->signature, maximum_signature_length));
  335. /* If validation mode is S2N_ASYNC_PKEY_VALIDATION_STRICT
  336. * then use local hash copy to sign the signature */
  337. if (op->validation_mode == S2N_ASYNC_PKEY_VALIDATION_STRICT) {
  338. DEFER_CLEANUP(struct s2n_hash_state hash_state_copy, s2n_hash_free);
  339. RESULT_GUARD_POSIX(s2n_hash_new(&hash_state_copy));
  340. RESULT_GUARD_POSIX(s2n_hash_copy(&hash_state_copy, &sign->digest));
  341. RESULT_GUARD_POSIX(s2n_pkey_sign(pkey, sign->sig_alg, &hash_state_copy, &sign->signature));
  342. } else {
  343. RESULT_GUARD_POSIX(s2n_pkey_sign(pkey, sign->sig_alg, &sign->digest, &sign->signature));
  344. }
  345. return S2N_RESULT_OK;
  346. }
  347. S2N_RESULT s2n_async_pkey_sign_apply(struct s2n_async_pkey_op *op, struct s2n_connection *conn)
  348. {
  349. RESULT_ENSURE_REF(op);
  350. RESULT_ENSURE_REF(conn);
  351. struct s2n_async_pkey_sign_data *sign = &op->op.sign;
  352. /* Perform signature validation only if validation feature is opt in */
  353. if (op->validation_mode == S2N_ASYNC_PKEY_VALIDATION_STRICT) {
  354. RESULT_GUARD(s2n_async_pkey_verify_signature(conn, sign->sig_alg, &sign->digest, &sign->signature));
  355. }
  356. RESULT_GUARD_POSIX(sign->on_complete(conn, &sign->signature));
  357. return S2N_RESULT_OK;
  358. }
  359. S2N_RESULT s2n_async_pkey_verify_signature(struct s2n_connection *conn, s2n_signature_algorithm sig_alg,
  360. struct s2n_hash_state *digest, struct s2n_blob *signature)
  361. {
  362. RESULT_ENSURE_REF(conn);
  363. RESULT_ENSURE_REF(conn->handshake_params.our_chain_and_key);
  364. RESULT_ENSURE_REF(digest);
  365. RESULT_ENSURE_REF(signature);
  366. /* Parse public key for the cert */
  367. DEFER_CLEANUP(struct s2n_pkey public_key = { 0 }, s2n_pkey_free);
  368. s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN;
  369. RESULT_GUARD_POSIX(s2n_asn1der_to_public_key_and_type(&public_key, &pkey_type,
  370. &conn->handshake_params.our_chain_and_key->cert_chain->head->raw));
  371. RESULT_ENSURE(s2n_pkey_verify(&public_key, sig_alg, digest, signature) == S2N_SUCCESS, S2N_ERR_VERIFY_SIGNATURE);
  372. return S2N_RESULT_OK;
  373. }
  374. S2N_RESULT s2n_async_pkey_sign_free(struct s2n_async_pkey_op *op)
  375. {
  376. RESULT_ENSURE_REF(op);
  377. struct s2n_async_pkey_sign_data *sign = &op->op.sign;
  378. RESULT_GUARD_POSIX(s2n_hash_free(&sign->digest));
  379. RESULT_GUARD_POSIX(s2n_free(&sign->signature));
  380. return S2N_RESULT_OK;
  381. }
  382. int s2n_async_pkey_op_set_validation_mode(struct s2n_async_pkey_op *op, s2n_async_pkey_validation_mode mode)
  383. {
  384. POSIX_ENSURE_REF(op);
  385. switch (mode) {
  386. case S2N_ASYNC_PKEY_VALIDATION_FAST:
  387. case S2N_ASYNC_PKEY_VALIDATION_STRICT:
  388. op->validation_mode = mode;
  389. return S2N_SUCCESS;
  390. }
  391. POSIX_BAIL(S2N_ERR_INVALID_ARGUMENT);
  392. }
  393. int s2n_async_pkey_op_get_op_type(struct s2n_async_pkey_op *op, s2n_async_pkey_op_type *type)
  394. {
  395. POSIX_ENSURE_REF(op);
  396. POSIX_ENSURE_REF(type);
  397. *type = op->type;
  398. return S2N_SUCCESS;
  399. }
  400. int s2n_async_pkey_op_get_input_size(struct s2n_async_pkey_op *op, uint32_t *data_len)
  401. {
  402. POSIX_ENSURE_REF(op);
  403. POSIX_ENSURE_REF(data_len);
  404. const struct s2n_async_pkey_op_actions *actions = NULL;
  405. POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
  406. POSIX_ENSURE_REF(actions);
  407. POSIX_GUARD_RESULT(actions->get_input_size(op, data_len));
  408. return S2N_SUCCESS;
  409. }
  410. static S2N_RESULT s2n_async_pkey_get_input_size_decrypt(struct s2n_async_pkey_op *op, uint32_t *data_len)
  411. {
  412. RESULT_ENSURE_REF(op);
  413. RESULT_ENSURE_REF(data_len);
  414. struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
  415. struct s2n_blob *in = &decrypt->encrypted;
  416. *data_len = in->size;
  417. return S2N_RESULT_OK;
  418. }
  419. static S2N_RESULT s2n_async_pkey_get_input_size_sign(struct s2n_async_pkey_op *op, uint32_t *data_len)
  420. {
  421. RESULT_ENSURE_REF(op);
  422. RESULT_ENSURE_REF(data_len);
  423. struct s2n_async_pkey_sign_data *sign = &op->op.sign;
  424. struct s2n_hash_state *digest = &sign->digest;
  425. uint8_t digest_length = 0;
  426. RESULT_GUARD_POSIX(s2n_hash_digest_size(digest->alg, &digest_length));
  427. *data_len = digest_length;
  428. return S2N_RESULT_OK;
  429. }
  430. int s2n_async_pkey_op_get_input(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len)
  431. {
  432. POSIX_ENSURE_REF(op);
  433. POSIX_ENSURE_REF(data);
  434. const struct s2n_async_pkey_op_actions *actions = NULL;
  435. POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
  436. POSIX_ENSURE_REF(actions);
  437. POSIX_GUARD_RESULT(actions->get_input(op, data, data_len));
  438. return S2N_SUCCESS;
  439. }
  440. static S2N_RESULT s2n_async_pkey_get_input_decrypt(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len)
  441. {
  442. RESULT_ENSURE_REF(op);
  443. RESULT_ENSURE_REF(data);
  444. struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
  445. struct s2n_blob *in = &decrypt->encrypted;
  446. RESULT_ENSURE_LTE(in->size, data_len);
  447. RESULT_CHECKED_MEMCPY(data, in->data, in->size);
  448. return S2N_RESULT_OK;
  449. }
  450. static S2N_RESULT s2n_async_pkey_get_input_sign(struct s2n_async_pkey_op *op, uint8_t *data, uint32_t data_len)
  451. {
  452. RESULT_ENSURE_REF(op);
  453. RESULT_ENSURE_REF(data);
  454. struct s2n_async_pkey_sign_data *sign = &op->op.sign;
  455. DEFER_CLEANUP(struct s2n_hash_state digest_copy = { 0 }, s2n_hash_free);
  456. RESULT_GUARD_POSIX(s2n_hash_new(&digest_copy));
  457. RESULT_GUARD_POSIX(s2n_hash_copy(&digest_copy, &sign->digest));
  458. uint8_t digest_length = 0;
  459. RESULT_GUARD_POSIX(s2n_hash_digest_size(digest_copy.alg, &digest_length));
  460. RESULT_ENSURE_LTE(digest_length, data_len);
  461. RESULT_GUARD_POSIX(s2n_hash_digest(&digest_copy, data, digest_length));
  462. return S2N_RESULT_OK;
  463. }
  464. int s2n_async_pkey_op_set_output(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len)
  465. {
  466. POSIX_ENSURE_REF(op);
  467. POSIX_ENSURE_REF(data);
  468. const struct s2n_async_pkey_op_actions *actions = NULL;
  469. POSIX_GUARD_RESULT(s2n_async_get_actions(op->type, &actions));
  470. POSIX_ENSURE_REF(actions);
  471. POSIX_GUARD_RESULT(actions->set_output(op, data, data_len));
  472. op->complete = true;
  473. return S2N_SUCCESS;
  474. }
  475. static S2N_RESULT s2n_async_pkey_op_set_output_decrypt(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len)
  476. {
  477. RESULT_ENSURE_REF(op);
  478. RESULT_ENSURE_REF(data);
  479. struct s2n_async_pkey_decrypt_data *decrypt = &op->op.decrypt;
  480. struct s2n_blob *out = &decrypt->decrypted;
  481. RESULT_GUARD_POSIX(s2n_realloc(out, data_len));
  482. RESULT_CHECKED_MEMCPY(out->data, data, data_len);
  483. return S2N_RESULT_OK;
  484. }
  485. static S2N_RESULT s2n_async_pkey_op_set_output_sign(struct s2n_async_pkey_op *op, const uint8_t *data, uint32_t data_len)
  486. {
  487. RESULT_ENSURE_REF(op);
  488. RESULT_ENSURE_REF(data);
  489. struct s2n_async_pkey_sign_data *sign = &op->op.sign;
  490. struct s2n_blob *sigcopy = &sign->signature;
  491. RESULT_GUARD_POSIX(s2n_realloc(sigcopy, data_len));
  492. RESULT_CHECKED_MEMCPY(sigcopy->data, data, data_len);
  493. return S2N_RESULT_OK;
  494. }