ldmud-3.3.719/
ldmud-3.3.719/doc/
ldmud-3.3.719/doc/efun.de/
ldmud-3.3.719/doc/efun/
ldmud-3.3.719/doc/man/
ldmud-3.3.719/doc/other/
ldmud-3.3.719/mud/
ldmud-3.3.719/mud/heaven7/
ldmud-3.3.719/mud/lp-245/
ldmud-3.3.719/mud/lp-245/banish/
ldmud-3.3.719/mud/lp-245/doc/
ldmud-3.3.719/mud/lp-245/doc/examples/
ldmud-3.3.719/mud/lp-245/doc/sefun/
ldmud-3.3.719/mud/lp-245/log/
ldmud-3.3.719/mud/lp-245/obj/Go/
ldmud-3.3.719/mud/lp-245/players/lars/
ldmud-3.3.719/mud/lp-245/room/death/
ldmud-3.3.719/mud/lp-245/room/maze1/
ldmud-3.3.719/mud/lp-245/room/sub/
ldmud-3.3.719/mud/lp-245/secure/
ldmud-3.3.719/mud/sticklib/
ldmud-3.3.719/mud/sticklib/src/
ldmud-3.3.719/mudlib/deprecated/
ldmud-3.3.719/mudlib/uni-crasher/
ldmud-3.3.719/pkg/
ldmud-3.3.719/pkg/debugger/
ldmud-3.3.719/pkg/diff/
ldmud-3.3.719/pkg/misc/
ldmud-3.3.719/src/
ldmud-3.3.719/src/autoconf/
ldmud-3.3.719/src/ptmalloc/
ldmud-3.3.719/src/util/
ldmud-3.3.719/src/util/erq/
ldmud-3.3.719/src/util/indent/hosts/next/
ldmud-3.3.719/src/util/xerq/
ldmud-3.3.719/src/util/xerq/lpc/
ldmud-3.3.719/src/util/xerq/lpc/www/
ldmud-3.3.719/test/generic/
ldmud-3.3.719/test/inc/
ldmud-3.3.719/test/t-0000398/
ldmud-3.3.719/test/t-0000548/
ldmud-3.3.719/test/t-030925/
ldmud-3.3.719/test/t-040413/
ldmud-3.3.719/test/t-041124/
ldmud-3.3.719/test/t-language/
/*------------------------------------------------------------------
 * Wrapper for the GCrypt library.
 *
 *------------------------------------------------------------------
 */
#include "driver.h"

#ifdef USE_GCRYPT

#include <stdarg.h>
#include <stdio.h>

#include <gcrypt.h>

#include "main.h"
#include "simulate.h"
#include "typedefs.h"
#include "xalloc.h"
#include "pkg-gcrypt.h"

#include "../mudlib/sys/tls.h"

/*-------------------------------------------------------------------------*/
static void *
gcrypt_xalloc (size_t size)

/* Wrapper function so that gcrypt will use the driver's allocator.
 * The wrapper is required as 'pxalloc' itself is a macro.
 */

{
    return pxalloc(size);
} /* tls_xalloc() */

/*-------------------------------------------------------------------------*/
static void *
gcrypt_rexalloc (void *old, size_t size)

/* Wrapper function so that gcrypt will use the driver's allocator.
 * The wrapper is required as 'prexalloc' itself is a macro.
 */

{
    return prexalloc(old, size);
} /* tls_rexalloc() */

/*-------------------------------------------------------------------------*/
static void
gcrypt_xfree (void *p)

/* Wrapper function so that gcrypt will use the driver's allocator.
 * The wrapper is not exactly required for pfree(),  but it keeps things
 * consistent.
 */

{
    return pfree(p);
} /* tls_xfree() */

/*-------------------------------------------------------------------------*/
static void
gcrypt_log_message (void *data UNUSED, int level UNUSED, const char* msg, va_list va_args)

/* Wrapper function that logs gcrypt messages.
 */

{
#ifdef __MWERKS__
#    pragma unused(data)
#    pragma unused(level)
#endif
    vprintf(msg, va_args);
    vdebug_message(msg, va_args);
} /* tls_xfree() */

/*-------------------------------------------------------------------------*/
Bool
pkg_gcrypt_init (void)

/* Initialize the gcrypt library.
 */

{
    if (!gcry_check_version(GCRYPT_VERSION))
    {
        printf("%s libgcrypt: version mismatch.\n", time_stamp());
        debug_message("%s libgcrypt: version mismatch.\n", time_stamp());

        return MY_FALSE;
    }

    /* We don't need secure memory and aren't root anyway. */
    gcry_control(GCRYCTL_DISABLE_SECMEM, 0);

    if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
    {
        gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
        gcry_set_allocation_handler(gcrypt_xalloc, NULL, NULL,
            gcrypt_rexalloc, gcrypt_xfree);
        gcry_set_log_handler(gcrypt_log_message, NULL);
    }

    return MY_TRUE;
}

/*-------------------------------------------------------------------------*/
Bool
get_digest (int num, digest_t * md, size_t *len)

/* Determine the proper digest descriptor <*md> and length <*len>
 * from the designator <num>, which is one of the TLS_HASH_ constants.
 *
 * Return MY_FALSE if the desired digest isn't available.
 */

{
    switch(num)
    {
    case TLS_HASH_SHA1:
        (*md) = GCRY_MD_SHA1;
        break;
    case TLS_HASH_RIPEMD160:
        (*md) = GCRY_MD_RMD160;
        break;
    case TLS_HASH_MD5:
        (*md) = GCRY_MD_MD5;
        break;
    case TLS_HASH_SHA224:
        (*md) = GCRY_MD_SHA224;
        break;
    case TLS_HASH_SHA256:
        (*md) = GCRY_MD_SHA256;
        break;
    case TLS_HASH_SHA384:
        (*md) = GCRY_MD_SHA384;
        break;
    case TLS_HASH_SHA512:
        (*md) = GCRY_MD_SHA512;
        break;
    default:
        (*md) = GCRY_MD_NONE;
        return MY_FALSE;
    }

    if (gcry_md_test_algo(*md))
        return MY_FALSE;

    (*len) = gcry_md_get_algo_dlen(*md);
    if(!(*len))
        return MY_FALSE;

    return MY_TRUE;
} /* get_digest() */

/*-------------------------------------------------------------------------*/
void
calc_digest (digest_t md, void *dest, size_t destlen, void *msg, size_t msglen, void *key, size_t keylen)

/* Calculates the hash or the HMAC if <key> != NULL from <msg> as determined
 * by method <md> as it was returned by get_digest().
 */
{
    gcry_md_hd_t hd;
    gcry_error_t err;

    err = gcry_md_open(&hd, md, (key==NULL) ? 0 : GCRY_MD_FLAG_HMAC);
    if (err)
    {
        errorf((key==NULL)?"hash: %s/%s\n":"hmac: %s/%s\n"
              , gcry_strsource (err), gcry_strerror (err));
        /* NOTREACHED */
    }

    if(key)
    {
        err = gcry_md_setkey(hd, key, keylen);
        if (err)
        {
            errorf("hmac: %s/%s\n"
                  , gcry_strsource (err), gcry_strerror (err));
            /* NOTREACHED */
        }
    }

    gcry_md_write(hd, msg, msglen);
    gcry_md_final(hd);
    memcpy(dest, gcry_md_read(hd, md), destlen);
    gcry_md_close(hd);
} /* calc_digest() */

#endif /* USE_GCRYPT */