From: Mark Wooding Date: Mon, 16 Dec 2019 17:21:25 +0000 (+0000) Subject: Merge branch '2.5.x' X-Git-Tag: 2.6.0~54 X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/commitdiff_plain/119bdfc4c80e313417047de10700e6b8c3955d0d?hp=7875ad25119a0099dfcfba3fbd256e404c722ff3 Merge branch '2.5.x' * 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. --- diff --git a/base/dispatch.c b/base/dispatch.c index c8bbc0b9..459302f0 100644 --- a/base/dispatch.c +++ b/base/dispatch.c @@ -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()); diff --git a/debian/catacomb2.symbols b/debian/catacomb2.symbols index 36f4a565..772d218e 100644 --- a/debian/catacomb2.symbols +++ b/debian/catacomb2.symbols @@ -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 diff --git a/key/key-data.c b/key/key-data.c index 8b01d725..cd5c8d78 100644 --- a/key/key-data.c +++ b/key/key-data.c @@ -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); diff --git a/key/key-misc.c b/key/key-misc.c index c3442f28..0d969a87 100644 --- a/key/key-misc.c +++ b/key/key-misc.c @@ -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)); } diff --git a/math/ec-exp.h b/math/ec-exp.h index 6cad7537..b393d7ec 100644 --- a/math/ec-exp.h +++ b/math/ec-exp.h @@ -37,9 +37,13 @@ #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)) diff --git a/math/limlee.c b/math/limlee.c index fbed738a..c99ba7bd 100644 --- a/math/limlee.c +++ b/math/limlee.c @@ -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); diff --git a/math/pgen.c b/math/pgen.c index f10d585f..f0606591 100644 --- a/math/pgen.c +++ b/math/pgen.c @@ -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; } } diff --git a/pub/dh-kcdsa.c b/pub/dh-kcdsa.c index e7733095..5feda92f 100644 --- a/pub/dh-kcdsa.c +++ b/pub/dh-kcdsa.c @@ -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; diff --git a/rand/lcrand.c b/rand/lcrand.c index f0f01ddf..f916c9c5 100644 --- a/rand/lcrand.c +++ b/rand/lcrand.c @@ -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 }; diff --git a/rand/rand.c b/rand/rand.c index 5cca087e..32605ac0 100644 --- a/rand/rand.c +++ b/rand/rand.c @@ -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);