1 /*
2  * Copyright (c) 2017-2024, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ============================================================================
33  *  @file       ECCParams.h
34  *
35  *  This file contains a common definition for elliptic curve structures used
36  *  throughout the ECC based drivers. Not all devices support every curve.
37  */
38 
39 #ifndef ti_drivers_cryptoutils_ecc_ECCParams__include
40 #define ti_drivers_cryptoutils_ecc_ECCParams__include
41 
42 #include <stdint.h>
43 #include <stddef.h>
44 #include <stdbool.h>
45 
46 #include <ti/drivers/cryptoutils/cryptokey/CryptoKey.h>
47 #include <ti/devices/DeviceFamily.h>
48 
49 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
50     #include <ti/drivers/cryptoutils/ecc/ECCParamsLPF3HSM.h>
51 #endif
52 
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56 
57 /* Error status codes for the utility functions */
58 
59 /*!
60  * @brief   Successful status code.
61  *
62  * Function return ECCParams_STATUS_SUCCESS if the control code was executed
63  * successfully.
64  */
65 #define ECCParams_STATUS_SUCCESS (0)
66 
67 /*!
68  * @brief   Generic error status code.
69  *
70  * Functions return ECCParams_STATUS_ERROR if the control code was not executed
71  * successfully.
72  */
73 #define ECCParams_STATUS_ERROR (-1)
74 
75 /*!
76  *  @brief Enumeration of curve equations supported.
77  *
78  *  Elliptic curves can be expressed using multiple equations of polynomials over
79  *  finite fields.
80  *  All forms can be converted to one another using parameter substitution.
81  *  Each curve has a default curve equations it was designed to use.
82  *
83  *  Some curve implementations have restrictions on which algorithms and schemes
84  *  they work with. For example, Curve25519 was explicitely designed with ECDH in mind.
85  *  It only uses and yields the X coordinate of a point on the elliptic curve in common
86  *  implementations. Some implementations do provide X and Y affine coordinates but most
87  *  do not.
88  *  Therefore, ECDSA and ECJPAKE do not have compatible implementations
89  *  for Curve25519 on some devices as the Y coordinate is required by them.
90  *
91  *  Check the header files of each device-specific implementation for information
92  *  regarding curve-support for specific schemes on a device.
93  *
94  *  | Name              | Equation                      |
95  *  |-------------------|-------------------------------|
96  *  | Short Weierstrass | y^2 = x^3 + a*x + b mod p     |
97  *  | Montgomery        | By^2 = x^3 + Ax^2 + x mod p   |
98  *  | Edwards           | x^2 + y^2 = 1 + dx^2y^2 mod p |
99  *
100  */
101 typedef uint32_t ECCParams_CurveType;
102 
103 #define ECCParams_CURVE_TYPE_NONE                  0U
104 #define ECCParams_CURVE_TYPE_SHORT_WEIERSTRASS_AN3 1U
105 #define ECCParams_CURVE_TYPE_SHORT_WEIERSTRASS_GEN 2U
106 #define ECCParams_CURVE_TYPE_MONTGOMERY            3U
107 #define ECCParams_CURVE_TYPE_EDWARDS               4U
108 
109 /*!
110  *  @brief Enumeration of ECC curve names supported by TF-M.
111  */
112 typedef enum
113 {
114     /*
115      * WARNING: Do not alter the order or contents of this enum without updating
116      * the corresponding curveParamTable array in ECCParamCC26X4_s.c
117      */
118     ECCParams_SecureCurve_NISTP224 = 0,
119     ECCParams_SecureCurve_NISTP256,
120     ECCParams_SecureCurve_NISTP384,
121     ECCParams_SecureCurve_NISTP521,
122     ECCParams_SecureCurve_BrainpoolP256R1,
123     ECCParams_SecureCurve_BrainpoolP384R1,
124     ECCParams_SecureCurve_BrainpoolP512R1,
125     ECCParams_SecureCurve_Curve25519,
126     ECCParams_SecureCurve_Ed25519,
127     ECCParams_SecureCurve_Wei25519,
128     ECCParams_SecureCurve_COUNT /* This element denotes the max enum value and is not a valid curve */
129 } ECCParams_SecureCurve;
130 
131 /*
132  * ECCParams_CurveParams have different struct members depending on the context
133  * of the build (Secure-only, Non-secure, or Secure)
134  */
135 #if (TFM_ENABLED == 0) || defined(TFM_BUILD) /* TFM_BUILD indicates this is a TF-M build */
136 
137 /*!
138  *  @brief A structure containing the parameters of an elliptic curve.
139  *
140  *  Elliptical Curve Cryptography (ECC) prime curve parameters.
141  */
142 
143 typedef struct ECCParams_CurveParams
144 {
145     const ECCParams_CurveType curveType;
146     const uint8_t *prime;
147     const uint8_t *a;
148     const uint8_t *b;
149     const uint8_t *order;
150     const uint8_t cofactor;
151     const size_t length;
152     const uint8_t *generatorX;
153     const uint8_t *generatorY;
154 } ECCParams_CurveParams;
155 
156 #else
157 
158 /*!
159  *  @brief A structure containing the curve name to reference elliptic curve
160  *         parameters stored in secure memory.
161  */
162 typedef struct ECCParams_CurveParams
163 {
164     ECCParams_SecureCurve secureCurve;
165 } ECCParams_CurveParams;
166 
167 #endif /* (TFM_ENABLED == 0) || defined(TFM_BUILD) */
168 
169 #if defined(TFM_BUILD) /* TFM_BUILD indicates this is a TF-M build */
170 
171 /*!
172  *  @brief A structure containing the curve name to reference elliptic curve
173  *         parameters stored in secure memory.
174  */
175 /* This must match the ECCParams_CurveParams struct definition directly above */
176 typedef struct ECCParams_ns_CurveParams
177 {
178     ECCParams_SecureCurve secureCurve;
179 } ECCParams_ns_CurveParams;
180 
181 #endif /* defined(TFM_BUILD) */
182 
183 /* Short Weierstrass curves */
184 
185 /*!
186  *
187  *  @brief The NISTP192 curve in short Weierstrass form.
188  *
189  */
190 extern const ECCParams_CurveParams ECCParams_NISTP192;
191 
192 /*!
193  *
194  *  @brief The NISTP224 curve in short Weierstrass form.
195  *
196  */
197 extern const ECCParams_CurveParams ECCParams_NISTP224;
198 
199 /*!
200  *
201  *  @brief The NISTP256 curve in short Weierstrass form.
202  *
203  */
204 extern const ECCParams_CurveParams ECCParams_NISTP256;
205 
206 /*!
207  *
208  *  @brief The NISTP384 curve in short Weierstrass form.
209  *
210  */
211 extern const ECCParams_CurveParams ECCParams_NISTP384;
212 
213 /*!
214  *
215  *  @brief The NISTP521 curve in short Weierstrass form.
216  *
217  */
218 extern const ECCParams_CurveParams ECCParams_NISTP521;
219 
220 /*!
221  *
222  *  @brief The BrainpoolP256R1 curve in short Weierstrass form.
223  *
224  */
225 extern const ECCParams_CurveParams ECCParams_BrainpoolP256R1;
226 
227 /*!
228  *
229  *  @brief The BrainpoolP384R1 curve in short Weierstrass form.
230  *
231  */
232 extern const ECCParams_CurveParams ECCParams_BrainpoolP384R1;
233 
234 /*!
235  *
236  *  @brief The BrainpoolP512R1 curve in short Weierstrass form.
237  *
238  */
239 extern const ECCParams_CurveParams ECCParams_BrainpoolP512R1;
240 
241 /*!
242  *  @brief A short Weierstrass equivalent representation of Ed25519.
243  */
244 extern const ECCParams_CurveParams ECCParams_Wei25519;
245 
246 /* Montgomery curves */
247 
248 /*!
249  *  @brief The Curve25519 curve in Montgomery form.
250  */
251 extern const ECCParams_CurveParams ECCParams_Curve25519;
252 
253 /* Edwards curves */
254 
255 /*!
256  *  @brief The Ed25519 curve in Edwards form.
257  */
258 extern const ECCParams_CurveParams ECCParams_Ed25519;
259 
260 /*!
261  *  @brief Number of bytes for the length word prepended before all parameters
262  *  passed into the ECC SW library functions.
263  */
264 #define ECC_LENGTH_PREFIX_BYTES 4
265 
266 #if (DeviceFamily_PARENT == DeviceFamily_PARENT_CC23X0) || (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX)
267 
268     /*!
269      *  @defgroup nistp256_params NIST P256 curve params to be used with ECC SW library
270      *  Note: CC26X1 uses NIST P256 curve params defined in driverlib/rom_ecc.h
271      *  @{
272      */
273 
274     /*!
275      *  @brief Length of NIST P256 curve parameters in bytes
276      */
277     #define ECCParams_NISTP256_LENGTH 32
278 
279     /*!
280      *  @brief Length in bytes of NISTP256 curve parameters including the prepended
281      *  length word.
282      */
283     #define ECC_NISTP256_PARAM_LENGTH_WITH_PREFIX_BYTES (ECCParams_NISTP256_LENGTH + ECC_LENGTH_PREFIX_BYTES)
284 
285 /*!
286  *  @brief Union to access ECC_NISTP256 curve params in bytes or words.
287  */
288 typedef union
289 {
290     uint8_t byte[ECC_NISTP256_PARAM_LENGTH_WITH_PREFIX_BYTES];
291     uint32_t word[ECC_NISTP256_PARAM_LENGTH_WITH_PREFIX_BYTES / sizeof(uint32_t)];
292 } ECC_NISTP256_Param;
293 
294 /*!
295  *  @brief X coordinate of the generator point of the ECC_NISTP256 curve.
296  */
297 extern const ECC_NISTP256_Param ECC_NISTP256_generatorX;
298 
299 /*!
300  *  @brief Y coordinate of the generator point of the ECC_NISTP256 curve.
301  */
302 extern const ECC_NISTP256_Param ECC_NISTP256_generatorY;
303 
304 /*!
305  *  @brief Prime of the generator point of the ECC_NISTP256 curve.
306  */
307 extern const ECC_NISTP256_Param ECC_NISTP256_prime;
308 
309 /*!
310  *  @brief 'a' constant of the ECC_NISTP256 curve when expressed in short
311  *  Weierstrass form (y^2 = x^3 + a*x + b).
312  */
313 extern const ECC_NISTP256_Param ECC_NISTP256_a;
314 
315 /*!
316  *  @brief 'b' constant of the ECC_NISTP256 curve when expressed in short
317  *  Weierstrass form (y^2 = x^3 + a*x + b).
318  */
319 extern const ECC_NISTP256_Param ECC_NISTP256_b;
320 
321 /*!
322  *  @brief Order of the generator point of the ECC_NISTP256 curve.
323  */
324 extern const ECC_NISTP256_Param ECC_NISTP256_order;
325 
326 /*!
327  *  @brief 'k' in Montgomery domain of the ECC_NISTP256 curve.
328  */
329 extern const ECC_NISTP256_Param ECC_NISTP256_k_mont;
330 
331 /*!
332  *  @brief 'a' in Montgomery domain of the ECC_NISTP256 curve.
333  */
334 extern const ECC_NISTP256_Param ECC_NISTP256_a_mont;
335 
336 /*!
337  *  @brief 'b' in Montgomery domain of the ECC_NISTP256 curve.
338  */
339 extern const ECC_NISTP256_Param ECC_NISTP256_b_mont;
340 
341     /*! @} */ /* end of nistp256_params */
342 
343     /*!
344      *  @defgroup nistp224_params NIST P224 curve params to be used with ECC SW library
345      *  @{
346      */
347 
348     /*!
349      *  @brief Length of NIST P224 curve parameters in bytes
350      */
351     #define ECCParams_NISTP224_LENGTH 28
352 
353     /*!
354      *  @brief Length in bytes of NISTP256 curve parameters including the prepended
355      *  length word.
356      */
357     #define ECC_NISTP224_PARAM_LENGTH_WITH_PREFIX_BYTES (ECCParams_NISTP224_LENGTH + ECC_LENGTH_PREFIX_BYTES)
358 
359 /*!
360  *  @brief Union to access ECC_NISTP256 curve params in bytes or words.
361  */
362 typedef union
363 {
364     uint8_t byte[ECC_NISTP224_PARAM_LENGTH_WITH_PREFIX_BYTES];
365     uint32_t word[ECC_NISTP224_PARAM_LENGTH_WITH_PREFIX_BYTES / sizeof(uint32_t)];
366 } ECC_NISTP224_Param;
367 
368 /*!
369  *  @brief X coordinate of the generator point of the ECC_NISTP224 curve.
370  */
371 extern const ECC_NISTP224_Param ECC_NISTP224_generatorX;
372 
373 /*!
374  *  @brief Y coordinate of the generator point of the ECC_NISTP224 curve.
375  */
376 extern const ECC_NISTP224_Param ECC_NISTP224_generatorY;
377 
378 /*!
379  *  @brief Prime of the generator point of the ECC_NISTP224 curve.
380  */
381 extern const ECC_NISTP224_Param ECC_NISTP224_prime;
382 
383 /*!
384  *  @brief 'a' constant of the ECC_NISTP224 curve when expressed in short
385  *  Weierstrass form (y^2 = x^3 + a*x + b).
386  */
387 extern const ECC_NISTP224_Param ECC_NISTP224_a;
388 
389 /*!
390  *  @brief 'b' constant of the ECC_NISTP224 curve when expressed in short
391  *  Weierstrass form (y^2 = x^3 + a*x + b).
392  */
393 extern const ECC_NISTP224_Param ECC_NISTP224_b;
394 
395 /*!
396  *  @brief Order of the generator point of the ECC_NISTP224 curve.
397  */
398 extern const ECC_NISTP224_Param ECC_NISTP224_order;
399 
400 /*!
401  *  @brief 'k' in Montgomery domain of the ECC_NISTP224 curve.
402  */
403 extern const ECC_NISTP224_Param ECC_NISTP224_k_mont;
404 
405 /*!
406  *  @brief 'a' in Montgomery domain of the ECC_NISTP224 curve.
407  */
408 extern const ECC_NISTP224_Param ECC_NISTP224_a_mont;
409 
410 /*!
411  *  @brief 'b' in Montgomery domain of the ECC_NISTP224 curve.
412  */
413 extern const ECC_NISTP224_Param ECC_NISTP224_b_mont;
414 
415     /*! @} */ /* end of nistp224_params */
416 
417     /* Octet string format requires an extra byte at the start of the public key */
418     #define OCTET_STRING_OFFSET 1
419 
420     /* Octet string format requires this value in the first byte of the public key */
421     #define OCTET_STRING_PREFIX 0x04
422 
423     /* Length of offset in bytes */
424     #define ECC_LENGTH_OFFSET_BYTES 4
425 
426     /* Param length needs to be equal to the length of the largest curve supported plus length offset bytes */
427     #define ECC_PARAM_LENGTH_WITH_OFFSET_BYTES (ECCParams_NISTP256_LENGTH + ECC_LENGTH_OFFSET_BYTES)
428 
429 /*!
430  *  @brief Union to format inputs to ECC library.
431  */
432 typedef union
433 {
434     uint32_t word[ECC_PARAM_LENGTH_WITH_OFFSET_BYTES / sizeof(uint32_t)];
435     uint8_t byte[ECC_PARAM_LENGTH_WITH_OFFSET_BYTES];
436 } ECC_Param;
437 
438 #endif /* (DeviceFamily_PARENT == DeviceFamily_PARENT_CC23X0) || (DeviceFamily_PARENT == DeviceFamily_PARENT_CC27XX) \
439         */
440 
441 /*!
442  *  @brief Length of Curve25519 curve parameters in bytes
443  */
444 #define ECCParams_CURVE25519_LENGTH 32
445 
446 /*!
447  *  @defgroup curve25519_params Curve25519 curve params to be used with ECC SW library
448  *  @{
449  */
450 
451 /*!
452  *  @brief Length in bytes of Curve25519 curve parameters including the prepended
453  *  length word.
454  */
455 #define ECC_CURVE25519_LENGTH_WITH_PREFIX_BYTES (ECCParams_CURVE25519_LENGTH + ECC_LENGTH_PREFIX_BYTES)
456 
457 /*!
458  *  @brief Union to access ECC_Curve25519 curve params in bytes or words.
459  */
460 typedef union
461 {
462     uint8_t byte[ECC_CURVE25519_LENGTH_WITH_PREFIX_BYTES];
463     uint32_t word[ECC_CURVE25519_LENGTH_WITH_PREFIX_BYTES / sizeof(uint32_t)];
464 } ECC_Curve25519_Param;
465 
466 /*!
467  *  @brief X coordinate of the generator point of the ECC_Curve25519 curve.
468  */
469 extern const ECC_Curve25519_Param ECC_Curve25519_generatorX;
470 
471 /*!
472  *  @brief Y coordinate of the generator point of the ECC_Curve25519 curve.
473  */
474 extern const ECC_Curve25519_Param ECC_Curve25519_generatorY;
475 
476 /*!
477  *  @brief Prime of the generator point of the ECC_Curve25519 curve.
478  */
479 extern const ECC_Curve25519_Param ECC_Curve25519_prime;
480 
481 /*!
482  *  @brief 'a' constant of the ECC_Curve25519 curve when expressed in short
483  *  Weierstrass form (y^2 = x^3 + a*x + b).
484  */
485 extern const ECC_Curve25519_Param ECC_Curve25519_a;
486 
487 /*!
488  *  @brief 'b' constant of the ECC_Curve25519 curve when expressed in short
489  *  Weierstrass form (y^2 = x^3 + a*x + b).
490  */
491 extern const ECC_Curve25519_Param ECC_Curve25519_b;
492 
493 /*!
494  *  @brief Order of the generator point of the ECC_Curve25519 curve.
495  */
496 extern const ECC_Curve25519_Param ECC_Curve25519_order;
497 
498 /*! @} */ /* end of curve25519_params */
499 
500 /* Utility functions */
501 
502 /* #define used for backwards compatibility */
503 #define ECCParams_FormatCurve25519PrivateKey ECCParams_formatCurve25519PrivateKey
504 
505 /*!
506  *  @brief Formats a CryptoKey to conform to Curve25519 private key requirements.
507  *
508  *  Curve25519 has specific private key requirements specified by the curve definition.
509  *  Specifically, the bottom three and the top bit may not be set and the second to
510  *  last bit must be set.
511  *
512  *  @param  myPrivateKey    An initialized CryptoKey describing the entropy for a
513  *                          Curve25519 private key. Platform-specific restrictions
514  *                          for the location of the keying material apply. Some
515  *                          implementations do not support modifying keying material
516  *                          in flash for example.
517  *
518  *  @pre Initialize the CryptoKey with a 32-byte buffer in a compliant location.
519  */
520 int_fast16_t ECCParams_formatCurve25519PrivateKey(CryptoKey *myPrivateKey);
521 
522 /*!
523  *  @brief Extracts the curve generator point from an ecliptic curve description.
524  *
525  *  The curve parameters #ECCParams_CurveParams::generatorX and
526  *  #ECCParams_CurveParams::generatorY are extracted from \c curveParams and
527  *  written as a concatenated octet string in big endian order to
528  *  \c buffer. The format is defined in SEC 1: Elliptic Curve Cryptography section
529  *  2.3.3.
530  *
531  *  The curve point has the format ``0x04 || X || Y`` and the length is
532  *  ``2 * size_of_x_or_y + 1`` where ``0x04`` specifies octet string format.
533  *  If the buffer \c length exceeds the curve point length, the remaining
534  *  buffer space is zeroed.
535  *
536  *  @param  curveParams     Points to the input curve parameters
537  *  @param  buffer          Points to the destination where the generator point will
538  *                          be written to. Make sure that \c buffer is large enough to
539  *                          hold
540  *  @param  length          Maximum length of \c buffer in bytes.
541  *
542  *  @retval #ECCParams_STATUS_SUCCESS on success, #ECCParams_STATUS_ERROR if the
543  *          provided buffer \c length is insufficient to hold the curve point.
544  *
545  */
546 int_fast16_t ECCParams_getUncompressedGeneratorPoint(const ECCParams_CurveParams *curveParams,
547                                                      uint8_t *buffer,
548                                                      size_t length);
549 
550 #ifdef __cplusplus
551 }
552 #endif
553 
554 #endif /* ti_drivers_cryptoutils_ecc_ECCParams__include */
555