s2n_ktls.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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_ktls.h"
  16. #include "crypto/s2n_ktls_crypto.h"
  17. #include "tls/s2n_prf.h"
  18. #include "tls/s2n_tls.h"
  19. /* Used for overriding setsockopt calls in testing */
  20. s2n_setsockopt_fn s2n_setsockopt = setsockopt;
  21. S2N_RESULT s2n_ktls_set_setsockopt_cb(s2n_setsockopt_fn cb)
  22. {
  23. RESULT_ENSURE(s2n_in_test(), S2N_ERR_NOT_IN_TEST);
  24. s2n_setsockopt = cb;
  25. return S2N_RESULT_OK;
  26. }
  27. bool s2n_ktls_is_supported_on_platform()
  28. {
  29. #if defined(S2N_KTLS_SUPPORTED)
  30. return true;
  31. #else
  32. return false;
  33. #endif
  34. }
  35. static int s2n_ktls_disabled_read(void *io_context, uint8_t *buf, uint32_t len)
  36. {
  37. POSIX_BAIL(S2N_ERR_IO);
  38. }
  39. static S2N_RESULT s2n_ktls_validate(struct s2n_connection *conn, s2n_ktls_mode ktls_mode)
  40. {
  41. RESULT_ENSURE_REF(conn);
  42. const struct s2n_config *config = conn->config;
  43. RESULT_ENSURE_REF(config);
  44. RESULT_ENSURE(s2n_ktls_is_supported_on_platform(), S2N_ERR_KTLS_UNSUPPORTED_PLATFORM);
  45. /* kTLS enable should only be called once the handshake has completed. */
  46. RESULT_ENSURE(is_handshake_complete(conn), S2N_ERR_HANDSHAKE_NOT_COMPLETE);
  47. /* TODO support TLS 1.3
  48. *
  49. * TLS 1.3 support requires sending the KeyUpdate message when the cryptographic
  50. * key usage limits are met. However, this is currently only possible by applying a
  51. * kernel patch to support this functionality.
  52. */
  53. RESULT_ENSURE(conn->actual_protocol_version == S2N_TLS12, S2N_ERR_KTLS_UNSUPPORTED_CONN);
  54. /* Check if the cipher supports kTLS */
  55. const struct s2n_cipher *cipher = NULL;
  56. RESULT_GUARD(s2n_connection_get_secure_cipher(conn, &cipher));
  57. RESULT_ENSURE_REF(cipher);
  58. RESULT_ENSURE(cipher->set_ktls_info, S2N_ERR_KTLS_UNSUPPORTED_CONN);
  59. /* Renegotiation requires updating the keys, which kTLS doesn't currently support.
  60. *
  61. * Setting the renegotiation callback doesn't guarantee that a client will
  62. * attempt to renegotiate. The callback can also be used to send warning alerts
  63. * signaling that renegotiation was rejected. However, we can provide applications
  64. * with a clearer signal earlier by preventing them from enabling ktls on a
  65. * connection that MIGHT require renegotiation. We can relax this restriction
  66. * later if necessary.
  67. */
  68. bool may_receive_hello_request = s2n_result_is_ok(s2n_client_hello_request_validate(conn));
  69. bool may_renegotiate = may_receive_hello_request && config->renegotiate_request_cb;
  70. RESULT_ENSURE(!may_renegotiate, S2N_ERR_KTLS_RENEG);
  71. /* kTLS I/O functionality is managed by s2n-tls. kTLS cannot be enabled if the
  72. * application sets custom I/O (managed_send_io == false means application has
  73. * set custom I/O).
  74. */
  75. switch (ktls_mode) {
  76. case S2N_KTLS_MODE_SEND:
  77. RESULT_ENSURE(conn->managed_send_io, S2N_ERR_KTLS_MANAGED_IO);
  78. /* The output stuffer should be empty before enabling kTLS. */
  79. RESULT_ENSURE(s2n_stuffer_data_available(&conn->out) == 0, S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING);
  80. break;
  81. case S2N_KTLS_MODE_RECV:
  82. RESULT_ENSURE(conn->managed_recv_io, S2N_ERR_KTLS_MANAGED_IO);
  83. /* The input stuffer should be empty before enabling kTLS. */
  84. RESULT_ENSURE(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING);
  85. break;
  86. default:
  87. RESULT_BAIL(S2N_ERR_SAFETY);
  88. break;
  89. }
  90. return S2N_RESULT_OK;
  91. }
  92. /* Enabling kTLS preserves the original *io_context; making this functions
  93. * safe to call even after kTLS has been enabled on the connection.
  94. *
  95. * Retrieving fd assumes that the connection is using socket IO and has the
  96. * send_io_context set. While kTLS overrides IO and essentially disables
  97. * the socket conn->send function callback, it doesn't modify the
  98. * send_io_context. */
  99. S2N_RESULT s2n_ktls_get_file_descriptor(struct s2n_connection *conn, s2n_ktls_mode ktls_mode, int *fd)
  100. {
  101. RESULT_ENSURE_REF(conn);
  102. RESULT_ENSURE_REF(fd);
  103. if (ktls_mode == S2N_KTLS_MODE_RECV) {
  104. RESULT_GUARD_POSIX(s2n_connection_get_read_fd(conn, fd));
  105. } else if (ktls_mode == S2N_KTLS_MODE_SEND) {
  106. RESULT_GUARD_POSIX(s2n_connection_get_write_fd(conn, fd));
  107. }
  108. return S2N_RESULT_OK;
  109. }
  110. static S2N_RESULT s2n_ktls_get_io_mode(s2n_ktls_mode ktls_mode, int *tls_tx_rx_mode)
  111. {
  112. RESULT_ENSURE_REF(tls_tx_rx_mode);
  113. if (ktls_mode == S2N_KTLS_MODE_SEND) {
  114. *tls_tx_rx_mode = S2N_TLS_TX;
  115. } else {
  116. *tls_tx_rx_mode = S2N_TLS_RX;
  117. }
  118. return S2N_RESULT_OK;
  119. }
  120. static S2N_RESULT s2n_ktls_crypto_info_init(struct s2n_connection *conn, s2n_ktls_mode ktls_mode,
  121. struct s2n_ktls_crypto_info *crypto_info)
  122. {
  123. RESULT_ENSURE_REF(conn);
  124. struct s2n_crypto_parameters *secure = conn->secure;
  125. RESULT_ENSURE_REF(secure);
  126. /* In order to avoid storing the encryption keys on the connection, we instead
  127. * regenerate them when required by ktls.
  128. *
  129. * s2n_key_material also includes an IV, but we should use the IV stored
  130. * on the connection instead. Some record algorithms (like CBC) mutate the
  131. * "implicit_iv" when writing records, so the IV may change after generation.
  132. */
  133. struct s2n_key_material key_material = { 0 };
  134. RESULT_GUARD(s2n_prf_generate_key_material(conn, &key_material));
  135. bool is_sending_key = (ktls_mode == S2N_KTLS_MODE_SEND);
  136. s2n_mode key_mode = (is_sending_key) ? conn->mode : S2N_PEER_MODE(conn->mode);
  137. struct s2n_ktls_crypto_info_inputs inputs = { 0 };
  138. if (key_mode == S2N_CLIENT) {
  139. inputs.key = key_material.client_key;
  140. RESULT_GUARD_POSIX(s2n_blob_init(&inputs.iv,
  141. secure->client_implicit_iv, sizeof(secure->client_implicit_iv)));
  142. RESULT_GUARD_POSIX(s2n_blob_init(&inputs.seq,
  143. secure->client_sequence_number, sizeof(secure->client_sequence_number)));
  144. } else {
  145. inputs.key = key_material.server_key;
  146. RESULT_GUARD_POSIX(s2n_blob_init(&inputs.iv,
  147. secure->server_implicit_iv, sizeof(secure->server_implicit_iv)));
  148. RESULT_GUARD_POSIX(s2n_blob_init(&inputs.seq,
  149. secure->server_sequence_number, sizeof(secure->server_sequence_number)));
  150. }
  151. const struct s2n_cipher *cipher = NULL;
  152. RESULT_GUARD(s2n_connection_get_secure_cipher(conn, &cipher));
  153. RESULT_ENSURE_REF(cipher);
  154. RESULT_ENSURE_REF(cipher->set_ktls_info);
  155. RESULT_GUARD(cipher->set_ktls_info(&inputs, crypto_info));
  156. return S2N_RESULT_OK;
  157. }
  158. /* This method intentionally returns void because it may NOT perform any fallible
  159. * operations. See s2n_connection_ktls_enable.
  160. */
  161. void s2n_ktls_configure_connection(struct s2n_connection *conn, s2n_ktls_mode ktls_mode)
  162. {
  163. if (conn == NULL) {
  164. return;
  165. }
  166. if (ktls_mode == S2N_KTLS_MODE_SEND) {
  167. conn->ktls_send_enabled = true;
  168. conn->send = s2n_ktls_send_cb;
  169. } else {
  170. conn->ktls_recv_enabled = true;
  171. conn->recv = s2n_ktls_disabled_read;
  172. }
  173. }
  174. static S2N_RESULT s2n_connection_ktls_enable(struct s2n_connection *conn, s2n_ktls_mode ktls_mode)
  175. {
  176. RESULT_ENSURE_REF(conn);
  177. RESULT_GUARD(s2n_ktls_validate(conn, ktls_mode));
  178. int fd = 0;
  179. RESULT_GUARD(s2n_ktls_get_file_descriptor(conn, ktls_mode, &fd));
  180. /* This call doesn't actually enable ktls or modify the IO behavior of the socket.
  181. * Instead, this is just a prerequisite for calling setsockopt with SOL_TLS.
  182. *
  183. * We intentionally ignore the result of this call. It may fail because ktls
  184. * is not supported, but it might also fail because ktls has already been enabled
  185. * for the socket. If SOL_TLS isn't enabled on the socket, our next call to
  186. * setsockopt with SOL_TLS will also fail, and we DO check that result.
  187. */
  188. s2n_setsockopt(fd, S2N_SOL_TCP, S2N_TCP_ULP, S2N_TLS_ULP_NAME, S2N_TLS_ULP_NAME_SIZE);
  189. int tls_tx_rx_mode = 0;
  190. RESULT_GUARD(s2n_ktls_get_io_mode(ktls_mode, &tls_tx_rx_mode));
  191. struct s2n_ktls_crypto_info crypto_info = { 0 };
  192. RESULT_GUARD(s2n_ktls_crypto_info_init(conn, ktls_mode, &crypto_info));
  193. /* If this call succeeds, then ktls is enabled for that io mode and will be offloaded */
  194. int ret = s2n_setsockopt(fd, S2N_SOL_TLS, tls_tx_rx_mode, crypto_info.value.data, crypto_info.value.size);
  195. RESULT_ENSURE(ret == 0, S2N_ERR_KTLS_ENABLE);
  196. /* At this point, ktls is enabled on the socket for the requested IO mode.
  197. * No further fallible operations may be performed, or else the caller may
  198. * incorrectly assume that enabling ktls failed and they should therefore
  199. * fall back to using application layer TLS.
  200. *
  201. * That means no calls to RESULT_ENSURE, RESULT_GUARD, etc. after this point.
  202. */
  203. s2n_ktls_configure_connection(conn, ktls_mode);
  204. return S2N_RESULT_OK;
  205. }
  206. int s2n_connection_ktls_enable_send(struct s2n_connection *conn)
  207. {
  208. POSIX_ENSURE_REF(conn);
  209. /* If already enabled then return success */
  210. if (conn->ktls_send_enabled) {
  211. return S2N_SUCCESS;
  212. }
  213. POSIX_GUARD_RESULT(s2n_connection_ktls_enable(conn, S2N_KTLS_MODE_SEND));
  214. return S2N_SUCCESS;
  215. }
  216. int s2n_connection_ktls_enable_recv(struct s2n_connection *conn)
  217. {
  218. POSIX_ENSURE_REF(conn);
  219. /* If already enabled then return success */
  220. if (conn->ktls_recv_enabled) {
  221. return S2N_SUCCESS;
  222. }
  223. POSIX_GUARD_RESULT(s2n_connection_ktls_enable(conn, S2N_KTLS_MODE_RECV));
  224. return S2N_SUCCESS;
  225. }