Mercurial > dropbear
comparison rsa.c @ 398:59c7938af2bd
merge of '1250b8af44b62d8f4fe0f8d9fc7e7a1cc34e7e1c'
and '7f8670ac3bb975f40967f3979d09d2199b7e90c8'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 03 Feb 2007 08:20:30 +0000 |
parents | a124aff0cbf1 |
children | b50f0107e505 76097ec1a29a |
comparison
equal
deleted
inserted
replaced
396:e7c1a77d2921 | 398:59c7938af2bd |
---|---|
46 * The key will have the same format as buf_put_rsa_key. | 46 * The key will have the same format as buf_put_rsa_key. |
47 * These should be freed with rsa_key_free. | 47 * These should be freed with rsa_key_free. |
48 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 48 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
49 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { | 49 int buf_get_rsa_pub_key(buffer* buf, rsa_key *key) { |
50 | 50 |
51 int ret = DROPBEAR_FAILURE; | |
51 TRACE(("enter buf_get_rsa_pub_key")) | 52 TRACE(("enter buf_get_rsa_pub_key")) |
52 dropbear_assert(key != NULL); | 53 dropbear_assert(key != NULL); |
53 key->e = m_malloc(sizeof(mp_int)); | 54 key->e = m_malloc(sizeof(mp_int)); |
54 key->n = m_malloc(sizeof(mp_int)); | 55 key->n = m_malloc(sizeof(mp_int)); |
55 m_mp_init_multi(key->e, key->n, NULL); | 56 m_mp_init_multi(key->e, key->n, NULL); |
60 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */ | 61 buf_incrpos(buf, 4+SSH_SIGNKEY_RSA_LEN); /* int + "ssh-rsa" */ |
61 | 62 |
62 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE | 63 if (buf_getmpint(buf, key->e) == DROPBEAR_FAILURE |
63 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { | 64 || buf_getmpint(buf, key->n) == DROPBEAR_FAILURE) { |
64 TRACE(("leave buf_get_rsa_pub_key: failure")) | 65 TRACE(("leave buf_get_rsa_pub_key: failure")) |
65 return DROPBEAR_FAILURE; | 66 goto out; |
66 } | 67 } |
67 | 68 |
68 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) { | 69 if (mp_count_bits(key->n) < MIN_RSA_KEYLEN) { |
69 dropbear_log(LOG_WARNING, "rsa key too short"); | 70 dropbear_log(LOG_WARNING, "rsa key too short"); |
70 return DROPBEAR_FAILURE; | 71 goto out; |
71 } | 72 } |
72 | 73 |
73 TRACE(("leave buf_get_rsa_pub_key: success")) | 74 TRACE(("leave buf_get_rsa_pub_key: success")) |
74 return DROPBEAR_SUCCESS; | 75 ret = DROPBEAR_SUCCESS; |
75 | 76 out: |
76 } | 77 if (ret == DROPBEAR_FAILURE) { |
77 | 78 m_free(key->e); |
78 /* Same as buf_get_rsa_pub_key, but reads a private "x" key at the end. | 79 m_free(key->n); |
80 } | |
81 return ret; | |
82 } | |
83 | |
84 /* Same as buf_get_rsa_pub_key, but reads private bits at the end. | |
79 * Loads a private rsa key from a buffer | 85 * Loads a private rsa key from a buffer |
80 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ | 86 * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ |
81 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { | 87 int buf_get_rsa_priv_key(buffer* buf, rsa_key *key) { |
82 | 88 int ret = DROPBEAR_FAILURE; |
83 dropbear_assert(key != NULL); | |
84 | 89 |
85 TRACE(("enter buf_get_rsa_priv_key")) | 90 TRACE(("enter buf_get_rsa_priv_key")) |
91 dropbear_assert(key != NULL); | |
86 | 92 |
87 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { | 93 if (buf_get_rsa_pub_key(buf, key) == DROPBEAR_FAILURE) { |
88 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")) | 94 TRACE(("leave buf_get_rsa_priv_key: pub: ret == DROPBEAR_FAILURE")) |
89 return DROPBEAR_FAILURE; | 95 return DROPBEAR_FAILURE; |
90 } | 96 } |
97 | |
98 key->d = NULL; | |
99 key->p = NULL; | |
100 key->q = NULL; | |
91 | 101 |
92 key->d = m_malloc(sizeof(mp_int)); | 102 key->d = m_malloc(sizeof(mp_int)); |
93 m_mp_init(key->d); | 103 m_mp_init(key->d); |
94 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { | 104 if (buf_getmpint(buf, key->d) == DROPBEAR_FAILURE) { |
95 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")) | 105 TRACE(("leave buf_get_rsa_priv_key: d: ret == DROPBEAR_FAILURE")) |
96 return DROPBEAR_FAILURE; | 106 goto out; |
97 } | 107 } |
98 | 108 |
99 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/ | |
100 if (buf->pos == buf->len) { | 109 if (buf->pos == buf->len) { |
101 key->p = NULL; | 110 /* old Dropbear private keys didn't keep p and q, so we will ignore them*/ |
102 key->q = NULL; | |
103 } else { | 111 } else { |
104 key->p = m_malloc(sizeof(mp_int)); | 112 key->p = m_malloc(sizeof(mp_int)); |
105 key->q = m_malloc(sizeof(mp_int)); | 113 key->q = m_malloc(sizeof(mp_int)); |
106 m_mp_init_multi(key->p, key->q, NULL); | 114 m_mp_init_multi(key->p, key->q, NULL); |
107 | 115 |
108 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { | 116 if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE) { |
109 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")) | 117 TRACE(("leave buf_get_rsa_priv_key: p: ret == DROPBEAR_FAILURE")) |
110 return DROPBEAR_FAILURE; | 118 goto out; |
111 } | 119 } |
112 | 120 |
113 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { | 121 if (buf_getmpint(buf, key->q) == DROPBEAR_FAILURE) { |
114 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")) | 122 TRACE(("leave buf_get_rsa_priv_key: q: ret == DROPBEAR_FAILURE")) |
115 return DROPBEAR_FAILURE; | 123 goto out; |
116 } | 124 } |
117 } | 125 } |
118 | 126 |
127 ret = DROPBEAR_SUCCESS; | |
128 out: | |
129 if (ret == DROPBEAR_FAILURE) { | |
130 m_free(key->d); | |
131 m_free(key->p); | |
132 m_free(key->q); | |
133 } | |
119 TRACE(("leave buf_get_rsa_priv_key")) | 134 TRACE(("leave buf_get_rsa_priv_key")) |
120 return DROPBEAR_SUCCESS; | 135 return ret; |
121 } | 136 } |
122 | 137 |
123 | 138 |
124 /* Clear and free the memory used by a public or private key */ | 139 /* Clear and free the memory used by a public or private key */ |
125 void rsa_key_free(rsa_key *key) { | 140 void rsa_key_free(rsa_key *key) { |
283 gen_random_mpint(key->n, &rsa_tmp2); | 298 gen_random_mpint(key->n, &rsa_tmp2); |
284 | 299 |
285 /* rsa_tmp1 is em */ | 300 /* rsa_tmp1 is em */ |
286 /* em' = em * r^e mod n */ | 301 /* em' = em * r^e mod n */ |
287 | 302 |
288 mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s); /* rsa_s used as a temp var*/ | 303 /* rsa_s used as a temp var*/ |
289 mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3); | 304 if (mp_exptmod(&rsa_tmp2, key->e, key->n, &rsa_s) != MP_OKAY) { |
290 mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2); | 305 dropbear_exit("rsa error"); |
306 } | |
307 if (mp_invmod(&rsa_tmp2, key->n, &rsa_tmp3) != MP_OKAY) { | |
308 dropbear_exit("rsa error"); | |
309 } | |
310 if (mp_mulmod(&rsa_tmp1, &rsa_s, key->n, &rsa_tmp2) != MP_OKAY) { | |
311 dropbear_exit("rsa error"); | |
312 } | |
291 | 313 |
292 /* rsa_tmp2 is em' */ | 314 /* rsa_tmp2 is em' */ |
293 /* s' = (em')^d mod n */ | 315 /* s' = (em')^d mod n */ |
294 mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1); | 316 if (mp_exptmod(&rsa_tmp2, key->d, key->n, &rsa_tmp1) != MP_OKAY) { |
317 dropbear_exit("rsa error"); | |
318 } | |
295 | 319 |
296 /* rsa_tmp1 is s' */ | 320 /* rsa_tmp1 is s' */ |
297 /* rsa_tmp3 is r^(-1) mod n */ | 321 /* rsa_tmp3 is r^(-1) mod n */ |
298 /* s = (s')r^(-1) mod n */ | 322 /* s = (s')r^(-1) mod n */ |
299 mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s); | 323 if (mp_mulmod(&rsa_tmp1, &rsa_tmp3, key->n, &rsa_s) != MP_OKAY) { |
324 dropbear_exit("rsa error"); | |
325 } | |
300 | 326 |
301 #else | 327 #else |
302 | 328 |
303 /* s = em^d mod n */ | 329 /* s = em^d mod n */ |
304 /* rsa_tmp1 is em */ | 330 /* rsa_tmp1 is em */ |