ecdsa.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. #include "includes.h"
  2. #include "dbutil.h"
  3. #include "crypto_desc.h"
  4. #include "ecc.h"
  5. #include "ecdsa.h"
  6. #include "signkey.h"
  7. #if DROPBEAR_ECDSA
  8. int signkey_is_ecdsa(enum signkey_type type)
  9. {
  10. return type == DROPBEAR_SIGNKEY_ECDSA_NISTP256
  11. || type == DROPBEAR_SIGNKEY_ECDSA_NISTP384
  12. || type == DROPBEAR_SIGNKEY_ECDSA_NISTP521;
  13. }
  14. enum signkey_type ecdsa_signkey_type(const ecc_key * key) {
  15. #if DROPBEAR_ECC_256
  16. if (key->dp == ecc_curve_nistp256.dp) {
  17. return DROPBEAR_SIGNKEY_ECDSA_NISTP256;
  18. }
  19. #endif
  20. #if DROPBEAR_ECC_384
  21. if (key->dp == ecc_curve_nistp384.dp) {
  22. return DROPBEAR_SIGNKEY_ECDSA_NISTP384;
  23. }
  24. #endif
  25. #if DROPBEAR_ECC_521
  26. if (key->dp == ecc_curve_nistp521.dp) {
  27. return DROPBEAR_SIGNKEY_ECDSA_NISTP521;
  28. }
  29. #endif
  30. return DROPBEAR_SIGNKEY_NONE;
  31. }
  32. ecc_key *gen_ecdsa_priv_key(unsigned int bit_size) {
  33. const ltc_ecc_set_type *dp = NULL; /* curve domain parameters */
  34. ecc_key *new_key = NULL;
  35. switch (bit_size) {
  36. #if DROPBEAR_ECC_256
  37. case 256:
  38. dp = ecc_curve_nistp256.dp;
  39. break;
  40. #endif
  41. #if DROPBEAR_ECC_384
  42. case 384:
  43. dp = ecc_curve_nistp384.dp;
  44. break;
  45. #endif
  46. #if DROPBEAR_ECC_521
  47. case 521:
  48. dp = ecc_curve_nistp521.dp;
  49. break;
  50. #endif
  51. }
  52. if (!dp) {
  53. dropbear_exit("Key size %d isn't valid. Try "
  54. #if DROPBEAR_ECC_256
  55. "256 "
  56. #endif
  57. #if DROPBEAR_ECC_384
  58. "384 "
  59. #endif
  60. #if DROPBEAR_ECC_521
  61. "521 "
  62. #endif
  63. , bit_size);
  64. }
  65. new_key = m_malloc(sizeof(*new_key));
  66. if (ecc_make_key_ex(NULL, dropbear_ltc_prng, new_key, dp) != CRYPT_OK) {
  67. dropbear_exit("ECC error");
  68. }
  69. return new_key;
  70. }
  71. ecc_key *buf_get_ecdsa_pub_key(buffer* buf) {
  72. unsigned char *key_ident = NULL, *identifier = NULL;
  73. unsigned int key_ident_len, identifier_len;
  74. buffer *q_buf = NULL;
  75. struct dropbear_ecc_curve **curve;
  76. ecc_key *new_key = NULL;
  77. /* string "ecdsa-sha2-[identifier]" or "sk-ecdsa-sha2-nistp256@openssh.com" */
  78. key_ident = (unsigned char*)buf_getstring(buf, &key_ident_len);
  79. /* string "[identifier]" */
  80. identifier = (unsigned char*)buf_getstring(buf, &identifier_len);
  81. if (strcmp (key_ident, "sk-ecdsa-sha2-nistp256@openssh.com") == 0) {
  82. if (strcmp (identifier, "nistp256") != 0) {
  83. TRACE(("mismatching identifiers"))
  84. goto out;
  85. }
  86. } else {
  87. if (key_ident_len != identifier_len + strlen ("ecdsa-sha2-")) {
  88. TRACE(("Bad identifier lengths"))
  89. goto out;
  90. }
  91. if (memcmp(&key_ident[strlen ("ecdsa-sha2-")], identifier, identifier_len) != 0) {
  92. TRACE(("mismatching identifiers"))
  93. goto out;
  94. }
  95. }
  96. for (curve = dropbear_ecc_curves; *curve; curve++) {
  97. if (memcmp(identifier, (char*)(*curve)->name, strlen((char*)(*curve)->name)) == 0) {
  98. break;
  99. }
  100. }
  101. if (!*curve) {
  102. TRACE(("couldn't match ecc curve"))
  103. goto out;
  104. }
  105. /* string Q */
  106. q_buf = buf_getstringbuf(buf);
  107. new_key = buf_get_ecc_raw_pubkey(q_buf, *curve);
  108. out:
  109. m_free(key_ident);
  110. m_free(identifier);
  111. if (q_buf) {
  112. buf_free(q_buf);
  113. q_buf = NULL;
  114. }
  115. TRACE(("leave buf_get_ecdsa_pub_key"))
  116. return new_key;
  117. }
  118. ecc_key *buf_get_ecdsa_priv_key(buffer *buf) {
  119. ecc_key *new_key = NULL;
  120. TRACE(("enter buf_get_ecdsa_priv_key"))
  121. new_key = buf_get_ecdsa_pub_key(buf);
  122. if (!new_key) {
  123. return NULL;
  124. }
  125. if (buf_getmpint(buf, new_key->k) != DROPBEAR_SUCCESS) {
  126. ecc_free(new_key);
  127. m_free(new_key);
  128. return NULL;
  129. }
  130. return new_key;
  131. }
  132. void buf_put_ecdsa_pub_key(buffer *buf, ecc_key *key) {
  133. struct dropbear_ecc_curve *curve = NULL;
  134. char key_ident[30];
  135. curve = curve_for_dp(key->dp);
  136. snprintf(key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name);
  137. buf_putstring(buf, key_ident, strlen(key_ident));
  138. buf_putstring(buf, curve->name, strlen(curve->name));
  139. buf_put_ecc_raw_pubkey_string(buf, key);
  140. }
  141. void buf_put_ecdsa_priv_key(buffer *buf, ecc_key *key) {
  142. buf_put_ecdsa_pub_key(buf, key);
  143. buf_putmpint(buf, key->k);
  144. }
  145. void buf_put_ecdsa_sign(buffer *buf, const ecc_key *key, const buffer *data_buf) {
  146. /* Based on libtomcrypt's ecc_sign_hash but without the asn1 */
  147. int err = DROPBEAR_FAILURE;
  148. struct dropbear_ecc_curve *curve = NULL;
  149. hash_state hs;
  150. unsigned char hash[64];
  151. void *e = NULL, *p = NULL, *s = NULL, *r;
  152. char key_ident[30];
  153. buffer *sigbuf = NULL;
  154. TRACE(("buf_put_ecdsa_sign"))
  155. curve = curve_for_dp(key->dp);
  156. if (ltc_init_multi(&r, &s, &p, &e, NULL) != CRYPT_OK) {
  157. goto out;
  158. }
  159. curve->hash_desc->init(&hs);
  160. curve->hash_desc->process(&hs, data_buf->data, data_buf->len);
  161. curve->hash_desc->done(&hs, hash);
  162. if (ltc_mp.unsigned_read(e, hash, curve->hash_desc->hashsize) != CRYPT_OK) {
  163. goto out;
  164. }
  165. if (ltc_mp.read_radix(p, (char *)key->dp->order, 16) != CRYPT_OK) {
  166. goto out;
  167. }
  168. for (;;) {
  169. ecc_key R_key; /* ephemeral key */
  170. if (ecc_make_key_ex(NULL, dropbear_ltc_prng, &R_key, key->dp) != CRYPT_OK) {
  171. goto out;
  172. }
  173. if (ltc_mp.mpdiv(R_key.pubkey.x, p, NULL, r) != CRYPT_OK) {
  174. goto out;
  175. }
  176. if (ltc_mp.compare_d(r, 0) == LTC_MP_EQ) {
  177. /* try again */
  178. ecc_free(&R_key);
  179. continue;
  180. }
  181. /* k = 1/k */
  182. if (ltc_mp.invmod(R_key.k, p, R_key.k) != CRYPT_OK) {
  183. goto out;
  184. }
  185. /* s = xr */
  186. if (ltc_mp.mulmod(key->k, r, p, s) != CRYPT_OK) {
  187. goto out;
  188. }
  189. /* s = e + xr */
  190. if (ltc_mp.add(e, s, s) != CRYPT_OK) {
  191. goto out;
  192. }
  193. if (ltc_mp.mpdiv(s, p, NULL, s) != CRYPT_OK) {
  194. goto out;
  195. }
  196. /* s = (e + xr)/k */
  197. if (ltc_mp.mulmod(s, R_key.k, p, s) != CRYPT_OK) {
  198. goto out;
  199. }
  200. ecc_free(&R_key);
  201. if (ltc_mp.compare_d(s, 0) != LTC_MP_EQ) {
  202. break;
  203. }
  204. }
  205. snprintf(key_ident, sizeof(key_ident), "ecdsa-sha2-%s", curve->name);
  206. buf_putstring(buf, key_ident, strlen(key_ident));
  207. /* enough for nistp521 */
  208. sigbuf = buf_new(200);
  209. buf_putmpint(sigbuf, (mp_int*)r);
  210. buf_putmpint(sigbuf, (mp_int*)s);
  211. buf_putbufstring(buf, sigbuf);
  212. err = DROPBEAR_SUCCESS;
  213. out:
  214. if (r && s && p && e) {
  215. ltc_deinit_multi(r, s, p, e, NULL);
  216. }
  217. if (sigbuf) {
  218. buf_free(sigbuf);
  219. }
  220. if (err == DROPBEAR_FAILURE) {
  221. dropbear_exit("ECC error");
  222. }
  223. }
  224. /* returns values in s and r
  225. returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
  226. static int buf_get_ecdsa_verify_params(buffer *buf,
  227. void *r, void* s) {
  228. int ret = DROPBEAR_FAILURE;
  229. unsigned int sig_len;
  230. unsigned int sig_pos;
  231. sig_len = buf_getint(buf);
  232. sig_pos = buf->pos;
  233. if (buf_getmpint(buf, r) != DROPBEAR_SUCCESS) {
  234. goto out;
  235. }
  236. if (buf_getmpint(buf, s) != DROPBEAR_SUCCESS) {
  237. goto out;
  238. }
  239. if (buf->pos - sig_pos != sig_len) {
  240. goto out;
  241. }
  242. ret = DROPBEAR_SUCCESS;
  243. out:
  244. return ret;
  245. }
  246. int buf_ecdsa_verify(buffer *buf, const ecc_key *key, const buffer *data_buf) {
  247. /* Based on libtomcrypt's ecc_verify_hash but without the asn1 */
  248. int ret = DROPBEAR_FAILURE;
  249. hash_state hs;
  250. struct dropbear_ecc_curve *curve = NULL;
  251. unsigned char hash[64];
  252. ecc_point *mG = NULL, *mQ = NULL;
  253. void *r = NULL, *s = NULL, *v = NULL, *w = NULL, *u1 = NULL, *u2 = NULL,
  254. *e = NULL, *p = NULL, *m = NULL;
  255. void *mp = NULL;
  256. /* verify
  257. *
  258. * w = s^-1 mod n
  259. * u1 = xw
  260. * u2 = rw
  261. * X = u1*G + u2*Q
  262. * v = X_x1 mod n
  263. * accept if v == r
  264. */
  265. TRACE(("buf_ecdsa_verify"))
  266. curve = curve_for_dp(key->dp);
  267. mG = ltc_ecc_new_point();
  268. mQ = ltc_ecc_new_point();
  269. if (ltc_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL) != CRYPT_OK
  270. || !mG
  271. || !mQ) {
  272. dropbear_exit("ECC error");
  273. }
  274. if (buf_get_ecdsa_verify_params(buf, r, s) != DROPBEAR_SUCCESS) {
  275. goto out;
  276. }
  277. curve->hash_desc->init(&hs);
  278. curve->hash_desc->process(&hs, data_buf->data, data_buf->len);
  279. curve->hash_desc->done(&hs, hash);
  280. if (ltc_mp.unsigned_read(e, hash, curve->hash_desc->hashsize) != CRYPT_OK) {
  281. goto out;
  282. }
  283. /* get the order */
  284. if (ltc_mp.read_radix(p, (char *)key->dp->order, 16) != CRYPT_OK) {
  285. goto out;
  286. }
  287. /* get the modulus */
  288. if (ltc_mp.read_radix(m, (char *)key->dp->prime, 16) != CRYPT_OK) {
  289. goto out;
  290. }
  291. /* check for zero */
  292. if (ltc_mp.compare_d(r, 0) == LTC_MP_EQ
  293. || ltc_mp.compare_d(s, 0) == LTC_MP_EQ
  294. || ltc_mp.compare(r, p) != LTC_MP_LT
  295. || ltc_mp.compare(s, p) != LTC_MP_LT) {
  296. goto out;
  297. }
  298. /* w = s^-1 mod n */
  299. if (ltc_mp.invmod(s, p, w) != CRYPT_OK) {
  300. goto out;
  301. }
  302. /* u1 = ew */
  303. if (ltc_mp.mulmod(e, w, p, u1) != CRYPT_OK) {
  304. goto out;
  305. }
  306. /* u2 = rw */
  307. if (ltc_mp.mulmod(r, w, p, u2) != CRYPT_OK) {
  308. goto out;
  309. }
  310. /* find mG and mQ */
  311. if (ltc_mp.read_radix(mG->x, (char *)key->dp->Gx, 16) != CRYPT_OK) {
  312. goto out;
  313. }
  314. if (ltc_mp.read_radix(mG->y, (char *)key->dp->Gy, 16) != CRYPT_OK) {
  315. goto out;
  316. }
  317. if (ltc_mp.set_int(mG->z, 1) != CRYPT_OK) {
  318. goto out;
  319. }
  320. if (ltc_mp.copy(key->pubkey.x, mQ->x) != CRYPT_OK
  321. || ltc_mp.copy(key->pubkey.y, mQ->y) != CRYPT_OK
  322. || ltc_mp.copy(key->pubkey.z, mQ->z) != CRYPT_OK) {
  323. goto out;
  324. }
  325. /* compute u1*mG + u2*mQ = mG */
  326. if (ltc_mp.ecc_mul2add == NULL) {
  327. if (ltc_mp.ecc_ptmul(u1, mG, mG, m, 0) != CRYPT_OK) {
  328. goto out;
  329. }
  330. if (ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0) != CRYPT_OK) {
  331. goto out;
  332. }
  333. /* find the montgomery mp */
  334. if (ltc_mp.montgomery_setup(m, &mp) != CRYPT_OK) {
  335. goto out;
  336. }
  337. /* add them */
  338. if (ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp) != CRYPT_OK) {
  339. goto out;
  340. }
  341. /* reduce */
  342. if (ltc_mp.ecc_map(mG, m, mp) != CRYPT_OK) {
  343. goto out;
  344. }
  345. } else {
  346. /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */
  347. if (ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m) != CRYPT_OK) {
  348. goto out;
  349. }
  350. }
  351. /* v = X_x1 mod n */
  352. if (ltc_mp.mpdiv(mG->x, p, NULL, v) != CRYPT_OK) {
  353. goto out;
  354. }
  355. /* does v == r */
  356. if (ltc_mp.compare(v, r) == LTC_MP_EQ) {
  357. ret = DROPBEAR_SUCCESS;
  358. }
  359. out:
  360. ltc_ecc_del_point(mG);
  361. ltc_ecc_del_point(mQ);
  362. ltc_deinit_multi(r, s, v, w, u1, u2, p, e, m, NULL);
  363. if (mp != NULL) {
  364. ltc_mp.montgomery_deinit(mp);
  365. }
  366. return ret;
  367. }
  368. #endif /* DROPBEAR_ECDSA */