xref: /aosp_15_r20/external/libwebsockets/plugins/ssh-base/kex-25519.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2019 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  */
24*1c60b9acSAndroid Build Coastguard Worker 
25*1c60b9acSAndroid Build Coastguard Worker #include "libwebsockets.h"
26*1c60b9acSAndroid Build Coastguard Worker #include "lws-ssh.h"
27*1c60b9acSAndroid Build Coastguard Worker 
28*1c60b9acSAndroid Build Coastguard Worker #include <string.h>
29*1c60b9acSAndroid Build Coastguard Worker 
30*1c60b9acSAndroid Build Coastguard Worker /*
31*1c60b9acSAndroid Build Coastguard Worker  * ssh-keygen -t ed25519
32*1c60b9acSAndroid Build Coastguard Worker  * head -n-1 srv-key-25519 | tail -n +2 | base64 -d | hexdump -C
33*1c60b9acSAndroid Build Coastguard Worker  */
34*1c60b9acSAndroid Build Coastguard Worker 
35*1c60b9acSAndroid Build Coastguard Worker static void
lws_sized_blob(uint8_t ** p,void * blob,uint32_t len)36*1c60b9acSAndroid Build Coastguard Worker lws_sized_blob(uint8_t **p, void *blob, uint32_t len)
37*1c60b9acSAndroid Build Coastguard Worker {
38*1c60b9acSAndroid Build Coastguard Worker 	lws_p32((*p), len);
39*1c60b9acSAndroid Build Coastguard Worker 	*p += 4;
40*1c60b9acSAndroid Build Coastguard Worker 	memcpy(*p, blob, len);
41*1c60b9acSAndroid Build Coastguard Worker 	*p += len;
42*1c60b9acSAndroid Build Coastguard Worker }
43*1c60b9acSAndroid Build Coastguard Worker 
44*1c60b9acSAndroid Build Coastguard Worker static const char key_leadin[] = "openssh-key-v1\x00\x00\x00\x00\x04none"
45*1c60b9acSAndroid Build Coastguard Worker 				 "\x00\x00\x00\x04none\x00"
46*1c60b9acSAndroid Build Coastguard Worker 				 "\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x33"
47*1c60b9acSAndroid Build Coastguard Worker 				 "\x00\x00\x00\x0bssh-ed25519\x00\x00\x00\x20",
48*1c60b9acSAndroid Build Coastguard Worker 		  key_sep[] = 	 "\x00\x00\x00\x90\xb1\x4f\xa7\x28"
49*1c60b9acSAndroid Build Coastguard Worker 				 "\xb1\x4f\xa7\x28\x00\x00\x00\x0bssh-ed25519"
50*1c60b9acSAndroid Build Coastguard Worker 				 "\x00\x00\x00\x20",
51*1c60b9acSAndroid Build Coastguard Worker 		  key_privl[] =	 "\x00\x00\x00\x40",
52*1c60b9acSAndroid Build Coastguard Worker 		  key_trail[] =  "\x00\x00\x00\x0cself-gen@cbl\x01";
53*1c60b9acSAndroid Build Coastguard Worker 
54*1c60b9acSAndroid Build Coastguard Worker static size_t
lws_gen_server_key_ed25519(struct lws_context * context,uint8_t * buf256,size_t max_len)55*1c60b9acSAndroid Build Coastguard Worker lws_gen_server_key_ed25519(struct lws_context *context, uint8_t *buf256,
56*1c60b9acSAndroid Build Coastguard Worker 			   size_t max_len)
57*1c60b9acSAndroid Build Coastguard Worker {
58*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *p = buf256 + sizeof(key_leadin) - 1;
59*1c60b9acSAndroid Build Coastguard Worker 
60*1c60b9acSAndroid Build Coastguard Worker 	if (max_len < sizeof(key_leadin) - 1 + 32 + sizeof(key_sep) - 1 + 32 +
61*1c60b9acSAndroid Build Coastguard Worker 		      sizeof(key_privl) - 1 + 64 + sizeof(key_trail) - 1)
62*1c60b9acSAndroid Build Coastguard Worker 		return 0;
63*1c60b9acSAndroid Build Coastguard Worker 
64*1c60b9acSAndroid Build Coastguard Worker 	memcpy(buf256, key_leadin, sizeof(key_leadin) - 1);
65*1c60b9acSAndroid Build Coastguard Worker 	crypto_sign_ed25519_keypair(context, p, p + 32 + sizeof(key_sep) - 1 +
66*1c60b9acSAndroid Build Coastguard Worker 				    32 + sizeof(key_privl) - 1);
67*1c60b9acSAndroid Build Coastguard Worker 	memcpy(p + 32 + sizeof(key_sep) - 1, p, 32);
68*1c60b9acSAndroid Build Coastguard Worker 	p += 32;
69*1c60b9acSAndroid Build Coastguard Worker 	memcpy(p, key_sep, sizeof(key_sep) - 1);
70*1c60b9acSAndroid Build Coastguard Worker 	p += sizeof(key_sep) - 1 + 32;
71*1c60b9acSAndroid Build Coastguard Worker 	memcpy(p, key_privl, sizeof(key_privl) - 1);
72*1c60b9acSAndroid Build Coastguard Worker 	p += sizeof(key_privl) - 1 + 64;
73*1c60b9acSAndroid Build Coastguard Worker 	memcpy(p, key_trail, sizeof(key_trail) - 1);
74*1c60b9acSAndroid Build Coastguard Worker 	p += sizeof(key_trail) - 1;
75*1c60b9acSAndroid Build Coastguard Worker 
76*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("%s: Generated key len %ld\n", __func__, (long)(p - buf256));
77*1c60b9acSAndroid Build Coastguard Worker 
78*1c60b9acSAndroid Build Coastguard Worker 	return (size_t)(p - buf256);
79*1c60b9acSAndroid Build Coastguard Worker }
80*1c60b9acSAndroid Build Coastguard Worker 
81*1c60b9acSAndroid Build Coastguard Worker static int
lws_mpint_rfc4251(uint8_t * dest,const uint8_t * src,int bytes,int uns)82*1c60b9acSAndroid Build Coastguard Worker lws_mpint_rfc4251(uint8_t *dest, const uint8_t *src, int bytes, int uns)
83*1c60b9acSAndroid Build Coastguard Worker {
84*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *odest = dest;
85*1c60b9acSAndroid Build Coastguard Worker 
86*1c60b9acSAndroid Build Coastguard Worker 	while (!*src && bytes > 1) {
87*1c60b9acSAndroid Build Coastguard Worker 		src++;
88*1c60b9acSAndroid Build Coastguard Worker 		bytes--;
89*1c60b9acSAndroid Build Coastguard Worker 	}
90*1c60b9acSAndroid Build Coastguard Worker 
91*1c60b9acSAndroid Build Coastguard Worker 	if (!*src) {
92*1c60b9acSAndroid Build Coastguard Worker 		*dest++ = 0;
93*1c60b9acSAndroid Build Coastguard Worker 		*dest++ = 0;
94*1c60b9acSAndroid Build Coastguard Worker 		*dest++ = 0;
95*1c60b9acSAndroid Build Coastguard Worker 		*dest++ = 0;
96*1c60b9acSAndroid Build Coastguard Worker 
97*1c60b9acSAndroid Build Coastguard Worker 		return 4;
98*1c60b9acSAndroid Build Coastguard Worker 	}
99*1c60b9acSAndroid Build Coastguard Worker 
100*1c60b9acSAndroid Build Coastguard Worker 	if (uns && (*src) & 0x80)
101*1c60b9acSAndroid Build Coastguard Worker 		bytes++;
102*1c60b9acSAndroid Build Coastguard Worker 
103*1c60b9acSAndroid Build Coastguard Worker 	*dest++ = (uint8_t)(bytes >> 24);
104*1c60b9acSAndroid Build Coastguard Worker 	*dest++ = (uint8_t)(bytes >> 16);
105*1c60b9acSAndroid Build Coastguard Worker 	*dest++ = (uint8_t)(bytes >> 8);
106*1c60b9acSAndroid Build Coastguard Worker 	*dest++ = (uint8_t)(bytes);
107*1c60b9acSAndroid Build Coastguard Worker 
108*1c60b9acSAndroid Build Coastguard Worker 	if (uns && (*src) & 0x80) {
109*1c60b9acSAndroid Build Coastguard Worker 		*dest++ = 0;
110*1c60b9acSAndroid Build Coastguard Worker 		bytes--;
111*1c60b9acSAndroid Build Coastguard Worker 	}
112*1c60b9acSAndroid Build Coastguard Worker 
113*1c60b9acSAndroid Build Coastguard Worker 	while (bytes--)
114*1c60b9acSAndroid Build Coastguard Worker 		*dest++ = *src++;
115*1c60b9acSAndroid Build Coastguard Worker 
116*1c60b9acSAndroid Build Coastguard Worker 	return lws_ptr_diff(dest, odest);
117*1c60b9acSAndroid Build Coastguard Worker }
118*1c60b9acSAndroid Build Coastguard Worker 
119*1c60b9acSAndroid Build Coastguard Worker int
ed25519_key_parse(uint8_t * p,size_t len,char * type,size_t type_len,uint8_t * pub,uint8_t * pri)120*1c60b9acSAndroid Build Coastguard Worker ed25519_key_parse(uint8_t *p, size_t len, char *type, size_t type_len,
121*1c60b9acSAndroid Build Coastguard Worker 		  uint8_t *pub, uint8_t *pri)
122*1c60b9acSAndroid Build Coastguard Worker {
123*1c60b9acSAndroid Build Coastguard Worker 	uint32_t l, publ, m;
124*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *op = p;
125*1c60b9acSAndroid Build Coastguard Worker 
126*1c60b9acSAndroid Build Coastguard Worker 	if (len < 180)
127*1c60b9acSAndroid Build Coastguard Worker 		return 1;
128*1c60b9acSAndroid Build Coastguard Worker 
129*1c60b9acSAndroid Build Coastguard Worker 	if (memcmp(p, "openssh-key-v1", 14))
130*1c60b9acSAndroid Build Coastguard Worker 		return 2;
131*1c60b9acSAndroid Build Coastguard Worker 
132*1c60b9acSAndroid Build Coastguard Worker 	p += 15;
133*1c60b9acSAndroid Build Coastguard Worker 
134*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* ciphername */
135*1c60b9acSAndroid Build Coastguard Worker 	if (l != 4 || memcmp(p, "none", 4))
136*1c60b9acSAndroid Build Coastguard Worker 		return 3;
137*1c60b9acSAndroid Build Coastguard Worker 	p += l;
138*1c60b9acSAndroid Build Coastguard Worker 
139*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* kdfname */
140*1c60b9acSAndroid Build Coastguard Worker 	if (l != 4 || memcmp(p, "none", 4))
141*1c60b9acSAndroid Build Coastguard Worker 		return 4;
142*1c60b9acSAndroid Build Coastguard Worker 	p += l;
143*1c60b9acSAndroid Build Coastguard Worker 
144*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* kdfoptions */
145*1c60b9acSAndroid Build Coastguard Worker 	if (l)
146*1c60b9acSAndroid Build Coastguard Worker 		return 5;
147*1c60b9acSAndroid Build Coastguard Worker 
148*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* number of keys */
149*1c60b9acSAndroid Build Coastguard Worker 	if (l != 1)
150*1c60b9acSAndroid Build Coastguard Worker 		return 6;
151*1c60b9acSAndroid Build Coastguard Worker 
152*1c60b9acSAndroid Build Coastguard Worker 	publ = lws_g32(&p); /* length of pubkey block */
153*1c60b9acSAndroid Build Coastguard Worker 	if ((size_t)((uint32_t)(p - op) + publ) >= len)
154*1c60b9acSAndroid Build Coastguard Worker 		return 7;
155*1c60b9acSAndroid Build Coastguard Worker 
156*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* key type length */
157*1c60b9acSAndroid Build Coastguard Worker 	if (l > 31)
158*1c60b9acSAndroid Build Coastguard Worker 		return 8;
159*1c60b9acSAndroid Build Coastguard Worker 	m = l;
160*1c60b9acSAndroid Build Coastguard Worker 	if (m >= type_len)
161*1c60b9acSAndroid Build Coastguard Worker 		m = (uint32_t)type_len -1 ;
162*1c60b9acSAndroid Build Coastguard Worker 	lws_strncpy(type, (const char *)p, m + 1);
163*1c60b9acSAndroid Build Coastguard Worker 
164*1c60b9acSAndroid Build Coastguard Worker 	p += l;
165*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* pub key length */
166*1c60b9acSAndroid Build Coastguard Worker 	if (l != 32)
167*1c60b9acSAndroid Build Coastguard Worker 		return 10;
168*1c60b9acSAndroid Build Coastguard Worker 
169*1c60b9acSAndroid Build Coastguard Worker 	p += l;
170*1c60b9acSAndroid Build Coastguard Worker 
171*1c60b9acSAndroid Build Coastguard Worker 	publ = lws_g32(&p); /* length of private key block */
172*1c60b9acSAndroid Build Coastguard Worker 	if ((size_t)((uint32_t)(p - op) + publ) != len)
173*1c60b9acSAndroid Build Coastguard Worker 		return 11;
174*1c60b9acSAndroid Build Coastguard Worker 
175*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* checkint 1 */
176*1c60b9acSAndroid Build Coastguard Worker 	if (lws_g32(&p) != l) /* must match checkint 2 */
177*1c60b9acSAndroid Build Coastguard Worker 		return 12;
178*1c60b9acSAndroid Build Coastguard Worker 
179*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* key type length */
180*1c60b9acSAndroid Build Coastguard Worker 
181*1c60b9acSAndroid Build Coastguard Worker 	p += l;
182*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* public key part length */
183*1c60b9acSAndroid Build Coastguard Worker 	if (l != LWS_SIZE_EC25519_PUBKEY)
184*1c60b9acSAndroid Build Coastguard Worker 		return 15;
185*1c60b9acSAndroid Build Coastguard Worker 
186*1c60b9acSAndroid Build Coastguard Worker 	if (pub)
187*1c60b9acSAndroid Build Coastguard Worker 		memcpy(pub, p, LWS_SIZE_EC25519_PUBKEY);
188*1c60b9acSAndroid Build Coastguard Worker 	p += l;
189*1c60b9acSAndroid Build Coastguard Worker 	l = lws_g32(&p); /* private key part length */
190*1c60b9acSAndroid Build Coastguard Worker 	if (l != LWS_SIZE_EC25519_PRIKEY)
191*1c60b9acSAndroid Build Coastguard Worker 		return 16;
192*1c60b9acSAndroid Build Coastguard Worker 
193*1c60b9acSAndroid Build Coastguard Worker 	if (pri)
194*1c60b9acSAndroid Build Coastguard Worker 		memcpy(pri, p, LWS_SIZE_EC25519_PRIKEY);
195*1c60b9acSAndroid Build Coastguard Worker 
196*1c60b9acSAndroid Build Coastguard Worker 	return 0;
197*1c60b9acSAndroid Build Coastguard Worker }
198*1c60b9acSAndroid Build Coastguard Worker 
199*1c60b9acSAndroid Build Coastguard Worker static int
_genhash_update_len(struct lws_genhash_ctx * ctx,const void * input,size_t ilen)200*1c60b9acSAndroid Build Coastguard Worker _genhash_update_len(struct lws_genhash_ctx *ctx, const void *input, size_t ilen)
201*1c60b9acSAndroid Build Coastguard Worker {
202*1c60b9acSAndroid Build Coastguard Worker 	uint32_t be;
203*1c60b9acSAndroid Build Coastguard Worker 
204*1c60b9acSAndroid Build Coastguard Worker 	lws_p32((uint8_t *)&be, (uint32_t)ilen);
205*1c60b9acSAndroid Build Coastguard Worker 
206*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_update(ctx, (uint8_t *)&be, 4))
207*1c60b9acSAndroid Build Coastguard Worker 		return 1;
208*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_update(ctx, input, ilen))
209*1c60b9acSAndroid Build Coastguard Worker 		return 1;
210*1c60b9acSAndroid Build Coastguard Worker 
211*1c60b9acSAndroid Build Coastguard Worker 	return 0;
212*1c60b9acSAndroid Build Coastguard Worker }
213*1c60b9acSAndroid Build Coastguard Worker 
214*1c60b9acSAndroid Build Coastguard Worker static int
kex_ecdh_dv(uint8_t * dest,int dest_len,const uint8_t * kbi,int kbi_len,const uint8_t * H,char c,const uint8_t * session_id)215*1c60b9acSAndroid Build Coastguard Worker kex_ecdh_dv(uint8_t *dest, int dest_len, const uint8_t *kbi, int kbi_len,
216*1c60b9acSAndroid Build Coastguard Worker 	    const uint8_t *H, char c, const uint8_t *session_id)
217*1c60b9acSAndroid Build Coastguard Worker {
218*1c60b9acSAndroid Build Coastguard Worker 	uint8_t pool[LWS_SIZE_SHA256];
219*1c60b9acSAndroid Build Coastguard Worker 	struct lws_genhash_ctx ctx;
220*1c60b9acSAndroid Build Coastguard Worker 	int n = 0, m;
221*1c60b9acSAndroid Build Coastguard Worker 
222*1c60b9acSAndroid Build Coastguard Worker 	/*
223*1c60b9acSAndroid Build Coastguard Worker 	 * Key data MUST be taken from the beginning of the hash output.
224*1c60b9acSAndroid Build Coastguard Worker 	 * As many bytes as needed are taken from the beginning of the hash
225*1c60b9acSAndroid Build Coastguard Worker 	 * value.
226*1c60b9acSAndroid Build Coastguard Worker 	 *
227*1c60b9acSAndroid Build Coastguard Worker 	 * If the key length needed is longer than the output of the HASH,
228*1c60b9acSAndroid Build Coastguard Worker 	 * the key is extended by computing HASH of the concatenation of K
229*1c60b9acSAndroid Build Coastguard Worker 	 * and H and the entire key so far, and appending the resulting
230*1c60b9acSAndroid Build Coastguard Worker 	 * bytes (as many as HASH generates) to the key.  This process is
231*1c60b9acSAndroid Build Coastguard Worker 	 * repeated until enough key material is available; the key is taken
232*1c60b9acSAndroid Build Coastguard Worker 	 * from the beginning of this value.  In other words:
233*1c60b9acSAndroid Build Coastguard Worker 	 *
234*1c60b9acSAndroid Build Coastguard Worker 	 * K1 = HASH(K || H || X || session_id)   (X is e.g., "A")
235*1c60b9acSAndroid Build Coastguard Worker 	 * K2 = HASH(K || H || K1)
236*1c60b9acSAndroid Build Coastguard Worker 	 * K3 = HASH(K || H || K1 || K2)
237*1c60b9acSAndroid Build Coastguard Worker 	 *      ...
238*1c60b9acSAndroid Build Coastguard Worker 	 * key = K1 || K2 || K3 || ...
239*1c60b9acSAndroid Build Coastguard Worker 	 */
240*1c60b9acSAndroid Build Coastguard Worker 
241*1c60b9acSAndroid Build Coastguard Worker 	while (n < dest_len) {
242*1c60b9acSAndroid Build Coastguard Worker 
243*1c60b9acSAndroid Build Coastguard Worker 		if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA256))
244*1c60b9acSAndroid Build Coastguard Worker 			return 1;
245*1c60b9acSAndroid Build Coastguard Worker 
246*1c60b9acSAndroid Build Coastguard Worker 		if (lws_genhash_update(&ctx, kbi, (unsigned int)kbi_len))
247*1c60b9acSAndroid Build Coastguard Worker 			goto hash_failed;
248*1c60b9acSAndroid Build Coastguard Worker 		if (lws_genhash_update(&ctx, H, LWS_SIZE_SHA256))
249*1c60b9acSAndroid Build Coastguard Worker 			goto hash_failed;
250*1c60b9acSAndroid Build Coastguard Worker 
251*1c60b9acSAndroid Build Coastguard Worker 		if (!n) {
252*1c60b9acSAndroid Build Coastguard Worker 			if (lws_genhash_update(&ctx, (void *)&c, 1))
253*1c60b9acSAndroid Build Coastguard Worker 				goto hash_failed;
254*1c60b9acSAndroid Build Coastguard Worker 			if (lws_genhash_update(&ctx, session_id,
255*1c60b9acSAndroid Build Coastguard Worker 					      LWS_SIZE_EC25519))
256*1c60b9acSAndroid Build Coastguard Worker 				goto hash_failed;
257*1c60b9acSAndroid Build Coastguard Worker 		} else
258*1c60b9acSAndroid Build Coastguard Worker 			if (lws_genhash_update(&ctx, pool, LWS_SIZE_EC25519))
259*1c60b9acSAndroid Build Coastguard Worker 				goto hash_failed;
260*1c60b9acSAndroid Build Coastguard Worker 
261*1c60b9acSAndroid Build Coastguard Worker 		lws_genhash_destroy(&ctx, pool);
262*1c60b9acSAndroid Build Coastguard Worker 
263*1c60b9acSAndroid Build Coastguard Worker 		m = LWS_SIZE_EC25519;
264*1c60b9acSAndroid Build Coastguard Worker 		if (m > (dest_len - n))
265*1c60b9acSAndroid Build Coastguard Worker 			m = dest_len - n;
266*1c60b9acSAndroid Build Coastguard Worker 
267*1c60b9acSAndroid Build Coastguard Worker 		memcpy(dest, pool, (unsigned int)m);
268*1c60b9acSAndroid Build Coastguard Worker 		n += m;
269*1c60b9acSAndroid Build Coastguard Worker 		dest += m;
270*1c60b9acSAndroid Build Coastguard Worker 	}
271*1c60b9acSAndroid Build Coastguard Worker 
272*1c60b9acSAndroid Build Coastguard Worker 	return 0;
273*1c60b9acSAndroid Build Coastguard Worker 
274*1c60b9acSAndroid Build Coastguard Worker hash_failed:
275*1c60b9acSAndroid Build Coastguard Worker 	lws_genhash_destroy(&ctx, NULL);
276*1c60b9acSAndroid Build Coastguard Worker 
277*1c60b9acSAndroid Build Coastguard Worker 	return 1;
278*1c60b9acSAndroid Build Coastguard Worker }
279*1c60b9acSAndroid Build Coastguard Worker 
280*1c60b9acSAndroid Build Coastguard Worker 
281*1c60b9acSAndroid Build Coastguard Worker static const unsigned char basepoint[32] = { 9 };
282*1c60b9acSAndroid Build Coastguard Worker 
283*1c60b9acSAndroid Build Coastguard Worker size_t
get_gen_server_key_25519(struct per_session_data__sshd * pss,uint8_t * b,size_t len)284*1c60b9acSAndroid Build Coastguard Worker get_gen_server_key_25519(struct per_session_data__sshd *pss, uint8_t *b,
285*1c60b9acSAndroid Build Coastguard Worker 			 size_t len)
286*1c60b9acSAndroid Build Coastguard Worker {
287*1c60b9acSAndroid Build Coastguard Worker 	size_t s, mylen;
288*1c60b9acSAndroid Build Coastguard Worker 
289*1c60b9acSAndroid Build Coastguard Worker 	mylen = pss->vhd->ops->get_server_key(pss->wsi, b, len);
290*1c60b9acSAndroid Build Coastguard Worker 	if (mylen)
291*1c60b9acSAndroid Build Coastguard Worker 		return mylen;
292*1c60b9acSAndroid Build Coastguard Worker 
293*1c60b9acSAndroid Build Coastguard Worker 	/* create one then */
294*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("Generating server hostkey\n");
295*1c60b9acSAndroid Build Coastguard Worker 	s = lws_gen_server_key_ed25519(pss->vhd->context, b, len);
296*1c60b9acSAndroid Build Coastguard Worker 	lwsl_notice("  gen key len %ld\n", (long)s);
297*1c60b9acSAndroid Build Coastguard Worker 	if (!s)
298*1c60b9acSAndroid Build Coastguard Worker 		return 0;
299*1c60b9acSAndroid Build Coastguard Worker 	/* set the key */
300*1c60b9acSAndroid Build Coastguard Worker 	if (!pss->vhd->ops->set_server_key(pss->wsi, b, s))
301*1c60b9acSAndroid Build Coastguard Worker 		return 0;
302*1c60b9acSAndroid Build Coastguard Worker 
303*1c60b9acSAndroid Build Coastguard Worker 	/* new key stored OK */
304*1c60b9acSAndroid Build Coastguard Worker 
305*1c60b9acSAndroid Build Coastguard Worker 	return s;
306*1c60b9acSAndroid Build Coastguard Worker }
307*1c60b9acSAndroid Build Coastguard Worker 
308*1c60b9acSAndroid Build Coastguard Worker int
kex_ecdh(struct per_session_data__sshd * pss,uint8_t * reply,uint32_t * plen)309*1c60b9acSAndroid Build Coastguard Worker kex_ecdh(struct per_session_data__sshd *pss, uint8_t *reply, uint32_t *plen)
310*1c60b9acSAndroid Build Coastguard Worker {
311*1c60b9acSAndroid Build Coastguard Worker 	uint8_t pri_key[64], temp[64], payload_sig[64 + 32], a, *lp, kbi[64];
312*1c60b9acSAndroid Build Coastguard Worker 	struct lws_kex *kex = pss->kex;
313*1c60b9acSAndroid Build Coastguard Worker 	struct lws_genhash_ctx ctx;
314*1c60b9acSAndroid Build Coastguard Worker         unsigned long long smlen;
315*1c60b9acSAndroid Build Coastguard Worker 	uint8_t *p = reply + 5;
316*1c60b9acSAndroid Build Coastguard Worker 	uint32_t be, kbi_len;
317*1c60b9acSAndroid Build Coastguard Worker 	uint8_t servkey[256];
318*1c60b9acSAndroid Build Coastguard Worker 	char keyt[33];
319*1c60b9acSAndroid Build Coastguard Worker 	int r, c;
320*1c60b9acSAndroid Build Coastguard Worker 
321*1c60b9acSAndroid Build Coastguard Worker 	r = (int)get_gen_server_key_25519(pss, servkey, (int)sizeof(servkey));
322*1c60b9acSAndroid Build Coastguard Worker 	if (!r) {
323*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: Failed to get or gen server key\n", __func__);
324*1c60b9acSAndroid Build Coastguard Worker 
325*1c60b9acSAndroid Build Coastguard Worker 		return 1;
326*1c60b9acSAndroid Build Coastguard Worker 	}
327*1c60b9acSAndroid Build Coastguard Worker 
328*1c60b9acSAndroid Build Coastguard Worker 	r = ed25519_key_parse(servkey, (unsigned int)r, keyt, sizeof(keyt),
329*1c60b9acSAndroid Build Coastguard Worker 			      pss->K_S /* public key */, pri_key);
330*1c60b9acSAndroid Build Coastguard Worker 	if (r) {
331*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: server key parse failed: %d\n", __func__, r);
332*1c60b9acSAndroid Build Coastguard Worker 
333*1c60b9acSAndroid Build Coastguard Worker 		return 1;
334*1c60b9acSAndroid Build Coastguard Worker 	}
335*1c60b9acSAndroid Build Coastguard Worker 	keyt[32] = '\0';
336*1c60b9acSAndroid Build Coastguard Worker 
337*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("Server key type: %s\n", keyt);
338*1c60b9acSAndroid Build Coastguard Worker 
339*1c60b9acSAndroid Build Coastguard Worker 	/*
340*1c60b9acSAndroid Build Coastguard Worker 	 * 1) Generate ephemeral key pair [ eph_pri_key | kex->Q_S ]
341*1c60b9acSAndroid Build Coastguard Worker 	 * 2) Compute shared secret.
342*1c60b9acSAndroid Build Coastguard Worker 	 * 3) Generate and sign exchange hash.
343*1c60b9acSAndroid Build Coastguard Worker 	 *
344*1c60b9acSAndroid Build Coastguard Worker 	 * 1) A 32 bytes private key should be generated for each new
345*1c60b9acSAndroid Build Coastguard Worker 	 *    connection, using a secure PRNG. The following actions
346*1c60b9acSAndroid Build Coastguard Worker 	 *    must be done on the private key:
347*1c60b9acSAndroid Build Coastguard Worker 	 *
348*1c60b9acSAndroid Build Coastguard Worker 	 *     mysecret[0] &= 248;
349*1c60b9acSAndroid Build Coastguard Worker 	 *     mysecret[31] &= 127;
350*1c60b9acSAndroid Build Coastguard Worker 	 *     mysecret[31] |= 64;
351*1c60b9acSAndroid Build Coastguard Worker 	 */
352*1c60b9acSAndroid Build Coastguard Worker 	lws_get_random(pss->vhd->context, kex->eph_pri_key, LWS_SIZE_EC25519);
353*1c60b9acSAndroid Build Coastguard Worker 	kex->eph_pri_key[0] &= 248;
354*1c60b9acSAndroid Build Coastguard Worker 	kex->eph_pri_key[31] &= 127;
355*1c60b9acSAndroid Build Coastguard Worker 	kex->eph_pri_key[31] |= 64;
356*1c60b9acSAndroid Build Coastguard Worker 
357*1c60b9acSAndroid Build Coastguard Worker 	/*
358*1c60b9acSAndroid Build Coastguard Worker 	 * 2) The public key is calculated using the cryptographic scalar
359*1c60b9acSAndroid Build Coastguard Worker 	 *    multiplication:
360*1c60b9acSAndroid Build Coastguard Worker 	 *
361*1c60b9acSAndroid Build Coastguard Worker 	 *     const unsigned char privkey[32];
362*1c60b9acSAndroid Build Coastguard Worker 	 *     unsigned char pubkey[32];
363*1c60b9acSAndroid Build Coastguard Worker 	 *
364*1c60b9acSAndroid Build Coastguard Worker 	 *     crypto_scalarmult (pubkey, privkey, basepoint);
365*1c60b9acSAndroid Build Coastguard Worker 	 */
366*1c60b9acSAndroid Build Coastguard Worker 	crypto_scalarmult_curve25519(kex->Q_S, kex->eph_pri_key, basepoint);
367*1c60b9acSAndroid Build Coastguard Worker 
368*1c60b9acSAndroid Build Coastguard Worker 	a = 0;
369*1c60b9acSAndroid Build Coastguard Worker 	for (r = 0; r < (int)sizeof(kex->Q_S); r++)
370*1c60b9acSAndroid Build Coastguard Worker 		a |= kex->Q_S[r];
371*1c60b9acSAndroid Build Coastguard Worker 	if (!a) {
372*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("all zero pubkey\n");
373*1c60b9acSAndroid Build Coastguard Worker 		return SSH_DISCONNECT_KEY_EXCHANGE_FAILED;
374*1c60b9acSAndroid Build Coastguard Worker 	}
375*1c60b9acSAndroid Build Coastguard Worker 
376*1c60b9acSAndroid Build Coastguard Worker 	/*
377*1c60b9acSAndroid Build Coastguard Worker 	 * The shared secret, k, is defined in SSH specifications to be a big
378*1c60b9acSAndroid Build Coastguard Worker 	 * integer.  This number is calculated using the following procedure:
379*1c60b9acSAndroid Build Coastguard Worker 	 *
380*1c60b9acSAndroid Build Coastguard Worker 	 * X is the 32 bytes point obtained by the scalar multiplication of
381*1c60b9acSAndroid Build Coastguard Worker 	 * the other side's public key and the local private key scalar.
382*1c60b9acSAndroid Build Coastguard Worker 	 */
383*1c60b9acSAndroid Build Coastguard Worker 	crypto_scalarmult_curve25519(pss->K, kex->eph_pri_key, kex->Q_C);
384*1c60b9acSAndroid Build Coastguard Worker 
385*1c60b9acSAndroid Build Coastguard Worker 	/*
386*1c60b9acSAndroid Build Coastguard Worker 	 * The whole 32 bytes of the number X are then converted into a big
387*1c60b9acSAndroid Build Coastguard Worker 	 * integer k.  This conversion follows the network byte order. This
388*1c60b9acSAndroid Build Coastguard Worker 	 * step differs from RFC5656.
389*1c60b9acSAndroid Build Coastguard Worker 	 */
390*1c60b9acSAndroid Build Coastguard Worker 	kbi_len = (uint32_t)lws_mpint_rfc4251(kbi, pss->K, LWS_SIZE_EC25519, 1);
391*1c60b9acSAndroid Build Coastguard Worker 
392*1c60b9acSAndroid Build Coastguard Worker 	/*
393*1c60b9acSAndroid Build Coastguard Worker 	 * The exchange hash H is computed as the hash of the concatenation of
394*1c60b9acSAndroid Build Coastguard Worker 	 * the following:
395*1c60b9acSAndroid Build Coastguard Worker 	 *
396*1c60b9acSAndroid Build Coastguard Worker 	 *      string    V_C, the client's identification string (CR and LF
397*1c60b9acSAndroid Build Coastguard Worker          *		       excluded)
398*1c60b9acSAndroid Build Coastguard Worker 	 *      string    V_S, the server's identification string (CR and LF
399*1c60b9acSAndroid Build Coastguard Worker          *		       excluded)
400*1c60b9acSAndroid Build Coastguard Worker 	 *      string    I_C, the payload of the client's SSH_MSG_KEXINIT
401*1c60b9acSAndroid Build Coastguard Worker 	 *      string    I_S, the payload of the server's SSH_MSG_KEXINIT
402*1c60b9acSAndroid Build Coastguard Worker 	 *      string    K_S, the host key
403*1c60b9acSAndroid Build Coastguard Worker 	 *      mpint     Q_C, exchange value sent by the client
404*1c60b9acSAndroid Build Coastguard Worker 	 *      mpint     Q_S, exchange value sent by the server
405*1c60b9acSAndroid Build Coastguard Worker 	 *      mpint     K, the shared secret
406*1c60b9acSAndroid Build Coastguard Worker 	 *
407*1c60b9acSAndroid Build Coastguard Worker 	 * However there are a lot of unwritten details in the hash
408*1c60b9acSAndroid Build Coastguard Worker 	 * definition...
409*1c60b9acSAndroid Build Coastguard Worker 	 */
410*1c60b9acSAndroid Build Coastguard Worker 
411*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_init(&ctx, LWS_GENHASH_TYPE_SHA256)) {
412*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("genhash init failed\n");
413*1c60b9acSAndroid Build Coastguard Worker 		return 1;
414*1c60b9acSAndroid Build Coastguard Worker 	}
415*1c60b9acSAndroid Build Coastguard Worker 
416*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, pss->V_C, strlen(pss->V_C)))
417*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
418*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, pss->vhd->ops->server_string, /* aka V_S */
419*1c60b9acSAndroid Build Coastguard Worker 			       strlen(pss->vhd->ops->server_string)))
420*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
421*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, kex->I_C, kex->I_C_payload_len))
422*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
423*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, kex->I_S, kex->I_S_payload_len))
424*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
425*1c60b9acSAndroid Build Coastguard Worker 	/*
426*1c60b9acSAndroid Build Coastguard Worker 	 * K_S (host public key)
427*1c60b9acSAndroid Build Coastguard Worker 	 *
428*1c60b9acSAndroid Build Coastguard Worker 	 * sum of name + key lengths and headers
429*1c60b9acSAndroid Build Coastguard Worker 	 * name length: name
430*1c60b9acSAndroid Build Coastguard Worker 	 * key length: key
431*1c60b9acSAndroid Build Coastguard Worker 	 * ---> */
432*1c60b9acSAndroid Build Coastguard Worker 	lws_p32((uint8_t *)&be, (uint32_t)(8 + (int)strlen(keyt) + LWS_SIZE_EC25519));
433*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_update(&ctx, (void *)&be, 4))
434*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
435*1c60b9acSAndroid Build Coastguard Worker 
436*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, keyt, strlen(keyt)))
437*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
438*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, pss->K_S, LWS_SIZE_EC25519))
439*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
440*1c60b9acSAndroid Build Coastguard Worker 	/* <---- */
441*1c60b9acSAndroid Build Coastguard Worker 
442*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, kex->Q_C, LWS_SIZE_EC25519))
443*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
444*1c60b9acSAndroid Build Coastguard Worker 	if (_genhash_update_len(&ctx, kex->Q_S, LWS_SIZE_EC25519))
445*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
446*1c60b9acSAndroid Build Coastguard Worker 
447*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_update(&ctx, kbi, kbi_len))
448*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
449*1c60b9acSAndroid Build Coastguard Worker 
450*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_destroy(&ctx, temp))
451*1c60b9acSAndroid Build Coastguard Worker 		goto hash_probs;
452*1c60b9acSAndroid Build Coastguard Worker 
453*1c60b9acSAndroid Build Coastguard Worker 	/*
454*1c60b9acSAndroid Build Coastguard Worker 	 * Sign the 32-byte SHA256 "exchange hash" in temp
455*1c60b9acSAndroid Build Coastguard Worker 	 * The signature is itself 64 bytes
456*1c60b9acSAndroid Build Coastguard Worker 	 */
457*1c60b9acSAndroid Build Coastguard Worker         smlen = LWS_SIZE_EC25519 + 64;
458*1c60b9acSAndroid Build Coastguard Worker         if (crypto_sign_ed25519(payload_sig, &smlen, temp, LWS_SIZE_EC25519,
459*1c60b9acSAndroid Build Coastguard Worker         			pri_key))
460*1c60b9acSAndroid Build Coastguard Worker 		return 1;
461*1c60b9acSAndroid Build Coastguard Worker 
462*1c60b9acSAndroid Build Coastguard Worker #if 0
463*1c60b9acSAndroid Build Coastguard Worker         l = LWS_SIZE_EC25519;
464*1c60b9acSAndroid Build Coastguard Worker         n = crypto_sign_ed25519_open(temp, &l, payload_sig, smlen, pss->K_S);
465*1c60b9acSAndroid Build Coastguard Worker 
466*1c60b9acSAndroid Build Coastguard Worker         lwsl_notice("own sig sanity check says %d\n", n);
467*1c60b9acSAndroid Build Coastguard Worker #endif
468*1c60b9acSAndroid Build Coastguard Worker 
469*1c60b9acSAndroid Build Coastguard Worker 	/* sig [64] and payload [32] concatenated in payload_sig
470*1c60b9acSAndroid Build Coastguard Worker 	 *
471*1c60b9acSAndroid Build Coastguard Worker 	 * The server then responds with the following
472*1c60b9acSAndroid Build Coastguard Worker 	 *
473*1c60b9acSAndroid Build Coastguard Worker 	 *	uint32    packet length (exl self + mac)
474*1c60b9acSAndroid Build Coastguard Worker 	 *	byte      padding len
475*1c60b9acSAndroid Build Coastguard Worker 	 *      byte      SSH_MSG_KEX_ECDH_REPLY
476*1c60b9acSAndroid Build Coastguard Worker 	 *      string    server public host key and certificates (K_S)
477*1c60b9acSAndroid Build Coastguard Worker 	 *      string    Q_S (exchange value sent by the server)
478*1c60b9acSAndroid Build Coastguard Worker 	 *      string    signature of H
479*1c60b9acSAndroid Build Coastguard Worker 	 *      padding
480*1c60b9acSAndroid Build Coastguard Worker 	 */
481*1c60b9acSAndroid Build Coastguard Worker 	*p++ = SSH_MSG_KEX_ECDH_REPLY;
482*1c60b9acSAndroid Build Coastguard Worker 
483*1c60b9acSAndroid Build Coastguard Worker 	/* server public host key and certificates (K_S) */
484*1c60b9acSAndroid Build Coastguard Worker 
485*1c60b9acSAndroid Build Coastguard Worker 	lp = p;
486*1c60b9acSAndroid Build Coastguard Worker 	p +=4;
487*1c60b9acSAndroid Build Coastguard Worker 	lws_sized_blob(&p, keyt, (uint32_t)strlen(keyt));
488*1c60b9acSAndroid Build Coastguard Worker 	lws_sized_blob(&p, pss->K_S, LWS_SIZE_EC25519);
489*1c60b9acSAndroid Build Coastguard Worker 	lws_p32(lp, (uint32_t)(lws_ptr_diff(p, lp) - 4));
490*1c60b9acSAndroid Build Coastguard Worker 
491*1c60b9acSAndroid Build Coastguard Worker 	/* Q_S (exchange value sent by the server) */
492*1c60b9acSAndroid Build Coastguard Worker 
493*1c60b9acSAndroid Build Coastguard Worker 	lws_sized_blob(&p, kex->Q_S, LWS_SIZE_EC25519);
494*1c60b9acSAndroid Build Coastguard Worker 
495*1c60b9acSAndroid Build Coastguard Worker 	/* signature of H */
496*1c60b9acSAndroid Build Coastguard Worker 
497*1c60b9acSAndroid Build Coastguard Worker 	lp = p;
498*1c60b9acSAndroid Build Coastguard Worker 	p +=4;
499*1c60b9acSAndroid Build Coastguard Worker 	lws_sized_blob(&p, keyt, (uint32_t)strlen(keyt));
500*1c60b9acSAndroid Build Coastguard Worker 	lws_sized_blob(&p, payload_sig, 64);
501*1c60b9acSAndroid Build Coastguard Worker 	lws_p32(lp, (uint32_t)(lws_ptr_diff(p, lp) - 4));
502*1c60b9acSAndroid Build Coastguard Worker 
503*1c60b9acSAndroid Build Coastguard Worker 	/* end of message */
504*1c60b9acSAndroid Build Coastguard Worker 
505*1c60b9acSAndroid Build Coastguard Worker 	lws_pad_set_length(pss, reply, &p, &pss->active_keys_stc);
506*1c60b9acSAndroid Build Coastguard Worker 	*plen = (uint32_t)lws_ptr_diff(p, reply);
507*1c60b9acSAndroid Build Coastguard Worker 
508*1c60b9acSAndroid Build Coastguard Worker 	if (!pss->active_keys_stc.valid)
509*1c60b9acSAndroid Build Coastguard Worker 		memcpy(pss->session_id, temp, LWS_SIZE_EC25519);
510*1c60b9acSAndroid Build Coastguard Worker 
511*1c60b9acSAndroid Build Coastguard Worker 	/* RFC4253 7.2:
512*1c60b9acSAndroid Build Coastguard Worker 	 *
513*1c60b9acSAndroid Build Coastguard Worker 	 * The key exchange produces two values: a shared secret K,
514*1c60b9acSAndroid Build Coastguard Worker 	 * and an exchange hash H.  Encryption and authentication
515*1c60b9acSAndroid Build Coastguard Worker 	 * keys are derived from these.  The exchange hash H from the
516*1c60b9acSAndroid Build Coastguard Worker 	 * first key exchange is additionally used as the session
517*1c60b9acSAndroid Build Coastguard Worker 	 * identifier, which is a unique identifier for this connection.
518*1c60b9acSAndroid Build Coastguard Worker 	 * It is used by authentication methods as a part of the data
519*1c60b9acSAndroid Build Coastguard Worker 	 * that is signed as a proof of possession of a private key.
520*1c60b9acSAndroid Build Coastguard Worker 	 * Once computed, the session identifier is not changed,
521*1c60b9acSAndroid Build Coastguard Worker 	 * even if keys are later re-exchanged.
522*1c60b9acSAndroid Build Coastguard Worker 	 *
523*1c60b9acSAndroid Build Coastguard Worker 	 * The hash alg used in the KEX must be used for key derivation.
524*1c60b9acSAndroid Build Coastguard Worker 	 *
525*1c60b9acSAndroid Build Coastguard Worker 	 * 1) Initial IV client to server:
526*1c60b9acSAndroid Build Coastguard Worker 	 *
527*1c60b9acSAndroid Build Coastguard Worker 	 *     HASH(K || H || "A" || session_id)
528*1c60b9acSAndroid Build Coastguard Worker 	 *
529*1c60b9acSAndroid Build Coastguard Worker 	 * (Here K is encoded as mpint and "A" as byte and session_id
530*1c60b9acSAndroid Build Coastguard Worker 	 * as raw data.  "A" means the single character A, ASCII 65).
531*1c60b9acSAndroid Build Coastguard Worker 	 *
532*1c60b9acSAndroid Build Coastguard Worker 	 *
533*1c60b9acSAndroid Build Coastguard Worker 	 */
534*1c60b9acSAndroid Build Coastguard Worker 	for (c = 0; c < 3; c++) {
535*1c60b9acSAndroid Build Coastguard Worker 		kex_ecdh_dv(kex->keys_next_cts.key[c], LWS_SIZE_CHACHA256_KEY,
536*1c60b9acSAndroid Build Coastguard Worker 			    kbi, (int)kbi_len, temp, (char)('A' + (c * 2)),
537*1c60b9acSAndroid Build Coastguard Worker 			    pss->session_id);
538*1c60b9acSAndroid Build Coastguard Worker 		kex_ecdh_dv(kex->keys_next_stc.key[c], LWS_SIZE_CHACHA256_KEY,
539*1c60b9acSAndroid Build Coastguard Worker 			    kbi, (int)kbi_len, temp, (char)('B' + (c * 2)),
540*1c60b9acSAndroid Build Coastguard Worker 			    pss->session_id);
541*1c60b9acSAndroid Build Coastguard Worker 	}
542*1c60b9acSAndroid Build Coastguard Worker 
543*1c60b9acSAndroid Build Coastguard Worker 	lws_explicit_bzero(temp, sizeof(temp));
544*1c60b9acSAndroid Build Coastguard Worker 
545*1c60b9acSAndroid Build Coastguard Worker 	return 0;
546*1c60b9acSAndroid Build Coastguard Worker 
547*1c60b9acSAndroid Build Coastguard Worker hash_probs:
548*1c60b9acSAndroid Build Coastguard Worker 	lws_genhash_destroy(&ctx, NULL);
549*1c60b9acSAndroid Build Coastguard Worker 
550*1c60b9acSAndroid Build Coastguard Worker 	return 1;
551*1c60b9acSAndroid Build Coastguard Worker }
552