1 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 3 #ifndef _UECC_H_ 4 #define _UECC_H_ 5 6 #include <stdint.h> 7 8 /* Platform selection options. 9 If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. 10 Possible values for uECC_PLATFORM are defined below: */ 11 #define uECC_arch_other 0 12 #define uECC_x86 1 13 #define uECC_x86_64 2 14 #define uECC_arm 3 15 #define uECC_arm_thumb 4 16 #define uECC_arm_thumb2 5 17 #define uECC_arm64 6 18 #define uECC_avr 7 19 20 /* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). 21 If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your 22 platform. */ 23 24 /* Optimization level; trade speed for code size. 25 Larger values produce code that is faster but larger. 26 Currently supported values are 0 - 4; 0 is unusably slow for most applications. 27 Optimization level 4 currently only has an effect ARM platforms where more than one 28 curve is enabled. */ 29 #ifndef uECC_OPTIMIZATION_LEVEL 30 #define uECC_OPTIMIZATION_LEVEL 2 31 #endif 32 33 /* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be 34 used for (scalar) squaring instead of the generic multiplication function. This can make things 35 faster somewhat faster, but increases the code size. */ 36 #ifndef uECC_SQUARE_FUNC 37 #define uECC_SQUARE_FUNC 0 38 #endif 39 40 /* uECC_VLI_NATIVE_LITTLE_ENDIAN - If enabled (defined as nonzero), this will switch to native 41 little-endian format for *all* arrays passed in and out of the public API. This includes public 42 and private keys, shared secrets, signatures and message hashes. 43 Using this switch reduces the amount of call stack memory used by uECC, since less intermediate 44 translations are required. 45 Note that this will *only* work on native little-endian processors and it will treat the uint8_t 46 arrays passed into the public API as word arrays, therefore requiring the provided byte arrays 47 to be word aligned on architectures that do not support unaligned accesses. 48 IMPORTANT: Keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=1 are incompatible 49 with keys and signatures generated with uECC_VLI_NATIVE_LITTLE_ENDIAN=0; all parties must use 50 the same endianness. */ 51 #ifndef uECC_VLI_NATIVE_LITTLE_ENDIAN 52 #define uECC_VLI_NATIVE_LITTLE_ENDIAN 0 53 #endif 54 55 /* Curve support selection. Set to 0 to remove that curve. */ 56 #ifndef uECC_SUPPORTS_secp160r1 57 #define uECC_SUPPORTS_secp160r1 1 58 #endif 59 #ifndef uECC_SUPPORTS_secp192r1 60 #define uECC_SUPPORTS_secp192r1 1 61 #endif 62 #ifndef uECC_SUPPORTS_secp224r1 63 #define uECC_SUPPORTS_secp224r1 1 64 #endif 65 #ifndef uECC_SUPPORTS_secp256r1 66 #define uECC_SUPPORTS_secp256r1 1 67 #endif 68 #ifndef uECC_SUPPORTS_secp256k1 69 #define uECC_SUPPORTS_secp256k1 1 70 #endif 71 72 /* Specifies whether compressed point format is supported. 73 Set to 0 to disable point compression/decompression functions. */ 74 #ifndef uECC_SUPPORT_COMPRESSED_POINT 75 #define uECC_SUPPORT_COMPRESSED_POINT 1 76 #endif 77 78 struct uECC_Curve_t; 79 typedef const struct uECC_Curve_t * uECC_Curve; 80 81 #ifdef __cplusplus 82 extern "C" 83 { 84 #endif 85 86 #if uECC_SUPPORTS_secp160r1 87 uECC_Curve uECC_secp160r1(void); 88 #endif 89 #if uECC_SUPPORTS_secp192r1 90 uECC_Curve uECC_secp192r1(void); 91 #endif 92 #if uECC_SUPPORTS_secp224r1 93 uECC_Curve uECC_secp224r1(void); 94 #endif 95 #if uECC_SUPPORTS_secp256r1 96 uECC_Curve uECC_secp256r1(void); 97 #endif 98 #if uECC_SUPPORTS_secp256k1 99 uECC_Curve uECC_secp256k1(void); 100 #endif 101 102 /* uECC_RNG_Function type 103 The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if 104 'dest' was filled with random data, or 0 if the random data could not be generated. 105 The filled-in values should be either truly random, or from a cryptographically-secure PRNG. 106 107 A correctly functioning RNG function must be set (using uECC_set_rng()) before calling 108 uECC_make_key() or uECC_sign(). 109 110 Setting a correctly functioning RNG function improves the resistance to side-channel attacks 111 for uECC_shared_secret() and uECC_sign_deterministic(). 112 113 A correct RNG function is set by default when building for Windows, Linux, or OS X. 114 If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, 115 you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined 116 RNG function; you must provide your own. 117 */ 118 typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); 119 120 /* uECC_set_rng() function. 121 Set the function that will be used to generate random bytes. The RNG function should 122 return 1 if the random data was generated, or 0 if the random data could not be generated. 123 124 On platforms where there is no predefined RNG function (eg embedded platforms), this must 125 be called before uECC_make_key() or uECC_sign() are used. 126 127 Inputs: 128 rng_function - The function that will be used to generate random bytes. 129 */ 130 void uECC_set_rng(uECC_RNG_Function rng_function); 131 132 /* uECC_get_rng() function. 133 134 Returns the function that will be used to generate random bytes. 135 */ 136 uECC_RNG_Function uECC_get_rng(void); 137 138 /* uECC_curve_private_key_size() function. 139 140 Returns the size of a private key for the curve in bytes. 141 */ 142 int uECC_curve_private_key_size(uECC_Curve curve); 143 144 /* uECC_curve_public_key_size() function. 145 146 Returns the size of a public key for the curve in bytes. 147 */ 148 int uECC_curve_public_key_size(uECC_Curve curve); 149 150 /* uECC_make_key() function. 151 Create a public/private key pair. 152 153 Outputs: 154 public_key - Will be filled in with the public key. Must be at least 2 * the curve size 155 (in bytes) long. For example, if the curve is secp256r1, public_key must be 64 156 bytes long. 157 private_key - Will be filled in with the private key. Must be as long as the curve order; this 158 is typically the same as the curve size, except for secp160r1. For example, if the 159 curve is secp256r1, private_key must be 32 bytes long. 160 161 For secp160r1, private_key must be 21 bytes long! Note that the first byte will 162 almost always be 0 (there is about a 1 in 2^80 chance of it being non-zero). 163 164 Returns 1 if the key pair was generated successfully, 0 if an error occurred. 165 */ 166 int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve); 167 168 /* uECC_shared_secret() function. 169 Compute a shared secret given your secret key and someone else's public key. 170 Note: It is recommended that you hash the result of uECC_shared_secret() before using it for 171 symmetric encryption or HMAC. 172 173 Inputs: 174 public_key - The public key of the remote party. 175 private_key - Your private key. 176 177 Outputs: 178 secret - Will be filled in with the shared secret value. Must be the same size as the 179 curve size; for example, if the curve is secp256r1, secret must be 32 bytes long. 180 181 Returns 1 if the shared secret was generated successfully, 0 if an error occurred. 182 */ 183 int uECC_shared_secret(const uint8_t *public_key, 184 const uint8_t *private_key, 185 uint8_t *secret, 186 uECC_Curve curve); 187 188 #if uECC_SUPPORT_COMPRESSED_POINT 189 /* uECC_compress() function. 190 Compress a public key. 191 192 Inputs: 193 public_key - The public key to compress. 194 195 Outputs: 196 compressed - Will be filled in with the compressed public key. Must be at least 197 (curve size + 1) bytes long; for example, if the curve is secp256r1, 198 compressed must be 33 bytes long. 199 */ 200 void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve); 201 202 /* uECC_decompress() function. 203 Decompress a compressed public key. 204 205 Inputs: 206 compressed - The compressed public key. 207 208 Outputs: 209 public_key - Will be filled in with the decompressed public key. 210 */ 211 void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve); 212 #endif /* uECC_SUPPORT_COMPRESSED_POINT */ 213 214 /* uECC_valid_public_key() function. 215 Check to see if a public key is valid. 216 217 Note that you are not required to check for a valid public key before using any other uECC 218 functions. However, you may wish to avoid spending CPU time computing a shared secret or 219 verifying a signature using an invalid public key. 220 221 Inputs: 222 public_key - The public key to check. 223 224 Returns 1 if the public key is valid, 0 if it is invalid. 225 */ 226 int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve); 227 228 /* uECC_compute_public_key() function. 229 Compute the corresponding public key for a private key. 230 231 Inputs: 232 private_key - The private key to compute the public key for 233 234 Outputs: 235 public_key - Will be filled in with the corresponding public key 236 237 Returns 1 if the key was computed successfully, 0 if an error occurred. 238 */ 239 int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve); 240 241 /* uECC_sign() function. 242 Generate an ECDSA signature for a given hash value. 243 244 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to 245 this function along with your private key. 246 247 Inputs: 248 private_key - Your private key. 249 message_hash - The hash of the message to sign. 250 hash_size - The size of message_hash in bytes. 251 252 Outputs: 253 signature - Will be filled in with the signature value. Must be at least 2 * curve size long. 254 For example, if the curve is secp256r1, signature must be 64 bytes long. 255 256 Returns 1 if the signature generated successfully, 0 if an error occurred. 257 */ 258 int uECC_sign(const uint8_t *private_key, 259 const uint8_t *message_hash, 260 unsigned hash_size, 261 uint8_t *signature, 262 uECC_Curve curve); 263 264 /* uECC_HashContext structure. 265 This is used to pass in an arbitrary hash function to uECC_sign_deterministic(). 266 The structure will be used for multiple hash computations; each time a new hash 267 is computed, init_hash() will be called, followed by one or more calls to 268 update_hash(), and finally a call to finish_hash() to produce the resulting hash. 269 270 The intention is that you will create a structure that includes uECC_HashContext 271 followed by any hash-specific data. For example: 272 273 typedef struct SHA256_HashContext { 274 uECC_HashContext uECC; 275 SHA256_CTX ctx; 276 } SHA256_HashContext; 277 278 void init_SHA256(uECC_HashContext *base) { 279 SHA256_HashContext *context = (SHA256_HashContext *)base; 280 SHA256_Init(&context->ctx); 281 } 282 283 void update_SHA256(uECC_HashContext *base, 284 const uint8_t *message, 285 unsigned message_size) { 286 SHA256_HashContext *context = (SHA256_HashContext *)base; 287 SHA256_Update(&context->ctx, message, message_size); 288 } 289 290 void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { 291 SHA256_HashContext *context = (SHA256_HashContext *)base; 292 SHA256_Final(hash_result, &context->ctx); 293 } 294 295 ... when signing ... 296 { 297 uint8_t tmp[32 + 32 + 64]; 298 SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}}; 299 uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature); 300 } 301 */ 302 typedef struct uECC_HashContext { 303 void (*init_hash)(const struct uECC_HashContext *context); 304 void (*update_hash)(const struct uECC_HashContext *context, 305 const uint8_t *message, 306 unsigned message_size); 307 void (*finish_hash)(const struct uECC_HashContext *context, uint8_t *hash_result); 308 unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */ 309 unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */ 310 uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */ 311 } uECC_HashContext; 312 313 /* uECC_sign_deterministic() function. 314 Generate an ECDSA signature for a given hash value, using a deterministic algorithm 315 (see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling 316 this function; however, if the RNG is defined it will improve resistance to side-channel 317 attacks. 318 319 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it to 320 this function along with your private key and a hash context. Note that the message_hash 321 does not need to be computed with the same hash function used by hash_context. 322 323 Inputs: 324 private_key - Your private key. 325 message_hash - The hash of the message to sign. 326 hash_size - The size of message_hash in bytes. 327 hash_context - A hash context to use. 328 329 Outputs: 330 signature - Will be filled in with the signature value. 331 332 Returns 1 if the signature generated successfully, 0 if an error occurred. 333 */ 334 int uECC_sign_deterministic(const uint8_t *private_key, 335 const uint8_t *message_hash, 336 unsigned hash_size, 337 const uECC_HashContext *hash_context, 338 uint8_t *signature, 339 uECC_Curve curve); 340 341 /* uECC_verify() function. 342 Verify an ECDSA signature. 343 344 Usage: Compute the hash of the signed data using the same hash as the signer and 345 pass it to this function along with the signer's public key and the signature values (r and s). 346 347 Inputs: 348 public_key - The signer's public key. 349 message_hash - The hash of the signed data. 350 hash_size - The size of message_hash in bytes. 351 signature - The signature value. 352 353 Returns 1 if the signature is valid, 0 if it is invalid. 354 */ 355 int uECC_verify(const uint8_t *public_key, 356 const uint8_t *message_hash, 357 unsigned hash_size, 358 const uint8_t *signature, 359 uECC_Curve curve); 360 361 #ifdef __cplusplus 362 } /* end of extern "C" */ 363 #endif 364 365 #endif /* _UECC_H_ */ 366