1 /*
2 * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <string.h>
8 #include "soc/hwcrypto_periph.h"
9 #include "ecc_impl.h"
10
11 #include "mbedtls/ecp.h"
12 #include "mbedtls/platform_util.h"
13
14 #if defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK)
15
16 #define MAX_SIZE 32 // 256 bits
17
esp_mbedtls_ecp_point_multiply(const mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P)18 static int esp_mbedtls_ecp_point_multiply(const mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
19 const mbedtls_mpi *m, const mbedtls_ecp_point *P)
20 {
21 int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
22 uint8_t x_tmp[MAX_SIZE] = {0};
23 uint8_t y_tmp[MAX_SIZE] = {0};
24
25 uint8_t m_le[MAX_SIZE] = {0};
26 ecc_point_t p_pt = {0};
27 ecc_point_t r_pt = {0};
28
29 p_pt.len = grp->pbits / 8;
30
31 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&P->MBEDTLS_PRIVATE(X), p_pt.x, MAX_SIZE));
32 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(&P->MBEDTLS_PRIVATE(Y), p_pt.y, MAX_SIZE));
33 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary_le(m, m_le, MAX_SIZE));
34
35 ret = esp_ecc_point_multiply(&p_pt, m_le, &r_pt, false);
36
37 for (int i = 0; i < MAX_SIZE; i++) {
38 x_tmp[MAX_SIZE - i - 1] = r_pt.x[i];
39 y_tmp[MAX_SIZE - i - 1] = r_pt.y[i];
40 }
41
42 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->MBEDTLS_PRIVATE(X), x_tmp, MAX_SIZE));
43 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&R->MBEDTLS_PRIVATE(Y), y_tmp, MAX_SIZE));
44 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&R->MBEDTLS_PRIVATE(Z), 1));
45 return ret;
46
47 cleanup:
48 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
49 }
50
ecp_mul_restartable_internal(mbedtls_ecp_group * grp,mbedtls_ecp_point * R,const mbedtls_mpi * m,const mbedtls_ecp_point * P,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng,mbedtls_ecp_restart_ctx * rs_ctx)51 int ecp_mul_restartable_internal( mbedtls_ecp_group *grp, mbedtls_ecp_point *R,
52 const mbedtls_mpi *m, const mbedtls_ecp_point *P,
53 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng,
54 mbedtls_ecp_restart_ctx *rs_ctx )
55 {
56 int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
57 if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) {
58 #if defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK)
59 return ecp_mul_restartable_internal_soft(grp, R, m, P, f_rng, p_rng, rs_ctx);
60 #else
61 return ret;
62 #endif
63 }
64
65 /* Common sanity checks to conform with mbedTLS return values */
66 MBEDTLS_MPI_CHK( mbedtls_ecp_check_privkey(grp, m) );
67 MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey(grp, P) );
68
69 MBEDTLS_MPI_CHK( esp_mbedtls_ecp_point_multiply(grp, R, m, P) );
70 cleanup:
71 return( ret );
72 }
73
74 #endif /* defined(MBEDTLS_ECP_MUL_ALT) || defined(MBEDTLS_ECP_MUL_ALT_SOFT_FALLBACK) */
75
76 #if defined(MBEDTLS_ECP_VERIFY_ALT) || defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK)
77
mbedtls_ecp_check_pubkey(const mbedtls_ecp_group * grp,const mbedtls_ecp_point * pt)78 int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp,
79 const mbedtls_ecp_point *pt )
80 {
81 int res;
82 ecc_point_t point;
83
84 if (grp->id != MBEDTLS_ECP_DP_SECP192R1 && grp->id != MBEDTLS_ECP_DP_SECP256R1) {
85 #if defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK)
86 return mbedtls_ecp_check_pubkey_soft(grp, pt);
87 #else
88 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
89 #endif
90 }
91
92 if (grp == NULL || pt == NULL) {
93 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
94 }
95
96 /* Must use affine coordinates */
97 if( mbedtls_mpi_cmp_int( &pt->MBEDTLS_PRIVATE(Z), 1 ) != 0 )
98 return( MBEDTLS_ERR_ECP_INVALID_KEY );
99
100 mbedtls_platform_zeroize((void *)&point, sizeof(ecc_point_t));
101
102 memcpy(&point.x, pt->MBEDTLS_PRIVATE(X).MBEDTLS_PRIVATE(p), mbedtls_mpi_size(&pt->MBEDTLS_PRIVATE(X)));
103 memcpy(&point.y, pt->MBEDTLS_PRIVATE(Y).MBEDTLS_PRIVATE(p), mbedtls_mpi_size(&pt->MBEDTLS_PRIVATE(Y)));
104
105 point.len = grp->pbits / 8;
106
107 res = esp_ecc_point_verify(&point);
108 if (res == 1) {
109 return 0;
110 } else {
111 return MBEDTLS_ERR_ECP_INVALID_KEY;
112 }
113 }
114 #endif /* defined(MBEDTLS_ECP_VERIFY_ALT) || defined(MBEDTLS_ECP_VERIFY_ALT_SOFT_FALLBACK) */
115