s2n_kex.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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_kex.h"
  16. #include "pq-crypto/s2n_pq.h"
  17. #include "tls/s2n_cipher_preferences.h"
  18. #include "tls/s2n_cipher_suites.h"
  19. #include "tls/s2n_client_key_exchange.h"
  20. #include "tls/s2n_kem.h"
  21. #include "tls/s2n_security_policies.h"
  22. #include "tls/s2n_server_key_exchange.h"
  23. #include "tls/s2n_tls.h"
  24. #include "utils/s2n_safety.h"
  25. static S2N_RESULT s2n_check_rsa_key(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
  26. {
  27. RESULT_ENSURE_REF(cipher_suite);
  28. RESULT_ENSURE_REF(conn);
  29. RESULT_ENSURE_REF(is_supported);
  30. *is_supported = s2n_get_compatible_cert_chain_and_key(conn, S2N_PKEY_TYPE_RSA) != NULL;
  31. return S2N_RESULT_OK;
  32. }
  33. static S2N_RESULT s2n_check_dhe(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
  34. {
  35. RESULT_ENSURE_REF(cipher_suite);
  36. RESULT_ENSURE_REF(conn);
  37. RESULT_ENSURE_REF(conn->config);
  38. RESULT_ENSURE_REF(is_supported);
  39. *is_supported = conn->config->dhparams != NULL;
  40. return S2N_RESULT_OK;
  41. }
  42. static S2N_RESULT s2n_check_ecdhe(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
  43. {
  44. RESULT_ENSURE_REF(cipher_suite);
  45. RESULT_ENSURE_REF(conn);
  46. RESULT_ENSURE_REF(is_supported);
  47. *is_supported = conn->kex_params.server_ecc_evp_params.negotiated_curve != NULL;
  48. return S2N_RESULT_OK;
  49. }
  50. static S2N_RESULT s2n_check_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
  51. {
  52. RESULT_ENSURE_REF(cipher_suite);
  53. RESULT_ENSURE_REF(conn);
  54. RESULT_ENSURE_REF(is_supported);
  55. /* If any of the necessary conditions are not met, we will return early and indicate KEM is not supported. */
  56. *is_supported = false;
  57. const struct s2n_kem_preferences *kem_preferences = NULL;
  58. RESULT_GUARD_POSIX(s2n_connection_get_kem_preferences(conn, &kem_preferences));
  59. RESULT_ENSURE_REF(kem_preferences);
  60. if (!s2n_pq_is_enabled() || kem_preferences->kem_count == 0) {
  61. return S2N_RESULT_OK;
  62. }
  63. const struct s2n_iana_to_kem *supported_params = NULL;
  64. if (s2n_cipher_suite_to_kem(cipher_suite->iana_value, &supported_params) != S2N_SUCCESS) {
  65. return S2N_RESULT_OK;
  66. }
  67. RESULT_ENSURE_REF(supported_params);
  68. if (supported_params->kem_count == 0) {
  69. return S2N_RESULT_OK;
  70. }
  71. struct s2n_blob *client_kem_pref_list = &(conn->kex_params.client_pq_kem_extension);
  72. const struct s2n_kem *chosen_kem = NULL;
  73. if (client_kem_pref_list == NULL || client_kem_pref_list->data == NULL) {
  74. /* If the client did not send a PQ KEM extension, then the server can pick its preferred parameter */
  75. if (s2n_choose_kem_without_peer_pref_list(
  76. cipher_suite->iana_value, kem_preferences->kems, kem_preferences->kem_count, &chosen_kem)
  77. != S2N_SUCCESS) {
  78. return S2N_RESULT_OK;
  79. }
  80. } else {
  81. /* If the client did send a PQ KEM extension, then the server must find a mutually supported parameter. */
  82. if (s2n_choose_kem_with_peer_pref_list(
  83. cipher_suite->iana_value, client_kem_pref_list, kem_preferences->kems, kem_preferences->kem_count, &chosen_kem)
  84. != S2N_SUCCESS) {
  85. return S2N_RESULT_OK;
  86. }
  87. }
  88. *is_supported = chosen_kem != NULL;
  89. return S2N_RESULT_OK;
  90. }
  91. static S2N_RESULT s2n_configure_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
  92. {
  93. RESULT_ENSURE_REF(cipher_suite);
  94. RESULT_ENSURE_REF(conn);
  95. RESULT_ENSURE(s2n_pq_is_enabled(), S2N_ERR_PQ_DISABLED);
  96. const struct s2n_kem_preferences *kem_preferences = NULL;
  97. RESULT_GUARD_POSIX(s2n_connection_get_kem_preferences(conn, &kem_preferences));
  98. RESULT_ENSURE_REF(kem_preferences);
  99. struct s2n_blob *proposed_kems = &(conn->kex_params.client_pq_kem_extension);
  100. const struct s2n_kem *chosen_kem = NULL;
  101. if (proposed_kems == NULL || proposed_kems->data == NULL) {
  102. /* If the client did not send a PQ KEM extension, then the server can pick its preferred parameter */
  103. RESULT_GUARD_POSIX(s2n_choose_kem_without_peer_pref_list(cipher_suite->iana_value, kem_preferences->kems,
  104. kem_preferences->kem_count, &chosen_kem));
  105. } else {
  106. /* If the client did send a PQ KEM extension, then the server must find a mutually supported parameter. */
  107. RESULT_GUARD_POSIX(s2n_choose_kem_with_peer_pref_list(cipher_suite->iana_value, proposed_kems, kem_preferences->kems,
  108. kem_preferences->kem_count, &chosen_kem));
  109. }
  110. conn->kex_params.kem_params.kem = chosen_kem;
  111. return S2N_RESULT_OK;
  112. }
  113. static S2N_RESULT s2n_no_op_configure(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
  114. {
  115. return S2N_RESULT_OK;
  116. }
  117. static S2N_RESULT s2n_check_hybrid_ecdhe_kem(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
  118. {
  119. RESULT_ENSURE_REF(cipher_suite);
  120. RESULT_ENSURE_REF(conn);
  121. RESULT_ENSURE_REF(is_supported);
  122. bool ecdhe_supported = false;
  123. bool kem_supported = false;
  124. RESULT_GUARD(s2n_check_ecdhe(cipher_suite, conn, &ecdhe_supported));
  125. RESULT_GUARD(s2n_check_kem(cipher_suite, conn, &kem_supported));
  126. *is_supported = ecdhe_supported && kem_supported;
  127. return S2N_RESULT_OK;
  128. }
  129. const struct s2n_kex s2n_kem = {
  130. .is_ephemeral = true,
  131. .connection_supported = &s2n_check_kem,
  132. .configure_connection = &s2n_configure_kem,
  133. .server_key_recv_read_data = &s2n_kem_server_key_recv_read_data,
  134. .server_key_recv_parse_data = &s2n_kem_server_key_recv_parse_data,
  135. .server_key_send = &s2n_kem_server_key_send,
  136. .client_key_recv = &s2n_kem_client_key_recv,
  137. .client_key_send = &s2n_kem_client_key_send,
  138. };
  139. const struct s2n_kex s2n_rsa = {
  140. .is_ephemeral = false,
  141. .connection_supported = &s2n_check_rsa_key,
  142. .configure_connection = &s2n_no_op_configure,
  143. .server_key_recv_read_data = NULL,
  144. .server_key_recv_parse_data = NULL,
  145. .server_key_send = NULL,
  146. .client_key_recv = &s2n_rsa_client_key_recv,
  147. .client_key_send = &s2n_rsa_client_key_send,
  148. .prf = &s2n_prf_calculate_master_secret,
  149. };
  150. const struct s2n_kex s2n_dhe = {
  151. .is_ephemeral = true,
  152. .connection_supported = &s2n_check_dhe,
  153. .configure_connection = &s2n_no_op_configure,
  154. .server_key_recv_read_data = &s2n_dhe_server_key_recv_read_data,
  155. .server_key_recv_parse_data = &s2n_dhe_server_key_recv_parse_data,
  156. .server_key_send = &s2n_dhe_server_key_send,
  157. .client_key_recv = &s2n_dhe_client_key_recv,
  158. .client_key_send = &s2n_dhe_client_key_send,
  159. .prf = &s2n_prf_calculate_master_secret,
  160. };
  161. const struct s2n_kex s2n_ecdhe = {
  162. .is_ephemeral = true,
  163. .connection_supported = &s2n_check_ecdhe,
  164. .configure_connection = &s2n_no_op_configure,
  165. .server_key_recv_read_data = &s2n_ecdhe_server_key_recv_read_data,
  166. .server_key_recv_parse_data = &s2n_ecdhe_server_key_recv_parse_data,
  167. .server_key_send = &s2n_ecdhe_server_key_send,
  168. .client_key_recv = &s2n_ecdhe_client_key_recv,
  169. .client_key_send = &s2n_ecdhe_client_key_send,
  170. .prf = &s2n_prf_calculate_master_secret,
  171. };
  172. const struct s2n_kex s2n_hybrid_ecdhe_kem = {
  173. .is_ephemeral = true,
  174. .hybrid = { &s2n_ecdhe, &s2n_kem },
  175. .connection_supported = &s2n_check_hybrid_ecdhe_kem,
  176. .configure_connection = &s2n_configure_kem,
  177. .server_key_recv_read_data = &s2n_hybrid_server_key_recv_read_data,
  178. .server_key_recv_parse_data = &s2n_hybrid_server_key_recv_parse_data,
  179. .server_key_send = &s2n_hybrid_server_key_send,
  180. .client_key_recv = &s2n_hybrid_client_key_recv,
  181. .client_key_send = &s2n_hybrid_client_key_send,
  182. .prf = &s2n_hybrid_prf_master_secret,
  183. };
  184. S2N_RESULT s2n_kex_supported(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn, bool *is_supported)
  185. {
  186. RESULT_ENSURE_REF(cipher_suite);
  187. RESULT_ENSURE_REF(cipher_suite->key_exchange_alg);
  188. RESULT_ENSURE_REF(cipher_suite->key_exchange_alg->connection_supported);
  189. RESULT_ENSURE_REF(conn);
  190. RESULT_ENSURE_REF(is_supported);
  191. RESULT_GUARD(cipher_suite->key_exchange_alg->connection_supported(cipher_suite, conn, is_supported));
  192. return S2N_RESULT_OK;
  193. }
  194. S2N_RESULT s2n_configure_kex(const struct s2n_cipher_suite *cipher_suite, struct s2n_connection *conn)
  195. {
  196. RESULT_ENSURE_REF(cipher_suite);
  197. RESULT_ENSURE_REF(cipher_suite->key_exchange_alg);
  198. RESULT_ENSURE_REF(cipher_suite->key_exchange_alg->configure_connection);
  199. RESULT_ENSURE_REF(conn);
  200. RESULT_GUARD(cipher_suite->key_exchange_alg->configure_connection(cipher_suite, conn));
  201. return S2N_RESULT_OK;
  202. }
  203. S2N_RESULT s2n_kex_is_ephemeral(const struct s2n_kex *kex, bool *is_ephemeral)
  204. {
  205. RESULT_ENSURE_REF(kex);
  206. RESULT_ENSURE_REF(is_ephemeral);
  207. *is_ephemeral = kex->is_ephemeral;
  208. return S2N_RESULT_OK;
  209. }
  210. S2N_RESULT s2n_kex_server_key_recv_parse_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_kex_raw_server_data *raw_server_data)
  211. {
  212. RESULT_ENSURE_REF(kex);
  213. RESULT_ENSURE_REF(kex->server_key_recv_parse_data);
  214. RESULT_ENSURE_REF(conn);
  215. RESULT_ENSURE_REF(raw_server_data);
  216. RESULT_GUARD_POSIX(kex->server_key_recv_parse_data(conn, raw_server_data));
  217. return S2N_RESULT_OK;
  218. }
  219. S2N_RESULT s2n_kex_server_key_recv_read_data(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_verify,
  220. struct s2n_kex_raw_server_data *raw_server_data)
  221. {
  222. RESULT_ENSURE_REF(kex);
  223. RESULT_ENSURE_REF(kex->server_key_recv_read_data);
  224. RESULT_ENSURE_REF(conn);
  225. RESULT_ENSURE_REF(data_to_verify);
  226. RESULT_GUARD_POSIX(kex->server_key_recv_read_data(conn, data_to_verify, raw_server_data));
  227. return S2N_RESULT_OK;
  228. }
  229. S2N_RESULT s2n_kex_server_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *data_to_sign)
  230. {
  231. RESULT_ENSURE_REF(kex);
  232. RESULT_ENSURE_REF(kex->server_key_send);
  233. RESULT_ENSURE_REF(conn);
  234. RESULT_ENSURE_REF(data_to_sign);
  235. RESULT_GUARD_POSIX(kex->server_key_send(conn, data_to_sign));
  236. return S2N_RESULT_OK;
  237. }
  238. S2N_RESULT s2n_kex_client_key_recv(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key)
  239. {
  240. RESULT_ENSURE_REF(kex);
  241. RESULT_ENSURE_REF(kex->client_key_recv);
  242. RESULT_ENSURE_REF(conn);
  243. RESULT_ENSURE_REF(shared_key);
  244. RESULT_GUARD_POSIX(kex->client_key_recv(conn, shared_key));
  245. return S2N_RESULT_OK;
  246. }
  247. S2N_RESULT s2n_kex_client_key_send(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key)
  248. {
  249. RESULT_ENSURE_REF(kex);
  250. RESULT_ENSURE_REF(kex->client_key_send);
  251. RESULT_ENSURE_REF(conn);
  252. RESULT_ENSURE_REF(shared_key);
  253. RESULT_GUARD_POSIX(kex->client_key_send(conn, shared_key));
  254. return S2N_RESULT_OK;
  255. }
  256. S2N_RESULT s2n_kex_tls_prf(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *premaster_secret)
  257. {
  258. RESULT_ENSURE_REF(kex);
  259. RESULT_ENSURE_REF(kex->prf);
  260. RESULT_ENSURE_REF(conn);
  261. RESULT_ENSURE_REF(premaster_secret);
  262. RESULT_GUARD_POSIX(kex->prf(conn, premaster_secret));
  263. return S2N_RESULT_OK;
  264. }
  265. bool s2n_kex_includes(const struct s2n_kex *kex, const struct s2n_kex *query)
  266. {
  267. if (kex == query) {
  268. return true;
  269. }
  270. if (kex == NULL || query == NULL) {
  271. return false;
  272. }
  273. return query == kex->hybrid[0] || query == kex->hybrid[1];
  274. }