1 /* Copyright (c) 2016, Art <https://github.com/wildart>
2 * All rights reserved.
3 *
4 * Redistribution and use in source and binary forms,
5 * with or without modification, are permitted provided
6 * that the following conditions are met:
7 *
8 * Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the
10 * following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
16 *
17 * Neither the name of the copyright holder nor the names
18 * of any other contributors may be used to endorse or
19 * promote products derived from this software without
20 * specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
23 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
24 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
32 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
34 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
35 * OF SUCH DAMAGE.
36 */
37
38 #include "libssh2_priv.h"
39
40 #ifdef LIBSSH2_MBEDTLS /* compile only if we build with mbedtls */
41
42 /*******************************************************************/
43 /*
44 * mbedTLS backend: Global context handles
45 */
46
47 static mbedtls_entropy_context _libssh2_mbedtls_entropy;
48 static mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg;
49
50 /*******************************************************************/
51 /*
52 * mbedTLS backend: Generic functions
53 */
54
55 void
_libssh2_mbedtls_init(void)56 _libssh2_mbedtls_init(void)
57 {
58 int ret;
59
60 mbedtls_entropy_init(&_libssh2_mbedtls_entropy);
61 mbedtls_ctr_drbg_init(&_libssh2_mbedtls_ctr_drbg);
62
63 ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg,
64 mbedtls_entropy_func,
65 &_libssh2_mbedtls_entropy, NULL, 0);
66 if(ret != 0)
67 mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg);
68 }
69
70 void
_libssh2_mbedtls_free(void)71 _libssh2_mbedtls_free(void)
72 {
73 mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg);
74 mbedtls_entropy_free(&_libssh2_mbedtls_entropy);
75 }
76
77 int
_libssh2_mbedtls_random(unsigned char * buf,int len)78 _libssh2_mbedtls_random(unsigned char *buf, int len)
79 {
80 int ret;
81 ret = mbedtls_ctr_drbg_random(&_libssh2_mbedtls_ctr_drbg, buf, len);
82 return ret == 0 ? 0 : -1;
83 }
84
85 static void
_libssh2_mbedtls_safe_free(void * buf,int len)86 _libssh2_mbedtls_safe_free(void *buf, int len)
87 {
88 #ifndef LIBSSH2_CLEAR_MEMORY
89 (void)len;
90 #endif
91
92 if(!buf)
93 return;
94
95 #ifdef LIBSSH2_CLEAR_MEMORY
96 if(len > 0)
97 _libssh2_explicit_zero(buf, len);
98 #endif
99
100 mbedtls_free(buf);
101 }
102
103 int
_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx * ctx,_libssh2_cipher_type (algo),unsigned char * iv,unsigned char * secret,int encrypt)104 _libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx,
105 _libssh2_cipher_type(algo),
106 unsigned char *iv,
107 unsigned char *secret,
108 int encrypt)
109 {
110 const mbedtls_cipher_info_t *cipher_info;
111 int ret, op;
112
113 if(!ctx)
114 return -1;
115
116 op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT;
117
118 cipher_info = mbedtls_cipher_info_from_type(algo);
119 if(!cipher_info)
120 return -1;
121
122 mbedtls_cipher_init(ctx);
123 ret = mbedtls_cipher_setup(ctx, cipher_info);
124 if(!ret)
125 ret = mbedtls_cipher_setkey(ctx, secret, cipher_info->key_bitlen, op);
126
127 if(!ret)
128 ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->iv_size);
129
130 return ret == 0 ? 0 : -1;
131 }
132
133 int
_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx * ctx,_libssh2_cipher_type (algo),int encrypt,unsigned char * block,size_t blocklen)134 _libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx,
135 _libssh2_cipher_type(algo),
136 int encrypt,
137 unsigned char *block,
138 size_t blocklen)
139 {
140 int ret;
141 unsigned char *output;
142 size_t osize, olen, finish_olen;
143
144 (void) encrypt;
145 (void) algo;
146
147 osize = blocklen + mbedtls_cipher_get_block_size(ctx);
148
149 output = (unsigned char *)mbedtls_calloc(osize, sizeof(char));
150 if(output) {
151 ret = mbedtls_cipher_reset(ctx);
152
153 if(!ret)
154 ret = mbedtls_cipher_update(ctx, block, blocklen, output, &olen);
155
156 if(!ret)
157 ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen);
158
159 if(!ret) {
160 olen += finish_olen;
161 memcpy(block, output, olen);
162 }
163
164 _libssh2_mbedtls_safe_free(output, osize);
165 }
166 else
167 ret = -1;
168
169 return ret == 0 ? 0 : -1;
170 }
171
172 void
_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx * ctx)173 _libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx)
174 {
175 mbedtls_cipher_free(ctx);
176 }
177
178
179 int
_libssh2_mbedtls_hash_init(mbedtls_md_context_t * ctx,mbedtls_md_type_t mdtype,const unsigned char * key,unsigned long keylen)180 _libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx,
181 mbedtls_md_type_t mdtype,
182 const unsigned char *key, unsigned long keylen)
183 {
184 const mbedtls_md_info_t *md_info;
185 int ret, hmac;
186
187 md_info = mbedtls_md_info_from_type(mdtype);
188 if(!md_info)
189 return 0;
190
191 hmac = key == NULL ? 0 : 1;
192
193 mbedtls_md_init(ctx);
194 ret = mbedtls_md_setup(ctx, md_info, hmac);
195 if(!ret) {
196 if(hmac)
197 ret = mbedtls_md_hmac_starts(ctx, key, keylen);
198 else
199 ret = mbedtls_md_starts(ctx);
200 }
201
202 return ret == 0 ? 1 : 0;
203 }
204
205 int
_libssh2_mbedtls_hash_final(mbedtls_md_context_t * ctx,unsigned char * hash)206 _libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash)
207 {
208 int ret;
209
210 ret = mbedtls_md_finish(ctx, hash);
211 mbedtls_md_free(ctx);
212
213 return ret == 0 ? 0 : -1;
214 }
215
216 int
_libssh2_mbedtls_hash(const unsigned char * data,unsigned long datalen,mbedtls_md_type_t mdtype,unsigned char * hash)217 _libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen,
218 mbedtls_md_type_t mdtype, unsigned char *hash)
219 {
220 const mbedtls_md_info_t *md_info;
221 int ret;
222
223 md_info = mbedtls_md_info_from_type(mdtype);
224 if(!md_info)
225 return 0;
226
227 ret = mbedtls_md(md_info, data, datalen, hash);
228
229 return ret == 0 ? 0 : -1;
230 }
231
232 /*******************************************************************/
233 /*
234 * mbedTLS backend: BigNumber functions
235 */
236
237 _libssh2_bn *
_libssh2_mbedtls_bignum_init(void)238 _libssh2_mbedtls_bignum_init(void)
239 {
240 _libssh2_bn *bignum;
241
242 bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn));
243 if(bignum) {
244 mbedtls_mpi_init(bignum);
245 }
246
247 return bignum;
248 }
249
250 void
_libssh2_mbedtls_bignum_free(_libssh2_bn * bn)251 _libssh2_mbedtls_bignum_free(_libssh2_bn *bn)
252 {
253 if(bn) {
254 mbedtls_mpi_free(bn);
255 mbedtls_free(bn);
256 }
257 }
258
259 static int
_libssh2_mbedtls_bignum_random(_libssh2_bn * bn,int bits,int top,int bottom)260 _libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom)
261 {
262 size_t len;
263 int err;
264 int i;
265
266 if(!bn || bits <= 0)
267 return -1;
268
269 len = (bits + 7) >> 3;
270 err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random,
271 &_libssh2_mbedtls_ctr_drbg);
272 if(err)
273 return -1;
274
275 /* Zero unused bits above the most significant bit*/
276 for(i = len*8 - 1; bits <= i; --i) {
277 err = mbedtls_mpi_set_bit(bn, i, 0);
278 if(err)
279 return -1;
280 }
281
282 /* If `top` is -1, the most significant bit of the random number can be
283 zero. If top is 0, the most significant bit of the random number is
284 set to 1, and if top is 1, the two most significant bits of the number
285 will be set to 1, so that the product of two such random numbers will
286 always have 2*bits length.
287 */
288 for(i = 0; i <= top; ++i) {
289 err = mbedtls_mpi_set_bit(bn, bits-i-1, 1);
290 if(err)
291 return -1;
292 }
293
294 /* make odd by setting first bit in least significant byte */
295 if(bottom) {
296 err = mbedtls_mpi_set_bit(bn, 0, 1);
297 if(err)
298 return -1;
299 }
300
301 return 0;
302 }
303
304
305 /*******************************************************************/
306 /*
307 * mbedTLS backend: RSA functions
308 */
309
310 int
_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx ** rsa,const unsigned char * edata,unsigned long elen,const unsigned char * ndata,unsigned long nlen,const unsigned char * ddata,unsigned long dlen,const unsigned char * pdata,unsigned long plen,const unsigned char * qdata,unsigned long qlen,const unsigned char * e1data,unsigned long e1len,const unsigned char * e2data,unsigned long e2len,const unsigned char * coeffdata,unsigned long coefflen)311 _libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
312 const unsigned char *edata,
313 unsigned long elen,
314 const unsigned char *ndata,
315 unsigned long nlen,
316 const unsigned char *ddata,
317 unsigned long dlen,
318 const unsigned char *pdata,
319 unsigned long plen,
320 const unsigned char *qdata,
321 unsigned long qlen,
322 const unsigned char *e1data,
323 unsigned long e1len,
324 const unsigned char *e2data,
325 unsigned long e2len,
326 const unsigned char *coeffdata,
327 unsigned long coefflen)
328 {
329 int ret;
330 libssh2_rsa_ctx *ctx;
331
332 ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
333 if(ctx != NULL) {
334 mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0);
335 }
336 else
337 return -1;
338
339 /* !checksrc! disable ASSIGNWITHINCONDITION 1 */
340 if((ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 ||
341 (ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0) {
342 ret = -1;
343 }
344
345 if(!ret) {
346 ctx->len = mbedtls_mpi_size(&(ctx->N));
347 }
348
349 if(!ret && ddata) {
350 /* !checksrc! disable ASSIGNWITHINCONDITION 1 */
351 if((ret = mbedtls_mpi_read_binary(&(ctx->D), ddata, dlen) ) != 0 ||
352 (ret = mbedtls_mpi_read_binary(&(ctx->P), pdata, plen) ) != 0 ||
353 (ret = mbedtls_mpi_read_binary(&(ctx->Q), qdata, qlen) ) != 0 ||
354 (ret = mbedtls_mpi_read_binary(&(ctx->DP), e1data, e1len) ) != 0 ||
355 (ret = mbedtls_mpi_read_binary(&(ctx->DQ), e2data, e2len) ) != 0 ||
356 (ret = mbedtls_mpi_read_binary(&(ctx->QP), coeffdata, coefflen) )
357 != 0) {
358 ret = -1;
359 }
360 ret = mbedtls_rsa_check_privkey(ctx);
361 }
362 else if(!ret) {
363 ret = mbedtls_rsa_check_pubkey(ctx);
364 }
365
366 if(ret && ctx) {
367 _libssh2_mbedtls_rsa_free(ctx);
368 ctx = NULL;
369 }
370 *rsa = ctx;
371 return ret;
372 }
373
374 int
_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx ** rsa,LIBSSH2_SESSION * session,const char * filename,const unsigned char * passphrase)375 _libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
376 LIBSSH2_SESSION *session,
377 const char *filename,
378 const unsigned char *passphrase)
379 {
380 int ret;
381 mbedtls_pk_context pkey;
382 mbedtls_rsa_context *pk_rsa;
383
384 *rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx));
385 if(*rsa == NULL)
386 return -1;
387
388 mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0);
389 mbedtls_pk_init(&pkey);
390
391 ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase);
392 if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
393 mbedtls_pk_free(&pkey);
394 mbedtls_rsa_free(*rsa);
395 LIBSSH2_FREE(session, *rsa);
396 *rsa = NULL;
397 return -1;
398 }
399
400 pk_rsa = mbedtls_pk_rsa(pkey);
401 mbedtls_rsa_copy(*rsa, pk_rsa);
402 mbedtls_pk_free(&pkey);
403
404 return 0;
405 }
406
407 int
_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,LIBSSH2_SESSION * session,const char * filedata,size_t filedata_len,unsigned const char * passphrase)408 _libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
409 LIBSSH2_SESSION *session,
410 const char *filedata,
411 size_t filedata_len,
412 unsigned const char *passphrase)
413 {
414 int ret;
415 mbedtls_pk_context pkey;
416 mbedtls_rsa_context *pk_rsa;
417 void *filedata_nullterm;
418 size_t pwd_len;
419
420 *rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx));
421 if(*rsa == NULL)
422 return -1;
423
424 /*
425 mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'"
426 private-key from memory will fail if the last byte is not a null byte
427 */
428 filedata_nullterm = mbedtls_calloc(filedata_len + 1, 1);
429 if(filedata_nullterm == NULL) {
430 return -1;
431 }
432 memcpy(filedata_nullterm, filedata, filedata_len);
433
434 mbedtls_pk_init(&pkey);
435
436 pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0;
437 ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm,
438 filedata_len + 1,
439 passphrase, pwd_len);
440 _libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len);
441
442 if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) {
443 mbedtls_pk_free(&pkey);
444 mbedtls_rsa_free(*rsa);
445 LIBSSH2_FREE(session, *rsa);
446 *rsa = NULL;
447 return -1;
448 }
449
450 pk_rsa = mbedtls_pk_rsa(pkey);
451 mbedtls_rsa_copy(*rsa, pk_rsa);
452 mbedtls_pk_free(&pkey);
453
454 return 0;
455 }
456
457 int
_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx * rsa,const unsigned char * sig,unsigned long sig_len,const unsigned char * m,unsigned long m_len)458 _libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
459 const unsigned char *sig,
460 unsigned long sig_len,
461 const unsigned char *m,
462 unsigned long m_len)
463 {
464 unsigned char hash[SHA_DIGEST_LENGTH];
465 int ret;
466
467 ret = _libssh2_mbedtls_hash(m, m_len, MBEDTLS_MD_SHA1, hash);
468 if(ret)
469 return -1; /* failure */
470
471 ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC,
472 MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH,
473 hash, sig);
474
475 return (ret == 0) ? 0 : -1;
476 }
477
478 int
_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION * session,libssh2_rsa_ctx * rsa,const unsigned char * hash,size_t hash_len,unsigned char ** signature,size_t * signature_len)479 _libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session,
480 libssh2_rsa_ctx *rsa,
481 const unsigned char *hash,
482 size_t hash_len,
483 unsigned char **signature,
484 size_t *signature_len)
485 {
486 int ret;
487 unsigned char *sig;
488 unsigned int sig_len;
489
490 (void)hash_len;
491
492 sig_len = rsa->len;
493 sig = LIBSSH2_ALLOC(session, sig_len);
494 if(!sig) {
495 return -1;
496 }
497
498 ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE,
499 MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH,
500 hash, sig);
501 if(ret) {
502 LIBSSH2_FREE(session, sig);
503 return -1;
504 }
505
506 *signature = sig;
507 *signature_len = sig_len;
508
509 return (ret == 0) ? 0 : -1;
510 }
511
512 void
_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx * ctx)513 _libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *ctx)
514 {
515 mbedtls_rsa_free(ctx);
516 mbedtls_free(ctx);
517 }
518
519 static unsigned char *
gen_publickey_from_rsa(LIBSSH2_SESSION * session,mbedtls_rsa_context * rsa,size_t * keylen)520 gen_publickey_from_rsa(LIBSSH2_SESSION *session,
521 mbedtls_rsa_context *rsa,
522 size_t *keylen)
523 {
524 int e_bytes, n_bytes;
525 unsigned long len;
526 unsigned char *key;
527 unsigned char *p;
528
529 e_bytes = mbedtls_mpi_size(&rsa->E);
530 n_bytes = mbedtls_mpi_size(&rsa->N);
531
532 /* Key form is "ssh-rsa" + e + n. */
533 len = 4 + 7 + 4 + e_bytes + 4 + n_bytes;
534
535 key = LIBSSH2_ALLOC(session, len);
536 if(!key) {
537 return NULL;
538 }
539
540 /* Process key encoding. */
541 p = key;
542
543 _libssh2_htonu32(p, 7); /* Key type. */
544 p += 4;
545 memcpy(p, "ssh-rsa", 7);
546 p += 7;
547
548 _libssh2_htonu32(p, e_bytes);
549 p += 4;
550 mbedtls_mpi_write_binary(&rsa->E, p, e_bytes);
551
552 _libssh2_htonu32(p, n_bytes);
553 p += 4;
554 mbedtls_mpi_write_binary(&rsa->N, p, n_bytes);
555
556 *keylen = (size_t)(p - key);
557 return key;
558 }
559
560 static int
_libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION * session,unsigned char ** method,size_t * method_len,unsigned char ** pubkeydata,size_t * pubkeydata_len,mbedtls_pk_context * pkey)561 _libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION *session,
562 unsigned char **method,
563 size_t *method_len,
564 unsigned char **pubkeydata,
565 size_t *pubkeydata_len,
566 mbedtls_pk_context *pkey)
567 {
568 unsigned char *key = NULL, *mth = NULL;
569 size_t keylen = 0, mthlen = 0;
570 int ret;
571 mbedtls_rsa_context *rsa;
572
573 if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA) {
574 mbedtls_pk_free(pkey);
575 return _libssh2_error(session, LIBSSH2_ERROR_FILE,
576 "Key type not supported");
577 }
578
579 /* write method */
580 mthlen = 7;
581 mth = LIBSSH2_ALLOC(session, mthlen);
582 if(mth) {
583 memcpy(mth, "ssh-rsa", mthlen);
584 }
585 else {
586 ret = -1;
587 }
588
589 rsa = mbedtls_pk_rsa(*pkey);
590 key = gen_publickey_from_rsa(session, rsa, &keylen);
591 if(key == NULL) {
592 ret = -1;
593 }
594
595 /* write output */
596 if(ret) {
597 if(mth)
598 LIBSSH2_FREE(session, mth);
599 if(key)
600 LIBSSH2_FREE(session, key);
601 }
602 else {
603 *method = mth;
604 *method_len = mthlen;
605 *pubkeydata = key;
606 *pubkeydata_len = keylen;
607 }
608
609 return ret;
610 }
611
612 int
_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION * session,unsigned char ** method,size_t * method_len,unsigned char ** pubkeydata,size_t * pubkeydata_len,const char * privatekey,const char * passphrase)613 _libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session,
614 unsigned char **method,
615 size_t *method_len,
616 unsigned char **pubkeydata,
617 size_t *pubkeydata_len,
618 const char *privatekey,
619 const char *passphrase)
620 {
621 mbedtls_pk_context pkey;
622 char buf[1024];
623 int ret;
624
625 mbedtls_pk_init(&pkey);
626 ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase);
627 if(ret != 0) {
628 mbedtls_strerror(ret, (char *)buf, sizeof(buf));
629 mbedtls_pk_free(&pkey);
630 return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf);
631 }
632
633 ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len,
634 pubkeydata, pubkeydata_len, &pkey);
635
636 mbedtls_pk_free(&pkey);
637
638 return ret;
639 }
640
641 int
_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION * session,unsigned char ** method,size_t * method_len,unsigned char ** pubkeydata,size_t * pubkeydata_len,const char * privatekeydata,size_t privatekeydata_len,const char * passphrase)642 _libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
643 unsigned char **method,
644 size_t *method_len,
645 unsigned char **pubkeydata,
646 size_t *pubkeydata_len,
647 const char *privatekeydata,
648 size_t privatekeydata_len,
649 const char *passphrase)
650 {
651 mbedtls_pk_context pkey;
652 char buf[1024];
653 int ret;
654 void *privatekeydata_nullterm;
655 size_t pwd_len;
656
657 /*
658 mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'"
659 private-key from memory will fail if the last byte is not a null byte
660 */
661 privatekeydata_nullterm = mbedtls_calloc(privatekeydata_len + 1, 1);
662 if(privatekeydata_nullterm == NULL) {
663 return -1;
664 }
665 memcpy(privatekeydata_nullterm, privatekeydata, privatekeydata_len);
666
667 mbedtls_pk_init(&pkey);
668
669 pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0;
670 ret = mbedtls_pk_parse_key(&pkey,
671 (unsigned char *)privatekeydata_nullterm,
672 privatekeydata_len + 1,
673 (const unsigned char *)passphrase, pwd_len);
674 _libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len);
675
676 if(ret != 0) {
677 mbedtls_strerror(ret, (char *)buf, sizeof(buf));
678 mbedtls_pk_free(&pkey);
679 return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf);
680 }
681
682 ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len,
683 pubkeydata, pubkeydata_len, &pkey);
684
685 mbedtls_pk_free(&pkey);
686
687 return ret;
688 }
689
_libssh2_init_aes_ctr(void)690 void _libssh2_init_aes_ctr(void)
691 {
692 /* no implementation */
693 }
694
695
696 /*******************************************************************/
697 /*
698 * mbedTLS backend: Diffie-Hellman functions
699 */
700
701 void
_libssh2_dh_init(_libssh2_dh_ctx * dhctx)702 _libssh2_dh_init(_libssh2_dh_ctx *dhctx)
703 {
704 *dhctx = _libssh2_mbedtls_bignum_init(); /* Random from client */
705 }
706
707 int
_libssh2_dh_key_pair(_libssh2_dh_ctx * dhctx,_libssh2_bn * public,_libssh2_bn * g,_libssh2_bn * p,int group_order)708 _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
709 _libssh2_bn *g, _libssh2_bn *p, int group_order)
710 {
711 /* Generate x and e */
712 _libssh2_mbedtls_bignum_random(*dhctx, group_order * 8 - 1, 0, -1);
713 mbedtls_mpi_exp_mod(public, g, *dhctx, p, NULL);
714 return 0;
715 }
716
717 int
_libssh2_dh_secret(_libssh2_dh_ctx * dhctx,_libssh2_bn * secret,_libssh2_bn * f,_libssh2_bn * p)718 _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
719 _libssh2_bn *f, _libssh2_bn *p)
720 {
721 /* Compute the shared secret */
722 mbedtls_mpi_exp_mod(secret, f, *dhctx, p, NULL);
723 return 0;
724 }
725
726 void
_libssh2_dh_dtor(_libssh2_dh_ctx * dhctx)727 _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
728 {
729 _libssh2_mbedtls_bignum_free(*dhctx);
730 *dhctx = NULL;
731 }
732
733 #if LIBSSH2_ECDSA
734
735 /*******************************************************************/
736 /*
737 * mbedTLS backend: ECDSA functions
738 */
739
740 /*
741 * _libssh2_ecdsa_create_key
742 *
743 * Creates a local private key based on input curve
744 * and returns octal value and octal length
745 *
746 */
747
748 int
_libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION * session,_libssh2_ec_key ** privkey,unsigned char ** pubkey_oct,size_t * pubkey_oct_len,libssh2_curve_type curve)749 _libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session,
750 _libssh2_ec_key **privkey,
751 unsigned char **pubkey_oct,
752 size_t *pubkey_oct_len,
753 libssh2_curve_type curve)
754 {
755 size_t plen = 0;
756
757 *privkey = LIBSSH2_ALLOC(session, sizeof(mbedtls_ecp_keypair));
758
759 if(*privkey == NULL)
760 goto failed;
761
762 mbedtls_ecdsa_init(*privkey);
763
764 if(mbedtls_ecdsa_genkey(*privkey, (mbedtls_ecp_group_id)curve,
765 mbedtls_ctr_drbg_random,
766 &_libssh2_mbedtls_ctr_drbg) != 0)
767 goto failed;
768
769 plen = 2 * mbedtls_mpi_size(&(*privkey)->grp.P) + 1;
770 *pubkey_oct = LIBSSH2_ALLOC(session, plen);
771
772 if(*pubkey_oct == NULL)
773 goto failed;
774
775 if(mbedtls_ecp_point_write_binary(&(*privkey)->grp, &(*privkey)->Q,
776 MBEDTLS_ECP_PF_UNCOMPRESSED,
777 pubkey_oct_len, *pubkey_oct, plen) == 0)
778 return 0;
779
780 failed:
781
782 _libssh2_mbedtls_ecdsa_free(*privkey);
783 _libssh2_mbedtls_safe_free(*pubkey_oct, plen);
784 *privkey = NULL;
785
786 return -1;
787 }
788
789 /* _libssh2_ecdsa_curve_name_with_octal_new
790 *
791 * Creates a new public key given an octal string, length and type
792 *
793 */
794
795 int
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ctx,const unsigned char * k,size_t k_len,libssh2_curve_type curve)796 _libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx,
797 const unsigned char *k,
798 size_t k_len,
799 libssh2_curve_type curve)
800 {
801 *ctx = mbedtls_calloc(1, sizeof(mbedtls_ecp_keypair));
802
803 if(*ctx == NULL)
804 goto failed;
805
806 mbedtls_ecdsa_init(*ctx);
807
808 if(mbedtls_ecp_group_load(&(*ctx)->grp, (mbedtls_ecp_group_id)curve) != 0)
809 goto failed;
810
811 if(mbedtls_ecp_point_read_binary(&(*ctx)->grp, &(*ctx)->Q, k, k_len) != 0)
812 goto failed;
813
814 if(mbedtls_ecp_check_pubkey(&(*ctx)->grp, &(*ctx)->Q) == 0)
815 return 0;
816
817 failed:
818
819 _libssh2_mbedtls_ecdsa_free(*ctx);
820 *ctx = NULL;
821
822 return -1;
823 }
824
825 /* _libssh2_ecdh_gen_k
826 *
827 * Computes the shared secret K given a local private key,
828 * remote public key and length
829 */
830
831 int
_libssh2_mbedtls_ecdh_gen_k(_libssh2_bn ** k,_libssh2_ec_key * privkey,const unsigned char * server_pubkey,size_t server_pubkey_len)832 _libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k,
833 _libssh2_ec_key *privkey,
834 const unsigned char *server_pubkey,
835 size_t server_pubkey_len)
836 {
837 mbedtls_ecp_point pubkey;
838 int rc = 0;
839
840 if(*k == NULL)
841 return -1;
842
843 mbedtls_ecp_point_init(&pubkey);
844
845 if(mbedtls_ecp_point_read_binary(&privkey->grp, &pubkey,
846 server_pubkey, server_pubkey_len) != 0) {
847 rc = -1;
848 goto cleanup;
849 }
850
851 if(mbedtls_ecdh_compute_shared(&privkey->grp, *k,
852 &pubkey, &privkey->d,
853 mbedtls_ctr_drbg_random,
854 &_libssh2_mbedtls_ctr_drbg) != 0) {
855 rc = -1;
856 goto cleanup;
857 }
858
859 if(mbedtls_ecp_check_privkey(&privkey->grp, *k) != 0)
860 rc = -1;
861
862 cleanup:
863
864 mbedtls_ecp_point_free(&pubkey);
865
866 return rc;
867 }
868
869 #define LIBSSH2_MBEDTLS_ECDSA_VERIFY(digest_type) \
870 { \
871 unsigned char hsh[SHA##digest_type##_DIGEST_LENGTH]; \
872 \
873 if(libssh2_sha##digest_type(m, m_len, hsh) == 0) { \
874 rc = mbedtls_ecdsa_verify(&ctx->grp, hsh, \
875 SHA##digest_type##_DIGEST_LENGTH, \
876 &ctx->Q, &pr, &ps); \
877 } \
878 \
879 }
880
881 /* _libssh2_ecdsa_sign
882 *
883 * Verifies the ECDSA signature of a hashed message
884 *
885 */
886
887 int
_libssh2_mbedtls_ecdsa_verify(libssh2_ecdsa_ctx * ctx,const unsigned char * r,size_t r_len,const unsigned char * s,size_t s_len,const unsigned char * m,size_t m_len)888 _libssh2_mbedtls_ecdsa_verify(libssh2_ecdsa_ctx *ctx,
889 const unsigned char *r, size_t r_len,
890 const unsigned char *s, size_t s_len,
891 const unsigned char *m, size_t m_len)
892 {
893 mbedtls_mpi pr, ps;
894 int rc = -1;
895
896 mbedtls_mpi_init(&pr);
897 mbedtls_mpi_init(&ps);
898
899 if(mbedtls_mpi_read_binary(&pr, r, r_len) != 0)
900 goto cleanup;
901
902 if(mbedtls_mpi_read_binary(&ps, s, s_len) != 0)
903 goto cleanup;
904
905 switch(_libssh2_ecdsa_get_curve_type(ctx)) {
906 case LIBSSH2_EC_CURVE_NISTP256:
907 LIBSSH2_MBEDTLS_ECDSA_VERIFY(256);
908 break;
909 case LIBSSH2_EC_CURVE_NISTP384:
910 LIBSSH2_MBEDTLS_ECDSA_VERIFY(384);
911 break;
912 case LIBSSH2_EC_CURVE_NISTP521:
913 LIBSSH2_MBEDTLS_ECDSA_VERIFY(512);
914 break;
915 default:
916 rc = -1;
917 }
918
919 cleanup:
920
921 mbedtls_mpi_free(&pr);
922 mbedtls_mpi_free(&ps);
923
924 return (rc == 0) ? 0 : -1;
925 }
926
927 static int
_libssh2_mbedtls_parse_eckey(libssh2_ecdsa_ctx ** ctx,mbedtls_pk_context * pkey,LIBSSH2_SESSION * session,const unsigned char * data,size_t data_len,const unsigned char * pwd)928 _libssh2_mbedtls_parse_eckey(libssh2_ecdsa_ctx **ctx,
929 mbedtls_pk_context *pkey,
930 LIBSSH2_SESSION *session,
931 const unsigned char *data,
932 size_t data_len,
933 const unsigned char *pwd)
934 {
935 size_t pwd_len;
936
937 pwd_len = pwd ? strlen((const char *) pwd) : 0;
938
939 if(mbedtls_pk_parse_key(pkey, data, data_len, pwd, pwd_len) != 0)
940 goto failed;
941
942 if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_ECKEY)
943 goto failed;
944
945 *ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx));
946
947 if(*ctx == NULL)
948 goto failed;
949
950 mbedtls_ecdsa_init(*ctx);
951
952 if(mbedtls_ecdsa_from_keypair(*ctx, mbedtls_pk_ec(*pkey)) == 0)
953 return 0;
954
955 failed:
956
957 _libssh2_mbedtls_ecdsa_free(*ctx);
958 *ctx = NULL;
959
960 return -1;
961 }
962
963 static int
_libssh2_mbedtls_parse_openssh_key(libssh2_ecdsa_ctx ** ctx,LIBSSH2_SESSION * session,const unsigned char * data,size_t data_len,const unsigned char * pwd)964 _libssh2_mbedtls_parse_openssh_key(libssh2_ecdsa_ctx **ctx,
965 LIBSSH2_SESSION *session,
966 const unsigned char *data,
967 size_t data_len,
968 const unsigned char *pwd)
969 {
970 libssh2_curve_type type;
971 unsigned char *name = NULL;
972 struct string_buf *decrypted = NULL;
973 size_t curvelen, exponentlen, pointlen;
974 unsigned char *curve, *exponent, *point_buf;
975
976 if(_libssh2_openssh_pem_parse_memory(session, pwd,
977 (const char *)data, data_len,
978 &decrypted) != 0)
979 goto failed;
980
981 if(_libssh2_get_string(decrypted, &name, NULL) != 0)
982 goto failed;
983
984 if(_libssh2_mbedtls_ecdsa_curve_type_from_name((const char *)name,
985 &type) != 0)
986 goto failed;
987
988 if(_libssh2_get_string(decrypted, &curve, &curvelen) != 0)
989 goto failed;
990
991 if(_libssh2_get_string(decrypted, &point_buf, &pointlen) != 0)
992 goto failed;
993
994 if(_libssh2_get_bignum_bytes(decrypted, &exponent, &exponentlen) != 0)
995 goto failed;
996
997 *ctx = LIBSSH2_ALLOC(session, sizeof(libssh2_ecdsa_ctx));
998
999 if(*ctx == NULL)
1000 goto failed;
1001
1002 mbedtls_ecdsa_init(*ctx);
1003
1004 if(mbedtls_ecp_group_load(&(*ctx)->grp, (mbedtls_ecp_group_id)type) != 0)
1005 goto failed;
1006
1007 if(mbedtls_mpi_read_binary(&(*ctx)->d, exponent, exponentlen) != 0)
1008 goto failed;
1009
1010 if(mbedtls_ecp_mul(&(*ctx)->grp, &(*ctx)->Q,
1011 &(*ctx)->d, &(*ctx)->grp.G,
1012 mbedtls_ctr_drbg_random,
1013 &_libssh2_mbedtls_ctr_drbg) != 0)
1014 goto failed;
1015
1016 if(mbedtls_ecp_check_privkey(&(*ctx)->grp, &(*ctx)->d) == 0)
1017 goto cleanup;
1018
1019 failed:
1020
1021 _libssh2_mbedtls_ecdsa_free(*ctx);
1022 *ctx = NULL;
1023
1024 cleanup:
1025
1026 if(decrypted) {
1027 _libssh2_string_buf_free(session, decrypted);
1028 }
1029
1030 return (*ctx == NULL) ? -1 : 0;
1031 }
1032
1033 /* _libssh2_ecdsa_new_private
1034 *
1035 * Creates a new private key given a file path and password
1036 *
1037 */
1038
1039 int
_libssh2_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx ** ctx,LIBSSH2_SESSION * session,const char * filename,const unsigned char * pwd)1040 _libssh2_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx **ctx,
1041 LIBSSH2_SESSION *session,
1042 const char *filename,
1043 const unsigned char *pwd)
1044 {
1045 mbedtls_pk_context pkey;
1046 unsigned char *data;
1047 size_t data_len;
1048
1049 if(mbedtls_pk_load_file(filename, &data, &data_len) != 0)
1050 goto cleanup;
1051
1052 mbedtls_pk_init(&pkey);
1053
1054 if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session,
1055 data, data_len, pwd) == 0)
1056 goto cleanup;
1057
1058 _libssh2_mbedtls_parse_openssh_key(ctx, session, data, data_len, pwd);
1059
1060 cleanup:
1061
1062 mbedtls_pk_free(&pkey);
1063
1064 _libssh2_mbedtls_safe_free(data, data_len);
1065
1066 return (*ctx == NULL) ? -1 : 0;
1067 }
1068
1069 /* _libssh2_ecdsa_new_private
1070 *
1071 * Creates a new private key given a file data and password
1072 *
1073 */
1074
1075 int
_libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ctx,LIBSSH2_SESSION * session,const char * data,size_t data_len,const unsigned char * pwd)1076 _libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx **ctx,
1077 LIBSSH2_SESSION *session,
1078 const char *data,
1079 size_t data_len,
1080 const unsigned char *pwd)
1081 {
1082 unsigned char *ntdata;
1083 mbedtls_pk_context pkey;
1084
1085 mbedtls_pk_init(&pkey);
1086
1087 ntdata = LIBSSH2_ALLOC(session, data_len + 1);
1088
1089 if(ntdata == NULL)
1090 goto cleanup;
1091
1092 memcpy(ntdata, data, data_len);
1093
1094 if(_libssh2_mbedtls_parse_eckey(ctx, &pkey, session,
1095 ntdata, data_len + 1, pwd) == 0)
1096 goto cleanup;
1097
1098 _libssh2_mbedtls_parse_openssh_key(ctx, session,
1099 ntdata, data_len + 1, pwd);
1100
1101 cleanup:
1102
1103 mbedtls_pk_free(&pkey);
1104
1105 _libssh2_mbedtls_safe_free(ntdata, data_len);
1106
1107 return (*ctx == NULL) ? -1 : 0;
1108 }
1109
1110 static unsigned char *
_libssh2_mbedtls_mpi_write_binary(unsigned char * buf,const mbedtls_mpi * mpi,size_t bytes)1111 _libssh2_mbedtls_mpi_write_binary(unsigned char *buf,
1112 const mbedtls_mpi *mpi,
1113 size_t bytes)
1114 {
1115 unsigned char *p = buf;
1116
1117 if(sizeof(&p) / sizeof(p[0]) < 4) {
1118 goto done;
1119 }
1120
1121 p += 4;
1122 *p = 0;
1123
1124 if(bytes > 0) {
1125 mbedtls_mpi_write_binary(mpi, p + 1, bytes - 1);
1126 }
1127
1128 if(bytes > 0 && !(*(p + 1) & 0x80)) {
1129 memmove(p, p + 1, --bytes);
1130 }
1131
1132 _libssh2_htonu32(p - 4, bytes);
1133
1134 done:
1135
1136 return p + bytes;
1137 }
1138
1139 /* _libssh2_ecdsa_sign
1140 *
1141 * Computes the ECDSA signature of a previously-hashed message
1142 *
1143 */
1144
1145 int
_libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION * session,libssh2_ecdsa_ctx * ctx,const unsigned char * hash,unsigned long hash_len,unsigned char ** sign,size_t * sign_len)1146 _libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session,
1147 libssh2_ecdsa_ctx *ctx,
1148 const unsigned char *hash,
1149 unsigned long hash_len,
1150 unsigned char **sign,
1151 size_t *sign_len)
1152 {
1153 size_t r_len, s_len, tmp_sign_len = 0;
1154 unsigned char *sp, *tmp_sign = NULL;
1155 mbedtls_mpi pr, ps;
1156
1157 mbedtls_mpi_init(&pr);
1158 mbedtls_mpi_init(&ps);
1159
1160 if(mbedtls_ecdsa_sign(&ctx->grp, &pr, &ps, &ctx->d,
1161 hash, hash_len,
1162 mbedtls_ctr_drbg_random,
1163 &_libssh2_mbedtls_ctr_drbg) != 0)
1164 goto cleanup;
1165
1166 r_len = mbedtls_mpi_size(&pr) + 1;
1167 s_len = mbedtls_mpi_size(&ps) + 1;
1168 tmp_sign_len = r_len + s_len + 8;
1169
1170 tmp_sign = LIBSSH2_CALLOC(session, tmp_sign_len);
1171
1172 if(tmp_sign == NULL)
1173 goto cleanup;
1174
1175 sp = tmp_sign;
1176 sp = _libssh2_mbedtls_mpi_write_binary(sp, &pr, r_len);
1177 sp = _libssh2_mbedtls_mpi_write_binary(sp, &ps, s_len);
1178
1179 *sign_len = (size_t)(sp - tmp_sign);
1180
1181 *sign = LIBSSH2_CALLOC(session, *sign_len);
1182
1183 if(*sign == NULL)
1184 goto cleanup;
1185
1186 memcpy(*sign, tmp_sign, *sign_len);
1187
1188 cleanup:
1189
1190 mbedtls_mpi_free(&pr);
1191 mbedtls_mpi_free(&ps);
1192
1193 _libssh2_mbedtls_safe_free(tmp_sign, tmp_sign_len);
1194
1195 return (*sign == NULL) ? -1 : 0;
1196 }
1197
1198 /* _libssh2_ecdsa_get_curve_type
1199 *
1200 * returns key curve type that maps to libssh2_curve_type
1201 *
1202 */
1203
1204 libssh2_curve_type
_libssh2_mbedtls_ecdsa_get_curve_type(libssh2_ecdsa_ctx * ctx)1205 _libssh2_mbedtls_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ctx)
1206 {
1207 return (libssh2_curve_type) ctx->grp.id;
1208 }
1209
1210 /* _libssh2_ecdsa_curve_type_from_name
1211 *
1212 * returns 0 for success, key curve type that maps to libssh2_curve_type
1213 *
1214 */
1215
1216 int
_libssh2_mbedtls_ecdsa_curve_type_from_name(const char * name,libssh2_curve_type * out_type)1217 _libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name,
1218 libssh2_curve_type *out_type)
1219 {
1220 int ret = 0;
1221 libssh2_curve_type type;
1222
1223 if(name == NULL || strlen(name) != 19)
1224 return -1;
1225
1226 if(strcmp(name, "ecdsa-sha2-nistp256") == 0)
1227 type = LIBSSH2_EC_CURVE_NISTP256;
1228 else if(strcmp(name, "ecdsa-sha2-nistp384") == 0)
1229 type = LIBSSH2_EC_CURVE_NISTP384;
1230 else if(strcmp(name, "ecdsa-sha2-nistp521") == 0)
1231 type = LIBSSH2_EC_CURVE_NISTP521;
1232 else {
1233 ret = -1;
1234 }
1235
1236 if(ret == 0 && out_type) {
1237 *out_type = type;
1238 }
1239
1240 return ret;
1241 }
1242
1243 void
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx * ctx)1244 _libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx)
1245 {
1246 mbedtls_ecdsa_free(ctx);
1247 mbedtls_free(ctx);
1248 }
1249
1250 #endif /* LIBSSH2_ECDSA */
1251 #endif /* LIBSSH2_MBEDTLS */
1252