summaryrefslogtreecommitdiff
path: root/lib/lib6.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lib6.c')
-rw-r--r--lib/lib6.c216
1 files changed, 210 insertions, 6 deletions
diff --git a/lib/lib6.c b/lib/lib6.c
index 5999e91..85dbd9e 100644
--- a/lib/lib6.c
+++ b/lib/lib6.c
@@ -4,6 +4,7 @@
#include "lib3.h"
#include "lib2.h"
#include "lib.h"
+#include "util/set.h"
#include <openssl/sha.h>
@@ -31,21 +32,20 @@ int rsa_verify_bignum(BIGNUM *signed_message, BIGNUM *org_message, struct rsa_ke
**/
void pkcs1_5_padding(char *message, char *result, unsigned int target_length_byte)
{
- SHA1Context sha1;
+ SHA_CTX sha1;
char sha1_hash[20];
int i;
memset(result, 0xff, target_length_byte);
result[0] = 0x00;
- result[1] = 0x01;
+ result[1] = 0x02;
result[target_length_byte-21] = 0x00;
// TODO ASN.1 things
- SHA1Reset(&sha1);
- SHA1Input(&sha1, message, strlen(message));
- SHA1Result(&sha1);
- memcpy(sha1_hash, &(sha1.Message_Digest), 20);
+ SHA1_Init(&sha1);
+ SHA1_Update(&sha1, message, strlen(message));
+ SHA1_Final(sha1_hash, &sha1);
for(i = 20;i>0;i--)
result[target_length_byte-i] = sha1_hash[20-i];
@@ -95,6 +95,9 @@ int shitty_pkcs1_5_padding_verify(char *to_verify, int len, char *message)
return 0;
}
+ char buf[(1024/8)*2];
+ hex_binary_to_string(to_verify, buf, len);
+ printf("got:\n%s\n", buf);
return 1;
}
@@ -245,3 +248,204 @@ int rsa_parity_orcale(BIGNUM *message, struct rsa_key_bignum *private)
rsa_decrypt_bignum(message, decrypted, private);
return BN_is_odd(decrypted);
}
+
+int rsa_bleichenbacher_orcale(BIGNUM *ciphertext, struct rsa_key_bignum *priv)
+{
+ int ret = 0;
+ BIGNUM *plaintext = BN_new();
+ rsa_decrypt_bignum(ciphertext, plaintext, priv);
+ char *p = malloc(BN_num_bytes(plaintext));
+ BN_bn2bin(plaintext, p);
+
+ if(p[0] == 0x02)
+ ret = 1;
+
+ free(p);
+ BN_free(plaintext);
+ return ret;
+}
+
+int bleichenbacher_prepare(BIGNUM *c_0, struct rsa_key_bignum *public,
+ struct bb_attack *b)
+{
+ b->_2a = BN_new();
+ b->one = BN_new();
+ b->two = BN_new();
+ b->three = BN_new();
+ b->B = BN_new();
+ b->_2B = BN_new();
+ b->_3B = BN_new();
+ b->c_0 = BN_new();
+ BIGNUM *tmp2 = BN_new();
+
+ BN_set_word(b->one, 1);
+ BN_set_word(b->two, 2);
+ BN_set_word(b->three, 3);
+ BN_copy(b->c_0, c_0);
+
+ unsigned long long k = (BN_num_bytes(public->modulo) - 2) * 8;
+ BN_set_word(tmp2, k);
+ BN_mod_exp(b->B, b->two, tmp2, public->modulo, ctx);
+ BN_mod_mul(b->_3B, b->B, b->three, public->modulo, ctx);
+ BN_mod_mul(b->_2B, b->B, b->two, public->modulo, ctx);
+ BN_div(b->_2a, NULL, public->modulo, b->_3B, ctx);
+ printf("\n2a\n");
+ BN_print(out, b->_2a);
+ printf("\n");
+}
+
+int bleichenbacher_step_2a(BIGNUM *s_i, struct rsa_key_bignum *public,
+ struct rsa_key_bignum *private, struct bb_attack *b)
+{
+ printf("bleichenbacher attack: step 2a\n");
+ BIGNUM *new_c = BN_new();
+
+ // start from 2a = c_0/3B
+ BN_copy(s_i, b->_2a);
+ printf("start with s_i:\n");
+ BN_print(out, s_i);
+
+ while(1) {
+ // c_0 * s^e = m_0 * s
+ BN_mod_exp(new_c, s_i, public->exponent, public->modulo, ctx);
+ BN_mod_mul(new_c, new_c, b->c_0, public->modulo, ctx);
+ // asking orcale if this ciphertext has valid pkcs
+ if(rsa_bleichenbacher_orcale(new_c, private)) {
+ break;
+ }
+ // try next number
+ BN_mod_add(s_i, s_i, b->one, public->modulo, ctx);
+ }
+ printf("\ns_i from step 2a:\n");
+ BN_print(out, s_i);
+}
+/**
+ * when methods get called, s_i contains s_i-1
+ **/
+int bleichenbacher_step_2c(struct interval *m, BIGNUM *s_i, struct rsa_key_bignum *public,
+ struct rsa_key_bignum *private, struct bb_attack *b)
+{
+ BIGNUM *r_i = BN_new();
+ BIGNUM *r_i_start = BN_new();
+ BIGNUM *s_i_1 = BN_new();
+ BIGNUM *tmp= BN_new();
+ BIGNUM *si_upper = BN_new();
+ BIGNUM *si_lower = BN_new();
+ BIGNUM *new_c = BN_new();
+
+ BN_copy(s_i_1, s_i);
+ // TODO set it here to look if it works for the first step
+ BN_copy(m->lower, b->_2B);
+ BN_copy(m->upper, b->_3B);
+
+ BN_mul(tmp, s_i_1, m->upper, ctx);
+ BN_sub(tmp, tmp, b->_2B);
+ BN_mul(tmp, tmp, b->two, ctx);
+ BN_div(r_i_start, NULL, tmp, public->modulo, ctx);
+ printf("tmp:\n");
+ BN_print(out, tmp);
+
+ printf("\nr_i start is:\n");
+ BN_print(out, r_i_start);
+
+ printf("\nout out out\n");
+ // compute s_i intervall, increment r_i in this loop
+ while(1) {
+ BN_mul(tmp, r_i, public->modulo, ctx);
+ BN_add(si_lower, b->_2B, tmp);
+ BN_div(si_lower, NULL, si_lower, m->upper, ctx);
+ BN_add(si_upper, b->_3B, tmp);
+ BN_div(si_upper, NULL, si_upper, m->lower, ctx);
+ printf("\nsi_lower\n");
+ BN_print(out, si_lower);
+ printf("\nsi_upper\n");
+ BN_print(out, si_upper);
+ // try all s_i in [si_lower, si_upper]
+ while(BN_cmp(s_i, si_upper) != 1) {
+ // for all s_i between [si_lower, si_upper]
+ BN_mod_exp(tmp, s_i, public->exponent, public->modulo, ctx);
+ BN_mod_mul(new_c, tmp, b->c_0, public->modulo, ctx);
+ // try if we get valid pkcs padding
+ if(rsa_bleichenbacher_orcale(new_c, private))
+ goto found_si;
+
+ BN_add(s_i, s_i, b->one);
+ }
+ }
+
+
+found_si:
+ printf("found s_i in step 2c:\n");
+ BN_print(out, s_i);
+}
+
+/**
+ * Narrowing down the solution
+ **/
+
+/**
+int bleichenbacher_step_3(BIGNUM *s_i, set_t *m_i1)
+{
+ struct list *intervall, *head;
+ // compute m_i from m_i-1
+ LIST_TO_END(intervall, head) {
+
+ }
+
+}
+**/
+
+BIGNUM *BN_max(BIGNUM *e1, BIGNUM *e2)
+{
+ if(BN_cmp(e1, e2) == 1)
+ return e1;
+ else
+ return e2;
+}
+
+/**
+ * returns 1 if the intervall have been merged (one intervall),
+ * 2 if intevalls not overlapping (two intervalls)
+ **/
+int iv_merge2(struct interval *left, struct interval *right)
+{
+ if(!(BN_cmp(left->upper, right->lower) == -1)) {
+ BN_copy(left->upper, BN_max(left->upper, right->upper));
+ return 1;
+ }
+
+ return 2;
+}
+
+/**
+ * returns 1 if all three intervalls have merged to one, res in left
+ * returns 2 if the left + middle has been merged and the right not, res in left
+ * returns 3 if none have been merged
+ * retuern 4 if the middle and the right has been merged and left not, res in middle
+ *
+ **/
+
+int iv_merge3(struct interval *left, struct interval *middle, struct interval *rigth)
+{
+ if(iv_merge2(left, middle) == 1) {
+ if (iv_merge2(left, rigth) == 1)
+ return 1;
+ else
+ return 2;
+ } else {
+ if(iv_merge2(middle, rigth) == 1)
+ return 4;
+ else
+ return 3;
+ }
+
+}
+
+void iv_printf(struct interval *e1)
+{
+ printf("lower:");
+ BN_print(out, e1->lower);
+ printf("\nupper:");
+ BN_print(out, e1->upper);
+ printf("\n");
+}