mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ansond 0:137634ff4186 1 /**
ansond 0:137634ff4186 2 * \file ecp.h
ansond 0:137634ff4186 3 *
ansond 0:137634ff4186 4 * \brief Elliptic curves over GF(p)
ansond 0:137634ff4186 5 *
ansond 0:137634ff4186 6 * Copyright (C) 2006-2013, ARM Limited, All Rights Reserved
ansond 0:137634ff4186 7 *
ansond 0:137634ff4186 8 * This file is part of mbed TLS (https://tls.mbed.org)
ansond 0:137634ff4186 9 *
ansond 0:137634ff4186 10 * This program is free software; you can redistribute it and/or modify
ansond 0:137634ff4186 11 * it under the terms of the GNU General Public License as published by
ansond 0:137634ff4186 12 * the Free Software Foundation; either version 2 of the License, or
ansond 0:137634ff4186 13 * (at your option) any later version.
ansond 0:137634ff4186 14 *
ansond 0:137634ff4186 15 * This program is distributed in the hope that it will be useful,
ansond 0:137634ff4186 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ansond 0:137634ff4186 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ansond 0:137634ff4186 18 * GNU General Public License for more details.
ansond 0:137634ff4186 19 *
ansond 0:137634ff4186 20 * You should have received a copy of the GNU General Public License along
ansond 0:137634ff4186 21 * with this program; if not, write to the Free Software Foundation, Inc.,
ansond 0:137634ff4186 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ansond 0:137634ff4186 23 */
ansond 0:137634ff4186 24 #ifndef POLARSSL_ECP_H
ansond 0:137634ff4186 25 #define POLARSSL_ECP_H
ansond 0:137634ff4186 26
ansond 0:137634ff4186 27 #include "bignum.h"
ansond 0:137634ff4186 28
ansond 0:137634ff4186 29 /*
ansond 0:137634ff4186 30 * ECP error codes
ansond 0:137634ff4186 31 */
ansond 0:137634ff4186 32 #define POLARSSL_ERR_ECP_BAD_INPUT_DATA -0x4F80 /**< Bad input parameters to function. */
ansond 0:137634ff4186 33 #define POLARSSL_ERR_ECP_BUFFER_TOO_SMALL -0x4F00 /**< The buffer is too small to write to. */
ansond 0:137634ff4186 34 #define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE -0x4E80 /**< Requested curve not available. */
ansond 0:137634ff4186 35 #define POLARSSL_ERR_ECP_VERIFY_FAILED -0x4E00 /**< The signature is not valid. */
ansond 0:137634ff4186 36 #define POLARSSL_ERR_ECP_MALLOC_FAILED -0x4D80 /**< Memory allocation failed. */
ansond 0:137634ff4186 37 #define POLARSSL_ERR_ECP_RANDOM_FAILED -0x4D00 /**< Generation of random value, such as (ephemeral) key, failed. */
ansond 0:137634ff4186 38 #define POLARSSL_ERR_ECP_INVALID_KEY -0x4C80 /**< Invalid private or public key. */
ansond 0:137634ff4186 39 #define POLARSSL_ERR_ECP_SIG_LEN_MISMATCH -0x4C00 /**< Signature is valid but shorter than the user-supplied length. */
ansond 0:137634ff4186 40
ansond 0:137634ff4186 41 #ifdef __cplusplus
ansond 0:137634ff4186 42 extern "C" {
ansond 0:137634ff4186 43 #endif
ansond 0:137634ff4186 44
ansond 0:137634ff4186 45 /**
ansond 0:137634ff4186 46 * Domain parameters (curve, subgroup and generator) identifiers.
ansond 0:137634ff4186 47 *
ansond 0:137634ff4186 48 * Only curves over prime fields are supported.
ansond 0:137634ff4186 49 *
ansond 0:137634ff4186 50 * \warning This library does not support validation of arbitrary domain
ansond 0:137634ff4186 51 * parameters. Therefore, only well-known domain parameters from trusted
ansond 0:137634ff4186 52 * sources should be used. See ecp_use_known_dp().
ansond 0:137634ff4186 53 */
ansond 0:137634ff4186 54 typedef enum
ansond 0:137634ff4186 55 {
ansond 0:137634ff4186 56 POLARSSL_ECP_DP_NONE = 0,
ansond 0:137634ff4186 57 POLARSSL_ECP_DP_SECP192R1, /*!< 192-bits NIST curve */
ansond 0:137634ff4186 58 POLARSSL_ECP_DP_SECP224R1, /*!< 224-bits NIST curve */
ansond 0:137634ff4186 59 POLARSSL_ECP_DP_SECP256R1, /*!< 256-bits NIST curve */
ansond 0:137634ff4186 60 POLARSSL_ECP_DP_SECP384R1, /*!< 384-bits NIST curve */
ansond 0:137634ff4186 61 POLARSSL_ECP_DP_SECP521R1, /*!< 521-bits NIST curve */
ansond 0:137634ff4186 62 POLARSSL_ECP_DP_BP256R1, /*!< 256-bits Brainpool curve */
ansond 0:137634ff4186 63 POLARSSL_ECP_DP_BP384R1, /*!< 384-bits Brainpool curve */
ansond 0:137634ff4186 64 POLARSSL_ECP_DP_BP512R1, /*!< 512-bits Brainpool curve */
ansond 0:137634ff4186 65 POLARSSL_ECP_DP_M221, /*!< (not implemented yet) */
ansond 0:137634ff4186 66 POLARSSL_ECP_DP_M255, /*!< Curve25519 */
ansond 0:137634ff4186 67 POLARSSL_ECP_DP_M383, /*!< (not implemented yet) */
ansond 0:137634ff4186 68 POLARSSL_ECP_DP_M511, /*!< (not implemented yet) */
ansond 0:137634ff4186 69 POLARSSL_ECP_DP_SECP192K1, /*!< 192-bits "Koblitz" curve */
ansond 0:137634ff4186 70 POLARSSL_ECP_DP_SECP224K1, /*!< 224-bits "Koblitz" curve */
ansond 0:137634ff4186 71 POLARSSL_ECP_DP_SECP256K1, /*!< 256-bits "Koblitz" curve */
ansond 0:137634ff4186 72 } ecp_group_id;
ansond 0:137634ff4186 73
ansond 0:137634ff4186 74 /**
ansond 0:137634ff4186 75 * Number of supported curves (plus one for NONE).
ansond 0:137634ff4186 76 *
ansond 0:137634ff4186 77 * (Montgomery curves excluded for now.)
ansond 0:137634ff4186 78 */
ansond 0:137634ff4186 79 #define POLARSSL_ECP_DP_MAX 12
ansond 0:137634ff4186 80
ansond 0:137634ff4186 81 /**
ansond 0:137634ff4186 82 * Curve information for use by other modules
ansond 0:137634ff4186 83 */
ansond 0:137634ff4186 84 typedef struct
ansond 0:137634ff4186 85 {
ansond 0:137634ff4186 86 ecp_group_id grp_id; /*!< Internal identifier */
ansond 0:137634ff4186 87 uint16_t tls_id; /*!< TLS NamedCurve identifier */
ansond 0:137634ff4186 88 uint16_t size; /*!< Curve size in bits */
ansond 0:137634ff4186 89 const char *name; /*!< Human-friendly name */
ansond 0:137634ff4186 90 } ecp_curve_info;
ansond 0:137634ff4186 91
ansond 0:137634ff4186 92 /**
ansond 0:137634ff4186 93 * \brief ECP point structure (jacobian coordinates)
ansond 0:137634ff4186 94 *
ansond 0:137634ff4186 95 * \note All functions expect and return points satisfying
ansond 0:137634ff4186 96 * the following condition: Z == 0 or Z == 1. (Other
ansond 0:137634ff4186 97 * values of Z are used by internal functions only.)
ansond 0:137634ff4186 98 * The point is zero, or "at infinity", if Z == 0.
ansond 0:137634ff4186 99 * Otherwise, X and Y are its standard (affine) coordinates.
ansond 0:137634ff4186 100 */
ansond 0:137634ff4186 101 typedef struct
ansond 0:137634ff4186 102 {
ansond 0:137634ff4186 103 mpi X; /*!< the point's X coordinate */
ansond 0:137634ff4186 104 mpi Y; /*!< the point's Y coordinate */
ansond 0:137634ff4186 105 mpi Z; /*!< the point's Z coordinate */
ansond 0:137634ff4186 106 }
ansond 0:137634ff4186 107 ecp_point;
ansond 0:137634ff4186 108
ansond 0:137634ff4186 109 /**
ansond 0:137634ff4186 110 * \brief ECP group structure
ansond 0:137634ff4186 111 *
ansond 0:137634ff4186 112 * We consider two types of curves equations:
ansond 0:137634ff4186 113 * 1. Short Weierstrass y^2 = x^3 + A x + B mod P (SEC1 + RFC 4492)
ansond 0:137634ff4186 114 * 2. Montgomery, y^2 = x^3 + A x^2 + x mod P (M255 + draft)
ansond 0:137634ff4186 115 * In both cases, a generator G for a prime-order subgroup is fixed. In the
ansond 0:137634ff4186 116 * short weierstrass, this subgroup is actually the whole curve, and its
ansond 0:137634ff4186 117 * cardinal is denoted by N.
ansond 0:137634ff4186 118 *
ansond 0:137634ff4186 119 * In the case of Short Weierstrass curves, our code requires that N is an odd
ansond 0:137634ff4186 120 * prime. (Use odd in ecp_mul() and prime in ecdsa_sign() for blinding.)
ansond 0:137634ff4186 121 *
ansond 0:137634ff4186 122 * In the case of Montgomery curves, we don't store A but (A + 2) / 4 which is
ansond 0:137634ff4186 123 * the quantity actually used in the formulas. Also, nbits is not the size of N
ansond 0:137634ff4186 124 * but the required size for private keys.
ansond 0:137634ff4186 125 *
ansond 0:137634ff4186 126 * If modp is NULL, reduction modulo P is done using a generic algorithm.
ansond 0:137634ff4186 127 * Otherwise, it must point to a function that takes an mpi in the range
ansond 0:137634ff4186 128 * 0..2^(2*pbits)-1 and transforms it in-place in an integer of little more
ansond 0:137634ff4186 129 * than pbits, so that the integer may be efficiently brought in the 0..P-1
ansond 0:137634ff4186 130 * range by a few additions or substractions. It must return 0 on success and
ansond 0:137634ff4186 131 * non-zero on failure.
ansond 0:137634ff4186 132 */
ansond 0:137634ff4186 133 typedef struct
ansond 0:137634ff4186 134 {
ansond 0:137634ff4186 135 ecp_group_id id; /*!< internal group identifier */
ansond 0:137634ff4186 136 mpi P; /*!< prime modulus of the base field */
ansond 0:137634ff4186 137 mpi A; /*!< 1. A in the equation, or 2. (A + 2) / 4 */
ansond 0:137634ff4186 138 mpi B; /*!< 1. B in the equation, or 2. unused */
ansond 0:137634ff4186 139 ecp_point G; /*!< generator of the (sub)group used */
ansond 0:137634ff4186 140 mpi N; /*!< 1. the order of G, or 2. unused */
ansond 0:137634ff4186 141 size_t pbits; /*!< number of bits in P */
ansond 0:137634ff4186 142 size_t nbits; /*!< number of bits in 1. P, or 2. private keys */
ansond 0:137634ff4186 143 unsigned int h; /*!< internal: 1 if the constants are static */
ansond 0:137634ff4186 144 int (*modp)(mpi *); /*!< function for fast reduction mod P */
ansond 0:137634ff4186 145 int (*t_pre)(ecp_point *, void *); /*!< unused */
ansond 0:137634ff4186 146 int (*t_post)(ecp_point *, void *); /*!< unused */
ansond 0:137634ff4186 147 void *t_data; /*!< unused */
ansond 0:137634ff4186 148 ecp_point *T; /*!< pre-computed points for ecp_mul_comb() */
ansond 0:137634ff4186 149 size_t T_size; /*!< number for pre-computed points */
ansond 0:137634ff4186 150 }
ansond 0:137634ff4186 151 ecp_group;
ansond 0:137634ff4186 152
ansond 0:137634ff4186 153 /**
ansond 0:137634ff4186 154 * \brief ECP key pair structure
ansond 0:137634ff4186 155 *
ansond 0:137634ff4186 156 * A generic key pair that could be used for ECDSA, fixed ECDH, etc.
ansond 0:137634ff4186 157 *
ansond 0:137634ff4186 158 * \note Members purposefully in the same order as struc ecdsa_context.
ansond 0:137634ff4186 159 */
ansond 0:137634ff4186 160 typedef struct
ansond 0:137634ff4186 161 {
ansond 0:137634ff4186 162 ecp_group grp; /*!< Elliptic curve and base point */
ansond 0:137634ff4186 163 mpi d; /*!< our secret value */
ansond 0:137634ff4186 164 ecp_point Q; /*!< our public value */
ansond 0:137634ff4186 165 }
ansond 0:137634ff4186 166 ecp_keypair;
ansond 0:137634ff4186 167
ansond 0:137634ff4186 168 /**
ansond 0:137634ff4186 169 * \name SECTION: Module settings
ansond 0:137634ff4186 170 *
ansond 0:137634ff4186 171 * The configuration options you can set for this module are in this section.
ansond 0:137634ff4186 172 * Either change them in config.h or define them on the compiler command line.
ansond 0:137634ff4186 173 * \{
ansond 0:137634ff4186 174 */
ansond 0:137634ff4186 175
ansond 0:137634ff4186 176 #if !defined(POLARSSL_ECP_MAX_BITS)
ansond 0:137634ff4186 177 /**
ansond 0:137634ff4186 178 * Maximum size of the groups (that is, of N and P)
ansond 0:137634ff4186 179 */
ansond 0:137634ff4186 180 #define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */
ansond 0:137634ff4186 181 #endif
ansond 0:137634ff4186 182
ansond 0:137634ff4186 183 #define POLARSSL_ECP_MAX_BYTES ( ( POLARSSL_ECP_MAX_BITS + 7 ) / 8 )
ansond 0:137634ff4186 184 #define POLARSSL_ECP_MAX_PT_LEN ( 2 * POLARSSL_ECP_MAX_BYTES + 1 )
ansond 0:137634ff4186 185
ansond 0:137634ff4186 186 #if !defined(POLARSSL_ECP_WINDOW_SIZE)
ansond 0:137634ff4186 187 /*
ansond 0:137634ff4186 188 * Maximum "window" size used for point multiplication.
ansond 0:137634ff4186 189 * Default: 6.
ansond 0:137634ff4186 190 * Minimum value: 2. Maximum value: 7.
ansond 0:137634ff4186 191 *
ansond 0:137634ff4186 192 * Result is an array of at most ( 1 << ( POLARSSL_ECP_WINDOW_SIZE - 1 ) )
ansond 0:137634ff4186 193 * points used for point multiplication. This value is directly tied to EC
ansond 0:137634ff4186 194 * peak memory usage, so decreasing it by one should roughly cut memory usage
ansond 0:137634ff4186 195 * by two (if large curves are in use).
ansond 0:137634ff4186 196 *
ansond 0:137634ff4186 197 * Reduction in size may reduce speed, but larger curves are impacted first.
ansond 0:137634ff4186 198 * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1):
ansond 0:137634ff4186 199 * w-size: 6 5 4 3 2
ansond 0:137634ff4186 200 * 521 145 141 135 120 97
ansond 0:137634ff4186 201 * 384 214 209 198 177 146
ansond 0:137634ff4186 202 * 256 320 320 303 262 226
ansond 0:137634ff4186 203
ansond 0:137634ff4186 204 * 224 475 475 453 398 342
ansond 0:137634ff4186 205 * 192 640 640 633 587 476
ansond 0:137634ff4186 206 */
ansond 0:137634ff4186 207 #define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
ansond 0:137634ff4186 208 #endif /* POLARSSL_ECP_WINDOW_SIZE */
ansond 0:137634ff4186 209
ansond 0:137634ff4186 210 #if !defined(POLARSSL_ECP_FIXED_POINT_OPTIM)
ansond 0:137634ff4186 211 /*
ansond 0:137634ff4186 212 * Trade memory for speed on fixed-point multiplication.
ansond 0:137634ff4186 213 *
ansond 0:137634ff4186 214 * This speeds up repeated multiplication of the generator (that is, the
ansond 0:137634ff4186 215 * multiplication in ECDSA signatures, and half of the multiplications in
ansond 0:137634ff4186 216 * ECDSA verification and ECDHE) by a factor roughly 3 to 4.
ansond 0:137634ff4186 217 *
ansond 0:137634ff4186 218 * The cost is increasing EC peak memory usage by a factor roughly 2.
ansond 0:137634ff4186 219 *
ansond 0:137634ff4186 220 * Change this value to 0 to reduce peak memory usage.
ansond 0:137634ff4186 221 */
ansond 0:137634ff4186 222 #define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
ansond 0:137634ff4186 223 #endif /* POLARSSL_ECP_FIXED_POINT_OPTIM */
ansond 0:137634ff4186 224
ansond 0:137634ff4186 225 /* \} name SECTION: Module settings */
ansond 0:137634ff4186 226
ansond 0:137634ff4186 227 /*
ansond 0:137634ff4186 228 * Point formats, from RFC 4492's enum ECPointFormat
ansond 0:137634ff4186 229 */
ansond 0:137634ff4186 230 #define POLARSSL_ECP_PF_UNCOMPRESSED 0 /**< Uncompressed point format */
ansond 0:137634ff4186 231 #define POLARSSL_ECP_PF_COMPRESSED 1 /**< Compressed point format */
ansond 0:137634ff4186 232
ansond 0:137634ff4186 233 /*
ansond 0:137634ff4186 234 * Some other constants from RFC 4492
ansond 0:137634ff4186 235 */
ansond 0:137634ff4186 236 #define POLARSSL_ECP_TLS_NAMED_CURVE 3 /**< ECCurveType's named_curve */
ansond 0:137634ff4186 237
ansond 0:137634ff4186 238 /**
ansond 0:137634ff4186 239 * \brief Get the list of supported curves in order of preferrence
ansond 0:137634ff4186 240 * (full information)
ansond 0:137634ff4186 241 *
ansond 0:137634ff4186 242 * \return A statically allocated array, the last entry is 0.
ansond 0:137634ff4186 243 */
ansond 0:137634ff4186 244 const ecp_curve_info *ecp_curve_list( void );
ansond 0:137634ff4186 245
ansond 0:137634ff4186 246 /**
ansond 0:137634ff4186 247 * \brief Get the list of supported curves in order of preferrence
ansond 0:137634ff4186 248 * (grp_id only)
ansond 0:137634ff4186 249 *
ansond 0:137634ff4186 250 * \return A statically allocated array,
ansond 0:137634ff4186 251 * terminated with POLARSSL_ECP_DP_NONE.
ansond 0:137634ff4186 252 */
ansond 0:137634ff4186 253 const ecp_group_id *ecp_grp_id_list( void );
ansond 0:137634ff4186 254
ansond 0:137634ff4186 255 /**
ansond 0:137634ff4186 256 * \brief Get curve information from an internal group identifier
ansond 0:137634ff4186 257 *
ansond 0:137634ff4186 258 * \param grp_id A POLARSSL_ECP_DP_XXX value
ansond 0:137634ff4186 259 *
ansond 0:137634ff4186 260 * \return The associated curve information or NULL
ansond 0:137634ff4186 261 */
ansond 0:137634ff4186 262 const ecp_curve_info *ecp_curve_info_from_grp_id( ecp_group_id grp_id );
ansond 0:137634ff4186 263
ansond 0:137634ff4186 264 /**
ansond 0:137634ff4186 265 * \brief Get curve information from a TLS NamedCurve value
ansond 0:137634ff4186 266 *
ansond 0:137634ff4186 267 * \param tls_id A POLARSSL_ECP_DP_XXX value
ansond 0:137634ff4186 268 *
ansond 0:137634ff4186 269 * \return The associated curve information or NULL
ansond 0:137634ff4186 270 */
ansond 0:137634ff4186 271 const ecp_curve_info *ecp_curve_info_from_tls_id( uint16_t tls_id );
ansond 0:137634ff4186 272
ansond 0:137634ff4186 273 /**
ansond 0:137634ff4186 274 * \brief Get curve information from a human-readable name
ansond 0:137634ff4186 275 *
ansond 0:137634ff4186 276 * \param name The name
ansond 0:137634ff4186 277 *
ansond 0:137634ff4186 278 * \return The associated curve information or NULL
ansond 0:137634ff4186 279 */
ansond 0:137634ff4186 280 const ecp_curve_info *ecp_curve_info_from_name( const char *name );
ansond 0:137634ff4186 281
ansond 0:137634ff4186 282 /**
ansond 0:137634ff4186 283 * \brief Initialize a point (as zero)
ansond 0:137634ff4186 284 */
ansond 0:137634ff4186 285 void ecp_point_init( ecp_point *pt );
ansond 0:137634ff4186 286
ansond 0:137634ff4186 287 /**
ansond 0:137634ff4186 288 * \brief Initialize a group (to something meaningless)
ansond 0:137634ff4186 289 */
ansond 0:137634ff4186 290 void ecp_group_init( ecp_group *grp );
ansond 0:137634ff4186 291
ansond 0:137634ff4186 292 /**
ansond 0:137634ff4186 293 * \brief Initialize a key pair (as an invalid one)
ansond 0:137634ff4186 294 */
ansond 0:137634ff4186 295 void ecp_keypair_init( ecp_keypair *key );
ansond 0:137634ff4186 296
ansond 0:137634ff4186 297 /**
ansond 0:137634ff4186 298 * \brief Free the components of a point
ansond 0:137634ff4186 299 */
ansond 0:137634ff4186 300 void ecp_point_free( ecp_point *pt );
ansond 0:137634ff4186 301
ansond 0:137634ff4186 302 /**
ansond 0:137634ff4186 303 * \brief Free the components of an ECP group
ansond 0:137634ff4186 304 */
ansond 0:137634ff4186 305 void ecp_group_free( ecp_group *grp );
ansond 0:137634ff4186 306
ansond 0:137634ff4186 307 /**
ansond 0:137634ff4186 308 * \brief Free the components of a key pair
ansond 0:137634ff4186 309 */
ansond 0:137634ff4186 310 void ecp_keypair_free( ecp_keypair *key );
ansond 0:137634ff4186 311
ansond 0:137634ff4186 312 /**
ansond 0:137634ff4186 313 * \brief Copy the contents of point Q into P
ansond 0:137634ff4186 314 *
ansond 0:137634ff4186 315 * \param P Destination point
ansond 0:137634ff4186 316 * \param Q Source point
ansond 0:137634ff4186 317 *
ansond 0:137634ff4186 318 * \return 0 if successful,
ansond 0:137634ff4186 319 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
ansond 0:137634ff4186 320 */
ansond 0:137634ff4186 321 int ecp_copy( ecp_point *P, const ecp_point *Q );
ansond 0:137634ff4186 322
ansond 0:137634ff4186 323 /**
ansond 0:137634ff4186 324 * \brief Copy the contents of a group object
ansond 0:137634ff4186 325 *
ansond 0:137634ff4186 326 * \param dst Destination group
ansond 0:137634ff4186 327 * \param src Source group
ansond 0:137634ff4186 328 *
ansond 0:137634ff4186 329 * \return 0 if successful,
ansond 0:137634ff4186 330 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
ansond 0:137634ff4186 331 */
ansond 0:137634ff4186 332 int ecp_group_copy( ecp_group *dst, const ecp_group *src );
ansond 0:137634ff4186 333
ansond 0:137634ff4186 334 /**
ansond 0:137634ff4186 335 * \brief Set a point to zero
ansond 0:137634ff4186 336 *
ansond 0:137634ff4186 337 * \param pt Destination point
ansond 0:137634ff4186 338 *
ansond 0:137634ff4186 339 * \return 0 if successful,
ansond 0:137634ff4186 340 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
ansond 0:137634ff4186 341 */
ansond 0:137634ff4186 342 int ecp_set_zero( ecp_point *pt );
ansond 0:137634ff4186 343
ansond 0:137634ff4186 344 /**
ansond 0:137634ff4186 345 * \brief Tell if a point is zero
ansond 0:137634ff4186 346 *
ansond 0:137634ff4186 347 * \param pt Point to test
ansond 0:137634ff4186 348 *
ansond 0:137634ff4186 349 * \return 1 if point is zero, 0 otherwise
ansond 0:137634ff4186 350 */
ansond 0:137634ff4186 351 int ecp_is_zero( ecp_point *pt );
ansond 0:137634ff4186 352
ansond 0:137634ff4186 353 /**
ansond 0:137634ff4186 354 * \brief Import a non-zero point from two ASCII strings
ansond 0:137634ff4186 355 *
ansond 0:137634ff4186 356 * \param P Destination point
ansond 0:137634ff4186 357 * \param radix Input numeric base
ansond 0:137634ff4186 358 * \param x First affine coordinate as a null-terminated string
ansond 0:137634ff4186 359 * \param y Second affine coordinate as a null-terminated string
ansond 0:137634ff4186 360 *
ansond 0:137634ff4186 361 * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
ansond 0:137634ff4186 362 */
ansond 0:137634ff4186 363 int ecp_point_read_string( ecp_point *P, int radix,
ansond 0:137634ff4186 364 const char *x, const char *y );
ansond 0:137634ff4186 365
ansond 0:137634ff4186 366 /**
ansond 0:137634ff4186 367 * \brief Export a point into unsigned binary data
ansond 0:137634ff4186 368 *
ansond 0:137634ff4186 369 * \param grp Group to which the point should belong
ansond 0:137634ff4186 370 * \param P Point to export
ansond 0:137634ff4186 371 * \param format Point format, should be a POLARSSL_ECP_PF_XXX macro
ansond 0:137634ff4186 372 * \param olen Length of the actual output
ansond 0:137634ff4186 373 * \param buf Output buffer
ansond 0:137634ff4186 374 * \param buflen Length of the output buffer
ansond 0:137634ff4186 375 *
ansond 0:137634ff4186 376 * \return 0 if successful,
ansond 0:137634ff4186 377 * or POLARSSL_ERR_ECP_BAD_INPUT_DATA
ansond 0:137634ff4186 378 * or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
ansond 0:137634ff4186 379 */
ansond 0:137634ff4186 380 int ecp_point_write_binary( const ecp_group *grp, const ecp_point *P,
ansond 0:137634ff4186 381 int format, size_t *olen,
ansond 0:137634ff4186 382 unsigned char *buf, size_t buflen );
ansond 0:137634ff4186 383
ansond 0:137634ff4186 384 /**
ansond 0:137634ff4186 385 * \brief Import a point from unsigned binary data
ansond 0:137634ff4186 386 *
ansond 0:137634ff4186 387 * \param grp Group to which the point should belong
ansond 0:137634ff4186 388 * \param P Point to import
ansond 0:137634ff4186 389 * \param buf Input buffer
ansond 0:137634ff4186 390 * \param ilen Actual length of input
ansond 0:137634ff4186 391 *
ansond 0:137634ff4186 392 * \return 0 if successful,
ansond 0:137634ff4186 393 * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid,
ansond 0:137634ff4186 394 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed,
ansond 0:137634ff4186 395 * POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE if the point format
ansond 0:137634ff4186 396 * is not implemented.
ansond 0:137634ff4186 397 *
ansond 0:137634ff4186 398 * \note This function does NOT check that the point actually
ansond 0:137634ff4186 399 * belongs to the given group, see ecp_check_pubkey() for
ansond 0:137634ff4186 400 * that.
ansond 0:137634ff4186 401 */
ansond 0:137634ff4186 402 int ecp_point_read_binary( const ecp_group *grp, ecp_point *P,
ansond 0:137634ff4186 403 const unsigned char *buf, size_t ilen );
ansond 0:137634ff4186 404
ansond 0:137634ff4186 405 /**
ansond 0:137634ff4186 406 * \brief Import a point from a TLS ECPoint record
ansond 0:137634ff4186 407 *
ansond 0:137634ff4186 408 * \param grp ECP group used
ansond 0:137634ff4186 409 * \param pt Destination point
ansond 0:137634ff4186 410 * \param buf $(Start of input buffer)
ansond 0:137634ff4186 411 * \param len Buffer length
ansond 0:137634ff4186 412 *
ansond 0:137634ff4186 413 * \note buf is updated to point right after the ECPoint on exit
ansond 0:137634ff4186 414 *
ansond 0:137634ff4186 415 * \return 0 if successful,
ansond 0:137634ff4186 416 * POLARSSL_ERR_MPI_XXX if initialization failed
ansond 0:137634ff4186 417 * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
ansond 0:137634ff4186 418 */
ansond 0:137634ff4186 419 int ecp_tls_read_point( const ecp_group *grp, ecp_point *pt,
ansond 0:137634ff4186 420 const unsigned char **buf, size_t len );
ansond 0:137634ff4186 421
ansond 0:137634ff4186 422 /**
ansond 0:137634ff4186 423 * \brief Export a point as a TLS ECPoint record
ansond 0:137634ff4186 424 *
ansond 0:137634ff4186 425 * \param grp ECP group used
ansond 0:137634ff4186 426 * \param pt Point to export
ansond 0:137634ff4186 427 * \param format Export format
ansond 0:137634ff4186 428 * \param olen length of data written
ansond 0:137634ff4186 429 * \param buf Buffer to write to
ansond 0:137634ff4186 430 * \param blen Buffer length
ansond 0:137634ff4186 431 *
ansond 0:137634ff4186 432 * \return 0 if successful,
ansond 0:137634ff4186 433 * or POLARSSL_ERR_ECP_BAD_INPUT_DATA
ansond 0:137634ff4186 434 * or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
ansond 0:137634ff4186 435 */
ansond 0:137634ff4186 436 int ecp_tls_write_point( const ecp_group *grp, const ecp_point *pt,
ansond 0:137634ff4186 437 int format, size_t *olen,
ansond 0:137634ff4186 438 unsigned char *buf, size_t blen );
ansond 0:137634ff4186 439
ansond 0:137634ff4186 440 /**
ansond 0:137634ff4186 441 * \brief Import an ECP group from null-terminated ASCII strings
ansond 0:137634ff4186 442 *
ansond 0:137634ff4186 443 * \param grp Destination group
ansond 0:137634ff4186 444 * \param radix Input numeric base
ansond 0:137634ff4186 445 * \param p Prime modulus of the base field
ansond 0:137634ff4186 446 * \param b Constant term in the equation
ansond 0:137634ff4186 447 * \param gx The generator's X coordinate
ansond 0:137634ff4186 448 * \param gy The generator's Y coordinate
ansond 0:137634ff4186 449 * \param n The generator's order
ansond 0:137634ff4186 450 *
ansond 0:137634ff4186 451 * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code
ansond 0:137634ff4186 452 *
ansond 0:137634ff4186 453 * \note Sets all fields except modp.
ansond 0:137634ff4186 454 */
ansond 0:137634ff4186 455 int ecp_group_read_string( ecp_group *grp, int radix,
ansond 0:137634ff4186 456 const char *p, const char *b,
ansond 0:137634ff4186 457 const char *gx, const char *gy, const char *n);
ansond 0:137634ff4186 458
ansond 0:137634ff4186 459 /**
ansond 0:137634ff4186 460 * \brief Set a group using well-known domain parameters
ansond 0:137634ff4186 461 *
ansond 0:137634ff4186 462 * \param grp Destination group
ansond 0:137634ff4186 463 * \param index Index in the list of well-known domain parameters
ansond 0:137634ff4186 464 *
ansond 0:137634ff4186 465 * \return 0 if successful,
ansond 0:137634ff4186 466 * POLARSSL_ERR_MPI_XXX if initialization failed
ansond 0:137634ff4186 467 * POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE for unkownn groups
ansond 0:137634ff4186 468 *
ansond 0:137634ff4186 469 * \note Index should be a value of RFC 4492's enum NamdeCurve,
ansond 0:137634ff4186 470 * possibly in the form of a POLARSSL_ECP_DP_XXX macro.
ansond 0:137634ff4186 471 */
ansond 0:137634ff4186 472 int ecp_use_known_dp( ecp_group *grp, ecp_group_id index );
ansond 0:137634ff4186 473
ansond 0:137634ff4186 474 /**
ansond 0:137634ff4186 475 * \brief Set a group from a TLS ECParameters record
ansond 0:137634ff4186 476 *
ansond 0:137634ff4186 477 * \param grp Destination group
ansond 0:137634ff4186 478 * \param buf &(Start of input buffer)
ansond 0:137634ff4186 479 * \param len Buffer length
ansond 0:137634ff4186 480 *
ansond 0:137634ff4186 481 * \note buf is updated to point right after ECParameters on exit
ansond 0:137634ff4186 482 *
ansond 0:137634ff4186 483 * \return 0 if successful,
ansond 0:137634ff4186 484 * POLARSSL_ERR_MPI_XXX if initialization failed
ansond 0:137634ff4186 485 * POLARSSL_ERR_ECP_BAD_INPUT_DATA if input is invalid
ansond 0:137634ff4186 486 */
ansond 0:137634ff4186 487 int ecp_tls_read_group( ecp_group *grp, const unsigned char **buf, size_t len );
ansond 0:137634ff4186 488
ansond 0:137634ff4186 489 /**
ansond 0:137634ff4186 490 * \brief Write the TLS ECParameters record for a group
ansond 0:137634ff4186 491 *
ansond 0:137634ff4186 492 * \param grp ECP group used
ansond 0:137634ff4186 493 * \param olen Number of bytes actually written
ansond 0:137634ff4186 494 * \param buf Buffer to write to
ansond 0:137634ff4186 495 * \param blen Buffer length
ansond 0:137634ff4186 496 *
ansond 0:137634ff4186 497 * \return 0 if successful,
ansond 0:137634ff4186 498 * or POLARSSL_ERR_ECP_BUFFER_TOO_SMALL
ansond 0:137634ff4186 499 */
ansond 0:137634ff4186 500 int ecp_tls_write_group( const ecp_group *grp, size_t *olen,
ansond 0:137634ff4186 501 unsigned char *buf, size_t blen );
ansond 0:137634ff4186 502
ansond 0:137634ff4186 503 /**
ansond 0:137634ff4186 504 * \brief Addition: R = P + Q
ansond 0:137634ff4186 505 *
ansond 0:137634ff4186 506 * \param grp ECP group
ansond 0:137634ff4186 507 * \param R Destination point
ansond 0:137634ff4186 508 * \param P Left-hand point
ansond 0:137634ff4186 509 * \param Q Right-hand point
ansond 0:137634ff4186 510 *
ansond 0:137634ff4186 511 * \return 0 if successful,
ansond 0:137634ff4186 512 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
ansond 0:137634ff4186 513 *
ansond 0:137634ff4186 514 * \note This function does not support Montgomery curves, such as
ansond 0:137634ff4186 515 * Curve25519.
ansond 0:137634ff4186 516 */
ansond 0:137634ff4186 517 int ecp_add( const ecp_group *grp, ecp_point *R,
ansond 0:137634ff4186 518 const ecp_point *P, const ecp_point *Q );
ansond 0:137634ff4186 519
ansond 0:137634ff4186 520 /**
ansond 0:137634ff4186 521 * \brief Subtraction: R = P - Q
ansond 0:137634ff4186 522 *
ansond 0:137634ff4186 523 * \param grp ECP group
ansond 0:137634ff4186 524 * \param R Destination point
ansond 0:137634ff4186 525 * \param P Left-hand point
ansond 0:137634ff4186 526 * \param Q Right-hand point
ansond 0:137634ff4186 527 *
ansond 0:137634ff4186 528 * \return 0 if successful,
ansond 0:137634ff4186 529 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
ansond 0:137634ff4186 530 *
ansond 0:137634ff4186 531 * \note This function does not support Montgomery curves, such as
ansond 0:137634ff4186 532 * Curve25519.
ansond 0:137634ff4186 533 */
ansond 0:137634ff4186 534 int ecp_sub( const ecp_group *grp, ecp_point *R,
ansond 0:137634ff4186 535 const ecp_point *P, const ecp_point *Q );
ansond 0:137634ff4186 536
ansond 0:137634ff4186 537 /**
ansond 0:137634ff4186 538 * \brief Multiplication by an integer: R = m * P
ansond 0:137634ff4186 539 * (Not thread-safe to use same group in multiple threads)
ansond 0:137634ff4186 540 *
ansond 0:137634ff4186 541 * \param grp ECP group
ansond 0:137634ff4186 542 * \param R Destination point
ansond 0:137634ff4186 543 * \param m Integer by which to multiply
ansond 0:137634ff4186 544 * \param P Point to multiply
ansond 0:137634ff4186 545 * \param f_rng RNG function (see notes)
ansond 0:137634ff4186 546 * \param p_rng RNG parameter
ansond 0:137634ff4186 547 *
ansond 0:137634ff4186 548 * \return 0 if successful,
ansond 0:137634ff4186 549 * POLARSSL_ERR_ECP_INVALID_KEY if m is not a valid privkey
ansond 0:137634ff4186 550 * or P is not a valid pubkey,
ansond 0:137634ff4186 551 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed
ansond 0:137634ff4186 552 *
ansond 0:137634ff4186 553 * \note In order to prevent timing attacks, this function
ansond 0:137634ff4186 554 * executes the exact same sequence of (base field)
ansond 0:137634ff4186 555 * operations for any valid m. It avoids any if-branch or
ansond 0:137634ff4186 556 * array index depending on the value of m.
ansond 0:137634ff4186 557 *
ansond 0:137634ff4186 558 * \note If f_rng is not NULL, it is used to randomize intermediate
ansond 0:137634ff4186 559 * results in order to prevent potential timing attacks
ansond 0:137634ff4186 560 * targeting these results. It is recommended to always
ansond 0:137634ff4186 561 * provide a non-NULL f_rng (the overhead is negligible).
ansond 0:137634ff4186 562 */
ansond 0:137634ff4186 563 int ecp_mul( ecp_group *grp, ecp_point *R,
ansond 0:137634ff4186 564 const mpi *m, const ecp_point *P,
ansond 0:137634ff4186 565 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
ansond 0:137634ff4186 566
ansond 0:137634ff4186 567 /**
ansond 0:137634ff4186 568 * \brief Check that a point is a valid public key on this curve
ansond 0:137634ff4186 569 *
ansond 0:137634ff4186 570 * \param grp Curve/group the point should belong to
ansond 0:137634ff4186 571 * \param pt Point to check
ansond 0:137634ff4186 572 *
ansond 0:137634ff4186 573 * \return 0 if point is a valid public key,
ansond 0:137634ff4186 574 * POLARSSL_ERR_ECP_INVALID_KEY otherwise.
ansond 0:137634ff4186 575 *
ansond 0:137634ff4186 576 * \note This function only checks the point is non-zero, has valid
ansond 0:137634ff4186 577 * coordinates and lies on the curve, but not that it is
ansond 0:137634ff4186 578 * indeed a multiple of G. This is additional check is more
ansond 0:137634ff4186 579 * expensive, isn't required by standards, and shouldn't be
ansond 0:137634ff4186 580 * necessary if the group used has a small cofactor. In
ansond 0:137634ff4186 581 * particular, it is useless for the NIST groups which all
ansond 0:137634ff4186 582 * have a cofactor of 1.
ansond 0:137634ff4186 583 *
ansond 0:137634ff4186 584 * \note Uses bare components rather than an ecp_keypair structure
ansond 0:137634ff4186 585 * in order to ease use with other structures such as
ansond 0:137634ff4186 586 * ecdh_context of ecdsa_context.
ansond 0:137634ff4186 587 */
ansond 0:137634ff4186 588 int ecp_check_pubkey( const ecp_group *grp, const ecp_point *pt );
ansond 0:137634ff4186 589
ansond 0:137634ff4186 590 /**
ansond 0:137634ff4186 591 * \brief Check that an mpi is a valid private key for this curve
ansond 0:137634ff4186 592 *
ansond 0:137634ff4186 593 * \param grp Group used
ansond 0:137634ff4186 594 * \param d Integer to check
ansond 0:137634ff4186 595 *
ansond 0:137634ff4186 596 * \return 0 if point is a valid private key,
ansond 0:137634ff4186 597 * POLARSSL_ERR_ECP_INVALID_KEY otherwise.
ansond 0:137634ff4186 598 *
ansond 0:137634ff4186 599 * \note Uses bare components rather than an ecp_keypair structure
ansond 0:137634ff4186 600 * in order to ease use with other structures such as
ansond 0:137634ff4186 601 * ecdh_context of ecdsa_context.
ansond 0:137634ff4186 602 */
ansond 0:137634ff4186 603 int ecp_check_privkey( const ecp_group *grp, const mpi *d );
ansond 0:137634ff4186 604
ansond 0:137634ff4186 605 /**
ansond 0:137634ff4186 606 * \brief Generate a keypair
ansond 0:137634ff4186 607 *
ansond 0:137634ff4186 608 * \param grp ECP group
ansond 0:137634ff4186 609 * \param d Destination MPI (secret part)
ansond 0:137634ff4186 610 * \param Q Destination point (public part)
ansond 0:137634ff4186 611 * \param f_rng RNG function
ansond 0:137634ff4186 612 * \param p_rng RNG parameter
ansond 0:137634ff4186 613 *
ansond 0:137634ff4186 614 * \return 0 if successful,
ansond 0:137634ff4186 615 * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
ansond 0:137634ff4186 616 *
ansond 0:137634ff4186 617 * \note Uses bare components rather than an ecp_keypair structure
ansond 0:137634ff4186 618 * in order to ease use with other structures such as
ansond 0:137634ff4186 619 * ecdh_context of ecdsa_context.
ansond 0:137634ff4186 620 */
ansond 0:137634ff4186 621 int ecp_gen_keypair( ecp_group *grp, mpi *d, ecp_point *Q,
ansond 0:137634ff4186 622 int (*f_rng)(void *, unsigned char *, size_t),
ansond 0:137634ff4186 623 void *p_rng );
ansond 0:137634ff4186 624
ansond 0:137634ff4186 625 /**
ansond 0:137634ff4186 626 * \brief Generate a keypair
ansond 0:137634ff4186 627 *
ansond 0:137634ff4186 628 * \param grp_id ECP group identifier
ansond 0:137634ff4186 629 * \param key Destination keypair
ansond 0:137634ff4186 630 * \param f_rng RNG function
ansond 0:137634ff4186 631 * \param p_rng RNG parameter
ansond 0:137634ff4186 632 *
ansond 0:137634ff4186 633 * \return 0 if successful,
ansond 0:137634ff4186 634 * or a POLARSSL_ERR_ECP_XXX or POLARSSL_MPI_XXX error code
ansond 0:137634ff4186 635 */
ansond 0:137634ff4186 636 int ecp_gen_key( ecp_group_id grp_id, ecp_keypair *key,
ansond 0:137634ff4186 637 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );
ansond 0:137634ff4186 638
ansond 0:137634ff4186 639 /**
ansond 0:137634ff4186 640 * \brief Check a public-private key pair
ansond 0:137634ff4186 641 *
ansond 0:137634ff4186 642 * \param pub Keypair structure holding a public key
ansond 0:137634ff4186 643 * \param prv Keypair structure holding a private (plus public) key
ansond 0:137634ff4186 644 *
ansond 0:137634ff4186 645 * \return 0 if successful (keys are valid and match), or
ansond 0:137634ff4186 646 * POLARSSL_ERR_ECP_BAD_INPUT_DATA, or
ansond 0:137634ff4186 647 * a POLARSSL_ERR_ECP_XXX or POLARSSL_ERR_MPI_XXX code.
ansond 0:137634ff4186 648 */
ansond 0:137634ff4186 649 int ecp_check_pub_priv( const ecp_keypair *pub, const ecp_keypair *prv );
ansond 0:137634ff4186 650
ansond 0:137634ff4186 651 #if defined(POLARSSL_SELF_TEST)
ansond 0:137634ff4186 652 /**
ansond 0:137634ff4186 653 * \brief Checkup routine
ansond 0:137634ff4186 654 *
ansond 0:137634ff4186 655 * \return 0 if successful, or 1 if a test failed
ansond 0:137634ff4186 656 */
ansond 0:137634ff4186 657 int ecp_self_test( int verbose );
ansond 0:137634ff4186 658 #endif
ansond 0:137634ff4186 659
ansond 0:137634ff4186 660 #ifdef __cplusplus
ansond 0:137634ff4186 661 }
ansond 0:137634ff4186 662 #endif
ansond 0:137634ff4186 663
ansond 0:137634ff4186 664 #endif /* ecp.h */
ansond 0:137634ff4186 665