psa_crypto_ecp.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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 "psa_crypto_hash.h"
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include "mbedtls/platform.h"
  30. #if !defined(MBEDTLS_PLATFORM_C)
  31. #define mbedtls_calloc calloc
  32. #define mbedtls_free free
  33. #endif
  34. #include <mbedtls/ecdsa.h>
  35. #include <mbedtls/ecp.h>
  36. #include <mbedtls/error.h>
  37. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
  38. defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) || \
  39. defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
  40. defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) || \
  41. defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH)
  42. psa_status_t mbedtls_psa_ecp_load_representation(
  43. psa_key_type_t type, size_t curve_bits,
  44. const uint8_t *data, size_t data_length,
  45. mbedtls_ecp_keypair **p_ecp )
  46. {
  47. mbedtls_ecp_group_id grp_id = MBEDTLS_ECP_DP_NONE;
  48. psa_status_t status;
  49. mbedtls_ecp_keypair *ecp = NULL;
  50. size_t curve_bytes = data_length;
  51. int explicit_bits = ( curve_bits != 0 );
  52. if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) &&
  53. PSA_KEY_TYPE_ECC_GET_FAMILY( type ) != PSA_ECC_FAMILY_MONTGOMERY )
  54. {
  55. /* A Weierstrass public key is represented as:
  56. * - The byte 0x04;
  57. * - `x_P` as a `ceiling(m/8)`-byte string, big-endian;
  58. * - `y_P` as a `ceiling(m/8)`-byte string, big-endian.
  59. * So its data length is 2m+1 where m is the curve size in bits.
  60. */
  61. if( ( data_length & 1 ) == 0 )
  62. return( PSA_ERROR_INVALID_ARGUMENT );
  63. curve_bytes = data_length / 2;
  64. /* Montgomery public keys are represented in compressed format, meaning
  65. * their curve_bytes is equal to the amount of input. */
  66. /* Private keys are represented in uncompressed private random integer
  67. * format, meaning their curve_bytes is equal to the amount of input. */
  68. }
  69. if( explicit_bits )
  70. {
  71. /* With an explicit bit-size, the data must have the matching length. */
  72. if( curve_bytes != PSA_BITS_TO_BYTES( curve_bits ) )
  73. return( PSA_ERROR_INVALID_ARGUMENT );
  74. }
  75. else
  76. {
  77. /* We need to infer the bit-size from the data. Since the only
  78. * information we have is the length in bytes, the value of curve_bits
  79. * at this stage is rounded up to the nearest multiple of 8. */
  80. curve_bits = PSA_BYTES_TO_BITS( curve_bytes );
  81. }
  82. /* Allocate and initialize a key representation. */
  83. ecp = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) );
  84. if( ecp == NULL )
  85. return( PSA_ERROR_INSUFFICIENT_MEMORY );
  86. mbedtls_ecp_keypair_init( ecp );
  87. /* Load the group. */
  88. grp_id = mbedtls_ecc_group_of_psa( PSA_KEY_TYPE_ECC_GET_FAMILY( type ),
  89. curve_bits, !explicit_bits );
  90. if( grp_id == MBEDTLS_ECP_DP_NONE )
  91. {
  92. /* We can't distinguish between a nonsensical family/size combination
  93. * (which would warrant PSA_ERROR_INVALID_ARGUMENT) and a
  94. * well-regarded curve that Mbed TLS just doesn't know about (which
  95. * would warrant PSA_ERROR_NOT_SUPPORTED). For uniformity with how
  96. * curves that Mbed TLS knows about but for which support is disabled
  97. * at build time, return NOT_SUPPORTED. */
  98. status = PSA_ERROR_NOT_SUPPORTED;
  99. goto exit;
  100. }
  101. status = mbedtls_to_psa_error(
  102. mbedtls_ecp_group_load( &ecp->grp, grp_id ) );
  103. if( status != PSA_SUCCESS )
  104. goto exit;
  105. /* Load the key material. */
  106. if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
  107. {
  108. /* Load the public value. */
  109. status = mbedtls_to_psa_error(
  110. mbedtls_ecp_point_read_binary( &ecp->grp, &ecp->Q,
  111. data,
  112. data_length ) );
  113. if( status != PSA_SUCCESS )
  114. goto exit;
  115. /* Check that the point is on the curve. */
  116. status = mbedtls_to_psa_error(
  117. mbedtls_ecp_check_pubkey( &ecp->grp, &ecp->Q ) );
  118. if( status != PSA_SUCCESS )
  119. goto exit;
  120. }
  121. else
  122. {
  123. /* Load and validate the secret value. */
  124. status = mbedtls_to_psa_error(
  125. mbedtls_ecp_read_key( ecp->grp.id,
  126. ecp,
  127. data,
  128. data_length ) );
  129. if( status != PSA_SUCCESS )
  130. goto exit;
  131. }
  132. *p_ecp = ecp;
  133. exit:
  134. if( status != PSA_SUCCESS )
  135. {
  136. mbedtls_ecp_keypair_free( ecp );
  137. mbedtls_free( ecp );
  138. }
  139. return( status );
  140. }
  141. #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
  142. * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) ||
  143. * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) ||
  144. * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) ||
  145. * defined(MBEDTLS_PSA_BUILTIN_ALG_ECDH) */
  146. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) || \
  147. defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY)
  148. psa_status_t mbedtls_psa_ecp_import_key(
  149. const psa_key_attributes_t *attributes,
  150. const uint8_t *data, size_t data_length,
  151. uint8_t *key_buffer, size_t key_buffer_size,
  152. size_t *key_buffer_length, size_t *bits )
  153. {
  154. psa_status_t status;
  155. mbedtls_ecp_keypair *ecp = NULL;
  156. /* Parse input */
  157. status = mbedtls_psa_ecp_load_representation( attributes->core.type,
  158. attributes->core.bits,
  159. data,
  160. data_length,
  161. &ecp );
  162. if( status != PSA_SUCCESS )
  163. goto exit;
  164. if( PSA_KEY_TYPE_ECC_GET_FAMILY( attributes->core.type ) ==
  165. PSA_ECC_FAMILY_MONTGOMERY )
  166. *bits = ecp->grp.nbits + 1;
  167. else
  168. *bits = ecp->grp.nbits;
  169. /* Re-export the data to PSA export format. There is currently no support
  170. * for other input formats then the export format, so this is a 1-1
  171. * copy operation. */
  172. status = mbedtls_psa_ecp_export_key( attributes->core.type,
  173. ecp,
  174. key_buffer,
  175. key_buffer_size,
  176. key_buffer_length );
  177. exit:
  178. /* Always free the PK object (will also free contained ECP context) */
  179. mbedtls_ecp_keypair_free( ecp );
  180. mbedtls_free( ecp );
  181. return( status );
  182. }
  183. psa_status_t mbedtls_psa_ecp_export_key( psa_key_type_t type,
  184. mbedtls_ecp_keypair *ecp,
  185. uint8_t *data,
  186. size_t data_size,
  187. size_t *data_length )
  188. {
  189. psa_status_t status;
  190. if( PSA_KEY_TYPE_IS_PUBLIC_KEY( type ) )
  191. {
  192. /* Check whether the public part is loaded */
  193. if( mbedtls_ecp_is_zero( &ecp->Q ) )
  194. {
  195. /* Calculate the public key */
  196. status = mbedtls_to_psa_error(
  197. mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
  198. mbedtls_psa_get_random,
  199. MBEDTLS_PSA_RANDOM_STATE ) );
  200. if( status != PSA_SUCCESS )
  201. return( status );
  202. }
  203. status = mbedtls_to_psa_error(
  204. mbedtls_ecp_point_write_binary( &ecp->grp, &ecp->Q,
  205. MBEDTLS_ECP_PF_UNCOMPRESSED,
  206. data_length,
  207. data,
  208. data_size ) );
  209. if( status != PSA_SUCCESS )
  210. memset( data, 0, data_size );
  211. return( status );
  212. }
  213. else
  214. {
  215. if( data_size < PSA_BITS_TO_BYTES( ecp->grp.nbits ) )
  216. return( PSA_ERROR_BUFFER_TOO_SMALL );
  217. status = mbedtls_to_psa_error(
  218. mbedtls_ecp_write_key( ecp,
  219. data,
  220. PSA_BITS_TO_BYTES( ecp->grp.nbits ) ) );
  221. if( status == PSA_SUCCESS )
  222. *data_length = PSA_BITS_TO_BYTES( ecp->grp.nbits );
  223. else
  224. memset( data, 0, data_size );
  225. return( status );
  226. }
  227. }
  228. psa_status_t mbedtls_psa_ecp_export_public_key(
  229. const psa_key_attributes_t *attributes,
  230. const uint8_t *key_buffer, size_t key_buffer_size,
  231. uint8_t *data, size_t data_size, size_t *data_length )
  232. {
  233. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  234. mbedtls_ecp_keypair *ecp = NULL;
  235. status = mbedtls_psa_ecp_load_representation(
  236. attributes->core.type, attributes->core.bits,
  237. key_buffer, key_buffer_size, &ecp );
  238. if( status != PSA_SUCCESS )
  239. return( status );
  240. status = mbedtls_psa_ecp_export_key(
  241. PSA_KEY_TYPE_ECC_PUBLIC_KEY(
  242. PSA_KEY_TYPE_ECC_GET_FAMILY( attributes->core.type ) ),
  243. ecp, data, data_size, data_length );
  244. mbedtls_ecp_keypair_free( ecp );
  245. mbedtls_free( ecp );
  246. return( status );
  247. }
  248. #endif /* defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR) ||
  249. * defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_PUBLIC_KEY) */
  250. #if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_ECC_KEY_PAIR)
  251. psa_status_t mbedtls_psa_ecp_generate_key(
  252. const psa_key_attributes_t *attributes,
  253. uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length )
  254. {
  255. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  256. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  257. psa_ecc_family_t curve = PSA_KEY_TYPE_ECC_GET_FAMILY(
  258. attributes->core.type );
  259. mbedtls_ecp_group_id grp_id =
  260. mbedtls_ecc_group_of_psa( curve, attributes->core.bits, 0 );
  261. const mbedtls_ecp_curve_info *curve_info =
  262. mbedtls_ecp_curve_info_from_grp_id( grp_id );
  263. mbedtls_ecp_keypair ecp;
  264. if( attributes->domain_parameters_size != 0 )
  265. return( PSA_ERROR_NOT_SUPPORTED );
  266. if( grp_id == MBEDTLS_ECP_DP_NONE || curve_info == NULL )
  267. return( PSA_ERROR_NOT_SUPPORTED );
  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. {
  274. mbedtls_ecp_keypair_free( &ecp );
  275. return( mbedtls_to_psa_error( ret ) );
  276. }
  277. status = mbedtls_to_psa_error(
  278. mbedtls_ecp_write_key( &ecp, key_buffer, key_buffer_size ) );
  279. mbedtls_ecp_keypair_free( &ecp );
  280. if( status == PSA_SUCCESS )
  281. *key_buffer_length = key_buffer_size;
  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. curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
  309. mbedtls_mpi_init( &r );
  310. mbedtls_mpi_init( &s );
  311. if( signature_size < 2 * curve_bytes )
  312. {
  313. ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
  314. goto cleanup;
  315. }
  316. if( PSA_ALG_ECDSA_IS_DETERMINISTIC( alg ) )
  317. {
  318. #if defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA)
  319. psa_algorithm_t hash_alg = PSA_ALG_SIGN_GET_HASH( alg );
  320. const mbedtls_md_info_t *md_info = mbedtls_md_info_from_psa( hash_alg );
  321. mbedtls_md_type_t md_alg = mbedtls_md_get_type( md_info );
  322. MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det_ext(
  323. &ecp->grp, &r, &s,
  324. &ecp->d, hash,
  325. hash_length, md_alg,
  326. mbedtls_psa_get_random,
  327. MBEDTLS_PSA_RANDOM_STATE ) );
  328. #else
  329. ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
  330. goto cleanup;
  331. #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
  332. }
  333. else
  334. {
  335. (void) alg;
  336. MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ecp->grp, &r, &s, &ecp->d,
  337. hash, hash_length,
  338. mbedtls_psa_get_random,
  339. MBEDTLS_PSA_RANDOM_STATE ) );
  340. }
  341. MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &r,
  342. signature,
  343. curve_bytes ) );
  344. MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &s,
  345. signature + curve_bytes,
  346. curve_bytes ) );
  347. cleanup:
  348. mbedtls_mpi_free( &r );
  349. mbedtls_mpi_free( &s );
  350. if( ret == 0 )
  351. *signature_length = 2 * curve_bytes;
  352. mbedtls_ecp_keypair_free( ecp );
  353. mbedtls_free( ecp );
  354. return( mbedtls_to_psa_error( ret ) );
  355. }
  356. psa_status_t mbedtls_psa_ecdsa_verify_hash(
  357. const psa_key_attributes_t *attributes,
  358. const uint8_t *key_buffer, size_t key_buffer_size,
  359. psa_algorithm_t alg, const uint8_t *hash, size_t hash_length,
  360. const uint8_t *signature, size_t signature_length )
  361. {
  362. psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
  363. mbedtls_ecp_keypair *ecp = NULL;
  364. int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
  365. size_t curve_bytes;
  366. mbedtls_mpi r, s;
  367. (void)alg;
  368. status = mbedtls_psa_ecp_load_representation( attributes->core.type,
  369. attributes->core.bits,
  370. key_buffer,
  371. key_buffer_size,
  372. &ecp );
  373. if( status != PSA_SUCCESS )
  374. return( status );
  375. curve_bytes = PSA_BITS_TO_BYTES( ecp->grp.pbits );
  376. mbedtls_mpi_init( &r );
  377. mbedtls_mpi_init( &s );
  378. if( signature_length != 2 * curve_bytes )
  379. {
  380. ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
  381. goto cleanup;
  382. }
  383. MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r,
  384. signature,
  385. curve_bytes ) );
  386. MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &s,
  387. signature + curve_bytes,
  388. curve_bytes ) );
  389. /* Check whether the public part is loaded. If not, load it. */
  390. if( mbedtls_ecp_is_zero( &ecp->Q ) )
  391. {
  392. MBEDTLS_MPI_CHK(
  393. mbedtls_ecp_mul( &ecp->grp, &ecp->Q, &ecp->d, &ecp->grp.G,
  394. mbedtls_psa_get_random, MBEDTLS_PSA_RANDOM_STATE ) );
  395. }
  396. ret = mbedtls_ecdsa_verify( &ecp->grp, hash, hash_length,
  397. &ecp->Q, &r, &s );
  398. cleanup:
  399. mbedtls_mpi_free( &r );
  400. mbedtls_mpi_free( &s );
  401. mbedtls_ecp_keypair_free( ecp );
  402. mbedtls_free( ecp );
  403. return( mbedtls_to_psa_error( ret ) );
  404. }
  405. #endif /* defined(MBEDTLS_PSA_BUILTIN_ALG_ECDSA) || \
  406. * defined(MBEDTLS_PSA_BUILTIN_ALG_DETERMINISTIC_ECDSA) */
  407. #endif /* MBEDTLS_PSA_CRYPTO_C */