makes sure random values are safe.

This commit is contained in:
Moisés Guimarães
2015-08-04 14:48:17 -03:00
parent 12b8445153
commit 690cb14746
4 changed files with 48 additions and 41 deletions

View File

@ -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";

View File

@ -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) */

View File

@ -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 */
};

View File

@ -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.
*/