123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 |
- #include "includes.h"
- #include "dbutil.h"
- #include "bignum.h"
- #include "rsa.h"
- #include "buffer.h"
- #include "ssh.h"
- #include "dbrandom.h"
- #ifdef DROPBEAR_RSA
- static void rsa_pad_em(dropbear_rsa_key * key,
- buffer *data_buf, mp_int * rsa_em);
- int buf_get_rsa_pub_key(buffer* buf, dropbear_rsa_key *key) {
- int ret = DROPBEAR_FAILURE;
- TRACE(("enter buf_get_rsa_pub_key"))
- dropbear_assert(key != NULL);
- m_mp_alloc_init_multi(&key->e, &key->n, NULL);
- key->d = NULL;
- key->p = NULL;
- key->q = NULL;
- buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN);
- if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE
- || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) {
- TRACE(("leave buf_get_rsa_pub_key: failure"))
- goto out;
- }
- if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) {
- dropbear_log(LOG_WARNING, "RSA key too short");
- goto out;
- }
- TRACE(("leave buf_get_rsa_pub_key: success"))
- ret = DROPBEAR_SUCCESS;
- out:
- if (ret == DROPBEAR_FAILURE) {
- m_free(key->e);
- m_free(key->n);
- }
- return ret;
- }
- int buf_get_rsa_priv_key(buffer* buf, dropbear_rsa_key *key) {
- int ret = DROPBEAR_FAILURE;
- TRACE(("enter buf_get_rsa_priv_key"))
- dropbear_assert(key != NULL);
- if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) {
- TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE"))
- return DROPBEAR_FAILURE;
- }
-
- key->d = NULL;
- key->p = NULL;
- key->q = NULL;
- m_mp_alloc_init_multi(&key->d, NULL);
- if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) {
- TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE"))
- goto out;
- }
- if (buf->pos == buf->len) {
-
- } else {
- m_mp_alloc_init_multi(&key->p, &key->q, NULL);
- if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) {
- TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE"))
- goto out;
- }
- if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) {
- TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE"))
- goto out;
- }
- }
- ret = DROPBEAR_SUCCESS;
- out:
- if (ret == DROPBEAR_FAILURE) {
- m_free(key->d);
- m_free(key->p);
- m_free(key->q);
- }
- TRACE(("leave buf_get_rsa_priv_key"))
- return ret;
- }
-
- void rsa_key_free(dropbear_rsa_key *key) {
- TRACE2(("enter rsa_key_free"))
- if (key == NULL) {
- TRACE2(("leave rsa_key_free: key == NULL"))
- return;
- }
- if (key->d) {
- mp_clear(key->d);
- m_free(key->d);
- }
- if (key->e) {
- mp_clear(key->e);
- m_free(key->e);
- }
- if (key->n) {
- mp_clear(key->n);
- m_free(key->n);
- }
- if (key->p) {
- mp_clear(key->p);
- m_free(key->p);
- }
- if (key->q) {
- mp_clear(key->q);
- m_free(key->q);
- }
- m_free(key);
- TRACE2(("leave rsa_key_free"))
- }
- void buf_put_rsa_pub_key(buffer* buf, dropbear_rsa_key *key) {
- TRACE(("enter buf_put_rsa_pub_key"))
- dropbear_assert(key != NULL);
- buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
- buf_putmpint(buf, key->e);
- buf_putmpint(buf, key->n);
- TRACE(("leave buf_put_rsa_pub_key"))
- }
- void buf_put_rsa_priv_key(buffer* buf, dropbear_rsa_key *key) {
- TRACE(("enter buf_put_rsa_priv_key"))
- dropbear_assert(key != NULL);
- buf_put_rsa_pub_key(buf, key);
- buf_putmpint(buf, key->d);
-
- if (key->p) {
- buf_putmpint(buf, key->p);
- }
- if (key->q) {
- buf_putmpint(buf, key->q);
- }
- TRACE(("leave buf_put_rsa_priv_key"))
- }
- #ifdef DROPBEAR_SIGNKEY_VERIFY
- int buf_rsa_verify(buffer * buf, dropbear_rsa_key *key, buffer *data_buf) {
- unsigned int slen;
- DEF_MP_INT(rsa_s);
- DEF_MP_INT(rsa_mdash);
- DEF_MP_INT(rsa_em);
- int ret = DROPBEAR_FAILURE;
- TRACE(("enter buf_rsa_verify"))
- dropbear_assert(key != NULL);
- m_mp_init_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL);
- slen = buf_getint(buf);
- if (slen != (unsigned int)mp_unsigned_bin_size(key->n)) {
- TRACE(("bad size"))
- goto out;
- }
- if (mp_read_unsigned_bin(&rsa_s, buf_getptr(buf, buf->len - buf->pos),
- buf->len - buf->pos) != MP_OKAY) {
- TRACE(("failed reading rsa_s"))
- goto out;
- }
-
- if (mp_cmp(&rsa_s, key->n) != MP_LT) {
- TRACE(("s > n-1"))
- goto out;
- }
-
- rsa_pad_em(key, data_buf, &rsa_em);
- if (mp_exptmod(&rsa_s, key->e, key->n, &rsa_mdash) != MP_OKAY) {
- TRACE(("failed exptmod rsa_s"))
- goto out;
- }
- if (mp_cmp(&rsa_em, &rsa_mdash) == MP_EQ) {
-
- TRACE(("success!"))
- ret = DROPBEAR_SUCCESS;
- }
- out:
- mp_clear_multi(&rsa_mdash, &rsa_s, &rsa_em, NULL);
- TRACE(("leave buf_rsa_verify: ret %d", ret))
- return ret;
- }
- #endif
- void buf_put_rsa_sign(buffer* buf, dropbear_rsa_key *key, buffer *data_buf) {
- unsigned int nsize, ssize;
- unsigned int i;
- DEF_MP_INT(rsa_s);
- DEF_MP_INT(rsa_tmp1);
- DEF_MP_INT(rsa_tmp2);
- DEF_MP_INT(rsa_tmp3);
-
- TRACE(("enter buf_put_rsa_sign"))
- dropbear_assert(key != NULL);
- m_mp_init_multi(&rsa_s, &rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
- rsa_pad_em(key, data_buf, &rsa_tmp1);
-
- #ifdef RSA_BLINDING
-
-
-
- gen_random_mpint(key->n, &rsa_tmp2);
-
-
-
- if (mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s) != MP_OKAY) {
- dropbear_exit("RSA error");
- }
- if (mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3) != MP_OKAY) {
- dropbear_exit("RSA error");
- }
- if (mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2) != MP_OKAY) {
- dropbear_exit("RSA error");
- }
-
-
- if (mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1) != MP_OKAY) {
- dropbear_exit("RSA error");
- }
-
-
-
- if (mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s) != MP_OKAY) {
- dropbear_exit("RSA error");
- }
- #else
-
-
- if (mp_exptmod(&rsa_tmp1, key->d, key->n, &rsa_s) != MP_OKAY) {
- dropbear_exit("RSA error");
- }
- #endif
- mp_clear_multi(&rsa_tmp1, &rsa_tmp2, &rsa_tmp3, NULL);
-
-
- buf_putstring(buf, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN);
- nsize = mp_unsigned_bin_size(key->n);
-
- buf_putint(buf, nsize);
-
- ssize = mp_unsigned_bin_size(&rsa_s);
- dropbear_assert(ssize <= nsize);
- for (i = 0; i < nsize-ssize; i++) {
- buf_putbyte(buf, 0x00);
- }
- if (mp_to_unsigned_bin(&rsa_s, buf_getwriteptr(buf, ssize)) != MP_OKAY) {
- dropbear_exit("RSA error");
- }
- buf_incrwritepos(buf, ssize);
- mp_clear(&rsa_s);
- #if defined(DEBUG_RSA) && defined(DEBUG_TRACE)
- if (!debug_trace) {
- printhex("RSA sig", buf->data, buf->len);
- }
- #endif
-
- TRACE(("leave buf_put_rsa_sign"))
- }
- static void rsa_pad_em(dropbear_rsa_key * key,
- buffer *data_buf, mp_int * rsa_em) {
-
- const unsigned char rsa_asn1_magic[] =
- {0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b,
- 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
- const unsigned int RSA_ASN1_MAGIC_LEN = 16;
- buffer * rsa_EM = NULL;
- hash_state hs;
- unsigned int nsize;
-
- dropbear_assert(key != NULL);
- nsize = mp_unsigned_bin_size(key->n);
- rsa_EM = buf_new(nsize-1);
-
- buf_putbyte(rsa_EM, 0x01);
-
- while(rsa_EM->pos != rsa_EM->size - RSA_ASN1_MAGIC_LEN - SHA1_HASH_SIZE) {
- buf_putbyte(rsa_EM, 0xff);
- }
-
- memcpy(buf_getwriteptr(rsa_EM, RSA_ASN1_MAGIC_LEN),
- rsa_asn1_magic, RSA_ASN1_MAGIC_LEN);
- buf_incrwritepos(rsa_EM, RSA_ASN1_MAGIC_LEN);
-
- sha1_init(&hs);
- sha1_process(&hs, data_buf->data, data_buf->len);
- sha1_done(&hs, buf_getwriteptr(rsa_EM, SHA1_HASH_SIZE));
- buf_incrwritepos(rsa_EM, SHA1_HASH_SIZE);
- dropbear_assert(rsa_EM->pos == rsa_EM->size);
-
- buf_setpos(rsa_EM, 0);
- bytes_to_mp(rsa_em, buf_getptr(rsa_EM, rsa_EM->size),
- rsa_EM->size);
- buf_free(rsa_EM);
- }
- #endif
|