forked from wolfSSL/wolfssl
makes sure random values are safe.
This commit is contained in:
@ -328,6 +328,15 @@ const char* wc_GetErrorString(int error)
|
||||
case ECC_PRIV_KEY_E:
|
||||
return " ECC private key is not valid error";
|
||||
|
||||
case SRP_CALL_ORDER_E:
|
||||
return "SRP function called in the wrong order error";
|
||||
|
||||
case SRP_VERIFY_E:
|
||||
return "SRP proof verification error";
|
||||
|
||||
case SRP_BAD_KEY_E:
|
||||
return "SRP bad key values error";
|
||||
|
||||
default:
|
||||
return "unknown error number";
|
||||
|
||||
|
@ -32,40 +32,7 @@
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
/** Computes the session key using the Mask Generation Function 1. */
|
||||
static int wc_SrpSetK(Srp* srp, byte* secret, word32 size);
|
||||
|
||||
#include <stdio.h>
|
||||
static inline void LogHex(byte* data, word32 length)
|
||||
{
|
||||
#define LINE_LEN 16
|
||||
|
||||
word32 i;
|
||||
|
||||
printf("\t");
|
||||
|
||||
if (!data) {
|
||||
printf("NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < LINE_LEN; i++) {
|
||||
if (i < length)
|
||||
printf("%02x ", data[i]);
|
||||
else
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
printf("| ");
|
||||
|
||||
for (i = 0; i < LINE_LEN; i++)
|
||||
if (i < length)
|
||||
printf("%c", 31 < data[i] && data[i] < 127 ? data[i] : '.');
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (length > LINE_LEN)
|
||||
LogHex(data + LINE_LEN, length - LINE_LEN);
|
||||
}
|
||||
static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size);
|
||||
|
||||
static int SrpHashInit(SrpHash* hash, SrpType type)
|
||||
{
|
||||
@ -216,7 +183,7 @@ int wc_SrpInit(Srp* srp, SrpType type, SrpSide side)
|
||||
srp->user = NULL; srp->userSz = 0;
|
||||
srp->key = NULL; srp->keySz = 0;
|
||||
|
||||
srp->keyGenFunc_cb = wc_SrpSetK;
|
||||
srp->keyGenFunc_cb = wc_SrpSetKey;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -273,10 +240,16 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz,
|
||||
if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY)
|
||||
return MP_READ_E;
|
||||
|
||||
if (mp_count_bits(&srp->N) < SRP_DEFAULT_MIN_BITS)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* Set g */
|
||||
if (mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY)
|
||||
return MP_READ_E;
|
||||
|
||||
if (mp_cmp(&srp->N, &srp->g) != MP_GT)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
/* Set salt */
|
||||
if (srp->salt) {
|
||||
XMEMSET(srp->salt, 0, srp->saltSz);
|
||||
@ -397,13 +370,23 @@ int wc_SrpSetVerifier(Srp* srp, const byte* verifier, word32 size)
|
||||
|
||||
int wc_SrpSetPrivate(Srp* srp, const byte* private, word32 size)
|
||||
{
|
||||
mp_int p;
|
||||
int r;
|
||||
|
||||
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);
|
||||
r = mp_init(&p);
|
||||
if (!r) r = mp_read_unsigned_bin(&p, private, size);
|
||||
if (!r) r = mp_mod(&p, &srp->N, &srp->priv);
|
||||
if (!r) r = mp_iszero(&srp->priv) ? SRP_BAD_KEY_E : 0;
|
||||
|
||||
mp_clear(&p);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Generates random data using wolfcrypt RNG. */
|
||||
@ -452,6 +435,7 @@ int wc_SrpGetPublic(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_iszero(&i) ? SRP_BAD_KEY_E : 0;
|
||||
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, &pubkey, &i);
|
||||
@ -470,7 +454,7 @@ int wc_SrpGetPublic(Srp* srp, byte* public, word32* size)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int wc_SrpSetK(Srp* srp, byte* secret, word32 size)
|
||||
static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size)
|
||||
{
|
||||
SrpHash hash;
|
||||
byte digest[SRP_MAX_DIGEST_SIZE];
|
||||
@ -566,11 +550,15 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
|
||||
/* building s (secret) */
|
||||
|
||||
if (!r && srp->side == SRP_CLIENT_SIDE) {
|
||||
/* temp1 = B - k * v */
|
||||
|
||||
/* temp1 = B - k * v; rejects k == 0, B == 0 and B >= N. */
|
||||
r = mp_read_unsigned_bin(&temp1, srp->k, digestSz);
|
||||
if (!r) r = mp_iszero(&temp1) ? SRP_BAD_KEY_E : 0;
|
||||
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_iszero(&temp2) ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_cmp(&temp2, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_sub(&temp2, &s, &temp1);
|
||||
|
||||
/* temp2 = a + u * x */
|
||||
@ -584,10 +572,18 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
|
||||
/* temp1 = v ^ u % N */
|
||||
r = mp_exptmod(&srp->auth, &u, &srp->N, &temp1);
|
||||
|
||||
/* temp2 = A * temp1 % N */
|
||||
/* temp2 = A * temp1 % N; rejects A == 0, A >= N */
|
||||
if (!r) r = mp_read_unsigned_bin(&s, clientPubKey, clientPubKeySz);
|
||||
if (!r) r = mp_iszero(&s) ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_cmp(&s, &srp->N) != MP_LT ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_mulmod(&s, &temp1, &srp->N, &temp2);
|
||||
|
||||
/* rejects A * v ^ u % N >= 1, A * v ^ u % N == -1 % N */
|
||||
if (!r) r = mp_read_unsigned_bin(&temp1, (const byte*)"\001", 1);
|
||||
if (!r) r = mp_cmp(&temp2, &temp1) != MP_GT ? SRP_BAD_KEY_E : 0;
|
||||
if (!r) r = mp_sub(&srp->N, &temp1, &s);
|
||||
if (!r) r = mp_cmp(&temp2, &s) == MP_EQ ? SRP_BAD_KEY_E : 0;
|
||||
|
||||
/* secret = temp2 * b % N */
|
||||
if (!r) r = mp_exptmod(&temp2, &srp->priv, &srp->N, &s);
|
||||
}
|
||||
@ -596,8 +592,6 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
|
||||
|
||||
if (!r) r = mp_to_unsigned_bin(&s, secret);
|
||||
if (!r) r = srp->keyGenFunc_cb(srp, secret, mp_unsigned_bin_size(&s));
|
||||
printf("key\n");
|
||||
LogHex(srp->key, srp->keySz);
|
||||
|
||||
/* updating client proof = H( H(N) ^ H(g) | H(user) | salt | A | B | K) */
|
||||
|
||||
|
@ -153,6 +153,7 @@ enum {
|
||||
|
||||
SRP_CALL_ORDER_E = -217, /* SRP function called in the wrong order. */
|
||||
SRP_VERIFY_E = -218, /* SRP proof verification failed. */
|
||||
SRP_BAD_KEY_E = -219, /* SRP bad ephemeral values. */
|
||||
|
||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||
};
|
||||
|
@ -47,6 +47,9 @@
|
||||
#error "You have to have some kind of SHA hash if you want to use SRP."
|
||||
#endif
|
||||
|
||||
/* Set the minimum number of bits acceptable in an SRP modulus */
|
||||
#define SRP_DEFAULT_MIN_BITS 512
|
||||
|
||||
/**
|
||||
* SRP side, client or server.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user