56c0642008-07-31Martin Stjernholm /* -*- c -*- || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information. */
6d1a542003-03-13Niels Möller  #include "global.h" #include "interpret.h" #include "svalue.h"
602fe62004-02-21Martin Nilsson #include "threads.h"
6d1a542003-03-13Niels Möller  /* For this_object() */ #include "object.h" #include "module_support.h"
0a146b2013-03-12Arne Goedeke #include "pike_memory.h"
6d1a542003-03-13Niels Möller  #include "nettle_config.h" #ifdef HAVE_LIBNETTLE
56c0642008-07-31Martin Stjernholm DECLARATIONS
6d1a542003-03-13Niels Möller #include "nettle.h" #include <nettle/md5.h>
5c36c82003-08-26Martin Nilsson #ifdef HAVE_NETTLE_MD4_INIT
40f88a2003-08-01Martin Nilsson #include <nettle/md4.h>
5c36c82003-08-26Martin Nilsson #include <nettle/md2.h>
40f88a2003-08-01Martin Nilsson #endif
6d1a542003-03-13Niels Möller #include <nettle/sha.h> #include <nettle/nettle-meta.h> #include <stdio.h> #include <stdarg.h>
5a20f92004-04-28Martin Nilsson #include "fdlib.h"
7a38822004-04-30Martin Nilsson 
6d1a542003-03-13Niels Möller #if 0 static void werror(const char *format, ...) { va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); } #else #define werror(x) #endif
5a20f92004-04-28Martin Nilsson static struct program *Fd_ref_program = NULL;
68c0f92009-02-24Henrik Grubbström (Grubba) static struct program *Fd_program = NULL;
5a20f92004-04-28Martin Nilsson 
411a282003-03-18Niels Möller /*! @module Nettle */
cd26482003-03-18Niels Möller /*! @class HashInfo *! *! Represents information about a hash algorithm, such as *! name, digest size, and internal block size. */ PIKECLASS HashInfo
6d1a542003-03-13Niels Möller { CVAR const struct nettle_hash *meta;
5345c92013-05-19Martin Nilsson  /*! @decl string(0..255) name(void)
cd26482003-03-18Niels Möller  *! *! Returns a human readable name for the algorithm. */
5345c92013-05-19Martin Nilsson  PIKEFUN string(0..255) name()
1a2b712004-02-14Martin Nilsson  optflags OPT_TRY_OPTIMIZE;
6d1a542003-03-13Niels Möller  { if (!THIS->meta)
f1c9f42003-08-05Martin Nilsson  Pike_error("HashInfo not properly initialized.\n");
6d1a542003-03-13Niels Möller 
3f286d2003-11-29Martin Nilsson  push_text(THIS->meta->name);
6d1a542003-03-13Niels Möller  }
5345c92013-05-19Martin Nilsson  /*! @decl int(0..) digest_size(void)
cd26482003-03-18Niels Möller  *! *! Returns the size of a hash digests. */
5345c92013-05-19Martin Nilsson  PIKEFUN int(0..) digest_size()
1a2b712004-02-14Martin Nilsson  optflags OPT_TRY_OPTIMIZE;
6d1a542003-03-13Niels Möller  { if (!THIS->meta)
f1c9f42003-08-05Martin Nilsson  Pike_error("HashInfo not properly initialized.\n");
6d1a542003-03-13Niels Möller  push_int(THIS->meta->digest_size); }
5345c92013-05-19Martin Nilsson  /*! @decl int(0..) block_size(void)
cd26482003-03-18Niels Möller  *!
f1c9f42003-08-05Martin Nilsson  *! Returns the internal block size of the hash algorithm.
cd26482003-03-18Niels Möller  */
5345c92013-05-19Martin Nilsson  PIKEFUN int(0..) block_size()
1a2b712004-02-14Martin Nilsson  optflags OPT_TRY_OPTIMIZE;
6d1a542003-03-13Niels Möller  { if (!THIS->meta)
f1c9f42003-08-05Martin Nilsson  Pike_error("HashInfo not properly initialized.\n");
6d1a542003-03-13Niels Möller  push_int(THIS->meta->block_size); }
9512252004-04-28Martin Nilsson 
5345c92013-05-19Martin Nilsson  /*! @decl string(0..255) hash(string data)
9512252004-04-28Martin Nilsson  *! *! Works as a (faster) shortcut for
87b9aa2010-06-21Martin Stjernholm  *! @expr{HashState()->update(data)->digest()@}, where HashState is *! the hash state class corresponding to this HashInfo.
9512252004-04-28Martin Nilsson  *! *! @seealso *! @[HashState()->update()] and @[HashState()->digest()]. */
5345c92013-05-19Martin Nilsson  PIKEFUN string(0..255) hash(string in)
9512252004-04-28Martin Nilsson  optflags OPT_TRY_OPTIMIZE; { void *ctx; struct pike_string *out; unsigned digest_length;
5a20f92004-04-28Martin Nilsson  const struct nettle_hash *meta = THIS->meta;
9512252004-04-28Martin Nilsson 
5a20f92004-04-28Martin Nilsson  if (!meta)
9512252004-04-28Martin Nilsson  Pike_error("HashInfo not properly initialized.\n"); NO_WIDE_STRING(in);
5a20f92004-04-28Martin Nilsson  ctx = (void *)alloca(meta->context_size);
9512252004-04-28Martin Nilsson  if(!ctx)
8a3e562004-05-19Martin Nilsson  SIMPLE_OUT_OF_MEMORY_ERROR("hash", meta->context_size);
9512252004-04-28Martin Nilsson 
e8be7c2010-11-14Jonas Walldén  /* Only thread this block for significant data size */ if (in->len > THREADS_ALLOW_THRESHOLD) { THREADS_ALLOW(); meta->init(ctx); meta->update(ctx, in->len, (const uint8_t *)in->str); THREADS_DISALLOW(); } else { meta->init(ctx); meta->update(ctx, in->len, (const uint8_t *)in->str); }
9512252004-04-28Martin Nilsson 
5a20f92004-04-28Martin Nilsson  digest_length = meta->digest_size;
9512252004-04-28Martin Nilsson  out = begin_shared_string(digest_length);
20e2ef2005-12-12Martin Nilsson  meta->digest(ctx, digest_length, (uint8_t *)out->str);
5a20f92004-04-28Martin Nilsson  pop_n_elems(args); push_string(end_shared_string(out)); }
5345c92013-05-19Martin Nilsson  /*! @decl string(0..255) hash(Stdio.File file, void|int bytes)
5a20f92004-04-28Martin Nilsson  *! *! Works as a (faster) shortcut for
87b9aa2010-06-21Martin Stjernholm  *! @expr{HashState()->update(Stdio.read_file(file))->digest()@}, *! where HashState is the hash state class corresponding to this *! HashInfo.
5a20f92004-04-28Martin Nilsson  *!
7a38822004-04-30Martin Nilsson  *! @param bytes *! The number of bytes of the file object @[file] that should be *! hashed. Negative numbers are ignored and the whole file is *! hashed. *!
5a20f92004-04-28Martin Nilsson  *! @seealso *! @[Stdio.File], @[HashState()->update()] and *! @[HashState()->digest()]. */
5345c92013-05-19Martin Nilsson  PIKEFUN string(0..255) hash(object in, void|int bytes)
5a20f92004-04-28Martin Nilsson  optflags OPT_EXTERNAL_DEPEND; { void *ctx;
fe11b92004-04-29Martin Nilsson  int len, fd;
5a20f92004-04-28Martin Nilsson  char *read_buffer; PIKE_STAT_T st; struct pike_string *out; const struct nettle_hash *meta = THIS->meta; if (!meta) Pike_error("HashInfo not properly initialized.\n");
68c0f92009-02-24Henrik Grubbström (Grubba)  /* Verify that the input is a Stdio.Fd or Stdio.Fd_ref */ if (!Fd_program) { push_text("files.Fd"); SAFE_APPLY_MASTER("resolv",1); Fd_program = program_from_svalue(Pike_sp-1); if (!Fd_program) { pop_stack(); Pike_error("Unable to resolv files.Fd.\n"); } add_ref(Fd_program); pop_stack( ); }
5a20f92004-04-28Martin Nilsson  if (!Fd_ref_program) { push_text("files.Fd_ref"); SAFE_APPLY_MASTER("resolv",1); Fd_ref_program = program_from_svalue(Pike_sp-1); if (!Fd_ref_program) { pop_stack(); Pike_error("Unable to resolv files.Fd_ref.\n"); } add_ref(Fd_ref_program); pop_stack( ); }
68c0f92009-02-24Henrik Grubbström (Grubba)  if (!get_storage(in, Fd_program) && !get_storage(in, Fd_ref_program) ) Pike_error("Object not Fd or Fd_ref or subclass.\n");
5a20f92004-04-28Martin Nilsson  safe_apply(in, "query_fd", 0);
fe11b92004-04-29Martin Nilsson  fd = Pike_sp[-1].u.integer;
5a20f92004-04-28Martin Nilsson  pop_stack(); if (fd_fstat(fd, &st)<0) Pike_error("File not found!\n"); if (!S_ISREG(st.st_mode)) Pike_error("Non-regular file.\n"); ctx = (void *)alloca(meta->context_size); if (!ctx)
8a3e562004-05-19Martin Nilsson  SIMPLE_OUT_OF_MEMORY_ERROR("hash", meta->context_size);
5a20f92004-04-28Martin Nilsson 
337f332004-04-28Martin Nilsson  read_buffer=(char *)malloc(8192); if (!read_buffer)
8a3e562004-05-19Martin Nilsson  SIMPLE_OUT_OF_MEMORY_ERROR("hash", 8192);
337f332004-04-28Martin Nilsson 
5a20f92004-04-28Martin Nilsson  THREADS_ALLOW(); meta->init(ctx);
7a38822004-04-30Martin Nilsson  if(args==2 && bytes->u.integer>-1) { int bytes_left = bytes->u.integer; int read_bytes = MINIMUM(8192, bytes_left); while(read_bytes>0 && (len=fd_read(fd, read_buffer, read_bytes))>0) {
20e2ef2005-12-12Martin Nilsson  meta->update(ctx, len, (const uint8_t *)read_buffer);
7a38822004-04-30Martin Nilsson  bytes_left -= read_bytes; read_bytes = MINIMUM(8192, bytes_left); } } else while((len=fd_read(fd, read_buffer, 8192))>0)
20e2ef2005-12-12Martin Nilsson  meta->update(ctx, len, (const uint8_t *)read_buffer);
337f332004-04-28Martin Nilsson  free(read_buffer);
5a20f92004-04-28Martin Nilsson 
d51d792010-06-21Martin Stjernholm  THREADS_DISALLOW();
5a20f92004-04-28Martin Nilsson  out = begin_shared_string(meta->digest_size);
20e2ef2005-12-12Martin Nilsson  meta->digest(ctx, meta->digest_size, (uint8_t *)out->str);
9512252004-04-28Martin Nilsson  pop_n_elems(args); push_string(end_shared_string(out)); }
7940a82013-03-07Henrik Grubbström (Grubba)  /* NOTE: This is NOT the MIME base64 table! */ static const char b64tab[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static inline void b64enc(char *dest, int a, int b, int c, int sz) { unsigned int bitbuf = a | (b << 8) | (c << 16); while (sz--) { *(dest++) = b64tab[bitbuf & 63]; bitbuf >>= 6; } }
bff3272013-05-28Martin Nilsson  /*! @decl string(0..127) crypt_hash(string password, string salt, rounds)
7940a82013-03-07Henrik Grubbström (Grubba)  *! *! Password hashing function in @[crypt_md5()]-style. *! *! Implements the algorithm described in *! @url{http://www.akkadia.org/drepper/SHA-crypt.txt@}. *! *! This is the algorithm used by @tt{crypt(2)@} in *! methods @tt{$5$@} (SHA256) and @tt{$6$@} (SHA512). *! *! @seealso *! @[crypt_md5()] */
bff3272013-05-28Martin Nilsson  PIKEFUN string(0..127) crypt_hash(string password, string salt, int rounds)
7940a82013-03-07Henrik Grubbström (Grubba)  { struct pike_string *res; const struct nettle_hash *meta = THIS->meta; void *ctx; uint8_t *abcbuf; uint8_t *dpbuf; uint8_t *dsbuf;
5345c92013-05-19Martin Nilsson  unsigned char *p; unsigned char *s;
7940a82013-03-07Henrik Grubbström (Grubba)  int plen; int slen; int dsz = meta->digest_size; int i; int r; int a, b, c; if (!rounds) rounds = 5000; if (rounds < 1000) rounds = 1000; if (rounds > 999999999) rounds = 999999999; NO_WIDE_STRING(password); NO_WIDE_STRING(salt); ctx = (void *)alloca(meta->context_size); if (!ctx) SIMPLE_OUT_OF_MEMORY_ERROR("crypt_hash", meta->context_size); abcbuf = (uint8_t *)alloca(meta->digest_size * 3); if (!abcbuf) SIMPLE_OUT_OF_MEMORY_ERROR("crypt_hash", meta->digest_size * 3); dpbuf = abcbuf + meta->digest_size; dsbuf = dpbuf + meta->digest_size; /* NB: We use these to allow the compiler to * avoid dereferencing at every step. */
5345c92013-05-19Martin Nilsson  p = (unsigned char*)password->str;
7940a82013-03-07Henrik Grubbström (Grubba)  plen = password->len;
5345c92013-05-19Martin Nilsson  s = (unsigned char*)salt->str;
7940a82013-03-07Henrik Grubbström (Grubba)  slen = salt->len; if (slen > 16) slen = 16; dsz = meta->digest_size; /* NB: We allocate the result here to avoid throwing away all the work * on out of memory at the end. */ if (dsz == 32) { /* 4 * (30/3) + 3 */ res = begin_shared_string(43); } else if (dsz == 64) { /* 4 * (63/3) + 2 */ res = begin_shared_string(86); } else { Pike_error("crypt_hash() not supported for this digest size yet (%d).\n", dsz); } THREADS_ALLOW(); /* NB: Comments refer to http://www.akkadia.org/drepper/SHA-crypt.txt */ meta->init(ctx); /* 4 */ meta->update(ctx, plen, p); /* 5 */ meta->update(ctx, slen, s); /* 6 */ meta->update(ctx, plen, p); /* 7 */ meta->digest(ctx, dsz, abcbuf); /* 8 */ meta->init(ctx); /* 1 */ meta->update(ctx, plen, p); /* 2 */ meta->update(ctx, slen, s); /* 3 */ for (i = 0; i + dsz < plen; i += dsz) { /* 9 */ meta->update(ctx, dsz, abcbuf); } meta->update(ctx, plen - i, abcbuf); /* 10 */ for (i = 1; i < plen; i <<= 1) { /* 11 */ if (plen & i) { meta->update(ctx, dsz, abcbuf); } else { meta->update(ctx, plen, p); } } meta->digest(ctx, dsz, abcbuf); /* 12 */ meta->init(ctx); /* 13 */ for (i = 0; i < plen; i++) { /* 14 */ meta->update(ctx, plen, p); } meta->digest(ctx, dsz, dpbuf); /* 15 */ /* Sequence P is implicit. */ /* 16 */ meta->init(ctx); /* 17 */ for(i = 0; i < 16 + abcbuf[0]; i++) { /* 18 */ meta->update(ctx, slen, s); } meta->digest(ctx, dsz, dsbuf); /* 19 */ /* Sequence S is implicit. */ /* 20 */ for (r = 0; r < rounds; r++) { /* 21 */ meta->init(ctx); /* a */ if (r & 1) { /* b */ for (i = 0; i + dsz < plen; i += dsz) { meta->update(ctx, dsz, dpbuf); } meta->update(ctx, plen - i, dpbuf); } else { meta->update(ctx, dsz, abcbuf); /* c */ } if (r % 3) { /* d */ for (i = 0; i + dsz < slen; i += dsz) { meta->update(ctx, dsz, dsbuf); } meta->update(ctx, slen - i, dsbuf); } if (r % 7) { /* e */ for (i = 0; i + dsz < plen; i += dsz) { meta->update(ctx, dsz, dpbuf); } meta->update(ctx, plen - i, dpbuf); } if (r & 1) { /* f */ meta->update(ctx, dsz, abcbuf); } else { /* g */ for (i = 0; i + dsz < plen; i += dsz) { meta->update(ctx, dsz, dpbuf); } meta->update(ctx, plen - i, dpbuf); } meta->digest(ctx, dsz, abcbuf); /* h */ } THREADS_DISALLOW(); /* And now time for some pointless shuffling of the result. * Note that the shuffling is slightly different between * the two cases. * * This is followed by a custom base64-style encoding. */ c = 0; b = dsz/3; a = 2*b; if (dsz == 32) { for (i = 0, r = 0; i + 3 < dsz; i+=3, r+=4) { int t; b64enc(res->str + r, abcbuf[a], abcbuf[b], abcbuf[c], 4); t = a+1; a = b+1; b = c+1; c = t; } b64enc(res->str + r, abcbuf[30], abcbuf[31], 0, 3); } else { for (i = 0, r = 0; i + 3 < dsz; i+=3, r+=4) { int t; b64enc(res->str + r, abcbuf[a], abcbuf[b], abcbuf[c], 4); t = a+1; a = c+1; c = b+1; b = t; } b64enc(res->str + r, abcbuf[63], 0, 0, 2); } push_string(end_shared_string(res)); /* 22e */ /* Clean intermediate values. */ MEMSET(ctx, 0, meta->context_size); MEMSET(abcbuf, 0, 3*dsz); }
6d1a542003-03-13Niels Möller  INIT {
cd26482003-03-18Niels Möller  werror("HashInfo->INIT\n");
6d1a542003-03-13Niels Möller  THIS->meta = NULL; } }
411a282003-03-18Niels Möller /*! @endclass HashInfo */
6d1a542003-03-13Niels Möller #define GET_META(o) \
cd26482003-03-18Niels Möller ( ((struct HashInfo_struct *) get_storage((o), HashInfo_program)) \
6d1a542003-03-13Niels Möller  ->meta) /* The algorithm objects have to be implemented in pike. */
cd26482003-03-18Niels Möller /*! @class HashState *! *! Base class for hashing contexts. */ PIKECLASS HashState
6d1a542003-03-13Niels Möller {
cd26482003-03-18Niels Möller  INHERIT HashInfo;
6d1a542003-03-13Niels Möller  CVAR void *ctx; /* FIXME: Create should copy state from the other object, if * provided. */
4a63d42003-03-18Martin Nilsson  /*! @decl HashState update(string data)
cd26482003-03-18Niels Möller  *! *! Hashes more data. */
6d1a542003-03-13Niels Möller  PIKEFUN object update(string data)
1a2b712004-02-14Martin Nilsson  optflags OPT_SIDE_EFFECT;
6d1a542003-03-13Niels Möller  {
766bc82004-10-16Marcus Agehall  void *ctx = THIS->ctx;
9119632003-05-07Henrik Grubbström (Grubba)  const struct nettle_hash *meta = GET_META(Pike_fp->current_object);
6d1a542003-03-13Niels Möller 
03123d2004-02-21Martin Nilsson  if (!ctx || !meta)
f1c9f42003-08-05Martin Nilsson  Pike_error("HashState not properly initialized.\n");
6d1a542003-03-13Niels Möller  NO_WIDE_STRING(data);
e8be7c2010-11-14Jonas Walldén  /* Only thread this block for significant data size */ if (data->len > THREADS_ALLOW_THRESHOLD) { THREADS_ALLOW(); meta->update(ctx, data->len, (const uint8_t *)data->str); THREADS_DISALLOW(); } else { meta->update(ctx, data->len, (const uint8_t *)data->str); }
6d1a542003-03-13Niels Möller  push_object(this_object()); }
5345c92013-05-19Martin Nilsson  /*! @decl string(0..255) digest(int|void length)
cd26482003-03-18Niels Möller  *! *! Generates a digests, and resets the hashing contents. *! *! @param length *! If the length argument is provided, the digest is truncated *! to the given length. *!
4a63d42003-03-18Martin Nilsson  *! @returns *! The digest.
cd26482003-03-18Niels Möller  */
5345c92013-05-19Martin Nilsson  PIKEFUN string(0..255) digest(int|void arg)
6d1a542003-03-13Niels Möller  { const struct nettle_hash *meta; struct pike_string *digest; unsigned length; if (! THIS->ctx)
f1c9f42003-08-05Martin Nilsson  Pike_error("HashState not properly initialized.\n");
6d1a542003-03-13Niels Möller 
9119632003-05-07Henrik Grubbström (Grubba)  meta = GET_META(Pike_fp->current_object);
6d1a542003-03-13Niels Möller  assert(meta); if (!arg) length = meta->digest_size; else {
017b572011-10-28Henrik Grubbström (Grubba)  if (TYPEOF(*arg) != PIKE_T_INT)
f1c9f42003-08-05Martin Nilsson  Pike_error("Bad argument type.\n"); if (arg->u.integer < 0) Pike_error("Invalid length, must be positive.\n");
61e14b2004-01-23Martin Nilsson  if ((unsigned)arg->u.integer > meta->digest_size)
f1c9f42003-08-05Martin Nilsson  Pike_error("Unsupported digest length.\n");
6d1a542003-03-13Niels Möller  length = arg->u.integer; } digest = begin_shared_string(length);
20e2ef2005-12-12Martin Nilsson  meta->digest(THIS->ctx, length, (uint8_t *)digest->str);
6d1a542003-03-13Niels Möller  push_string(end_shared_string(digest)); }
ac14652003-07-29Martin Nilsson 
6d1a542003-03-13Niels Möller  INIT {
cd26482003-03-18Niels Möller  werror("HashState->INIT\n");
6d1a542003-03-13Niels Möller  THIS->ctx = NULL; }
22038d2008-05-30Martin Nilsson 
6d1a542003-03-13Niels Möller  EXIT
d3df7c2008-05-30Martin Nilsson  gc_trivial;
6d1a542003-03-13Niels Möller  {
cd26482003-03-18Niels Möller  werror("HashState->EXIT\n");
983e2d2003-05-08Henrik Grubbström (Grubba)  if (THIS->ctx && Pike_fp->current_object->prog)
6d1a542003-03-13Niels Möller  {
9119632003-05-07Henrik Grubbström (Grubba)  const struct nettle_hash *meta = GET_META(Pike_fp->current_object);
6d1a542003-03-13Niels Möller  assert(meta); memset(THIS->ctx, 0, meta->context_size); } } }
411a282003-03-18Niels Möller /*! @endclass HashState */
88064b2011-12-20Henrik Grubbström (Grubba) #cmod_define TOSTR(DEF) #DEF
6d1a542003-03-13Niels Möller 
88064b2011-12-20Henrik Grubbström (Grubba) #cmod_define PIKE_NAME MD5 #cmod_define NETTLE_NAME md5 #cmod_include "hash.H" #cmod_undef PIKE_NAME #cmod_undef NETTLE_NAME
6d1a542003-03-13Niels Möller 
5c36c82003-08-26Martin Nilsson #ifdef HAVE_NETTLE_MD4_INIT
40f88a2003-08-01Martin Nilsson 
88064b2011-12-20Henrik Grubbström (Grubba) #cmod_define PIKE_NAME MD4 #cmod_define NETTLE_NAME md4 #cmod_include "hash.H" #cmod_undef PIKE_NAME #cmod_undef NETTLE_NAME
5c36c82003-08-26Martin Nilsson 
88064b2011-12-20Henrik Grubbström (Grubba) #cmod_define PIKE_NAME MD2 #cmod_define NETTLE_NAME md2 #cmod_include "hash.H" #cmod_undef PIKE_NAME #cmod_undef NETTLE_NAME
5c36c82003-08-26Martin Nilsson  #endif /* HAVE_NETTLE_MD4_INIT */
40f88a2003-08-01Martin Nilsson 
88064b2011-12-20Henrik Grubbström (Grubba) #cmod_define PIKE_NAME SHA1 #cmod_define NETTLE_NAME sha1 #cmod_include "hash.H" #cmod_undef PIKE_NAME #cmod_undef NETTLE_NAME #cmod_define PIKE_NAME SHA256 #cmod_define NETTLE_NAME sha256 #cmod_include "hash.H" #cmod_undef PIKE_NAME #cmod_undef NETTLE_NAME
0980772003-07-29Martin Nilsson 
1ebab82011-12-20Henrik Grubbström (Grubba) #ifdef SHA384_DIGEST_SIZE #cmod_define PIKE_NAME SHA384 #cmod_define NETTLE_NAME sha384 #cmod_include "hash.H" #cmod_undef PIKE_NAME #cmod_undef NETTLE_NAME #endif /* SHA384_DIGEST_SIZE */ #ifdef SHA512_DIGEST_SIZE #cmod_define PIKE_NAME SHA512 #cmod_define NETTLE_NAME sha512 #cmod_include "hash.H" #cmod_undef PIKE_NAME #cmod_undef NETTLE_NAME #endif /* SHA512_DIGEST_SIZE */
411a282003-03-18Niels Möller /*! @endmodule Nettle */
6d1a542003-03-13Niels Möller  void hash_init(void) { werror("Nettle, hash init\n"); INIT; } void hash_exit(void) { werror("Nettle, hash exit\n");
68c0f92009-02-24Henrik Grubbström (Grubba)  if (Fd_program) { free_program( Fd_program ); }
5a20f92004-04-28Martin Nilsson  if (Fd_ref_program) { free_program( Fd_ref_program ); }
6d1a542003-03-13Niels Möller  EXIT; } #endif /* HAVE_LIBNETTLE */