1 /**
2  * \file ecp_invasive.h
3  *
4  * \brief ECP module: interfaces for invasive testing only.
5  *
6  * The interfaces in this file are intended for testing purposes only.
7  * They SHOULD NOT be made available in library integrations except when
8  * building the library for testing.
9  */
10 /*
11  *  Copyright The Mbed TLS Contributors
12  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
13  */
14 #ifndef MBEDTLS_ECP_INVASIVE_H
15 #define MBEDTLS_ECP_INVASIVE_H
16 
17 #include "common.h"
18 #include "mbedtls/bignum.h"
19 #include "bignum_mod.h"
20 #include "mbedtls/ecp.h"
21 
22 /*
23  * Curve modulus types
24  */
25 typedef enum {
26     MBEDTLS_ECP_MOD_NONE = 0,
27     MBEDTLS_ECP_MOD_COORDINATE,
28     MBEDTLS_ECP_MOD_SCALAR
29 } mbedtls_ecp_modulus_type;
30 
31 typedef enum {
32     MBEDTLS_ECP_VARIANT_NONE = 0,
33     MBEDTLS_ECP_VARIANT_WITH_MPI_STRUCT,
34     MBEDTLS_ECP_VARIANT_WITH_MPI_UINT
35 } mbedtls_ecp_variant;
36 
37 #if defined(MBEDTLS_TEST_HOOKS) && defined(MBEDTLS_ECP_LIGHT)
38 
39 /** Queries the ecp variant.
40  *
41  * \return  The id of the ecp variant.
42  */
43 MBEDTLS_STATIC_TESTABLE
44 mbedtls_ecp_variant mbedtls_ecp_get_variant(void);
45 
46 #if defined(MBEDTLS_ECP_MONTGOMERY_ENABLED)
47 /** Generate a private key on a Montgomery curve (Curve25519 or Curve448).
48  *
49  * This function implements key generation for the set of secret keys
50  * specified in [Curve25519] p. 5 and in [Curve448]. The resulting value
51  * has the lower bits masked but is not necessarily canonical.
52  *
53  * \note            - [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf
54  *                  - [RFC7748] https://tools.ietf.org/html/rfc7748
55  *
56  * \p high_bit      The position of the high-order bit of the key to generate.
57  *                  This is the bit-size of the key minus 1:
58  *                  254 for Curve25519 or 447 for Curve448.
59  * \param d         The randomly generated key. This is a number of size
60  *                  exactly \p high_bit + 1 bits, with the least significant bits
61  *                  masked as specified in [Curve25519] and in [RFC7748] §5.
62  * \param f_rng     The RNG function.
63  * \param p_rng     The RNG context to be passed to \p f_rng.
64  *
65  * \return          \c 0 on success.
66  * \return          \c MBEDTLS_ERR_ECP_xxx or MBEDTLS_ERR_MPI_xxx on failure.
67  */
68 int mbedtls_ecp_gen_privkey_mx(size_t high_bit,
69                                mbedtls_mpi *d,
70                                int (*f_rng)(void *, unsigned char *, size_t),
71                                void *p_rng);
72 
73 #endif /* MBEDTLS_ECP_MONTGOMERY_ENABLED */
74 
75 #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED)
76 
77 /** Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1)
78  *
79  * This operation expects a 384 bit MPI and the result of the reduction
80  * is a 192 bit MPI.
81  *
82  * \param[in,out]   Np  The address of the MPI to be converted.
83  *                      Must have twice as many limbs as the modulus.
84  *                      Upon return this holds the reduced value. The bitlength
85  *                      of the reduced value is the same as that of the modulus
86  *                      (192 bits).
87  * \param[in]       Nn  The length of \p Np in limbs.
88  */
89 MBEDTLS_STATIC_TESTABLE
90 int mbedtls_ecp_mod_p192_raw(mbedtls_mpi_uint *Np, size_t Nn);
91 
92 #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */
93 
94 #if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED)
95 
96 /** Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2)
97  *
98  * \param[in,out]   X       The address of the MPI to be converted.
99  *                          Must have exact limb size that stores a 448-bit MPI
100  *                          (double the bitlength of the modulus).
101  *                          Upon return holds the reduced value which is
102  *                          in range `0 <= X < 2 * N` (where N is the modulus).
103  *                          The bitlength of the reduced value is the same as
104  *                          that of the modulus (224 bits).
105  * \param[in]       X_limbs The length of \p X in limbs.
106  *
107  * \return          \c 0 on success.
108  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the
109  *                  limb size that sores a 448-bit MPI.
110  */
111 MBEDTLS_STATIC_TESTABLE
112 int mbedtls_ecp_mod_p224_raw(mbedtls_mpi_uint *X, size_t X_limbs);
113 
114 #endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */
115 
116 #if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED)
117 
118 /** Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3)
119  *
120  * \param[in,out]   X       The address of the MPI to be converted.
121  *                          Must have exact limb size that stores a 512-bit MPI
122  *                          (double the bitlength of the modulus).
123  *                          Upon return holds the reduced value which is
124  *                          in range `0 <= X < 2 * N` (where N is the modulus).
125  *                          The bitlength of the reduced value is the same as
126  *                          that of the modulus (256 bits).
127  * \param[in]       X_limbs The length of \p X in limbs.
128  *
129  * \return          \c 0 on success.
130  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs is not the
131  *                  limb size that sores a 512-bit MPI.
132  */
133 MBEDTLS_STATIC_TESTABLE
134 int mbedtls_ecp_mod_p256_raw(mbedtls_mpi_uint *X, size_t X_limbs);
135 
136 #endif
137 
138 #if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED)
139 
140 /** Fast quasi-reduction modulo p521 = 2^521 - 1 (FIPS 186-3 D.2.5)
141  *
142  * \param[in,out]   X       The address of the MPI to be converted.
143  *                          Must have twice as many limbs as the modulus
144  *                          (the modulus is 521 bits long). Upon return this
145  *                          holds the reduced value. The reduced value is
146  *                          in range `0 <= X < 2 * N` (where N is the modulus).
147  *                          and its the bitlength is one plus the bitlength
148  *                          of the modulus.
149  * \param[in]       X_limbs The length of \p X in limbs.
150  *
151  * \return          \c 0 on success.
152  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X_limbs does not have
153  *                  twice as many limbs as the modulus.
154  */
155 MBEDTLS_STATIC_TESTABLE
156 int mbedtls_ecp_mod_p521_raw(mbedtls_mpi_uint *X, size_t X_limbs);
157 
158 #endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */
159 
160 #if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED)
161 
162 /** Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4)
163  *
164  * \param[in,out]   X       The address of the MPI to be converted.
165  *                          Must have exact limb size that stores a 768-bit MPI
166  *                          (double the bitlength of the modulus).
167  *                          Upon return holds the reduced value which is
168  *                          in range `0 <= X < 2 * N` (where N is the modulus).
169  *                          The bitlength of the reduced value is the same as
170  *                          that of the modulus (384 bits).
171  * \param[in]       X_limbs The length of \p N in limbs.
172  *
173  * \return          \c 0 on success.
174  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p N_n does not have
175  *                  twice as many limbs as the modulus.
176  */
177 MBEDTLS_STATIC_TESTABLE
178 int  mbedtls_ecp_mod_p384_raw(mbedtls_mpi_uint *X, size_t X_limbs);
179 
180 #endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */
181 
182 #if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED)
183 
184 /** Fast quasi-reduction modulo p192k1 = 2^192 - R,
185  * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x01000011C9
186  *
187  * \param[in,out]   X       The address of the MPI to be converted.
188  *                          Must have exact limb size that stores a 384-bit MPI
189  *                          (double the bitlength of the modulus).
190  *                          Upon return holds the reduced value which is
191  *                          in range `0 <= X < 2 * N` (where N is the modulus).
192  *                          The bitlength of the reduced value is the same as
193  *                          that of the modulus (192 bits).
194  * \param[in]       X_limbs The length of \p X in limbs.
195  *
196  * \return          \c 0 on success.
197  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
198  *                  twice as many limbs as the modulus.
199  * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
200  */
201 MBEDTLS_STATIC_TESTABLE
202 int mbedtls_ecp_mod_p192k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
203 
204 #endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */
205 
206 #if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED)
207 
208 /** Fast quasi-reduction modulo p224k1 = 2^224 - R,
209  * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93
210  *
211  * \param[in,out]   X       The address of the MPI to be converted.
212  *                          Must have exact limb size that stores a 448-bit MPI
213  *                          (double the bitlength of the modulus).
214  *                          Upon return holds the reduced value which is
215  *                          in range `0 <= X < 2 * N` (where N is the modulus).
216  *                          The bitlength of the reduced value is the same as
217  *                          that of the modulus (224 bits).
218  * \param[in]       X_limbs The length of \p X in limbs.
219  *
220  * \return          \c 0 on success.
221  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
222  *                  twice as many limbs as the modulus.
223  * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
224  */
225 MBEDTLS_STATIC_TESTABLE
226 int mbedtls_ecp_mod_p224k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
227 
228 #endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */
229 
230 #if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED)
231 
232 /** Fast quasi-reduction modulo p256k1 = 2^256 - R,
233  * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1
234  *
235  * \param[in,out]   X       The address of the MPI to be converted.
236  *                          Must have exact limb size that stores a 512-bit MPI
237  *                          (double the bitlength of the modulus).
238  *                          Upon return holds the reduced value which is
239  *                          in range `0 <= X < 2 * N` (where N is the modulus).
240  *                          The bitlength of the reduced value is the same as
241  *                          that of the modulus (256 bits).
242  * \param[in]       X_limbs The length of \p X in limbs.
243  *
244  * \return          \c 0 on success.
245  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
246  *                  twice as many limbs as the modulus.
247  * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
248  */
249 MBEDTLS_STATIC_TESTABLE
250 int mbedtls_ecp_mod_p256k1_raw(mbedtls_mpi_uint *X, size_t X_limbs);
251 
252 #endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */
253 
254 #if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED)
255 
256 /** Fast quasi-reduction modulo p255 = 2^255 - 19
257  *
258  * \param[in,out]   X       The address of the MPI to be converted.
259  *                          Must have exact limb size that stores a 510-bit MPI
260  *                          (double the bitlength of the modulus).
261  *                          Upon return holds the reduced value which is
262  *                          in range `0 <= X < 2 * N` (where N is the modulus).
263  * \param[in]       X_limbs The length of \p X in limbs.
264  *
265  * \return          \c 0 on success.
266  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
267  *                  twice as many limbs as the modulus.
268  * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation failed.
269  */
270 MBEDTLS_STATIC_TESTABLE
271 int mbedtls_ecp_mod_p255_raw(mbedtls_mpi_uint *X, size_t X_limbs);
272 
273 #endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */
274 
275 #if defined(MBEDTLS_ECP_DP_CURVE448_ENABLED)
276 
277 /** Fast quasi-reduction modulo p448 = 2^448 - 2^224 - 1
278  * Write X as A0 + 2^448 A1 and A1 as B0 + 2^224 B1, and return A0 + A1 + B1 +
279  * (B0 + B1) * 2^224.
280  *
281  * \param[in,out]   X       The address of the MPI to be converted.
282  *                          Must have exact limb size that stores a 896-bit MPI
283  *                          (double the bitlength of the modulus). Upon return
284  *                          holds the reduced value which is in range `0 <= X <
285  *                          N` (where N is the modulus). The bitlength of the
286  *                          reduced value is the same as that of the modulus
287  *                          (448 bits).
288  * \param[in]       X_limbs The length of \p X in limbs.
289  *
290  * \return          \c 0 on Success.
291  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if \p X does not have
292  *                  twice as many limbs as the modulus.
293  * \return          #MBEDTLS_ERR_ECP_ALLOC_FAILED if memory allocation
294  *                  failed.
295  */
296 MBEDTLS_STATIC_TESTABLE
297 int mbedtls_ecp_mod_p448_raw(mbedtls_mpi_uint *X, size_t X_limbs);
298 
299 #endif /* MBEDTLS_ECP_DP_CURVE448_ENABLED */
300 
301 /** Initialise a modulus with hard-coded const curve data.
302  *
303  * \note            The caller is responsible for the \p N modulus' memory.
304  *                  mbedtls_mpi_mod_modulus_free(&N) should be invoked at the
305  *                  end of its lifecycle.
306  *
307  * \param[in,out] N The address of the modulus structure to populate.
308  *                  Must be initialized.
309  * \param[in] id    The mbedtls_ecp_group_id for which to initialise the modulus.
310  * \param[in] ctype The mbedtls_ecp_modulus_type identifier for a coordinate modulus (P)
311  *                  or a scalar modulus (N).
312  *
313  * \return          \c 0 if successful.
314  * \return          #MBEDTLS_ERR_ECP_BAD_INPUT_DATA if the given MPIs do not
315  *                  have the correct number of limbs.
316  *
317  */
318 MBEDTLS_STATIC_TESTABLE
319 int mbedtls_ecp_modulus_setup(mbedtls_mpi_mod_modulus *N,
320                               const mbedtls_ecp_group_id id,
321                               const mbedtls_ecp_modulus_type ctype);
322 
323 #endif /* MBEDTLS_TEST_HOOKS && MBEDTLS_ECP_C */
324 
325 #endif /* MBEDTLS_ECP_INVASIVE_H */
326