diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index 780044017..555f3172c 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -30,84 +30,117 @@ #include #include -static int SrpHashInit(Srp* srp) +static int SrpHashInit(SrpHash* hash, int type) { - switch (srp->type) { + hash->type = type; + + switch (type) { #ifndef NO_SHA case SRP_TYPE_SHA: - return wc_InitSha(&srp->hash.sha); + return wc_InitSha(&hash->data.sha); #endif #ifndef NO_SHA256 case SRP_TYPE_SHA256: - return wc_InitSha256(&srp->hash.sha256); + return wc_InitSha256(&hash->data.sha256); #endif #ifdef WOLFSSL_SHA384 case SRP_TYPE_SHA384: - return wc_InitSha384(&srp->hash.sha384); + return wc_InitSha384(&hash->data.sha384); #endif #ifdef WOLFSSL_SHA512 case SRP_TYPE_SHA512: - return wc_InitSha512(&srp->hash.sha512); + return wc_InitSha512(&hash->data.sha512); #endif - default: return BAD_FUNC_ARG; + default: + return BAD_FUNC_ARG; } } -static int SrpHashUpdate(Srp* srp, byte* data, word32 size) +static int SrpHashUpdate(SrpHash* hash, byte* data, word32 size) { - switch (srp->type) { + switch (hash->type) { #ifndef NO_SHA case SRP_TYPE_SHA: - return wc_ShaUpdate(&srp->hash.sha, data, size); + return wc_ShaUpdate(&hash->data.sha, data, size); #endif #ifndef NO_SHA256 case SRP_TYPE_SHA256: - return wc_Sha256Update(&srp->hash.sha256, data, size); + return wc_Sha256Update(&hash->data.sha256, data, size); #endif #ifdef WOLFSSL_SHA384 case SRP_TYPE_SHA384: - return wc_Sha384Update(&srp->hash.sha384, data, size); + return wc_Sha384Update(&hash->data.sha384, data, size); #endif #ifdef WOLFSSL_SHA512 case SRP_TYPE_SHA512: - return wc_Sha512Update(&srp->hash.sha512, data, size); + return wc_Sha512Update(&hash->data.sha512, data, size); #endif - default: return BAD_FUNC_ARG; + default: + return BAD_FUNC_ARG; } } -static int SrpHashFinal(Srp* srp, byte* digest) +static int SrpHashFinal(SrpHash* hash, byte* digest) { - switch (srp->type) { + switch (hash->type) { #ifndef NO_SHA case SRP_TYPE_SHA: - return wc_ShaFinal(&srp->hash.sha, digest); + return wc_ShaFinal(&hash->data.sha, digest); #endif #ifndef NO_SHA256 - case SRP_TYPE_SHA256: return - wc_Sha256Final(&srp->hash.sha256, digest); + case SRP_TYPE_SHA256: + return wc_Sha256Final(&hash->data.sha256, digest); #endif #ifdef WOLFSSL_SHA384 - case SRP_TYPE_SHA384: return - wc_Sha384Final(&srp->hash.sha384, digest); + case SRP_TYPE_SHA384: + return wc_Sha384Final(&hash->data.sha384, digest); #endif #ifdef WOLFSSL_SHA512 - case SRP_TYPE_SHA512: return - wc_Sha512Final(&srp->hash.sha512, digest); + case SRP_TYPE_SHA512: + return wc_Sha512Final(&hash->data.sha512, digest); #endif - default: return BAD_FUNC_ARG; + default: + return BAD_FUNC_ARG; + } +} + +static word32 SrpHashSize(byte type) +{ + switch (type) { + #ifndef NO_SHA + case SRP_TYPE_SHA: + return SHA_DIGEST_SIZE; + #endif + + #ifndef NO_SHA256 + case SRP_TYPE_SHA256: + return SHA256_DIGEST_SIZE; + #endif + + #ifdef WOLFSSL_SHA384 + case SRP_TYPE_SHA384: + return SHA384_DIGEST_SIZE; + #endif + + #ifdef WOLFSSL_SHA512 + case SRP_TYPE_SHA512: + return SHA512_DIGEST_SIZE; + #endif + + default: + return 0; } } @@ -115,6 +148,8 @@ int wc_SrpInit(Srp* srp, byte type, byte side) { int ret = 0; + /* validating params */ + if (!srp) return BAD_FUNC_ARG; @@ -125,6 +160,8 @@ int wc_SrpInit(Srp* srp, byte type, byte side) type != SRP_TYPE_SHA384 && type != SRP_TYPE_SHA512) 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; @@ -132,21 +169,31 @@ int wc_SrpInit(Srp* srp, byte type, byte side) if (mp_init_multi(&srp->N, &srp->g, &srp->s, &srp->u, 0, 0) != MP_OKAY) return MP_INIT_E; + /* initializing client specific data */ + if (srp->side == SRP_CLIENT_SIDE) { - if (mp_init_multi(&srp->specific.client.a, - &srp->specific.client.A, - &srp->specific.client.B, - &srp->specific.client.password, 0, 0) != MP_OKAY) + 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; } - else { + + /* 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.verifier, 0, 0) != MP_OKAY) + &srp->specific.server.v, 0, 0) != MP_OKAY) ret = MP_INIT_E; } + /* undo initializations on error */ + if (ret != 0) { mp_clear(&srp->N); mp_clear(&srp->g); mp_clear(&srp->s); mp_clear(&srp->u); @@ -169,15 +216,16 @@ void wc_SrpTerm(Srp* srp) { mp_clear(&srp->specific.client.a); mp_clear(&srp->specific.client.A); mp_clear(&srp->specific.client.B); - mp_clear(&srp->specific.client.password); + mp_clear(&srp->specific.client.x); - XMEMSET(srp->specific.client.x, 0, SRP_MAX_DIGEST_SIZE); + XMEMSET(&srp->specific.client.proof, 0, sizeof(SrpHash)); } - else { + + if (srp->side == SRP_SERVER_SIDE) { mp_clear(&srp->specific.server.b); mp_clear(&srp->specific.server.B); mp_clear(&srp->specific.server.A); - mp_clear(&srp->specific.server.verifier); + mp_clear(&srp->specific.server.v); } } } @@ -200,6 +248,7 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, const byte* g, word32 gSz, const byte* salt, word32 saltSz) { + SrpHash hash; int ret = 0; if (!srp || !N || !g || !salt) @@ -211,16 +260,16 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, if (mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY) return MP_READ_E; - if ((ret = SrpHashInit(srp)) != 0) + if ((ret = SrpHashInit(&hash, srp->type)) != 0) return ret; - if ((ret = SrpHashUpdate(srp, (byte*) N, nSz)) != 0) + if ((ret = SrpHashUpdate(&hash, (byte*) N, nSz)) != 0) return ret; - if ((ret = SrpHashUpdate(srp, (byte*) g, gSz)) != 0) + if ((ret = SrpHashUpdate(&hash, (byte*) g, gSz)) != 0) return ret; - if ((ret = SrpHashFinal(srp, srp->k)) != 0) + if ((ret = SrpHashFinal(&hash, srp->k)) != 0) return ret; srp->salt = (byte*)XMALLOC(saltSz, NULL, DYNAMIC_TYPE_SRP); @@ -234,11 +283,16 @@ int wc_SrpSetParams(Srp* srp, const byte* N, word32 nSz, } int wc_SrpSetPassword(Srp* srp, const byte* password, word32 size) { + byte digest[SRP_MAX_DIGEST_SIZE]; + if (!srp || !password || srp->side != SRP_CLIENT_SIDE) return BAD_FUNC_ARG; - if (mp_read_unsigned_bin(&srp->specific.client.password, password, size) - != MP_OKAY) + (void) size; + /* TODO: calculate digest. */ + + if (mp_read_unsigned_bin(&srp->specific.client.x, digest, + SrpHashSize(srp->type)) != MP_OKAY) return MP_READ_E; return 0; diff --git a/wolfssl/wolfcrypt/srp.h b/wolfssl/wolfcrypt/srp.h index f79042b83..b75ac547a 100644 --- a/wolfssl/wolfcrypt/srp.h +++ b/wolfssl/wolfcrypt/srp.h @@ -64,34 +64,37 @@ enum { #endif }; -typedef union { - #ifndef NO_SHA - Sha sha; - #endif - #ifndef NO_SHA256 - Sha256 sha256; - #endif - #ifdef WOLFSSL_SHA384 - Sha384 sha384; - #endif - #ifdef WOLFSSL_SHA512 - Sha512 sha512; - #endif +typedef struct { + byte type; + union { + #ifndef NO_SHA + Sha sha; + #endif + #ifndef NO_SHA256 + Sha256 sha256; + #endif + #ifdef WOLFSSL_SHA384 + Sha384 sha384; + #endif + #ifdef WOLFSSL_SHA512 + Sha512 sha512; + #endif + } data; } SrpHash; typedef struct { mp_int a; /**< Private ephemeral value. Random. */ mp_int A; /**< Public ephemeral value. pow(g, a, N) */ mp_int B; /**< Server's public ephemeral value. */ - byte x[SRP_MAX_DIGEST_SIZE]; /**< Priv key. H(salt, H(user, ":", pswd)) */ - mp_int password; /**< Password. */ + mp_int x; /**< Priv key. H(salt, H(user, ":", pswd)) */ + SrpHash proof; /**< Client proof. Sent to Server. */ } SrpClient; typedef struct { mp_int b; /**< Private ephemeral value. */ mp_int B; /**< Public ephemeral value. */ mp_int A; /**< Client's public ephemeral value. */ - mp_int verifier; /**< Verifier. v = pow(g, x, N) */ + mp_int v; /**< Verifier. v = pow(g, x, N) */ } SrpServer; typedef struct { @@ -110,7 +113,6 @@ typedef struct { SrpClient client; SrpServer server; } specific; - SrpHash hash; /**< Hash object. */ } Srp; WOLFSSL_API int wc_SrpInit(Srp* srp, byte type, byte side);