ecc.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #include "includes.h"
  2. #include "options.h"
  3. #include "ecc.h"
  4. #include "dbutil.h"
  5. #include "bignum.h"
  6. #ifdef DROPBEAR_ECC
  7. /* .dp members are filled out by dropbear_ecc_fill_dp() at startup */
  8. #ifdef DROPBEAR_ECC_256
  9. struct dropbear_ecc_curve ecc_curve_nistp256 = {
  10. 32, /* .ltc_size */
  11. NULL, /* .dp */
  12. &sha256_desc, /* .hash_desc */
  13. "nistp256" /* .name */
  14. };
  15. #endif
  16. #ifdef DROPBEAR_ECC_384
  17. struct dropbear_ecc_curve ecc_curve_nistp384 = {
  18. 48, /* .ltc_size */
  19. NULL, /* .dp */
  20. &sha384_desc, /* .hash_desc */
  21. "nistp384" /* .name */
  22. };
  23. #endif
  24. #ifdef DROPBEAR_ECC_521
  25. struct dropbear_ecc_curve ecc_curve_nistp521 = {
  26. 66, /* .ltc_size */
  27. NULL, /* .dp */
  28. &sha512_desc, /* .hash_desc */
  29. "nistp521" /* .name */
  30. };
  31. #endif
  32. struct dropbear_ecc_curve *dropbear_ecc_curves[] = {
  33. #ifdef DROPBEAR_ECC_256
  34. &ecc_curve_nistp256,
  35. #endif
  36. #ifdef DROPBEAR_ECC_384
  37. &ecc_curve_nistp384,
  38. #endif
  39. #ifdef DROPBEAR_ECC_521
  40. &ecc_curve_nistp521,
  41. #endif
  42. NULL
  43. };
  44. void dropbear_ecc_fill_dp() {
  45. struct dropbear_ecc_curve **curve;
  46. /* libtomcrypt guarantees they're ordered by size */
  47. const ltc_ecc_set_type *dp = ltc_ecc_sets;
  48. for (curve = dropbear_ecc_curves; *curve; curve++) {
  49. for (;dp->size > 0; dp++) {
  50. if (dp->size == (*curve)->ltc_size) {
  51. (*curve)->dp = dp;
  52. break;
  53. }
  54. }
  55. if (!(*curve)->dp) {
  56. dropbear_exit("Missing ECC params %s", (*curve)->name);
  57. }
  58. }
  59. }
  60. struct dropbear_ecc_curve* curve_for_dp(const ltc_ecc_set_type *dp) {
  61. struct dropbear_ecc_curve **curve = NULL;
  62. for (curve = dropbear_ecc_curves; *curve; curve++) {
  63. if ((*curve)->dp == dp) {
  64. break;
  65. }
  66. }
  67. assert(*curve);
  68. return *curve;
  69. }
  70. ecc_key * new_ecc_key(void) {
  71. ecc_key *key = m_malloc(sizeof(*key));
  72. m_mp_alloc_init_multi((mp_int**)&key->pubkey.x, (mp_int**)&key->pubkey.y,
  73. (mp_int**)&key->pubkey.z, (mp_int**)&key->k, NULL);
  74. return key;
  75. }
  76. /* Copied from libtomcrypt ecc_import.c (version there is static), modified
  77. for different mp_int pointer without LTC_SOURCE */
  78. static int ecc_is_point(ecc_key *key)
  79. {
  80. mp_int *prime, *b, *t1, *t2;
  81. int err;
  82. m_mp_alloc_init_multi(&prime, &b, &t1, &t2, NULL);
  83. /* load prime and b */
  84. if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; }
  85. if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; }
  86. /* compute y^2 */
  87. if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
  88. /* compute x^3 */
  89. if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
  90. if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
  91. if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
  92. /* compute y^2 - x^3 */
  93. if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
  94. /* compute y^2 - x^3 + 3x */
  95. if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
  96. if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
  97. if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
  98. if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
  99. while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
  100. if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
  101. }
  102. while (mp_cmp(t1, prime) != LTC_MP_LT) {
  103. if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
  104. }
  105. /* compare to b */
  106. if (mp_cmp(t1, b) != LTC_MP_EQ) {
  107. err = CRYPT_INVALID_PACKET;
  108. } else {
  109. err = CRYPT_OK;
  110. }
  111. error:
  112. mp_clear_multi(prime, b, t1, t2, NULL);
  113. m_free(prime);
  114. m_free(b);
  115. m_free(t1);
  116. m_free(t2);
  117. return err;
  118. }
  119. /* For the "ephemeral public key octet string" in ECDH (rfc5656 section 4) */
  120. void buf_put_ecc_raw_pubkey_string(buffer *buf, ecc_key *key) {
  121. unsigned long len = key->dp->size*2 + 1;
  122. int err;
  123. buf_putint(buf, len);
  124. err = ecc_ansi_x963_export(key, buf_getwriteptr(buf, len), &len);
  125. if (err != CRYPT_OK) {
  126. dropbear_exit("ECC error");
  127. }
  128. buf_incrwritepos(buf, len);
  129. }
  130. /* For the "ephemeral public key octet string" in ECDH (rfc5656 section 4) */
  131. ecc_key * buf_get_ecc_raw_pubkey(buffer *buf, const struct dropbear_ecc_curve *curve) {
  132. ecc_key *key = NULL;
  133. int ret = DROPBEAR_FAILURE;
  134. const unsigned int size = curve->dp->size;
  135. unsigned char first;
  136. TRACE(("enter buf_get_ecc_raw_pubkey"))
  137. buf_setpos(buf, 0);
  138. first = buf_getbyte(buf);
  139. if (first == 2 || first == 3) {
  140. dropbear_log(LOG_WARNING, "Dropbear doesn't support ECC point compression");
  141. return NULL;
  142. }
  143. if (first != 4 || buf->len != 1+2*size) {
  144. TRACE(("leave, wrong size"))
  145. return NULL;
  146. }
  147. key = new_ecc_key();
  148. key->dp = curve->dp;
  149. if (mp_read_unsigned_bin(key->pubkey.x, buf_getptr(buf, size), size) != MP_OKAY) {
  150. TRACE(("failed to read x"))
  151. goto out;
  152. }
  153. buf_incrpos(buf, size);
  154. if (mp_read_unsigned_bin(key->pubkey.y, buf_getptr(buf, size), size) != MP_OKAY) {
  155. TRACE(("failed to read y"))
  156. goto out;
  157. }
  158. buf_incrpos(buf, size);
  159. mp_set(key->pubkey.z, 1);
  160. if (ecc_is_point(key) != CRYPT_OK) {
  161. TRACE(("failed, not a point"))
  162. goto out;
  163. }
  164. /* SEC1 3.2.3.1 Check that Q != 0 */
  165. if (mp_cmp_d(key->pubkey.x, 0) == LTC_MP_EQ) {
  166. TRACE(("failed, x == 0"))
  167. goto out;
  168. }
  169. if (mp_cmp_d(key->pubkey.y, 0) == LTC_MP_EQ) {
  170. TRACE(("failed, y == 0"))
  171. goto out;
  172. }
  173. ret = DROPBEAR_SUCCESS;
  174. out:
  175. if (ret == DROPBEAR_FAILURE) {
  176. if (key) {
  177. ecc_free(key);
  178. m_free(key);
  179. key = NULL;
  180. }
  181. }
  182. return key;
  183. }
  184. /* a modified version of libtomcrypt's "ecc_shared_secret" to output
  185. a mp_int instead. */
  186. mp_int * dropbear_ecc_shared_secret(ecc_key *public_key, ecc_key *private_key)
  187. {
  188. ecc_point *result = NULL;
  189. mp_int *prime = NULL, *shared_secret = NULL;
  190. int err = DROPBEAR_FAILURE;
  191. /* type valid? */
  192. if (private_key->type != PK_PRIVATE) {
  193. goto done;
  194. }
  195. if (private_key->dp != public_key->dp) {
  196. goto done;
  197. }
  198. /* make new point */
  199. result = ltc_ecc_new_point();
  200. if (result == NULL) {
  201. goto done;
  202. }
  203. prime = m_malloc(sizeof(*prime));
  204. m_mp_init(prime);
  205. if (mp_read_radix(prime, (char *)private_key->dp->prime, 16) != CRYPT_OK) {
  206. goto done;
  207. }
  208. if (ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1) != CRYPT_OK) {
  209. goto done;
  210. }
  211. err = DROPBEAR_SUCCESS;
  212. done:
  213. if (err == DROPBEAR_SUCCESS) {
  214. shared_secret = m_malloc(sizeof(*shared_secret));
  215. m_mp_init(shared_secret);
  216. mp_copy(result->x, shared_secret);
  217. }
  218. if (prime) {
  219. mp_clear(prime);
  220. m_free(prime);
  221. }
  222. if (result)
  223. {
  224. ltc_ecc_del_point(result);
  225. }
  226. if (err == DROPBEAR_FAILURE) {
  227. dropbear_exit("ECC error");
  228. }
  229. return shared_secret;
  230. }
  231. #endif