forked from wolfSSL/wolfssl
adds tests to SrpSetPassword(), SrpSetVerifier(), SrpGetVerifier();
adds SrpGenPublic() and SrpSetPrivate() with unit tests; fixes k with left pad at g; adds new error SRP_CALL_ORDER_E to force the functions to be called in the right order.
This commit is contained in:
196
tests/srp.c
196
tests/srp.c
@ -30,20 +30,19 @@
|
||||
|
||||
#ifdef WOLFCRYPT_HAVE_SRP
|
||||
|
||||
static char user[] = "user";
|
||||
static byte username[] = "user";
|
||||
static word32 usernameSz = 4;
|
||||
|
||||
static byte password[] = "password";
|
||||
static word32 passwordSz = 8;
|
||||
|
||||
static byte N[] = {
|
||||
0x00, 0xc0, 0x37, 0xc3, 0x75, 0x88, 0xb4, 0x32, 0x98, 0x87, 0xe6, 0x1c,
|
||||
0x2d, 0xa3, 0x32, 0x4b, 0x1b, 0xa4, 0xb8, 0x1a, 0x63, 0xf9, 0x74, 0x8f,
|
||||
0xed, 0x2d, 0x8a, 0x41, 0x0c, 0x2f, 0xc2, 0x1b, 0x12, 0x32, 0xf0, 0xd3,
|
||||
0xbf, 0xa0, 0x24, 0x27, 0x6c, 0xfd, 0x88, 0x44, 0x81, 0x97, 0xaa, 0xe4,
|
||||
0x86, 0xa6, 0x3b, 0xfc, 0xa7, 0xb8, 0xbf, 0x77, 0x54, 0xdf, 0xb3, 0x27,
|
||||
0xc7, 0x20, 0x1f, 0x6f, 0xd1, 0x7f, 0xd7, 0xfd, 0x74, 0x15, 0x8b, 0xd3,
|
||||
0x1c, 0xe7, 0x72, 0xc9, 0xf5, 0xf8, 0xab, 0x58, 0x45, 0x48, 0xa9, 0x9a,
|
||||
0x75, 0x9b, 0x5a, 0x2c, 0x05, 0x32, 0x16, 0x2b, 0x7b, 0x62, 0x18, 0xe8,
|
||||
0xf1, 0x42, 0xbc, 0xe2, 0xc3, 0x0d, 0x77, 0x84, 0x68, 0x9a, 0x48, 0x3e,
|
||||
0x09, 0x5e, 0x70, 0x16, 0x18, 0x43, 0x79, 0x13, 0xa8, 0xc3, 0x9c, 0x3d,
|
||||
0xd0, 0xd4, 0xca, 0x3c, 0x50, 0x0b, 0x88, 0x5f, 0xe3
|
||||
0xD4, 0xC7, 0xF8, 0xA2, 0xB3, 0x2C, 0x11, 0xB8, 0xFB, 0xA9, 0x58, 0x1E,
|
||||
0xC4, 0xBA, 0x4F, 0x1B, 0x04, 0x21, 0x56, 0x42, 0xEF, 0x73, 0x55, 0xE3,
|
||||
0x7C, 0x0F, 0xC0, 0x44, 0x3E, 0xF7, 0x56, 0xEA, 0x2C, 0x6B, 0x8E, 0xEB,
|
||||
0x75, 0x5A, 0x1C, 0x72, 0x30, 0x27, 0x66, 0x3C, 0xAA, 0x26, 0x5E, 0xF7,
|
||||
0x85, 0xB8, 0xFF, 0x6A, 0x9B, 0x35, 0x22, 0x7A, 0x52, 0xD8, 0x66, 0x33,
|
||||
0xDB, 0xDF, 0xCA, 0x43
|
||||
};
|
||||
|
||||
static byte g[] = {
|
||||
@ -51,7 +50,46 @@ static byte g[] = {
|
||||
};
|
||||
|
||||
static byte salt[] = {
|
||||
'r', 'a', 'n', 'd', 'o', 'm'
|
||||
0x80, 0x66, 0x61, 0x5B, 0x7D, 0x33, 0xA2, 0x2E, 0x79, 0x18
|
||||
};
|
||||
|
||||
static byte verifier[] = {
|
||||
0x24, 0x5F, 0xA5, 0x1B, 0x2A, 0x28, 0xF8, 0xFF, 0xE2, 0xA0, 0xF8, 0x61,
|
||||
0x7B, 0x0F, 0x3C, 0x05, 0xD6, 0x4A, 0x55, 0xDF, 0x74, 0x31, 0x54, 0x47,
|
||||
0xA1, 0xFA, 0x9D, 0x25, 0x7B, 0x02, 0x88, 0x0A, 0xE8, 0x5A, 0xBA, 0x8B,
|
||||
0xA2, 0xD3, 0x8A, 0x62, 0x46, 0x8C, 0xEC, 0x52, 0xBE, 0xDE, 0xFC, 0x75,
|
||||
0xF5, 0xDB, 0x9C, 0x8C, 0x9B, 0x34, 0x7A, 0xE7, 0x4A, 0x5F, 0xBB, 0x96,
|
||||
0x38, 0x19, 0xAB, 0x24
|
||||
};
|
||||
|
||||
static byte a[] = {
|
||||
0x37, 0x95, 0xF2, 0xA6, 0xF1, 0x6F, 0x0D, 0x58, 0xBF, 0xED, 0x44, 0x87,
|
||||
0xE0, 0xB6, 0xCC, 0x1C, 0xA0, 0x50, 0xC6, 0x61, 0xBB, 0x36, 0xE0, 0x9A,
|
||||
0xF3, 0xF7, 0x1E, 0x7A, 0x61, 0x86, 0x5A, 0xF5
|
||||
};
|
||||
|
||||
static byte A[] = {
|
||||
0x8D, 0x28, 0xC5, 0x6A, 0x46, 0x5C, 0x82, 0xDB, 0xC7, 0xF6, 0x8B, 0x62,
|
||||
0x1A, 0xAD, 0xA1, 0x76, 0x1B, 0x55, 0xFF, 0xAB, 0x10, 0x2F, 0xFF, 0x4A,
|
||||
0xAA, 0x46, 0xAD, 0x33, 0x64, 0xDE, 0x28, 0x2E, 0x82, 0x7A, 0xBE, 0xEA,
|
||||
0x32, 0xFC, 0xD6, 0x14, 0x01, 0x71, 0xE6, 0xC8, 0xC9, 0x53, 0x69, 0x55,
|
||||
0xE1, 0xF8, 0x3D, 0xDD, 0xC7, 0xD5, 0x21, 0xCE, 0xFF, 0x17, 0xFC, 0x23,
|
||||
0xBF, 0xCF, 0x2D, 0xB0
|
||||
};
|
||||
|
||||
static byte b[] = {
|
||||
0x2B, 0xDD, 0x30, 0x30, 0x53, 0xAF, 0xD8, 0x3A, 0xE7, 0xE0, 0x17, 0x82,
|
||||
0x39, 0x44, 0x2C, 0xDB, 0x30, 0x88, 0x0F, 0xC8, 0x88, 0xC2, 0xB2, 0xC1,
|
||||
0x78, 0x43, 0x2F, 0xD5, 0x60, 0xD4, 0xDA, 0x43
|
||||
};
|
||||
|
||||
static byte B[] = {
|
||||
0xB5, 0x80, 0x36, 0x7F, 0x50, 0x89, 0xC1, 0x04, 0x42, 0x98, 0xD7, 0x6A,
|
||||
0x37, 0x8E, 0xF1, 0x81, 0x52, 0xC5, 0x7A, 0xA1, 0xD5, 0xB7, 0x66, 0x84,
|
||||
0xA1, 0x3E, 0x32, 0x82, 0x2B, 0x3A, 0xB5, 0xD7, 0x3D, 0x50, 0xF1, 0x58,
|
||||
0xBD, 0x89, 0x75, 0xC7, 0x51, 0xCF, 0x6C, 0x03, 0xD4, 0xCA, 0xD5, 0x6E,
|
||||
0x97, 0x4D, 0xA3, 0x1E, 0x19, 0x0B, 0xF0, 0xAA, 0x7D, 0x14, 0x90, 0x80,
|
||||
0x0E, 0xC7, 0x92, 0xAD
|
||||
};
|
||||
|
||||
static void test_SrpInit(void)
|
||||
@ -76,13 +114,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, user));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetUsername(&srp, NULL));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetUsername(NULL, username, usernameSz));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetUsername(&srp, NULL, usernameSz));
|
||||
|
||||
/* success */
|
||||
AssertIntEQ(0, wc_SrpSetUsername(&srp, user));
|
||||
AssertIntEQ((int) XSTRLEN(user), srp.userSz);
|
||||
AssertIntEQ(0, XMEMCMP(srp.user, user, srp.userSz));
|
||||
AssertIntEQ(0, wc_SrpSetUsername(&srp, username, usernameSz));
|
||||
AssertIntEQ((int) usernameSz, srp.userSz);
|
||||
AssertIntEQ(0, XMEMCMP(srp.user, username, usernameSz));
|
||||
|
||||
wc_SrpTerm(&srp);
|
||||
}
|
||||
@ -92,7 +130,14 @@ 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 call order */
|
||||
AssertIntEQ(SRP_CALL_ORDER_E, wc_SrpSetParams(&srp, N, sizeof(N),
|
||||
g, sizeof(g),
|
||||
salt, sizeof(salt)));
|
||||
|
||||
/* fix call order */
|
||||
AssertIntEQ(0, wc_SrpSetUsername(&srp, username, usernameSz));
|
||||
|
||||
/* invalid params */
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetParams(NULL, N, sizeof(N),
|
||||
@ -119,6 +164,117 @@ static void test_SrpSetParams(void)
|
||||
wc_SrpTerm(&srp);
|
||||
}
|
||||
|
||||
static void test_SrpSetPassword(void)
|
||||
{
|
||||
Srp srp;
|
||||
byte v[64];
|
||||
word32 vSz = 0;
|
||||
|
||||
AssertIntEQ(0, wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE));
|
||||
AssertIntEQ(0, wc_SrpSetUsername(&srp, username, usernameSz));
|
||||
|
||||
/* invalid call order */
|
||||
AssertIntEQ(SRP_CALL_ORDER_E,
|
||||
wc_SrpSetPassword(&srp, password, passwordSz));
|
||||
AssertIntEQ(SRP_CALL_ORDER_E,
|
||||
wc_SrpGetVerifier(&srp, v, &vSz));
|
||||
|
||||
/* fix call order */
|
||||
AssertIntEQ(0, wc_SrpSetParams(&srp, N, sizeof(N),
|
||||
g, sizeof(g),
|
||||
salt, sizeof(salt)));
|
||||
|
||||
/* invalid params */
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetPassword(NULL, password, passwordSz));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetPassword(&srp, NULL, passwordSz));
|
||||
|
||||
/* success */
|
||||
AssertIntEQ(0, wc_SrpSetPassword(&srp, password, passwordSz));
|
||||
|
||||
/* invalid params */
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGetVerifier(NULL, v, &vSz));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpGetVerifier(&srp, NULL, &vSz));
|
||||
AssertIntEQ(BUFFER_E, wc_SrpGetVerifier(&srp, v, &vSz));
|
||||
|
||||
/* success */
|
||||
vSz = sizeof(v);
|
||||
AssertIntEQ(0, wc_SrpGetVerifier(&srp, v, &vSz));
|
||||
AssertIntEQ(vSz, sizeof(verifier));
|
||||
AssertIntEQ(0, XMEMCMP(verifier, v, vSz));
|
||||
|
||||
/* invalid params - client side srp */
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetVerifier(&srp, v, vSz));
|
||||
|
||||
wc_SrpTerm(&srp);
|
||||
AssertIntEQ(0, wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_SERVER_SIDE));
|
||||
|
||||
/* invalid params */
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetVerifier(NULL, v, vSz));
|
||||
AssertIntEQ(BAD_FUNC_ARG, wc_SrpSetVerifier(&srp, NULL, vSz));
|
||||
|
||||
/* success */
|
||||
AssertIntEQ(0, wc_SrpSetVerifier(&srp, v, vSz));
|
||||
|
||||
wc_SrpTerm(&srp);
|
||||
}
|
||||
|
||||
static void test_SrpGenPublic(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 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));
|
||||
|
||||
/* 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(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_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));
|
||||
|
||||
/* 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(publicSz, sizeof(B));
|
||||
AssertIntEQ(0, XMEMCMP(public, B, publicSz));
|
||||
|
||||
wc_SrpTerm(&srp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void SrpTest(void)
|
||||
@ -127,5 +283,7 @@ void SrpTest(void)
|
||||
test_SrpInit();
|
||||
test_SrpSetUsername();
|
||||
test_SrpSetParams();
|
||||
test_SrpSetPassword();
|
||||
test_SrpGenPublic();
|
||||
#endif
|
||||
}
|
||||
|
@ -27,8 +27,8 @@
|
||||
|
||||
#define Fail(description, result) do { \
|
||||
printf("\nERROR - %s line %d failed with:", __FILE__, __LINE__); \
|
||||
printf("\n\n test: "); printf description; \
|
||||
printf("\n\n result: "); printf result; \
|
||||
printf("\n expected: "); printf description; \
|
||||
printf("\n result: "); printf result; printf("\n\n"); \
|
||||
abort(); \
|
||||
} while(0)
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#ifdef WOLFCRYPT_HAVE_SRP
|
||||
|
||||
#include <wolfssl/wolfcrypt/srp.h>
|
||||
#include <wolfssl/wolfcrypt/random.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
static int SrpHashInit(SrpHash* hash, int type)
|
||||
@ -218,21 +219,20 @@ void wc_SrpTerm(Srp* srp)
|
||||
}
|
||||
}
|
||||
|
||||
int wc_SrpSetUsername(Srp* srp, const char* user)
|
||||
int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size)
|
||||
{
|
||||
if (!srp || !user)
|
||||
if (!srp || !username)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
srp->user = (byte*)XMALLOC(XSTRLEN(user), NULL, DYNAMIC_TYPE_SRP);
|
||||
srp->user = (byte*)XMALLOC(size, NULL, DYNAMIC_TYPE_SRP);
|
||||
if (srp->user == NULL)
|
||||
return MEMORY_E;
|
||||
|
||||
srp->userSz = (word32) XSTRLEN(user);
|
||||
XMEMCPY(srp->user, user, srp->userSz);
|
||||
srp->userSz = size;
|
||||
XMEMCPY(srp->user, username, srp->userSz);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
const byte* g, word32 gSz,
|
||||
const byte* salt, word32 saltSz)
|
||||
@ -240,11 +240,15 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
SrpHash hash;
|
||||
byte digest1[SRP_MAX_DIGEST_SIZE];
|
||||
byte digest2[SRP_MAX_DIGEST_SIZE];
|
||||
byte pad = 0;
|
||||
int i, j, r;
|
||||
|
||||
if (!srp || !srp->user || !N || !g || !salt)
|
||||
if (!srp || !N || !g || !salt || nSz < gSz)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (!srp->user)
|
||||
return SRP_CALL_ORDER_E;
|
||||
|
||||
/* Set N */
|
||||
if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY)
|
||||
return MP_READ_E;
|
||||
@ -269,6 +273,8 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
/* Set k = H(N, g) */
|
||||
r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, (byte*) N, nSz);
|
||||
for (i = 0; (word32)i < nSz - gSz; i++)
|
||||
SrpHashUpdate(&hash, &pad, 1);
|
||||
if (!r) r = SrpHashUpdate(&hash, (byte*) g, gSz);
|
||||
if (!r) r = SrpHashFinal(&hash, srp->k);
|
||||
|
||||
@ -307,9 +313,12 @@ int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size)
|
||||
byte digest[SRP_MAX_DIGEST_SIZE];
|
||||
int r;
|
||||
|
||||
if (!srp || !srp->user || !password || srp->side != SRP_CLIENT_SIDE)
|
||||
if (!srp || !password || srp->side != SRP_CLIENT_SIDE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (!srp->salt)
|
||||
return SRP_CALL_ORDER_E;
|
||||
|
||||
/* digest = H(username | ':' | password) */
|
||||
r = SrpHashInit(&hash, srp->type);
|
||||
if (!r) r = SrpHashUpdate(&hash, srp->user, srp->userSz);
|
||||
@ -341,13 +350,16 @@ int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size)
|
||||
if (!srp || !verifier || !size || srp->side != SRP_CLIENT_SIDE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (mp_iszero(&srp->specific.client.x))
|
||||
return SRP_CALL_ORDER_E;
|
||||
|
||||
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 = *size < (word32)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);
|
||||
if (!r) *size = mp_unsigned_bin_size(&v);
|
||||
|
||||
mp_clear(&v);
|
||||
|
||||
@ -366,4 +378,107 @@ int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wc_SrpSetPrivate(Srp* srp, const byte* private, word32 size) {
|
||||
if (!srp || !private || !size)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
return mp_read_unsigned_bin(srp->type == SRP_CLIENT_SIDE
|
||||
? &srp->specific.client.a
|
||||
: &srp->specific.server.b, private, size);
|
||||
}
|
||||
|
||||
static int wc_SrpGenPrivate(Srp* srp, byte* private, word32 size) {
|
||||
RNG rng;
|
||||
int r = wc_InitRng(&rng);
|
||||
|
||||
if (!r) r = wc_RNG_GenerateBlock(&rng, private, size);
|
||||
if (!r) r = wc_SrpSetPrivate(srp, private, size);
|
||||
if (!r) wc_FreeRng(&rng);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int wc_SrpGenPublic(Srp* srp, byte* public, word32* size)
|
||||
{
|
||||
byte* buf;
|
||||
word32 len;
|
||||
int r = 0;
|
||||
|
||||
if (!srp || (!public && size) || (public && !size))
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (srp->side == SRP_CLIENT_SIDE && mp_iszero(&srp->N))
|
||||
return SRP_CALL_ORDER_E;
|
||||
|
||||
if (srp->side == SRP_SERVER_SIDE && (mp_iszero(&srp->N) ||
|
||||
mp_iszero(&srp->specific.server.v)))
|
||||
return SRP_CALL_ORDER_E;
|
||||
|
||||
len = mp_unsigned_bin_size(&srp->N);
|
||||
if (size && *size < len)
|
||||
return BUFFER_E;
|
||||
|
||||
buf = public ? public : (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_SRP);
|
||||
if (!buf)
|
||||
return MEMORY_E;
|
||||
|
||||
if (srp->side == SRP_CLIENT_SIDE) {
|
||||
/* a = random() */
|
||||
if (mp_iszero(&srp->specific.client.a))
|
||||
r = wc_SrpGenPrivate(srp, buf, len);
|
||||
|
||||
/* A = g ^ a % N */
|
||||
if (!r) r = mp_exptmod(&srp->g, &srp->specific.client.a,
|
||||
&srp->N, &srp->specific.client.A);
|
||||
|
||||
/* extract public key to buffer */
|
||||
XMEMSET(buf, 0, len);
|
||||
if (!r) r = mp_to_unsigned_bin(&srp->specific.client.A, buf);
|
||||
if (!r) len = mp_unsigned_bin_size(&srp->specific.client.A);
|
||||
|
||||
/* 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);
|
||||
|
||||
} else {
|
||||
mp_int i, j;
|
||||
|
||||
if (mp_init_multi(&i, &j, 0, 0, 0, 0) == MP_OKAY) {
|
||||
/* b = random() */
|
||||
if (mp_iszero(&srp->specific.server.b))
|
||||
r = wc_SrpGenPrivate(srp, buf, len);
|
||||
|
||||
/* B = (k * v + (g ^ b % N)) % N */
|
||||
if (!r) r = mp_read_unsigned_bin(&i, srp->k,SrpHashSize(srp->type));
|
||||
if (!r) r = mp_exptmod(&srp->g, &srp->specific.server.b,
|
||||
&srp->N, &srp->specific.server.B);
|
||||
if (!r) r = mp_mul(&i, &srp->specific.server.v, &j);
|
||||
if (!r) r = mp_add(&j, &srp->specific.server.B, &i);
|
||||
if (!r) r = mp_mod(&i, &srp->N, &srp->specific.server.B);
|
||||
|
||||
/* extract public key to buffer */
|
||||
XMEMSET(buf, 0, len);
|
||||
if (!r) r = mp_to_unsigned_bin(&srp->specific.server.B, buf);
|
||||
if (!r) len = mp_unsigned_bin_size(&srp->specific.server.B);
|
||||
|
||||
/* 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);
|
||||
|
||||
mp_clear(&i); mp_clear(&j);
|
||||
}
|
||||
}
|
||||
|
||||
if (public)
|
||||
*size = len;
|
||||
else
|
||||
XFREE(buf, NULL, DYNAMIC_TYPE_SRP);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* WOLFCRYPT_HAVE_SRP */
|
||||
|
@ -151,6 +151,8 @@ enum {
|
||||
ECC_INF_E = -215, /* ECC point infinity error */
|
||||
ECC_PRIV_KEY_E = -216, /* ECC private key not valid error */
|
||||
|
||||
SRP_CALL_ORDER_E = -217, /* SRP function called in the wrong order. */
|
||||
|
||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||
};
|
||||
|
||||
@ -163,5 +165,3 @@ WOLFSSL_API const char* wc_GetErrorString(int error);
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
#endif /* WOLF_CRYPT_ERROR_H */
|
||||
|
||||
|
||||
|
@ -116,20 +116,24 @@ typedef struct {
|
||||
} specific;
|
||||
} Srp;
|
||||
|
||||
WOLFSSL_API int wc_SrpInit(Srp* srp, byte type, byte side);
|
||||
WOLFSSL_API int wc_SrpInit(Srp* srp, byte type, byte side);
|
||||
WOLFSSL_API void wc_SrpTerm(Srp* srp);
|
||||
|
||||
WOLFSSL_API int wc_SrpSetUsername(Srp* srp, const char* user);
|
||||
WOLFSSL_API int wc_SrpSetUsername(Srp* srp, const byte* username, word32 size);
|
||||
|
||||
WOLFSSL_API int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
const byte* g, word32 gSz,
|
||||
const byte* salt, word32 saltSz);
|
||||
WOLFSSL_API int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
const byte* g, word32 gSz,
|
||||
const byte* salt, word32 saltSz);
|
||||
|
||||
WOLFSSL_API int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size);
|
||||
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_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size);
|
||||
|
||||
WOLFSSL_API int wc_SrpGetVerifier(Srp* srp, byte* verifier, word32* size);
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
Reference in New Issue
Block a user