1 // thread procs for shallot
5 #include <stdint.h> // OpenBSD needs this included before sys/endian.h
7 #if defined(LINUX_PORT) || defined(OSX) || defined(GENERIC)
10 #include <sys/param.h> // OpenBSD needs this early on too
11 #include <sys/endian.h>
24 #include <openssl/rsa.h>
25 #include <openssl/sha.h>
27 void *worker(void *params
) { // life cycle of a cracking pthread
28 uint64_t e_be
; // storage for our "big endian" version of e
29 uint8_t buf
[SHA1_DIGEST_LEN
],
30 der
[RSA_EXP_DER_LEN
+ 1], // TODO: is the size of this right?
31 optimum
= *(uint8_t*)params
;
32 char onion
[BASE32_ONIONLEN
];
37 printf("Thread entering loop... (ID: 0x%X)\n", (uint32_t)pthread_self());
40 // keys are only generated every so often
41 // every 549,755,781,120 tries by default
43 printf("Generating new key... (ID: 0x%X)\n", (uint32_t)pthread_self());
46 rsa
= easygen(RSA_OPTM_BITLEN
- RSA_PK_E_LENGTH
* 8, RSA_PK_E_LENGTH
,
47 der
, RSA_OPT_DER_LEN
, &hash
);
49 rsa
= easygen(RSA_KEYS_BITLEN
, RSA_PK_E_LENGTH
, der
, RSA_EXP_DER_LEN
,
52 if(!rsa
) // if key generation fails (no [p]rng seed?)
53 error(X_KEY_GEN_FAILS
);
55 uint8_t e_bytes
= RSA_PK_E_LENGTH
; // number of bytes e occupies
56 uint64_t e
= RSA_PK_EXPONENT
; // public exponent
57 uint64_t e_byte_thresh
;
59 int_pow(2, e_bytes
* 8, &e_byte_thresh
);
62 uint8_t *e_ptr
= ((uint8_t*)&e_be
) + 8 - e_bytes
;
64 while((e
<= elim
) && !found
) { // main loop
65 // copy the relevant parts of our already set up context
66 memcpy(©
, &hash
, SHA_REL_CTX_LEN
); // 40 bytes here...
67 copy
.num
= hash
.num
; // and don't forget the num (9)
69 // convert e to big-endian format
72 // compute SHA1 digest (majority of loop time spent here!)
73 SHA1_Update(©
, e_ptr
, e_bytes
);
74 SHA1_Final(buf
, ©
);
76 base32_onion(onion
, buf
); // base32 encode SHA1 digest
77 loop
++; // keep track of our tries...
79 if(!regexec(regex
, onion
, 0, 0, 0)) { // check for a match
81 printf("Matching hash found, killing off other threads..."
82 " (ID: 0x%X)\n", (uint32_t)pthread_self());
84 // let our main thread know on which thread to wait
85 lucky_thread
= pthread_self();
86 found
= 1; // kill off our other threads, asyncronously
89 printf("\n"); // keep our printing pretty!
91 if(!BN_bin2bn(e_ptr
, e_bytes
, rsa
->e
)) // store our e in the actual key
92 error(X_BIGNUM_FAILED
); // and make sure it got there
94 if(!sane_key(rsa
)) // check our key
95 error(X_YOURE_UNLUCKY
); // bad key :(
98 printf("Public exponent (e) is 0x%llX.\n", e
);
100 print_onion(onion
); // print our domain
101 print_prkey(rsa
); // and more importantly the key
103 RSA_free(rsa
); // free up what's left
106 printf("Thread exiting loop... (ID: 0x%X)\n",
107 (uint32_t)pthread_self());
112 e
+= 2; // do *** NOT *** forget this!
114 if(e
== e_byte_thresh
) { // ASN.1 stuff (hey, it could be worse!)
115 // calculate our new threshold
116 int_pow(2, ++e_bytes
* 8, &e_byte_thresh
);
121 easygen(RSA_OPTM_BITLEN
- e_bytes
* 8, e_bytes
, der
, RSA_OPT_DER_LEN
,
125 error(X_KEY_GEN_FAILS
);
127 // play with our key structure (do not try this at home!)
128 der
[RSA_ADD_DER_OFF
]++;
129 der
[RSA_EXP_DER_LEN
- RSA_PK_E_LENGTH
- 1]++;
131 // and our prebuilt hash
132 SHA1_Init(&hash
); // TODO: move to a function
133 SHA1_Update(&hash
, der
, RSA_EXP_DER_LEN
- RSA_PK_E_LENGTH
);
136 e_ptr
--; // and move the pointer back
143 printf("Thread exiting loop... (ID: 0x%X)\n", (uint32_t)pthread_self());
148 void *monitor_proc(void *unused
) {
149 printf("\033[sPlease wait a moment for statistics...");
150 time_t start
= time(NULL
);
153 fflush(stdout
); // make sure it gets printed
159 time_t current
= time(NULL
);
160 time_t elapsed
= current
- start
;
163 continue; // be paranoid and avoid divide-by-zero exceptions
165 printf("\033[u\033[KHashes: %-20llu Time: %-10d Speed: %-llu",
166 loop
, (int)elapsed
, loop
/ elapsed
);
169 return 0; // unreachable code, but prevents warnings (!?)