adds key computation.

removes unnecessary fields from the srp struct.
This commit is contained in:
Moisés Guimarães
2015-07-28 18:59:15 -03:00
parent ba0c75011b
commit 490d063dec
3 changed files with 233 additions and 158 deletions

View File

@@ -5,16 +5,16 @@
* This file is part of wolfSSL. (formerly known as CyaSSL)
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* it under the terms of the GNU Geteral Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* GNU Geteral Public License for more details.
*
* You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU Geteral Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
@@ -92,6 +92,13 @@ static byte B[] = {
0x0E, 0xC7, 0x92, 0xAD
};
static byte key[] = {
0x66, 0x00, 0x9D, 0x58, 0xB3, 0xD2, 0x0D, 0x4B, 0x69, 0x7F, 0xCF, 0x48,
0xFF, 0x8F, 0x15, 0x81, 0x4C, 0x4B, 0xFE, 0x9D, 0x85, 0x77, 0x88, 0x60,
0x1D, 0x1E, 0x51, 0xCF, 0x75, 0xCC, 0x58, 0x00, 0xE7, 0x8D, 0x22, 0x87,
0x13, 0x6C, 0x88, 0x55
};
static void test_SrpInit(void)
{
Srp srp;
@@ -218,63 +225,126 @@ static void test_SrpSetPassword(void)
wc_SrpTerm(&srp);
}
static void test_SrpGenPublic(void)
static void test_SrpGetPublic(void)
{
Srp srp;
byte public[64];
word32 publicSz = 0;
AssertIntEQ(0, wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE));
/* invalid call order */
AssertIntEQ(SRP_CALL_ORDER_E, wc_SrpGenPublic(&srp, public, &publicSz));
/* fix call order */
AssertIntEQ(0, wc_SrpSetUsername(&srp, username, usernameSz));
AssertIntEQ(0, wc_SrpSetParams(&srp, N, sizeof(N),
g, sizeof(g),
salt, sizeof(salt)));
/* invalid call order */
AssertIntEQ(SRP_CALL_ORDER_E, wc_SrpGetPublic(&srp, public, &publicSz));
/* fix call order */
AssertIntEQ(0, wc_SrpSetPassword(&srp, password, passwordSz));
/* invalid params */
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGenPublic(NULL, public, &publicSz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGenPublic(&srp, NULL, &publicSz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGenPublic(&srp, public, NULL));
AssertIntEQ(BUFFER_E, wc_SrpGenPublic(&srp, public, &publicSz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGetPublic(NULL, public, &publicSz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGetPublic(&srp, NULL, &publicSz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGetPublic(&srp, public, NULL));
AssertIntEQ(BUFFER_E, wc_SrpGetPublic(&srp, public, &publicSz));
/* success */
publicSz = sizeof(public);
AssertIntEQ(0, wc_SrpGenPublic(&srp, NULL, NULL));
AssertIntEQ(0, wc_SrpSetPrivate(&srp, a, sizeof(a)));
AssertIntEQ(0, wc_SrpGenPublic(&srp, public, &publicSz));
AssertIntEQ(0, wc_SrpGetPublic(&srp, public, &publicSz));
AssertIntEQ(publicSz, sizeof(A));
AssertIntEQ(0, XMEMCMP(public, A, publicSz));
wc_SrpTerm(&srp);
AssertIntEQ(0, wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_SERVER_SIDE));
AssertIntEQ(0, wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_SERVER_SIDE));
AssertIntEQ(0, wc_SrpSetUsername(&srp, username, usernameSz));
AssertIntEQ(0, wc_SrpSetParams(&srp, N, sizeof(N),
g, sizeof(g),
salt, sizeof(salt)));
/* invalid call order */
AssertIntEQ(SRP_CALL_ORDER_E, wc_SrpGenPublic(&srp, public, &publicSz));
AssertIntEQ(SRP_CALL_ORDER_E, wc_SrpGetPublic(&srp, public, &publicSz));
/* fix call order */
AssertIntEQ(0, wc_SrpSetVerifier(&srp, verifier, sizeof(verifier)));
/* success */
AssertIntEQ(0, wc_SrpGenPublic(&srp, NULL, NULL));
AssertIntEQ(0, wc_SrpSetPrivate(&srp, b, sizeof(b)));
AssertIntEQ(0, wc_SrpGenPublic(&srp, public, &publicSz));
AssertIntEQ(0, wc_SrpGetPublic(&srp, public, &publicSz));
AssertIntEQ(publicSz, sizeof(B));
AssertIntEQ(0, XMEMCMP(public, B, publicSz));
wc_SrpTerm(&srp);
}
static void test_SrpComputeKey(void)
{
Srp cli, srv;
byte clientPubKey[64];
byte serverPubKey[64];
word32 clientPubKeySz = 64;
word32 serverPubKeySz = 64;
AssertIntEQ(0, wc_SrpInit(&cli, SRP_TYPE_SHA, SRP_CLIENT_SIDE));
AssertIntEQ(0, wc_SrpInit(&srv, SRP_TYPE_SHA, SRP_SERVER_SIDE));
/* invalid call order */
AssertIntEQ(SRP_CALL_ORDER_E, wc_SrpComputeKey(&cli,
clientPubKey, clientPubKeySz,
serverPubKey, serverPubKeySz));
/* fix call order */
AssertIntEQ(0, wc_SrpSetUsername(&cli, username, usernameSz));
AssertIntEQ(0, wc_SrpSetUsername(&srv, username, usernameSz));
AssertIntEQ(0, wc_SrpSetParams(&cli, N, sizeof(N),
g, sizeof(g),
salt, sizeof(salt)));
AssertIntEQ(0, wc_SrpSetParams(&srv, N, sizeof(N),
g, sizeof(g),
salt, sizeof(salt)));
AssertIntEQ(0, wc_SrpSetPassword(&cli, password, passwordSz));
AssertIntEQ(0, wc_SrpSetVerifier(&srv, verifier, sizeof(verifier)));
AssertIntEQ(0, wc_SrpSetPrivate(&cli, a, sizeof(a)));
AssertIntEQ(0, wc_SrpGetPublic(&cli, clientPubKey, &clientPubKeySz));
AssertIntEQ(0, XMEMCMP(clientPubKey, A, clientPubKeySz));
AssertIntEQ(0, wc_SrpSetPrivate(&srv, b, sizeof(b)));
AssertIntEQ(0, wc_SrpGetPublic(&srv, serverPubKey, &serverPubKeySz));
AssertIntEQ(0, XMEMCMP(serverPubKey, B, serverPubKeySz));
/* invalid params */
AssertIntEQ(BAD_FUNC_ARG, wc_SrpComputeKey(NULL,
clientPubKey, clientPubKeySz,
serverPubKey, serverPubKeySz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpComputeKey(&cli,
NULL, clientPubKeySz,
serverPubKey, serverPubKeySz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpComputeKey(&cli,
clientPubKey, 0,
serverPubKey, serverPubKeySz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpComputeKey(&cli,
clientPubKey, clientPubKeySz,
NULL, serverPubKeySz));
AssertIntEQ(BAD_FUNC_ARG, wc_SrpComputeKey(&cli,
clientPubKey, clientPubKeySz,
serverPubKey, 0));
/* success */
AssertIntEQ(0, wc_SrpComputeKey(&cli, clientPubKey, clientPubKeySz,
serverPubKey, serverPubKeySz));
AssertIntEQ(0, wc_SrpComputeKey(&srv, clientPubKey, clientPubKeySz,
serverPubKey, serverPubKeySz));
AssertIntEQ(0, XMEMCMP(cli.key, key, sizeof(key)));
AssertIntEQ(0, XMEMCMP(srv.key, key, sizeof(key)));
wc_SrpTerm(&cli);
wc_SrpTerm(&srv);
}
#endif
void SrpTest(void)
@@ -284,6 +354,7 @@ void SrpTest(void)
test_SrpSetUsername();
test_SrpSetParams();
test_SrpSetPassword();
test_SrpGenPublic();
test_SrpGetPublic();
test_SrpComputeKey();
#endif
}

View File

@@ -169,18 +169,10 @@ int wc_SrpInit(Srp* srp, byte type, byte side)
if ((r = SrpHashInit(&srp->server_proof, type)) != 0)
return r;
if ((r = mp_init_multi(&srp->N, &srp->g, &srp->s, &srp->u, 0, 0)) != 0)
if ((r = mp_init_multi(&srp->N, &srp->g, &srp->auth,
&srp->priv, &srp->u, 0)) != 0)
return r;
if ((r = mp_init_multi(&srp->auth, &srp->peer, &srp->priv, &srp->pub,
0, 0)) != 0) {
/* undo previous initializations on error */
mp_clear(&srp->N); mp_clear(&srp->g);
mp_clear(&srp->s); mp_clear(&srp->u);
return r;
}
srp->side = side; srp->type = type;
srp->salt = NULL; srp->saltSz = 0;
srp->user = NULL; srp->userSz = 0;
@@ -192,9 +184,8 @@ void wc_SrpTerm(Srp* srp)
{
if (srp) {
mp_clear(&srp->N); mp_clear(&srp->g);
mp_clear(&srp->s); mp_clear(&srp->u);
mp_clear(&srp->auth); mp_clear(&srp->peer);
mp_clear(&srp->priv); mp_clear(&srp->pub);
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);
@@ -367,6 +358,9 @@ int wc_SrpSetPrivate(Srp* srp, const byte* private, word32 size)
if (!srp || !private || !size)
return BAD_FUNC_ARG;
if (mp_iszero(&srp->auth))
return SRP_CALL_ORDER_E;
return mp_read_unsigned_bin(&srp->priv, private, size);
}
@@ -382,38 +376,32 @@ static int wc_SrpGenPrivate(Srp* srp, byte* private, word32 size)
return r;
}
int wc_SrpGenPublic(Srp* srp, byte* public, word32* size)
int wc_SrpGetPublic(Srp* srp, byte* public, word32* size)
{
byte* buf;
word32 len;
int r = 0;
mp_int pubkey;
word32 modulusSz;
int r = mp_init(&pubkey);
if (!srp || (!public && size) || (public && !size))
if (r != 0)
return r;
if (!srp || !public || !size)
return BAD_FUNC_ARG;
if (mp_iszero(&srp->N))
if (mp_iszero(&srp->auth))
return SRP_CALL_ORDER_E;
if (srp->side == SRP_SERVER_SIDE && mp_iszero(&srp->auth))
return SRP_CALL_ORDER_E;
len = mp_unsigned_bin_size(&srp->N);
if (size && *size < len)
modulusSz = mp_unsigned_bin_size(&srp->N);
if (*size < modulusSz)
return BUFFER_E;
buf = public ? public : (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_SRP);
if (!buf)
return MEMORY_E;
/* priv = random() */
if (mp_iszero(&srp->priv))
r = wc_SrpGenPrivate(srp, buf, len);
r = wc_SrpGenPrivate(srp, public, modulusSz);
/* client side: A = g ^ a % N */
if (srp->side == SRP_CLIENT_SIDE) {
if (!r) r = mp_exptmod(&srp->g, &srp->priv,
&srp->N, &srp->pub);
if (!r) r = mp_exptmod(&srp->g, &srp->priv, &srp->N, &pubkey);
/* server side: B = (k * v + (g ^ b % N)) % N */
} else {
@@ -421,142 +409,159 @@ int wc_SrpGenPublic(Srp* srp, byte* public, word32* size)
if (mp_init_multi(&i, &j, 0, 0, 0, 0) == MP_OKAY) {
if (!r) r = mp_read_unsigned_bin(&i, srp->k,SrpHashSize(srp->type));
if (!r) r = mp_exptmod(&srp->g, &srp->priv,
&srp->N, &srp->pub);
if (!r) r = mp_exptmod(&srp->g, &srp->priv, &srp->N, &pubkey);
if (!r) r = mp_mulmod(&i, &srp->auth, &srp->N, &j);
if (!r) r = mp_add(&j, &srp->pub, &i);
if (!r) r = mp_mod(&i, &srp->N, &srp->pub);
if (!r) r = mp_add(&j, &pubkey, &i);
if (!r) r = mp_mod(&i, &srp->N, &pubkey);
mp_clear(&i); mp_clear(&j);
}
}
/* extract public key to buffer */
XMEMSET(buf, 0, len);
if (!r) r = mp_to_unsigned_bin(&srp->pub, buf);
if (!r) len = mp_unsigned_bin_size(&srp->pub);
/* update proofs */
if (srp->side == SRP_CLIENT_SIDE) {
/* Client proof = H( H(N) ^ H(g) | H(user) | salt | A) */
if (!r) r = SrpHashUpdate(&srp->client_proof, buf, len);
/* Server proof = H(A) */
if (!r) r = SrpHashUpdate(&srp->server_proof, buf, len);
}
if (public)
*size = len;
else
XFREE(buf, NULL, DYNAMIC_TYPE_SRP);
XMEMSET(public, 0, modulusSz);
if (!r) r = mp_to_unsigned_bin(&pubkey, public);
if (!r) *size = mp_unsigned_bin_size(&pubkey);
mp_clear(&pubkey);
return r;
}
static int wc_SrpSetU(Srp* srp, byte* peersKey, word32 peersKeySz)
static int wc_SrpSetU(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
byte* serverPubKey, word32 serverPubKeySz)
{
SrpHash hash;
byte digest[SRP_MAX_DIGEST_SIZE];
byte* public = NULL;
word32 publicSz = 0;
word32 modulusSz = mp_unsigned_bin_size(&srp->N);
byte pad = 0;
word32 i;
int r = SrpHashInit(&hash, srp->type);
if (!r && srp->side == SRP_CLIENT_SIDE) {
publicSz = mp_unsigned_bin_size(&srp->pub);
public = (byte*)XMALLOC(publicSz, NULL, DYNAMIC_TYPE_SRP);
/* H(A) */
for (i = 0; !r && i < modulusSz - clientPubKeySz; i++)
r = SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, clientPubKey, clientPubKeySz);
if (public == NULL)
r = MEMORY_E;
/* H(A | B) */
for (i = 0; !r && i < modulusSz - serverPubKeySz; i++)
r = SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, serverPubKey, serverPubKeySz);
/* H(A) */
if (!r) r = mp_to_unsigned_bin(&srp->pub, public);
for (i = 0; i < modulusSz - publicSz; i++)
SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, public, publicSz);
/* 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);
/* H(A | B) */
if (!r) r = mp_read_unsigned_bin(&srp->peer,
peersKey, peersKeySz);
for (i = 0; i < modulusSz - peersKeySz; i++)
SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, peersKey, peersKeySz);
/* Client proof = H( H(N) ^ H(g) | H(user) | salt | A | B) */
if (!r) r = SrpHashUpdate(&srp->client_proof, peersKey, peersKeySz);
} else if (!r && srp->side == SRP_SERVER_SIDE) {
publicSz = mp_unsigned_bin_size(&srp->pub);
public = (byte*)XMALLOC(publicSz, NULL, DYNAMIC_TYPE_SRP);
if (public == NULL)
r = MEMORY_E;
/* H(A) */
if (!r) r = mp_read_unsigned_bin(&srp->peer,
peersKey, peersKeySz);
for (i = 0; i < modulusSz - peersKeySz; i++)
SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, peersKey, peersKeySz);
/* H(A | B) */
if (!r) r = mp_to_unsigned_bin(&srp->pub, public);
for (i = 0; i < modulusSz - publicSz; i++)
SrpHashUpdate(&hash, &pad, 1);
if (!r) r = SrpHashUpdate(&hash, public, publicSz);
}
/* 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));
XFREE(public, NULL, DYNAMIC_TYPE_SRP);
return r;
}
WOLFSSL_API int wc_SrpComputeKey(Srp* srp, byte* peersKey, word32 peersKeySz)
static int wc_SrpSetK(Srp* srp, byte* secret, word32 size)
{
mp_int i, j;
SrpHash hash;
byte digest[SRP_MAX_DIGEST_SIZE];
word32 digestSz = SrpHashSize(srp->type);
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;
r = SrpHashInit(&hash, srp->type);
if (!r) r = SrpHashUpdate(&hash, secret, size);
if (!r) r = SrpHashUpdate(&hash, cnt, 4);
if(pos + digestSz > digestSz * 2) {
if (!r) r = SrpHashFinal(&hash, digest);
XMEMCPY(srp->key + pos, digest, digestSz * 2 - pos);
pos = digestSz * 2;
}
else {
if (!r) r = SrpHashFinal(&hash, srp->key + pos);
pos += digestSz;
}
}
XMEMSET(digest, 0, sizeof(digest));
XMEMSET(&hash, 0, sizeof(SrpHash));
return r;
}
WOLFSSL_API int wc_SrpComputeKey(Srp* srp,
byte* clientPubKey, word32 clientPubKeySz,
byte* serverPubKey, word32 serverPubKeySz)
{
byte* secret;
word32 secretSz;
mp_int i, j, s;
int r;
if (!srp || !peersKey || peersKeySz == 0)
if (!srp || !clientPubKey || clientPubKeySz == 0
|| !serverPubKey || serverPubKeySz == 0)
return BAD_FUNC_ARG;
if ((r = mp_init_multi(&i, &j, 0, 0, 0, 0)) != MP_OKAY)
if (mp_iszero(&srp->priv))
return SRP_CALL_ORDER_E;
if ((r = mp_init_multi(&i, &j, &s, 0, 0, 0)) != MP_OKAY)
return r;
r = wc_SrpSetU(srp, peersKey, peersKeySz);
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);
return MEMORY_E;
}
r = wc_SrpSetU(srp, clientPubKey, clientPubKeySz,
serverPubKey, serverPubKeySz);
if (!r && srp->side == SRP_CLIENT_SIDE) {
r = mp_read_unsigned_bin(&i, srp->k, SrpHashSize(srp->type));
/* i = B - k * v */
r = mp_read_unsigned_bin(&i, srp->k, SrpHashSize(srp->type));
if (!r) r = mp_exptmod(&srp->g, &srp->auth, &srp->N, &j);
if (!r) r = mp_mulmod(&i, &j, &srp->N, &srp->s);
if (!r) r = mp_sub(&srp->peer, &srp->s, &i);
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);
/* j = a + u * x */
if (!r) r = mp_mulmod(&srp->u, &srp->auth, &srp->N, &srp->s);
if (!r) r = mp_add(&srp->priv, &srp->s, &j);
if (!r) r = mp_mulmod(&srp->u, &srp->auth, &srp->N, &s);
if (!r) r = mp_add(&srp->priv, &s, &j);
/* s = i ^ j % N */
if (!r) r = mp_exptmod(&i, &j, &srp->N, &srp->s);
/* secret = i ^ j % N */
if (!r) r = mp_exptmod(&i, &j, &srp->N, &s);
} else if (!r && srp->side == SRP_SERVER_SIDE) {
/* i = v ^ u % N */
if (!r) r = mp_exptmod(&srp->auth, &srp->u, &srp->N, &i);
r = mp_exptmod(&srp->auth, &srp->u, &srp->N, &i);
/* j = A * i % N */
if (!r) r = mp_mulmod(&srp->peer, &i, &srp->N, &j);
if (!r) r = mp_read_unsigned_bin(&s, clientPubKey, clientPubKeySz);
if (!r) r = mp_mulmod(&s, &i, &srp->N, &j);
/* s = j * b % N */
if (!r) r = mp_exptmod(&j, &srp->priv, &srp->N, &srp->s);
/* secret = j * b % N */
if (!r) r = mp_exptmod(&j, &srp->priv, &srp->N, &s);
}
mp_clear(&i);
mp_clear(&j);
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, sizeof(srp->key));
XFREE(secret, NULL, DYNAMIC_TYPE_SRP);
mp_clear(&i); mp_clear(&j); mp_clear(&s);
return r;
}

View File

@@ -83,23 +83,21 @@ typedef struct {
} SrpHash;
typedef struct {
byte side; /**< SRP_CLIENT_SIDE or SRP_SERVER_SIDE */
byte type; /**< Hash type, one of SRP_TYPE_SHA[|256|384|512] */
byte* user; /**< Username, login. */
word32 userSz; /**< Username length. */
byte* salt; /**< Small salt. */
word32 saltSz; /**< Salt length. */
mp_int N; /**< Modulus. N = 2q+1, [q, N] are primes. */
mp_int g; /**< Generator. A generator modulo N. */
byte k[SRP_MAX_DIGEST_SIZE]; /**< Multiplier parameeter. H(N, g) */
mp_int auth; /**< Priv key. H(salt, H(user, ":", pswd)) */
mp_int priv; /**< Private ephemeral value. */
mp_int pub; /**< Public ephemeral value. */
mp_int peer; /**< Peer's public ephemeral value. */
mp_int u; /**< Random scrambling parameeter. */
SrpHash client_proof; /**< Client proof. Sent to Server. */
SrpHash server_proof; /**< Server proof. Sent to Client. */
mp_int s; /**< Session key. */
byte side; /**< SRP_CLIENT_SIDE or SRP_SERVER_SIDE */
byte type; /**< Hash type, one of SRP_TYPE_SHA[|256|384|512] */
byte* user; /**< Username, login. */
word32 userSz; /**< Username length. */
byte* salt; /**< Small salt. */
word32 saltSz; /**< Salt length. */
mp_int N; /**< Modulus. N = 2q+1, [q, N] are primes. */
mp_int g; /**< Generator. A generator modulo N. */
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. */
} Srp;
WOLFSSL_API int wc_SrpInit(Srp* srp, byte type, byte side);
@@ -120,9 +118,10 @@ WOLFSSL_API int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size);
WOLFSSL_API int wc_SrpSetPrivate(Srp* srp, const byte* private, word32 size);
WOLFSSL_API int wc_SrpGenPublic(Srp* srp, byte* public, word32* size);
WOLFSSL_API int wc_SrpGetPublic(Srp* srp, byte* public, word32* size);
WOLFSSL_API int wc_SrpComputeKey(Srp* srp, byte* peersKey, word32 peersKeySz);
WOLFSSL_API int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
byte* serverPubKey, word32 serverPubKeySz);
#ifdef __cplusplus
} /* extern "C" */