• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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