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