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:
|
case ECC_PRIV_KEY_E:
|
||||||
return " ECC private key is not valid error";
|
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:
|
default:
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
|
|
||||||
|
@ -32,40 +32,7 @@
|
|||||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||||
|
|
||||||
/** Computes the session key using the Mask Generation Function 1. */
|
/** Computes the session key using the Mask Generation Function 1. */
|
||||||
static int wc_SrpSetK(Srp* srp, byte* secret, word32 size);
|
static int wc_SrpSetKey(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 SrpHashInit(SrpHash* hash, SrpType type)
|
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->user = NULL; srp->userSz = 0;
|
||||||
srp->key = NULL; srp->keySz = 0;
|
srp->key = NULL; srp->keySz = 0;
|
||||||
|
|
||||||
srp->keyGenFunc_cb = wc_SrpSetK;
|
srp->keyGenFunc_cb = wc_SrpSetKey;
|
||||||
|
|
||||||
return 0;
|
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)
|
if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY)
|
||||||
return MP_READ_E;
|
return MP_READ_E;
|
||||||
|
|
||||||
|
if (mp_count_bits(&srp->N) < SRP_DEFAULT_MIN_BITS)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* Set g */
|
/* Set g */
|
||||||
if (mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY)
|
if (mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY)
|
||||||
return MP_READ_E;
|
return MP_READ_E;
|
||||||
|
|
||||||
|
if (mp_cmp(&srp->N, &srp->g) != MP_GT)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
/* Set salt */
|
/* Set salt */
|
||||||
if (srp->salt) {
|
if (srp->salt) {
|
||||||
XMEMSET(srp->salt, 0, srp->saltSz);
|
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)
|
int wc_SrpSetPrivate(Srp* srp, const byte* private, word32 size)
|
||||||
{
|
{
|
||||||
|
mp_int p;
|
||||||
|
int r;
|
||||||
|
|
||||||
if (!srp || !private || !size)
|
if (!srp || !private || !size)
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (mp_iszero(&srp->auth))
|
if (mp_iszero(&srp->auth))
|
||||||
return SRP_CALL_ORDER_E;
|
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. */
|
/** 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 (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_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_exptmod(&srp->g, &srp->priv, &srp->N, &pubkey);
|
||||||
if (!r) r = mp_mulmod(&i, &srp->auth, &srp->N, &j);
|
if (!r) r = mp_mulmod(&i, &srp->auth, &srp->N, &j);
|
||||||
if (!r) r = mp_add(&j, &pubkey, &i);
|
if (!r) r = mp_add(&j, &pubkey, &i);
|
||||||
@ -470,7 +454,7 @@ int wc_SrpGetPublic(Srp* srp, byte* public, word32* size)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wc_SrpSetK(Srp* srp, byte* secret, word32 size)
|
static int wc_SrpSetKey(Srp* srp, byte* secret, word32 size)
|
||||||
{
|
{
|
||||||
SrpHash hash;
|
SrpHash hash;
|
||||||
byte digest[SRP_MAX_DIGEST_SIZE];
|
byte digest[SRP_MAX_DIGEST_SIZE];
|
||||||
@ -566,11 +550,15 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
|
|||||||
/* building s (secret) */
|
/* building s (secret) */
|
||||||
|
|
||||||
if (!r && srp->side == SRP_CLIENT_SIDE) {
|
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);
|
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_exptmod(&srp->g, &srp->auth, &srp->N, &temp2);
|
||||||
if (!r) r = mp_mulmod(&temp1, &temp2, &srp->N, &s);
|
if (!r) r = mp_mulmod(&temp1, &temp2, &srp->N, &s);
|
||||||
if (!r) r = mp_read_unsigned_bin(&temp2, serverPubKey, serverPubKeySz);
|
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);
|
if (!r) r = mp_sub(&temp2, &s, &temp1);
|
||||||
|
|
||||||
/* temp2 = a + u * x */
|
/* temp2 = a + u * x */
|
||||||
@ -584,10 +572,18 @@ int wc_SrpComputeKey(Srp* srp, byte* clientPubKey, word32 clientPubKeySz,
|
|||||||
/* temp1 = v ^ u % N */
|
/* temp1 = v ^ u % N */
|
||||||
r = mp_exptmod(&srp->auth, &u, &srp->N, &temp1);
|
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_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);
|
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 */
|
/* secret = temp2 * b % N */
|
||||||
if (!r) r = mp_exptmod(&temp2, &srp->priv, &srp->N, &s);
|
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 = mp_to_unsigned_bin(&s, secret);
|
||||||
if (!r) r = srp->keyGenFunc_cb(srp, secret, mp_unsigned_bin_size(&s));
|
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) */
|
/* 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_CALL_ORDER_E = -217, /* SRP function called in the wrong order. */
|
||||||
SRP_VERIFY_E = -218, /* SRP proof verification failed. */
|
SRP_VERIFY_E = -218, /* SRP proof verification failed. */
|
||||||
|
SRP_BAD_KEY_E = -219, /* SRP bad ephemeral values. */
|
||||||
|
|
||||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
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."
|
#error "You have to have some kind of SHA hash if you want to use SRP."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Set the minimum number of bits acceptable in an SRP modulus */
|
||||||
|
#define SRP_DEFAULT_MIN_BITS 512
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SRP side, client or server.
|
* SRP side, client or server.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user