libsec: add q parameter to dh_new() for subgroup support, sanitize dh parameters
This commit is contained in:
parent
844bbecadb
commit
3bb0b9f4ea
3 changed files with 60 additions and 25 deletions
|
@ -447,15 +447,16 @@ struct DHstate
|
||||||
{
|
{
|
||||||
mpint *g; /* base g */
|
mpint *g; /* base g */
|
||||||
mpint *p; /* large prime */
|
mpint *p; /* large prime */
|
||||||
|
mpint *q; /* subgroup prime */
|
||||||
mpint *x; /* random secret */
|
mpint *x; /* random secret */
|
||||||
mpint *y; /* public key y = g ^ x % p */
|
mpint *y; /* public key y = g**x % p */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* generate new public key: y = g ^ x % p */
|
/* generate new public key: y = g**x % p */
|
||||||
mpint* dh_new(DHstate *dh, mpint *p, mpint *g);
|
mpint* dh_new(DHstate *dh, mpint *p, mpint *q, mpint *g);
|
||||||
|
|
||||||
/* calculate shared key: k = pub ^ x % p */
|
/* calculate shared key: k = y**x % p */
|
||||||
mpint* dh_finish(DHstate *dh, mpint *pub);
|
mpint* dh_finish(DHstate *dh, mpint *y);
|
||||||
|
|
||||||
/* password-based key derivation function 2 (RFC 2898) */
|
/* password-based key derivation function 2 (RFC 2898) */
|
||||||
void pbkdf2_hmac_sha1(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d, ulong dlen);
|
void pbkdf2_hmac_sha1(uchar *p, ulong plen, uchar *s, ulong slen, ulong rounds, uchar *d, ulong dlen);
|
||||||
|
|
|
@ -3,38 +3,72 @@
|
||||||
#include <libsec.h>
|
#include <libsec.h>
|
||||||
|
|
||||||
mpint*
|
mpint*
|
||||||
dh_new(DHstate *dh, mpint *p, mpint *g)
|
dh_new(DHstate *dh, mpint *p, mpint *q, mpint *g)
|
||||||
{
|
{
|
||||||
|
mpint *pm1;
|
||||||
|
int n;
|
||||||
|
|
||||||
memset(dh, 0, sizeof(*dh));
|
memset(dh, 0, sizeof(*dh));
|
||||||
dh->g = mpcopy(g);
|
if(mpcmp(g, mpone) <= 0)
|
||||||
|
return nil;
|
||||||
|
|
||||||
|
n = mpsignif(p);
|
||||||
|
pm1 = mpnew(n);
|
||||||
|
mpsub(p, mpone, pm1);
|
||||||
dh->p = mpcopy(p);
|
dh->p = mpcopy(p);
|
||||||
if(dh->g != nil && dh->p != nil){
|
dh->g = mpcopy(g);
|
||||||
dh->x = mprand(mpsignif(dh->p), genrandom, nil);
|
dh->q = mpcopy(q != nil ? q : pm1);
|
||||||
dh->y = mpnew(0);
|
dh->x = mpnew(mpsignif(dh->q));
|
||||||
if(dh->x != nil && dh->y != nil){
|
dh->y = mpnew(n);
|
||||||
mpexp(dh->g, dh->x, dh->p, dh->y);
|
for(;;){
|
||||||
return dh->y;
|
mpnrand(dh->q, genrandom, dh->x);
|
||||||
}
|
mpexp(dh->g, dh->x, dh->p, dh->y);
|
||||||
|
if(mpcmp(dh->y, mpone) > 0 && mpcmp(dh->y, pm1) < 0)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
dh_finish(dh, nil);
|
mpfree(pm1);
|
||||||
return nil;
|
|
||||||
|
return dh->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpint*
|
mpint*
|
||||||
dh_finish(DHstate *dh, mpint *pub)
|
dh_finish(DHstate *dh, mpint *y)
|
||||||
{
|
{
|
||||||
mpint *k;
|
mpint *k = nil;
|
||||||
|
|
||||||
k = nil;
|
if(y == nil || dh->x == nil || dh->p == nil || dh->q == nil)
|
||||||
if(pub != nil && dh->x != nil && dh->p != nil){
|
goto Out;
|
||||||
if((k = mpnew(0)) != nil)
|
|
||||||
mpexp(pub, dh->x, dh->p, k);
|
/* y > 1 */
|
||||||
|
if(mpcmp(y, mpone) <= 0)
|
||||||
|
goto Out;
|
||||||
|
|
||||||
|
k = mpnew(mpsignif(dh->p));
|
||||||
|
|
||||||
|
/* y < p-1 */
|
||||||
|
mpsub(dh->p, mpone, k);
|
||||||
|
if(mpcmp(y, k) >= 0){
|
||||||
|
Bad:
|
||||||
|
mpfree(k);
|
||||||
|
k = nil;
|
||||||
|
goto Out;
|
||||||
}
|
}
|
||||||
mpfree(dh->g);
|
|
||||||
|
/* y**q % p == 1 if q < p-1 */
|
||||||
|
if(mpcmp(dh->q, k) < 0){
|
||||||
|
mpexp(y, dh->q, dh->p, k);
|
||||||
|
if(mpcmp(k, mpone) != 0)
|
||||||
|
goto Bad;
|
||||||
|
}
|
||||||
|
|
||||||
|
mpexp(y, dh->x, dh->p, k);
|
||||||
|
|
||||||
|
Out:
|
||||||
mpfree(dh->p);
|
mpfree(dh->p);
|
||||||
|
mpfree(dh->q);
|
||||||
|
mpfree(dh->g);
|
||||||
mpfree(dh->x);
|
mpfree(dh->x);
|
||||||
mpfree(dh->y);
|
mpfree(dh->y);
|
||||||
memset(dh, 0, sizeof(*dh));
|
memset(dh, 0, sizeof(*dh));
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -797,7 +797,7 @@ tlsSecDHEc(TlsSec *sec, uchar *srandom, int vers,
|
||||||
Y = bytestomp(Ys);
|
Y = bytestomp(Ys);
|
||||||
K = nil;
|
K = nil;
|
||||||
|
|
||||||
if(P == nil || G == nil || Y == nil || dh_new(&dh, P, G) == nil)
|
if(P == nil || G == nil || Y == nil || dh_new(&dh, P, nil, G) == nil)
|
||||||
goto Out;
|
goto Out;
|
||||||
epm = mptobytes(dh.y);
|
epm = mptobytes(dh.y);
|
||||||
K = dh_finish(&dh, Y);
|
K = dh_finish(&dh, Y);
|
||||||
|
|
Loading…
Reference in a new issue