xref: /btstack/3rd-party/micro-ecc/uECC.h (revision 43d468d2c30e744695e5d199f757400a8f04c0fd)
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