/*------------------------------------------------------------------ * 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 */