Clan x86

Technical (Development, Security, etc.) => General Programming => Botdev => Topic started by: sdfg on August 30, 2008, 02:20:42 AM

Title: SRP proof?
Post by: sdfg on August 30, 2008, 02:20:42 AM
Hello, my implementation of SRP always seems to fail on the password proof, can anyone see what the problem is? I don't really have anything to test my values against, so i'm completely lost as to where the screwup originates.

static unsigned char N_raw[32] = {0x87, 0xc7, 0x23, 0x85, 0x65, 0xf6, 0x16, 0x12,
    0xd9, 0x12, 0x32, 0xc7, 0x78, 0x6c, 0x97, 0x7e,
      0x55, 0xb5, 0x92, 0xa0, 0x8c, 0xb6, 0x86, 0x21,
  0x03, 0x18, 0x99, 0x61, 0x8b, 0x1a, 0xff, 0xf8};
   

static unsigned char I_raw[20] = {0x6c, 0x0E, 0x97, 0xED,
      0x0A, 0xF9, 0x6B, 0xAB,
      0xB1, 0x58, 0x89, 0xEB,
  0x8B, 0xBA, 0x25, 0xA4,
  0xF0, 0x8C, 0x01, 0xF8};

char usernamehash[20];
char usernpasshash[20];
BigBuffer g;
BigBuffer n;
BigBuffer a;
BigBuffer A;
char A_raw[32];
int userlen, passlen;

char a_tmp[32] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1
};

void SRPInit(char *user, char *pass) {
char asdf[128];
userlen = strlen(user);
passlen = strlen(pass);
ucasecpy(asdf, user);
asdf[userlen] = ':';
ucasecpy(asdf + userlen + 1, pass);
SHA1(asdf, userlen + 1 + passlen, usernpasshash);
ucasecpy(asdf, user);
SHA1(asdf, userlen, usernamehash);
storm.SBigNew(&n);
storm.SBigNew(&a);
storm.SBigNew(&g);
storm.SBigFromBinary(n, N_raw, 32);
storm.SBigFromBinary(a, a_tmp, 32);
storm.SBigFromUnsigned(g, 0x2F);
}

void SRPCalculateA(char *outbuf) {
unsigned long len = 32;
storm.SBigNew(&A);
storm.SBigPowMod(A, g, a, n);
storm.SBigToBinaryBuffer(A, A_raw, len, &len);
memcpy(outbuf, A_raw, 32);
}

void SRPCalculateM1(char *outbuf, char *B, char *salt) {
char K[40], S[32], hashbuf[176];
SRPCalculateS(S, B, salt);
SRPCalculateK(K, S);
memcpy(hashbuf, I_raw, 20);
memcpy(hashbuf + 20, usernamehash, 20);
memcpy(hashbuf + 40, salt, 32);
memcpy(hashbuf + 72, A_raw, 32);
memcpy(hashbuf + 104, B, 32);
memcpy(hashbuf + 136, K, 40);
SHA1(hashbuf, 176, outbuf);
}

void SRPCalculateS(char *outbuf, const char *B, const char *salt) {
//S = ((N + B - v) % N) ^ (a + u * x) % N;
BigBuffer tmp, S_exp, S_base, x, v, u_tmp;
///////////////////////x and v calculations////////
storm.SBigNew(&x);
storm.SBigNew(&v);
SRPCalculateX(x, salt);   //x calc
storm.SBigPowMod(v, g, x, n); //v calc
///////////////////////////////////base calc //////
storm.SBigNew(&tmp);
storm.SBigFromBinary(tmp, B, 32); //b from raw
storm.SBigNew(&S_base);
storm.SBigCopy(S_base, n);   //mov eax, n
storm.SBigAdd(S_base, S_base, tmp);   //add eax, b
storm.SBigSub(S_base, S_base, v);   //sub eax, v
storm.SBigMod(S_base, S_base, n);   //mod eax, n
////////////////////////////////////////////////////
storm.SBigNew(&S_exp);
storm.SBigNew(&u_tmp);
storm.SBigCopy(S_exp, x);   //mov ebx, x
storm.SBigFromUnsigned(u_tmp, SRPCalculateU(B));  //mov ecx, u
storm.SBigMul(S_exp, S_exp, u_tmp);   //mul ebx, ecx
storm.SBigAdd(S_exp, S_exp, a);   //add ebx, a
storm.SBigDel(u_tmp);
storm.SBigDel(x);
storm.SBigDel(v);
storm.SBigDel(tmp);
storm.SBigNew(&tmp);
storm.SBigPowMod(tmp, S_base, S_exp, n);
unsigned long len = 32;
storm.SBigToBinaryBuffer(outbuf, tmp, len, &len);
storm.SBigDel(S_base);
storm.SBigDel(S_exp);
storm.SBigDel(tmp);
}

void SRPCalculateX(BigBuffer x, const char *raw_salt) {
char hash[20], temp[52];
memcpy(temp, raw_salt, 32);
memcpy(temp + 32, usernpasshash, 20);
SHA1(temp, 52, hash);
storm.SBigFromBinary(x, hash, 20);
}

void SRPCalculateK(char *outbuf, const char *S) {
char odds[16], evens[16], oddhash[20], evenhash[20];
char *saltptr = (char *)S;
char *oddptr  = odds;
char *evenptr = evens;
for (int i = 0; i != 16; i++) {
*(oddptr++) = *(saltptr++);
*(evenptr++) = *(saltptr++);
}
SHA1(odds, 16, oddhash);
SHA1(evens, 16, evenhash);
saltptr = outbuf;
oddptr  = oddhash;
evenptr = evenhash;
for (i = 0; i != 20; i++) {
*(saltptr++) = *(oddptr++);
*(saltptr++) = *(evenptr++);
}
}

unsigned int SRPCalculateU(const char *B) {
char hash[20];
SHA1((char *)B, 32, hash);
return *(unsigned int *)hash;
}
Title: Re: SRP proof?
Post by: sdfg on September 06, 2008, 02:16:18 PM
Nobody? :(
I was kinda hoping iago would see this and help me, since he is the one who reversed it in the first place, and my code is heavily based on his notes.
Or somebody else who knows whatsup... O well/me goes back to the batcave

Thanks anyways!
Title: Re: SRP proof?
Post by: iago on September 06, 2008, 03:24:12 PM
I looked, but I'm no good at reading other people's code (or my own). I suggest finding a working implementation and changing it to output at every step, then comparing where you're going wrong. That's how I normally troubleshoot these things.
Title: Re: SRP proof?
Post by: c0ol on September 10, 2008, 03:15:40 PM
Not totally sure about this, but your derivation of 'u' seems off.  Should you not treat it similarly to x and run storm.SBigFromBinary(u, hash, 20); on it?  Instead you are doing something different which could be causing the problem
Title: Re: SRP proof?
Post by: sdfg on September 10, 2008, 04:25:08 PM
u is the first 4 bytes of SHA1(B), according to iago's notes.
Title: Re: SRP proof?
Post by: c0ol on September 10, 2008, 06:47:37 PM
Yes you are right, and with that it looks to me like your operations are in order for S.

My notes have:
Sc = (((n+B-v) % n) ^ (xu+a)) % n

And you have:
tmp = B
Sbase = n
Sbase += tmp
Sbase -= v
Sbase %= n
Sexp = x
Sexp *= u
Sexp += a
Sc = (Sbase ^ Sexp) % n

These seem like equal operations so I am going to have to assume your S function is correct barring library issues.

As a side note, in your K function it seems to me like odd and even are oppositely named, this shouldn't effect your result though.
Title: Re: SRP proof?
Post by: MyndFyre on September 10, 2008, 07:26:56 PM
I think Sexp needs to be taken mod N, yes?




[iago: fixed tags]
Title: Re: SRP proof?
Post by: c0ol on September 11, 2008, 10:24:42 AM
Quote from: MyndFyre on September 10, 2008, 07:26:56 PM
I think Sexp needs to be taken mod N, yes?

I thought taking (Sbase ^ Sexp) % n was sufficient?  I cross referenced this with the bncsutils code and that is what they have also as far as I can tell.