forked from wolfSSL/wolfssl
finishes SrpSetPassword(), SrpSetVerifier(), SrpGetVerifier();
updates client_proof during SrpSetParams();
This commit is contained in:
11
tests/srp.c
11
tests/srp.c
@ -30,7 +30,7 @@
|
||||
|
||||
#ifdef WOLFCRYPT_HAVE_SRP
|
||||
|
||||
static char username[] = "username";
|
||||
static char user[] = "user";
|
||||
|
||||
static byte N[] = {
|
||||
0x00, 0xc0, 0x37, 0xc3, 0x75, 0x88, 0xb4, 0x32, 0x98, 0x87, 0xe6, 0x1c,
|
||||
@ -76,13 +76,13 @@ static void test_SrpSetUsername(void)
|
||||
AssertIntEQ(0, wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE));
|
||||
|
||||
/* invalid params */
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetUsername(NULL, username));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetUsername(NULL, user));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetUsername(&srp, NULL));
|
||||
|
||||
/* success */
|
||||
AssertIntEQ(0, wc_SrpSetUsername(&srp, username));
|
||||
AssertIntEQ((int) XSTRLEN(username), srp.usernameSz);
|
||||
AssertIntEQ(0, XMEMCMP(srp.username, username, srp.usernameSz));
|
||||
AssertIntEQ(0, wc_SrpSetUsername(&srp, user));
|
||||
AssertIntEQ((int) XSTRLEN(user), srp.userSz);
|
||||
AssertIntEQ(0, XMEMCMP(srp.user, user, srp.userSz));
|
||||
|
||||
wc_SrpTerm(&srp);
|
||||
}
|
||||
@ -92,6 +92,7 @@ static void test_SrpSetParams(void)
|
||||
Srp srp;
|
||||
|
||||
AssertIntEQ(0, wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE));
|
||||
AssertIntEQ(0, wc_SrpSetUsername(&srp, user));
|
||||
|
||||
/* invalid params */
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetParams(NULL, N, sizeof(N),
|
||||
|
@ -60,7 +60,7 @@ static int SrpHashInit(SrpHash* hash, int type)
|
||||
}
|
||||
}
|
||||
|
||||
static int SrpHashUpdate(SrpHash* hash, byte* data, word32 size)
|
||||
static int SrpHashUpdate(SrpHash* hash, const byte* data, word32 size)
|
||||
{
|
||||
switch (hash->type) {
|
||||
#ifndef NO_SHA
|
||||
@ -146,10 +146,9 @@ static word32 SrpHashSize(byte type)
|
||||
|
||||
int wc_SrpInit(Srp* srp, byte type, byte side)
|
||||
{
|
||||
int ret = 0;
|
||||
int r;
|
||||
|
||||
/* validating params */
|
||||
|
||||
if (!srp)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
@ -161,64 +160,51 @@ int wc_SrpInit(Srp* srp, byte type, byte side)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* initializing common data */
|
||||
|
||||
srp->side = side; srp->type = type;
|
||||
srp->salt = NULL; srp->saltSz = 0;
|
||||
srp->username = NULL; srp->usernameSz = 0;
|
||||
srp->user = NULL; srp->userSz = 0;
|
||||
|
||||
if (mp_init_multi(&srp->N, &srp->g, &srp->s, &srp->u, 0, 0) != MP_OKAY)
|
||||
return MP_INIT_E;
|
||||
|
||||
r = SrpHashInit(&srp->client_proof, type);
|
||||
if (!r) r = SrpHashInit(&srp->server_proof, type);
|
||||
|
||||
/* initializing client specific data */
|
||||
|
||||
if (srp->side == SRP_CLIENT_SIDE) {
|
||||
ret = SrpHashInit(&srp->specific.client.proof, type);
|
||||
|
||||
if (ret == 0 && mp_init_multi(&srp->specific.client.a,
|
||||
&srp->specific.client.A,
|
||||
&srp->specific.client.B,
|
||||
&srp->specific.client.x,
|
||||
0, 0) != MP_OKAY)
|
||||
ret = MP_INIT_E;
|
||||
}
|
||||
if (!r && srp->side == SRP_CLIENT_SIDE)
|
||||
r = mp_init_multi(&srp->specific.client.a, &srp->specific.client.A,
|
||||
&srp->specific.client.B, &srp->specific.client.x,0,0);
|
||||
|
||||
/* initializing server specific data */
|
||||
|
||||
if (srp->side == SRP_SERVER_SIDE) {
|
||||
if (mp_init_multi(&srp->specific.server.b,
|
||||
&srp->specific.server.B,
|
||||
&srp->specific.server.A,
|
||||
&srp->specific.server.v, 0, 0) != MP_OKAY)
|
||||
ret = MP_INIT_E;
|
||||
}
|
||||
if (!r && srp->side == SRP_SERVER_SIDE)
|
||||
r = mp_init_multi(&srp->specific.server.b, &srp->specific.server.B,
|
||||
&srp->specific.server.A, &srp->specific.server.v,0,0);
|
||||
|
||||
/* undo initializations on error */
|
||||
|
||||
if (ret != 0) {
|
||||
if (r != 0) {
|
||||
mp_clear(&srp->N); mp_clear(&srp->g);
|
||||
mp_clear(&srp->s); mp_clear(&srp->u);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return r;
|
||||
}
|
||||
|
||||
void wc_SrpTerm(Srp* srp) {
|
||||
void wc_SrpTerm(Srp* srp)
|
||||
{
|
||||
if (srp) {
|
||||
mp_clear(&srp->N); mp_clear(&srp->g);
|
||||
mp_clear(&srp->s); mp_clear(&srp->u);
|
||||
|
||||
XMEMSET(srp->salt, 0, srp->saltSz);
|
||||
XFREE(srp->salt, NULL, DYNAMIC_TYPE_SRP);
|
||||
XMEMSET(srp->username, 0, srp->usernameSz);
|
||||
XFREE(srp->username, NULL, DYNAMIC_TYPE_SRP);
|
||||
XMEMSET(srp->user, 0, srp->userSz);
|
||||
XFREE(srp->user, NULL, DYNAMIC_TYPE_SRP);
|
||||
|
||||
if (srp->side == SRP_CLIENT_SIDE) {
|
||||
mp_clear(&srp->specific.client.a);
|
||||
mp_clear(&srp->specific.client.A);
|
||||
mp_clear(&srp->specific.client.B);
|
||||
mp_clear(&srp->specific.client.x);
|
||||
|
||||
XMEMSET(&srp->specific.client.proof, 0, sizeof(SrpHash));
|
||||
}
|
||||
|
||||
if (srp->side == SRP_SERVER_SIDE) {
|
||||
@ -227,19 +213,22 @@ void wc_SrpTerm(Srp* srp) {
|
||||
mp_clear(&srp->specific.server.A);
|
||||
mp_clear(&srp->specific.server.v);
|
||||
}
|
||||
|
||||
XMEMSET(srp, 0, sizeof(Srp));
|
||||
}
|
||||
}
|
||||
|
||||
int wc_SrpSetUsername(Srp* srp, const char* username) {
|
||||
if (!srp || !username)
|
||||
int wc_SrpSetUsername(Srp* srp, const char* user)
|
||||
{
|
||||
if (!srp || !user)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
srp->username = (byte*)XMALLOC(XSTRLEN(username), NULL, DYNAMIC_TYPE_SRP);
|
||||
if (srp->username == NULL)
|
||||
srp->user = (byte*)XMALLOC(XSTRLEN(user), NULL, DYNAMIC_TYPE_SRP);
|
||||
if (srp->user == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
srp->usernameSz = (word32) XSTRLEN(username);
|
||||
XMEMCPY(srp->username, username, srp->usernameSz);
|
||||
srp->userSz = (word32) XSTRLEN(user);
|
||||
XMEMCPY(srp->user, user, srp->userSz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -249,28 +238,26 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
const byte* salt, word32 saltSz)
|
||||
{
|
||||
SrpHash hash;
|
||||
int ret = 0;
|
||||
byte digest1[SRP_MAX_DIGEST_SIZE];
|
||||
byte digest2[SRP_MAX_DIGEST_SIZE];
|
||||
int i, j, r;
|
||||
|
||||
if (!srp || !N || !g || !salt)
|
||||
if (!srp || !srp->user || !N || !g || !salt)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* Set N */
|
||||
if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY)
|
||||
return MP_READ_E;
|
||||
|
||||
/* Set g */
|
||||
if (mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY)
|
||||
return MP_READ_E;
|
||||
|
||||
if ((ret = SrpHashInit(&hash, srp->type)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = SrpHashUpdate(&hash, (byte*) N, nSz)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = SrpHashUpdate(&hash, (byte*) g, gSz)) != 0)
|
||||
return ret;
|
||||
|
||||
if ((ret = SrpHashFinal(&hash, srp->k)) != 0)
|
||||
return ret;
|
||||
/* Set salt */
|
||||
if (srp->salt) {
|
||||
XMEMSET(srp->salt, 0, srp->saltSz);
|
||||
XFREE(srp->salt, NULL, DYNAMIC_TYPE_SRP);
|
||||
}
|
||||
|
||||
srp->salt = (byte*)XMALLOC(saltSz, NULL, DYNAMIC_TYPE_SRP);
|
||||
if (srp->salt == NULL)
|
||||
@ -279,20 +266,101 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
XMEMCPY(srp->salt, salt, saltSz);
|
||||
srp->saltSz = saltSz;
|
||||
|
||||
return 0;
|
||||
/* Set k = H(N, g) */
|
||||
r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz);
|
||||
if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz);
|
||||
if (!r) r = SrpHashFinal(&hash, srp->k);
|
||||
|
||||
/* Update client proof */
|
||||
|
||||
/* digest1 = H(N) */
|
||||
if (!r) r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz);
|
||||
if (!r) r = SrpHashFinal(&hash, digest1);
|
||||
|
||||
/* digest2 = H(g) */
|
||||
if (!r) r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz);
|
||||
if (!r) r = SrpHashFinal(&hash, digest2);
|
||||
|
||||
/* digest1 = H(N) ^ H(g) */
|
||||
for (i = 0, j = SrpHashSize(srp->type); i < j; i++)
|
||||
digest1[i] ^= digest2[i];
|
||||
|
||||
/* digest2 = H(user) */
|
||||
if (!r) r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz);
|
||||
if (!r) r = SrpHashFinal(&hash, digest2);
|
||||
|
||||
/* Client proof = H( H(N) ^ H(g) | H(user) | salt) */
|
||||
if (!r) r = SrpHashUpdate(&srp->client_proof, digest1, j);
|
||||
if (!r) r = SrpHashUpdate(&srp->client_proof, digest2, j);
|
||||
if (!r) r = SrpHashUpdate(&srp->client_proof, salt, saltSz);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size) {
|
||||
int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size)
|
||||
{
|
||||
SrpHash hash;
|
||||
byte digest[SRP_MAX_DIGEST_SIZE];
|
||||
int r;
|
||||
|
||||
if (!srp || !password || srp->side != SRP_CLIENT_SIDE)
|
||||
if (!srp || !srp->user || !password || srp->side != SRP_CLIENT_SIDE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
(void) size;
|
||||
/* TODO: calculate digest. */
|
||||
/* digest = H(username | ':' | password) */
|
||||
r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz);
|
||||
if (!r) r = SrpHashUpdate(&hash, (const byte*) ":", 1);
|
||||
if (!r) r = SrpHashUpdate(&hash, password, size);
|
||||
if (!r) r = SrpHashFinal(&hash, digest);
|
||||
|
||||
if (mp_read_unsigned_bin(&srp->specific.client.x, digest,
|
||||
/* digest = H(salt | H(username | ':' | password)) */
|
||||
if (!r) r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, srp->salt, srp->saltSz);
|
||||
if (!r) r = SrpHashUpdate(&hash, digest, SrpHashSize(srp->type));
|
||||
if (!r) r = SrpHashFinal(&hash, digest);
|
||||
|
||||
/* Set x (private key) */
|
||||
if (!r && mp_read_unsigned_bin(&srp->specific.client.x, digest,
|
||||
SrpHashSize(srp->type)) != MP_OKAY)
|
||||
r = MP_READ_E;
|
||||
|
||||
XMEMSET(digest, 0, SRP_MAX_DIGEST_SIZE);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size)
|
||||
{
|
||||
mp_int v;
|
||||
int r;
|
||||
|
||||
if (!srp || !verifier || !size || srp->side != SRP_CLIENT_SIDE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
r = mp_init(&v);
|
||||
|
||||
/* v = g ^ x % N */
|
||||
if (!r) r = mp_exptmod(&srp->g, &srp->specific.client.x, &srp->N, &v);
|
||||
if (!r) r = (int)*size < mp_unsigned_bin_size(&v) ? BUFFER_E : MP_OKAY;
|
||||
if (!r) r = mp_to_unsigned_bin(&v, verifier);
|
||||
if (!r) *size = mp_unsigned_bin_size(&srp->specific.server.v);
|
||||
|
||||
mp_clear(&v);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size)
|
||||
{
|
||||
if (!srp || !verifier || srp->side != SRP_SERVER_SIDE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (mp_read_unsigned_bin(&srp->specific.server.v, verifier, size)
|
||||
!= MP_OKAY)
|
||||
return MP_READ_E;
|
||||
|
||||
return 0;
|
||||
|
@ -87,7 +87,6 @@ typedef struct {
|
||||
mp_int A; /**< Public ephemeral value. pow(g, a, N) */
|
||||
mp_int B; /**< Server's public ephemeral value. */
|
||||
mp_int x; /**< Priv key. H(salt, H(user, ":", pswd)) */
|
||||
SrpHash proof; /**< Client proof. Sent to Server. */
|
||||
} SrpClient;
|
||||
|
||||
typedef struct {
|
||||
@ -105,10 +104,12 @@ typedef struct {
|
||||
mp_int s; /**< Session key. */
|
||||
byte k[SRP_MAX_DIGEST_SIZE]; /**< Multiplier parameeter. H(N, g) */
|
||||
mp_int u; /**< Random scrambling parameeter. */
|
||||
byte* username; /**< Username, login. */
|
||||
word32 usernameSz; /**< Username length. */
|
||||
byte* user; /**< Username, login. */
|
||||
word32 userSz; /**< Username length. */
|
||||
byte* salt; /**< Small salt. */
|
||||
word32 saltSz; /**< Salt length. */
|
||||
SrpHash client_proof; /**< Client proof. Sent to Server. */
|
||||
SrpHash server_proof; /**< Server proof. Sent to Client. */
|
||||
union {
|
||||
SrpClient client;
|
||||
SrpServer server;
|
||||
@ -126,6 +127,10 @@ WOLFSSL_API int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
|
||||
WOLFSSL_API int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size);
|
||||
|
||||
WOLFSSL_API int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size);
|
||||
|
||||
WOLFSSL_API int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user