ssl_ticket.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  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 "ssl_misc.h"
  11. #include "mbedtls/ssl_ticket.h"
  12. #include "mbedtls/error.h"
  13. #include "mbedtls/platform_util.h"
  14. #include <string.h>
  15. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  16. /* Define a local translating function to save code size by not using too many
  17. * arguments in each translating place. */
  18. static int local_err_translation(psa_status_t status)
  19. {
  20. return psa_status_to_mbedtls(status, psa_to_ssl_errors,
  21. ARRAY_LENGTH(psa_to_ssl_errors),
  22. psa_generic_status_to_mbedtls);
  23. }
  24. #define PSA_TO_MBEDTLS_ERR(status) local_err_translation(status)
  25. #endif
  26. /*
  27. * Initialize context
  28. */
  29. void mbedtls_ssl_ticket_init(mbedtls_ssl_ticket_context *ctx)
  30. {
  31. memset(ctx, 0, sizeof(mbedtls_ssl_ticket_context));
  32. #if defined(MBEDTLS_THREADING_C)
  33. mbedtls_mutex_init(&ctx->mutex);
  34. #endif
  35. }
  36. #define MAX_KEY_BYTES MBEDTLS_SSL_TICKET_MAX_KEY_BYTES
  37. #define TICKET_KEY_NAME_BYTES MBEDTLS_SSL_TICKET_KEY_NAME_BYTES
  38. #define TICKET_IV_BYTES 12
  39. #define TICKET_CRYPT_LEN_BYTES 2
  40. #define TICKET_AUTH_TAG_BYTES 16
  41. #define TICKET_MIN_LEN (TICKET_KEY_NAME_BYTES + \
  42. TICKET_IV_BYTES + \
  43. TICKET_CRYPT_LEN_BYTES + \
  44. TICKET_AUTH_TAG_BYTES)
  45. #define TICKET_ADD_DATA_LEN (TICKET_KEY_NAME_BYTES + \
  46. TICKET_IV_BYTES + \
  47. TICKET_CRYPT_LEN_BYTES)
  48. /*
  49. * Generate/update a key
  50. */
  51. MBEDTLS_CHECK_RETURN_CRITICAL
  52. static int ssl_ticket_gen_key(mbedtls_ssl_ticket_context *ctx,
  53. unsigned char index)
  54. {
  55. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  56. unsigned char buf[MAX_KEY_BYTES] = { 0 };
  57. mbedtls_ssl_ticket_key *key = ctx->keys + index;
  58. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  59. psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
  60. #endif
  61. #if defined(MBEDTLS_HAVE_TIME)
  62. key->generation_time = mbedtls_time(NULL);
  63. #endif
  64. /* The lifetime of a key is the configured lifetime of the tickets when
  65. * the key is created.
  66. */
  67. key->lifetime = ctx->ticket_lifetime;
  68. if ((ret = ctx->f_rng(ctx->p_rng, key->name, sizeof(key->name))) != 0) {
  69. return ret;
  70. }
  71. if ((ret = ctx->f_rng(ctx->p_rng, buf, sizeof(buf))) != 0) {
  72. return ret;
  73. }
  74. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  75. psa_set_key_usage_flags(&attributes,
  76. PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  77. psa_set_key_algorithm(&attributes, key->alg);
  78. psa_set_key_type(&attributes, key->key_type);
  79. psa_set_key_bits(&attributes, key->key_bits);
  80. ret = PSA_TO_MBEDTLS_ERR(
  81. psa_import_key(&attributes, buf,
  82. PSA_BITS_TO_BYTES(key->key_bits),
  83. &key->key));
  84. #else
  85. /* With GCM and CCM, same context can encrypt & decrypt */
  86. ret = mbedtls_cipher_setkey(&key->ctx, buf,
  87. mbedtls_cipher_get_key_bitlen(&key->ctx),
  88. MBEDTLS_ENCRYPT);
  89. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  90. mbedtls_platform_zeroize(buf, sizeof(buf));
  91. return ret;
  92. }
  93. /*
  94. * Rotate/generate keys if necessary
  95. */
  96. MBEDTLS_CHECK_RETURN_CRITICAL
  97. static int ssl_ticket_update_keys(mbedtls_ssl_ticket_context *ctx)
  98. {
  99. #if !defined(MBEDTLS_HAVE_TIME)
  100. ((void) ctx);
  101. #else
  102. mbedtls_ssl_ticket_key * const key = ctx->keys + ctx->active;
  103. if (key->lifetime != 0) {
  104. mbedtls_time_t current_time = mbedtls_time(NULL);
  105. mbedtls_time_t key_time = key->generation_time;
  106. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  107. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  108. #endif
  109. if (current_time >= key_time &&
  110. (uint64_t) (current_time - key_time) < key->lifetime) {
  111. return 0;
  112. }
  113. ctx->active = 1 - ctx->active;
  114. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  115. if ((status = psa_destroy_key(ctx->keys[ctx->active].key)) != PSA_SUCCESS) {
  116. return PSA_TO_MBEDTLS_ERR(status);
  117. }
  118. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  119. return ssl_ticket_gen_key(ctx, ctx->active);
  120. } else
  121. #endif /* MBEDTLS_HAVE_TIME */
  122. return 0;
  123. }
  124. /*
  125. * Rotate active session ticket encryption key
  126. */
  127. int mbedtls_ssl_ticket_rotate(mbedtls_ssl_ticket_context *ctx,
  128. const unsigned char *name, size_t nlength,
  129. const unsigned char *k, size_t klength,
  130. uint32_t lifetime)
  131. {
  132. const unsigned char idx = 1 - ctx->active;
  133. mbedtls_ssl_ticket_key * const key = ctx->keys + idx;
  134. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  135. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  136. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  137. psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
  138. const size_t bitlen = key->key_bits;
  139. #else
  140. const int bitlen = mbedtls_cipher_get_key_bitlen(&key->ctx);
  141. #endif
  142. if (nlength < TICKET_KEY_NAME_BYTES || klength * 8 < (size_t) bitlen) {
  143. return MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA;
  144. }
  145. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  146. if ((status = psa_destroy_key(key->key)) != PSA_SUCCESS) {
  147. ret = PSA_TO_MBEDTLS_ERR(status);
  148. return ret;
  149. }
  150. psa_set_key_usage_flags(&attributes,
  151. PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
  152. psa_set_key_algorithm(&attributes, key->alg);
  153. psa_set_key_type(&attributes, key->key_type);
  154. psa_set_key_bits(&attributes, key->key_bits);
  155. if ((status = psa_import_key(&attributes, k,
  156. PSA_BITS_TO_BYTES(key->key_bits),
  157. &key->key)) != PSA_SUCCESS) {
  158. ret = PSA_TO_MBEDTLS_ERR(status);
  159. return ret;
  160. }
  161. #else
  162. ret = mbedtls_cipher_setkey(&key->ctx, k, bitlen, MBEDTLS_ENCRYPT);
  163. if (ret != 0) {
  164. return ret;
  165. }
  166. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  167. ctx->active = idx;
  168. ctx->ticket_lifetime = lifetime;
  169. memcpy(key->name, name, TICKET_KEY_NAME_BYTES);
  170. #if defined(MBEDTLS_HAVE_TIME)
  171. key->generation_time = mbedtls_time(NULL);
  172. #endif
  173. key->lifetime = lifetime;
  174. return 0;
  175. }
  176. /*
  177. * Setup context for actual use
  178. */
  179. int mbedtls_ssl_ticket_setup(mbedtls_ssl_ticket_context *ctx,
  180. int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
  181. mbedtls_cipher_type_t cipher,
  182. uint32_t lifetime)
  183. {
  184. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  185. size_t key_bits;
  186. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  187. psa_algorithm_t alg;
  188. psa_key_type_t key_type;
  189. #else
  190. const mbedtls_cipher_info_t *cipher_info;
  191. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  192. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  193. if (mbedtls_ssl_cipher_to_psa(cipher, TICKET_AUTH_TAG_BYTES,
  194. &alg, &key_type, &key_bits) != PSA_SUCCESS) {
  195. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  196. }
  197. if (PSA_ALG_IS_AEAD(alg) == 0) {
  198. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  199. }
  200. #else
  201. cipher_info = mbedtls_cipher_info_from_type(cipher);
  202. if (mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_GCM &&
  203. mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CCM &&
  204. mbedtls_cipher_info_get_mode(cipher_info) != MBEDTLS_MODE_CHACHAPOLY) {
  205. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  206. }
  207. key_bits = mbedtls_cipher_info_get_key_bitlen(cipher_info);
  208. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  209. if (key_bits > 8 * MAX_KEY_BYTES) {
  210. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  211. }
  212. ctx->f_rng = f_rng;
  213. ctx->p_rng = p_rng;
  214. ctx->ticket_lifetime = lifetime;
  215. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  216. ctx->keys[0].alg = alg;
  217. ctx->keys[0].key_type = key_type;
  218. ctx->keys[0].key_bits = key_bits;
  219. ctx->keys[1].alg = alg;
  220. ctx->keys[1].key_type = key_type;
  221. ctx->keys[1].key_bits = key_bits;
  222. #else
  223. if ((ret = mbedtls_cipher_setup(&ctx->keys[0].ctx, cipher_info)) != 0) {
  224. return ret;
  225. }
  226. if ((ret = mbedtls_cipher_setup(&ctx->keys[1].ctx, cipher_info)) != 0) {
  227. return ret;
  228. }
  229. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  230. if ((ret = ssl_ticket_gen_key(ctx, 0)) != 0 ||
  231. (ret = ssl_ticket_gen_key(ctx, 1)) != 0) {
  232. return ret;
  233. }
  234. return 0;
  235. }
  236. /*
  237. * Create session ticket, with the following structure:
  238. *
  239. * struct {
  240. * opaque key_name[4];
  241. * opaque iv[12];
  242. * opaque encrypted_state<0..2^16-1>;
  243. * opaque tag[16];
  244. * } ticket;
  245. *
  246. * The key_name, iv, and length of encrypted_state are the additional
  247. * authenticated data.
  248. */
  249. int mbedtls_ssl_ticket_write(void *p_ticket,
  250. const mbedtls_ssl_session *session,
  251. unsigned char *start,
  252. const unsigned char *end,
  253. size_t *tlen,
  254. uint32_t *ticket_lifetime)
  255. {
  256. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  257. mbedtls_ssl_ticket_context *ctx = p_ticket;
  258. mbedtls_ssl_ticket_key *key;
  259. unsigned char *key_name = start;
  260. unsigned char *iv = start + TICKET_KEY_NAME_BYTES;
  261. unsigned char *state_len_bytes = iv + TICKET_IV_BYTES;
  262. unsigned char *state = state_len_bytes + TICKET_CRYPT_LEN_BYTES;
  263. size_t clear_len, ciph_len;
  264. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  265. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  266. #endif
  267. *tlen = 0;
  268. if (ctx == NULL || ctx->f_rng == NULL) {
  269. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  270. }
  271. /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag,
  272. * in addition to session itself, that will be checked when writing it. */
  273. MBEDTLS_SSL_CHK_BUF_PTR(start, end, TICKET_MIN_LEN);
  274. #if defined(MBEDTLS_THREADING_C)
  275. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  276. return ret;
  277. }
  278. #endif
  279. if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
  280. goto cleanup;
  281. }
  282. key = &ctx->keys[ctx->active];
  283. *ticket_lifetime = key->lifetime;
  284. memcpy(key_name, key->name, TICKET_KEY_NAME_BYTES);
  285. if ((ret = ctx->f_rng(ctx->p_rng, iv, TICKET_IV_BYTES)) != 0) {
  286. goto cleanup;
  287. }
  288. /* Dump session state */
  289. if ((ret = mbedtls_ssl_session_save(session,
  290. state, (size_t) (end - state),
  291. &clear_len)) != 0 ||
  292. (unsigned long) clear_len > 65535) {
  293. goto cleanup;
  294. }
  295. MBEDTLS_PUT_UINT16_BE(clear_len, state_len_bytes, 0);
  296. /* Encrypt and authenticate */
  297. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  298. if ((status = psa_aead_encrypt(key->key, key->alg, iv, TICKET_IV_BYTES,
  299. key_name, TICKET_ADD_DATA_LEN,
  300. state, clear_len,
  301. state, end - state,
  302. &ciph_len)) != PSA_SUCCESS) {
  303. ret = PSA_TO_MBEDTLS_ERR(status);
  304. goto cleanup;
  305. }
  306. #else
  307. if ((ret = mbedtls_cipher_auth_encrypt_ext(&key->ctx,
  308. iv, TICKET_IV_BYTES,
  309. /* Additional data: key name, IV and length */
  310. key_name, TICKET_ADD_DATA_LEN,
  311. state, clear_len,
  312. state, (size_t) (end - state), &ciph_len,
  313. TICKET_AUTH_TAG_BYTES)) != 0) {
  314. goto cleanup;
  315. }
  316. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  317. if (ciph_len != clear_len + TICKET_AUTH_TAG_BYTES) {
  318. ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
  319. goto cleanup;
  320. }
  321. *tlen = TICKET_MIN_LEN + ciph_len - TICKET_AUTH_TAG_BYTES;
  322. cleanup:
  323. #if defined(MBEDTLS_THREADING_C)
  324. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  325. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  326. }
  327. #endif
  328. return ret;
  329. }
  330. /*
  331. * Select key based on name
  332. */
  333. static mbedtls_ssl_ticket_key *ssl_ticket_select_key(
  334. mbedtls_ssl_ticket_context *ctx,
  335. const unsigned char name[4])
  336. {
  337. unsigned char i;
  338. for (i = 0; i < sizeof(ctx->keys) / sizeof(*ctx->keys); i++) {
  339. if (memcmp(name, ctx->keys[i].name, 4) == 0) {
  340. return &ctx->keys[i];
  341. }
  342. }
  343. return NULL;
  344. }
  345. /*
  346. * Load session ticket (see mbedtls_ssl_ticket_write for structure)
  347. */
  348. int mbedtls_ssl_ticket_parse(void *p_ticket,
  349. mbedtls_ssl_session *session,
  350. unsigned char *buf,
  351. size_t len)
  352. {
  353. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  354. mbedtls_ssl_ticket_context *ctx = p_ticket;
  355. mbedtls_ssl_ticket_key *key;
  356. unsigned char *key_name = buf;
  357. unsigned char *iv = buf + TICKET_KEY_NAME_BYTES;
  358. unsigned char *enc_len_p = iv + TICKET_IV_BYTES;
  359. unsigned char *ticket = enc_len_p + TICKET_CRYPT_LEN_BYTES;
  360. size_t enc_len, clear_len;
  361. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  362. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  363. #endif
  364. if (ctx == NULL || ctx->f_rng == NULL) {
  365. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  366. }
  367. if (len < TICKET_MIN_LEN) {
  368. return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  369. }
  370. #if defined(MBEDTLS_THREADING_C)
  371. if ((ret = mbedtls_mutex_lock(&ctx->mutex)) != 0) {
  372. return ret;
  373. }
  374. #endif
  375. if ((ret = ssl_ticket_update_keys(ctx)) != 0) {
  376. goto cleanup;
  377. }
  378. enc_len = MBEDTLS_GET_UINT16_BE(enc_len_p, 0);
  379. if (len != TICKET_MIN_LEN + enc_len) {
  380. ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
  381. goto cleanup;
  382. }
  383. /* Select key */
  384. if ((key = ssl_ticket_select_key(ctx, key_name)) == NULL) {
  385. /* We can't know for sure but this is a likely option unless we're
  386. * under attack - this is only informative anyway */
  387. ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
  388. goto cleanup;
  389. }
  390. /* Decrypt and authenticate */
  391. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  392. if ((status = psa_aead_decrypt(key->key, key->alg, iv, TICKET_IV_BYTES,
  393. key_name, TICKET_ADD_DATA_LEN,
  394. ticket, enc_len + TICKET_AUTH_TAG_BYTES,
  395. ticket, enc_len, &clear_len)) != PSA_SUCCESS) {
  396. ret = PSA_TO_MBEDTLS_ERR(status);
  397. goto cleanup;
  398. }
  399. #else
  400. if ((ret = mbedtls_cipher_auth_decrypt_ext(&key->ctx,
  401. iv, TICKET_IV_BYTES,
  402. /* Additional data: key name, IV and length */
  403. key_name, TICKET_ADD_DATA_LEN,
  404. ticket, enc_len + TICKET_AUTH_TAG_BYTES,
  405. ticket, enc_len, &clear_len,
  406. TICKET_AUTH_TAG_BYTES)) != 0) {
  407. if (ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED) {
  408. ret = MBEDTLS_ERR_SSL_INVALID_MAC;
  409. }
  410. goto cleanup;
  411. }
  412. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  413. if (clear_len != enc_len) {
  414. ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR;
  415. goto cleanup;
  416. }
  417. /* Actually load session */
  418. if ((ret = mbedtls_ssl_session_load(session, ticket, clear_len)) != 0) {
  419. goto cleanup;
  420. }
  421. #if defined(MBEDTLS_HAVE_TIME)
  422. mbedtls_ms_time_t ticket_creation_time, ticket_age;
  423. mbedtls_ms_time_t ticket_lifetime =
  424. (mbedtls_ms_time_t) key->lifetime * 1000;
  425. ret = mbedtls_ssl_session_get_ticket_creation_time(session,
  426. &ticket_creation_time);
  427. if (ret != 0) {
  428. goto cleanup;
  429. }
  430. ticket_age = mbedtls_ms_time() - ticket_creation_time;
  431. if (ticket_age < 0 || ticket_age > ticket_lifetime) {
  432. ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED;
  433. goto cleanup;
  434. }
  435. #endif
  436. cleanup:
  437. #if defined(MBEDTLS_THREADING_C)
  438. if (mbedtls_mutex_unlock(&ctx->mutex) != 0) {
  439. return MBEDTLS_ERR_THREADING_MUTEX_ERROR;
  440. }
  441. #endif
  442. return ret;
  443. }
  444. /*
  445. * Free context
  446. */
  447. void mbedtls_ssl_ticket_free(mbedtls_ssl_ticket_context *ctx)
  448. {
  449. if (ctx == NULL) {
  450. return;
  451. }
  452. #if defined(MBEDTLS_USE_PSA_CRYPTO)
  453. psa_destroy_key(ctx->keys[0].key);
  454. psa_destroy_key(ctx->keys[1].key);
  455. #else
  456. mbedtls_cipher_free(&ctx->keys[0].ctx);
  457. mbedtls_cipher_free(&ctx->keys[1].ctx);
  458. #endif /* MBEDTLS_USE_PSA_CRYPTO */
  459. #if defined(MBEDTLS_THREADING_C)
  460. mbedtls_mutex_free(&ctx->mutex);
  461. #endif
  462. mbedtls_platform_zeroize(ctx, sizeof(mbedtls_ssl_ticket_context));
  463. }
  464. #endif /* MBEDTLS_SSL_TICKET_C */