Parcourir la source

Merge branch 'feature/wiener' into fix/posix

This shit is just needed to have gen.c and thus make a proper Makefile under apps/
Michele Orrù il y a 11 ans
Parent
commit
4974cb084a

+ 0 - 1
Makefile.am

@@ -2,5 +2,4 @@
 SUBDIRS = src/
 AUTOMAKE_ARGS = --add-missing
 
-
 dist_doc_DATA = README

+ 36 - 0
book/wiener.tex

@@ -0,0 +1,36 @@
+\documentclass[10pt, a4paper]{report}
+\usepackage[a4paper,
+  inner=1.5cm, outer=3cm,
+  top=3cm, bottom=3cm,
+  bindingoffset=1cm]{geometry}
+\usepackage{minted}
+\usepackage{hyperref}
+
+\begin{document}
+
+\section{Bombelli's Algoritm}
+%% cuz python is pseudocode.
+\begin{minted}[fontsize=\small]{python}
+  def intsqrt(a):
+    i = 0
+    while a > 0:
+        g[i] = a % 100
+        a /= 100
+        i += 1
+
+    x = 0
+    r = 0
+    for j in range(L-1, -1, -1):
+        r = r*100 + g[j]
+        y = 0
+        for d in range(1, 10):
+            yn = d*(20*x + d)
+            if yn < r: y = yn
+            else: break
+        r -= y
+        x = 10*x + d-1
+    return (x, r)
+\end{minted}
+Has complexity $O(\log ^2 n)$.
+
+\end{document}

+ 1 - 1
configure.ac

@@ -25,4 +25,4 @@ AC_FUNC_ERROR_AT_LINE
 AC_FUNC_MALLOC
 #AC_CHECK_FUNCS([dup2 setlocale strdup])
 
-AC_OUTPUT([Makefile src/Makefile src/questions/Makefile])
+AC_OUTPUT([Makefile src/Makefile src/questions/Makefile src/apps/Makefile ])

+ 6 - 2
src/Makefile.am

@@ -1,6 +1,10 @@
-SUBDIRS = questions/
+SUBDIRS = questions/ apps/
+
 CC = clang
-AM_CFLAGS = --std=c99 -ggdb -lm -lssl -lcrypto -I include/ -I questions/
+
+AM_LDFLAGS = -lcrypto -lm -lssl
+AM_CFLAGS = --std=c99 -ggdb -I include/ -I questions/
+
 bin_PROGRAMS = qa
 qa_SOURCES = qa.c qa_sock.c cmdline.c
 qa_LDADD = questions/libquestions.a

+ 65 - 0
src/apps/gen.c

@@ -0,0 +1,65 @@
+/**
+ * \file gen.c
+ *
+ * Generate a fake RSA certificate file, given as input e, d, p, q.
+ */
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/bn.h>
+#include <openssl/ssl.h>
+#include <openssl/rsa.h>
+
+
+void usage(void)
+{
+  static const char* help_message = "%s usage: %s"
+    " <pub key> <priv key> <p> <q>"
+    "\n";
+  fprintf(stderr, help_message, program_invocation_short_name,
+          program_invocation_name);
+}
+
+int main(int argc, char **argv)
+{
+  BN_CTX* ctx;
+  BIGNUM* p1, *q1;
+  RSA* rsa;
+
+  rsa = RSA_new();
+  p1 = BN_new();
+  q1 = BN_new();
+  ctx = BN_CTX_new();
+  rsa->n = BN_new();
+  rsa->iqmp = BN_new();
+  rsa->dmp1 = BN_new();
+  rsa->dmq1 = BN_new();
+
+  if (argc < 4+1) {
+    usage();
+    return EXIT_FAILURE;
+  }
+
+  BN_dec2bn(&rsa->e, argv[1]);
+  BN_dec2bn(&rsa->d, argv[2]);
+  BN_dec2bn(&rsa->p, argv[3]);
+  BN_dec2bn(&rsa->q, argv[4]);
+  BN_mul(rsa->n, rsa->p, rsa->q, ctx);
+  BN_sub(p1, rsa->p, BN_value_one());
+  BN_sub(q1, rsa->q, BN_value_one());
+  BN_mod(rsa->dmq1, rsa->d, q1, ctx);
+  BN_mod(rsa->dmp1, rsa->d, p1, ctx);
+  BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx);
+  PEM_write_RSAPrivateKey(stdout, rsa, NULL, NULL, 0, NULL, NULL);
+
+
+  BN_CTX_free(ctx);
+  BN_free(q1);
+  BN_free(p1);
+  RSA_free(rsa);
+
+  return 0;
+}

+ 1 - 0
src/questions/Makefile.am

@@ -1,3 +1,4 @@
 
 lib_LIBRARIES = libquestions.a
 libquestions_a_SOURCES = wiener.c example.c allquestions.c
+# da fuck liquestions_a_HEADERS = qwiener.h questions.h

+ 5 - 0
src/questions/qwiener.h

@@ -21,10 +21,15 @@ typedef struct cf {
   BN_CTX* ctx;
 } cf_t;
 
+/* continued fractions utilities. */
 cf_t* cf_new(void);
 cf_t* cf_init(cf_t *f, BIGNUM *num, BIGNUM *b);
 bigfraction_t* cf_next(cf_t *f);
 
+/* square root calculation */
+int BN_sqrtmod(BIGNUM* dv, BIGNUM* rem, BIGNUM* a, BN_CTX* ctx);
+
+/* the actual attack */
 extern struct qa_question WienerQuestion;
 
 #endif /* _QA_WIENER_H_ */

+ 34 - 0
src/questions/test/test_wiener.c

@@ -70,8 +70,42 @@ void test_cf(void)
 }
 
 
+void test_BN_sqrtmod(void)
+{
+  BIGNUM *a, *b, *expected;
+  BIGNUM *root, *rem;
+  BIGNUM *mayzero;
+  BN_CTX *ctx;
+
+  root = BN_new();
+  rem = BN_new();
+  mayzero = BN_new();
+  ctx = BN_CTX_new();
+
+  BN_dec2bn(&a, "144");
+  BN_dec2bn(&expected, "12");
+  BN_sqrtmod(root, rem, a, ctx);
+  assert(!BN_cmp(expected, root));
+  assert(BN_is_zero(rem));
+
+  BN_dec2bn(&a, "15245419238964964");
+  BN_dec2bn(&expected, "123472342");
+  BN_sqrtmod(root, rem, a, ctx);
+  assert(!BN_cmp(root, expected));
+  assert(BN_is_zero(rem));
+
+  BN_free(root);
+  BN_free(rem);
+  BN_free(mayzero);
+  BN_CTX_free(ctx);
+  BN_free(a);
+  BN_free(expected);
+}
+
 int main(int argc, char ** argv)
 {
   test_cf();
+  test_BN_sqrtmod();
+
   return 0;
 }

+ 82 - 17
src/questions/wiener.c

@@ -1,3 +1,7 @@
+/**
+ * \file wiener.c
+ *
+ */
 #include <math.h>
 #include <stdlib.h>
 
@@ -8,17 +12,6 @@
 #include "questions.h"
 #include "qwiener.h"
 
-char * print_bignum(BIGNUM* n)
-{
-  char * dec;
-
-  dec = (char *) malloc(BN_num_bytes(n));
-  return dec = BN_bn2dec(n);
-  printf("%s\n", dec);
-
-  free(dec);
-}
-
 
 cf_t* cf_new(void)
 {
@@ -145,7 +138,56 @@ bigfraction_t* cf_next(cf_t *f)
   exit(EXIT_FAILURE);
 }
 
+
+int BN_sqrtmod(BIGNUM* dv, BIGNUM* rem, BIGNUM* a, BN_CTX* ctx)
+{
+  char *abn2dec, *bbn2dec;
+  int g[100];
+  long al, bl;
+  long x = 0, r = 0;
+  int i, j;
+  int d;
+  long y, yn;
+
+  abn2dec = BN_bn2dec(a);
+  sscanf(abn2dec, "%ld", &al);
+
+  r = 0;
+  x = 0;
+  for (i=0; al > 0; i++) {
+    g[i] = al%100;
+    al /= 100;
+  }
+
+  for (j=i-1; j>=0; j--) {
+    r = r*100 + g[j];
+    y = 0;
+    for (d=1; d!=10; d++) {
+      yn = d*(20*x + d);
+      if (yn <= r) y = yn; else break;
+    }
+    r -= y;
+    x = 10*x + d -1;
+  }
+
+  sprintf(abn2dec, "%ld", r);
+  BN_dec2bn(&rem, abn2dec);
+  sprintf(abn2dec, "%ld", x);
+  BN_dec2bn(&dv, abn2dec);
+
+
+  OPENSSL_free(abn2dec);
+
+  return BN_is_zero(rem);
+}
+
+
+/*
+ *  Weiner Attack Implementation
+ */
+
 int wiener_question_setup(void) { return 0; }
+
 int wiener_question_teardown(void) { return 0; }
 
 int wiener_question_test(X509* cert) { return 1; }
@@ -153,26 +195,49 @@ int wiener_question_test(X509* cert) { return 1; }
 
 int wiener_question_ask(X509* cert)
 {
-  struct rsa_st *rsa;
-  BIGNUM *n, *e;
-  BN_CTX* ctx;
+  RSA *rsa;
+  BIGNUM *n, *e, *d, *phi;
+  BIGNUM *t, *tmp, *rem;
   cf_t* cf;
+  bigfraction_t *it;
+  size_t  i;
 
-  ctx = BN_CTX_new();
+  phi = BN_new();
+  tmp = BN_new();
+  rem = BN_new();
   rsa = X509_get_pubkey(cert)->pkey.rsa;
   n = rsa->n;
   e = rsa->e;
 
   cf = cf_init(NULL, n, e);
-  while
 
+  for (i=0, it = cf_next(cf);
+       i!=100 && it;
+       i++, it = cf_next(cf)) {
+    t = it->h;
+    d = it->k;
+    BN_mul(phi, e, d, cf->ctx);
+    BN_sub(tmp, phi, BN_value_one());
+    BN_div(phi, rem, tmp, t, cf->ctx);
+
+    /* test 1: there shall be no rem */
+    if (!BN_is_zero(rem)) continue;
+
+    printf("Found? ");
+    BN_print_fp(stdout, e);
+    printf(" ");
+    BN_print_fp(stdout, d);
+    printf(" ");
+    BN_print_fp(stdout, phi);
+  }
 
+  cf_free(cf);
   return 0;
 }
 
 
 
-struct qa_question WienerQuestion = {
+qa_question_t WienerQuestion = {
   .name = "Wiener",
   .setup = wiener_question_setup,
   .teardown = wiener_question_teardown,