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