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