psa_crypto_ecp.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  1. /*
  2. * PSA ECP layer on top of Mbed TLS crypto
  3. */
  4. /*
  5. * Copyright The Mbed TLS Contributors
  6. * SPDX-License-Identifier: Apache-2.0
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License"); you may
  9. * not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  16. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. */
  20. #include "common.h"
  21. #if defined(MBEDTLS_PSA_CRYPTO_C)
  22. #include <psa/crypto.h>
  23. #include "psa_crypto_core.h"
  24. #include "psa_crypto_ecp.h"
  25. #include "psa_crypto_random_impl.h"
  26. #include "hash_info.h"
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include "mbedtls/platform.h"
  30. #include <mbedtls/ecdsa.h>
  31. #include <mbedtls/ecdh.h>
  32. #include <mbedtls/ecp.h>
  33. #include <mbedtls/error.h>
  34. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
  35. defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
  36. defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
  37. defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
  38. defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
  39. psa_status_t mbedtls_psa_ecp_load_representation(
  40. psa_key_type_t type, size_t curve_bits,
  41. const uint8_t *data, size_t data_length,
  42. mbedtls_ecp_keypair **p_ecp)
  43. {
  44. mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
  45. psa_status_t status;
  46. mbedtls_ecp_keypair *ecp = NULL;
  47. size_t curve_bytes = data_length;
  48. int explicit_bits = (curve_bits != 0);
  49. if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type) &&
  50. PSA_KEY_TYPE_ECC_GET_FAMILY(type) != PSA_ECC_FAMILY_MONTGOMERY) {
  51. /* A Weierstrass public key is represented as:
  52. * - The byte 0x04;
  53. * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
  54. * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
  55. * So its data length is 2m+1 where m is the curve size in bits.
  56. */
  57. if ((data_length & 1) == 0) {
  58. return PSA_ERROR_INVALID_ARGUMENT;
  59. }
  60. curve_bytes = data_length / 2;
  61. /* Montgomery public keys are represented in compressed format, meaning
  62. * their curve_bytes is equal to the amount of input. */
  63. /* Private keys are represented in uncompressed private random integer
  64. * format, meaning their curve_bytes is equal to the amount of input. */
  65. }
  66. if (explicit_bits) {
  67. /* With an explicit bit-size, the data must have the matching length. */
  68. if (curve_bytes != PSA_BITS_TO_BYTES(curve_bits)) {
  69. return PSA_ERROR_INVALID_ARGUMENT;
  70. }
  71. } else {
  72. /* We need to infer the bit-size from the data. Since the only
  73. * information we have is the length in bytes, the value of curve_bits
  74. * at this stage is rounded up to the nearest multiple of 8. */
  75. curve_bits = PSA_BYTES_TO_BITS(curve_bytes);
  76. }
  77. /* Allocate and initialize a key representation. */
  78. ecp = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
  79. if (ecp == NULL) {
  80. return PSA_ERROR_INSUFFICIENT_MEMORY;
  81. }
  82. mbedtls_ecp_keypair_init(ecp);
  83. /* Load the group. */
  84. grp_id = mbedtls_ecc_group_of_psa(PSA_KEY_TYPE_ECC_GET_FAMILY(type),
  85. curve_bits, !explicit_bits);
  86. if (grp_id == MBEDTLS_ECP_DP_NONE) {
  87. /* We can't distinguish between a nonsensical family/size combination
  88. * (which would warrant PSA_ERROR_INVALID_ARGUMENT) and a
  89. * well-regarded curve that Mbed TLS just doesn't know about (which
  90. * would warrant PSA_ERROR_NOT_SUPPORTED). For uniformity with how
  91. * curves that Mbed TLS knows about but for which support is disabled
  92. * at build time, return NOT_SUPPORTED. */
  93. status = PSA_ERROR_NOT_SUPPORTED;
  94. goto exit;
  95. }
  96. status = mbedtls_to_psa_error(
  97. mbedtls_ecp_group_load(&ecp->grp, grp_id));
  98. if (status != PSA_SUCCESS) {
  99. goto exit;
  100. }
  101. /* Load the key material. */
  102. if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
  103. /* Load the public value. */
  104. status = mbedtls_to_psa_error(
  105. mbedtls_ecp_point_read_binary(&ecp->grp, &ecp->Q,
  106. data,
  107. data_length));
  108. if (status != PSA_SUCCESS) {
  109. goto exit;
  110. }
  111. /* Check that the point is on the curve. */
  112. status = mbedtls_to_psa_error(
  113. mbedtls_ecp_check_pubkey(&ecp->grp, &ecp->Q));
  114. if (status != PSA_SUCCESS) {
  115. goto exit;
  116. }
  117. } else {
  118. /* Load and validate the secret value. */
  119. status = mbedtls_to_psa_error(
  120. mbedtls_ecp_read_key(ecp->grp.id,
  121. ecp,
  122. data,
  123. data_length));
  124. if (status != PSA_SUCCESS) {
  125. goto exit;
  126. }
  127. }
  128. *p_ecp = ecp;
  129. exit:
  130. if (status != PSA_SUCCESS) {
  131. mbedtls_ecp_keypair_free(ecp);
  132. mbedtls_free(ecp);
  133. }
  134. return status;
  135. }
  136. #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
  137. * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
  138. * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
  139. * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) ||
  140. * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */
  141. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
  142. defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
  143. psa_status_t mbedtls_psa_ecp_import_key(
  144. const psa_key_attributes_t *attributes,
  145. const uint8_t *data, size_t data_length,
  146. uint8_t *key_buffer, size_t key_buffer_size,
  147. size_t *key_buffer_length, size_t *bits)
  148. {
  149. psa_status_t status;
  150. mbedtls_ecp_keypair *ecp = NULL;
  151. /* Parse input */
  152. status = mbedtls_psa_ecp_load_representation(attributes->core.type,
  153. attributes->core.bits,
  154. data,
  155. data_length,
  156. &ecp);
  157. if (status != PSA_SUCCESS) {
  158. goto exit;
  159. }
  160. if (PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type) ==
  161. PSA_ECC_FAMILY_MONTGOMERY) {
  162. *bits = ecp->grp.nbits + 1;
  163. } else {
  164. *bits = ecp->grp.nbits;
  165. }
  166. /* Re-export the data to PSA export format. There is currently no support
  167. * for other input formats then the export format, so this is a 1-1
  168. * copy operation. */
  169. status = mbedtls_psa_ecp_export_key(attributes->core.type,
  170. ecp,
  171. key_buffer,
  172. key_buffer_size,
  173. key_buffer_length);
  174. exit:
  175. /* Always free the PK object (will also free contained ECP context) */
  176. mbedtls_ecp_keypair_free(ecp);
  177. mbedtls_free(ecp);
  178. return status;
  179. }
  180. psa_status_t mbedtls_psa_ecp_export_key(psa_key_type_t type,
  181. mbedtls_ecp_keypair *ecp,
  182. uint8_t *data,
  183. size_t data_size,
  184. size_t *data_length)
  185. {
  186. psa_status_t status;
  187. if (PSA_KEY_TYPE_IS_PUBLIC_KEY(type)) {
  188. /* Check whether the public part is loaded */
  189. if (mbedtls_ecp_is_zero(&ecp->Q)) {
  190. /* Calculate the public key */
  191. status = mbedtls_to_psa_error(
  192. mbedtls_ecp_mul(&ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
  193. mbedtls_psa_get_random,
  194. MBEDTLS_PSA_RANDOM_STATE));
  195. if (status != PSA_SUCCESS) {
  196. return status;
  197. }
  198. }
  199. status = mbedtls_to_psa_error(
  200. mbedtls_ecp_point_write_binary(&ecp->grp, &ecp->Q,
  201. MBEDTLS_ECP_PF_UNCOMPRESSED,
  202. data_length,
  203. data,
  204. data_size));
  205. if (status != PSA_SUCCESS) {
  206. memset(data, 0, data_size);
  207. }
  208. return status;
  209. } else {
  210. if (data_size < PSA_BITS_TO_BYTES(ecp->grp.nbits)) {
  211. return PSA_ERROR_BUFFER_TOO_SMALL;
  212. }
  213. status = mbedtls_to_psa_error(
  214. mbedtls_ecp_write_key(ecp,
  215. data,
  216. PSA_BITS_TO_BYTES(ecp->grp.nbits)));
  217. if (status == PSA_SUCCESS) {
  218. *data_length = PSA_BITS_TO_BYTES(ecp->grp.nbits);
  219. } else {
  220. memset(data, 0, data_size);
  221. }
  222. return status;
  223. }
  224. }
  225. psa_status_t mbedtls_psa_ecp_export_public_key(
  226. const psa_key_attributes_t *attributes,
  227. const uint8_t *key_buffer, size_t key_buffer_size,
  228. uint8_t *data, size_t data_size, size_t *data_length)
  229. {
  230. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  231. mbedtls_ecp_keypair *ecp = NULL;
  232. status = mbedtls_psa_ecp_load_representation(
  233. attributes->core.type, attributes->core.bits,
  234. key_buffer, key_buffer_size, &ecp);
  235. if (status != PSA_SUCCESS) {
  236. return status;
  237. }
  238. status = mbedtls_psa_ecp_export_key(
  239. PSA_KEY_TYPE_ECC_PUBLIC_KEY(
  240. PSA_KEY_TYPE_ECC_GET_FAMILY(attributes->core.type)),
  241. ecp, data, data_size, data_length);
  242. mbedtls_ecp_keypair_free(ecp);
  243. mbedtls_free(ecp);
  244. return status;
  245. }
  246. #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
  247. * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
  248. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
  249. psa_status_t mbedtls_psa_ecp_generate_key(
  250. const psa_key_attributes_t *attributes,
  251. uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
  252. {
  253. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  254. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  255. psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
  256. attributes->core.type);
  257. mbedtls_ecp_group_id grp_id =
  258. mbedtls_ecc_group_of_psa(curve, attributes->core.bits, 0);
  259. const mbedtls_ecp_curve_info *curve_info =
  260. mbedtls_ecp_curve_info_from_grp_id(grp_id);
  261. mbedtls_ecp_keypair ecp;
  262. if (attributes->domain_parameters_size != 0) {
  263. return PSA_ERROR_NOT_SUPPORTED;
  264. }
  265. if (grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL) {
  266. return PSA_ERROR_NOT_SUPPORTED;
  267. }
  268. mbedtls_ecp_keypair_init(&ecp);
  269. ret = mbedtls_ecp_gen_key(grp_id, &ecp,
  270. mbedtls_psa_get_random,
  271. MBEDTLS_PSA_RANDOM_STATE);
  272. if (ret != 0) {
  273. mbedtls_ecp_keypair_free(&ecp);
  274. return mbedtls_to_psa_error(ret);
  275. }
  276. status = mbedtls_to_psa_error(
  277. mbedtls_ecp_write_key(&ecp, key_buffer, key_buffer_size));
  278. mbedtls_ecp_keypair_free(&ecp);
  279. if (status == PSA_SUCCESS) {
  280. *key_buffer_length = key_buffer_size;
  281. }
  282. return status;
  283. }
  284. #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) */
  285. /****************************************************************/
  286. /* ECDSA sign/verify */
  287. /****************************************************************/
  288. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
  289. defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
  290. psa_status_t mbedtls_psa_ecdsa_sign_hash(
  291. const psa_key_attributes_t *attributes,
  292. const uint8_t *key_buffer, size_t key_buffer_size,
  293. psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
  294. uint8_t *signature, size_t signature_size, size_t *signature_length)
  295. {
  296. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  297. mbedtls_ecp_keypair *ecp = NULL;
  298. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  299. size_t curve_bytes;
  300. mbedtls_mpi r, s;
  301. status = mbedtls_psa_ecp_load_representation(attributes->core.type,
  302. attributes->core.bits,
  303. key_buffer,
  304. key_buffer_size,
  305. &ecp);
  306. if (status != PSA_SUCCESS) {
  307. return status;
  308. }
  309. curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
  310. mbedtls_mpi_init(&r);
  311. mbedtls_mpi_init(&s);
  312. if (signature_size < 2 * curve_bytes) {
  313. ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
  314. goto cleanup;
  315. }
  316. if (PSA_ALG_ECDSA_IS_DETERMINISTIC(alg)) {
  317. #if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
  318. psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH(alg);
  319. mbedtls_md_type_t md_alg = mbedtls_hash_info_md_from_psa(hash_alg);
  320. MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign_det_ext(
  321. &ecp->grp, &r, &s,
  322. &ecp->d, hash,
  323. hash_length, md_alg,
  324. mbedtls_psa_get_random,
  325. MBEDTLS_PSA_RANDOM_STATE));
  326. #else
  327. ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
  328. goto cleanup;
  329. #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
  330. } else {
  331. (void) alg;
  332. MBEDTLS_MPI_CHK(mbedtls_ecdsa_sign(&ecp->grp, &r, &s, &ecp->d,
  333. hash, hash_length,
  334. mbedtls_psa_get_random,
  335. MBEDTLS_PSA_RANDOM_STATE));
  336. }
  337. MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&r,
  338. signature,
  339. curve_bytes));
  340. MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&s,
  341. signature + curve_bytes,
  342. curve_bytes));
  343. cleanup:
  344. mbedtls_mpi_free(&r);
  345. mbedtls_mpi_free(&s);
  346. if (ret == 0) {
  347. *signature_length = 2 * curve_bytes;
  348. }
  349. mbedtls_ecp_keypair_free(ecp);
  350. mbedtls_free(ecp);
  351. return mbedtls_to_psa_error(ret);
  352. }
  353. psa_status_t mbedtls_psa_ecp_load_public_part(mbedtls_ecp_keypair *ecp)
  354. {
  355. int ret = 0;
  356. /* Check whether the public part is loaded. If not, load it. */
  357. if (mbedtls_ecp_is_zero(&ecp->Q)) {
  358. ret = mbedtls_ecp_mul(&ecp->grp, &ecp->Q,
  359. &ecp->d, &ecp->grp.G,
  360. mbedtls_psa_get_random,
  361. MBEDTLS_PSA_RANDOM_STATE);
  362. }
  363. return mbedtls_to_psa_error(ret);
  364. }
  365. psa_status_t mbedtls_psa_ecdsa_verify_hash(
  366. const psa_key_attributes_t *attributes,
  367. const uint8_t *key_buffer, size_t key_buffer_size,
  368. psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
  369. const uint8_t *signature, size_t signature_length)
  370. {
  371. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  372. mbedtls_ecp_keypair *ecp = NULL;
  373. size_t curve_bytes;
  374. mbedtls_mpi r, s;
  375. (void) alg;
  376. status = mbedtls_psa_ecp_load_representation(attributes->core.type,
  377. attributes->core.bits,
  378. key_buffer,
  379. key_buffer_size,
  380. &ecp);
  381. if (status != PSA_SUCCESS) {
  382. return status;
  383. }
  384. curve_bytes = PSA_BITS_TO_BYTES(ecp->grp.pbits);
  385. mbedtls_mpi_init(&r);
  386. mbedtls_mpi_init(&s);
  387. if (signature_length != 2 * curve_bytes) {
  388. status = PSA_ERROR_INVALID_SIGNATURE;
  389. goto cleanup;
  390. }
  391. status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&r,
  392. signature,
  393. curve_bytes));
  394. if (status != PSA_SUCCESS) {
  395. goto cleanup;
  396. }
  397. status = mbedtls_to_psa_error(mbedtls_mpi_read_binary(&s,
  398. signature + curve_bytes,
  399. curve_bytes));
  400. if (status != PSA_SUCCESS) {
  401. goto cleanup;
  402. }
  403. status = mbedtls_psa_ecp_load_public_part(ecp);
  404. if (status != PSA_SUCCESS) {
  405. goto cleanup;
  406. }
  407. status = mbedtls_to_psa_error(mbedtls_ecdsa_verify(&ecp->grp, hash,
  408. hash_length, &ecp->Q,
  409. &r, &s));
  410. cleanup:
  411. mbedtls_mpi_free(&r);
  412. mbedtls_mpi_free(&s);
  413. mbedtls_ecp_keypair_free(ecp);
  414. mbedtls_free(ecp);
  415. return status;
  416. }
  417. #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
  418. * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
  419. /****************************************************************/
  420. /* ECDH Key Agreement */
  421. /****************************************************************/
  422. #if defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
  423. psa_status_t mbedtls_psa_key_agreement_ecdh(
  424. const psa_key_attributes_t *attributes,
  425. const uint8_t *key_buffer, size_t key_buffer_size,
  426. psa_algorithm_t alg, const uint8_t *peer_key, size_t peer_key_length,
  427. uint8_t *shared_secret, size_t shared_secret_size,
  428. size_t *shared_secret_length)
  429. {
  430. psa_status_t status;
  431. if (!PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->core.type) ||
  432. !PSA_ALG_IS_ECDH(alg)) {
  433. return PSA_ERROR_INVALID_ARGUMENT;
  434. }
  435. mbedtls_ecp_keypair *ecp = NULL;
  436. status = mbedtls_psa_ecp_load_representation(
  437. attributes->core.type,
  438. attributes->core.bits,
  439. key_buffer,
  440. key_buffer_size,
  441. &ecp);
  442. if (status != PSA_SUCCESS) {
  443. return status;
  444. }
  445. mbedtls_ecp_keypair *their_key = NULL;
  446. mbedtls_ecdh_context ecdh;
  447. size_t bits = 0;
  448. psa_ecc_family_t curve = mbedtls_ecc_group_to_psa(ecp->grp.id, &bits);
  449. mbedtls_ecdh_init(&ecdh);
  450. status = mbedtls_psa_ecp_load_representation(
  451. PSA_KEY_TYPE_ECC_PUBLIC_KEY(curve),
  452. bits,
  453. peer_key,
  454. peer_key_length,
  455. &their_key);
  456. if (status != PSA_SUCCESS) {
  457. goto exit;
  458. }
  459. status = mbedtls_to_psa_error(
  460. mbedtls_ecdh_get_params(&ecdh, their_key, MBEDTLS_ECDH_THEIRS));
  461. if (status != PSA_SUCCESS) {
  462. goto exit;
  463. }
  464. status = mbedtls_to_psa_error(
  465. mbedtls_ecdh_get_params(&ecdh, ecp, MBEDTLS_ECDH_OURS));
  466. if (status != PSA_SUCCESS) {
  467. goto exit;
  468. }
  469. status = mbedtls_to_psa_error(
  470. mbedtls_ecdh_calc_secret(&ecdh,
  471. shared_secret_length,
  472. shared_secret, shared_secret_size,
  473. mbedtls_psa_get_random,
  474. MBEDTLS_PSA_RANDOM_STATE));
  475. if (status != PSA_SUCCESS) {
  476. goto exit;
  477. }
  478. if (PSA_BITS_TO_BYTES(bits) != *shared_secret_length) {
  479. status = PSA_ERROR_CORRUPTION_DETECTED;
  480. }
  481. exit:
  482. if (status != PSA_SUCCESS) {
  483. mbedtls_platform_zeroize(shared_secret, shared_secret_size);
  484. }
  485. mbedtls_ecdh_free(&ecdh);
  486. mbedtls_ecp_keypair_free(their_key);
  487. mbedtls_free(their_key);
  488. mbedtls_ecp_keypair_free(ecp);
  489. mbedtls_free(ecp);
  490. return status;
  491. }
  492. #endif /* MBEDTLS_PSA_BUILTIN_ALG_ECDH */
  493. #endif /* MBEDTLS_PSA_CRYPTO_C */