Branch data Line data Source code
1 : : /* ec_dh.c - TinyCrypt implementation of EC-DH */
2 : :
3 : : /*
4 : : * Copyright (c) 2014, Kenneth MacKay
5 : : * All rights reserved.
6 : : *
7 : : * Redistribution and use in source and binary forms, with or without
8 : : * modification, are permitted provided that the following conditions are met:
9 : : * * Redistributions of source code must retain the above copyright notice,
10 : : * this list of conditions and the following disclaimer.
11 : : * * Redistributions in binary form must reproduce the above copyright notice,
12 : : * this list of conditions and the following disclaimer in the documentation
13 : : * and/or other materials provided with the distribution.
14 : : *
15 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 : : * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 : : * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 : : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 : : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 : : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 : : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 : : * POSSIBILITY OF SUCH DAMAGE.
26 : : */
27 : :
28 : : /*
29 : : * Copyright (C) 2017 by Intel Corporation, All Rights Reserved.
30 : : *
31 : : * Redistribution and use in source and binary forms, with or without
32 : : * modification, are permitted provided that the following conditions are met:
33 : : *
34 : : * - Redistributions of source code must retain the above copyright notice,
35 : : * this list of conditions and the following disclaimer.
36 : : *
37 : : * - Redistributions in binary form must reproduce the above copyright
38 : : * notice, this list of conditions and the following disclaimer in the
39 : : * documentation and/or other materials provided with the distribution.
40 : : *
41 : : * - Neither the name of Intel Corporation nor the names of its contributors
42 : : * may be used to endorse or promote products derived from this software
43 : : * without specific prior written permission.
44 : : *
45 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
46 : : * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
49 : : * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50 : : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51 : : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52 : : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53 : : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 : : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55 : : * POSSIBILITY OF SUCH DAMAGE.
56 : : */
57 : : #include <tinycrypt/constants.h>
58 : : #include <tinycrypt/ecc.h>
59 : : #include <tinycrypt/ecc_dh.h>
60 : : #include <tinycrypt/utils.h>
61 : : #include <string.h>
62 : :
63 : 0 : int uECC_make_key_with_d(uint8_t *public_key, uint8_t *private_key,
64 : : unsigned int *d, uECC_Curve curve)
65 : : {
66 : :
67 : 0 : uECC_word_t _private[NUM_ECC_WORDS];
68 : 0 : uECC_word_t _public[NUM_ECC_WORDS * 2];
69 : :
70 : : /* This function is designed for test purposes-only (such as validating NIST
71 : : * test vectors) as it uses a provided value for d instead of generating
72 : : * it uniformly at random. */
73 : 0 : memcpy (_private, d, NUM_ECC_BYTES);
74 : :
75 : : /* Computing public-key from private: */
76 [ # # ]: 0 : if (EccPoint_compute_public_key(_public, _private, curve)) {
77 : :
78 : : /* Converting buffers to correct bit order: */
79 : 0 : uECC_vli_nativeToBytes(private_key,
80 : 0 : BITS_TO_BYTES(curve->num_n_bits),
81 : : _private);
82 : 0 : uECC_vli_nativeToBytes(public_key,
83 : 0 : curve->num_bytes,
84 : : _public);
85 : 0 : uECC_vli_nativeToBytes(public_key + curve->num_bytes,
86 : 0 : curve->num_bytes,
87 : 0 : _public + curve->num_words);
88 : :
89 : : /* erasing temporary buffer used to store secret: */
90 : 0 : _set_secure(_private, 0, NUM_ECC_BYTES);
91 : :
92 : 0 : return 1;
93 : : }
94 : : return 0;
95 : : }
96 : :
97 : 0 : int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve)
98 : : {
99 : :
100 : 0 : uECC_word_t _random[NUM_ECC_WORDS * 2];
101 : 0 : uECC_word_t _private[NUM_ECC_WORDS];
102 : 0 : uECC_word_t _public[NUM_ECC_WORDS * 2];
103 : 0 : uECC_word_t tries;
104 : :
105 [ # # ]: 0 : for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
106 : : /* Generating _private uniformly at random: */
107 : 0 : uECC_RNG_Function rng_function = uECC_get_rng();
108 [ # # # # ]: 0 : if (!rng_function ||
109 : 0 : !rng_function((uint8_t *)_random, 2 * NUM_ECC_WORDS*uECC_WORD_SIZE)) {
110 : 0 : return 0;
111 : : }
112 : :
113 : : /* computing modular reduction of _random (see FIPS 186.4 B.4.1): */
114 : 0 : uECC_vli_mmod(_private, _random, curve->n, BITS_TO_WORDS(curve->num_n_bits));
115 : :
116 : : /* Computing public-key from private: */
117 [ # # ]: 0 : if (EccPoint_compute_public_key(_public, _private, curve)) {
118 : :
119 : : /* Converting buffers to correct bit order: */
120 : 0 : uECC_vli_nativeToBytes(private_key,
121 : 0 : BITS_TO_BYTES(curve->num_n_bits),
122 : : _private);
123 : 0 : uECC_vli_nativeToBytes(public_key,
124 : 0 : curve->num_bytes,
125 : : _public);
126 : 0 : uECC_vli_nativeToBytes(public_key + curve->num_bytes,
127 : 0 : curve->num_bytes,
128 : 0 : _public + curve->num_words);
129 : :
130 : : /* erasing temporary buffer that stored secret: */
131 : 0 : _set_secure(_private, 0, NUM_ECC_BYTES);
132 : :
133 : 0 : return 1;
134 : : }
135 : : }
136 : : return 0;
137 : : }
138 : :
139 : 0 : int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
140 : : uint8_t *secret, uECC_Curve curve)
141 : : {
142 : :
143 : 0 : uECC_word_t _public[NUM_ECC_WORDS * 2];
144 : 0 : uECC_word_t _private[NUM_ECC_WORDS];
145 : :
146 : 0 : uECC_word_t tmp[NUM_ECC_WORDS];
147 : 0 : uECC_word_t *p2[2] = {_private, tmp};
148 : 0 : uECC_word_t *initial_Z = 0;
149 : 0 : uECC_word_t carry;
150 : 0 : wordcount_t num_words = curve->num_words;
151 : 0 : wordcount_t num_bytes = curve->num_bytes;
152 : 0 : int r;
153 : :
154 : : /* Converting buffers to correct bit order: */
155 : 0 : uECC_vli_bytesToNative(_private,
156 : : private_key,
157 : 0 : BITS_TO_BYTES(curve->num_n_bits));
158 : 0 : uECC_vli_bytesToNative(_public,
159 : : public_key,
160 : : num_bytes);
161 : 0 : uECC_vli_bytesToNative(_public + num_words,
162 : : public_key + num_bytes,
163 : : num_bytes);
164 : :
165 : : /* Regularize the bitcount for the private key so that attackers cannot use a
166 : : * side channel attack to learn the number of leading zeros. */
167 : 0 : carry = regularize_k(_private, _private, tmp, curve);
168 : :
169 : : /* If an RNG function was specified, try to get a random initial Z value to
170 : : * improve protection against side-channel attacks. */
171 [ # # ]: 0 : if (uECC_get_rng()) {
172 [ # # ]: 0 : if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) {
173 : 0 : r = 0;
174 : 0 : goto clear_and_out;
175 : : }
176 : 0 : initial_Z = p2[carry];
177 : : }
178 : :
179 : 0 : EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1,
180 : : curve);
181 : :
182 : 0 : uECC_vli_nativeToBytes(secret, num_bytes, _public);
183 : 0 : r = !EccPoint_isZero(_public, curve);
184 : :
185 : 0 : clear_and_out:
186 : : /* erasing temporary buffer used to store secret: */
187 : 0 : _set_secure(p2, 0, sizeof(p2));
188 : 0 : _set_secure(tmp, 0, sizeof(tmp));
189 : 0 : _set_secure(_private, 0, sizeof(_private));
190 : :
191 : 0 : return r;
192 : : }
|