ssl_cookie.c 10 KB

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