ssl_cookie.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /*
  2. * DTLS cookie callbacks implementation
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  8. * not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. */
  19. /*
  20. * These session callbacks use a simple chained list
  21. * to store and retrieve the session information.
  22. */
  23. #include "common.h"
  24. #if defined(MBEDTLS_SSL_COOKIE_C)
  25. #include "mbedtls/platform.h"
  26. #include "mbedtls/ssl_cookie.h"
  27. #include "ssl_misc.h"
  28. #include "mbedtls/error.h"
  29. #include "mbedtls/platform_util.h"
  30. #include "mbedtls/constant_time.h"
  31. #include "mbedtls/legacy_or_psa.h"
  32. #include <string.h>
  33. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  34. #define PSA_TO_MBEDTLS_ERR(status) PSA_TO_MBEDTLS_ERR_LIST(status, \
  35. psa_to_ssl_errors, \
  36. psa_generic_status_to_mbedtls)
  37. #endif
  38. /*
  39. * If DTLS is in use, then at least one of SHA-256 or SHA-384 is
  40. * available. Try SHA-256 first as 384 wastes resources
  41. */
  42. #if defined(MBEDTLS_HAS_ALG_SHA_256_VIA_LOWLEVEL_OR_PSA)
  43. #define COOKIE_MD MBEDTLS_MD_SHA256
  44. #define COOKIE_MD_OUTLEN 32
  45. #define COOKIE_HMAC_LEN 28
  46. #elif defined(MBEDTLS_HAS_ALG_SHA_384_VIA_LOWLEVEL_OR_PSA)
  47. #define COOKIE_MD MBEDTLS_MD_SHA384
  48. #define COOKIE_MD_OUTLEN 48
  49. #define COOKIE_HMAC_LEN 28
  50. #else
  51. #error "DTLS hello verify needs SHA-256 or SHA-384"
  52. #endif
  53. /*
  54. * Cookies are formed of a 4-bytes timestamp (or serial number) and
  55. * an HMAC of timestamp and client ID.
  56. */
  57. #define COOKIE_LEN (4 + COOKIE_HMAC_LEN)
  58. void mbedtls_ssl_cookie_init(mbedtls_ssl_cookie_ctx *ctx)
  59. {
  60. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  61. ctx->psa_hmac_key = MBEDTLS_SVC_KEY_ID_INIT;
  62. #else
  63. mbedtls_md_init(&ctx->hmac_ctx);
  64. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  65. #if !defined(MBEDTLS_HAVE_TIME)
  66. ctx->serial = 0;
  67. #endif
  68. ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT;
  69. #if !defined(MBEDTLS_USE_PSA_CRYPTO)
  70. #if defined(MBEDTLS_THREADING_C)
  71. mbedtls_mutex_init(&ctx->mutex);
  72. #endif
  73. #endif /* !MBEDTLS_USE_PSA_CRYPTO */
  74. }
  75. void mbedtls_ssl_cookie_set_timeout(mbedtls_ssl_cookie_ctx *ctx, unsigned long delay)
  76. {
  77. ctx->timeout = delay;
  78. }
  79. void mbedtls_ssl_cookie_free(mbedtls_ssl_cookie_ctx *ctx)
  80. {
  81. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  82. psa_destroy_key(ctx->psa_hmac_key);
  83. #else
  84. mbedtls_md_free(&ctx->hmac_ctx);
  85. #if defined(MBEDTLS_THREADING_C)
  86. mbedtls_mutex_free(&ctx->mutex);
  87. #endif
  88. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  89. mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_cookie_ctx));
  90. }
  91. int mbedtls_ssl_cookie_setup(mbedtls_ssl_cookie_ctx *ctx,
  92. int (*f_rng)(void *, unsigned char *, size_t),
  93. void *p_rng)
  94. {
  95. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  96. psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
  97. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  98. psa_algorithm_t alg;
  99. (void) f_rng;
  100. (void) p_rng;
  101. alg = mbedtls_hash_info_psa_from_md(COOKIE_MD);
  102. if (alg == 0) {
  103. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  104. }
  105. ctx->psa_hmac_alg = PSA_ALG_TRUNCATED_MAC(PSA_ALG_HMAC(alg),
  106. COOKIE_HMAC_LEN);
  107. psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_MESSAGE |
  108. PSA_KEY_USAGE_SIGN_MESSAGE);
  109. psa_set_key_algorithm(&attributes, ctx->psa_hmac_alg);
  110. psa_set_key_type(&attributes, PSA_KEY_TYPE_HMAC);
  111. psa_set_key_bits(&attributes, PSA_BYTES_TO_BITS(COOKIE_MD_OUTLEN));
  112. if ((status = psa_generate_key(&attributes,
  113. &ctx->psa_hmac_key)) != PSA_SUCCESS) {
  114. return PSA_TO_MBEDTLS_ERR(status);
  115. }
  116. #else
  117. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  118. unsigned char key[COOKIE_MD_OUTLEN];
  119. if ((ret = f_rng(p_rng, key, sizeof(key))) != 0) {
  120. return ret;
  121. }
  122. ret = mbedtls_md_setup(&ctx->hmac_ctx, mbedtls_md_info_from_type(COOKIE_MD), 1);
  123. if (ret != 0) {
  124. return ret;
  125. }
  126. ret = mbedtls_md_hmac_starts(&ctx->hmac_ctx, key, sizeof(key));
  127. if (ret != 0) {
  128. return ret;
  129. }
  130. mbedtls_platform_zeroize(key, sizeof(key));
  131. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  132. return 0;
  133. }
  134. #if !defined(MBEDTLS_USE_PSA_CRYPTO)
  135. /*
  136. * Generate the HMAC part of a cookie
  137. */
  138. MBEDTLS_CHECK_RETURN_CRITICAL
  139. static int ssl_cookie_hmac(mbedtls_md_context_t *hmac_ctx,
  140. const unsigned char time[4],
  141. unsigned char **p, unsigned char *end,
  142. const unsigned char *cli_id, size_t cli_id_len)
  143. {
  144. unsigned char hmac_out[COOKIE_MD_OUTLEN];
  145. MBEDTLS_SSL_CHK_BUF_PTR(*p, end, COOKIE_HMAC_LEN);
  146. if (mbedtls_md_hmac_reset(hmac_ctx) != 0 ||
  147. mbedtls_md_hmac_update(hmac_ctx, time, 4) != 0 ||
  148. mbedtls_md_hmac_update(hmac_ctx, cli_id, cli_id_len) != 0 ||
  149. mbedtls_md_hmac_finish(hmac_ctx, hmac_out) != 0) {
  150. return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
  151. }
  152. memcpy(*p, hmac_out, COOKIE_HMAC_LEN);
  153. *p += COOKIE_HMAC_LEN;
  154. return 0;
  155. }
  156. #endif /* !MBEDTLS_USE_PSA_CRYPTO */
  157. /*
  158. * Generate cookie for DTLS ClientHello verification
  159. */
  160. int mbedtls_ssl_cookie_write(void *p_ctx,
  161. unsigned char **p, unsigned char *end,
  162. const unsigned char *cli_id, size_t cli_id_len)
  163. {
  164. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  165. psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
  166. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  167. size_t sign_mac_length = 0;
  168. #endif
  169. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  170. mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
  171. unsigned long t;
  172. if (ctx == NULL || cli_id == NULL) {
  173. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  174. }
  175. MBEDTLS_SSL_CHK_BUF_PTR(*p, end, COOKIE_LEN);
  176. #if defined(MBEDTLS_HAVE_TIME)
  177. t = (unsigned long) mbedtls_time(NULL);
  178. #else
  179. t = ctx->serial++;
  180. #endif
  181. MBEDTLS_PUT_UINT32_BE(t, *p, 0);
  182. *p += 4;
  183. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  184. status = psa_mac_sign_setup(&operation, ctx->psa_hmac_key,
  185. ctx->psa_hmac_alg);
  186. if (status != PSA_SUCCESS) {
  187. ret = PSA_TO_MBEDTLS_ERR(status);
  188. goto exit;
  189. }
  190. status = psa_mac_update(&operation, *p - 4, 4);
  191. if (status != PSA_SUCCESS) {
  192. ret = PSA_TO_MBEDTLS_ERR(status);
  193. goto exit;
  194. }
  195. status = psa_mac_update(&operation, cli_id, cli_id_len);
  196. if (status != PSA_SUCCESS) {
  197. ret = PSA_TO_MBEDTLS_ERR(status);
  198. goto exit;
  199. }
  200. status = psa_mac_sign_finish(&operation, *p, COOKIE_MD_OUTLEN,
  201. &sign_mac_length);
  202. if (status != PSA_SUCCESS) {
  203. ret = PSA_TO_MBEDTLS_ERR(status);
  204. goto exit;
  205. }
  206. *p += COOKIE_HMAC_LEN;
  207. ret = 0;
  208. #else
  209. #if defined(MBEDTLS_THREADING_C)
  210. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  211. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret);
  212. }
  213. #endif
  214. ret = ssl_cookie_hmac(&ctx->hmac_ctx, *p - 4,
  215. p, end, cli_id, cli_id_len);
  216. #if defined(MBEDTLS_THREADING_C)
  217. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  218. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR,
  219. MBEDTLS_ERR_THREADING_MUTEX_ERROR);
  220. }
  221. #endif
  222. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  223. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  224. exit:
  225. status = psa_mac_abort(&operation);
  226. if (status != PSA_SUCCESS) {
  227. ret = PSA_TO_MBEDTLS_ERR(status);
  228. }
  229. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  230. return ret;
  231. }
  232. /*
  233. * Check a cookie
  234. */
  235. int mbedtls_ssl_cookie_check(void *p_ctx,
  236. const unsigned char *cookie, size_t cookie_len,
  237. const unsigned char *cli_id, size_t cli_id_len)
  238. {
  239. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  240. psa_mac_operation_t operation = PSA_MAC_OPERATION_INIT;
  241. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  242. #else
  243. unsigned char ref_hmac[COOKIE_HMAC_LEN];
  244. unsigned char *p = ref_hmac;
  245. #endif
  246. int ret = 0;
  247. mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx;
  248. unsigned long cur_time, cookie_time;
  249. if (ctx == NULL || cli_id == NULL) {
  250. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  251. }
  252. if (cookie_len != COOKIE_LEN) {
  253. return -1;
  254. }
  255. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  256. status = psa_mac_verify_setup(&operation, ctx->psa_hmac_key,
  257. ctx->psa_hmac_alg);
  258. if (status != PSA_SUCCESS) {
  259. ret = PSA_TO_MBEDTLS_ERR(status);
  260. goto exit;
  261. }
  262. status = psa_mac_update(&operation, cookie, 4);
  263. if (status != PSA_SUCCESS) {
  264. ret = PSA_TO_MBEDTLS_ERR(status);
  265. goto exit;
  266. }
  267. status = psa_mac_update(&operation, cli_id,
  268. cli_id_len);
  269. if (status != PSA_SUCCESS) {
  270. ret = PSA_TO_MBEDTLS_ERR(status);
  271. goto exit;
  272. }
  273. status = psa_mac_verify_finish(&operation, cookie + 4,
  274. COOKIE_HMAC_LEN);
  275. if (status != PSA_SUCCESS) {
  276. ret = PSA_TO_MBEDTLS_ERR(status);
  277. goto exit;
  278. }
  279. ret = 0;
  280. #else
  281. #if defined(MBEDTLS_THREADING_C)
  282. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  283. return MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR, ret);
  284. }
  285. #endif
  286. if (ssl_cookie_hmac(&ctx->hmac_ctx, cookie,
  287. &p, p + sizeof(ref_hmac),
  288. cli_id, cli_id_len) != 0) {
  289. ret = -1;
  290. }
  291. #if defined(MBEDTLS_THREADING_C)
  292. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  293. ret = MBEDTLS_ERROR_ADD(MBEDTLS_ERR_SSL_INTERNAL_ERROR,
  294. MBEDTLS_ERR_THREADING_MUTEX_ERROR);
  295. }
  296. #endif
  297. if (ret != 0) {
  298. goto exit;
  299. }
  300. if (mbedtls_ct_memcmp(cookie + 4, ref_hmac, sizeof(ref_hmac)) != 0) {
  301. ret = -1;
  302. goto exit;
  303. }
  304. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  305. #if defined(MBEDTLS_HAVE_TIME)
  306. cur_time = (unsigned long) mbedtls_time(NULL);
  307. #else
  308. cur_time = ctx->serial;
  309. #endif
  310. cookie_time = ((unsigned long) cookie[0] << 24) |
  311. ((unsigned long) cookie[1] << 16) |
  312. ((unsigned long) cookie[2] << 8) |
  313. ((unsigned long) cookie[3]);
  314. if (ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout) {
  315. ret = -1;
  316. goto exit;
  317. }
  318. exit:
  319. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  320. status = psa_mac_abort(&operation);
  321. if (status != PSA_SUCCESS) {
  322. ret = PSA_TO_MBEDTLS_ERR(status);
  323. }
  324. #else
  325. mbedtls_platform_zeroize(ref_hmac, sizeof(ref_hmac));
  326. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  327. return ret;
  328. }
  329. #endif /* MBEDTLS_SSL_COOKIE_C */