removes u from srp struct.

This commit is contained in:
Moisés Guimarães
2015-08-03 12:30:56 -03:00
parent 53224281d2
commit 1d99bd3339
2 changed files with 97 additions and 85 deletions

View File

@ -172,7 +172,7 @@ int wc_SrpInit(Srp* srp, byte type, byte side)
return r;
if ((r = mp_init_multi(&srp->N, &srp->g, &srp->auth,
&srp->priv, &srp->u, 0)) != 0)
&srp->priv, 0, 0)) != 0)
return r;
srp->side = side; srp->type = type;
@ -187,7 +187,6 @@ void wc_SrpTerm(Srp* srp)
if (srp) {
mp_clear(&srp->N); mp_clear(&srp->g);
mp_clear(&srp->auth); mp_clear(&srp->priv);
mp_clear(&srp->u);
XMEMSET(srp->salt, 0, srp->saltSz);
XFREE(srp->salt, NULL, DYNAMIC_TYPE_SRP);
@ -429,68 +428,32 @@ int wc_SrpGetPublic(Srp* srp, byte* public, word32* size)
return r;
}
static int wc_SrpSetU(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
byte* serverPubKey, word32 serverPubKeySz)
{
SrpHash hash;
byte digest[SRP_MAX_DIGEST_SIZE];
word32 modulusSz = mp_unsigned_bin_size(&srp->N);
byte pad = 0;
word32 i;
int r = SrpHashInit(&hash, srp->type);
/* H(A) */
for (i = 0; !r && i < modulusSz - clientPubKeySz; i++)
r = SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, clientPubKey, clientPubKeySz);
/* H(A | B) */
for (i = 0; !r && i < modulusSz - serverPubKeySz; i++)
r = SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, serverPubKey, serverPubKeySz);
/* client proof = H( H(N) ^ H(g) | H(user) | salt | A | B) */
if (!r) r = SrpHashUpdate(&srp->client_proof, clientPubKey, clientPubKeySz);
if (!r) r = SrpHashUpdate(&srp->client_proof, serverPubKey, serverPubKeySz);
/* server proof = H(A) */
if (!r) r = SrpHashUpdate(&srp->server_proof, clientPubKey, clientPubKeySz);
/* set u */
if (!r) r = SrpHashFinal(&hash, digest);
if (!r) r = mp_read_unsigned_bin(&srp->u, digest, SrpHashSize(srp->type));
return r;
}
static int wc_SrpSetK(Srp* srp, byte* secret, word32 size)
{
SrpHash hash;
byte digest[SRP_MAX_DIGEST_SIZE];
word32 digestSz = SrpHashSize(srp->type);
word32 i, j, digestSz = SrpHashSize(srp->type);
byte counter[4];
int r;
word32 i = 0;
word32 pos = 0;
byte cnt[4];
for (i = 0; pos < digestSz * 2; i++) {
cnt[0] = (i >> 24) & 0xFF;
cnt[1] = (i >> 16) & 0xFF;
cnt[2] = (i >> 8) & 0xFF;
cnt[3] = i & 0xFF;
for (i = j = 0; j < 2 * digestSz; i++) {
counter[0] = (i >> 24) & 0xFF;
counter[1] = (i >> 16) & 0xFF;
counter[2] = (i >> 8) & 0xFF;
counter[3] = i & 0xFF;
r = SrpHashInit(&hash, srp->type);
if (!r) r = SrpHashUpdate(&hash, secret, size);
if (!r) r = SrpHashUpdate(&hash, cnt, 4);
if (!r) r = SrpHashUpdate(&hash, counter, 4);
if(pos + digestSz > digestSz * 2) {
if(j + digestSz > 2 * digestSz) {
if (!r) r = SrpHashFinal(&hash, digest);
XMEMCPY(srp->key + pos, digest, digestSz * 2 - pos);
pos = digestSz * 2;
XMEMCPY(srp->key + j, digest, 2 * digestSz - j);
j = 2 * digestSz;
}
else {
if (!r) r = SrpHashFinal(&hash, srp->key + pos);
pos += digestSz;
if (!r) r = SrpHashFinal(&hash, srp->key + j);
j += digestSz;
}
}
@ -503,12 +466,16 @@ static int wc_SrpSetK(Srp* srp, byte* secret, word32 size)
int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
byte* serverPubKey, word32 serverPubKeySz)
{
byte* secret;
word32 digestSz;
word32 secretSz;
mp_int i, j, s;
SrpHash hash;
byte *secret;
byte digest[SRP_MAX_DIGEST_SIZE];
word32 i, secretSz, digestSz;
mp_int u, s, temp1, temp2;
byte pad = 0;
int r;
/* validating params */
if (!srp || !clientPubKey || clientPubKeySz == 0
|| !serverPubKey || serverPubKeySz == 0)
return BAD_FUNC_ARG;
@ -516,56 +483,84 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
if (mp_iszero(&srp->priv))
return SRP_CALL_ORDER_E;
if ((r = mp_init_multi(&i, &j, &s, 0, 0, 0)) != MP_OKAY)
/* initializing variables */
if ((r = SrpHashInit(&hash, srp->type)) != 0)
return r;
digestSz = SrpHashSize(srp->type);
secretSz = mp_unsigned_bin_size(&srp->N);
secret = (byte*)XMALLOC(secretSz, NULL, DYNAMIC_TYPE_SRP);
if (secret == NULL) {
mp_clear(&i); mp_clear(&j); mp_clear(&s);
if ((secret = (byte*)XMALLOC(secretSz, NULL, DYNAMIC_TYPE_SRP)) == NULL)
return MEMORY_E;
if ((r = mp_init_multi(&u, &s, &temp1, &temp2, 0, 0)) != MP_OKAY) {
XFREE(secret, NULL, DYNAMIC_TYPE_SRP);
return r;
}
digestSz = SrpHashSize(srp->type);
/* building u (random scrambling parameeter) */
r = wc_SrpSetU(srp, clientPubKey, clientPubKeySz,
serverPubKey, serverPubKeySz);
/* H(A) */
for (i = 0; !r && i < secretSz - clientPubKeySz; i++)
r = SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, clientPubKey, clientPubKeySz);
/* H(A | B) */
for (i = 0; !r && i < secretSz - serverPubKeySz; i++)
r = SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, serverPubKey, serverPubKeySz);
/* set u */
if (!r) r = SrpHashFinal(&hash, digest);
if (!r) r = mp_read_unsigned_bin(&u, digest, SrpHashSize(srp->type));
/* building s (secret) */
if (!r && srp->side == SRP_CLIENT_SIDE) {
/* i = B - k * v */
r = mp_read_unsigned_bin(&i, srp->k, digestSz);
if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &j);
if (!r) r = mp_mulmod(&i, &j, &srp->N, &s);
if (!r) r = mp_read_unsigned_bin(&j, serverPubKey, serverPubKeySz);
if (!r) r = mp_sub(&j, &s, &i);
/* temp1 = B - k * v */
r = mp_read_unsigned_bin(&temp1, srp->k, digestSz);
if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &temp2);
if (!r) r = mp_mulmod(&temp1, &temp2, &srp->N, &s);
if (!r) r = mp_read_unsigned_bin(&temp2, serverPubKey, serverPubKeySz);
if (!r) r = mp_sub(&temp2, &s, &temp1);
/* j = a + u * x */
if (!r) r = mp_mulmod(&srp->u, &srp->auth, &srp->N, &s);
if (!r) r = mp_add(&srp->priv, &s, &j);
/* temp2 = a + u * x */
if (!r) r = mp_mulmod(&u, &srp->auth, &srp->N, &s);
if (!r) r = mp_add(&srp->priv, &s, &temp2);
/* secret = i ^ j % N */
if (!r) r = mp_exptmod(&i, &j, &srp->N, &s);
/* secret = temp1 ^ temp2 % N */
if (!r) r = mp_exptmod(&temp1, &temp2, &srp->N, &s);
} else if (!r && srp->side == SRP_SERVER_SIDE) {
/* i = v ^ u % N */
r = mp_exptmod(&srp->auth, &srp->u, &srp->N, &i);
/* temp1 = v ^ u % N */
r = mp_exptmod(&srp->auth, &u, &srp->N, &temp1);
/* j = A * i % N */
/* temp2 = A * temp1 % N */
if (!r) r = mp_read_unsigned_bin(&s, clientPubKey, clientPubKeySz);
if (!r) r = mp_mulmod(&s, &i, &srp->N, &j);
if (!r) r = mp_mulmod(&s, &temp1, &srp->N, &temp2);
/* secret = j * b % N */
if (!r) r = mp_exptmod(&j, &srp->priv, &srp->N, &s);
/* secret = temp2 * b % N */
if (!r) r = mp_exptmod(&temp2, &srp->priv, &srp->N, &s);
}
/* building session key from secret */
if (!r) r = mp_to_unsigned_bin(&s, secret);
if (!r) r = wc_SrpSetK(srp, secret, mp_unsigned_bin_size(&s));
/* client proof = H( H(N) ^ H(g) | H(user) | salt | A | B | K) */
if (!r) r = SrpHashUpdate(&srp->client_proof, srp->key, digestSz * 2);
/* updating client proof = H( H(N) ^ H(g) | H(user) | salt | A | B | K) */
if (!r) r = SrpHashUpdate(&srp->client_proof, clientPubKey, clientPubKeySz);
if (!r) r = SrpHashUpdate(&srp->client_proof, serverPubKey, serverPubKeySz);
if (!r) r = SrpHashUpdate(&srp->client_proof, srp->key, 2 * digestSz);
/* updating server proof = H(A) */
if (!r) r = SrpHashUpdate(&srp->server_proof, clientPubKey, clientPubKeySz);
XFREE(secret, NULL, DYNAMIC_TYPE_SRP);
mp_clear(&i); mp_clear(&j); mp_clear(&s);
mp_clear(&u); mp_clear(&s); mp_clear(&temp1); mp_clear(&temp2);
return r;
}
@ -590,7 +585,7 @@ int wc_SrpGetProof(Srp* srp, byte* proof, word32* size)
if (srp->side == SRP_CLIENT_SIDE) {
/* server proof = H( A | client proof | K) */
if (!r) r = SrpHashUpdate(&srp->server_proof, proof, *size);
if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, (*size) * 2);
if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, 2 * (*size));
}
return r;
@ -613,7 +608,7 @@ int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size)
if (srp->side == SRP_SERVER_SIDE) {
/* server proof = H( A | client proof | K) */
if (!r) r = SrpHashUpdate(&srp->server_proof, proof, size);
if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, size * 2);
if (!r) r = SrpHashUpdate(&srp->server_proof, srp->key, 2 * size);
}
if (!r && XMEMCMP(proof, digest, size) != 0)
@ -622,4 +617,20 @@ int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size)
return r;
}
int wc_SrpGetSessionKey(Srp* srp, byte* key, word32* size)
{
word32 sz;
if (!srp || !key || !size)
return BAD_FUNC_ARG;
if (*size < (sz = SrpHashSize(srp->type)))
return BUFFER_E;
XMEMCPY(key, srp->key, sz);
*size = sz;
return 0;
}
#endif /* WOLFCRYPT_HAVE_SRP */

View File

@ -94,7 +94,6 @@ typedef struct {
byte k[SRP_MAX_DIGEST_SIZE]; /**< Multiplier parameeter. H(N, g) */
mp_int auth; /**< client: x = H(salt, H(user, ":", pswd)) */
mp_int priv; /**< Private ephemeral value. */
mp_int u; /**< Random scrambling parameeter. */
SrpHash client_proof; /**< Client proof. Sent to Server. */
SrpHash server_proof; /**< Server proof. Sent to Client. */
byte key[2 * SRP_MAX_DIGEST_SIZE]; /**< Session key. */
@ -127,6 +126,8 @@ WOLFSSL_API int wc_SrpGetProof(Srp* srp, byte* proof, word32* size);
WOLFSSL_API int wc_SrpVerifyPeersProof(Srp* srp, byte* proof, word32 size);
WOLFSSL_API int wc_SrpGetSessionKey(Srp* srp, byte* key, word32* size);
#ifdef __cplusplus
} /* extern "C" */
#endif