curve25519.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  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. #include "includes.h"
  25. #include "dbrandom.h"
  26. #include "curve25519.h"
  27. #if DROPBEAR_CURVE25519 || DROPBEAR_ED25519
  28. /* Modified TweetNaCl version 20140427, a self-contained public-domain C library.
  29. * https://tweetnacl.cr.yp.to/ */
  30. #define FOR(i,n) for (i = 0;i < n;++i)
  31. #define sv static void
  32. typedef unsigned char u8;
  33. typedef unsigned long u32;
  34. typedef unsigned long long u64;
  35. typedef long long i64;
  36. typedef i64 gf[16];
  37. #if DROPBEAR_CURVE25519
  38. static const gf
  39. _121665 = {0xDB41,1};
  40. #endif /* DROPBEAR_CURVE25519 */
  41. #if DROPBEAR_ED25519
  42. static const gf
  43. gf0,
  44. gf1 = {1},
  45. D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
  46. X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
  47. Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666};
  48. #if DROPBEAR_SIGNKEY_VERIFY
  49. static const gf
  50. D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
  51. I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
  52. #endif /* DROPBEAR_SIGNKEY_VERIFY */
  53. #endif /* DROPBEAR_ED25519 */
  54. #if DROPBEAR_ED25519
  55. #if DROPBEAR_SIGNKEY_VERIFY
  56. static int vn(const u8 *x,const u8 *y,u32 n)
  57. {
  58. u32 i,d = 0;
  59. FOR(i,n) d |= x[i]^y[i];
  60. return (1 & ((d - 1) >> 8)) - 1;
  61. }
  62. static int crypto_verify_32(const u8 *x,const u8 *y)
  63. {
  64. return vn(x,y,32);
  65. }
  66. #endif /* DROPBEAR_SIGNKEY_VERIFY */
  67. sv set25519(gf r, const gf a)
  68. {
  69. int i;
  70. FOR(i,16) r[i]=a[i];
  71. }
  72. #endif /* DROPBEAR_ED25519 */
  73. sv car25519(gf o)
  74. {
  75. int i;
  76. i64 c;
  77. FOR(i,16) {
  78. o[i]+=(1LL<<16);
  79. c=o[i]>>16;
  80. o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
  81. o[i]-=c<<16;
  82. }
  83. }
  84. sv sel25519(gf p,gf q,int b)
  85. {
  86. i64 t,i,c=~(b-1);
  87. FOR(i,16) {
  88. t= c&(p[i]^q[i]);
  89. p[i]^=t;
  90. q[i]^=t;
  91. }
  92. }
  93. sv pack25519(u8 *o,const gf n)
  94. {
  95. int i,j,b;
  96. gf m,t;
  97. FOR(i,16) t[i]=n[i];
  98. car25519(t);
  99. car25519(t);
  100. car25519(t);
  101. FOR(j,2) {
  102. m[0]=t[0]-0xffed;
  103. for(i=1;i<15;i++) {
  104. m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
  105. m[i-1]&=0xffff;
  106. }
  107. m[15]=t[15]-0x7fff-((m[14]>>16)&1);
  108. b=(m[15]>>16)&1;
  109. m[14]&=0xffff;
  110. sel25519(t,m,1-b);
  111. }
  112. FOR(i,16) {
  113. o[2*i]=t[i]&0xff;
  114. o[2*i+1]=t[i]>>8;
  115. }
  116. }
  117. #if DROPBEAR_ED25519
  118. #if DROPBEAR_SIGNKEY_VERIFY
  119. static int neq25519(const gf a, const gf b)
  120. {
  121. u8 c[32],d[32];
  122. pack25519(c,a);
  123. pack25519(d,b);
  124. return crypto_verify_32(c,d);
  125. }
  126. #endif /* DROPBEAR_SIGNKEY_VERIFY */
  127. static u8 par25519(const gf a)
  128. {
  129. u8 d[32];
  130. pack25519(d,a);
  131. return d[0]&1;
  132. }
  133. #endif /* DROPBEAR_ED25519 */
  134. sv unpack25519(gf o, const u8 *n)
  135. {
  136. int i;
  137. FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
  138. o[15]&=0x7fff;
  139. }
  140. sv A(gf o,const gf a,const gf b)
  141. {
  142. int i;
  143. FOR(i,16) o[i]=a[i]+b[i];
  144. }
  145. sv Z(gf o,const gf a,const gf b)
  146. {
  147. int i;
  148. FOR(i,16) o[i]=a[i]-b[i];
  149. }
  150. sv M(gf o,const gf a,const gf b)
  151. {
  152. i64 i,j,t[31];
  153. FOR(i,31) t[i]=0;
  154. FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
  155. FOR(i,15) t[i]+=38*t[i+16];
  156. FOR(i,16) o[i]=t[i];
  157. car25519(o);
  158. car25519(o);
  159. }
  160. sv S(gf o,const gf a)
  161. {
  162. M(o,a,a);
  163. }
  164. sv inv25519(gf o,const gf i)
  165. {
  166. gf c;
  167. int a;
  168. FOR(a,16) c[a]=i[a];
  169. for(a=253;a>=0;a--) {
  170. S(c,c);
  171. if(a!=2&&a!=4) M(c,c,i);
  172. }
  173. FOR(a,16) o[a]=c[a];
  174. }
  175. #if DROPBEAR_ED25519 && DROPBEAR_SIGNKEY_VERIFY
  176. sv pow2523(gf o,const gf i)
  177. {
  178. gf c;
  179. int a;
  180. FOR(a,16) c[a]=i[a];
  181. for(a=250;a>=0;a--) {
  182. S(c,c);
  183. if(a!=1) M(c,c,i);
  184. }
  185. FOR(a,16) o[a]=c[a];
  186. }
  187. #endif /* DROPBEAR_ED25519 && DROPBEAR_SIGNKEY_VERIFY */
  188. #if DROPBEAR_CURVE25519
  189. void dropbear_curve25519_scalarmult(u8 *q,const u8 *n,const u8 *p)
  190. {
  191. u8 z[32];
  192. i64 x[80],r,i;
  193. gf a,b,c,d,e,f;
  194. FOR(i,31) z[i]=n[i];
  195. z[31]=(n[31]&127)|64;
  196. z[0]&=248;
  197. unpack25519(x,p);
  198. FOR(i,16) {
  199. b[i]=x[i];
  200. d[i]=a[i]=c[i]=0;
  201. }
  202. a[0]=d[0]=1;
  203. for(i=254;i>=0;--i) {
  204. r=(z[i>>3]>>(i&7))&1;
  205. sel25519(a,b,r);
  206. sel25519(c,d,r);
  207. A(e,a,c);
  208. Z(a,a,c);
  209. A(c,b,d);
  210. Z(b,b,d);
  211. S(d,e);
  212. S(f,a);
  213. M(a,c,a);
  214. M(c,b,e);
  215. A(e,a,c);
  216. Z(a,a,c);
  217. S(b,a);
  218. Z(c,d,f);
  219. M(a,c,_121665);
  220. A(a,a,d);
  221. M(c,c,a);
  222. M(a,d,f);
  223. M(d,b,x);
  224. S(b,e);
  225. sel25519(a,b,r);
  226. sel25519(c,d,r);
  227. }
  228. FOR(i,16) {
  229. x[i+16]=a[i];
  230. x[i+32]=c[i];
  231. x[i+48]=b[i];
  232. x[i+64]=d[i];
  233. }
  234. inv25519(x+32,x+32);
  235. M(x+16,x+16,x+32);
  236. pack25519(q,x+16);
  237. }
  238. #endif /* DROPBEAR_CURVE25519 */
  239. #if DROPBEAR_ED25519
  240. static int crypto_hash(u8 *out,const u8 *m,u64 n)
  241. {
  242. hash_state hs;
  243. sha512_init(&hs);
  244. sha512_process(&hs, m, n);
  245. return sha512_done(&hs, out);
  246. }
  247. sv add(gf p[4],gf q[4])
  248. {
  249. gf a,b,c,d,t,e,f,g,h;
  250. Z(a, p[1], p[0]);
  251. Z(t, q[1], q[0]);
  252. M(a, a, t);
  253. A(b, p[0], p[1]);
  254. A(t, q[0], q[1]);
  255. M(b, b, t);
  256. M(c, p[3], q[3]);
  257. M(c, c, D2);
  258. M(d, p[2], q[2]);
  259. A(d, d, d);
  260. Z(e, b, a);
  261. Z(f, d, c);
  262. A(g, d, c);
  263. A(h, b, a);
  264. M(p[0], e, f);
  265. M(p[1], h, g);
  266. M(p[2], g, f);
  267. M(p[3], e, h);
  268. }
  269. sv cswap(gf p[4],gf q[4],u8 b)
  270. {
  271. int i;
  272. FOR(i,4)
  273. sel25519(p[i],q[i],b);
  274. }
  275. sv pack(u8 *r,gf p[4])
  276. {
  277. gf tx, ty, zi;
  278. inv25519(zi, p[2]);
  279. M(tx, p[0], zi);
  280. M(ty, p[1], zi);
  281. pack25519(r, ty);
  282. r[31] ^= par25519(tx) << 7;
  283. }
  284. sv scalarmult(gf p[4],gf q[4],const u8 *s)
  285. {
  286. int i;
  287. set25519(p[0],gf0);
  288. set25519(p[1],gf1);
  289. set25519(p[2],gf1);
  290. set25519(p[3],gf0);
  291. for (i = 255;i >= 0;--i) {
  292. u8 b = (s[i/8]>>(i&7))&1;
  293. cswap(p,q,b);
  294. add(q,p);
  295. add(p,p);
  296. cswap(p,q,b);
  297. }
  298. }
  299. sv scalarbase(gf p[4],const u8 *s)
  300. {
  301. gf q[4];
  302. set25519(q[0],X);
  303. set25519(q[1],Y);
  304. set25519(q[2],gf1);
  305. M(q[3],X,Y);
  306. scalarmult(p,q,s);
  307. }
  308. void dropbear_ed25519_make_key(u8 *pk,u8 *sk)
  309. {
  310. u8 d[64];
  311. gf p[4];
  312. genrandom(sk, 32);
  313. crypto_hash(d, sk, 32);
  314. d[0] &= 248;
  315. d[31] &= 127;
  316. d[31] |= 64;
  317. scalarbase(p,d);
  318. pack(pk,p);
  319. }
  320. 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};
  321. sv modL(u8 *r,i64 x[64])
  322. {
  323. i64 carry,i,j;
  324. for (i = 63;i >= 32;--i) {
  325. carry = 0;
  326. for (j = i - 32;j < i - 12;++j) {
  327. x[j] += carry - 16 * x[i] * L[j - (i - 32)];
  328. carry = (x[j] + 128) >> 8;
  329. x[j] -= carry << 8;
  330. }
  331. x[j] += carry;
  332. x[i] = 0;
  333. }
  334. carry = 0;
  335. FOR(j,32) {
  336. x[j] += carry - (x[31] >> 4) * L[j];
  337. carry = x[j] >> 8;
  338. x[j] &= 255;
  339. }
  340. FOR(j,32) x[j] -= carry * L[j];
  341. FOR(i,32) {
  342. x[i+1] += x[i] >> 8;
  343. r[i] = x[i] & 255;
  344. }
  345. }
  346. sv reduce(u8 *r)
  347. {
  348. i64 x[64],i;
  349. FOR(i,64) x[i] = (u64) r[i];
  350. FOR(i,64) r[i] = 0;
  351. modL(r,x);
  352. }
  353. void dropbear_ed25519_sign(const u8 *m,u32 mlen,u8 *s,u32 *slen,const u8 *sk, const u8 *pk)
  354. {
  355. hash_state hs;
  356. u8 d[64],h[64],r[64];
  357. i64 x[64];
  358. gf p[4];
  359. u32 i,j;
  360. crypto_hash(d, sk, 32);
  361. d[0] &= 248;
  362. d[31] &= 127;
  363. d[31] |= 64;
  364. *slen = 64;
  365. sha512_init(&hs);
  366. sha512_process(&hs,d + 32,32);
  367. sha512_process(&hs,m,mlen);
  368. sha512_done(&hs,r);
  369. reduce(r);
  370. scalarbase(p,r);
  371. pack(s,p);
  372. sha512_init(&hs);
  373. sha512_process(&hs,s,32);
  374. sha512_process(&hs,pk,32);
  375. sha512_process(&hs,m,mlen);
  376. sha512_done(&hs,h);
  377. reduce(h);
  378. FOR(i,64) x[i] = 0;
  379. FOR(i,32) x[i] = (u64) r[i];
  380. FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
  381. modL(s + 32,x);
  382. }
  383. #if DROPBEAR_SIGNKEY_VERIFY
  384. static int unpackneg(gf r[4],const u8 p[32])
  385. {
  386. gf t, chk, num, den, den2, den4, den6;
  387. set25519(r[2],gf1);
  388. unpack25519(r[1],p);
  389. S(num,r[1]);
  390. M(den,num,D);
  391. Z(num,num,r[2]);
  392. A(den,r[2],den);
  393. S(den2,den);
  394. S(den4,den2);
  395. M(den6,den4,den2);
  396. M(t,den6,num);
  397. M(t,t,den);
  398. pow2523(t,t);
  399. M(t,t,num);
  400. M(t,t,den);
  401. M(t,t,den);
  402. M(r[0],t,den);
  403. S(chk,r[0]);
  404. M(chk,chk,den);
  405. if (neq25519(chk, num)) M(r[0],r[0],I);
  406. S(chk,r[0]);
  407. M(chk,chk,den);
  408. if (neq25519(chk, num)) return -1;
  409. if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
  410. M(r[3],r[0],r[1]);
  411. return 0;
  412. }
  413. int dropbear_ed25519_verify(const u8 *m,u32 mlen,const u8 *s,u32 slen,const u8 *pk)
  414. {
  415. hash_state hs;
  416. u8 t[32],h[64];
  417. gf p[4],q[4];
  418. if (slen < 64) return -1;
  419. if (unpackneg(q,pk)) return -1;
  420. sha512_init(&hs);
  421. sha512_process(&hs,s,32);
  422. sha512_process(&hs,pk,32);
  423. sha512_process(&hs,m,mlen);
  424. sha512_done(&hs,h);
  425. reduce(h);
  426. scalarmult(p,q,h);
  427. scalarbase(q,s + 32);
  428. add(p,q);
  429. pack(t,p);
  430. if (crypto_verify_32(s, t))
  431. return -1;
  432. return 0;
  433. }
  434. #endif /* DROPBEAR_SIGNKEY_VERIFY */
  435. #endif /* DROPBEAR_ED25519 */
  436. #endif /* DROPBEAR_CURVE25519 || DROPBEAR_ED25519 */