diff --git a/tests/include.am b/tests/include.am index f276f3af0..802ec5ad1 100644 --- a/tests/include.am +++ b/tests/include.am @@ -11,6 +11,7 @@ tests_unit_test_SOURCES = \ tests/api.c \ tests/suites.c \ tests/hash.c \ + tests/srp.c \ examples/client/client.c \ examples/server/server.c tests_unit_test_CFLAGS = -DNO_MAIN_DRIVER $(AM_CFLAGS) diff --git a/tests/srp.c b/tests/srp.c new file mode 100644 index 000000000..4b8879b43 --- /dev/null +++ b/tests/srp.c @@ -0,0 +1,91 @@ +/* srp.c SRP unit tests + * + * Copyright (C) 2006-2015 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#include +#include + +#ifdef WOLFCRYPT_HAVE_SRP + +static void test_SrpInit(void) +{ + 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 + }; + + byte g[] = { + 0x02 + }; + + Srp srp; + + AssertIntEQ(BAD_FUNC_ARG, + wc_SrpInit(NULL, SRP_TYPE_SHA, SRP_CLIENT_SIDE, N, sizeof(N), + g, sizeof(g))); + + AssertIntEQ(BAD_FUNC_ARG, + wc_SrpInit(&srp, 255, SRP_CLIENT_SIDE, N, sizeof(N), + g, sizeof(g))); + + AssertIntEQ(BAD_FUNC_ARG, + wc_SrpInit(&srp, SRP_TYPE_SHA, 255, N, sizeof(N), + g, sizeof(g))); + + AssertIntEQ(BAD_FUNC_ARG, + wc_SrpInit(&srp, SRP_TYPE_SHA, 255, N, sizeof(N), + g, sizeof(g))); + + AssertIntEQ(BAD_FUNC_ARG, + wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE, NULL, sizeof(N), + g, sizeof(g))); + + AssertIntEQ(BAD_FUNC_ARG, + wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE, N, sizeof(N), + NULL, sizeof(g))); + + AssertIntEQ(0, + wc_SrpInit(&srp, SRP_TYPE_SHA, SRP_CLIENT_SIDE, N, sizeof(N), + g, sizeof(g))); +} + +#endif + +void SrpTest(void) +{ +#ifdef WOLFCRYPT_HAVE_SRP + test_SrpInit(); +#endif +} diff --git a/tests/unit.c b/tests/unit.c index 73ae2bcd7..3a7f2452c 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -77,6 +77,8 @@ int unit_test(int argc, char** argv) } #endif + SrpTest(); + #ifdef HAVE_CAVIUM CspShutdown(CAVIUM_DEV_ID); #endif @@ -92,7 +94,7 @@ void wait_tcp_ready(func_args* args) (void)args; #elif defined(_POSIX_THREADS) && !defined(__MINGW32__) pthread_mutex_lock(&args->signal->mutex); - + if (!args->signal->ready) pthread_cond_wait(&args->signal->cond, &args->signal->mutex); args->signal->ready = 0; /* reset */ @@ -176,4 +178,3 @@ void FreeTcpReady(tcp_ready* ready) (void)ready; #endif } - diff --git a/tests/unit.h b/tests/unit.h index bccd6d2ce..997186291 100644 --- a/tests/unit.h +++ b/tests/unit.h @@ -76,9 +76,9 @@ void ApiTest(void); -int SuiteTest(void); -int HashTest(void); +int SuiteTest(void); +int HashTest(void); +void SrpTest(void); #endif /* CyaSSL_UNIT_H */ - diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index 242adfa55..50716f5d9 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -134,31 +134,31 @@ static int InitHmac(Hmac* hmac, int type) ret = wc_InitSha(&hmac->hash.sha); break; #endif - + #ifndef NO_SHA256 case SHA256: ret = wc_InitSha256(&hmac->hash.sha256); break; #endif - + #ifdef WOLFSSL_SHA384 case SHA384: ret = wc_InitSha384(&hmac->hash.sha384); break; #endif - + #ifdef WOLFSSL_SHA512 case SHA512: ret = wc_InitSha512(&hmac->hash.sha512); break; #endif - - #ifdef HAVE_BLAKE2 + + #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = wc_InitBlake2b(&hmac->hash.blake2b, BLAKE2B_256); break; #endif - + default: return BAD_FUNC_ARG; } @@ -287,7 +287,7 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) break; #endif - #ifdef HAVE_BLAKE2 + #ifdef HAVE_BLAKE2 case BLAKE2B_ID: { hmac_block_size = BLAKE2B_BLOCKBYTES; @@ -367,7 +367,7 @@ static int HmacKeyInnerHash(Hmac* hmac) break; #endif - #ifdef HAVE_BLAKE2 + #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = wc_Blake2bUpdate(&hmac->hash.blake2b, (byte*) hmac->ipad,BLAKE2B_BLOCKBYTES); @@ -438,7 +438,7 @@ int wc_HmacUpdate(Hmac* hmac, const byte* msg, word32 length) break; #endif - #ifdef HAVE_BLAKE2 + #ifdef HAVE_BLAKE2 case BLAKE2B_ID: ret = wc_Blake2bUpdate(&hmac->hash.blake2b, msg, length); if (ret != 0) @@ -570,7 +570,7 @@ int wc_HmacFinal(Hmac* hmac, byte* hash) break; #endif - #ifdef HAVE_BLAKE2 + #ifdef HAVE_BLAKE2 case BLAKE2B_ID: { ret = wc_Blake2bFinal(&hmac->hash.blake2b, (byte*) hmac->innerHash, @@ -622,7 +622,7 @@ int wc_HmacInitCavium(Hmac* hmac, int devId) hmac->devId = devId; hmac->magic = WOLFSSL_HMAC_CAVIUM_MAGIC; hmac->data = NULL; /* buffered input data */ - + hmac->innerHashKeyed = 0; return 0; @@ -650,7 +650,7 @@ static void HmacCaviumFinal(Hmac* hmac, byte* hash) (byte*)hmac->ipad, hmac->dataLen, hmac->data, hash, &requestId, hmac->devId) != 0) { WOLFSSL_MSG("Cavium Hmac failed"); - } + } hmac->innerHashKeyed = 0; /* tell update to start over if used again */ } @@ -685,7 +685,7 @@ static void HmacCaviumUpdate(Hmac* hmac, const byte* msg, word32 length) if (hmac->dataLen) XMEMCPY(tmp, hmac->data, hmac->dataLen); XMEMCPY(tmp + hmac->dataLen, msg, add); - + hmac->dataLen += add; XFREE(hmac->data, NULL, DYNAMIC_TYPE_CAVIUM_TMP); hmac->data = tmp; @@ -751,31 +751,31 @@ static INLINE int GetHashSizeByType(int type) return SHA_DIGEST_SIZE; break; #endif - + #ifndef NO_SHA256 case SHA256: return SHA256_DIGEST_SIZE; break; #endif - + #ifdef WOLFSSL_SHA384 case SHA384: return SHA384_DIGEST_SIZE; break; #endif - + #ifdef WOLFSSL_SHA512 case SHA512: return SHA512_DIGEST_SIZE; break; #endif - - #ifdef HAVE_BLAKE2 + + #ifdef HAVE_BLAKE2 case BLAKE2B_ID: return BLAKE2B_OUTBYTES; break; #endif - + default: return BAD_FUNC_ARG; break; @@ -824,7 +824,7 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, localSalt = tmp; saltSz = hashSz; } - + do { ret = wc_HmacSetKey(&myHmac, type, localSalt, saltSz); if (ret != 0) @@ -876,4 +876,3 @@ int wc_HKDF(int type, const byte* inKey, word32 inKeySz, #endif /* HAVE_FIPS */ #endif /* NO_HMAC */ - diff --git a/wolfcrypt/src/srp.c b/wolfcrypt/src/srp.c index 66a4f00cd..19862ae66 100644 --- a/wolfcrypt/src/srp.c +++ b/wolfcrypt/src/srp.c @@ -19,8 +19,131 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + #ifdef WOLFCRYPT_HAVE_SRP #include +#include + +static int SrpHashInit(Srp* srp) +{ + switch (srp->type) { + #ifndef NO_SHA + case SRP_TYPE_SHA: + return wc_InitSha(&srp->hash.sha); + #endif + + #ifndef NO_SHA256 + case SRP_TYPE_SHA256: + return wc_InitSha256(&srp->hash.sha256); + #endif + + #ifdef WOLFSSL_SHA384 + case SRP_TYPE_SHA384: + return wc_InitSha384(&srp->hash.sha384); + #endif + + #ifdef WOLFSSL_SHA512 + case SRP_TYPE_SHA512: + return wc_InitSha512(&srp->hash.sha512); + #endif + + default: return BAD_FUNC_ARG; + } +} + +static int SrpHashUpdate(Srp* srp, byte* data, word32 size) +{ + switch (srp->type) { + #ifndef NO_SHA + case SRP_TYPE_SHA: + return wc_ShaUpdate(&srp->hash.sha, data, size); + #endif + + #ifndef NO_SHA256 + case SRP_TYPE_SHA256: + return wc_Sha256Update(&srp->hash.sha256, data, size); + #endif + + #ifdef WOLFSSL_SHA384 + case SRP_TYPE_SHA384: + return wc_Sha384Update(&srp->hash.sha384, data, size); + #endif + + #ifdef WOLFSSL_SHA512 + case SRP_TYPE_SHA512: + return wc_Sha512Update(&srp->hash.sha512, data, size); + #endif + + default: return BAD_FUNC_ARG; + } +} + +static int SrpHashFinal(Srp* srp, byte* digest) +{ + switch (srp->type) { + #ifndef NO_SHA + case SRP_TYPE_SHA: + return wc_ShaFinal(&srp->hash.sha, digest); + #endif + + #ifndef NO_SHA256 + case SRP_TYPE_SHA256: return + wc_Sha256Final(&srp->hash.sha256, digest); + #endif + + #ifdef WOLFSSL_SHA384 + case SRP_TYPE_SHA384: return + wc_Sha384Final(&srp->hash.sha384, digest); + #endif + + #ifdef WOLFSSL_SHA512 + case SRP_TYPE_SHA512: return + wc_Sha512Final(&srp->hash.sha512, digest); + #endif + + default: return BAD_FUNC_ARG; + } +} + +int wc_SrpInit(Srp* srp, byte type, byte side, byte* N, word32 nSz, + byte* g, word32 gSz) +{ + int ret = 0; + + if (!srp || !N || !g) + return BAD_FUNC_ARG; + + if (side != SRP_CLIENT_SIDE && side != SRP_SERVER_SIDE) + return BAD_FUNC_ARG; + + srp->side = side; + srp->type = type; /* a valid type is checked inside SrpHashXXX functions. */ + + if (mp_init_multi(&srp->N, &srp->g, &srp->s, 0, 0, 0) != MP_OKAY) + return MP_INIT_E; + + if (mp_read_unsigned_bin(&srp->N, N, nSz) != MP_OKAY) + ret = MP_READ_E; + + if (ret == 0 && mp_read_unsigned_bin(&srp->g, g, gSz) != MP_OKAY) + ret = MP_READ_E; + + if (ret == 0) ret = SrpHashInit(srp); + if (ret == 0) ret = SrpHashUpdate(srp, N, nSz); + if (ret == 0) ret = SrpHashUpdate(srp, g, gSz); + if (ret == 0) ret = SrpHashFinal(srp, srp->k); + + if (ret != 0) { + mp_clear(&srp->N); mp_clear(&srp->g); mp_clear(&srp->s); + } + + return ret; +} #endif /* WOLFCRYPT_HAVE_SRP */ diff --git a/wolfssl/wolfcrypt/srp.h b/wolfssl/wolfcrypt/srp.h index f6a3edc10..b4ac77895 100644 --- a/wolfssl/wolfcrypt/srp.h +++ b/wolfssl/wolfcrypt/srp.h @@ -19,6 +19,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#ifdef WOLFCRYPT_HAVE_SRP + #ifndef WOLFCRYPT_SRP_H #define WOLFCRYPT_SRP_H @@ -28,20 +30,24 @@ #include #include -#ifdef WOLFCRYPT_HAVE_SRP +#ifdef __cplusplus + extern "C" { +#endif enum { -#ifdef NO_SHA - SRP_SHA = 1, + SRP_CLIENT_SIDE = 0, + SRP_SERVER_SIDE = 1, +#ifndef NO_SHA + SRP_TYPE_SHA = 1, #endif -#ifdef NO_SHA256 - SRP_SHA256 = 2, +#ifndef NO_SHA256 + SRP_TYPE_SHA256 = 2, #endif -#ifndef WOLFSSL_SHA384 - SRP_SHA384 = 3, +#ifdef WOLFSSL_SHA384 + SRP_TYPE_SHA384 = 3, #endif -#ifndef WOLFSSL_SHA512 - SRP_SHA512 = 4, +#ifdef WOLFSSL_SHA512 + SRP_TYPE_SHA512 = 4, #endif /* Select the largest available hash for the buffer size. */ @@ -58,6 +64,21 @@ 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 +} SrpHash; + typedef struct { mp_int a; /**< Private ephemeral value. Random. */ mp_int A; /**< Public ephemeral value. pow(g, a, N) */ @@ -90,9 +111,15 @@ typedef struct { SrpClient client; SrpServer server; } specific; + SrpHash hash; /**< Hash object. */ } Srp; -int SrpInit(Srp* srp, byte* N, word32 nSz, byte* g, word32 gSz); +WOLFSSL_API int wc_SrpInit(Srp* srp, byte type, byte side, byte* N, word32 nSz, + byte* g, word32 gSz); +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* WOLFCRYPT_SRP_H */ #endif /* WOLFCRYPT_HAVE_SRP */ -#endif /* WOLF_CRYPT_SRP_H */