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 // keys are only generated every so often
38 // every 549,755,781,120 tries by default
41 rsa
= easygen(RSA_OPTM_BITLEN
- RSA_PK_E_LENGTH
* 8, RSA_PK_E_LENGTH
,
42 der
, RSA_OPT_DER_LEN
, &hash
);
44 rsa
= easygen(RSA_KEYS_BITLEN
, RSA_PK_E_LENGTH
, der
, RSA_EXP_DER_LEN
,
47 if(!rsa
) // if key generation fails (no [p]rng seed?)
48 error(X_KEY_GEN_FAILS
);
50 uint8_t e_bytes
= RSA_PK_E_LENGTH
; // number of bytes e occupies
51 uint64_t e
= RSA_PK_EXPONENT
; // public exponent
52 uint64_t e_byte_thresh
;
54 int_pow(2, e_bytes
* 8, &e_byte_thresh
);
57 uint8_t *e_ptr
= ((uint8_t*)&e_be
) + 8 - e_bytes
;
59 while((e
<= elim
) && !found
) { // main loop
60 // copy the relevant parts of our already set up context
61 memcpy(©
, &hash
, SHA_REL_CTX_LEN
); // 40 bytes here...
62 copy
.num
= hash
.num
; // and don't forget the num (9)
64 // convert e to big-endian format
67 // compute SHA1 digest (majority of loop time spent here!)
68 SHA1_Update(©
, e_ptr
, e_bytes
);
69 SHA1_Final(buf
, ©
);
71 base32_onion(onion
, buf
); // base32 encode SHA1 digest
72 loop
++; // keep track of our tries...
74 if(!regexec(regex
, onion
, 0, 0, 0)) { // check for a match
76 // let our main thread know on which thread to wait
77 lucky_thread
= pthread_self();
78 found
= 1; // kill off our other threads, asyncronously
81 printf("\n"); // keep our printing pretty!
83 if(!BN_bin2bn(e_ptr
, e_bytes
, rsa
->e
)) // store our e in the actual key
84 error(X_BIGNUM_FAILED
); // and make sure it got there
86 if(!sane_key(rsa
)) // check our key
87 error(X_YOURE_UNLUCKY
); // bad key :(
89 print_onion(onion
); // print our domain
90 print_prkey(rsa
); // and more importantly the key
92 RSA_free(rsa
); // free up what's left
97 e
+= 2; // do *** NOT *** forget this!
99 if(e
== e_byte_thresh
) { // ASN.1 stuff (hey, it could be worse!)
100 // calculate our new threshold
101 int_pow(2, ++e_bytes
* 8, &e_byte_thresh
);
106 easygen(RSA_OPTM_BITLEN
- e_bytes
* 8, e_bytes
, der
, RSA_OPT_DER_LEN
,
110 error(X_KEY_GEN_FAILS
);
112 // play with our key structure (do not try this at home!)
113 der
[RSA_ADD_DER_OFF
]++;
114 der
[RSA_EXP_DER_LEN
- RSA_PK_E_LENGTH
- 1]++;
116 // and our prebuilt hash
117 SHA1_Init(&hash
); // TODO: move to a function
118 SHA1_Update(&hash
, der
, RSA_EXP_DER_LEN
- RSA_PK_E_LENGTH
);
121 e_ptr
--; // and move the pointer back
130 void *monitor_proc(void *unused
) {
131 printf("\033[sPlease wait a moment for statistics...");
132 time_t start
= time(NULL
);
135 fflush(stdout
); // make sure it gets printed
141 time_t current
= time(NULL
);
142 time_t elapsed
= current
- start
;
145 continue; // be paranoid and avoid divide-by-zero exceptions
147 printf("\033[u\033[KHashes: %-20llu Time: %-10d Speed: %-llu",
148 loop
, (int)elapsed
, loop
/ elapsed
);
151 return 0; // unreachable code, but prevents warnings (!?)