diff --git a/Makefile.am b/Makefile.am index e8941e6b5..043b9328d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,7 +59,7 @@ EXTRA_DIST+= gencertbuf.pl EXTRA_DIST+= README.md EXTRA_DIST+= LICENSING EXTRA_DIST+= INSTALL -EXTRA_DIST+= IPP/ +EXTRA_DIST+= IPP # user crypto plug in example EXTRA_DIST+= wolfcrypt/user-crypto/configure.ac diff --git a/configure.ac b/configure.ac index a4ccb5ce0..9dcb798db 100644 --- a/configure.ac +++ b/configure.ac @@ -2285,8 +2285,9 @@ AC_ARG_WITH([cavium], # Fast RSA using Intel IPP ippdir="${srcdir}/IPP" -ipplib="lib" # if autoconf guesses 32 changes lib directory -fastRSA_headers=no +ipplib="lib" # if autoconf guesses 32bit system changes lib directory +fastRSA_found=no +abs_path=`pwd` # set up variables used IPPLIBS= @@ -2301,11 +2302,12 @@ AC_ARG_ENABLE([fast-rsa], if test "$ENABLED_USER_RSA" = "no" && test "$ENABLED_FIPS" = "no"; then -if test "$enable_shared" = "no" && test "$ENABLED_FAST_RSA" = "yes"; then if test "$ac_cv_sizeof_long" = "4" && test "$ac_cv_sizeof_long_long" = "8"; then ipplib="lib_32" # 32 bit OS detected fi +# Use static IPP Libraries +if test "$enable_shared" = "no" && test "$ENABLED_FAST_RSA" = "yes"; then case $host_os in *darwin*) ipplib="$ipplib/mac_static" @@ -2322,92 +2324,100 @@ if test "$enable_shared" = "no" && test "$ENABLED_FAST_RSA" = "yes"; then AC_CHECK_FILES([$srcdir/IPP/$ipplib/libippcore.a $srcdir/IPP/$ipplib/libippcp.a], [], [ENABLED_FAST_RSA=no]) AC_CHECK_FILES([$srcdir/IPP/include/ipp.h $srcdir/IPP/include/ippcp.h], [AM_CPPFLAGS="-I$srcdir/IPP/include $AM_CPPFLAGS"], [ENABLED_FAST_RSA=no]) - LIB_STATIC_ADD="$srcdir/IPP/$ipplib/libippcp.a $srcdir/IPP/$ipplib/libippcore.a" + LIB_STATIC_ADD="$srcdir/IPP/$ipplib/libippcp.a $srcdir/IPP/$ipplib/libippcore.a $LIB_STATIC_ADD" if test "$ENABLED_FAST_RSA" = "no"; then AC_MSG_ERROR([Could not find fast rsa libraries]) fi else -# just check link and see if user has already exported paths -if test "$ENABLED_FAST_RSA" = "yes" - then - AC_MSG_NOTICE([Checking if IPP crypto library installed]) - AC_CHECK_HEADER([ippcp.h], [AC_CHECK_LIB([ippcp], [ippsRSAEncrypt_PKCSv15], [LIBS="$LIBS -lippcore"; fastRSA_headers=yes], [AS_UNSET([ac_cv_lib_ippcp_ippsRSAEncrypt_PKCSv15]); fastRSA_headers=no])], [fastRSA_headers=no]) - if test "$fastRSA_headers" = "yes"; then - AM_LDFLAGS="${AM_LDFLAGS} -lippcore -lippcp" - fi -fi -# Don't cache the result so it can be checked again -AS_UNSET([ac_cv_header_ippcp_h]) -AS_UNSET([ac_cv_header_ipp_h]) - -if test "$fastRSA_headers" = "no"; then -dnl set default paths +# Check for and use bundled IPP libraries if test "$ENABLED_FAST_RSA" = "yes"; then AC_MSG_NOTICE([Using local IPP crypto library]) - # build and default locations on linux and mac - STORE_LDFLAGS=${LDFLAGS} - STORE_CPPFLAGS=${CPPFLAGS} - if test "$ac_cv_sizeof_long" = "4" && test "$ac_cv_sizeof_long_long" = "8"; then - ipplib="lib_32" # 32 bit OS detected - fi - # using LDFLAGS instead of AM_ temporarily to test link to library - LDFLAGS="-L$ippdir/$ipplib -lippcp -lippcore" - CPPFLAGS="-I$ippdir/include" - AC_CHECK_HEADERS([ippcp.h], [AC_CHECK_LIB([ippcp], [ippsRSAEncrypt_PKCSv15], [], [ENABLED_FAST_RSA=no])], [ENABLED_FAST_RSA=no]) - if test "$ENABLED_FAST_RSA" = "yes"; then - # was succesfull so add tested LDFLAGS to AM_ flags - AM_LDFLAGS="${AM_LDFLAGS} ${LDFLAGS}" - AM_CPPFLAGS="${AM_CPPFLAGS} ${CPPFLAGS}" + AC_CHECK_FILES([$abs_path/IPP/include/ippcp.h], + [ + # build and default locations on linux and mac + STORE_LDFLAGS=${LDFLAGS} + STORE_CPPFLAGS=${CPPFLAGS} - case $host_os in - *darwin*) + # using LDFLAGS instead of AM_ temporarily to test link to library + LDFLAGS="-L$ippdir/$ipplib -lippcp -lippcore" + CPPFLAGS="-I$ippdir/include" + AC_CHECK_HEADERS([ippcp.h], [AC_CHECK_LIB([ippcp], [ippsRSAEncrypt_PKCSv15], [fastRSA_found=yes], [fastRSA_found=no])], [fastRSA_found=no]) name="$ippdir/$ipplib/libippcp" - IPPLIBS="${name}.dylib ${name}-9.0.dylib ${name}e9-9.0.dylib ${name}g9-9.0.dylib ${name}h9-9.0.dylib ${name}k0-9.0.dylib ${name}l9-9.0.dylib ${name}n8-9.0.dylib ${name}p8-9.0.dylib ${name}s8-9.0.dylib ${name}y8-9.0.dylib IPP/lib/libippcore.dylib IPP/lib/libippcore-9.0.dylib" - IPPLINK="mkdir -p src/.libs && ln -f ${name}.dylib src/.libs/libippcp.dylib && ln -f ${srcdir}/${name}-9.0.dylib src/.libs/libippcp-9.0.dylib && ln -f ${srcdir}/${name}e9-9.0.dylib src/.libs/libippcpe9-9.0.dylib && ln -f ${srcdir}/${name}g9-9.0.dylib src/.libs/libippcpg9-9.0.dylib && ln -f ${srcdir}/${name}h9-9.0.dylib src/.libs/libippcph9-9.0.dylib && ln -f ${srcdir}/${name}k0-9.0.dylib src/.libs/libippcpk0-9.0.dylib && ln -f ${srcdir}/${name}l9-9.0.dylib src/.libs/libippcpl9-9.0.dylib && ln -f ${srcdir}/${name}n8-9.0.dylib src/.libs/libippcpn8-9.0.dylib && ln -f ${srcdir}/${name}p8-9.0.dylib src/.libs/libippcpp8-9.0.dylib && ln -f ${srcdir}/${name}s8-9.0.dylib src/.libs/libippcps8-9.0.dylib && ln -f ${srcdir}/${name}y8-9.0.dylib src/.libs/libippcpy8-9.0.dylib && ln -f ${srcdir}/IPP/lib/libippcore.dylib src/.libs/libippcore.dylib && ln -f ${srcdir}/IPP/lib/libippcore-9.0.dylib src/.libs/libippcore-9.0.dylib" - break;; + case $host_os in + *darwin*) + # check file existence and conditionally set variables + AC_CHECK_FILES([$abs_path/IPP/$ipplib/libippcp.dylib], [ + IPPLIBS="${name}.dylib ${name}-9.0.dylib ${name}e9-9.0.dylib ${name}g9-9.0.dylib ${name}h9-9.0.dylib ${name}k0-9.0.dylib ${name}l9-9.0.dylib ${name}n8-9.0.dylib ${name}p8-9.0.dylib ${name}s8-9.0.dylib ${name}y8-9.0.dylib IPP/lib/libippcore.dylib IPP/lib/libippcore-9.0.dylib" + IPPLINK="mkdir -p src/.libs && ln -f ${name}.dylib src/.libs/libippcp.dylib && ln -f ${srcdir}/${name}-9.0.dylib src/.libs/libippcp-9.0.dylib && ln -f ${srcdir}/${name}e9-9.0.dylib src/.libs/libippcpe9-9.0.dylib && ln -f ${srcdir}/${name}g9-9.0.dylib src/.libs/libippcpg9-9.0.dylib && ln -f ${srcdir}/${name}h9-9.0.dylib src/.libs/libippcph9-9.0.dylib && ln -f ${srcdir}/${name}k0-9.0.dylib src/.libs/libippcpk0-9.0.dylib && ln -f ${srcdir}/${name}l9-9.0.dylib src/.libs/libippcpl9-9.0.dylib && ln -f ${srcdir}/${name}n8-9.0.dylib src/.libs/libippcpn8-9.0.dylib && ln -f ${srcdir}/${name}p8-9.0.dylib src/.libs/libippcpp8-9.0.dylib && ln -f ${srcdir}/${name}s8-9.0.dylib src/.libs/libippcps8-9.0.dylib && ln -f ${srcdir}/${name}y8-9.0.dylib src/.libs/libippcpy8-9.0.dylib && ln -f ${srcdir}/IPP/lib/libippcore.dylib src/.libs/libippcore.dylib && ln -f ${srcdir}/IPP/lib/libippcore-9.0.dylib src/.libs/libippcore-9.0.dylib" + ], [fastRSA_found=no]) + break;; - *linux*) - if test "$ac_cv_sizeof_long" = "4" && test "$ac_cv_sizeof_long_long" = "8"; then - name="$ippdir/$ipplib/libippcp" - IPPLIBS="${name}.so.9.0 ${name}g9.so.9.0 ${name}h9.so.9.0 ${name}p8.so.9.0 ${name}px.so.9.0 ${name}s8.so.9.0 ${name}.so ${name}w7.so.9.0 IPP/$ipplib/libippcore.so" - IPPLINK="mkdir -p src/.libs && ln -f ${name}.so.9.0 src/.libs/libippcp.so.9.0 && ln -f ${name}g9.so.9.0 src/.libs/libippcpg9.so.9.0 && ln -f ${name}h9.so.9.0 src/.libs/libippcph9.so.9.0 && ln -f ${name}p8.so.9.0 src/.libs/libippcpp8.so.9.0 && ln -f ${name}px.so.9.0 src/.libs/libippcppx.so.9.0 && ln -f ${name}s8.so.9.0 src/.libs/libippcps8.so.9.0 && ln -f ${name}.so src/.libs/libippcp.so && ln -f ${name}w7.so.9.0 src/.libs/libippcpw7.so.9.0 && ln -f IPP/$ipplib/libippcore.so src/.libs/libippcore.so && ln -f IPP/$ipplib/libippcore.so.9.0 src/.libs/libippcore.so.9.0" - else - name="$ippdir/$ipplib/libippcp" - IPPLIBS="${name}.so.9.0 ${name}e9.so.9.0 ${name}k0.so.9.0 ${name}l9.so.9.0 ${name}m7.so.9.0 ${name}mx.so.9.0 ${name}.so ${name}n8.so.9.0 ${name}y8.so.9.0 IPP/lib/libippcore.so" - IPPLINK="mkdir -p src/.libs && ln -f ${name}.so.9.0 src/.libs/libippcp.so.9.0 && ln -f ${name}e9.so.9.0 src/.libs/libippcpe9.so.9.0 && ln -f ${name}k0.so.9.0 src/.libs/libippcpk0.so.9.0 && ln -f ${name}l9.so.9.0 src/.libs/libippcpl9.so.9.0 && ln -f ${name}m7.so.9.0 src/.libs/libippcpm7.so.9.0 && ln -f ${name}mx.so.9.0 src/.libs/libippcpmx.so.9.0 && ln -f ${name}.so src/.libs/libippcp.so && ln -f ${name}n8.so.9.0 src/.libs/libippcpn8.so.9.0 && ln -f ${name}y8.so.9.0 src/.libs/libippcpy8.so.9.0 && ln -f IPP/lib/libippcore.so src/.libs/libippcore.so && ln -f IPP/lib/libippcore.so.9.0 src/.libs/libippcore.so.9.0" + *linux*) + # check file existence and conditionally set variables + AC_CHECK_FILES([$abs_path/IPP/$ipplib/libippcp.so.9.0], [ + if test "$ac_cv_sizeof_long" = "4" && test "$ac_cv_sizeof_long_long" = "8"; then + IPPLIBS="${name}.so.9.0 ${name}g9.so.9.0 ${name}h9.so.9.0 ${name}p8.so.9.0 ${name}px.so.9.0 ${name}s8.so.9.0 ${name}.so ${name}w7.so.9.0 IPP/$ipplib/libippcore.so IPP/$ipplib/libippcore.so.9.0" + IPPLINK="mkdir -p src/.libs && ln -f ${name}.so.9.0 src/.libs/libippcp.so.9.0 && ln -f ${name}g9.so.9.0 src/.libs/libippcpg9.so.9.0 && ln -f ${name}h9.so.9.0 src/.libs/libippcph9.so.9.0 && ln -f ${name}p8.so.9.0 src/.libs/libippcpp8.so.9.0 && ln -f ${name}px.so.9.0 src/.libs/libippcppx.so.9.0 && ln -f ${name}s8.so.9.0 src/.libs/libippcps8.so.9.0 && ln -f ${name}.so src/.libs/libippcp.so && ln -f ${name}w7.so.9.0 src/.libs/libippcpw7.so.9.0 && ln -f IPP/$ipplib/libippcore.so src/.libs/libippcore.so && ln -f IPP/$ipplib/libippcore.so.9.0 src/.libs/libippcore.so.9.0" + else + IPPLIBS="${name}.so.9.0 ${name}e9.so.9.0 ${name}k0.so.9.0 ${name}l9.so.9.0 ${name}m7.so.9.0 ${name}mx.so.9.0 ${name}.so ${name}n8.so.9.0 ${name}y8.so.9.0 IPP/lib/libippcore.so IPP/lib/libippcore.so.9.0" + IPPLINK="mkdir -p src/.libs && ln -f ${name}.so.9.0 src/.libs/libippcp.so.9.0 && ln -f ${name}e9.so.9.0 src/.libs/libippcpe9.so.9.0 && ln -f ${name}k0.so.9.0 src/.libs/libippcpk0.so.9.0 && ln -f ${name}l9.so.9.0 src/.libs/libippcpl9.so.9.0 && ln -f ${name}m7.so.9.0 src/.libs/libippcpm7.so.9.0 && ln -f ${name}mx.so.9.0 src/.libs/libippcpmx.so.9.0 && ln -f ${name}.so src/.libs/libippcp.so && ln -f ${name}n8.so.9.0 src/.libs/libippcpn8.so.9.0 && ln -f ${name}y8.so.9.0 src/.libs/libippcpy8.so.9.0 && ln -f IPP/lib/libippcore.so src/.libs/libippcore.so && ln -f IPP/lib/libippcore.so.9.0 src/.libs/libippcore.so.9.0" + fi + ], [fastRSA_found=no]) + break;; + *) + fastRSA_found=no + esac + + if test "$fastRSA_found" = "yes"; then + # was succesfull so add tested LDFLAGS to AM_ flags + AM_LDFLAGS="${AM_LDFLAGS} ${LDFLAGS}" + AM_CPPFLAGS="${AM_CPPFLAGS} ${CPPFLAGS}" + IPPHEADERS="${srcdir}/IPP/include/*.h" fi - break;; - *) - ENABLED_FAST_RSA=no - esac - fi - # restore LDFLAGS to user set - LDFLAGS=${STORE_LDFLAGS} - CPPFLAGS=${STORE_CPPFLAGS} - IPPHEADERS="${srcdir}/IPP/include/*.h" + + # restore LDFLAGS to user set + LDFLAGS=${STORE_LDFLAGS} + CPPFLAGS=${STORE_CPPFLAGS} + ], [fastRSA_found=no]) +fi + +# Don't cache the result so it can be checked +AS_UNSET([ac_cv_header_ippcp_h]) +AS_UNSET([ac_cv_header_ipp_h]) +AS_UNSET([ac_cv_lib_ippcp_ippsRSAEncrypt_PKCSv15]); + +# Check link and see if user has pre-existing IPP Libraries if not using local +if test "$ENABLED_FAST_RSA" = "yes" && test "$fastRSA_found" = "no"; then + AC_MSG_NOTICE([Checking if IPP crypto library installed]) + AC_CHECK_HEADER([ippcp.h], [AC_CHECK_LIB([ippcp], [ippsRSAEncrypt_PKCSv15], + [ + fastRSA_found=yes + AM_LDFLAGS="${AM_LDFLAGS} -lippcore -lippcp" + ], [ fastRSA_found=no]) + ], [fastRSA_found=no]) # Error out on not finding libraries - if test "$ENABLED_FAST_RSA" = "no"; then + if test "$fastRSA_found" = "no"; then AC_MSG_ERROR([Could not find fast rsa libraries]) fi fi -fi # end of if found exported paths fi # end of if for shared library else # if user rsa is set than do not use fast rsa option if test "$ENABLED_FAST_RSA" = "yes"; then AC_MSG_ERROR([Could not use fast rsa libraries with user crypto or fips]) fi -fi # end of if for user rsa crypto +fi # end of if for user rsa crypto or fips +# End result of checking for IPP Libraries AC_MSG_CHECKING([for fast RSA]) if test "$ENABLED_FAST_RSA" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DHAVE_FAST_RSA -DHAVE_USER_RSA" # add in user crypto header that uses Intel IPP AM_CPPFLAGS="$AM_CPPFLAGS -I$srcdir/wolfcrypt/user-crypto/include" if test "$enable_shared" = "yes"; then - LIBS="$LIBS -lippcore" + LIBS="$LIBS -lippcore -lippcp" LIB_ADD="-lippcp -lippcore $LIB_ADD" else LIB_ADD="$srcdir/IPP/$ipplib/libippcp.a $srcdir/IPP/$ipplib/libippcore.a $LIB_ADD" @@ -2420,7 +2430,6 @@ fi AC_SUBST([IPPLIBS]) AC_SUBST([IPPHEADERS]) AC_SUBST([IPPLINK]) -# Found IPP library now build in user crypto to use it AM_CONDITIONAL([BUILD_FAST_RSA], [test "x$ENABLED_FAST_RSA" = "xyes"]) diff --git a/wolfcrypt/user-crypto/src/rsa.c b/wolfcrypt/user-crypto/src/rsa.c index faa672cbb..a61d61781 100644 --- a/wolfcrypt/user-crypto/src/rsa.c +++ b/wolfcrypt/user-crypto/src/rsa.c @@ -19,10 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -/* - Created to use intel's IPP see their license for linking to intel's IPP library - */ - #ifdef HAVE_CONFIG_H /* configure options when using autoconf */ #include #endif @@ -164,7 +160,7 @@ static int SetIndividualExternal(WOLFSSL_BIGNUM** bn, IppsBigNumState* in) if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; - data = XMALLOC(sz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + data = (byte*)XMALLOC(sz, NULL, DYNAMIC_TYPE_USER_CRYPTO); if (data == NULL) return USER_CRYPTO_ERROR; @@ -204,13 +200,15 @@ static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, IppsBigNumState** mpi) if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; - *mpi = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + *mpi = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); if (*mpi == NULL) return USER_CRYPTO_ERROR; ret = ippsBigNumInit(length, *mpi); - if (ret != ippStsNoErr) + if (ret != ippStsNoErr) { + XFREE(*mpi, NULL, DYNAMIC_TYPE_USER_CRYPTO); return USER_CRYPTO_ERROR; + } } @@ -223,7 +221,7 @@ static int SetIndividualInternal(WOLFSSL_BIGNUM* bn, IppsBigNumState** mpi) return USER_CRYPTO_ERROR; } - data = XMALLOC(length, NULL, DYNAMIC_TYPE_USER_CRYPTO); + data = (Ipp8u*)XMALLOC(length, NULL, DYNAMIC_TYPE_USER_CRYPTO); if (data == NULL) return USER_CRYPTO_ERROR; @@ -403,7 +401,8 @@ int SetRsaInternal(WOLFSSL_RSA* rsa) return USER_CRYPTO_ERROR; } - key->pPub = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPub == NULL) return USER_CRYPTO_ERROR; @@ -456,7 +455,8 @@ int SetRsaInternal(WOLFSSL_RSA* rsa) } key->prvSz = ctxSz; - key->pPrv = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPrv == NULL) return USER_CRYPTO_ERROR; @@ -566,6 +566,103 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, } +/* Set up memory and structure for a Big Number + * returns ippStsNoErr on success + */ +static IppStatus init_bn(IppsBigNumState** in, int sz) +{ + int ctxSz; + IppStatus ret; + + ret = ippsBigNumGetSize(sz, &ctxSz); + if (ret != ippStsNoErr) { + return ret; + } + + *in = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + if (*in == NULL) { + return ippStsNoMemErr; + } + + ret = ippsBigNumInit(sz, *in); + if (ret != ippStsNoErr) { + XFREE(*in, NULL, DYNAMIC_TYPE_USER_CRYPTO); + *in = NULL; + return ret; + } + + return ippStsNoErr; +} + + +/* Set up memory and structure for a Montgomery struct + * returns ippStsNoErr on success + */ +static IppStatus init_mont(IppsMontState** mont, int* ctxSz, + IppsBigNumState* modul) +{ + int mSz; + Ipp32u* m; + IppStatus ret; + + ret = ippsExtGet_BN(NULL, ctxSz, NULL, modul); + if (ret != ippStsNoErr) { + return ret; + } + + /* convert bits to Ipp32u array size and round up + 32 is number of bits in type */ + mSz = (*ctxSz/32)+((*ctxSz % 32)? 1: 0); + m = (Ipp32u*)XMALLOC(mSz * sizeof(Ipp32u), 0, DYNAMIC_TYPE_USER_CRYPTO); + if (m == NULL) { + XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); + return ippStsNoMemErr; + } + + ret = ippsExtGet_BN(NULL, NULL, m, modul); + if (ret != ippStsNoErr) { + XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); + return ret; + } + + ret = ippsMontGetSize(IppsSlidingWindows, mSz, ctxSz); + if (ret != ippStsNoErr) { + XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); + return ret; + } + + /* 2. Allocate working buffer using malloc */ + *mont = (IppsMontState*)XMALLOC(*ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + if (mont == NULL) { + XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); + return ippStsNoMemErr; + } + ret = ippsMontInit(IppsSlidingWindows, mSz, *mont); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsMontInit error of %s\n", ippGetStatusString(ret))); + XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(*mont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + *mont = NULL; + return ret; + } + + /* 3. Call the function MontSet to set big number module */ + ret = ippsMontSet(m, mSz, *mont); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsMontSet error of %s\n", ippGetStatusString(ret))); + XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(*mont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + *mont = NULL; + return ret; + } + + XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); + + return ippStsNoErr; +} + + + int wc_FreeRsaKey(RsaKey* key) { if (key == NULL) @@ -701,7 +798,7 @@ static int GetInt(IppsBigNumState** mpi, const byte* input, word32* inOutIdx, if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; - *mpi = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + *mpi = (IppsBigNumState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); if (*mpi == NULL) return USER_CRYPTO_ERROR; @@ -808,7 +905,8 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, return USER_CRYPTO_ERROR; } - key->pPub = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPub == NULL) return USER_CRYPTO_ERROR; @@ -860,7 +958,8 @@ int wc_RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, } key->prvSz = ctxSz; - key->pPrv = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPrv == NULL) return USER_CRYPTO_ERROR; @@ -978,7 +1077,8 @@ int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, return USER_CRYPTO_ERROR; } - key->pPub = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPub == NULL) return USER_CRYPTO_ERROR; @@ -1015,15 +1115,7 @@ int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, return USER_CRYPTO_ERROR; /* set up IPP key states -- read in n */ - ret = ippsBigNumGetSize(nSz, &ctxSz); - if (ret != ippStsNoErr) - return USER_CRYPTO_ERROR; - - key->n = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->n == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(nSz, key->n); + ret = init_bn(&key->n, nSz); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; @@ -1032,15 +1124,7 @@ int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, return USER_CRYPTO_ERROR; /* read in e */ - ret = ippsBigNumGetSize(eSz, &ctxSz); - if (ret != ippStsNoErr) - return USER_CRYPTO_ERROR; - - key->e = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->e == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(eSz, key->e); + ret = init_bn(&key->e, eSz); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; @@ -1061,7 +1145,8 @@ int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, return USER_CRYPTO_ERROR; } - key->pPub = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPub == NULL) return USER_CRYPTO_ERROR; @@ -1106,8 +1191,8 @@ int wc_RsaPublicEncrypt(const byte* in, word32 inLen, byte* out, word32 outLen, if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; - scratchBuffer = XMALLOC(scratchSz*(sizeof(Ipp8u)), 0, - DYNAMIC_TYPE_USER_CRYPTO); + scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0, + DYNAMIC_TYPE_USER_CRYPTO); if (scratchBuffer == NULL) return USER_CRYPTO_ERROR; @@ -1149,8 +1234,8 @@ int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen, return USER_CRYPTO_ERROR; } - scratchBuffer = XMALLOC(scratchSz*(sizeof(Ipp8u)), 0, - DYNAMIC_TYPE_USER_CRYPTO); + scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0, + DYNAMIC_TYPE_USER_CRYPTO); if (scratchBuffer == NULL) { return USER_CRYPTO_ERROR; } @@ -1180,7 +1265,7 @@ int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) USER_DEBUG(("Entering wc_RsaPrivateDecryptInline\n")); /* allocate a buffer for max decrypted text */ - tmp = XMALLOC(key->sz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + tmp = (byte*)XMALLOC(key->sz, NULL, DYNAMIC_TYPE_USER_CRYPTO); if (tmp == NULL) return USER_CRYPTO_ERROR; @@ -1252,7 +1337,7 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) return USER_CRYPTO_ERROR; } - pPub = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + pPub = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); if (pPub == NULL) return USER_CRYPTO_ERROR; @@ -1264,7 +1349,6 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) return USER_CRYPTO_ERROR; } - ret = ippsRSA_SetPrivateKeyType1(key->n, key->e, pPub); if (ret != ippStsNoErr) { FreeHelper(pTxt, cTxt, scratchBuffer, pPub); @@ -1280,32 +1364,19 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) return USER_CRYPTO_ERROR; } - scratchBuffer = XMALLOC(scratchSz*(sizeof(Ipp8u)), 0, - DYNAMIC_TYPE_USER_CRYPTO); + scratchBuffer = (Ipp8u*)XMALLOC(scratchSz*(sizeof(Ipp8u)), 0, + DYNAMIC_TYPE_USER_CRYPTO); if (scratchBuffer == NULL) { FreeHelper(pTxt, cTxt, scratchBuffer, pPub); return USER_CRYPTO_ERROR; } /* load plain and cipher into big num states */ - ret = ippsBigNumGetSize(key->sz, &ctxSz); + ret = init_bn(&pTxt, key->sz); if (ret != ippStsNoErr) { FreeHelper(pTxt, cTxt, scratchBuffer, pPub); return USER_CRYPTO_ERROR; } - - pTxt = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (pTxt == NULL) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPub); - return USER_CRYPTO_ERROR; - } - - ret = ippsBigNumInit(key->sz, pTxt); - if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPub); - return USER_CRYPTO_ERROR; - } - ret = ippsSetOctString_BN((Ipp8u*)in, key->sz, pTxt); if (ret != ippStsNoErr) { FreeHelper(pTxt, cTxt, scratchBuffer, pPub); @@ -1313,24 +1384,11 @@ int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) } /* set up cipher to hold signature */ - ret = ippsBigNumGetSize(key->sz, &ctxSz); + ret = init_bn(&cTxt, key->sz); if (ret != ippStsNoErr) { FreeHelper(pTxt, cTxt, scratchBuffer, pPub); return USER_CRYPTO_ERROR; } - - cTxt = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (cTxt == NULL) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPub); - return USER_CRYPTO_ERROR; - } - - ret = ippsBigNumInit(key->sz, cTxt); - if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPub); - return USER_CRYPTO_ERROR; - } - ret = ippsSetOctString_BN((Ipp8u*)in, key->sz, cTxt); if (ret != ippStsNoErr) { FreeHelper(pTxt, cTxt, scratchBuffer, pPub); @@ -1397,147 +1455,394 @@ int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, } +/* Check if a > b , if so c = a mod b + return ippStsNoErr on success */ +static IppStatus reduce(IppsBigNumState* a, IppsBigNumState* b, + IppsBigNumState* c) +{ + IppStatus ret; + + if ((ret = ippsMod_BN(a, b, c)) != ippStsNoErr) + return ret; + + return ippStsNoErr; +} + + +static IppStatus exptmod(IppsBigNumState* a, IppsBigNumState* b, + IppsMontState* mont, IppsBigNumState* out, IppsBigNumState* one) +{ + IppStatus ret; + + ret = ippsMontForm(a, mont, a); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsMontForm error of %s\n", ippGetStatusString(ret))); + return ret; + } + + /* a = a^b mod mont */ + ret = ippsMontExp(a, b, mont, out); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsMontExp error of %s\n", ippGetStatusString(ret))); + return ret; + } + + /* convert back from montgomery */ + ret = ippsMontMul(out, one, mont, out); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsMontMul error of %s\n", ippGetStatusString(ret))); + return ret; + } + + return ippStsNoErr; +} + + +static void Free_BN(IppsBigNumState* bn) +{ + int sz, ctxSz; + IppStatus ret; + + if (bn != NULL) { + ret = ippStsNoErr; + ret |= ippsGetSize_BN(bn, &sz); + ret |= ippsBigNumGetSize(sz, &ctxSz); + if (ret == ippStsNoErr) { + ForceZero(bn, ctxSz); + } + else { + USER_DEBUG(("Issue with clearing a struct in RsaSSL_Sign free\n")); + } + XFREE(bn, NULL, DYNAMIC_TYPE_USER_CRYPTO); + bn = NULL; + } +} + + +/* free up memory used during CRT sign operation */ +static void FreeSignHelper(IppsBigNumState* one, IppsBigNumState* tmp, + IppsBigNumState* tmpP, IppsBigNumState* tmpQ, IppsBigNumState* tmpa, + IppsBigNumState* tmpb) +{ + Free_BN(one); + Free_BN(tmp); + Free_BN(tmpP); + Free_BN(tmpQ); + Free_BN(tmpa); + Free_BN(tmpb); +} + + /* for Rsa Sign */ int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, WC_RNG* rng) { - int sz; - int scratchSz; - int ctxSz; - int prvSz; + int sz, pSz, qSz; IppStatus ret; - Ipp8u* scratchBuffer = NULL; - IppsRSAPublicKeyState* pPrv = NULL; - IppsBigNumState* pTxt = NULL; - IppsBigNumState* cTxt = NULL; + word32 outSz = outLen; + + IppsMontState* pMont = NULL; + IppsMontState* qMont = NULL; + + IppsBigNumState* one = NULL; + IppsBigNumState* tmp = NULL; + IppsBigNumState* tmpP = NULL; + IppsBigNumState* tmpQ = NULL; + IppsBigNumState* tmpa = NULL; + IppsBigNumState* tmpb = NULL; + + IppsBigNumSGN sa, sb; + + Ipp8u o[1]; + o[0] = 1; + + USER_DEBUG(("Entering wc_RsaSSL_Sign\n")); sz = key->sz; - /* set up public key state using private key values */ - ret = ippsRSA_GetSizePublicKey(key->nSz, key->dSz, &ctxSz); - if (ret != ippStsNoErr) { - USER_DEBUG(("ippsRSA_GetSizePrivateKey error %s\n", - ippGetStatusString(ret))); + if (in == NULL || out == NULL || key == NULL || rng == NULL) { + USER_DEBUG(("Bad argument to wc_RsaSSL_Sign\n")); return USER_CRYPTO_ERROR; } - prvSz = ctxSz; /* used later to overright sensitive memory */ - pPrv = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (pPrv == NULL) { - USER_DEBUG(("memeory error assinging pPrv\n")); + /* sanity check on key being used */ + if (key->pipp == NULL || key->qipp == NULL || key->uipp == NULL || + key->dPipp == NULL || key->dQipp == NULL) { + USER_DEBUG(("Bad key argument to wc_RsaSSL_Sign\n")); return USER_CRYPTO_ERROR; } - ret = ippsRSA_InitPublicKey(key->nSz, key->dSz, pPrv, ctxSz); - if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - USER_DEBUG(("ippsRSA_InitPrivateKey error %s\n", - ippGetStatusString(ret))); + if (sz > (int)outLen) { + USER_DEBUG(("Bad argument outLen to wc_RsaSSL_Sign\n")); return USER_CRYPTO_ERROR; } - ret = ippsRSA_SetPublicKey(key->n, key->dipp, pPrv); - if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - USER_DEBUG(("ippsRSA_SetPrivateKey error %s\n", - ippGetStatusString(ret))); - return USER_CRYPTO_ERROR; - } - - /* set size of scratch buffer */ - ret = ippsRSA_GetBufferSizePublicKey(&scratchSz, pPrv); - if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - USER_DEBUG(("ippsRSA_GetBufferSizePublicKey error %s\n", - ippGetStatusString(ret))); - return USER_CRYPTO_ERROR; - } - - scratchBuffer = XMALLOC(scratchSz*(sizeof(Ipp8u)), 0, - DYNAMIC_TYPE_USER_CRYPTO); - if (scratchBuffer == NULL) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - USER_DEBUG(("memory error assigning scratch buffer\n")); + if (inLen > (word32)(sz - RSA_MIN_PAD_SZ)) { + USER_DEBUG(("Bad argument inLen to wc_RsaSSL_Sign\n")); return USER_CRYPTO_ERROR; } /* Set up needed pkcs v15 padding */ if (wc_RsaPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1, rng) != 0) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + USER_DEBUG(("RSA Padding error\n")); return USER_CRYPTO_ERROR; } - /* load plain and cipher into big num states */ - ret = ippsBigNumGetSize(sz, &ctxSz); + /* tmp = intput to sign */ + ret = init_bn(&tmp, sz); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - - pTxt = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (pTxt == NULL) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - return USER_CRYPTO_ERROR; - } - - ret = ippsBigNumInit(sz, pTxt); + ret = ippsSetOctString_BN(out, sz, tmp); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + USER_DEBUG(("ippsSetOctString_BN error of %s\n", + ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - ret = ippsSetOctString_BN((Ipp8u*)out, sz, pTxt); + /* tmpP = tmp mod p */ + ret = init_bn(&tmpP, sz); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - /* set up cipher to hold signature */ - ret = ippsBigNumGetSize(outLen, &ctxSz); + /* tmpQ = tmp mod q */ + ret = init_bn(&tmpQ, sz); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - cTxt = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (cTxt == NULL) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - return USER_CRYPTO_ERROR; - } - - ret = ippsBigNumInit(outLen, cTxt); + /* tmpa */ + ret = init_bn(&tmpa, sz); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - ret = ippsSetOctString_BN((Ipp8u*)out, outLen, cTxt); + /* tmpb */ + ret = init_bn(&tmpb, sz); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - /* encrypt using private key */ - ret = ippsRSA_Encrypt(pTxt, cTxt, pPrv, scratchBuffer); + /* one : used for conversion from Montgomery to classical */ + ret = init_bn(&one, sz); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - USER_DEBUG(("sign error of %s\n", ippGetStatusString(ret))); + USER_DEBUG(("init_BN error of %s\n", ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - - /* get output string from big number structure */ - ret = ippsGetOctString_BN((Ipp8u*)out, sz, cTxt); + ret = ippsSetOctString_BN(o, 1, one); if (ret != ippStsNoErr) { - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); - USER_DEBUG(("BN get string error of %s\n", ippGetStatusString(ret))); + USER_DEBUG(("ippsSetOctString_BN error of %s\n", + ippGetStatusString(ret))); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); return USER_CRYPTO_ERROR; } - /* clean up memory used */ - ForceZero(pPrv, prvSz); /* clear senstive memory */ - FreeHelper(pTxt, cTxt, scratchBuffer, pPrv); + /** + Set up Montgomery state + */ + ret = init_mont(&pMont, &pSz, key->pipp); + if (ret != ippStsNoErr) { + USER_DEBUG(("init_mont error of %s\n", ippGetStatusString(ret))); + if (pMont != NULL) { + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + } + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } - return sz; + ret = init_mont(&qMont, &qSz, key->qipp); + if (ret != ippStsNoErr) { + USER_DEBUG(("init_mont error of %s\n", ippGetStatusString(ret))); + if (qMont != NULL) { + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + } + ForceZero(pMont, pSz); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + /** + Check and reduce input + This is needed for calls to MontExp since required value of a < modulus + */ + ret = reduce(tmp, key->pipp, tmpP); + if (ret != ippStsNoErr) + { + USER_DEBUG(("reduce error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + ret = reduce(tmp, key->qipp, tmpQ); + if (ret != ippStsNoErr) + { + USER_DEBUG(("reduce error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + /* tmpa = (tmp mod p)^dP mod p */ + ret = exptmod(tmpP, key->dPipp, pMont, tmpa, one); + if (ret != ippStsNoErr) { + USER_DEBUG(("exptmod error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + /* tmpb = (tmp mod q)^dQ mod q */ + ret = exptmod(tmpQ, key->dQipp, qMont, tmpb, one); + if (ret != ippStsNoErr) { + USER_DEBUG(("exptmod error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + /* tmp = (tmpa - tmpb) * qInv (mod p) */ + ret = ippsSub_BN(tmpa, tmpb, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + ret = ippsMul_BN(tmp, key->uipp, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsMul_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + /* mod performed the same was as wolfSSL fp_mod -- tmpa is just scratch */ + ret = ippsDiv_BN(tmp, key->pipp, tmpa, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsDiv_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + /* Check sign of values and perform conditional add */ + ret = ippsExtGet_BN(&sa, NULL, NULL, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsExtGet_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + ret = ippsExtGet_BN(&sb, NULL, NULL, key->pipp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsExtGet_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + if (sa != sb) { + ret = ippsAdd_BN(tmp, key->pipp, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsAdd_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + } + + /* tmp = tmpb + q * tmp */ + ret = ippsMul_BN(tmp, key->qipp, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + + ret = ippsAdd_BN(tmp, tmpb, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsSub_BN error of %s\n", ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + /* Extract the output */ + ret = ippsGetOctString_BN(out, sz, tmp); + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsGetOctString_BN error of %s\n", + ippGetStatusString(ret))); + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + return USER_CRYPTO_ERROR; + } + + outSz = sz; + + /* clear memory and free */ + ForceZero(pMont, pSz); + ForceZero(qMont, qSz); + XFREE(qMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + XFREE(pMont, NULL, DYNAMIC_TYPE_USER_CRYPTO); + FreeSignHelper(one, tmp, tmpP, tmpQ, tmpa, tmpb); + + return outSz; } @@ -1599,6 +1904,27 @@ int wc_RsaFlattenPublicKey(RsaKey* key, byte* e, word32* eSz, byte* n, return 0; } + +IppStatus wolfSSL_rng(Ipp32u* pData, int nBits, void* pEbsParams); +IppStatus wolfSSL_rng(Ipp32u* pData, int nBits, void* pEbsParams) +{ + int nBytes; + + if (pData == NULL) { + USER_DEBUG(("error with wolfSSL_rng argument\n")); + return ippStsErr; + } + + nBytes = (nBits/8) + ((nBits % 8)? 1: 0); + if (wc_RNG_GenerateBlock(pEbsParams, (byte*)pData, nBytes) != 0) { + USER_DEBUG(("error in generating random wolfSSL block\n")); + return ippStsErr; + } + + return ippStsNoErr; +} + + #ifdef WOLFSSL_KEY_GEN /* Make an RSA key for size bits, with e specified, 65537 is a good e */ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) @@ -1612,8 +1938,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) Ipp8u* scratchBuffer; int trys = 8; /* Miller-Rabin test parameter */ IppsPrimeState* pPrime; - IppBitSupplier rndFunc; - IppsPRNGState* rndParam; /* rng context */ int qBitSz; /* size of q factor */ int bytSz; /* size of key in bytes */ @@ -1621,8 +1945,9 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) USER_DEBUG(("Entering wc_MakeRsaKey\n")); - qBitSz = size / 2; - bytSz = size / 8; + /* get byte size and individual private key size -- round up */ + qBitSz = (size / 2) + ((size % 2)? 1: 0); + bytSz = (size / 8) + ((size % 8)? 1: 0); if (key == NULL) return USER_CRYPTO_ERROR; @@ -1634,24 +1959,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return USER_CRYPTO_ERROR; key->type = RSA_PRIVATE; - - /* set up rng */ - ret = ippsPRNGGetSize(&ctxSz); - if (ret != ippStsNoErr) { - USER_DEBUG(("ippsPRNGGetSize error of %s\n", ippGetStatusString(ret))); - return USER_CRYPTO_ERROR; - } - - rndParam = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); - if (rndParam == NULL) - return USER_CRYPTO_ERROR; - - /*@TODO size of seed bits used hard set at 256 */ - ret = ippsPRNGInit(256, rndParam); - if (ret != ippStsNoErr) { - USER_DEBUG(("ippsPRNGInit error of %s\n", ippGetStatusString(ret))); - return USER_CRYPTO_ERROR; - } + key->sz = bytSz; /* initialize prime number */ ret = ippsPrimeGetSize(size, &ctxSz); /* size in bits */ @@ -1660,7 +1968,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return USER_CRYPTO_ERROR; } - pPrime = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + pPrime = (IppsPrimeState*)XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); if (pPrime == NULL) return USER_CRYPTO_ERROR; @@ -1670,12 +1978,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return USER_CRYPTO_ERROR; } - ret = ippsPrimeGen(size, 100, pPrime, ippsPRNGen, rndParam); - if (ret != ippStsNoErr) { - USER_DEBUG(("ippsPrimeGen error of %s\n", ippGetStatusString(ret))); - return USER_CRYPTO_ERROR; - } - /* define RSA privete key type 2 */ /* length in bits of p and q factors */ ret = ippsRSA_GetSizePrivateKeyType2(qBitSz, qBitSz, &ctxSz); @@ -1686,7 +1988,8 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) } key->prvSz = ctxSz; /* used when freeing private key */ - key->pPrv = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + key->pPrv = (IppsRSAPrivateKeyState*)XMALLOC(ctxSz, NULL, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPrv == NULL) return USER_CRYPTO_ERROR; @@ -1706,74 +2009,41 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return USER_CRYPTO_ERROR; } - scratchBuffer = XMALLOC(scratchSz, 0, DYNAMIC_TYPE_USER_CRYPTO); + scratchBuffer = (Ipp8u*)XMALLOC(scratchSz, 0, DYNAMIC_TYPE_USER_CRYPTO); if (scratchBuffer == NULL) return USER_CRYPTO_ERROR; /* set up initial value of pScrPublicExp */ leng = (int)sizeof(long); /* # of Ipp32u in long */ - ret = ippsBigNumGetSize(leng, &ctxSz); + ret = init_bn(&pSrcPublicExp, leng); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; - pSrcPublicExp = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (pSrcPublicExp == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(leng, pSrcPublicExp); - if (ret != ippStsNoErr) - return USER_CRYPTO_ERROR; ret = ippsSetOctString_BN((Ipp8u*)&e, leng, pSrcPublicExp); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; /* initializing key->n */ - ret = ippsBigNumGetSize(bytSz, &ctxSz); - if (ret != ippStsNoErr) - return USER_CRYPTO_ERROR; - - key->n = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->n == NULL) - return USER_CRYPTO_ERROR; - - key->nSz = size; - ret = ippsBigNumInit(bytSz, key->n); + ret = init_bn(&key->n, bytSz); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; /* initializing public exponent key->e */ - ret = ippsBigNumGetSize(leng, &ctxSz); - if (ret != ippStsNoErr) - return USER_CRYPTO_ERROR; - - key->e = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->e == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(leng, key->e); + ret = init_bn(&key->e, leng); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; /* private exponent key->dipp */ - ret = ippsBigNumGetSize(bytSz, &ctxSz); + ret = init_bn(&key->dipp, bytSz); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; - key->dipp = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->dipp == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(bytSz, key->dipp); - if (ret != ippStsNoErr) - return USER_CRYPTO_ERROR; - - rndFunc = ippsPRNGen; /* call IPP to generate keys, if inseficent entropy error call again using for loop to avoid infinte loop */ for (i = 0; i < 5; i++) { ret = ippsRSA_GenerateKeys(pSrcPublicExp, key->n, key->e, key->dipp, key->pPrv, scratchBuffer, trys, pPrime, - rndFunc, rndParam); + wolfSSL_rng, rng); if (ret == ippStsNoErr) { break; } @@ -1785,6 +2055,12 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return USER_CRYPTO_ERROR; } } + /* catch if still did not generate a good key */ + if (ret != ippStsNoErr) { + USER_DEBUG(("ippsRSA_GeneratKeys error of %s\n", + ippGetStatusString(ret))); + return USER_CRYPTO_ERROR; + } /* get bn sizes needed for private key set up */ ret = ippsExtGet_BN(NULL, &key->eSz, NULL, key->e); @@ -1807,7 +2083,8 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) return USER_CRYPTO_ERROR; } - key->pPub = XMALLOC(ctxSz, NULL, DYNAMIC_TYPE_USER_CRYPTO); + key->pPub = (IppsRSAPublicKeyState*)XMALLOC(ctxSz, NULL, + DYNAMIC_TYPE_USER_CRYPTO); if (key->pPub == NULL) return USER_CRYPTO_ERROR; @@ -1827,51 +2104,27 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) /* get private key information for key struct */ leng = size/16; /* size of q, p, u, dP, dQ */ - ret = ippsBigNumGetSize(leng, &ctxSz); /* get needed ctxSz and use */ - if (ret != ippStsNoErr) - return USER_CRYPTO_ERROR; - - key->pipp = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->pipp == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(leng, key->pipp); + ret = init_bn(&key->pipp, leng); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; /* set up q BN for key */ - key->qipp = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->qipp == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(leng, key->qipp); + ret = init_bn(&key->qipp, leng); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; /* set up dP BN for key */ - key->dPipp = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->dPipp == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(leng, key->dPipp); + ret = init_bn(&key->dPipp, leng); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; /* set up dQ BN for key */ - key->dQipp = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->dQipp == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(leng, key->dQipp); + ret = init_bn(&key->dQipp, leng); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; /* set up u BN for key */ - key->uipp = XMALLOC(ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (key->uipp == NULL) - return USER_CRYPTO_ERROR; - - ret = ippsBigNumInit(leng, key->uipp); + ret = init_bn(&key->uipp, leng); if (ret != ippStsNoErr) return USER_CRYPTO_ERROR; @@ -1888,9 +2141,6 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) XFREE(pSrcPublicExp, NULL, DYNAMIC_TYPE_USER_CRYPTO); XFREE(scratchBuffer, NULL, DYNAMIC_TYPE_USER_CRYPTO); XFREE(pPrime, NULL, DYNAMIC_TYPE_USER_CRYPTO); - XFREE(rndParam, NULL, DYNAMIC_TYPE_USER_CRYPTO); - - (void)rng; return 0; } @@ -2272,7 +2522,7 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) rawLen += lbit; tmps[i] = (byte*)XMALLOC(rawLen + MAX_SEQ_SZ, key->heap, - DYNAMIC_TYPE_USER_CRYPTO); + DYNAMIC_TYPE_USER_CRYPTO); if (tmps[i] == NULL) { ret = USER_CRYPTO_ERROR; break;