comparison curve25519.c @ 1733:d529a52b2f7c coverity coverity

merge coverity from main
author Matt Johnston <matt@ucc.asn.au>
date Fri, 26 Jun 2020 21:07:34 +0800
parents 41a0ff8d5a89
children
comparison
equal deleted inserted replaced
1643:b59623a64678 1733:d529a52b2f7c
1 /*
2 * Dropbear - a SSH2 server
3 *
4 * Copyright (c) 2002,2003 Matt Johnston
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE. */
24
25 #include "includes.h"
26 #include "dbrandom.h"
27 #include "curve25519.h"
28
29 #if DROPBEAR_CURVE25519 || DROPBEAR_ED25519
30
31 /* Modified TweetNaCl version 20140427, a self-contained public-domain C library.
32 * https://tweetnacl.cr.yp.to/ */
33
34 #define FOR(i,n) for (i = 0;i < n;++i)
35 #define sv static void
36
37 typedef unsigned char u8;
38 typedef unsigned long u32;
39 typedef unsigned long long u64;
40 typedef long long i64;
41 typedef i64 gf[16];
42
43 #if DROPBEAR_CURVE25519
44 static const gf
45 _121665 = {0xDB41,1};
46 #endif /* DROPBEAR_CURVE25519 */
47 #if DROPBEAR_ED25519
48 static const gf
49 gf0,
50 gf1 = {1},
51 D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
52 X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
53 Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666};
54 #if DROPBEAR_SIGNKEY_VERIFY
55 static const gf
56 D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
57 I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
58 #endif /* DROPBEAR_SIGNKEY_VERIFY */
59 #endif /* DROPBEAR_ED25519 */
60
61 #if DROPBEAR_ED25519
62 #if DROPBEAR_SIGNKEY_VERIFY
63 static int vn(const u8 *x,const u8 *y,u32 n)
64 {
65 u32 i,d = 0;
66 FOR(i,n) d |= x[i]^y[i];
67 return (1 & ((d - 1) >> 8)) - 1;
68 }
69
70 static int crypto_verify_32(const u8 *x,const u8 *y)
71 {
72 return vn(x,y,32);
73 }
74 #endif /* DROPBEAR_SIGNKEY_VERIFY */
75
76 sv set25519(gf r, const gf a)
77 {
78 int i;
79 FOR(i,16) r[i]=a[i];
80 }
81 #endif /* DROPBEAR_ED25519 */
82
83 sv car25519(gf o)
84 {
85 int i;
86 i64 c;
87 FOR(i,16) {
88 o[i]+=(1LL<<16);
89 c=o[i]>>16;
90 o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
91 o[i]-=c<<16;
92 }
93 }
94
95 sv sel25519(gf p,gf q,int b)
96 {
97 i64 t,i,c=~(b-1);
98 FOR(i,16) {
99 t= c&(p[i]^q[i]);
100 p[i]^=t;
101 q[i]^=t;
102 }
103 }
104
105 sv pack25519(u8 *o,const gf n)
106 {
107 int i,j,b;
108 gf m,t;
109 FOR(i,16) t[i]=n[i];
110 car25519(t);
111 car25519(t);
112 car25519(t);
113 FOR(j,2) {
114 m[0]=t[0]-0xffed;
115 for(i=1;i<15;i++) {
116 m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
117 m[i-1]&=0xffff;
118 }
119 m[15]=t[15]-0x7fff-((m[14]>>16)&1);
120 b=(m[15]>>16)&1;
121 m[14]&=0xffff;
122 sel25519(t,m,1-b);
123 }
124 FOR(i,16) {
125 o[2*i]=t[i]&0xff;
126 o[2*i+1]=t[i]>>8;
127 }
128 }
129
130 #if DROPBEAR_ED25519
131 #if DROPBEAR_SIGNKEY_VERIFY
132 static int neq25519(const gf a, const gf b)
133 {
134 u8 c[32],d[32];
135 pack25519(c,a);
136 pack25519(d,b);
137 return crypto_verify_32(c,d);
138 }
139 #endif /* DROPBEAR_SIGNKEY_VERIFY */
140
141 static u8 par25519(const gf a)
142 {
143 u8 d[32];
144 pack25519(d,a);
145 return d[0]&1;
146 }
147 #endif /* DROPBEAR_ED25519 */
148
149 sv unpack25519(gf o, const u8 *n)
150 {
151 int i;
152 FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
153 o[15]&=0x7fff;
154 }
155
156 sv A(gf o,const gf a,const gf b)
157 {
158 int i;
159 FOR(i,16) o[i]=a[i]+b[i];
160 }
161
162 sv Z(gf o,const gf a,const gf b)
163 {
164 int i;
165 FOR(i,16) o[i]=a[i]-b[i];
166 }
167
168 sv M(gf o,const gf a,const gf b)
169 {
170 i64 i,j,t[31];
171 FOR(i,31) t[i]=0;
172 FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
173 FOR(i,15) t[i]+=38*t[i+16];
174 FOR(i,16) o[i]=t[i];
175 car25519(o);
176 car25519(o);
177 }
178
179 sv S(gf o,const gf a)
180 {
181 M(o,a,a);
182 }
183
184 sv inv25519(gf o,const gf i)
185 {
186 gf c;
187 int a;
188 FOR(a,16) c[a]=i[a];
189 for(a=253;a>=0;a--) {
190 S(c,c);
191 if(a!=2&&a!=4) M(c,c,i);
192 }
193 FOR(a,16) o[a]=c[a];
194 }
195
196 #if DROPBEAR_ED25519 && DROPBEAR_SIGNKEY_VERIFY
197 sv pow2523(gf o,const gf i)
198 {
199 gf c;
200 int a;
201 FOR(a,16) c[a]=i[a];
202 for(a=250;a>=0;a--) {
203 S(c,c);
204 if(a!=1) M(c,c,i);
205 }
206 FOR(a,16) o[a]=c[a];
207 }
208 #endif /* DROPBEAR_ED25519 && DROPBEAR_SIGNKEY_VERIFY */
209
210 #if DROPBEAR_CURVE25519
211 void dropbear_curve25519_scalarmult(u8 *q,const u8 *n,const u8 *p)
212 {
213 u8 z[32];
214 i64 x[80],r,i;
215 gf a,b,c,d,e,f;
216 FOR(i,31) z[i]=n[i];
217 z[31]=(n[31]&127)|64;
218 z[0]&=248;
219 unpack25519(x,p);
220 FOR(i,16) {
221 b[i]=x[i];
222 d[i]=a[i]=c[i]=0;
223 }
224 a[0]=d[0]=1;
225 for(i=254;i>=0;--i) {
226 r=(z[i>>3]>>(i&7))&1;
227 sel25519(a,b,r);
228 sel25519(c,d,r);
229 A(e,a,c);
230 Z(a,a,c);
231 A(c,b,d);
232 Z(b,b,d);
233 S(d,e);
234 S(f,a);
235 M(a,c,a);
236 M(c,b,e);
237 A(e,a,c);
238 Z(a,a,c);
239 S(b,a);
240 Z(c,d,f);
241 M(a,c,_121665);
242 A(a,a,d);
243 M(c,c,a);
244 M(a,d,f);
245 M(d,b,x);
246 S(b,e);
247 sel25519(a,b,r);
248 sel25519(c,d,r);
249 }
250 FOR(i,16) {
251 x[i+16]=a[i];
252 x[i+32]=c[i];
253 x[i+48]=b[i];
254 x[i+64]=d[i];
255 }
256 inv25519(x+32,x+32);
257 M(x+16,x+16,x+32);
258 pack25519(q,x+16);
259 }
260 #endif /* DROPBEAR_CURVE25519 */
261
262 #if DROPBEAR_ED25519
263 static int crypto_hash(u8 *out,const u8 *m,u64 n)
264 {
265 hash_state hs;
266
267 sha512_init(&hs);
268 sha512_process(&hs, m, n);
269 return sha512_done(&hs, out);
270 }
271
272 sv add(gf p[4],gf q[4])
273 {
274 gf a,b,c,d,t,e,f,g,h;
275
276 Z(a, p[1], p[0]);
277 Z(t, q[1], q[0]);
278 M(a, a, t);
279 A(b, p[0], p[1]);
280 A(t, q[0], q[1]);
281 M(b, b, t);
282 M(c, p[3], q[3]);
283 M(c, c, D2);
284 M(d, p[2], q[2]);
285 A(d, d, d);
286 Z(e, b, a);
287 Z(f, d, c);
288 A(g, d, c);
289 A(h, b, a);
290
291 M(p[0], e, f);
292 M(p[1], h, g);
293 M(p[2], g, f);
294 M(p[3], e, h);
295 }
296
297 sv cswap(gf p[4],gf q[4],u8 b)
298 {
299 int i;
300 FOR(i,4)
301 sel25519(p[i],q[i],b);
302 }
303
304 sv pack(u8 *r,gf p[4])
305 {
306 gf tx, ty, zi;
307 inv25519(zi, p[2]);
308 M(tx, p[0], zi);
309 M(ty, p[1], zi);
310 pack25519(r, ty);
311 r[31] ^= par25519(tx) << 7;
312 }
313
314 sv scalarmult(gf p[4],gf q[4],const u8 *s)
315 {
316 int i;
317 set25519(p[0],gf0);
318 set25519(p[1],gf1);
319 set25519(p[2],gf1);
320 set25519(p[3],gf0);
321 for (i = 255;i >= 0;--i) {
322 u8 b = (s[i/8]>>(i&7))&1;
323 cswap(p,q,b);
324 add(q,p);
325 add(p,p);
326 cswap(p,q,b);
327 }
328 }
329
330 sv scalarbase(gf p[4],const u8 *s)
331 {
332 gf q[4];
333 set25519(q[0],X);
334 set25519(q[1],Y);
335 set25519(q[2],gf1);
336 M(q[3],X,Y);
337 scalarmult(p,q,s);
338 }
339
340 void dropbear_ed25519_make_key(u8 *pk,u8 *sk)
341 {
342 u8 d[64];
343 gf p[4];
344
345 genrandom(sk, 32);
346
347 crypto_hash(d, sk, 32);
348 d[0] &= 248;
349 d[31] &= 127;
350 d[31] |= 64;
351
352 scalarbase(p,d);
353 pack(pk,p);
354 }
355
356 static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
357
358 sv modL(u8 *r,i64 x[64])
359 {
360 i64 carry,i,j;
361 for (i = 63;i >= 32;--i) {
362 carry = 0;
363 for (j = i - 32;j < i - 12;++j) {
364 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
365 carry = (x[j] + 128) >> 8;
366 x[j] -= carry << 8;
367 }
368 x[j] += carry;
369 x[i] = 0;
370 }
371 carry = 0;
372 FOR(j,32) {
373 x[j] += carry - (x[31] >> 4) * L[j];
374 carry = x[j] >> 8;
375 x[j] &= 255;
376 }
377 FOR(j,32) x[j] -= carry * L[j];
378 FOR(i,32) {
379 x[i+1] += x[i] >> 8;
380 r[i] = x[i] & 255;
381 }
382 }
383
384 sv reduce(u8 *r)
385 {
386 i64 x[64],i;
387 FOR(i,64) x[i] = (u64) r[i];
388 FOR(i,64) r[i] = 0;
389 modL(r,x);
390 }
391
392 void dropbear_ed25519_sign(const u8 *m,u32 mlen,u8 *s,u32 *slen,const u8 *sk, const u8 *pk)
393 {
394 hash_state hs;
395 u8 d[64],h[64],r[64];
396 i64 x[64];
397 gf p[4];
398 u32 i,j;
399
400 crypto_hash(d, sk, 32);
401 d[0] &= 248;
402 d[31] &= 127;
403 d[31] |= 64;
404
405 *slen = 64;
406
407 sha512_init(&hs);
408 sha512_process(&hs,d + 32,32);
409 sha512_process(&hs,m,mlen);
410 sha512_done(&hs,r);
411 reduce(r);
412 scalarbase(p,r);
413 pack(s,p);
414
415 sha512_init(&hs);
416 sha512_process(&hs,s,32);
417 sha512_process(&hs,pk,32);
418 sha512_process(&hs,m,mlen);
419 sha512_done(&hs,h);
420 reduce(h);
421
422 FOR(i,64) x[i] = 0;
423 FOR(i,32) x[i] = (u64) r[i];
424 FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
425 modL(s + 32,x);
426 }
427
428 #if DROPBEAR_SIGNKEY_VERIFY
429 static int unpackneg(gf r[4],const u8 p[32])
430 {
431 gf t, chk, num, den, den2, den4, den6;
432 set25519(r[2],gf1);
433 unpack25519(r[1],p);
434 S(num,r[1]);
435 M(den,num,D);
436 Z(num,num,r[2]);
437 A(den,r[2],den);
438
439 S(den2,den);
440 S(den4,den2);
441 M(den6,den4,den2);
442 M(t,den6,num);
443 M(t,t,den);
444
445 pow2523(t,t);
446 M(t,t,num);
447 M(t,t,den);
448 M(t,t,den);
449 M(r[0],t,den);
450
451 S(chk,r[0]);
452 M(chk,chk,den);
453 if (neq25519(chk, num)) M(r[0],r[0],I);
454
455 S(chk,r[0]);
456 M(chk,chk,den);
457 if (neq25519(chk, num)) return -1;
458
459 if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
460
461 M(r[3],r[0],r[1]);
462 return 0;
463 }
464
465 int dropbear_ed25519_verify(const u8 *m,u32 mlen,const u8 *s,u32 slen,const u8 *pk)
466 {
467 hash_state hs;
468 u8 t[32],h[64];
469 gf p[4],q[4];
470
471 if (slen < 64) return -1;
472
473 if (unpackneg(q,pk)) return -1;
474
475 sha512_init(&hs);
476 sha512_process(&hs,s,32);
477 sha512_process(&hs,pk,32);
478 sha512_process(&hs,m,mlen);
479 sha512_done(&hs,h);
480
481 reduce(h);
482 scalarmult(p,q,h);
483
484 scalarbase(q,s + 32);
485 add(p,q);
486 pack(t,p);
487
488 if (crypto_verify_32(s, t))
489 return -1;
490
491 return 0;
492 }
493 #endif /* DROPBEAR_SIGNKEY_VERIFY */
494
495 #endif /* DROPBEAR_ED25519 */
496
497 #endif /* DROPBEAR_CURVE25519 || DROPBEAR_ED25519 */