ssl_ticket.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * TLS server tickets callbacks implementation
  3. *
  4. * Copyright The Mbed TLS Contributors
  5. * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
  6. */
  7. #include "common.h"
  8. #if defined(MBEDTLS_SSL_TICKET_C)
  9. #include "mbedtls/platform.h"
  10. #include "mbedtls/ssl_internal.h"
  11. #include "mbedtls/ssl_ticket.h"
  12. #include "mbedtls/error.h"
  13. #include "mbedtls/platform_util.h"
  14. #include <string.h>
  15. /*
  16. * Initialize context
  17. */
  18. void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx)
  19. {
  20. memset(ctx, 0, sizeof(mbedtls_ssl_ticket_context));
  21. #if defined(MBEDTLS_THREADING_C)
  22. mbedtls_mutex_init(&ctx->mutex);
  23. #endif
  24. }
  25. #define MAX_KEY_BYTES 32 /* 256 bits */
  26. #define TICKET_KEY_NAME_BYTES 4
  27. #define TICKET_IV_BYTES 12
  28. #define TICKET_CRYPT_LEN_BYTES 2
  29. #define TICKET_AUTH_TAG_BYTES 16
  30. #define TICKET_MIN_LEN (TICKET_KEY_NAME_BYTES + \
  31. TICKET_IV_BYTES + \
  32. TICKET_CRYPT_LEN_BYTES + \
  33. TICKET_AUTH_TAG_BYTES)
  34. #define TICKET_ADD_DATA_LEN (TICKET_KEY_NAME_BYTES + \
  35. TICKET_IV_BYTES + \
  36. TICKET_CRYPT_LEN_BYTES)
  37. /*
  38. * Generate/update a key
  39. */
  40. MBEDTLS_CHECK_RETURN_CRITICAL
  41. static int ssl_ticket_gen_key(mbedtls_ssl_ticket_context *ctx,
  42. unsigned char index)
  43. {
  44. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  45. unsigned char buf[MAX_KEY_BYTES];
  46. mbedtls_ssl_ticket_key *key = ctx->keys + index;
  47. #if defined(MBEDTLS_HAVE_TIME)
  48. key->generation_time = (uint32_t) mbedtls_time(NULL);
  49. #endif
  50. if ((ret = ctx->f_rng(ctx->p_rng, key->name, sizeof(key->name))) != 0) {
  51. return ret;
  52. }
  53. if ((ret = ctx->f_rng(ctx->p_rng, buf, sizeof(buf))) != 0) {
  54. return ret;
  55. }
  56. /* With GCM and CCM, same context can encrypt & decrypt */
  57. ret = mbedtls_cipher_setkey(&key->ctx, buf,
  58. mbedtls_cipher_get_key_bitlen(&key->ctx),
  59. MBEDTLS_ENCRYPT);
  60. mbedtls_platform_zeroize(buf, sizeof(buf));
  61. return ret;
  62. }
  63. /*
  64. * Rotate/generate keys if necessary
  65. */
  66. MBEDTLS_CHECK_RETURN_CRITICAL
  67. static int ssl_ticket_update_keys(mbedtls_ssl_ticket_context *ctx)
  68. {
  69. #if !defined(MBEDTLS_HAVE_TIME)
  70. ((void) ctx);
  71. #else
  72. if (ctx->ticket_lifetime != 0) {
  73. uint32_t current_time = (uint32_t) mbedtls_time(NULL);
  74. uint32_t key_time = ctx->keys[ctx->active].generation_time;
  75. if (current_time >= key_time &&
  76. current_time - key_time < ctx->ticket_lifetime) {
  77. return 0;
  78. }
  79. ctx->active = 1 - ctx->active;
  80. return ssl_ticket_gen_key(ctx, ctx->active);
  81. } else
  82. #endif /* MBEDTLS_HAVE_TIME */
  83. return 0;
  84. }
  85. /*
  86. * Setup context for actual use
  87. */
  88. int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx,
  89. int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
  90. mbedtls_cipher_type_t cipher,
  91. uint32_t lifetime)
  92. {
  93. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  94. const mbedtls_cipher_info_t *cipher_info;
  95. ctx->f_rng = f_rng;
  96. ctx->p_rng = p_rng;
  97. ctx->ticket_lifetime = lifetime;
  98. cipher_info = mbedtls_cipher_info_from_type(cipher);
  99. if (cipher_info == NULL) {
  100. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  101. }
  102. if (cipher_info->mode != MBEDTLS_MODE_GCM &&
  103. cipher_info->mode != MBEDTLS_MODE_CCM) {
  104. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  105. }
  106. if (cipher_info->key_bitlen > 8 * MAX_KEY_BYTES) {
  107. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  108. }
  109. int do_mbedtls_cipher_setup = 1;
  110. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  111. ret = mbedtls_cipher_setup_psa(&ctx->keys[0].ctx,
  112. cipher_info, TICKET_AUTH_TAG_BYTES);
  113. switch (ret) {
  114. case 0:
  115. do_mbedtls_cipher_setup = 0;
  116. break;
  117. case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
  118. /* We don't yet expect to support all ciphers through PSA,
  119. * so allow fallback to ordinary mbedtls_cipher_setup(). */
  120. do_mbedtls_cipher_setup = 1;
  121. break;
  122. default:
  123. return ret;
  124. }
  125. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  126. if (do_mbedtls_cipher_setup) {
  127. if ((ret = mbedtls_cipher_setup(&ctx->keys[0].ctx, cipher_info))
  128. != 0) {
  129. return ret;
  130. }
  131. }
  132. do_mbedtls_cipher_setup = 1;
  133. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  134. do_mbedtls_cipher_setup = 0;
  135. ret = mbedtls_cipher_setup_psa(&ctx->keys[1].ctx,
  136. cipher_info, TICKET_AUTH_TAG_BYTES);
  137. if (ret != 0 && ret != MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) {
  138. return ret;
  139. }
  140. if (ret == MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) {
  141. do_mbedtls_cipher_setup = 1;
  142. }
  143. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  144. if (do_mbedtls_cipher_setup) {
  145. if ((ret = mbedtls_cipher_setup(&ctx->keys[1].ctx, cipher_info))
  146. != 0) {
  147. return ret;
  148. }
  149. }
  150. if ((ret = ssl_ticket_gen_key(ctx, 0)) != 0 ||
  151. (ret = ssl_ticket_gen_key(ctx, 1)) != 0) {
  152. return ret;
  153. }
  154. return 0;
  155. }
  156. /*
  157. * Create session ticket, with the following structure:
  158. *
  159. * struct {
  160. * opaque key_name[4];
  161. * opaque iv[12];
  162. * opaque encrypted_state<0..2^16-1>;
  163. * opaque tag[16];
  164. * } ticket;
  165. *
  166. * The key_name, iv, and length of encrypted_state are the additional
  167. * authenticated data.
  168. */
  169. int mbedtls_ssl_ticket_write(void *p_ticket,
  170. const mbedtls_ssl_session *session,
  171. unsigned char *start,
  172. const unsigned char *end,
  173. size_t *tlen,
  174. uint32_t *ticket_lifetime)
  175. {
  176. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  177. mbedtls_ssl_ticket_context *ctx = p_ticket;
  178. mbedtls_ssl_ticket_key *key;
  179. unsigned char *key_name = start;
  180. unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
  181. unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
  182. unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
  183. size_t clear_len, ciph_len;
  184. *tlen = 0;
  185. if (ctx == NULL || ctx->f_rng == NULL) {
  186. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  187. }
  188. /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag,
  189. * in addition to session itself, that will be checked when writing it. */
  190. MBEDTLS_SSL_CHK_BUF_PTR(start, end, TICKET_MIN_LEN);
  191. #if defined(MBEDTLS_THREADING_C)
  192. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  193. return ret;
  194. }
  195. #endif
  196. if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
  197. goto cleanup;
  198. }
  199. key = &ctx->keys[ctx->active];
  200. *ticket_lifetime = ctx->ticket_lifetime;
  201. memcpy(key_name, key->name, TICKET_KEY_NAME_BYTES);
  202. if ((ret = ctx->f_rng(ctx->p_rng, iv, TICKET_IV_BYTES)) != 0) {
  203. goto cleanup;
  204. }
  205. /* Dump session state */
  206. if ((ret = mbedtls_ssl_session_save(session,
  207. state, end - state,
  208. &clear_len)) != 0 ||
  209. (unsigned long) clear_len > 65535) {
  210. goto cleanup;
  211. }
  212. MBEDTLS_PUT_UINT16_BE(clear_len, state_len_bytes, 0);
  213. /* Encrypt and authenticate */
  214. if ((ret = mbedtls_cipher_auth_encrypt_ext(&key->ctx,
  215. iv, TICKET_IV_BYTES,
  216. /* Additional data: key name, IV and length */
  217. key_name, TICKET_ADD_DATA_LEN,
  218. state, clear_len,
  219. state, end - state, &ciph_len,
  220. TICKET_AUTH_TAG_BYTES)) != 0) {
  221. goto cleanup;
  222. }
  223. if (ciph_len != clear_len + TICKET_AUTH_TAG_BYTES) {
  224. ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
  225. goto cleanup;
  226. }
  227. *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES;
  228. cleanup:
  229. #if defined(MBEDTLS_THREADING_C)
  230. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  231. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  232. }
  233. #endif
  234. return ret;
  235. }
  236. /*
  237. * Select key based on name
  238. */
  239. static mbedtls_ssl_ticket_key *ssl_ticket_select_key(
  240. mbedtls_ssl_ticket_context *ctx,
  241. const unsigned char name[4])
  242. {
  243. unsigned char i;
  244. for (i = 0; i < sizeof(ctx->keys) / sizeof(*ctx->keys); i++) {
  245. if (memcmp(name, ctx->keys[i].name, 4) == 0) {
  246. return &ctx->keys[i];
  247. }
  248. }
  249. return NULL;
  250. }
  251. /*
  252. * Load session ticket (see mbedtls_ssl_ticket_write for structure)
  253. */
  254. int mbedtls_ssl_ticket_parse(void *p_ticket,
  255. mbedtls_ssl_session *session,
  256. unsigned char *buf,
  257. size_t len)
  258. {
  259. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  260. mbedtls_ssl_ticket_context *ctx = p_ticket;
  261. mbedtls_ssl_ticket_key *key;
  262. unsigned char *key_name = buf;
  263. unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
  264. unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
  265. unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
  266. size_t enc_len, clear_len;
  267. if (ctx == NULL || ctx->f_rng == NULL) {
  268. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  269. }
  270. if (len < TICKET_MIN_LEN) {
  271. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  272. }
  273. #if defined(MBEDTLS_THREADING_C)
  274. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  275. return ret;
  276. }
  277. #endif
  278. if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
  279. goto cleanup;
  280. }
  281. enc_len = (enc_len_p[0] << 8) | enc_len_p[1];
  282. if (len != TICKET_MIN_LEN + enc_len) {
  283. ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  284. goto cleanup;
  285. }
  286. /* Select key */
  287. if ((key = ssl_ticket_select_key(ctx, key_name)) == NULL) {
  288. /* We can't know for sure but this is a likely option unless we're
  289. * under attack - this is only informative anyway */
  290. ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
  291. goto cleanup;
  292. }
  293. /* Decrypt and authenticate */
  294. if ((ret = mbedtls_cipher_auth_decrypt_ext(&key->ctx,
  295. iv, TICKET_IV_BYTES,
  296. /* Additional data: key name, IV and length */
  297. key_name, TICKET_ADD_DATA_LEN,
  298. ticket, enc_len + TICKET_AUTH_TAG_BYTES,
  299. ticket, enc_len, &clear_len,
  300. TICKET_AUTH_TAG_BYTES)) != 0) {
  301. if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
  302. ret = MBEDTLS_ERR_SSL_INVALID_MAC;
  303. }
  304. goto cleanup;
  305. }
  306. if (clear_len != enc_len) {
  307. ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
  308. goto cleanup;
  309. }
  310. /* Actually load session */
  311. if ((ret = mbedtls_ssl_session_load(session, ticket, clear_len)) != 0) {
  312. goto cleanup;
  313. }
  314. #if defined(MBEDTLS_HAVE_TIME)
  315. {
  316. /* Check for expiration */
  317. mbedtls_time_t current_time = mbedtls_time(NULL);
  318. if (current_time < session->start ||
  319. (uint32_t) (current_time - session->start) > ctx->ticket_lifetime) {
  320. ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
  321. goto cleanup;
  322. }
  323. }
  324. #endif
  325. cleanup:
  326. #if defined(MBEDTLS_THREADING_C)
  327. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  328. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  329. }
  330. #endif
  331. return ret;
  332. }
  333. /*
  334. * Free context
  335. */
  336. void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx)
  337. {
  338. mbedtls_cipher_free(&ctx->keys[0].ctx);
  339. mbedtls_cipher_free(&ctx->keys[1].ctx);
  340. #if defined(MBEDTLS_THREADING_C)
  341. mbedtls_mutex_free(&ctx->mutex);
  342. #endif
  343. mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_ticket_context));
  344. }
  345. #endif /* MBEDTLS_SSL_TICKET_C */