xref: /aosp_15_r20/external/libwebsockets/plugins/ssh-base/crypto/ed25519.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /* $OpenBSD: ed25519.c,v 1.3 2013/12/09 11:03:45 markus Exp $ */
2*1c60b9acSAndroid Build Coastguard Worker 
3*1c60b9acSAndroid Build Coastguard Worker /*
4*1c60b9acSAndroid Build Coastguard Worker  * Public Domain, Authors: Daniel J. Bernstein, Niels Duif, Tanja Lange,
5*1c60b9acSAndroid Build Coastguard Worker  * Peter Schwabe, Bo-Yin Yang.
6*1c60b9acSAndroid Build Coastguard Worker  * Copied from supercop-20130419/crypto_sign/ed25519/ref/ed25519.c
7*1c60b9acSAndroid Build Coastguard Worker  *
8*1c60b9acSAndroid Build Coastguard Worker  * Modified to use lws genhash by Andy Green <[email protected]>
9*1c60b9acSAndroid Build Coastguard Worker  */
10*1c60b9acSAndroid Build Coastguard Worker 
11*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
12*1c60b9acSAndroid Build Coastguard Worker #include <lws-ssh.h>
13*1c60b9acSAndroid Build Coastguard Worker #include "ge25519.h"
14*1c60b9acSAndroid Build Coastguard Worker 
15*1c60b9acSAndroid Build Coastguard Worker int
crypto_hash_sha512(uint8_t * hash64,const uint8_t * data,size_t len)16*1c60b9acSAndroid Build Coastguard Worker crypto_hash_sha512(uint8_t *hash64, const uint8_t *data, size_t len)
17*1c60b9acSAndroid Build Coastguard Worker {
18*1c60b9acSAndroid Build Coastguard Worker 	struct lws_genhash_ctx ctx;
19*1c60b9acSAndroid Build Coastguard Worker 	int ret;
20*1c60b9acSAndroid Build Coastguard Worker 
21*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA512)) {
22*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("Failed to init SHA512\n");
23*1c60b9acSAndroid Build Coastguard Worker 		return 0;
24*1c60b9acSAndroid Build Coastguard Worker 	}
25*1c60b9acSAndroid Build Coastguard Worker 
26*1c60b9acSAndroid Build Coastguard Worker 	ret = lws_genhash_update(&ctx, data, len);
27*1c60b9acSAndroid Build Coastguard Worker 
28*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_destroy(&ctx, hash64))
29*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("genhash destroy failed\n");
30*1c60b9acSAndroid Build Coastguard Worker 
31*1c60b9acSAndroid Build Coastguard Worker 	return ret ? 0 : 64;
32*1c60b9acSAndroid Build Coastguard Worker }
33*1c60b9acSAndroid Build Coastguard Worker 
34*1c60b9acSAndroid Build Coastguard Worker 
35*1c60b9acSAndroid Build Coastguard Worker static void
get_hram(unsigned char * hram,const unsigned char * sm,const unsigned char * pk,unsigned char * playground,size_t smlen)36*1c60b9acSAndroid Build Coastguard Worker get_hram(unsigned char *hram, const unsigned char *sm,
37*1c60b9acSAndroid Build Coastguard Worker 	 const unsigned char *pk, unsigned char *playground,
38*1c60b9acSAndroid Build Coastguard Worker 	 size_t smlen)
39*1c60b9acSAndroid Build Coastguard Worker {
40*1c60b9acSAndroid Build Coastguard Worker 	unsigned long long i;
41*1c60b9acSAndroid Build Coastguard Worker 
42*1c60b9acSAndroid Build Coastguard Worker 	for (i =  0; i < 32; ++i)
43*1c60b9acSAndroid Build Coastguard Worker 		playground[i] = sm[i];
44*1c60b9acSAndroid Build Coastguard Worker 	for (i = 32; i < 64; ++i)
45*1c60b9acSAndroid Build Coastguard Worker 		playground[i] = pk[i-32];
46*1c60b9acSAndroid Build Coastguard Worker 	for (i = 64; i < smlen; ++i)
47*1c60b9acSAndroid Build Coastguard Worker 		playground[i] = sm[i];
48*1c60b9acSAndroid Build Coastguard Worker 
49*1c60b9acSAndroid Build Coastguard Worker 	crypto_hash_sha512(hram, playground, smlen);
50*1c60b9acSAndroid Build Coastguard Worker }
51*1c60b9acSAndroid Build Coastguard Worker 
52*1c60b9acSAndroid Build Coastguard Worker 
crypto_sign_ed25519_keypair(struct lws_context * context,unsigned char * pk,unsigned char * sk)53*1c60b9acSAndroid Build Coastguard Worker int crypto_sign_ed25519_keypair(
54*1c60b9acSAndroid Build Coastguard Worker     struct lws_context *context,
55*1c60b9acSAndroid Build Coastguard Worker     unsigned char *pk,
56*1c60b9acSAndroid Build Coastguard Worker     unsigned char *sk
57*1c60b9acSAndroid Build Coastguard Worker     )
58*1c60b9acSAndroid Build Coastguard Worker {
59*1c60b9acSAndroid Build Coastguard Worker   sc25519 scsk;
60*1c60b9acSAndroid Build Coastguard Worker   ge25519 gepk;
61*1c60b9acSAndroid Build Coastguard Worker   unsigned char extsk[64];
62*1c60b9acSAndroid Build Coastguard Worker   int i;
63*1c60b9acSAndroid Build Coastguard Worker 
64*1c60b9acSAndroid Build Coastguard Worker   lws_get_random(context, sk, 32);
65*1c60b9acSAndroid Build Coastguard Worker   crypto_hash_sha512(extsk, sk, 32);
66*1c60b9acSAndroid Build Coastguard Worker   extsk[0] &= 248;
67*1c60b9acSAndroid Build Coastguard Worker   extsk[31] &= 127;
68*1c60b9acSAndroid Build Coastguard Worker   extsk[31] |= 64;
69*1c60b9acSAndroid Build Coastguard Worker 
70*1c60b9acSAndroid Build Coastguard Worker   sc25519_from32bytes(&scsk,extsk);
71*1c60b9acSAndroid Build Coastguard Worker 
72*1c60b9acSAndroid Build Coastguard Worker   ge25519_scalarmult_base(&gepk, &scsk);
73*1c60b9acSAndroid Build Coastguard Worker   ge25519_pack(pk, &gepk);
74*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
75*1c60b9acSAndroid Build Coastguard Worker     sk[32 + i] = pk[i];
76*1c60b9acSAndroid Build Coastguard Worker   return 0;
77*1c60b9acSAndroid Build Coastguard Worker }
78*1c60b9acSAndroid Build Coastguard Worker 
crypto_sign_ed25519(unsigned char * sm,unsigned long long * smlen,const unsigned char * m,size_t mlen,const unsigned char * sk)79*1c60b9acSAndroid Build Coastguard Worker int crypto_sign_ed25519(
80*1c60b9acSAndroid Build Coastguard Worker     unsigned char *sm,
81*1c60b9acSAndroid Build Coastguard Worker     unsigned long long *smlen,
82*1c60b9acSAndroid Build Coastguard Worker     const unsigned char *m, size_t mlen,
83*1c60b9acSAndroid Build Coastguard Worker     const unsigned char *sk
84*1c60b9acSAndroid Build Coastguard Worker     )
85*1c60b9acSAndroid Build Coastguard Worker {
86*1c60b9acSAndroid Build Coastguard Worker   sc25519 sck, scs, scsk;
87*1c60b9acSAndroid Build Coastguard Worker   ge25519 ger;
88*1c60b9acSAndroid Build Coastguard Worker   unsigned char r[32];
89*1c60b9acSAndroid Build Coastguard Worker   unsigned char s[32];
90*1c60b9acSAndroid Build Coastguard Worker   unsigned char extsk[64];
91*1c60b9acSAndroid Build Coastguard Worker   unsigned long long i;
92*1c60b9acSAndroid Build Coastguard Worker   unsigned char hmg[crypto_hash_sha512_BYTES];
93*1c60b9acSAndroid Build Coastguard Worker   unsigned char hram[crypto_hash_sha512_BYTES];
94*1c60b9acSAndroid Build Coastguard Worker 
95*1c60b9acSAndroid Build Coastguard Worker   crypto_hash_sha512(extsk, sk, 32);
96*1c60b9acSAndroid Build Coastguard Worker   extsk[0] &= 248;
97*1c60b9acSAndroid Build Coastguard Worker   extsk[31] &= 127;
98*1c60b9acSAndroid Build Coastguard Worker   extsk[31] |= 64;
99*1c60b9acSAndroid Build Coastguard Worker 
100*1c60b9acSAndroid Build Coastguard Worker   *smlen = mlen+64;
101*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<mlen;i++)
102*1c60b9acSAndroid Build Coastguard Worker     sm[64 + i] = m[i];
103*1c60b9acSAndroid Build Coastguard Worker   for(i=0;i<32;i++)
104*1c60b9acSAndroid Build Coastguard Worker     sm[32 + i] = extsk[32+i];
105*1c60b9acSAndroid Build Coastguard Worker 
106*1c60b9acSAndroid Build Coastguard Worker   crypto_hash_sha512(hmg, sm+32, mlen+32);
107*1c60b9acSAndroid Build Coastguard Worker   /* Generate k as h(extsk[32],...,extsk[63],m) */
108*1c60b9acSAndroid Build Coastguard Worker 
109*1c60b9acSAndroid Build Coastguard Worker   /* Computation of R */
110*1c60b9acSAndroid Build Coastguard Worker   sc25519_from64bytes(&sck, hmg);
111*1c60b9acSAndroid Build Coastguard Worker   ge25519_scalarmult_base(&ger, &sck);
112*1c60b9acSAndroid Build Coastguard Worker   ge25519_pack(r, &ger);
113*1c60b9acSAndroid Build Coastguard Worker 
114*1c60b9acSAndroid Build Coastguard Worker   /* Computation of s */
115*1c60b9acSAndroid Build Coastguard Worker   for (i = 0; i < 32; i++)
116*1c60b9acSAndroid Build Coastguard Worker     sm[i] = r[i];
117*1c60b9acSAndroid Build Coastguard Worker 
118*1c60b9acSAndroid Build Coastguard Worker   get_hram(hram, sm, sk + 32, sm, (size_t)mlen + 64);
119*1c60b9acSAndroid Build Coastguard Worker 
120*1c60b9acSAndroid Build Coastguard Worker   sc25519_from64bytes(&scs, hram);
121*1c60b9acSAndroid Build Coastguard Worker   sc25519_from32bytes(&scsk, extsk);
122*1c60b9acSAndroid Build Coastguard Worker   sc25519_mul(&scs, &scs, &scsk);
123*1c60b9acSAndroid Build Coastguard Worker 
124*1c60b9acSAndroid Build Coastguard Worker   sc25519_add(&scs, &scs, &sck);
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker   sc25519_to32bytes(s,&scs); /* cat s */
127*1c60b9acSAndroid Build Coastguard Worker   for (i = 0; i < 32; i++)
128*1c60b9acSAndroid Build Coastguard Worker     sm[32 + i] = s[i];
129*1c60b9acSAndroid Build Coastguard Worker 
130*1c60b9acSAndroid Build Coastguard Worker   return 0;
131*1c60b9acSAndroid Build Coastguard Worker }
132*1c60b9acSAndroid Build Coastguard Worker 
crypto_verify_32(const unsigned char * x,const unsigned char * y)133*1c60b9acSAndroid Build Coastguard Worker int crypto_verify_32(const unsigned char *x,const unsigned char *y)
134*1c60b9acSAndroid Build Coastguard Worker {
135*1c60b9acSAndroid Build Coastguard Worker   unsigned int differentbits = 0;
136*1c60b9acSAndroid Build Coastguard Worker #define F(i) differentbits |= x[i] ^ y[i];
137*1c60b9acSAndroid Build Coastguard Worker   F(0)
138*1c60b9acSAndroid Build Coastguard Worker   F(1)
139*1c60b9acSAndroid Build Coastguard Worker   F(2)
140*1c60b9acSAndroid Build Coastguard Worker   F(3)
141*1c60b9acSAndroid Build Coastguard Worker   F(4)
142*1c60b9acSAndroid Build Coastguard Worker   F(5)
143*1c60b9acSAndroid Build Coastguard Worker   F(6)
144*1c60b9acSAndroid Build Coastguard Worker   F(7)
145*1c60b9acSAndroid Build Coastguard Worker   F(8)
146*1c60b9acSAndroid Build Coastguard Worker   F(9)
147*1c60b9acSAndroid Build Coastguard Worker   F(10)
148*1c60b9acSAndroid Build Coastguard Worker   F(11)
149*1c60b9acSAndroid Build Coastguard Worker   F(12)
150*1c60b9acSAndroid Build Coastguard Worker   F(13)
151*1c60b9acSAndroid Build Coastguard Worker   F(14)
152*1c60b9acSAndroid Build Coastguard Worker   F(15)
153*1c60b9acSAndroid Build Coastguard Worker   F(16)
154*1c60b9acSAndroid Build Coastguard Worker   F(17)
155*1c60b9acSAndroid Build Coastguard Worker   F(18)
156*1c60b9acSAndroid Build Coastguard Worker   F(19)
157*1c60b9acSAndroid Build Coastguard Worker   F(20)
158*1c60b9acSAndroid Build Coastguard Worker   F(21)
159*1c60b9acSAndroid Build Coastguard Worker   F(22)
160*1c60b9acSAndroid Build Coastguard Worker   F(23)
161*1c60b9acSAndroid Build Coastguard Worker   F(24)
162*1c60b9acSAndroid Build Coastguard Worker   F(25)
163*1c60b9acSAndroid Build Coastguard Worker   F(26)
164*1c60b9acSAndroid Build Coastguard Worker   F(27)
165*1c60b9acSAndroid Build Coastguard Worker   F(28)
166*1c60b9acSAndroid Build Coastguard Worker   F(29)
167*1c60b9acSAndroid Build Coastguard Worker   F(30)
168*1c60b9acSAndroid Build Coastguard Worker   F(31)
169*1c60b9acSAndroid Build Coastguard Worker   return (int)((1 & ((differentbits - 1) >> 8)) - 1);
170*1c60b9acSAndroid Build Coastguard Worker }
171*1c60b9acSAndroid Build Coastguard Worker 
crypto_sign_ed25519_open(unsigned char * m,unsigned long long * mlen,const unsigned char * sm,unsigned long long smlen,const unsigned char * pk)172*1c60b9acSAndroid Build Coastguard Worker int crypto_sign_ed25519_open(
173*1c60b9acSAndroid Build Coastguard Worker     unsigned char *m,unsigned long long *mlen,
174*1c60b9acSAndroid Build Coastguard Worker     const unsigned char *sm,unsigned long long smlen,
175*1c60b9acSAndroid Build Coastguard Worker     const unsigned char *pk
176*1c60b9acSAndroid Build Coastguard Worker     )
177*1c60b9acSAndroid Build Coastguard Worker {
178*1c60b9acSAndroid Build Coastguard Worker   unsigned int i;
179*1c60b9acSAndroid Build Coastguard Worker   int ret;
180*1c60b9acSAndroid Build Coastguard Worker   unsigned char t2[32];
181*1c60b9acSAndroid Build Coastguard Worker   ge25519 get1, get2;
182*1c60b9acSAndroid Build Coastguard Worker   sc25519 schram, scs;
183*1c60b9acSAndroid Build Coastguard Worker   unsigned char hram[crypto_hash_sha512_BYTES];
184*1c60b9acSAndroid Build Coastguard Worker 
185*1c60b9acSAndroid Build Coastguard Worker   *mlen = (unsigned long long) -1;
186*1c60b9acSAndroid Build Coastguard Worker   if (smlen < 64) {
187*1c60b9acSAndroid Build Coastguard Worker 	  lwsl_notice("a\n");
188*1c60b9acSAndroid Build Coastguard Worker 
189*1c60b9acSAndroid Build Coastguard Worker 	  return -1;
190*1c60b9acSAndroid Build Coastguard Worker   }
191*1c60b9acSAndroid Build Coastguard Worker 
192*1c60b9acSAndroid Build Coastguard Worker   if (ge25519_unpackneg_vartime(&get1, pk)) {
193*1c60b9acSAndroid Build Coastguard Worker 	  lwsl_notice("b\n");
194*1c60b9acSAndroid Build Coastguard Worker 	  return -1;
195*1c60b9acSAndroid Build Coastguard Worker   }
196*1c60b9acSAndroid Build Coastguard Worker 
197*1c60b9acSAndroid Build Coastguard Worker   get_hram(hram,sm,pk,m, (size_t)smlen);
198*1c60b9acSAndroid Build Coastguard Worker 
199*1c60b9acSAndroid Build Coastguard Worker   sc25519_from64bytes(&schram, hram);
200*1c60b9acSAndroid Build Coastguard Worker 
201*1c60b9acSAndroid Build Coastguard Worker   sc25519_from32bytes(&scs, sm+32);
202*1c60b9acSAndroid Build Coastguard Worker 
203*1c60b9acSAndroid Build Coastguard Worker   ge25519_double_scalarmult_vartime(&get2, &get1, &schram, &ge25519_base, &scs);
204*1c60b9acSAndroid Build Coastguard Worker   ge25519_pack(t2, &get2);
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker   ret = crypto_verify_32(sm, t2);
207*1c60b9acSAndroid Build Coastguard Worker   lwsl_notice("vf says %d\n", ret);
208*1c60b9acSAndroid Build Coastguard Worker 
209*1c60b9acSAndroid Build Coastguard Worker   if (!ret)
210*1c60b9acSAndroid Build Coastguard Worker   {
211*1c60b9acSAndroid Build Coastguard Worker     for(i=0;i<smlen-64;i++)
212*1c60b9acSAndroid Build Coastguard Worker       m[i] = sm[i + 64];
213*1c60b9acSAndroid Build Coastguard Worker     *mlen = smlen-64;
214*1c60b9acSAndroid Build Coastguard Worker   }
215*1c60b9acSAndroid Build Coastguard Worker   else
216*1c60b9acSAndroid Build Coastguard Worker   {
217*1c60b9acSAndroid Build Coastguard Worker     for(i=0;i<smlen-64;i++)
218*1c60b9acSAndroid Build Coastguard Worker       m[i] = 0;
219*1c60b9acSAndroid Build Coastguard Worker   }
220*1c60b9acSAndroid Build Coastguard Worker   return ret;
221*1c60b9acSAndroid Build Coastguard Worker }
222