slitheen.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. /**
  2. * Author: Cecylia Bocovich <cbocovic@uwaterloo.ca>
  3. *
  4. * This file contains callback functions and all necessary helper functions to
  5. * tag flows for use with the Slitheen decoy routing system
  6. *
  7. */
  8. #include "slitheen.h"
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <semaphore.h>
  12. #include <openssl/rand.h>
  13. #include <openssl/sha.h>
  14. #include <openssl/ssl.h>
  15. #include <openssl/err.h>
  16. #include <openssl/ec.h>
  17. #include <openssl/bn.h>
  18. #include "ptwist.h"
  19. #include "crypto.h"
  20. tag_pair *keys;
  21. //look for key list
  22. sem_t key_lock;
  23. byte maingen[PTWIST_BYTES];
  24. byte twistgen[PTWIST_BYTES];
  25. byte mainpub[PTWIST_BYTES];
  26. byte twistpub[PTWIST_BYTES];
  27. //called once when phantomjs loads
  28. void slitheen_init(){
  29. int test;
  30. if(sem_init(&key_lock, 0, 1) == -1){
  31. printf("Initialization of semaphore failed\n");
  32. exit(1);
  33. }
  34. sem_getvalue(&key_lock, &test);
  35. }
  36. static void gen_tag(byte *tag, byte stored_key[16],
  37. const byte *context, size_t context_len){
  38. byte seckey[PTWIST_BYTES];
  39. byte sharedsec[PTWIST_BYTES+context_len];
  40. byte usetwist;
  41. byte taghashout[32];
  42. #if PTWIST_PUZZLE_STRENGTH > 0
  43. size_t puzzle_len = 16+PTWIST_RESP_BYTES;
  44. byte value_to_hash[puzzle_len];
  45. byte hashout[32];
  46. bn_t Rbn, Hbn;
  47. int i, len, sign;
  48. #endif
  49. memset(tag, 0xAA, PTWIST_TAG_BYTES);
  50. memset(stored_key, 0, 16);
  51. /* Use the main or the twist curve? */
  52. RAND_bytes(&usetwist, 1);
  53. usetwist &= 1;
  54. /* Create seckey*G and seckey*Y */
  55. RAND_bytes(seckey, PTWIST_BYTES);
  56. ptwist_pointmul(tag, usetwist ? twistgen : maingen, seckey);
  57. ptwist_pointmul(sharedsec, usetwist ? twistpub : mainpub, seckey);
  58. /* Create the tag hash keys */
  59. memmove(sharedsec+PTWIST_BYTES, context, context_len);
  60. SHA256(sharedsec, PTWIST_BYTES, taghashout);
  61. #if PTWIST_PUZZLE_STRENGTH > 0
  62. /* The puzzle is to find a response R such that SHA256(K || R)
  63. starts with PTWIST_PUZZLE_STRENGTH bits of 0s. K is the first
  64. 128 bits of the above hash tag keys. */
  65. /* Construct our response to the puzzle. Start looking for R in a
  66. * random place. */
  67. memmove(value_to_hash, taghashout, 16);
  68. RAND_bytes(value_to_hash+16, PTWIST_RESP_BYTES);
  69. value_to_hash[16+PTWIST_RESP_BYTES-1] &= PTWIST_RESP_MASK;
  70. while(1) {
  71. unsigned int firstbits;
  72. md_map_sh256(hashout, value_to_hash, puzzle_len);
  73. #if PTWIST_PUZZLE_STRENGTH < 32
  74. /* This assumes that you're on an architecture that doesn't care
  75. * about alignment, and is little endian. */
  76. firstbits = *(unsigned int*)hashout;
  77. if ((firstbits & PTWIST_PUZZLE_MASK) == 0) {
  78. break;
  79. }
  80. /* Increment R and try again. */
  81. for(i=0;i<PTWIST_RESP_BYTES;++i) {
  82. if (++value_to_hash[16+i]) break;
  83. }
  84. value_to_hash[16+PTWIST_RESP_BYTES-1] &= PTWIST_RESP_MASK;
  85. #else
  86. #error "Code assumes PTWIST_PUZZLE_STRENGTH < 32"
  87. #endif
  88. }
  89. /*
  90. for(i=0;i<puzzle_len;++i) {
  91. printf("%02x", value_to_hash[i]);
  92. if ((i%4) == 3) printf(" ");
  93. }
  94. printf("\n");
  95. for(i=0;i<32;++i) {
  96. printf("%02x", hashout[i]);
  97. if ((i%4) == 3) printf(" ");
  98. }
  99. printf("\n");
  100. */
  101. /* When we get here, we have solved the puzzle. R is in
  102. * value_to_hash[16..16+PTWIST_RESP_BYTES-1], the hash output
  103. * hashout starts with PTWIST_PUZZLE_STRENGTH bits of 0s, and we'll
  104. * want to copy out H (the next PTWIST_HASH_SHOWBITS bits of the
  105. * hash output). The final tag is [seckey*G]_x || R || H . */
  106. bn_new(Rbn);
  107. bn_new(Hbn);
  108. bn_read_bin(Rbn, value_to_hash+16, PTWIST_RESP_BYTES, BN_POS);
  109. hashout[PTWIST_HASH_TOTBYTES-1] &= PTWIST_HASH_MASK;
  110. bn_read_bin(Hbn, hashout, PTWIST_HASH_TOTBYTES, BN_POS);
  111. bn_lsh(Hbn, Hbn, PTWIST_RESP_BITS-PTWIST_PUZZLE_STRENGTH);
  112. bn_add(Hbn, Hbn, Rbn);
  113. len = PTWIST_TAG_BYTES-PTWIST_BYTES;
  114. bn_write_bin(tag+PTWIST_BYTES, &len, &sign, Hbn);
  115. /*
  116. for(i=0;i<PTWIST_TAG_BYTES;++i) {
  117. printf("%02x", tag[i]);
  118. if ((i%4) == 3) printf(" ");
  119. }
  120. printf("\n");
  121. */
  122. bn_free(Rbn);
  123. bn_free(Hbn);
  124. #elif PTWIST_HASH_SHOWBITS <= 128
  125. /* We're not using a client puzzle, so the tag is [seckey*G]_x || H
  126. * where H is the first PTWIST_HASH_SHOWBITS bits of the above hash
  127. * output. The key generated is the last 128 bits of that output.
  128. * If there's no client puzzle, PTWIST_HASH_SHOWBITS must be a multiple
  129. * of 8. */
  130. memmove(tag+PTWIST_BYTES, taghashout, PTWIST_HASH_SHOWBITS/8);
  131. #else
  132. #error "No client puzzle used, but PWTIST_HASH_SHOWBITS > 128"
  133. #endif
  134. memmove(stored_key, taghashout+16, 16);
  135. }
  136. int tag_hello(unsigned char *target, byte stored_key[16]){
  137. FILE *fp;
  138. int res;
  139. byte *tag;
  140. /* Create the generators */
  141. memset(maingen, 0, PTWIST_BYTES);
  142. maingen[0] = 2;
  143. memset(twistgen, 0, PTWIST_BYTES);
  144. /* Read the public keys */
  145. fp = fopen("pubkey", "rb");
  146. if (fp == NULL) {
  147. perror("fopen");
  148. exit(1);
  149. }
  150. res = fread(mainpub, PTWIST_BYTES, 1, fp);
  151. if (res < 1) {
  152. perror("fread");
  153. exit(1);
  154. }
  155. res = fread(twistpub, PTWIST_BYTES, 1, fp);
  156. if (res < 1) {
  157. perror("fread");
  158. exit(1);
  159. }
  160. fclose(fp);
  161. tag = target;
  162. gen_tag(tag, stored_key, (const byte *)"context", 7);
  163. return 0;
  164. }
  165. //Client hello callback
  166. int slitheen_tag_hello(SSL *s){
  167. unsigned char *result;
  168. int len;
  169. result = s->s3->client_random;
  170. len = sizeof(s->s3->client_random);
  171. if(len < PTWIST_TAG_BYTES) {
  172. printf("Uhoh\n");
  173. return 1;
  174. }
  175. unsigned long Time = (unsigned long)time(NULL);
  176. unsigned char *p = result;
  177. l2n(Time, p);
  178. //
  179. tag_pair *new_pair = calloc(1, sizeof(tag_pair));
  180. tag_hello((byte *) result+4, new_pair->key);
  181. new_pair->next = NULL;
  182. memcpy(new_pair->client_random, s->s3->client_random, SSL3_RANDOM_SIZE);
  183. int test;
  184. sem_getvalue(&key_lock, &test);
  185. sem_wait(&key_lock);
  186. tag_pair *last_pair;
  187. if(keys == NULL){
  188. keys = new_pair;
  189. } else {
  190. last_pair = keys;
  191. while(last_pair->next != NULL){
  192. last_pair = last_pair->next;
  193. }
  194. last_pair->next = new_pair;
  195. }
  196. sem_post(&key_lock);
  197. return 0;
  198. }
  199. //dh callback
  200. int slitheen_seed_from_tag(SSL *s, DH *dh)
  201. {
  202. int ok = 0;
  203. int generate_new_key = 0;
  204. unsigned l;
  205. BN_CTX *ctx;
  206. BN_MONT_CTX *mont = NULL;
  207. BIGNUM *pub_key = NULL, *priv_key= NULL;
  208. unsigned char *buf = NULL, *seed = NULL;
  209. int bytes = 0;
  210. byte key[16];
  211. //find key from keys list
  212. sem_wait(&key_lock);
  213. tag_pair *pair = keys;
  214. while(pair != NULL){
  215. if(!memcmp(pair->client_random, s->s3->client_random, SSL3_RANDOM_SIZE)){
  216. memcpy(key, pair->key, 16);
  217. break;
  218. }
  219. pair = pair->next;
  220. }
  221. if(pair == NULL){
  222. printf("ERROR: KEY NOT FOUND\n");
  223. sem_post(&key_lock);
  224. return 1;
  225. }
  226. sem_post(&key_lock);
  227. seed = (unsigned char *) key;
  228. ctx = BN_CTX_new();
  229. if (ctx == NULL)
  230. goto err;
  231. if (dh->priv_key == NULL) {
  232. priv_key = BN_new();
  233. if (priv_key == NULL)
  234. goto err;
  235. generate_new_key = 1;
  236. } else
  237. priv_key = dh->priv_key;
  238. if (dh->pub_key == NULL) {
  239. pub_key = BN_new();
  240. if (pub_key == NULL)
  241. goto err;
  242. } else
  243. pub_key = dh->pub_key;
  244. if (dh->flags & DH_FLAG_CACHE_MONT_P) {
  245. mont = BN_MONT_CTX_set_locked(&dh->method_mont_p,
  246. CRYPTO_LOCK_DH, dh->p, ctx);
  247. if (!mont)
  248. goto err;
  249. }
  250. if (generate_new_key) {
  251. /* secret exponent length */
  252. l = dh->length ? dh->length : BN_num_bits(dh->p) - 1;
  253. bytes = (l+7) / 8;
  254. /* set exponent to seeded prg value */
  255. buf = (unsigned char *)OPENSSL_malloc(bytes);
  256. if (buf == NULL){
  257. BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
  258. goto err;
  259. }
  260. PRF(seed, 16,
  261. (uint8_t *) SLITHEEN_KEYGEN_CONST, SLITHEEN_KEYGEN_CONST_SIZE,
  262. NULL, 0, NULL, 0, NULL, 0,
  263. buf, bytes);
  264. #ifdef DEBUG
  265. printf("Generated the following rand bytes: ");
  266. for(i=0; i< bytes; i++){
  267. printf(" %02x ", buf[i]);
  268. }
  269. printf("\n");
  270. #endif
  271. if (!BN_bin2bn(buf, bytes, priv_key))
  272. goto err;
  273. }
  274. {
  275. BIGNUM local_prk;
  276. BIGNUM *prk;
  277. if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) {
  278. BN_init(&local_prk);
  279. prk = &local_prk;
  280. BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME);
  281. } else
  282. prk = priv_key;
  283. if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont))
  284. goto err;
  285. }
  286. dh->pub_key = pub_key;
  287. dh->priv_key = priv_key;
  288. ok = 1;
  289. err:
  290. if (buf != NULL){
  291. OPENSSL_cleanse(buf, bytes);
  292. OPENSSL_free(buf);
  293. }
  294. if (ok != 1)
  295. DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB);
  296. if ((pub_key != NULL) && (dh->pub_key == NULL))
  297. BN_free(pub_key);
  298. if ((priv_key != NULL) && (dh->priv_key == NULL))
  299. BN_free(priv_key);
  300. BN_CTX_free(ctx);
  301. return (ok);
  302. }
  303. int slitheen_ec_seed_from_tag(SSL *s, EC_KEY *eckey){
  304. int ok = 0;
  305. BN_CTX *ctx = NULL;
  306. BIGNUM *priv_key = NULL, *order = NULL;
  307. EC_POINT *pub_key = NULL;
  308. unsigned l;
  309. unsigned char *buf = NULL, *seed = NULL;
  310. int bytes = 0;
  311. byte key[16];
  312. //find key from keys list
  313. sem_wait(&key_lock);
  314. tag_pair *pair = keys;
  315. while(pair != NULL){
  316. if(!memcmp(pair->client_random, s->s3->client_random, SSL3_RANDOM_SIZE)){
  317. memcpy(key, pair->key, 16);
  318. break;
  319. }
  320. pair = pair->next;
  321. }
  322. if(pair == NULL){
  323. printf("ERROR: KEY NOT FOUND\n");
  324. sem_post(&key_lock);
  325. return 1;
  326. }
  327. sem_post(&key_lock);
  328. #ifdef DEBUG
  329. printf("IN SLITHEEN EC GENERATE CALLBACK (key =");
  330. for(i=0; i< 16; i++){
  331. printf(" %02x", key[i]);
  332. }
  333. printf(")\n");
  334. #endif
  335. seed = (unsigned char *) key;
  336. if (!eckey || !EC_KEY_get0_group(eckey)) {
  337. ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
  338. return 0;
  339. }
  340. if ((order = BN_new()) == NULL)
  341. goto err;
  342. if ((ctx = BN_CTX_new()) == NULL)
  343. goto err;
  344. if (EC_KEY_get0_private_key(eckey) == NULL) {
  345. priv_key = BN_new();
  346. if (priv_key == NULL)
  347. goto err;
  348. } else
  349. priv_key = EC_KEY_get0_private_key(eckey);
  350. if (!EC_GROUP_get_order(EC_KEY_get0_group(eckey), order, ctx))
  351. goto err;
  352. /* secret exponent length */
  353. l = BN_num_bits(order) - 1;
  354. bytes = (l+7) / 8;
  355. /* set exponent to seeded prg value */
  356. buf = (unsigned char *)OPENSSL_malloc(bytes);
  357. if (buf == NULL){
  358. BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
  359. goto err;
  360. }
  361. PRF(seed, 16,
  362. (uint8_t *) SLITHEEN_KEYGEN_CONST, SLITHEEN_KEYGEN_CONST_SIZE,
  363. NULL, 0, NULL, 0, NULL, 0,
  364. buf, bytes);
  365. #ifdef DEBUG
  366. printf("Generated the following rand bytes: ");
  367. for(i=0; i< bytes; i++){
  368. printf(" %02x ", buf[i]);
  369. }
  370. printf("\n");
  371. #endif
  372. if (!BN_bin2bn(buf, bytes, priv_key))
  373. goto err;
  374. if (EC_KEY_get0_public_key(eckey) == NULL) {
  375. pub_key = EC_POINT_new(EC_KEY_get0_group(eckey));
  376. if (pub_key == NULL)
  377. goto err;
  378. } else
  379. pub_key = EC_KEY_get0_public_key(eckey);
  380. if (!EC_POINT_mul(EC_KEY_get0_group(eckey), pub_key, priv_key, NULL, NULL, ctx))
  381. goto err;
  382. EC_KEY_set_private_key(eckey, priv_key);
  383. EC_KEY_set_public_key(eckey, pub_key);
  384. ok = 1;
  385. err:
  386. if (buf != NULL){
  387. OPENSSL_cleanse(buf, bytes);
  388. OPENSSL_free(buf);
  389. }
  390. if (order)
  391. BN_free(order);
  392. if (pub_key != NULL && EC_KEY_get0_public_key(eckey) == NULL)
  393. EC_POINT_free(pub_key);
  394. if (priv_key != NULL && EC_KEY_get0_private_key(eckey) == NULL)
  395. BN_free(priv_key);
  396. if (ctx != NULL)
  397. BN_CTX_free(ctx);
  398. return (ok);
  399. }
  400. /* Finished_mac_callback
  401. *
  402. * This function checks the MAC both against the expected input, and additionally
  403. * with an extra shared-secret-based input to the MAC. If it passes the former, a
  404. * warning flag is set to indicate non-usage of the decoy routing protocol
  405. *
  406. * Returns 1 (ordinary) or 2 (modified) on success, 0 on failure
  407. */
  408. int slitheen_finished_mac(SSL *ssl, unsigned char *finished_mac){
  409. EVP_MD_CTX ctx;
  410. uint8_t output[2*EVP_MAX_MD_SIZE];
  411. uint32_t output_len;
  412. int i;
  413. uint8_t *modified_mac, *extra_input;
  414. uint32_t extra_input_len;
  415. byte key[16];
  416. EVP_MD_CTX_init(&ctx);
  417. modified_mac = calloc(1, ssl->s3->tmp.peer_finish_md_len);
  418. //find shared secret from keys list
  419. sem_wait(&key_lock);
  420. tag_pair *pair = keys;
  421. tag_pair *prev = NULL;
  422. while(pair != NULL){
  423. if(!memcmp(pair->client_random, ssl->s3->client_random, SSL3_RANDOM_SIZE)){
  424. memcpy(key, pair->key, 16);
  425. break;
  426. }
  427. prev = pair;
  428. pair = pair->next;
  429. }
  430. if(pair == NULL){
  431. printf("ERROR: KEY NOT FOUND\n");
  432. sem_post(&key_lock);
  433. return 1;
  434. }
  435. sem_post(&key_lock);
  436. //remove that key from the keys list: we are now done with it
  437. sem_wait(&key_lock);
  438. if (prev == NULL){
  439. keys = keys->next;
  440. free(pair);
  441. } else {
  442. prev->next = pair->next;
  443. free(pair);
  444. }
  445. sem_post(&key_lock);
  446. //compute extra input to finished from shared secret
  447. extra_input_len = SSL3_RANDOM_SIZE;
  448. extra_input = calloc(1, extra_input_len);
  449. PRF(ssl->session->master_key, ssl->session->master_key_length,
  450. (uint8_t *) SLITHEEN_FINISHED_INPUT_CONST, SLITHEEN_FINISHED_INPUT_CONST_SIZE,
  451. NULL, 0, NULL, 0, NULL, 0,
  452. extra_input, extra_input_len);
  453. //compute modified finish message from relay station
  454. EVP_MD_CTX *hdgst = NULL;
  455. for(i=0; i< SSL_MAX_DIGEST; i++){
  456. if(ssl->s3->handshake_dgst[i]){
  457. hdgst = ssl->s3->handshake_dgst[i]; //there are many of these, find right one(s)?
  458. }
  459. }
  460. if(!hdgst){
  461. printf("Could not find digest, skipping extra check\n");
  462. } else {
  463. EVP_MD_CTX_copy_ex(&ctx, hdgst);
  464. EVP_DigestUpdate(&ctx, extra_input, extra_input_len);
  465. EVP_DigestFinal_ex(&ctx, output, &output_len);
  466. PRF(ssl->session->master_key, ssl->session->master_key_length,
  467. (uint8_t *) TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
  468. output, output_len, NULL, 0, NULL, 0,
  469. modified_mac, ssl->s3->tmp.peer_finish_md_len);
  470. }
  471. #ifdef DEBUG
  472. printf("modified mac:\n");
  473. for(i=0; i<ssl->s3->tmp.peer_finish_md_len; i++){
  474. printf("%02x ", modified_mac[i]);
  475. }
  476. printf("\n");
  477. #endif
  478. //now add unmodified Finish message to the finish mac computation
  479. uint8_t *unmodified_finish = malloc(ssl->s3->tmp.peer_finish_md_len+4);
  480. memcpy(unmodified_finish, ssl->init_buf->data, 4);//copy header
  481. memcpy(unmodified_finish+4, ssl->s3->tmp.peer_finish_md, ssl->s3->tmp.peer_finish_md_len);
  482. printf("Unmodified hash:\n");
  483. for(i=0; i< ssl->s3->tmp.peer_finish_md_len; i++){
  484. printf("%02x ", ssl->s3->tmp.peer_finish_md[i]);
  485. }
  486. printf("\n");
  487. ssl3_finish_mac(ssl, unmodified_finish, ssl->s3->tmp.peer_finish_md_len + 4);
  488. free(unmodified_finish);
  489. int32_t retval = 0;
  490. //Compare MAC to what it should be
  491. if(CRYPTO_memcmp(finished_mac, ssl->s3->tmp.peer_finish_md, ssl->s3->tmp.peer_finish_md_len) != 0){
  492. //check to see if we have the modified MAC instead.
  493. if(CRYPTO_memcmp(finished_mac, modified_mac, ssl->s3->tmp.peer_finish_md_len) != 0){
  494. printf("MAC unknown\n");
  495. } else {
  496. retval = 2;
  497. printf("MAC was correctly modified!\n");
  498. }
  499. } else {
  500. retval = 1;
  501. printf("MAC was ordinary\n");
  502. }
  503. //clean up
  504. EVP_MD_CTX_cleanup(&ctx);
  505. OPENSSL_cleanse(extra_input, extra_input_len);
  506. OPENSSL_cleanse(output, output_len);
  507. return !retval;
  508. }