]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/WolfSSL/wolfcrypt/src/ed25519.c
Update WolfSSL library to the latest version.
[freertos] / FreeRTOS-Plus / Source / WolfSSL / wolfcrypt / src / ed25519.c
1 /* ed25519.c
2  *
3  * Copyright (C) 2006-2015 wolfSSL Inc.
4  *
5  * This file is part of wolfSSL. (formerly known as CyaSSL)
6  *
7  * wolfSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * wolfSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22  /* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. */
23
24 #ifdef HAVE_CONFIG_H
25     #include <config.h>
26 #endif
27
28 /* in case user set HAVE_ED25519 there */
29 #include <wolfssl/wolfcrypt/settings.h>
30
31 #ifdef HAVE_ED25519
32
33 #include <wolfssl/wolfcrypt/ed25519.h>
34 #include <wolfssl/wolfcrypt/error-crypt.h>
35 #ifdef NO_INLINE
36     #include <wolfssl/wolfcrypt/misc.h>
37 #else
38     #include <wolfcrypt/src/misc.c>
39 #endif
40
41
42 /*
43     generate an ed25519 key pair.
44     returns 0 on success
45  */
46 int wc_ed25519_make_key(RNG* rng, int keySz, ed25519_key* key)
47 {
48     byte  az[64];
49     int   ret;
50     ge_p3 A;
51
52     if (rng == NULL || key == NULL)
53         return BAD_FUNC_ARG;
54
55     /* ed25519 has 32 byte key sizes */
56     if (keySz != ED25519_KEY_SIZE)
57         return BAD_FUNC_ARG;
58
59     ret = 0;
60     ret |= wc_RNG_GenerateBlock(rng, key->k, 32);
61     ret |= wc_Sha512Hash(key->k, 32, az);
62     az[0] &= 248;
63     az[31] &= 63;
64     az[31] |= 64;
65
66     ge_scalarmult_base(&A, az);
67     ge_p3_tobytes(key->p, &A);
68     XMEMMOVE(key->k + 32, key->p, 32);
69
70     return ret;
71 }
72
73
74 /*
75     in     contains the message to sign
76     inlen  is the length of the message to sign
77     out    is the buffer to write the signature
78     outlen [in/out] input size of out buf
79                     output gets set as the final length of out
80     key    is the ed25519 key to use when signing
81     return 0 on success
82  */
83 int wc_ed25519_sign_msg(const byte* in, word32 inlen, byte* out,
84                         word32 *outlen, ed25519_key* key)
85 {
86     ge_p3  R;
87     byte   nonce[SHA512_DIGEST_SIZE];
88     byte   hram[SHA512_DIGEST_SIZE];
89     byte   az[64];
90     word32 sigSz;
91     Sha512 sha;
92     int    ret = 0;
93
94     /* sanity check on arguments */
95     if (in == NULL || out == NULL || outlen == NULL || key == NULL)
96         return BAD_FUNC_ARG;
97
98     /* check and set up out length */
99     ret   = 0;
100     sigSz = wc_ed25519_sig_size(key);
101     if (*outlen < sigSz)
102         return BAD_FUNC_ARG;
103     *outlen = sigSz;
104
105     /* step 1: create nonce to use where nonce is r in
106        r = H(h_b, ... ,h_2b-1,M) */
107     ret |= wc_Sha512Hash(key->k,32,az);
108     az[0]  &= 248;
109     az[31] &= 63;
110     az[31] |= 64;
111     ret |= wc_InitSha512(&sha);
112     ret |= wc_Sha512Update(&sha, az + 32, 32);
113     ret |= wc_Sha512Update(&sha, in, inlen);
114     ret |= wc_Sha512Final(&sha, nonce);
115     sc_reduce(nonce);
116
117     /* step 2: computing R = rB where rB is the scalar multiplication of
118        r and B */
119     ge_scalarmult_base(&R,nonce);
120     ge_p3_tobytes(out,&R);
121
122     /* step 3: hash R + public key + message getting H(R,A,M) then
123        creating S = (r + H(R,A,M)a) mod l */
124     ret |= wc_InitSha512(&sha);
125     ret |= wc_Sha512Update(&sha, out, 32);
126     ret |= wc_Sha512Update(&sha, key->p, 32);
127     ret |= wc_Sha512Update(&sha, in, inlen);
128     ret |= wc_Sha512Final(&sha, hram);
129     sc_reduce(hram);
130     sc_muladd(out + 32, hram, az, nonce);
131
132     return ret;
133 }
134
135
136 /*
137    sig     is array of bytes containing the signature
138    siglen  is the length of sig byte array
139    msg     the array of bytes containing the message
140    msglen  length of msg array
141    stat    will be 1 on successful verify and 0 on unsuccessful
142 */
143 int wc_ed25519_verify_msg(byte* sig, word32 siglen, const byte* msg,
144                           word32 msglen, int* stat, ed25519_key* key)
145 {
146     byte   rcheck[32];
147     byte   h[SHA512_DIGEST_SIZE];
148     ge_p3  A;
149     ge_p2  R;
150     word32 sigSz;
151     int    ret;
152     Sha512 sha;
153
154     /* sanity check on arguments */
155     if (sig == NULL || msg == NULL || stat == NULL || key == NULL)
156         return BAD_FUNC_ARG;
157
158     ret   = 0;
159     *stat = 0;
160     sigSz = wc_ed25519_size(key);
161
162     /* check on basics needed to verify signature */
163     if (siglen < sigSz)
164         return BAD_FUNC_ARG;
165     if (sig[63] & 224)
166         return BAD_FUNC_ARG;
167
168     /* uncompress A (public key), test if valid, and negate it */
169     if (ge_frombytes_negate_vartime(&A, key->p) != 0)
170         return BAD_FUNC_ARG;
171
172     /* find H(R,A,M) and store it as h */
173     ret |= wc_InitSha512(&sha);
174     ret |= wc_Sha512Update(&sha, sig,    32);
175     ret |= wc_Sha512Update(&sha, key->p, 32);
176     ret |= wc_Sha512Update(&sha, msg,    msglen);
177     ret |= wc_Sha512Final(&sha,  h);
178     sc_reduce(h);
179
180     /*
181        Uses a fast single-signature verification SB = R + H(R,A,M)A becomes
182        SB - H(R,A,M)A saving decompression of R
183     */
184     ret |= ge_double_scalarmult_vartime(&R, h, &A, sig + 32);
185     ge_tobytes(rcheck, &R);
186
187     /* comparison of R created to R in sig */
188     ret  |= ConstantCompare(rcheck, sig, 32);
189
190     *stat = (ret == 0)? 1: 0;
191
192     return ret;
193 }
194
195
196 /* initialize information and memory for key */
197 int wc_ed25519_init(ed25519_key* key)
198 {
199     if (key == NULL)
200         return BAD_FUNC_ARG;
201
202     XMEMSET(key, 0, sizeof(ed25519_key));
203
204     return 0;
205 }
206
207
208 /* clear memory of key */
209 void wc_ed25519_free(ed25519_key* key)
210 {
211     if (key == NULL)
212         return;
213
214     ForceZero(key, sizeof(ed25519_key));
215 }
216
217
218 /*
219     outLen should contain the size of out buffer when input. outLen is than set
220     to the final output length.
221     returns 0 on success
222  */
223 int wc_ed25519_export_public(ed25519_key* key, byte* out, word32* outLen)
224 {
225     word32 keySz;
226
227     /* sanity check on arguments */
228     if (key == NULL || out == NULL || outLen == NULL)
229         return BAD_FUNC_ARG;
230
231     keySz = wc_ed25519_size(key);
232     if (*outLen < keySz) {
233         *outLen = keySz;
234         return BUFFER_E;
235     }
236     *outLen = keySz;
237     XMEMCPY(out, key->p, keySz);
238
239     return 0;
240 }
241
242
243 /*
244     Imports a compressed/uncompressed public key.
245     in    the byte array containing the public key
246     inLen the length of the byte array being passed in
247     key   ed25519 key struct to put the public key in
248  */
249 int wc_ed25519_import_public(const byte* in, word32 inLen, ed25519_key* key)
250 {
251     word32 keySz;
252     int    ret;
253
254     /* sanity check on arguments */
255     if (in == NULL || key == NULL)
256         return BAD_FUNC_ARG;
257
258     keySz = wc_ed25519_size(key);
259
260     if (inLen < keySz)
261         return BAD_FUNC_ARG;
262
263     /* compressed prefix according to draft
264        http://www.ietf.org/id/draft-koch-eddsa-for-openpgp-02.txt */
265     if (in[0] == 0x40) {
266         /* key is stored in compressed format so just copy in */
267         XMEMCPY(key->p, (in + 1), keySz);
268         return 0;
269     }
270
271     /* importing uncompressed public key */
272     if (in[0] == 0x04) {
273         /* pass in (x,y) and store compressed key */
274         ret = ge_compress_key(key->p, (in+1), (in+1+keySz), keySz);
275         return ret;
276     }
277
278     /* if not specified compressed or uncompressed check key size
279        if key size is equal to compressed key size copy in key */
280     if (inLen == keySz) {
281         XMEMCPY(key->p, in, keySz);
282         return 0;
283     }
284
285     /* bad public key format */
286     return BAD_FUNC_ARG;
287 }
288
289
290 /*
291     For importing a private key and its associated public key.
292  */
293 int wc_ed25519_import_private_key(const byte* priv, word32 privSz,
294                                 const byte* pub, word32 pubSz, ed25519_key* key)
295 {
296     word32 keySz;
297     int    ret;
298
299     /* sanity check on arguments */
300     if (priv == NULL || pub == NULL || key == NULL)
301         return BAD_FUNC_ARG;
302
303     keySz = wc_ed25519_size(key);
304
305     /* key size check */
306     if (privSz < keySz || pubSz < keySz)
307         return BAD_FUNC_ARG;
308
309     XMEMCPY(key->k, priv, keySz);
310     ret = wc_ed25519_import_public(pub, pubSz, key);
311     XMEMCPY((key->k + keySz), key->p, keySz);
312
313     return ret;
314 }
315
316
317 /*
318     outLen should contain the size of out buffer when input. outLen is than set
319     to the final output length.
320     returns 0 on success
321  */
322 int wc_ed25519_export_private_only(ed25519_key* key, byte* out, word32* outLen)
323 {
324     word32 keySz;
325
326     /* sanity checks on arguments */
327     if (key == NULL || out == NULL || outLen == NULL)
328         return BAD_FUNC_ARG;
329
330     keySz = wc_ed25519_size(key);
331     if (*outLen < keySz) {
332         *outLen = keySz;
333         return BUFFER_E;
334     }
335     *outLen = keySz;
336     XMEMCPY(out, key->k, keySz);
337
338     return 0;
339 }
340
341
342 /* is the compressed key size in bytes */
343 int wc_ed25519_size(ed25519_key* key)
344 {
345     word32 keySz;
346
347     if (key == NULL)
348         return BAD_FUNC_ARG;
349
350     keySz = ED25519_KEY_SIZE;
351
352     return keySz;
353 }
354
355
356 /* returns the size of signature in bytes */
357 int wc_ed25519_sig_size(ed25519_key* key)
358 {
359     word32 sigSz;
360
361     if (key == NULL)
362         return BAD_FUNC_ARG;
363
364     sigSz = ED25519_SIG_SIZE;
365
366     return sigSz;
367 }
368
369 #endif /* HAVE_ED25519 */
370