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