Merge branch '2.5.x'
authorMark Wooding <mdw@distorted.org.uk>
Mon, 16 Dec 2019 17:21:25 +0000 (17:21 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Mon, 16 Dec 2019 17:21:25 +0000 (17:21 +0000)
* 2.5.x:
  debian/catacomb2.symbols: Bump versions for fixed functions.
  rand/rand.c: Mix the pool key in `rand_gate' and `rand_stretch'.
  rand/lcrand.c: Swap flags and max so generator not advertised as strong.
  pub/dh-kcdsa.c: Free the correct factor.
  math/limlee.c: Don't leak the factor vector on overall failure.
  math/limlee.c: Handle an abort from `pgen' correctly.
  math/pgen.c: Don't free the tester if it's not set up.
  math/ec-exp.h: Fix segfault when base point is at infinity.
  key/key-data.c (key_copydata): Fix catastrophic bug.
  key/key-data.c (key_split): Fix long-standing reference leak.
  key/key-misc.c (key_bytag): Don't give up because a by-id search fails.
  base/dispatch.c, etc.: Check that `rdrand' works.

base/dispatch.c
debian/catacomb2.symbols
key/key-data.c
key/key-misc.c
math/ec-exp.h
math/limlee.c
math/pgen.c
pub/dh-kcdsa.c
rand/lcrand.c
rand/rand.c

index c8bbc0b..459302f 100644 (file)
@@ -101,6 +101,59 @@ static int xmm_registers_available_p(void)
   return (f);
 }
 
+/* --- @rdrand_works_p@ --- *
+ *
+ *
+ * Arguments:  ---
+ *
+ * Returns:    Nonzero if the `rdrand' instruction actually works.  Assumes
+ *             that it's already been verified to be safe to issue.
+ */
+
+#ifdef __GNUC__
+static int rdrand(unsigned *x)
+{
+  int i, rc;
+  unsigned _t;
+
+  i = 16;
+  __asm__ ("" : "=g" (_t));
+  __asm__ ("0: rdrand %2; jc 1f; decl %1; jnz 0b\n"
+          "mov $-1, %0; jmp 9f\n"
+          "1: movl %2, (%3); xorl %0, %0\n"
+          "9:"
+          : "=r" (rc), "+r" (i), "+r" (_t)
+          : "r" (x)
+          : "cc");
+  return (rc);
+}
+#endif
+
+static int rdrand_works_p(void)
+{
+  unsigned ref, x, i;
+
+  /* Check that it doesn't always give the same answer.  Try four times: this
+   * will fail with probability %$2^{-128}$% with a truly random generator,
+   * which seems fair enough.
+   */
+  if (rdrand(&ref)) goto fail;
+  for (i = 0; i < 4; i++) {
+    if (rdrand(&x)) goto fail;
+    if (x != ref) goto not_stuck;
+  }
+  dispatch_debug("RDRAND always returns 0x%08x!", ref);
+  return (0);
+
+not_stuck:
+  dispatch_debug("RDRAND instruction looks plausible");
+  return (1);
+
+fail:
+  dispatch_debug("RDRAND instruction fails too often");
+  return (0);
+}
+
 #endif
 
 /*----- General feature probing using auxiliary vectors -------------------*/
@@ -453,7 +506,7 @@ int cpu_feature_p(int feat)
                 cpuid_features_p(CPUID1D_SSE2, CPUID1C_AESNI) &&
                 xmm_registers_available_p());
     CASE_CPUFEAT(X86_RDRAND, "x86:rdrand",
-                cpuid_features_p(0, CPUID1C_RDRAND));
+                cpuid_features_p(0, CPUID1C_RDRAND) && rdrand_works_p());
     CASE_CPUFEAT(X86_AVX, "x86:avx",
                 cpuid_features_p(0, CPUID1C_AVX) &&
                 xmm_registers_available_p());
index 36f4a56..772d218 100644 (file)
@@ -421,8 +421,8 @@ libcatacomb.so.2 catacomb2 #MINVER#
        strongprime@Base 2.3.1
 
 ## limlee
-       limlee_step@Base 2.2.4
-       limlee@Base 2.2.4
+       limlee_step@Base 2.5.1+
+       limlee@Base 2.5.1+
 
 ## gfx
        gfx_acc@Base 2.0.0
@@ -512,10 +512,10 @@ libcatacomb.so.2 catacomb2 #MINVER#
        ec_dbl@Base 2.2.0
        ec_neg@Base 2.2.0
        ec_sub@Base 2.2.0
-       ec_imul@Base 2.2.0
-       ec_mul@Base 2.2.0
-       ec_immul@Base 2.2.0
-       ec_mmul@Base 2.2.0
+       ec_imul@Base 2.5.1+
+       ec_mul@Base 2.5.1+
+       ec_immul@Base 2.5.1+
+       ec_mmul@Base 2.5.1+
        ec_check@Base 2.2.0
        ec_destroycurve@Base 2.2.0
        ec_idfix@Base 2.2.0
@@ -637,7 +637,7 @@ libcatacomb.so.2 catacomb2 #MINVER#
 
 ## lcrand
        lcrand@Base 2.0.0
-       lcrand_create@Base 2.0.0
+       lcrand_create@Base 2.5.1+
        lcrand_range@Base 2.0.0
 
 ## rand
@@ -646,7 +646,7 @@ libcatacomb.so.2 catacomb2 #MINVER#
        rand_seed@Base 2.2.3
        rand_quick@Base 2.2.3
        (optional|arch=i386 amd64)rand_quick_x86ish_rdrand@Base 2.5.0
-       rand_key@Base 2.2.3
+       rand_key@Base 2.5.1+
        rand_add@Base 2.2.3
        rand_goodbits@Base 2.2.3
        rand_get@Base 2.2.3
@@ -4221,8 +4221,8 @@ libcatacomb.so.2 catacomb2 #MINVER#
 
 ## dh
        dh_gen@Base 2.1.1
-       dh_kcdsagen@Base 2.1.1
-       dh_limlee@Base 2.2.4
+       dh_kcdsagen@Base 2.5.1+
+       dh_limlee@Base 2.5.1+
        dh_checkparam@Base 2.1.1
        dh_parse@Base 2.1.1
        dhbin_parse@Base 2.1.1
@@ -4353,9 +4353,9 @@ libcatacomb.so.2 catacomb2 #MINVER#
        key_structsteal@Base 2.1.1
        key_mksubkeyiter@Base 2.1.1
        key_nextsubkey@Base 2.1.1
-       key_copydata@Base 2.1.2
+       key_copydata@Base 2.5.1+
        key_incref@Base 2.1.1
-       key_split@Base 2.1.1
+       key_split@Base 2.5.1+
        key_drop@Base 2.1.1
        key_destroy@Base 2.1.1
        key_do@Base 2.1.1
@@ -4413,7 +4413,7 @@ libcatacomb.so.2 catacomb2 #MINVER#
 
 ## key-misc
        key_byid@Base 2.1.1
-       key_bytag@Base 2.1.1
+       key_bytag@Base 2.5.1+
        key_bytype@Base 2.1.1
        key_qtag@Base 2.1.1
        key_expired@Base 2.1.1
index 8b01d72..cd5c8d7 100644 (file)
@@ -153,6 +153,7 @@ void key_split(key_data **kk)
     default:
       abort();
   }
+  key_drop(k);
 }
 
 /*----- Setting new values ------------------------------------------------*/
@@ -427,8 +428,8 @@ static int structmatchp(key_data *k, const key_filter *kf)
 {
   key_subkeyiter i;
 
-  if (!KEY_MATCH(k, kf)) return (0);
-  else if ((k->e & KF_ENCMASK) == KENC_STRUCT) return (1);
+  if ((k->e & KF_ENCMASK) != KENC_STRUCT)
+    return (KEY_MATCH(k, kf));
   else {
     for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, 0, &k); )
       if (!structmatchp(k, kf)) return (0);
index c3442f2..0d969a8 100644 (file)
@@ -160,12 +160,12 @@ key *key_bytag(key_file *f, const char *tag)
   char *p;
   uint32 id;
   key_ref *kr = sym_find(&f->bytag, tag, -1, 0, 0);
+  key *k;
 
   if (kr && !(KEY_EXPIRED(t, kr->k->exp) && KEY_EXPIRED(t, kr->k->del)))
     return (kr->k);
   id = strtoul(tag, &p, 16);
-  if (!*p)
-    return (key_byid(f, id));
+  if (!*p && (k = key_byid(f, id)) != 0) return (k);
   return (key_bytype(f, tag));
 }
 
index 6cad753..b393d7e 100644 (file)
 #define EXP_TYPE ec
 
 #define EXP_COPY(d, p) do {                                            \
-  (d).x = MP_COPY((p).x);                                              \
-  (d).y = MP_COPY((p).y);                                              \
-  (d).z = (p).z ? MP_COPY((p).z) : MP_NEW;                             \
+  if (EC_ATINF(&(p)))                                                  \
+    (d).x = (d).y = (d).z = MP_NEW;                                    \
+  else {                                                               \
+    (d).x = MP_COPY((p).x);                                            \
+    (d).y = MP_COPY((p).y);                                            \
+    (d).z = (p).z ? MP_COPY((p).z) : MP_NEW;                           \
+  }                                                                    \
 } while (0)
 #define EXP_DROP(x) EC_DESTROY(&(x))
 
index fbed738..c99ba7b 100644 (file)
@@ -114,13 +114,10 @@ static void llgen(limlee_factor *f, unsigned pl, limlee_stepctx *l)
   rabin r;
   mp *p;
 
-again:
   p = mprand(l->newp, pl, l->r, 1);
   pf.step = 2;
   p = pgen(l->u.s.name, p, p, l->iev, l->iec, 0, pgen_filter, &pf,
           rabin_iters(pl), pgen_test, &r);
-  if (!p)
-    goto again;
   f->p = p;
 }
 
@@ -200,7 +197,7 @@ static int init(pgen_event *ev, limlee_stepctx *l)
 static int next(int rq, pgen_event *ev, limlee_stepctx *l)
 {
   dstr d = DSTR_INIT;
-  mp *p;
+  mp *p = 0;
   int rc;
   int dist;
   unsigned nb;
@@ -242,6 +239,8 @@ static int next(int rq, pgen_event *ev, limlee_stepctx *l)
        dstr_putf(&d, "%s_%lu", ev->name, l->seq++);
        l->u.s.name = d.buf;
        l->pops->pgen(&l->v[i], l->ql, l);
+       if (!l->v[i].p)
+         { mp_drop(mpmul_done(&mm)); rc = PGEN_ABORT; goto end; }
       }
       mpmul_add(&mm, l->v[i].p);
     }
@@ -254,6 +253,7 @@ static int next(int rq, pgen_event *ev, limlee_stepctx *l)
       dstr_putf(&d, "%s*_%lu", ev->name, l->seq++);
       l->u.s.name = d.buf;
       l->pops->pgen(&l->qq, l->pl - mp_bits(p), l);
+      if (!l->qq.p) { MP_DROP(p); p = 0; rc = PGEN_ABORT; break; }
       l->u.s.steps = l->u.s.disp = 0;
       p = mp_mul(p, p, l->qq.p);
     }
@@ -274,9 +274,10 @@ static int next(int rq, pgen_event *ev, limlee_stepctx *l)
 
     if ((rc = pfilt_smallfactor(p)) != PGEN_FAIL)
       break;
-    mp_drop(p);
+    MP_DROP(p); p = 0;
   }
 
+end:
   ev->m = p;
   DDESTROY(&d);
   return (rc);
@@ -389,6 +390,8 @@ mp *limlee(const char *name, mp *d, mp *newp,
 {
   limlee_stepctx l;
   rabin rr;
+  mp **v;
+  size_t i;
 
   l.f = 0; if (f) l.f |= LIMLEE_KEEPFACTORS;
   l.newp = newp;
@@ -401,15 +404,18 @@ mp *limlee(const char *name, mp *d, mp *newp,
   d = pgen(name, d, 0, oev, oec, on, limlee_step, &l,
           rabin_iters(pl), pgen_test, &rr);
 
-  if (d && f) {
-    mp **v;
-    size_t i;
-    v = xmalloc(l.nf * sizeof(mp *));
-    for (i = 0; i < l.nf; i++)
-      v[i] = l.v[i].p;
-    xfree(l.v);
-    *f = v;
-    *nf = l.nf;
+  if (f) {
+    if (!d) {
+      for (i = 0; i < l.nf; i++)
+       if (l.v[i].p) llfree(&l.v[i], &l);
+    } else {
+      v = xmalloc(l.nf * sizeof(mp *));
+      for (i = 0; i < l.nf; i++)
+       v[i] = l.v[i].p;
+      xfree(l.v);
+      *f = v;
+      *nf = l.nf;
+    }
   }
 
   return (d);
index f10d585..f060659 100644 (file)
@@ -283,7 +283,7 @@ mp *pgen(const char *name, mp *d, mp *m, pgen_proc *event, void *ectx,
       rc = PGEN_ABORT;
       if (!(act & A_DONE)) {
        act |= A_ENDSTEP | A_DONE;
-       if (p == P_TEST)
+       if (p == P_TEST && rq != PGEN_BEGIN)
          act |= A_ENDTEST;
       }
     }
index e773309..5feda92 100644 (file)
@@ -88,7 +88,7 @@ int dh_kcdsagen(dh_param *dp, unsigned ql, unsigned pl,
   dp->q = pgen("p", MP_NEW, x, ev, ec,
               steps, pgen_simulstep, &ss,
               rabin_iters(ql), pgen_simultest, &ss);
-  mp_drop(sp[0].mul);
+  mp_drop(sp[1].mul);
   if (!dp->q)
     goto fail_1;
   dp->p = sp[1].u.x;
index f0f01dd..f916c9c 100644 (file)
@@ -241,7 +241,7 @@ static uint32 grange(grand *r, uint32 l)
 
 static const grand_ops gops = {
   "lcrand",
-  LCRAND_P, 0,
+  0, LCRAND_P,
   gmisc, gdestroy,
   graw, gbyte, grand_defaultword, grange, grand_defaultfill
 };
index 5cca087..32605ac 100644 (file)
@@ -311,6 +311,7 @@ void rand_gate(rand_pool *r)
 
   HASH_INIT(&hc);
   STORE32(g, r->gen); HASH(&hc, g, sizeof(g));
+  HASH(&hc, r->k.k, RAND_KEYSZ);
   HASH(&hc, r->pool, RAND_POOLSZ);
   HASH(&hc, r->buf, RAND_BUFSZ);
   HASH_DONE(&hc, h);
@@ -361,6 +362,7 @@ void rand_stretch(rand_pool *r)
 
   HASH_INIT(&hc);
   STORE32(g, r->gen); HASH(&hc, g, sizeof(g));
+  HASH(&hc, r->k.k, RAND_KEYSZ);
   HASH(&hc, r->pool, RAND_POOLSZ);
   HASH(&hc, r->buf, RAND_BUFSZ);
   HASH_DONE(&hc, h);