s2n_crypto.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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_crypto.h"
  16. #include "api/s2n.h"
  17. #include "tls/s2n_cipher_suites.h"
  18. #include "utils/s2n_result.h"
  19. #include "utils/s2n_safety.h"
  20. S2N_RESULT s2n_crypto_parameters_new(struct s2n_crypto_parameters **new_params)
  21. {
  22. RESULT_ENSURE_REF(new_params);
  23. RESULT_ENSURE_EQ(*new_params, NULL);
  24. DEFER_CLEANUP(struct s2n_blob mem = { 0 }, s2n_free);
  25. RESULT_GUARD_POSIX(s2n_alloc(&mem, sizeof(struct s2n_crypto_parameters)));
  26. RESULT_GUARD_POSIX(s2n_blob_zero(&mem));
  27. DEFER_CLEANUP(struct s2n_crypto_parameters *params = (struct s2n_crypto_parameters *) (void *) mem.data,
  28. s2n_crypto_parameters_free);
  29. ZERO_TO_DISABLE_DEFER_CLEANUP(mem);
  30. /* Allocate long-term memory for the HMAC states */
  31. RESULT_GUARD_POSIX(s2n_hmac_new(&params->client_record_mac));
  32. RESULT_GUARD_POSIX(s2n_hmac_new(&params->server_record_mac));
  33. /* Allocate key memory */
  34. RESULT_GUARD_POSIX(s2n_session_key_alloc(&params->client_key));
  35. RESULT_GUARD_POSIX(s2n_session_key_alloc(&params->server_key));
  36. /* Setup */
  37. RESULT_GUARD(s2n_crypto_parameters_wipe(params));
  38. *new_params = params;
  39. ZERO_TO_DISABLE_DEFER_CLEANUP(params);
  40. return S2N_RESULT_OK;
  41. }
  42. S2N_RESULT s2n_crypto_parameters_wipe(struct s2n_crypto_parameters *params)
  43. {
  44. RESULT_ENSURE_REF(params);
  45. /* Wipe the hmacs for reuse */
  46. struct s2n_hmac_state client_state = params->client_record_mac;
  47. struct s2n_hmac_state server_state = params->server_record_mac;
  48. RESULT_GUARD_POSIX(s2n_hmac_init(&client_state, S2N_HMAC_NONE, NULL, 0));
  49. RESULT_GUARD_POSIX(s2n_hmac_init(&server_state, S2N_HMAC_NONE, NULL, 0));
  50. /* Wipe the keys for reuse */
  51. struct s2n_session_key client_key = params->client_key;
  52. struct s2n_session_key server_key = params->server_key;
  53. if (params->cipher_suite
  54. && params->cipher_suite->record_alg
  55. && params->cipher_suite->record_alg->cipher
  56. && params->cipher_suite->record_alg->cipher->destroy_key) {
  57. RESULT_GUARD_POSIX(params->cipher_suite->record_alg->cipher->destroy_key(&params->client_key));
  58. RESULT_GUARD_POSIX(params->cipher_suite->record_alg->cipher->destroy_key(&params->server_key));
  59. }
  60. *params = (struct s2n_crypto_parameters){ 0 };
  61. params->client_record_mac = client_state;
  62. params->server_record_mac = server_state;
  63. params->client_key = client_key;
  64. params->server_key = server_key;
  65. params->cipher_suite = &s2n_null_cipher_suite;
  66. return S2N_RESULT_OK;
  67. }
  68. S2N_CLEANUP_RESULT s2n_crypto_parameters_free(struct s2n_crypto_parameters **params)
  69. {
  70. if (params == NULL || *params == NULL) {
  71. return S2N_RESULT_OK;
  72. }
  73. /* Free HMAC states */
  74. RESULT_GUARD_POSIX(s2n_hmac_free(&(*params)->client_record_mac));
  75. RESULT_GUARD_POSIX(s2n_hmac_free(&(*params)->server_record_mac));
  76. /* Free session keys */
  77. RESULT_GUARD_POSIX(s2n_session_key_free(&(*params)->client_key));
  78. RESULT_GUARD_POSIX(s2n_session_key_free(&(*params)->server_key));
  79. RESULT_GUARD_POSIX(s2n_free_object((uint8_t **) params, sizeof(struct s2n_crypto_parameters)));
  80. return S2N_RESULT_OK;
  81. }
  82. S2N_RESULT s2n_crypto_parameters_switch(struct s2n_connection *conn)
  83. {
  84. RESULT_ENSURE_REF(conn);
  85. RESULT_ENSURE_REF(conn->secure);
  86. RESULT_ENSURE_REF(conn->initial);
  87. /* Only start encryption if we have not already switched to secure parameters */
  88. if (conn->mode == S2N_CLIENT && conn->client == conn->initial) {
  89. struct s2n_blob seq = { 0 };
  90. RESULT_GUARD_POSIX(s2n_blob_init(&seq, conn->secure->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
  91. RESULT_GUARD_POSIX(s2n_blob_zero(&seq));
  92. conn->client = conn->secure;
  93. } else if (conn->mode == S2N_SERVER && conn->server == conn->initial) {
  94. struct s2n_blob seq = { 0 };
  95. RESULT_GUARD_POSIX(s2n_blob_init(&seq, conn->secure->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
  96. RESULT_GUARD_POSIX(s2n_blob_zero(&seq));
  97. conn->server = conn->secure;
  98. }
  99. return S2N_RESULT_OK;
  100. }