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 -------------------*/
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());
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
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
## 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
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
## 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
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
## 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
default:
abort();
}
+ key_drop(k);
}
/*----- Setting new values ------------------------------------------------*/
{
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);
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));
}
#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))
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;
}
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;
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);
}
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);
}
if ((rc = pfilt_smallfactor(p)) != PGEN_FAIL)
break;
- mp_drop(p);
+ MP_DROP(p); p = 0;
}
+end:
ev->m = p;
DDESTROY(&d);
return (rc);
{
limlee_stepctx l;
rabin rr;
+ mp **v;
+ size_t i;
l.f = 0; if (f) l.f |= LIMLEE_KEEPFACTORS;
l.newp = 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);
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;
}
}
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;
static const grand_ops gops = {
"lcrand",
- LCRAND_P, 0,
+ 0, LCRAND_P,
gmisc, gdestroy,
graw, gbyte, grand_defaultword, grange, grand_defaultfill
};
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);
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);