sshdss.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*
  2. * Digital Signature Standard implementation for PuTTY.
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <assert.h>
  7. #include "ssh.h"
  8. #include "mpint.h"
  9. #include "misc.h"
  10. static void dss_freekey(ssh_key *key); /* forward reference */
  11. static ssh_key *dss_new_pub(const ssh_keyalg *self, ptrlen data)
  12. {
  13. BinarySource src[1];
  14. struct dss_key *dss;
  15. BinarySource_BARE_INIT(src, data.ptr, data.len);
  16. if (!ptrlen_eq_string(get_string(src), "ssh-dss"))
  17. return NULL;
  18. dss = snew(struct dss_key);
  19. dss->sshk.vt = &ssh_dss;
  20. dss->p = get_mp_ssh2(src);
  21. dss->q = get_mp_ssh2(src);
  22. dss->g = get_mp_ssh2(src);
  23. dss->y = get_mp_ssh2(src);
  24. dss->x = NULL;
  25. if (get_err(src) ||
  26. mp_eq_integer(dss->p, 0) || mp_eq_integer(dss->q, 0)) {
  27. /* Invalid key. */
  28. dss_freekey(&dss->sshk);
  29. return NULL;
  30. }
  31. return &dss->sshk;
  32. }
  33. static void dss_freekey(ssh_key *key)
  34. {
  35. struct dss_key *dss = container_of(key, struct dss_key, sshk);
  36. if (dss->p)
  37. mp_free(dss->p);
  38. if (dss->q)
  39. mp_free(dss->q);
  40. if (dss->g)
  41. mp_free(dss->g);
  42. if (dss->y)
  43. mp_free(dss->y);
  44. if (dss->x)
  45. mp_free(dss->x);
  46. sfree(dss);
  47. }
  48. static void append_hex_to_strbuf(strbuf *sb, mp_int *x)
  49. {
  50. if (sb->len > 0)
  51. put_byte(sb, ',');
  52. put_data(sb, "0x", 2);
  53. { // WINSCP
  54. char *hex = mp_get_hex(x);
  55. size_t hexlen = strlen(hex);
  56. put_data(sb, hex, hexlen);
  57. smemclr(hex, hexlen);
  58. sfree(hex);
  59. } // WINSCP
  60. }
  61. static char *dss_cache_str(ssh_key *key)
  62. {
  63. struct dss_key *dss = container_of(key, struct dss_key, sshk);
  64. strbuf *sb = strbuf_new();
  65. if (!dss->p)
  66. return NULL;
  67. append_hex_to_strbuf(sb, dss->p);
  68. append_hex_to_strbuf(sb, dss->q);
  69. append_hex_to_strbuf(sb, dss->g);
  70. append_hex_to_strbuf(sb, dss->y);
  71. return strbuf_to_str(sb);
  72. }
  73. static bool dss_verify(ssh_key *key, ptrlen sig, ptrlen data)
  74. {
  75. struct dss_key *dss = container_of(key, struct dss_key, sshk);
  76. BinarySource src[1];
  77. unsigned char hash[20];
  78. bool toret;
  79. if (!dss->p)
  80. return false;
  81. BinarySource_BARE_INIT(src, sig.ptr, sig.len);
  82. /*
  83. * Commercial SSH (2.0.13) and OpenSSH disagree over the format
  84. * of a DSA signature. OpenSSH is in line with RFC 4253:
  85. * it uses a string "ssh-dss", followed by a 40-byte string
  86. * containing two 160-bit integers end-to-end. Commercial SSH
  87. * can't be bothered with the header bit, and considers a DSA
  88. * signature blob to be _just_ the 40-byte string containing
  89. * the two 160-bit integers. We tell them apart by measuring
  90. * the length: length 40 means the commercial-SSH bug, anything
  91. * else is assumed to be RFC-compliant.
  92. */
  93. if (sig.len != 40) { /* bug not present; read admin fields */
  94. ptrlen type = get_string(src);
  95. sig = get_string(src);
  96. if (get_err(src) || !ptrlen_eq_string(type, "ssh-dss") ||
  97. sig.len != 40)
  98. return false;
  99. }
  100. /* Now we're sitting on a 40-byte string for sure. */
  101. { // WINSCP
  102. mp_int *r = mp_from_bytes_be(make_ptrlen(sig.ptr, 20));
  103. mp_int *s = mp_from_bytes_be(make_ptrlen((const char *)sig.ptr + 20, 20));
  104. if (!r || !s) {
  105. if (r)
  106. mp_free(r);
  107. if (s)
  108. mp_free(s);
  109. return false;
  110. }
  111. if (mp_eq_integer(s, 0)) {
  112. mp_free(r);
  113. mp_free(s);
  114. return false;
  115. }
  116. /*
  117. * Step 1. w <- s^-1 mod q.
  118. */
  119. { // WINSCP
  120. mp_int *w = mp_invert(s, dss->q);
  121. if (!w) {
  122. mp_free(r);
  123. mp_free(s);
  124. return false;
  125. }
  126. /*
  127. * Step 2. u1 <- SHA(message) * w mod q.
  128. */
  129. SHA_Simple(data.ptr, data.len, hash);
  130. { // WINSCP
  131. mp_int *sha = mp_from_bytes_be(make_ptrlen(hash, 20));
  132. mp_int *u1 = mp_modmul(sha, w, dss->q);
  133. /*
  134. * Step 3. u2 <- r * w mod q.
  135. */
  136. mp_int *u2 = mp_modmul(r, w, dss->q);
  137. /*
  138. * Step 4. v <- (g^u1 * y^u2 mod p) mod q.
  139. */
  140. mp_int *gu1p = mp_modpow(dss->g, u1, dss->p);
  141. mp_int *yu2p = mp_modpow(dss->y, u2, dss->p);
  142. mp_int *gu1yu2p = mp_modmul(gu1p, yu2p, dss->p);
  143. mp_int *v = mp_mod(gu1yu2p, dss->q);
  144. /*
  145. * Step 5. v should now be equal to r.
  146. */
  147. toret = mp_cmp_eq(v, r);
  148. mp_free(w);
  149. mp_free(sha);
  150. mp_free(u1);
  151. mp_free(u2);
  152. mp_free(gu1p);
  153. mp_free(yu2p);
  154. mp_free(gu1yu2p);
  155. mp_free(v);
  156. mp_free(r);
  157. mp_free(s);
  158. } // WINSCP
  159. } // WINSCP
  160. } // WINSCP
  161. return toret;
  162. }
  163. static void dss_public_blob(ssh_key *key, BinarySink *bs)
  164. {
  165. struct dss_key *dss = container_of(key, struct dss_key, sshk);
  166. put_stringz(bs, "ssh-dss");
  167. put_mp_ssh2(bs, dss->p);
  168. put_mp_ssh2(bs, dss->q);
  169. put_mp_ssh2(bs, dss->g);
  170. put_mp_ssh2(bs, dss->y);
  171. }
  172. static void dss_private_blob(ssh_key *key, BinarySink *bs)
  173. {
  174. struct dss_key *dss = container_of(key, struct dss_key, sshk);
  175. put_mp_ssh2(bs, dss->x);
  176. }
  177. static ssh_key *dss_new_priv(const ssh_keyalg *self, ptrlen pub, ptrlen priv)
  178. {
  179. BinarySource src[1];
  180. ssh_key *sshk;
  181. struct dss_key *dss;
  182. ptrlen hash;
  183. SHA_State s;
  184. unsigned char digest[20];
  185. mp_int *ytest;
  186. sshk = dss_new_pub(self, pub);
  187. if (!sshk)
  188. return NULL;
  189. dss = container_of(sshk, struct dss_key, sshk);
  190. BinarySource_BARE_INIT(src, priv.ptr, priv.len);
  191. dss->x = get_mp_ssh2(src);
  192. if (get_err(src)) {
  193. dss_freekey(&dss->sshk);
  194. return NULL;
  195. }
  196. /*
  197. * Check the obsolete hash in the old DSS key format.
  198. */
  199. hash = get_string(src);
  200. if (hash.len == 20) {
  201. SHA_Init(&s);
  202. put_mp_ssh2(&s, dss->p);
  203. put_mp_ssh2(&s, dss->q);
  204. put_mp_ssh2(&s, dss->g);
  205. SHA_Final(&s, digest);
  206. if (!smemeq(hash.ptr, digest, 20)) {
  207. dss_freekey(&dss->sshk);
  208. return NULL;
  209. }
  210. }
  211. /*
  212. * Now ensure g^x mod p really is y.
  213. */
  214. ytest = mp_modpow(dss->g, dss->x, dss->p);
  215. if (!mp_cmp_eq(ytest, dss->y)) {
  216. mp_free(ytest);
  217. dss_freekey(&dss->sshk);
  218. return NULL;
  219. }
  220. mp_free(ytest);
  221. return &dss->sshk;
  222. }
  223. static ssh_key *dss_new_priv_openssh(const ssh_keyalg *self,
  224. BinarySource *src)
  225. {
  226. struct dss_key *dss;
  227. dss = snew(struct dss_key);
  228. dss->sshk.vt = &ssh_dss;
  229. dss->p = get_mp_ssh2(src);
  230. dss->q = get_mp_ssh2(src);
  231. dss->g = get_mp_ssh2(src);
  232. dss->y = get_mp_ssh2(src);
  233. dss->x = get_mp_ssh2(src);
  234. if (get_err(src) ||
  235. mp_eq_integer(dss->q, 0) || mp_eq_integer(dss->p, 0)) {
  236. /* Invalid key. */
  237. dss_freekey(&dss->sshk);
  238. return NULL;
  239. }
  240. return &dss->sshk;
  241. }
  242. static void dss_openssh_blob(ssh_key *key, BinarySink *bs)
  243. {
  244. struct dss_key *dss = container_of(key, struct dss_key, sshk);
  245. put_mp_ssh2(bs, dss->p);
  246. put_mp_ssh2(bs, dss->q);
  247. put_mp_ssh2(bs, dss->g);
  248. put_mp_ssh2(bs, dss->y);
  249. put_mp_ssh2(bs, dss->x);
  250. }
  251. static int dss_pubkey_bits(const ssh_keyalg *self, ptrlen pub)
  252. {
  253. ssh_key *sshk;
  254. struct dss_key *dss;
  255. int ret;
  256. sshk = dss_new_pub(self, pub);
  257. if (!sshk)
  258. return -1;
  259. dss = container_of(sshk, struct dss_key, sshk);
  260. ret = mp_get_nbits(dss->p);
  261. dss_freekey(&dss->sshk);
  262. return ret;
  263. }
  264. mp_int *dss_gen_k(const char *id_string, mp_int *modulus,
  265. mp_int *private_key,
  266. unsigned char *digest, int digest_len)
  267. {
  268. /*
  269. * The basic DSS signing algorithm is:
  270. *
  271. * - invent a random k between 1 and q-1 (exclusive).
  272. * - Compute r = (g^k mod p) mod q.
  273. * - Compute s = k^-1 * (hash + x*r) mod q.
  274. *
  275. * This has the dangerous properties that:
  276. *
  277. * - if an attacker in possession of the public key _and_ the
  278. * signature (for example, the host you just authenticated
  279. * to) can guess your k, he can reverse the computation of s
  280. * and work out x = r^-1 * (s*k - hash) mod q. That is, he
  281. * can deduce the private half of your key, and masquerade
  282. * as you for as long as the key is still valid.
  283. *
  284. * - since r is a function purely of k and the public key, if
  285. * the attacker only has a _range of possibilities_ for k
  286. * it's easy for him to work through them all and check each
  287. * one against r; he'll never be unsure of whether he's got
  288. * the right one.
  289. *
  290. * - if you ever sign two different hashes with the same k, it
  291. * will be immediately obvious because the two signatures
  292. * will have the same r, and moreover an attacker in
  293. * possession of both signatures (and the public key of
  294. * course) can compute k = (hash1-hash2) * (s1-s2)^-1 mod q,
  295. * and from there deduce x as before.
  296. *
  297. * - the Bleichenbacher attack on DSA makes use of methods of
  298. * generating k which are significantly non-uniformly
  299. * distributed; in particular, generating a 160-bit random
  300. * number and reducing it mod q is right out.
  301. *
  302. * For this reason we must be pretty careful about how we
  303. * generate our k. Since this code runs on Windows, with no
  304. * particularly good system entropy sources, we can't trust our
  305. * RNG itself to produce properly unpredictable data. Hence, we
  306. * use a totally different scheme instead.
  307. *
  308. * What we do is to take a SHA-512 (_big_) hash of the private
  309. * key x, and then feed this into another SHA-512 hash that
  310. * also includes the message hash being signed. That is:
  311. *
  312. * proto_k = SHA512 ( SHA512(x) || SHA160(message) )
  313. *
  314. * This number is 512 bits long, so reducing it mod q won't be
  315. * noticeably non-uniform. So
  316. *
  317. * k = proto_k mod q
  318. *
  319. * This has the interesting property that it's _deterministic_:
  320. * signing the same hash twice with the same key yields the
  321. * same signature.
  322. *
  323. * Despite this determinism, it's still not predictable to an
  324. * attacker, because in order to repeat the SHA-512
  325. * construction that created it, the attacker would have to
  326. * know the private key value x - and by assumption he doesn't,
  327. * because if he knew that he wouldn't be attacking k!
  328. *
  329. * (This trick doesn't, _per se_, protect against reuse of k.
  330. * Reuse of k is left to chance; all it does is prevent
  331. * _excessively high_ chances of reuse of k due to entropy
  332. * problems.)
  333. *
  334. * Thanks to Colin Plumb for the general idea of using x to
  335. * ensure k is hard to guess, and to the Cambridge University
  336. * Computer Security Group for helping to argue out all the
  337. * fine details.
  338. */
  339. SHA512_State ss;
  340. unsigned char digest512[64];
  341. /*
  342. * Hash some identifying text plus x.
  343. */
  344. SHA512_Init(&ss);
  345. put_asciz(&ss, id_string);
  346. put_mp_ssh2(&ss, private_key);
  347. SHA512_Final(&ss, digest512);
  348. /*
  349. * Now hash that digest plus the message hash.
  350. */
  351. SHA512_Init(&ss);
  352. put_data(&ss, digest512, sizeof(digest512));
  353. put_data(&ss, digest, digest_len);
  354. SHA512_Final(&ss, digest512);
  355. /*
  356. * Now convert the result into a bignum, and coerce it to the
  357. * range [2,q), which we do by reducing it mod q-2 and adding 2.
  358. */
  359. { // WINSCP
  360. mp_int *modminus2 = mp_copy(modulus);
  361. mp_sub_integer_into(modminus2, modminus2, 2);
  362. { // WINSCP
  363. mp_int *proto_k = mp_from_bytes_be(make_ptrlen(digest512, 64));
  364. mp_int *k = mp_mod(proto_k, modminus2);
  365. mp_free(proto_k);
  366. mp_free(modminus2);
  367. mp_add_integer_into(k, k, 2);
  368. smemclr(&ss, sizeof(ss));
  369. smemclr(digest512, sizeof(digest512));
  370. return k;
  371. } // WINSCP
  372. } // WINSCP
  373. }
  374. static void dss_sign(ssh_key *key, const void *data, int datalen,
  375. unsigned flags, BinarySink *bs)
  376. {
  377. struct dss_key *dss = container_of(key, struct dss_key, sshk);
  378. unsigned char digest[20];
  379. int i;
  380. SHA_Simple(data, datalen, digest);
  381. { // WINSCP
  382. mp_int *k = dss_gen_k("DSA deterministic k generator", dss->q, dss->x,
  383. digest, sizeof(digest));
  384. mp_int *kinv = mp_invert(k, dss->q); /* k^-1 mod q */
  385. /*
  386. * Now we have k, so just go ahead and compute the signature.
  387. */
  388. mp_int *gkp = mp_modpow(dss->g, k, dss->p); /* g^k mod p */
  389. mp_int *r = mp_mod(gkp, dss->q); /* r = (g^k mod p) mod q */
  390. mp_free(gkp);
  391. { // WINSCP
  392. mp_int *hash = mp_from_bytes_be(make_ptrlen(digest, 20));
  393. mp_int *hxr = mp_mul(dss->x, r);
  394. mp_add_into(hxr, hxr, hash); /* hash + x*r */
  395. { // WINSCP
  396. mp_int *s = mp_modmul(kinv, hxr, dss->q); /* s = k^-1 * (hash+x*r) mod q */
  397. mp_free(hxr);
  398. mp_free(kinv);
  399. mp_free(k);
  400. mp_free(hash);
  401. put_stringz(bs, "ssh-dss");
  402. put_uint32(bs, 40);
  403. for (i = 0; i < 20; i++)
  404. put_byte(bs, mp_get_byte(r, 19 - i));
  405. for (i = 0; i < 20; i++)
  406. put_byte(bs, mp_get_byte(s, 19 - i));
  407. mp_free(r);
  408. mp_free(s);
  409. } // WINSCP
  410. } // WINSCP
  411. } // WINSCP
  412. }
  413. const ssh_keyalg ssh_dss = {
  414. dss_new_pub,
  415. dss_new_priv,
  416. dss_new_priv_openssh,
  417. dss_freekey,
  418. dss_sign,
  419. dss_verify,
  420. dss_public_blob,
  421. dss_private_blob,
  422. dss_openssh_blob,
  423. dss_cache_str,
  424. dss_pubkey_bits,
  425. "ssh-dss",
  426. "dss",
  427. NULL,
  428. 0, /* no supported flags */
  429. };