Exemplo n.º 1
0
int
findkey(char *keyfile, char *host, RSApub *key)
{
	char *h;
	Biobuf *b;
	RSApub *k;

	if((b = Bopen(keyfile, OREAD)) == nil)
		return NoKeyFile;

	for(;;){
		if((k = readpublickey(b, &h)) == nil){
			Bterm(b);
			return NoKey;
		}
		if(match(h, host) != 0){
			free(h);
			rsapubfree(k);
			continue;
		}
		if(mpcmp(k->n, key->n) != 0 || mpcmp(k->ek, key->ek) != 0){
			free(h);
			rsapubfree(k);
			Bterm(b);
			return KeyWrong;
		}
		free(h);
		rsapubfree(k);
		Bterm(b);
		return KeyOk;
	}
}
Exemplo n.º 2
0
void
ecdsasign(ECdomain *dom, ECpriv *priv, uchar *dig, int len, mpint *r, mpint *s)
{
	ECpriv tmp;
	mpint *E, *t;

	tmp.x = mpnew(0);
	tmp.y = mpnew(0);
	tmp.d = mpnew(0);
	E = betomp(dig, len, nil);
	t = mpnew(0);
	if(mpsignif(dom->n) < 8*len)
		mpright(E, 8*len - mpsignif(dom->n), E);
	for(;;){
		ecgen(dom, &tmp);
		mpmod(tmp.x, dom->n, r);
		if(mpcmp(r, mpzero) == 0)
			continue;
		mpmul(r, priv->d, s);
		mpadd(E, s, s);
		mpinvert(tmp.d, dom->n, t);
		mpmul(s, t, s);
		mpmod(s, dom->n, s);
		if(mpcmp(s, mpzero) != 0)
			break;
	}
	mpfree(t);
	mpfree(E);
	mpfree(tmp.x);
	mpfree(tmp.y);
	mpfree(tmp.d);
}
Exemplo n.º 3
0
int
egverify(EGpub *pub, EGsig *sig, mpint *m)
{
	mpint *p = pub->p, *alpha = pub->alpha;
	mpint *r = sig->r, *s = sig->s;
	mpint *v1, *v2, *rs;
	int rv = -1;

	if(mpcmp(r, mpone) < 0 || mpcmp(r, p) >= 0)
		return rv;
	v1 = mpnew(0);
	rs = mpnew(0);
	v2 = mpnew(0);
	mpexp(pub->key, r, p, v1);
	mpexp(r, s, p, rs);
	mpmul(v1, rs, v1);
	mpmod(v1, p, v1);
	mpexp(alpha, m, p, v2);
	if(mpcmp(v1, v2) == 0)
		rv = 0;
	mpfree(v1);
	mpfree(rs);
	mpfree(v2);
	return rv;
}
Exemplo n.º 4
0
void
ecmul(ECdomain *dom, ECpoint *a, mpint *k, ECpoint *s)
{
	ECpoint ns, na;
	mpint *l;

	if(a->inf || mpcmp(k, mpzero) == 0){
		s->inf = 1;
		return;
	}
	ns.inf = 1;
	ns.x = mpnew(0);
	ns.y = mpnew(0);
	na.x = mpnew(0);
	na.y = mpnew(0);
	ecassign(dom, a, &na);
	l = mpcopy(k);
	l->sign = 1;
	while(mpcmp(l, mpzero) != 0){
		if(l->p[0] & 1)
			ecadd(dom, &na, &ns, &ns);
		ecadd(dom, &na, &na, &na);
		mpright(l, 1, l);
	}
	if(k->sign < 0){
		ns.y->sign = -1;
		mpmod(ns.y, dom->p, ns.y);
	}
	ecassign(dom, &ns, s);
	mpfree(ns.x);
	mpfree(ns.y);
	mpfree(na.x);
	mpfree(na.y);
}
Exemplo n.º 5
0
int
findkey(char *keyfile, char *host, RSApub *key)
{
	char *h;
	Biobuf *b;
	RSApub *k;
	int res;

	if ((b = Bopen(keyfile, OREAD)) == nil)
		return NoKeyFile;

	for (res = NoKey; res != KeyOk;) {
		if ((k = readpublickey(b, &h)) == nil)
			break;
		if (match(h, host) == 0) {
			if (mpcmp(k->n, key->n) == 0 &&
			    mpcmp(k->ek, key->ek) == 0)
				res = KeyOk;
			else
				res = KeyWrong;
		}
		free(h);
		free(k->ek);
		free(k->n);
		free(k);
	}
	Bterm(b);
	return res;
}
Exemplo n.º 6
0
// find a prime p of length n and a generator alpha of Z^*_p
// Alg 4.86 Menezes et al () Handbook, p.164
void
gensafeprime(mpint *p, mpint *alpha, int n, int accuracy)
{
	mpint *q, *b;

	q = mpnew(n-1);
	while(1){
		genprime(q, n-1, accuracy);
		mpleft(q, 1, p);
		mpadd(p, mpone, p); // p = 2*q+1
		if(probably_prime(p, accuracy))
			break;
	}
	// now find a generator alpha of the multiplicative
	// group Z*_p of order p-1=2q
	b = mpnew(0);
	while(1){
		mprand(n, genrandom, alpha);
		mpmod(alpha, p, alpha);
		mpmul(alpha, alpha, b);
		mpmod(b, p, b);
		if(mpcmp(b, mpone) == 0)
			continue;
		mpexp(alpha, q, p, b);
		if(mpcmp(b, mpone) != 0)
			break;
	}
	mpfree(b);
	mpfree(q);
}
Exemplo n.º 7
0
RSApriv*
rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q)
{
	mpint *c2, *kq, *kp, *x;
	RSApriv *rsa;

	// make sure we're not being hoodwinked
	if(!probably_prime(p, 10) || !probably_prime(q, 10)){
		werrstr("rsafill: p or q not prime");
		return nil;
	}
	x = mpnew(0);
	mpmul(p, q, x);
	if(mpcmp(n, x) != 0){
		werrstr("rsafill: n != p*q");
		mpfree(x);
		return nil;
	}
	c2 = mpnew(0);
	mpsub(p, mpone, c2);
	mpsub(q, mpone, x);
	mpmul(c2, x, x);
	mpmul(e, d, c2);
	mpmod(c2, x, x);
	if(mpcmp(x, mpone) != 0){
		werrstr("rsafill: e*d != 1 mod (p-1)*(q-1)");
		mpfree(x);
		mpfree(c2);
		return nil;
	}

	// compute chinese remainder coefficient
	mpinvert(p, q, c2);

	// for crt a**k mod p == (a**(k mod p-1)) mod p
	kq = mpnew(0);
	kp = mpnew(0);
	mpsub(p, mpone, x);
	mpmod(d, x, kp);
	mpsub(q, mpone, x);
	mpmod(d, x, kq);

	rsa = rsaprivalloc();
	rsa->pub.ek = mpcopy(e);
	rsa->pub.n = mpcopy(n);
	rsa->dk = mpcopy(d);
	rsa->kp = kp;
	rsa->kq = kq;
	rsa->p = mpcopy(p);
	rsa->q = mpcopy(q);
	rsa->c2 = c2;

	mpfree(x);

	return rsa;
}
Exemplo n.º 8
0
DSApriv*
dsagen(DSApub *opub)
{
	DSApub *pub;
	DSApriv *priv;
	mpint *exp;
	mpint *g;
	mpint *r;
	int bits;

	priv = dsaprivalloc();
	pub = &priv->pub;

	if(opub != nil){
		pub->p = mpcopy(opub->p);
		pub->q = mpcopy(opub->q);
	} else {
		pub->p = mpnew(0);
		pub->q = mpnew(0);
		DSAprimes(pub->q, pub->p, nil);
	}
	bits = Dbits*pub->p->top;

	pub->alpha = mpnew(0);
	pub->key = mpnew(0);
	priv->secret = mpnew(0);

	// find a generator alpha of the multiplicative
	// group Z*p, i.e., of order n = p-1.  We use the
	// fact that q divides p-1 to reduce the exponent.
	exp = mpnew(0);
	g = mpnew(0);
	r = mpnew(0);
	mpsub(pub->p, mpone, exp);
	mpdiv(exp, pub->q, exp, r);
	if(mpcmp(r, mpzero) != 0)
		sysfatal("dsagen foul up");
	while(1){
		mprand(bits, genrandom, g);
		mpmod(g, pub->p, g);
		mpexp(g, exp, pub->p, pub->alpha);
		if(mpcmp(pub->alpha, mpone) != 0)
			break;
	}
	mpfree(g);
	mpfree(exp);

	// create the secret key
	mprand(bits, genrandom, priv->secret);
	mpmod(priv->secret, pub->p, priv->secret);
	mpexp(pub->alpha, priv->secret, pub->p, pub->key);

	return priv;
}
Exemplo n.º 9
0
void
mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d)
{
	int i, ns, ds;

	ns = n->neg;
	ds = d->neg;
	n->neg = 0;
	d->neg = 0;

	mpmovefixfix(r, n);
	mpmovecfix(q, 0);

	// shift denominator until it
	// is larger than numerator
	for(i=0; i<Mpprec*Mpscale; i++) {
		if(mpcmp(d, r) > 0)
			break;
		mplsh(d);
	}

	// if it never happens
	// denominator is probably zero
	if(i >= Mpprec*Mpscale) {
		q->ovf = 1;
		r->ovf = 1;
		n->neg = ns;
		d->neg = ds;
		yyerror("set ovf in mpdivmodfixfix");
		return;
	}

	// shift denominator back creating
	// quotient a bit at a time
	// when done the remaining numerator
	// will be the remainder
	for(; i>0; i--) {
		mplsh(q);
		mprsh(d);
		if(mpcmp(d, r) <= 0) {
			mpaddcfix(q, 1);
			mpsubfixfix(r, d);
		}
	}

	n->neg = ns;
	d->neg = ds;
	r->neg = ns;
	q->neg = ns^ds;
}
Exemplo n.º 10
0
DSAsig*
dsasign(DSApriv *priv, mpint *m)
{
	DSApub *pub = &priv->pub;
	DSAsig *sig;
	mpint *qm1, *k, *kinv, *r, *s;
	mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
	int qlen = mpsignif(q);

	qm1 = mpnew(0);
	kinv = mpnew(0);
	r = mpnew(0);
	s = mpnew(0);
	k = mpnew(0);
	mpsub(pub->q, mpone, qm1);

	// find a k that has an inverse mod q
	while(1){
		mprand(qlen, genrandom, k);
		if((mpcmp(mpone, k) > 0) || (mpcmp(k, qm1) >= 0))
			continue;
		mpextendedgcd(k, q, r, kinv, s);
		if(mpcmp(r, mpone) != 0)
			continue;
		break;
	}

  	// make kinv positive
	mpmod(kinv, qm1, kinv);

	// r = ((alpha**k) mod p) mod q
	mpexp(alpha, k, p, r);
	mpmod(r, q, r);

	// s = (kinv*(m + ar)) mod q
	mpmul(r, priv->secret, s);
	mpadd(s, m, s);
	mpmul(s, kinv, s);
	mpmod(s, q, s);

	sig = dsasigalloc();
	sig->r = r;
	sig->s = s;
	mpfree(qm1);
	mpfree(k);
	mpfree(kinv);
	return sig;
}
Exemplo n.º 11
0
void
mpdivfract(Mpint *a, Mpint *b)
{
	Mpint n, d;
	int i, j, neg;
	long *a1, x;

	mpmovefixfix(&n, a);	// numerator
	mpmovefixfix(&d, b);	// denominator
	a1 = &a->a[Mpprec];	// quotient

	neg = n.neg ^ d.neg;
	n.neg = 0;
	d.neg = 0;

	for(i=0; i<Mpprec; i++) {
		x = 0;
		for(j=0; j<Mpscale; j++) {
			x <<= 1;
			if(mpcmp(&d, &n) <= 0) {
				x |= 1;
				mpsubfixfix(&n, &d);
			}
			mprsh(&d);
		}
		*--a1 = x;
	}
	a->neg = neg;
}
Exemplo n.º 12
0
Arquivo: pkcs1.c Projeto: zlxy/plan9
int
rsaverify(RSApub *key, DigestAlg *hash, uchar *digest, uint dlen,
          uchar *sig, uint siglen)
{
    uchar asn1[512], *buf;
    int n, len, pad;
    mpint *m, *mm, *s;

    /*
     * Create ASN.1
     */
    n = mkasn1(asn1, hash, digest, dlen);

    /*
     * Create number to sign.
     */
    len = (mpsignif(key->n)+7)/8 - 1;
    if(len < n+2) {
        werrstr("rsa key too short");
        return -1;
    }
    pad = len - (n+2);
    if(siglen < len) {
        werrstr("signature buffer too short");
        return -1;
    }
    buf = malloc(len);
    if(buf == nil)
        return -1;
    buf[0] = 0x01;
    memset(buf+1, 0xFF, pad);
    buf[1+pad] = 0x00;
    memmove(buf+1+pad+1, asn1, n);
    m = betomp(buf, len, nil);
    free(buf);
    if(m == nil)
        return -1;

    /*
     * Extract plaintext of signature.
     */
    s = betomp(sig, siglen, nil);
    if(s == nil)
        return -1;
    mm = rsaencrypt(key, s, nil);
    mpfree(s);
    if(mm == nil)
        return -1;
    if(mpcmp(m, mm) != 0) {
        werrstr("signature did not verify");
        mpfree(mm);
        mpfree(m);
        return -1;
    }
    mpfree(mm);
    mpfree(m);
    return 0;
}
Exemplo n.º 13
0
ECpriv*
ecgen(ECdomain *dom, ECpriv *p)
{
	if(p == nil){
		p = mallocz(sizeof(*p), 1);
		if(p == nil)
			return nil;
		p->x = mpnew(0);
		p->y = mpnew(0);
		p->d = mpnew(0);
	}
	for(;;){
		mprand(mpsignif(dom->n), genrandom, p->d);
		if(mpcmp(p->d, mpzero) > 0 && mpcmp(p->d, dom->n) < 0)
			break;
	}
	ecmul(dom, dom->G, p->d, p);
	return p;
}
Exemplo n.º 14
0
int
dsaverify(DSApub *pub, DSAsig *sig, mpint *m)
{
	int rv = -1;
	mpint *u1, *u2, *v, *sinv;

	if(sig->r->sign < 0 || mpcmp(sig->r, pub->q) >= 0)
		return rv;
	if(sig->s->sign < 0 || mpcmp(sig->s, pub->q) >= 0)
		return rv;
	u1 = mpnew(0);
	u2 = mpnew(0);
	v = mpnew(0);
	sinv = mpnew(0);

	// find (s**-1) mod q, make sure it exists
	mpextendedgcd(sig->s, pub->q, u1, sinv, v);
	if(mpcmp(u1, mpone) != 0)
		goto out;

	// u1 = (sinv * m) mod q, u2 = (r * sinv) mod q
	mpmul(sinv, m, u1);
	mpmod(u1, pub->q, u1);
	mpmul(sig->r, sinv, u2);
	mpmod(u2, pub->q, u2);

	// v = (((alpha**u1)*(key**u2)) mod p) mod q
	mpexp(pub->alpha, u1, pub->p, sinv);
	mpexp(pub->key, u2, pub->p, v);
	mpmul(sinv, v, v);
	mpmod(v, pub->p, v);
	mpmod(v, pub->q, v);

	if(mpcmp(v, sig->r) == 0)
		rv = 0;
out:
	mpfree(v);
	mpfree(u1);
	mpfree(u2);
	mpfree(sinv);
	return rv;
}
Exemplo n.º 15
0
static int
rsa_verify(mpint* m, void *sig, void *key)
{
	mpint *t;
	int r;

	t = rsaencrypt((RSApub*)key, (mpint*)sig, nil);
	r = mpcmp(t, m) == 0;
	mpfree(t);
	return r;
}
Exemplo n.º 16
0
int
ecdsaverify(ECdomain *dom, ECpub *pub, uchar *dig, int len, mpint *r, mpint *s)
{
	mpint *E, *t, *u1, *u2;
	ECpoint R, S;
	int ret;

	if(mpcmp(r, mpone) < 0 || mpcmp(s, mpone) < 0 || mpcmp(r, dom->n) >= 0 || mpcmp(r, dom->n) >= 0)
		return 0;
	E = betomp(dig, len, nil);
	if(mpsignif(dom->n) < 8*len)
		mpright(E, 8*len - mpsignif(dom->n), E);
	t = mpnew(0);
	u1 = mpnew(0);
	u2 = mpnew(0);
	R.x = mpnew(0);
	R.y = mpnew(0);
	S.x = mpnew(0);
	S.y = mpnew(0);
	mpinvert(s, dom->n, t);
	mpmul(E, t, u1);
	mpmod(u1, dom->n, u1);
	mpmul(r, t, u2);
	mpmod(u2, dom->n, u2);
	ecmul(dom, dom->G, u1, &R);
	ecmul(dom, pub, u2, &S);
	ecadd(dom, &R, &S, &R);
	ret = 0;
	if(!R.inf){
		mpmod(R.x, dom->n, t);
		ret = mpcmp(r, t) == 0;
	}
	mpfree(t);
	mpfree(u1);
	mpfree(u2);
	mpfree(R.x);
	mpfree(R.y);
	mpfree(S.x);
	mpfree(S.y);
	return ret;
}
Exemplo n.º 17
0
// use extended gcd to find the multiplicative inverse
// res = b**-1 mod m
void
mpinvert(mpint *b, mpint *m, mpint *res)
{
	mpint *dc1, *dc2;	// don't care

	dc1 = mpnew(0);
	dc2 = mpnew(0);
	mpextendedgcd(b, m, dc1, res, dc2);
	if(mpcmp(dc1, mpone) != 0)
		abort();
	mpmod(res, m, res);
	mpfree(dc1);
	mpfree(dc2);
}
Exemplo n.º 18
0
static int
mpleg(mpint *a, mpint *b)
{
	int r, k;
	mpint *m, *n, *t;
	
	r = 1;
	m = mpcopy(a);
	n = mpcopy(b);
	for(;;){
		if(mpcmp(m, n) > 0)
			mpmod(m, n, m);
		if(mpcmp(m, mpzero) == 0){
			r = 0;
			break;
		}
		if(mpcmp(m, mpone) == 0)
			break;
		k = mplowbits0(m);
		if(k > 0){
			if(k & 1)
				switch(n->p[0] & 15){
				case 3: case 5: case 11: case 13:
					r = -r;
				}
			mpright(m, k, m);
		}
		if((n->p[0] & 3) == 3 && (m->p[0] & 3) == 3)
			r = -r;
		t = m;
		m = n;
		n = t;
	}
	mpfree(m);
	mpfree(n);
	return r;
}
Exemplo n.º 19
0
Arquivo: meta.c Projeto: aiju/hdl
static int
metacond(ASTNode *c)
{
	c = onlyone(metarun(c));
	if(c == nil){
		error(nil, "metacond: nil");
		return -1;
	}
	if(c->t == ASTCINT)
		return c->i != 0;
	if(c->t == ASTCONST)
		return mpcmp(c->cons.n, mpzero) != 0;
	error(c, "if: unresolved %n", c);
	return -1;
}
Exemplo n.º 20
0
int
mptestfix(Mpint *a)
{
	Mpint b;
	int r;

	mpmovecfix(&b, 0);
	r = mpcmp(a, &b);
	if(a->neg) {
		if(r > 0)
			return -1;
		if(r < 0)
			return +1;
	}
	return r;
}
Exemplo n.º 21
0
void
base58enc(uchar *src, char *dst, int len)
{
	mpint *n, *r, *b;
	char *sdst, t;
	
	sdst = dst;
	n = betomp(src, len, nil);
	b = uitomp(58, nil);
	r = mpnew(0);
	while(mpcmp(n, mpzero) != 0){
		mpdiv(n, b, n, r);
		*dst++ = code[mptoui(r)];
	}
	for(; *src == 0; src++)
		*dst++ = code[0];
	dst--;
	while(dst > sdst){
		t = *sdst;
		*sdst++ = *dst;
		*dst-- = t;
	}
}
Exemplo n.º 22
0
int
ecverify(ECdomain *dom, ECpoint *a)
{
	mpint *p, *q;
	int r;

	if(a->inf)
		return 1;
	
	p = mpnew(0);
	q = mpnew(0);
	mpmul(a->y, a->y, p);
	mpmod(p, dom->p, p);
	mpmul(a->x, a->x, q);
	mpadd(q, dom->a, q);
	mpmul(a->x, q, q);
	mpadd(q, dom->b, q);
	mpmod(q, dom->p, q);
	r = mpcmp(p, q);
	mpfree(p);
	mpfree(q);
	return r == 0;
}
Exemplo n.º 23
0
/*
 * Miller-Rabin probabilistic primality testing
 *	Knuth (1981) Seminumerical Algorithms, p.379
 *	Menezes et al () Handbook, p.39
 * 0 if composite; 1 if almost surely prime, Pr(err)<1/4**nrep
 */
int
probably_prime(mpint *n, int nrep)
{
	int j, k, rep, nbits, isprime;
	mpint *nm1, *q, *x, *y, *r;

	if(n->sign < 0)
		sysfatal("negative prime candidate");

	if(nrep <= 0)
		nrep = 18;

	k = mptoi(n);
	if(k == 2)		/* 2 is prime */
		return 1;
	if(k < 2)		/* 1 is not prime */
		return 0;
	if((n->p[0] & 1) == 0)	/* even is not prime */
		return 0;

	/* test against small prime numbers */
	if(smallprimetest(n) < 0)
		return 0;

	/* fermat test, 2^n mod n == 2 if p is prime */
	x = uitomp(2, nil);
	y = mpnew(0);
	mpexp(x, n, n, y);
	k = mptoi(y);
	if(k != 2){
		mpfree(x);
		mpfree(y);
		return 0;
	}

	nbits = mpsignif(n);
	nm1 = mpnew(nbits);
	mpsub(n, mpone, nm1);	/* nm1 = n - 1 */
	k = mplowbits0(nm1);
	q = mpnew(0);
	mpright(nm1, k, q);	/* q = (n-1)/2**k */

	for(rep = 0; rep < nrep; rep++){
		for(;;){
			/* find x = random in [2, n-2] */
		 	r = mprand(nbits, prng, nil);
		 	mpmod(r, nm1, x);
		 	mpfree(r);
		 	if(mpcmp(x, mpone) > 0)
		 		break;
		}

		/* y = x**q mod n */
		mpexp(x, q, n, y);

		if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0)
		 	continue;

		for(j = 1;; j++){
		 	if(j >= k) {
		 		isprime = 0;
		 		goto done;
		 	}
		 	mpmul(y, y, x);
		 	mpmod(x, n, y);	/* y = y*y mod n */
		 	if(mpcmp(y, nm1) == 0)
		 		break;
		 	if(mpcmp(y, mpone) == 0){
		 		isprime = 0;
		 		goto done;
		 	}
		}
	}
	isprime = 1;
done:
	mpfree(y);
	mpfree(x);
	mpfree(q);
	mpfree(nm1);
	return isprime;
}
Exemplo n.º 24
0
static int
mpsqrt(mpint *n, mpint *p, mpint *r)
{
	mpint *a, *t, *s, *xp, *xq, *yp, *yq, *zp, *zq, *N;

	if(mpleg(n, p) == -1)
		return 0;
	a = mpnew(0);
	t = mpnew(0);
	s = mpnew(0);
	N = mpnew(0);
	xp = mpnew(0);
	xq = mpnew(0);
	yp = mpnew(0);
	yq = mpnew(0);
	zp = mpnew(0);
	zq = mpnew(0);
	for(;;){
		for(;;){
			mprand(mpsignif(p), genrandom, a);
			if(mpcmp(a, mpzero) > 0 && mpcmp(a, p) < 0)
				break;
		}
		mpmul(a, a, t);
		mpsub(t, n, t);
		mpmod(t, p, t);
		if(mpleg(t, p) == -1)
			break;
	}
	mpadd(p, mpone, N);
	mpright(N, 1, N);
	mpmul(a, a, t);
	mpsub(t, n, t);
	mpassign(a, xp);
	uitomp(1, xq);
	uitomp(1, yp);
	uitomp(0, yq);
	while(mpcmp(N, mpzero) != 0){
		if(N->p[0] & 1){
			mpmul(xp, yp, zp);
			mpmul(xq, yq, zq);
			mpmul(zq, t, zq);
			mpadd(zp, zq, zp);
			mpmod(zp, p, zp);
			mpmul(xp, yq, zq);
			mpmul(xq, yp, s);
			mpadd(zq, s, zq);
			mpmod(zq, p, yq);
			mpassign(zp, yp);
		}
		mpmul(xp, xp, zp);
		mpmul(xq, xq, zq);
		mpmul(zq, t, zq);
		mpadd(zp, zq, zp);
		mpmod(zp, p, zp);
		mpmul(xp, xq, zq);
		mpadd(zq, zq, zq);
		mpmod(zq, p, xq);
		mpassign(zp, xp);
		mpright(N, 1, N);
	}
	if(mpcmp(yq, mpzero) != 0)
		abort();
	mpassign(yp, r);
	mpfree(a);
	mpfree(t);
	mpfree(s);
	mpfree(N);
	mpfree(xp);
	mpfree(xq);
	mpfree(yp);
	mpfree(yq);
	mpfree(zp);
	mpfree(zq);
	return 1;
}
Exemplo n.º 25
0
void
mpaddfixfix(Mpint *a, Mpint *b)
{
	int i, c;
	long x, *a1, *b1;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mpaddxx");
		a->ovf = 1;
		return;
	}

	c = 0;
	a1 = &a->a[0];
	b1 = &b->a[0];
	if(a->neg != b->neg)
		goto sub;

	// perform a+b
	for(i=0; i<Mpprec; i++) {
		x = *a1 + *b1++ + c;
		c = 0;
		if(x >= Mpbase) {
			x -= Mpbase;
			c = 1;
		}
		*a1++ = x;
	}
	a->ovf = c;
	if(a->ovf)
		yyerror("set ovf in mpaddxx");

	return;

sub:
	// perform a-b
	switch(mpcmp(a, b)) {
	case 0:
		mpmovecfix(a, 0);
		break;

	case 1:
		for(i=0; i<Mpprec; i++) {
			x = *a1 - *b1++ - c;
			c = 0;
			if(x < 0) {
				x += Mpbase;
				c = 1;
			}
			*a1++ = x;
		}
		break;

	case -1:
		a->neg ^= 1;
		for(i=0; i<Mpprec; i++) {
			x = *b1++ - *a1 - c;
			c = 0;
			if(x < 0) {
				x += Mpbase;
				c = 1;
			}
			*a1++ = x;
		}
		break;
	}
}
Exemplo n.º 26
0
// extended binary gcd
//
// For a anv b it solves, v = gcd(a,b) and finds x and y s.t.
// ax + by = v
//
// Handbook of Applied Cryptography, Menezes et al, 1997, pg 608.  
void
mpextendedgcd(mpint *a, mpint *b, mpint *v, mpint *x, mpint *y)
{
	mpint *u, *A, *B, *C, *D;
	int g;

	if(a->top == 0){
		mpassign(b, v);
		mpassign(mpone, y);
		mpassign(mpzero, x);
		return;
	}
	if(b->top == 0){
		mpassign(a, v);
		mpassign(mpone, x);
		mpassign(mpzero, y);
		return;
	}

	g = 0;
	a = mpcopy(a);
	b = mpcopy(b);

	while(iseven(a) && iseven(b)){
		mpright(a, 1, a);
		mpright(b, 1, b);
		g++;
	}

	u = mpcopy(a);
	mpassign(b, v);
	A = mpcopy(mpone);
	B = mpcopy(mpzero);
	C = mpcopy(mpzero);
	D = mpcopy(mpone);

	for(;;) {
//		print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
		while(iseven(u)){
			mpright(u, 1, u);
			if(!iseven(A) || !iseven(B)) {
				mpadd(A, b, A);
				mpsub(B, a, B);
			}
			mpright(A, 1, A);
			mpright(B, 1, B);
		}
	
//		print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
		while(iseven(v)){
			mpright(v, 1, v);
			if(!iseven(C) || !iseven(D)) {
				mpadd(C, b, C);
				mpsub(D, a, D);
			}
			mpright(C, 1, C);
			mpright(D, 1, D);
		}
	
//		print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
		if(mpcmp(u, v) >= 0){
			mpsub(u, v, u);
			mpsub(A, C, A);
			mpsub(B, D, B);
		} else {
			mpsub(v, u, v);
			mpsub(C, A, C);
			mpsub(D, B, D);
		}

		if(u->top == 0)
			break;

	}
	mpassign(C, x);
	mpassign(D, y);
	mpleft(v, g, v);

	mpfree(A);
	mpfree(B);
	mpfree(C);
	mpfree(D);
	mpfree(u);
	mpfree(a);
	mpfree(b);
}
Exemplo n.º 27
0
RSApriv*
rsagen(int nlen, int elen, int rounds)
{
	mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2;
	RSApriv *rsa;

	p = mpnew(nlen/2);
	q = mpnew(nlen/2);
	n = mpnew(nlen);
	e = mpnew(elen);
	d = mpnew(0);
	phi = mpnew(nlen);

	// create the prime factors and euclid's function
	genprime(p, nlen/2, rounds);
	genprime(q, nlen - mpsignif(p) + 1, rounds);
	mpmul(p, q, n);
	mpsub(p, mpone, e);
	mpsub(q, mpone, d);
	mpmul(e, d, phi);

	// find an e relatively prime to phi
	t1 = mpnew(0);
	t2 = mpnew(0);
	mprand(elen, genrandom, e);
	if(mpcmp(e,mptwo) <= 0)
		itomp(3, e);
	// See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion
	// of the merits of various choices of primes and exponents.  e=3 is a
	// common and recommended exponent, but doesn't necessarily work here
	// because we chose strong rather than safe primes.
	for(;;){
		mpextendedgcd(e, phi, t1, d, t2);
		if(mpcmp(t1, mpone) == 0)
			break;
		mpadd(mpone, e, e);
	}
	mpfree(t1);
	mpfree(t2);

	// compute chinese remainder coefficient
	c2 = mpnew(0);
	mpinvert(p, q, c2);

	// for crt a**k mod p == (a**(k mod p-1)) mod p
	kq = mpnew(0);
	kp = mpnew(0);
	mpsub(p, mpone, phi);
	mpmod(d, phi, kp);
	mpsub(q, mpone, phi);
	mpmod(d, phi, kq);

	rsa = rsaprivalloc();
	rsa->pub.ek = e;
	rsa->pub.n = n;
	rsa->dk = d;
	rsa->kp = kp;
	rsa->kq = kq;
	rsa->p = p;
	rsa->q = q;
	rsa->c2 = c2;

	mpfree(phi);

	return rsa;
}
Exemplo n.º 28
0
static int
dorsa(mpint *mod, mpint *exp, mpint *chal, uint8_t chalbuf[32])
{
	int afd;
	AuthRpc *rpc;
	mpint *m;
	char buf[4096], *p;
	mpint *decr, *unpad;

	USED(exp);

	snprint(buf, sizeof buf, "proto=rsa service=ssh role=client");
	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
		debug(DBG_AUTH, "open /mnt/factotum/rpc: %r\n");
		return -1;
	}
	if((rpc = auth_allocrpc(afd)) == nil){
		debug(DBG_AUTH, "auth_allocrpc: %r\n");
		close(afd);
		return -1;
	}
	if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
		debug(DBG_AUTH, "auth_rpc start failed: %r\n");
	Die:
		auth_freerpc(rpc);
		close(afd);
		return -1;
	}
	m = nil;
	debug(DBG_AUTH, "trying factotum rsa keys\n");
	while(auth_rpc(rpc, "read", nil, 0) == ARok){
		debug(DBG_AUTH, "try %s\n", (char*)rpc->arg);
		m = strtomp(rpc->arg, nil, 16, nil);
		if(mpcmp(m, mod) == 0)
			break;
		mpfree(m);
		m = nil;
	}
	if(m == nil)
		goto Die;
	mpfree(m);
	
	p = mptoa(chal, 16, nil, 0);
	if(p == nil){
		debug(DBG_AUTH, "\tmptoa failed: %r\n");
		goto Die;
	}
	if(auth_rpc(rpc, "write", p, strlen(p)) != ARok){
		debug(DBG_AUTH, "\tauth_rpc write failed: %r\n");
		free(p);
		goto Die;
	}
	free(p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok){
		debug(DBG_AUTH, "\tauth_rpc read failed: %r\n");
		goto Die;
	}
	decr = strtomp(rpc->arg, nil, 16, nil);
	if(decr == nil){
		debug(DBG_AUTH, "\tdecr %s failed\n", rpc->arg);
		goto Die;
	}
	debug(DBG_AUTH, "\tdecrypted %B\n", decr);
	unpad = rsaunpad(decr);
	if(unpad == nil){
		debug(DBG_AUTH, "\tunpad %B failed\n", decr);
		mpfree(decr);
		goto Die;
	}
	debug(DBG_AUTH, "\tunpadded %B\n", unpad);
	mpfree(decr);
	mptoberjust(unpad, chalbuf, 32);
	mpfree(unpad);
	auth_freerpc(rpc);
	close(afd);
	return 0;
}
Exemplo n.º 29
0
void
sshserverhandshake(Conn *c)
{
	char *p, buf[128];
	Biobuf *b;
	Attr *a;
	int i, afd;
	mpint *m;
	AuthRpc *rpc;
	RSApub *key;

	/*
	 * BUG: should use `attr' to get the key attributes
	 * after the read, but that's not implemented yet.
	 */
	if((b = Bopen("/mnt/factotum/ctl", OREAD)) == nil)
		sysfatal("open /mnt/factotum/ctl: %r");
	while((p = Brdline(b, '\n')) != nil){
		p[Blinelen(b)-1] = '\0';
		if(strstr(p, " proto=rsa ") && strstr(p, " service=sshserve "))
			break;
	}
	if(p == nil)
		sysfatal("no sshserve keys found in /mnt/factotum/ctl");
	a = _parseattr(p);
	Bterm(b);
	key = emalloc(sizeof(*key));
	if((p = _strfindattr(a, "n")) == nil)
		sysfatal("no n in sshserve key");
	if((key->n = strtomp(p, &p, 16, nil)) == nil || *p != 0)
		sysfatal("bad n in sshserve key");
	if((p = _strfindattr(a, "ek")) == nil)
		sysfatal("no ek in sshserve key");
	if((key->ek = strtomp(p, &p, 16, nil)) == nil || *p != 0)
		sysfatal("bad ek in sshserve key");
	_freeattr(a);

	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
		sysfatal("open /mnt/factotum/rpc: %r");
	if((rpc = auth_allocrpc(afd)) == nil)
		sysfatal("auth_allocrpc: %r");
	p = "proto=rsa role=client service=sshserve";
	if(auth_rpc(rpc, "start", p, strlen(p)) != ARok)
		sysfatal("auth_rpc start %s: %r", p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok)
		sysfatal("auth_rpc read: %r");
	m = strtomp(rpc->arg, nil, 16, nil);
	if(mpcmp(m, key->n) != 0)
		sysfatal("key in /mnt/factotum/ctl does not match rpc key");
	mpfree(m);
	c->hostkey = key;

	/* send id string */
	fprint(c->fd[0], "SSH-1.5-Plan9\n");

	/* receive id string */
	if(readstrnl(c->fd[0], buf, sizeof buf) < 0)
		sysfatal("reading server version: %r");

	/* id string is "SSH-m.n-comment".  We need m=1, n>=5. */
	if(strncmp(buf, "SSH-", 4) != 0
	|| strtol(buf+4, &p, 10) != 1
	|| *p != '.'
	|| strtol(p+1, &p, 10) < 5
	|| *p != '-')
		sysfatal("protocol mismatch; got %s, need SSH-1.x for x>=5", buf);

	for(i=0; i<COOKIELEN; i++)
		c->cookie[i] = fastrand();
	calcsessid(c);
	send_ssh_smsg_public_key(c);
	recv_ssh_cmsg_session_key(c, rpc);
	auth_freerpc(rpc);
	close(afd);

	c->cstate = (*c->cipher->init)(c, 1);		/* turns on encryption */
	sendmsg(allocmsg(c, SSH_SMSG_SUCCESS, 0));

	authsrvuser(c);
}
Exemplo n.º 30
0
void
ecadd(ECdomain *dom, ECpoint *a, ECpoint *b, ECpoint *s)
{
	mpint *l, *k, *sx, *sy;

	if(a->inf && b->inf){
		s->inf = 1;
		return;
	}
	if(a->inf){
		ecassign(dom, b, s);
		return;
	}
	if(b->inf){
		ecassign(dom, a, s);
		return;
	}
	if(mpcmp(a->x, b->x) == 0 && (mpcmp(a->y, mpzero) == 0 || mpcmp(a->y, b->y) != 0)){
		s->inf = 1;
		return;
	}
	l = mpnew(0);
	k = mpnew(0);
	sx = mpnew(0);
	sy = mpnew(0);
	if(mpcmp(a->x, b->x) == 0 && mpcmp(a->y, b->y) == 0){
		mpadd(mpone, mptwo, k);
		mpmul(a->x, a->x, l);
		mpmul(l, k, l);
		mpadd(l, dom->a, l);
		mpleft(a->y, 1, k);
		mpmod(k, dom->p, k);
		mpinvert(k, dom->p, k);
		mpmul(k, l, l);
		mpmod(l, dom->p, l);

		mpleft(a->x, 1, k);
		mpmul(l, l, sx);
		mpsub(sx, k, sx);
		mpmod(sx, dom->p, sx);

		mpsub(a->x, sx, sy);
		mpmul(l, sy, sy);
		mpsub(sy, a->y, sy);
		mpmod(sy, dom->p, sy);
		mpassign(sx, s->x);
		mpassign(sy, s->y);
		mpfree(sx);
		mpfree(sy);
		mpfree(l);
		mpfree(k);
		return;
	}
	mpsub(b->y, a->y, l);
	mpmod(l, dom->p, l);
	mpsub(b->x, a->x, k);
	mpmod(k, dom->p, k);
	mpinvert(k, dom->p, k);
	mpmul(k, l, l);
	mpmod(l, dom->p, l);
	
	mpmul(l, l, sx);
	mpsub(sx, a->x, sx);
	mpsub(sx, b->x, sx);
	mpmod(sx, dom->p, sx);
	
	mpsub(a->x, sx, sy);
	mpmul(sy, l, sy);
	mpsub(sy, a->y, sy);
	mpmod(sy, dom->p, sy);
	
	mpassign(sx, s->x);
	mpassign(sy, s->y);
	mpfree(sx);
	mpfree(sy);
	mpfree(l);
	mpfree(k);
}