[1/2] bcrypt: Add support for SHA hashes on Linux using Nettle.

Damjan Jovanovic damjan.jov at gmail.com
Mon Jan 11 05:47:46 CST 2016


Hi

I don't believe it's possible to use Nettle in Wine right now, due to its
copyright license:

"Nettle is dual licenced under the GNU General Public License version 2 or
later, and the GNU Lesser General Public License version 3 or later. When
using Nettle, you must comply fully with all conditions of at least one of
these licenses." (
http://www.lysator.liu.se/~nisse/nettle/nettle.html#Copyright)

Wine is only LGPLv2+, which isn't compatible with either.

Besides, why not GnuTLS or Mozilla's NSS?

Regards
Damjan


On Mon, Jan 11, 2016 at 12:25 PM, Hans Leidekker <hans at codeweavers.com>
wrote:

> v2: Load Nettle dynamically.
>
> Signed-off-by: Hans Leidekker <hans at codeweavers.com>
> ---
>  configure.ac              |  13 +++
>  dlls/bcrypt/Makefile.in   |   1 +
>  dlls/bcrypt/bcrypt_main.c | 199
> ++++++++++++++++++++++++++++++++++++++++++++--
>  3 files changed, 208 insertions(+), 5 deletions(-)
>
> diff --git a/configure.ac b/configure.ac
> index 2b1dd81..32b09ad 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -60,6 +60,7 @@ AC_ARG_WITH(ldap,
> AS_HELP_STRING([--without-ldap],[do not use LDAP]),
>              [if test "x$withval" = "xno"; then ac_cv_header_ldap_h=no;
> ac_cv_header_lber_h=no; fi])
>  AC_ARG_WITH(mpg123,    AS_HELP_STRING([--without-mpg123],[do not use the
> mpg123 library]))
>  AC_ARG_WITH(netapi,    AS_HELP_STRING([--without-netapi],[do not use the
> Samba NetAPI library]))
> +AC_ARG_WITH(nettle,    AS_HELP_STRING([--without-nettle],[do not use
> Nettle]))
>  AC_ARG_WITH(openal,    AS_HELP_STRING([--without-openal],[do not use
> OpenAL]),
>              [if test "x$withval" = "xno"; then ac_cv_header_AL_al_h=no;
> ac_cv_header_OpenAL_al_h=no; fi])
>  AC_ARG_WITH(opencl,    AS_HELP_STRING([--without-opencl],[do not use
> OpenCL]),
> @@ -1274,6 +1275,18 @@ fi
>  WINE_WARNING_WITH(gnutls,[test "x$ac_cv_lib_soname_gnutls" = "x"],
>                   [libgnutls ${notice_platform}development files not
> found, no schannel support.])
>
> +dnl **** Check for libnettle ***
> +if test "x$with_nettle" != "xno"
> +then
> +    WINE_PACKAGE_FLAGS(NETTLE,[nettle],,,,
> +        [AC_CHECK_HEADER([nettle/sha2.h],
> +
> [WINE_CHECK_SONAME(nettle,nettle_sha512_init,,[NETTLE_CFLAGS=""],[$NETTLE_LIBS])],
> +            [NETTLE_CFLAGS=""])])
> +fi
> +WINE_WARNING_WITH(nettle,[test "x$ac_cv_lib_soname_nettle" = "x" -a \
> +
>  "x$ac_cv_header_CommonCrypto_CommonDigest_h" != "xyes"],
> +                 [libnettle ${notice_platform}development files not
> found, no crypto support (bcrypt).])
> +
>  dnl **** Check which curses lib to use ***
>  CURSES_LIBS=""
>  if test "$ac_cv_header_ncurses_h" = "yes"
> diff --git a/dlls/bcrypt/Makefile.in b/dlls/bcrypt/Makefile.in
> index 87e1429..e83cbab 100644
> --- a/dlls/bcrypt/Makefile.in
> +++ b/dlls/bcrypt/Makefile.in
> @@ -1,5 +1,6 @@
>  MODULE    = bcrypt.dll
>  IMPORTS   = advapi32
> +EXTRAINCL = $(NETTLE_CFLAGS)
>
>  C_SRCS = \
>         bcrypt_main.c
> diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
> index 9cc5227..e66a70f 100644
> --- a/dlls/bcrypt/bcrypt_main.c
> +++ b/dlls/bcrypt/bcrypt_main.c
> @@ -18,10 +18,14 @@
>   */
>
>  #include "config.h"
> +#include "wine/port.h"
>
>  #include <stdarg.h>
>  #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
>  #include <CommonCrypto/CommonDigest.h>
> +#elif defined(SONAME_LIBNETTLE)
> +#include <nettle/sha1.h>
> +#include <nettle/sha2.h>
>  #endif
>
>  #include "ntstatus.h"
> @@ -32,10 +36,73 @@
>  #include "bcrypt.h"
>
>  #include "wine/debug.h"
> +#include "wine/library.h"
>  #include "wine/unicode.h"
>
>  WINE_DEFAULT_DEBUG_CHANNEL(bcrypt);
>
> +static HINSTANCE instance;
> +
> +#if defined(SONAME_LIBNETTLE) &&
> !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
> +WINE_DECLARE_DEBUG_CHANNEL(winediag);
> +
> +static void *libnettle_handle;
> +#define MAKE_FUNCPTR(f) static typeof(f) * p##f
> +MAKE_FUNCPTR(nettle_sha1_init);
> +MAKE_FUNCPTR(nettle_sha256_init);
> +MAKE_FUNCPTR(nettle_sha384_init);
> +MAKE_FUNCPTR(nettle_sha512_init);
> +MAKE_FUNCPTR(nettle_sha1_update);
> +MAKE_FUNCPTR(nettle_sha256_update);
> +MAKE_FUNCPTR(nettle_sha512_update);
> +MAKE_FUNCPTR(nettle_sha1_digest);
> +MAKE_FUNCPTR(nettle_sha256_digest);
> +MAKE_FUNCPTR(nettle_sha384_digest);
> +MAKE_FUNCPTR(nettle_sha512_digest);
> +#undef MAKE_FUNCPTR
> +
> +static BOOL nettle_init(void)
> +{
> +    if (!(libnettle_handle = wine_dlopen( SONAME_LIBNETTLE, RTLD_NOW,
> NULL, 0 )))
> +    {
> +        ERR_(winediag)( "failed to load libnettle, no crypto support\n" );
> +        return FALSE;
> +    }
> +
> +#define LOAD_FUNCPTR(f) \
> +    if (!(p##f = wine_dlsym( libnettle_handle, #f, NULL, 0 ))) \
> +    { \
> +        ERR( "failed to load %s\n", #f ); \
> +        goto fail; \
> +    }
> +
> +    LOAD_FUNCPTR(nettle_sha1_init)
> +    LOAD_FUNCPTR(nettle_sha256_init)
> +    LOAD_FUNCPTR(nettle_sha384_init)
> +    LOAD_FUNCPTR(nettle_sha512_init)
> +    LOAD_FUNCPTR(nettle_sha1_update)
> +    LOAD_FUNCPTR(nettle_sha256_update)
> +    LOAD_FUNCPTR(nettle_sha512_update)
> +    LOAD_FUNCPTR(nettle_sha1_digest)
> +    LOAD_FUNCPTR(nettle_sha256_digest)
> +    LOAD_FUNCPTR(nettle_sha384_digest)
> +    LOAD_FUNCPTR(nettle_sha512_digest)
> +#undef LOAD_FUNCPTR
> +    return TRUE;
> +
> +fail:
> +    wine_dlclose( libnettle_handle, NULL, 0 );
> +    libnettle_handle = NULL;
> +    return FALSE;
> +}
> +
> +static void nettle_deinit(void)
> +{
> +    wine_dlclose( libnettle_handle, NULL, 0 );
> +    libnettle_handle = NULL;
> +}
> +#endif /* SONAME_LIBNETTLE && !HAVE_COMMONCRYPTO_COMMONDIGEST_H */
> +
>  NTSTATUS WINAPI BCryptEnumAlgorithms(ULONG dwAlgOperations, ULONG
> *pAlgCount,
>                                       BCRYPT_ALGORITHM_IDENTIFIER
> **ppAlgList, ULONG dwFlags)
>  {
> @@ -203,7 +270,7 @@ static NTSTATUS hash_init( struct hash *hash )
>      return STATUS_SUCCESS;
>  }
>
> -static void hash_update( struct hash *hash, UCHAR *input, ULONG size )
> +static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
>  {
>      switch (hash->alg_id)
>      {
> @@ -225,8 +292,9 @@ static void hash_update( struct hash *hash, UCHAR
> *input, ULONG size )
>
>      default:
>          ERR( "unhandled id %u\n", hash->alg_id );
> -        break;
> +        return STATUS_NOT_IMPLEMENTED;
>      }
> +    return STATUS_SUCCESS;
>  }
>
>  static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size
> )
> @@ -255,6 +323,105 @@ static NTSTATUS hash_finish( struct hash *hash,
> UCHAR *output, ULONG size )
>      }
>      return STATUS_SUCCESS;
>  }
> +#elif defined(SONAME_LIBNETTLE)
> +struct hash
> +{
> +    struct object hdr;
> +    enum alg_id   alg_id;
> +    union
> +    {
> +        struct sha1_ctx   sha1_ctx;
> +        struct sha256_ctx sha256_ctx;
> +        struct sha512_ctx sha512_ctx;
> +    } u;
> +};
> +
> +static NTSTATUS hash_init( struct hash *hash )
> +{
> +    if (!libnettle_handle) return STATUS_NOT_IMPLEMENTED;
> +
> +    switch (hash->alg_id)
> +    {
> +    case ALG_ID_SHA1:
> +        pnettle_sha1_init( &hash->u.sha1_ctx );
> +        break;
> +
> +    case ALG_ID_SHA256:
> +        pnettle_sha256_init( &hash->u.sha256_ctx );
> +        break;
> +
> +    case ALG_ID_SHA384:
> +        pnettle_sha384_init( &hash->u.sha512_ctx );
> +        break;
> +
> +    case ALG_ID_SHA512:
> +        pnettle_sha512_init( &hash->u.sha512_ctx );
> +        break;
> +
> +    default:
> +        ERR( "unhandled id %u\n", hash->alg_id );
> +        return STATUS_NOT_IMPLEMENTED;
> +    }
> +    return STATUS_SUCCESS;
> +}
> +
> +static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
> +{
> +    if (!libnettle_handle) return STATUS_NOT_IMPLEMENTED;
> +
> +    switch (hash->alg_id)
> +    {
> +    case ALG_ID_SHA1:
> +        pnettle_sha1_update( &hash->u.sha1_ctx, size, input );
> +        break;
> +
> +    case ALG_ID_SHA256:
> +        pnettle_sha256_update( &hash->u.sha256_ctx, size, input );
> +        break;
> +
> +    case ALG_ID_SHA384:
> +        pnettle_sha512_update( &hash->u.sha512_ctx, size, input );
> +        break;
> +
> +    case ALG_ID_SHA512:
> +        pnettle_sha512_update( &hash->u.sha512_ctx, size, input );
> +        break;
> +
> +    default:
> +        ERR( "unhandled id %u\n", hash->alg_id );
> +        return STATUS_NOT_IMPLEMENTED;
> +    }
> +    return STATUS_SUCCESS;
> +}
> +
> +static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size
> )
> +{
> +    if (!libnettle_handle) return STATUS_NOT_IMPLEMENTED;
> +
> +    switch (hash->alg_id)
> +    {
> +    case ALG_ID_SHA1:
> +        pnettle_sha1_digest( &hash->u.sha1_ctx, size, output );
> +        break;
> +
> +    case ALG_ID_SHA256:
> +        pnettle_sha256_digest( &hash->u.sha256_ctx, size, output );
> +        break;
> +
> +    case ALG_ID_SHA384:
> +        pnettle_sha384_digest( &hash->u.sha512_ctx, size, output );
> +        break;
> +
> +    case ALG_ID_SHA512:
> +        pnettle_sha512_digest( &hash->u.sha512_ctx, size, output );
> +        break;
> +
> +    default:
> +        ERR( "unhandled id %u\n", hash->alg_id );
> +        return STATUS_NOT_IMPLEMENTED;
> +    }
> +    return STATUS_SUCCESS;
> +}
>  #else
>  struct hash
>  {
> @@ -268,9 +435,10 @@ static NTSTATUS hash_init( struct hash *hash )
>      return STATUS_NOT_IMPLEMENTED;
>  }
>
> -static void hash_update( struct hash *hash, UCHAR *input, ULONG size )
> +static NTSTATUS hash_update( struct hash *hash, UCHAR *input, ULONG size )
>  {
>      ERR( "support for hashes not available at build time\n" );
> +    return STATUS_NOT_IMPLEMENTED;
>  }
>
>  static NTSTATUS hash_finish( struct hash *hash, UCHAR *output, ULONG size
> )
> @@ -484,8 +652,7 @@ NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE
> handle, UCHAR *input, ULONG s
>      if (!hash || hash->hdr.magic != MAGIC_HASH) return
> STATUS_INVALID_HANDLE;
>      if (!input) return STATUS_INVALID_PARAMETER;
>
> -    hash_update( hash, input, size );
> -    return STATUS_SUCCESS;
> +    return hash_update( hash, input, size );
>  }
>
>  NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR
> *output, ULONG size, ULONG flags )
> @@ -499,3 +666,25 @@ NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE
> handle, UCHAR *output, ULON
>
>      return hash_finish( hash, output, size );
>  }
> +
> +BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved )
> +{
> +    switch (reason)
> +    {
> +    case DLL_PROCESS_ATTACH:
> +        instance = hinst;
> +        DisableThreadLibraryCalls( hinst );
> +#if defined(SONAME_LIBNETTLE) &&
> !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
> +        nettle_init();
> +#endif
> +        break;
> +
> +    case DLL_PROCESS_DETACH:
> +        if (reserved) break;
> +#if defined(SONAME_LIBNETTLE) &&
> !defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
> +        nettle_deinit();
> +#endif
> +        break;
> +    }
> +    return TRUE;
> +}
> --
> 2.6.4
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20160111/650bc428/attachment-0001.html>


More information about the wine-devel mailing list