1 /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2 3 #ifndef MICRO_ECC_H_ 4 #define MICRO_ECC_H_ 5 6 // BK 7 #include "btstack_config_uECC.h" 8 // 9 10 #include <stdint.h> 11 12 /* Platform selection options. 13 If uECC_PLATFORM is not defined, the code will try to guess it based on compiler macros. 14 Possible values for uECC_PLATFORM are defined below: */ 15 #define uECC_arch_other 0 16 #define uECC_x86 1 17 #define uECC_x86_64 2 18 #define uECC_arm 3 19 #define uECC_arm_thumb 4 20 #define uECC_avr 5 21 #define uECC_arm_thumb2 6 22 23 /* If desired, you can define uECC_WORD_SIZE as appropriate for your platform (1, 4, or 8 bytes). 24 If uECC_WORD_SIZE is not explicitly defined then it will be automatically set based on your 25 platform. */ 26 27 /* Inline assembly options. 28 uECC_asm_none - Use standard C99 only. 29 uECC_asm_small - Use GCC inline assembly for the target platform (if available), optimized for 30 minimum size. 31 uECC_asm_fast - Use GCC inline assembly optimized for maximum speed. */ 32 #define uECC_asm_none 0 33 #define uECC_asm_small 1 34 #define uECC_asm_fast 2 35 #ifndef uECC_ASM 36 #define uECC_ASM uECC_asm_fast 37 #endif 38 39 /* Curve selection options. */ 40 #define uECC_secp160r1 1 41 #define uECC_secp192r1 2 42 #define uECC_secp256r1 3 43 #define uECC_secp256k1 4 44 #define uECC_secp224r1 5 45 #ifndef uECC_CURVE 46 #define uECC_CURVE uECC_secp160r1 47 #endif 48 49 /* uECC_SQUARE_FUNC - If enabled (defined as nonzero), this will cause a specific function to be 50 used for (scalar) squaring instead of the generic multiplication function. This will make things 51 faster by about 8% but increases the code size. */ 52 #ifndef uECC_SQUARE_FUNC 53 #define uECC_SQUARE_FUNC 1 54 #endif 55 56 #define uECC_CONCAT1(a, b) a##b 57 #define uECC_CONCAT(a, b) uECC_CONCAT1(a, b) 58 59 #define uECC_size_1 20 /* secp160r1 */ 60 #define uECC_size_2 24 /* secp192r1 */ 61 #define uECC_size_3 32 /* secp256r1 */ 62 #define uECC_size_4 32 /* secp256k1 */ 63 #define uECC_size_5 28 /* secp224r1 */ 64 65 #define uECC_BYTES uECC_CONCAT(uECC_size_, uECC_CURVE) 66 67 #ifdef __cplusplus 68 extern "C" 69 { 70 #endif 71 72 /* uECC_RNG_Function type 73 The RNG function should fill 'size' random bytes into 'dest'. It should return 1 if 74 'dest' was filled with random data, or 0 if the random data could not be generated. 75 The filled-in values should be either truly random, or from a cryptographically-secure PRNG. 76 77 A correctly functioning RNG function must be set (using uECC_set_rng()) before calling 78 uECC_make_key() or uECC_sign(). 79 80 Setting a correctly functioning RNG function improves the resistance to side-channel attacks 81 for uECC_shared_secret() and uECC_sign_deterministic(). 82 83 A correct RNG function is set by default when building for Windows, Linux, or OS X. 84 If you are building on another POSIX-compliant system that supports /dev/random or /dev/urandom, 85 you can define uECC_POSIX to use the predefined RNG. For embedded platforms there is no predefined 86 RNG function; you must provide your own. 87 */ 88 typedef int (*uECC_RNG_Function)(uint8_t *dest, unsigned size); 89 90 /* uECC_set_rng() function. 91 Set the function that will be used to generate random bytes. The RNG function should 92 return 1 if the random data was generated, or 0 if the random data could not be generated. 93 94 On platforms where there is no predefined RNG function (eg embedded platforms), this must 95 be called before uECC_make_key() or uECC_sign() are used. 96 97 Inputs: 98 rng_function - The function that will be used to generate random bytes. 99 */ 100 void uECC_set_rng(uECC_RNG_Function rng_function); 101 102 /* uECC_make_key() function. 103 Create a public/private key pair. 104 105 Outputs: 106 public_key - Will be filled in with the public key. 107 private_key - Will be filled in with the private key. 108 109 Returns 1 if the key pair was generated successfully, 0 if an error occurred. 110 */ 111 int uECC_make_key(uint8_t public_key[uECC_BYTES*2], uint8_t private_key[uECC_BYTES]); 112 113 /* uECC_shared_secret() function. 114 Compute a shared secret given your secret key and someone else's public key. 115 Note: It is recommended that you hash the result of uECC_shared_secret() before using it for 116 symmetric encryption or HMAC. 117 118 Inputs: 119 public_key - The public key of the remote party. 120 private_key - Your private key. 121 122 Outputs: 123 secret - Will be filled in with the shared secret value. 124 125 Returns 1 if the shared secret was generated successfully, 0 if an error occurred. 126 */ 127 int uECC_shared_secret(const uint8_t public_key[uECC_BYTES*2], 128 const uint8_t private_key[uECC_BYTES], 129 uint8_t secret[uECC_BYTES]); 130 131 /* uECC_sign() function. 132 Generate an ECDSA signature for a given hash value. 133 134 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to 135 this function along with your private key. 136 137 Inputs: 138 private_key - Your private key. 139 message_hash - The hash of the message to sign. 140 141 Outputs: 142 signature - Will be filled in with the signature value. 143 144 Returns 1 if the signature generated successfully, 0 if an error occurred. 145 */ 146 int uECC_sign(const uint8_t private_key[uECC_BYTES], 147 const uint8_t message_hash[uECC_BYTES], 148 uint8_t signature[uECC_BYTES*2]); 149 150 /* uECC_HashContext structure. 151 This is used to pass in an arbitrary hash function to uECC_sign_deterministic(). 152 The structure will be used for multiple hash computations; each time a new hash 153 is computed, init_hash() will be called, followed by one or more calls to 154 update_hash(), and finally a call to finish_hash() to prudoce the resulting hash. 155 156 The intention is that you will create a structure that includes uECC_HashContext 157 followed by any hash-specific data. For example: 158 159 typedef struct SHA256_HashContext { 160 uECC_HashContext uECC; 161 SHA256_CTX ctx; 162 } SHA256_HashContext; 163 164 void init_SHA256(uECC_HashContext *base) { 165 SHA256_HashContext *context = (SHA256_HashContext *)base; 166 SHA256_Init(&context->ctx); 167 } 168 169 void update_SHA256(uECC_HashContext *base, 170 const uint8_t *message, 171 unsigned message_size) { 172 SHA256_HashContext *context = (SHA256_HashContext *)base; 173 SHA256_Update(&context->ctx, message, message_size); 174 } 175 176 void finish_SHA256(uECC_HashContext *base, uint8_t *hash_result) { 177 SHA256_HashContext *context = (SHA256_HashContext *)base; 178 SHA256_Final(hash_result, &context->ctx); 179 } 180 181 ... when signing ... 182 { 183 uint8_t tmp[32 + 32 + 64]; 184 SHA256_HashContext ctx = {{&init_SHA256, &update_SHA256, &finish_SHA256, 64, 32, tmp}}; 185 uECC_sign_deterministic(key, message_hash, &ctx.uECC, signature); 186 } 187 */ 188 typedef struct uECC_HashContext { 189 void (*init_hash)(struct uECC_HashContext *context); 190 void (*update_hash)(struct uECC_HashContext *context, 191 const uint8_t *message, 192 unsigned message_size); 193 void (*finish_hash)(struct uECC_HashContext *context, uint8_t *hash_result); 194 unsigned block_size; /* Hash function block size in bytes, eg 64 for SHA-256. */ 195 unsigned result_size; /* Hash function result size in bytes, eg 32 for SHA-256. */ 196 uint8_t *tmp; /* Must point to a buffer of at least (2 * result_size + block_size) bytes. */ 197 } uECC_HashContext; 198 199 /* uECC_sign_deterministic() function. 200 Generate an ECDSA signature for a given hash value, using a deterministic algorithm 201 (see RFC 6979). You do not need to set the RNG using uECC_set_rng() before calling 202 this function; however, if the RNG is defined it will improve resistance to side-channel 203 attacks. 204 205 Usage: Compute a hash of the data you wish to sign (SHA-2 is recommended) and pass it in to 206 this function along with your private key and a hash context. 207 208 Inputs: 209 private_key - Your private key. 210 message_hash - The hash of the message to sign. 211 hash_context - A hash context to use. 212 213 Outputs: 214 signature - Will be filled in with the signature value. 215 216 Returns 1 if the signature generated successfully, 0 if an error occurred. 217 */ 218 int uECC_sign_deterministic(const uint8_t private_key[uECC_BYTES], 219 const uint8_t message_hash[uECC_BYTES], 220 uECC_HashContext *hash_context, 221 uint8_t signature[uECC_BYTES*2]); 222 223 /* uECC_verify() function. 224 Verify an ECDSA signature. 225 226 Usage: Compute the hash of the signed data using the same hash as the signer and 227 pass it to this function along with the signer's public key and the signature values (r and s). 228 229 Inputs: 230 public_key - The signer's public key 231 hash - The hash of the signed data. 232 signature - The signature value. 233 234 Returns 1 if the signature is valid, 0 if it is invalid. 235 */ 236 int uECC_verify(const uint8_t public_key[uECC_BYTES*2], 237 const uint8_t hash[uECC_BYTES], 238 const uint8_t signature[uECC_BYTES*2]); 239 240 /* uECC_compress() function. 241 Compress a public key. 242 243 Inputs: 244 public_key - The public key to compress. 245 246 Outputs: 247 compressed - Will be filled in with the compressed public key. 248 */ 249 void uECC_compress(const uint8_t public_key[uECC_BYTES*2], uint8_t compressed[uECC_BYTES+1]); 250 251 /* uECC_decompress() function. 252 Decompress a compressed public key. 253 254 Inputs: 255 compressed - The compressed public key. 256 257 Outputs: 258 public_key - Will be filled in with the decompressed public key. 259 */ 260 void uECC_decompress(const uint8_t compressed[uECC_BYTES+1], uint8_t public_key[uECC_BYTES*2]); 261 262 /* uECC_valid_public_key() function. 263 Check to see if a public key is valid. 264 265 Note that you are not required to check for a valid public key before using any other uECC 266 functions. However, you may wish to avoid spending CPU time computing a shared secret or 267 verifying a signature using an invalid public key. 268 269 Inputs: 270 public_key - The public key to check. 271 272 Returns 1 if the public key is valid, 0 if it is invalid. 273 */ 274 int uECC_valid_public_key(const uint8_t public_key[uECC_BYTES*2]); 275 276 /* uECC_compute_public_key() function. 277 Compute the corresponding public key for a private key. 278 279 Inputs: 280 private_key - The private key to compute the public key for 281 282 Outputs: 283 public_key - Will be filled in with the corresponding public key 284 285 Returns 1 if the key was computed successfully, 0 if an error occurred. 286 */ 287 int uECC_compute_public_key(const uint8_t private_key[uECC_BYTES], 288 uint8_t public_key[uECC_BYTES * 2]); 289 290 291 /* uECC_bytes() function. 292 Returns the value of uECC_BYTES. Helpful for foreign-interfaces to higher-level languages. 293 */ 294 int uECC_bytes(void); 295 296 /* uECC_curve() function. 297 Returns the value of uECC_CURVE. Helpful for foreign-interfaces to higher-level languages. 298 */ 299 int uECC_curve(void); 300 301 #ifdef __cplusplus 302 } /* end of extern "C" */ 303 #endif 304 305 #endif /* _MICRO_ECC_H_ */ 306