From 22c4b59ea865fbb2be49b1656ec7f85040ea65df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?=
 <grubba@grubba.org>
Date: Tue, 5 Nov 1996 16:10:10 +0100
Subject: [PATCH] External precompiled modules for Pike.

Rev: src/modules/_Crypto/Makefile:1.1.1.1
Rev: src/modules/_Crypto/crypto.c:1.1.1.1
Rev: src/modules/_Crypto/crypto.h:1.1.1.1
Rev: src/modules/_Crypto/crypto.pre.pike:1.1.1.1
Rev: src/modules/_Crypto/des.c:1.1.1.1
Rev: src/modules/_Crypto/des.pike:1.1.1.1
Rev: src/modules/_Crypto/idea.c:1.1.1.1
Rev: src/modules/_Crypto/md2.c:1.1.1.1
Rev: src/modules/_Crypto/md5.c:1.1.1.1
Rev: src/modules/_Crypto/md5.pike:1.1.1.1
Rev: src/modules/_Crypto/precompiled_crypto.h:1.1.1.1
---
 .gitattributes                           |  15 +
 src/modules/_Crypto/Makefile             |  32 ++
 src/modules/_Crypto/crypto.c             | 178 +++++++++++
 src/modules/_Crypto/crypto.h             |  14 +
 src/modules/_Crypto/crypto.pre.pike      |   6 +
 src/modules/_Crypto/des.c                | 382 +++++++++++++++++++++++
 src/modules/_Crypto/des.pike             | 133 ++++++++
 src/modules/_Crypto/idea.c               | 252 +++++++++++++++
 src/modules/_Crypto/md2.c                | 176 +++++++++++
 src/modules/_Crypto/md5.c                | 176 +++++++++++
 src/modules/_Crypto/md5.pike             |  69 ++++
 src/modules/_Crypto/precompiled_crypto.h | 100 ++++++
 12 files changed, 1533 insertions(+)
 create mode 100644 src/modules/_Crypto/Makefile
 create mode 100644 src/modules/_Crypto/crypto.c
 create mode 100644 src/modules/_Crypto/crypto.h
 create mode 100644 src/modules/_Crypto/crypto.pre.pike
 create mode 100644 src/modules/_Crypto/des.c
 create mode 100755 src/modules/_Crypto/des.pike
 create mode 100644 src/modules/_Crypto/idea.c
 create mode 100644 src/modules/_Crypto/md2.c
 create mode 100644 src/modules/_Crypto/md5.c
 create mode 100755 src/modules/_Crypto/md5.pike
 create mode 100644 src/modules/_Crypto/precompiled_crypto.h

diff --git a/.gitattributes b/.gitattributes
index 12dded836d..fa7081d30e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,18 @@
 [attr]binary -text -crlf -diff -ident
 * text ident
 testfont binary
+
+# Handling of foreign (ie CVS) identifiers.
+#
+[attr]foreign_ident -ident block_commit=Remove-foreign_ident-attribute-before-commit.
+# Files containing CVS ids follow.
+# Remove the corresponding line before committing
+# changes to these files.
+/src/modules/_Crypto/crypto.c foreign_ident
+/src/modules/_Crypto/crypto.h foreign_ident
+/src/modules/_Crypto/des.c foreign_ident
+/src/modules/_Crypto/des.pike foreign_ident
+/src/modules/_Crypto/idea.c foreign_ident
+/src/modules/_Crypto/md2.c foreign_ident
+/src/modules/_Crypto/md5.c foreign_ident
+/src/modules/_Crypto/md5.pike foreign_ident
diff --git a/src/modules/_Crypto/Makefile b/src/modules/_Crypto/Makefile
new file mode 100644
index 0000000000..fb6315a8c2
--- /dev/null
+++ b/src/modules/_Crypto/Makefile
@@ -0,0 +1,32 @@
+# The compiler
+CC=gcc
+
+# You need the pike source somewhere
+PIKESRCDIR=../pike/src
+
+# And you need a dir where Pike was compiled (might be same as sourcedir)
+PIKEBUILDDIR=../pike/build/sol2.5
+
+# The SSLeay root is here
+SSLROOT=/usr/local/ssl/
+
+# Include search path
+IFLAGS=-I$(PIKESRCDIR) -I$(PIKEBUILDDIR) -I$(SSLROOT)/include
+
+# Additional C preprocessor flags
+CPPFLAGS=
+
+# The flags to generate a shared library
+CFLAGS=-Wall -O -shared -fpic $(IFLAGS) $(CPPFLAGS) -pedantic -Wall
+
+LDFLAGS=-shared -fpic -R$(SSLROOT)/lib -L$(SSLROOT)/lib
+LOADLIBES=-lcrypto -lssl
+
+OBJS=crypto.o md5.o md2.o idea.o des.o
+
+# The actual rules
+
+crypto.so: $(OBJS)
+	$(CC) $(LDFLAGS) $^ -o crypto.so $(LOADLIBES)
+
+$(OBJS) : precompiled_crypto.h
diff --git a/src/modules/_Crypto/crypto.c b/src/modules/_Crypto/crypto.c
new file mode 100644
index 0000000000..6735237ed4
--- /dev/null
+++ b/src/modules/_Crypto/crypto.c
@@ -0,0 +1,178 @@
+/*
+ * $Id: crypto.c,v 1.1.1.1 1996/11/05 15:10:09 grubba Exp $
+ *
+ * A pike module for getting access to some common cryptos.
+ *
+ * Henrik Grubbström 1996-10-24
+ */
+
+/*
+ * Includes
+ */
+
+/* From the Pike distribution */
+#include "global.h"
+#include "stralloc.h"
+#include "interpret.h"
+#include "svalue.h"
+#include "constants.h"
+#include "macros.h"
+#include "threads.h"
+#include "object.h"
+#include "stralloc.h"
+#include "interpret.h"
+#include "builtin_functions.h"
+
+/* System includes */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* Module specific includes */
+#include "precompiled_crypto.h"
+
+/*
+ * Globals
+ */
+
+/*
+ * Functions
+ */
+
+/*
+ * efuns and the like
+ */
+
+/* string string_to_hex(string) */
+static void f_string_to_hex(INT32 args)
+{
+  char *buffer;
+  int i;
+
+  if (args != 1) {
+    error("Wrong number of arguments to string_to_hex()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to string_to_hex()\n");
+  }
+
+  if (!(buffer=alloca(sp[-1].u.string->len*2))) {
+    error("string_to_hex(): Out of memory\n");
+  }
+  
+  for (i=0; i<sp[-1].u.string->len; i++) {
+    sprintf(buffer + i*2, "%02x", sp[-1].u.string->str[i] & 0xff);
+  }
+  
+  pop_n_elems(args);
+  
+  push_string(make_shared_binary_string(buffer, i*2));
+  sp[-1].u.string->refs++;
+}
+
+/* string hex_to_string(string) */
+static void f_hex_to_string(INT32 args)
+{
+  char *buffer;
+  int i;
+
+  if (args != 1) {
+    error("Wrong number of arguments to hex_to_string()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to hex_to_string()\n");
+  }
+  if (sp[-1].u.string->len & 1) {
+    error("Bad string length to hex_to_string()\n");
+  }
+  if (!(buffer = alloca(sp[-1].u.string->len/2))) {
+    error("hex_to_string(): Out of memory\n");
+  }
+  for (i=0; i*2<sp[-1].u.string->len; i++) {
+    switch (sp[-1].u.string->str[i*2]) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      buffer[i] = (sp[-1].u.string->str[i*2] - '0')<<4;
+      break;
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      buffer[i] = (sp[-1].u.string->str[i*2] + 10 - 'A')<<4;
+      break;
+    default:
+      error("hex_to_string(): Illegal character (0x%02x) in string\n",
+	    sp[-1].u.string->str[i*2] & 0xff);
+    }
+    switch (sp[-1].u.string->str[i*2+1]) {
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      buffer[i] |= sp[-1].u.string->str[i*2+1] - '0';
+      break;
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      buffer[i] |= (sp[-1].u.string->str[i*2+1] + 10 - 'A') & 0x0f;
+      break;
+    default:
+      error("hex_to_string(): Illegal character (0x%02x) in string\n",
+	    sp[-1].u.string->str[i*2+1] & 0xff);
+    }
+  }
+
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string(buffer, i));
+  sp[-1].u.string->refs++;
+}
+
+/*
+ * Module linkage
+ */
+
+void init_module_efuns(void)
+{
+  /* add_efun()s */
+
+  add_efun("string_to_hex", f_string_to_hex, "function(string:string)", OPT_TRY_OPTIMIZE);
+  add_efun("hex_to_string", f_hex_to_string, "function(string:string)", OPT_TRY_OPTIMIZE);
+
+  init_md2_efuns();
+  init_md5_efuns();
+  init_idea_efuns();
+  init_des_efuns();
+}
+
+void init_module_programs(void)
+{
+  /*
+   * start_new_program();
+   *
+   * add_storage();
+   *
+   * add_function();
+   * add_function();
+   * ...
+   *
+   * set_init_callback();
+   * set_exit_callback();
+   *
+   * program = end_c_program();
+   * program->refs++;
+   *
+   */
+  init_md2_programs();
+  init_md5_programs();
+  init_idea_programs();
+  init_des_programs();
+}
+
+void exit_module(void)
+{
+  /* free_program()s */
+  exit_md2();
+  exit_md5();
+  exit_idea();
+  exit_des();
+}
diff --git a/src/modules/_Crypto/crypto.h b/src/modules/_Crypto/crypto.h
new file mode 100644
index 0000000000..2c61d25e87
--- /dev/null
+++ b/src/modules/_Crypto/crypto.h
@@ -0,0 +1,14 @@
+/*
+ * $Id: crypto.h,v 1.1.1.1 1996/11/05 15:10:09 grubba Exp $
+ *
+ * The Pike crypto module
+ *
+ * Henrik Grubbström 1996-10-24
+ *
+ * This module provides the Pike interface to libcrypto.so.
+ *
+ * NOTE:
+ *	If the crypto module was compiled as a dynamic module (the default),
+ *	you MUST include this file to get it loaded.
+ */
+
diff --git a/src/modules/_Crypto/crypto.pre.pike b/src/modules/_Crypto/crypto.pre.pike
new file mode 100644
index 0000000000..824903cd69
--- /dev/null
+++ b/src/modules/_Crypto/crypto.pre.pike
@@ -0,0 +1,6 @@
+void create()
+{
+  if (!load_module("./crypto.so")) {
+    werror("Could't load module \"./crypto.so\"\n");
+  }
+}
diff --git a/src/modules/_Crypto/des.c b/src/modules/_Crypto/des.c
new file mode 100644
index 0000000000..85bfb95139
--- /dev/null
+++ b/src/modules/_Crypto/des.c
@@ -0,0 +1,382 @@
+/*
+ * $Id: des.c,v 1.1.1.1 1996/11/05 15:10:09 grubba Exp $
+ *
+ * A pike module for getting access to some common cryptos.
+ *
+ * /precompiled/crypto/des
+ *
+ * Henrik Grubbström 1996-10-24
+ */
+
+/*
+ * Includes
+ */
+
+/* From the Pike distribution */
+#include "global.h"
+#include "stralloc.h"
+#include "interpret.h"
+#include "svalue.h"
+#include "constants.h"
+#include "macros.h"
+#include "threads.h"
+#include "object.h"
+#include "stralloc.h"
+#include "builtin_functions.h"
+
+/* System includes */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* SSL includes */
+#include <des.h>
+
+/* Module specific includes */
+#include "precompiled_crypto.h"
+
+/*
+ * Globals
+ */
+
+struct program *pike_des_program;
+
+/*
+ * Functions
+ */
+
+static void print_hex(const char *str, int len)
+{
+  static char buffer[4096];
+  int i;
+
+  for (i=0; i<len; i++) {
+    sprintf(buffer+i*2, "%02x", str[i] & 0xff);
+  }
+  write(2, buffer, strlen(buffer));
+}
+
+
+static void init_pike_des(struct object *o)
+{
+  memset(PIKE_DES, 0, sizeof(struct pike_des));
+}
+
+static void exit_pike_des(struct object *o)
+{
+  memset(PIKE_DES, 0, sizeof(struct pike_des));
+}
+
+/*
+ * efuns and the like
+ */
+
+/* void set_key(string) */
+static void f_set_key(INT32 args)
+{
+  if (args != 1) {
+    error("Wrong number of arguments to des->set_key()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to des->set_key()\n");
+  }
+  if ((sp[-1].u.string->len != 8) &&
+      (sp[-1].u.string->len != 16)) {
+    error("des->set_key(): Unsupported key length %d\n",
+	  sp[-1].u.string->len);
+  }
+  if ((PIKE_DES->flags3 = (sp[-1].u.string->len == 16))) {
+    des_set_key((C_Block *)(sp[-1].u.string->str + 8),
+		PIKE_DES->key_schedules[1]);
+  }
+  des_set_key((C_Block *)(sp[-1].u.string->str),
+	      PIKE_DES->key_schedules[0]);
+
+  pop_n_elems(args);
+}
+
+/* string get_schedule(void) */
+static void f_get_schedule(INT32 args)
+{
+  if (args) {
+    error("Too many arguments to des->get_schedule()\n");
+  }
+  push_string(make_shared_binary_string((const char *)&(PIKE_DES->key_schedules[0]),
+					sizeof(PIKE_DES->key_schedules)));
+  sp[-1].u.string->refs++;
+}
+
+/* string make_key(string) */
+static void f_make_key(INT32 args)
+{
+  des_cblock buffer[2];
+
+  if (args != 1) {
+    error("Wrong number of arguments to des->make_key()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to des->make_key()\n");
+  }
+  write(2, "rawkey:", 7);
+  write(2, sp[-1].u.string->str, sp[-1].u.string->len);
+  write(2, "\n", 1);
+  des_string_to_2keys(sp[-1].u.string->str, &buffer[0], &buffer[1]);
+  des_set_key(&buffer[1], &PIKE_DES->key_schedules[1]);
+
+  write(2, "key:", 4);
+  print_hex(buffer, sizeof(buffer));
+  write(2, "\n", 1);
+
+  if (strlen(sp[-1].u.string->str) != sp[-1].u.string->len) {
+    write(2, "FOOBAR!\n", 8);
+  }
+
+  if (sp[-1].u.string->len > 8) {
+    pop_n_elems(args);
+
+    push_string(make_shared_binary_string((const char *)&(buffer[0][0]), 16));
+  } else {
+    pop_n_elems(args);
+
+    push_string(make_shared_binary_string((const char *)&(buffer[0][0]), 8));
+  }
+  sp[-1].u.string->refs++;
+
+  memset(buffer, 0, sizeof(buffer));
+}
+
+/* string make_sun_key(string) */
+static void f_make_sun_key(INT32 args)
+{
+  des_cblock key;
+  int i;
+
+  if (args != 1) {
+    error("Wrong number of arguments to des->make_sun_key()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to des->make_sun_key()\n");
+  }
+  if (sp[-1].u.string->len < 8) {
+    error("Too short key to des->make_sun_key()\n");
+  }
+  for (i=0; i<8; i++) {
+    int parity;
+    unsigned byte;
+    /* Calculate parity
+     *
+     * SSLeay bug:
+     *	SSLeay has bit #7 is in the parity, but for a key
+     *	to be legal it must have odd parity, so...
+     */
+    for ((byte = sp[-1].u.string->str[i] & 0x7f), parity=1; byte; byte >>= 1) {
+      parity ^= byte & 1;
+    }
+    key[i] = (sp[-1].u.string->str[i] & 0x7f) | (parity<<7);
+  }
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string((const char *)key, 8));
+  sp[-1].u.string->refs++;
+
+  memset(key, 0, 8);
+}
+
+/* void sum(string) */
+static void f_sum(INT32 args)
+{
+  unsigned char *buffer;
+  unsigned newlen;
+
+  if (args != 1) {
+    error("Wrong number of arguments to des->sum()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to des->sum()\n");
+  }
+  if (!(buffer = alloca(sp[-1].u.string->len + 8))) {
+    error("des->sum(): Out of memory\n");
+  }
+  if ((newlen = PIKE_DES->overflow_len)) {
+    memcpy(buffer, PIKE_DES->overflow, newlen);
+  }
+  memcpy(buffer + newlen, sp[-1].u.string->str, sp[-1].u.string->len);
+  newlen += sp[-1].u.string->len;
+
+  if ((PIKE_DES->overflow_len = newlen & 0x07)) {
+    memcpy(PIKE_DES->overflow, buffer + (newlen & ~0x07), newlen & 0x07);
+  }
+
+  /* NOTE: Need to sum the last part at the end */
+  des_cbc_cksum((C_Block *)buffer, &PIKE_DES->checksum,
+		newlen & ~0x07, PIKE_DES->key_schedules[0],
+		&PIKE_DES->checksum);
+  
+  memset(buffer, 0, newlen);
+
+  pop_n_elems(args);
+}
+
+/* DDDDDDDDDDxxxxx(actual%8) */
+
+/* string encrypt(string) */
+static void f_encrypt(INT32 args)
+{
+  unsigned char *buffer;
+  unsigned len;
+
+  if (args != 1) {
+    error("Wrong number of arguments to des->encrypt()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to des->encrypt()\n");
+  }
+  if ((len = sp[-1].u.string->len) & 0x07) {
+    error("Bad string length in des->encrypt()\n");
+  }
+  if (!(buffer = alloca(len))) {
+    error("des->encrypt(): Out of memory\n");
+  }
+
+  if (PIKE_DES->flags3) {
+    write(2, "Mode:3\n", 7);
+
+    des_3cbc_encrypt((C_Block *)sp[-1].u.string->str, (C_Block *)buffer, len,
+		     &(PIKE_DES->key_schedules[0][0]),
+		     &(PIKE_DES->key_schedules[1][0]),
+		     &PIKE_DES->ivs[0], &PIKE_DES->ivs[1], DES_ENCRYPT);
+  } else {
+    write(2, "Mode:0\n", 7);
+
+    des_cbc_encrypt((C_Block *)sp[-1].u.string->str, (C_Block *)buffer, len,
+		    &(PIKE_DES->key_schedules[0][0]),
+		    &PIKE_DES->ivs[0], DES_ENCRYPT);
+    if (len > 8) {
+      /* This seems unmotivated */
+      memcpy(&PIKE_DES->ivs[0], buffer + len - 8, 8);
+    }
+  }
+
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string((const char *)buffer, len));
+  sp[-1].u.string->refs++;
+  
+  memset(buffer, 0, len);
+}
+
+/* string decrypt(string) */
+static void f_decrypt(INT32 args)
+{
+  unsigned char *buffer;
+  unsigned len;
+
+  if (args != 1) {
+    error("Wrong number of arguments to des->decrypt()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to des->decrypt()\n");
+  }
+  if ((len = sp[-1].u.string->len) & 0x07) {
+    error("Bad string length in des->decrypt()\n");
+  }
+  if (!(buffer = alloca(len))) {
+    error("des->decrypt(): Out of memory\n");
+  }
+
+  if (PIKE_DES->flags3) {
+    write(2, "Mode:3\n", 7);
+
+    des_3cbc_encrypt((C_Block *)sp[-1].u.string->str, (C_Block *)buffer, len,
+		     &(PIKE_DES->key_schedules[0][0]),
+		     &(PIKE_DES->key_schedules[1][0]),
+		     &(PIKE_DES->ivs[0]), &(PIKE_DES->ivs[1]), DES_DECRYPT);
+  } else {
+    write(2, "Mode:0\n", 7);
+
+    des_cbc_encrypt((C_Block *)sp[-1].u.string->str, (C_Block *)buffer, len,
+		    &(PIKE_DES->key_schedules[0][0]),
+		    &(PIKE_DES->ivs[0]), DES_DECRYPT);
+    if (len > 8) {
+      /* This seems unmotivated */
+      memcpy(buffer + len - 8, &PIKE_DES->ivs[0], 8);
+    }
+  }
+
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string((const char *)buffer, len));
+  sp[-1].u.string->refs++;
+  
+  memset(buffer, 0, len);
+}
+
+/* string dump(void) */
+static void f_dump(INT32 args)
+{
+  if (args) {
+    error("Too many arguemnts to des->dump()\n");
+  }
+  push_string(make_shared_binary_string(PIKE_DES, sizeof(struct pike_des)));
+  sp[-1].u.string->refs++;
+}
+
+
+/*
+ * Module linkage
+ */
+
+void init_des_efuns(void)
+{
+  /* add_efun()s */
+}
+
+void init_des_programs(void)
+{
+  /*
+   * start_new_program();
+   *
+   * add_storage();
+   *
+   * add_function();
+   * add_function();
+   * ...
+   *
+   * set_init_callback();
+   * set_exit_callback();
+   *
+   * program = end_c_program();
+   * program->refs++;
+   *
+   */
+
+  /* /precompiled/crypto/des */
+  start_new_program();
+  add_storage(sizeof(struct pike_des));
+
+  add_function("set_key", f_set_key, "function(string:void)", OPT_SIDE_EFFECT);
+  add_function("get_schedule", f_get_schedule, "function(void:string)", OPT_EXTERNAL_DEPEND);
+  add_function("make_key", f_make_key, "function(string:string)", OPT_TRY_OPTIMIZE);
+  add_function("make_sun_key", f_make_sun_key, "function(string:string)", OPT_TRY_OPTIMIZE);
+  add_function("encrypt", f_encrypt, "function(string:string)", OPT_SIDE_EFFECT);
+  add_function("decrypt", f_decrypt, "function(string:string)", OPT_SIDE_EFFECT);
+  add_function("sum", f_sum, "function(string:void)", OPT_SIDE_EFFECT);
+
+  add_function("dump", f_dump, "function(void:string)", OPT_EXTERNAL_DEPEND);
+
+  set_init_callback(init_pike_des);
+  set_exit_callback(exit_pike_des);
+
+  pike_des_program = end_c_program("/precompiled/crypto/des");
+  pike_des_program->refs++;
+}
+
+void exit_des(void)
+{
+  /* free_program()s */
+  free_program(pike_des_program);
+}
diff --git a/src/modules/_Crypto/des.pike b/src/modules/_Crypto/des.pike
new file mode 100755
index 0000000000..956662031d
--- /dev/null
+++ b/src/modules/_Crypto/des.pike
@@ -0,0 +1,133 @@
+#!/home/grubba/src/pike/build/sol2.5/pike
+/*
+ * $Id: des.pike,v 1.1.1.1 1996/11/05 15:10:10 grubba Exp $
+ *
+ * An equvivalent for /usr/local/ssl/bin/des written in Pike
+ *
+ * Henrik Grubbström 1996-10-25
+ */
+
+/*
+ * Includes
+ */
+
+#include <stdio.h>
+
+#include "crypto.h"
+
+/*
+ * Functions
+ */
+
+int main(int argc, string *argv)
+{
+  int encrypt = 1;
+  int sunos = 0;
+  int hexkey = 0;
+  int i;
+  object des_object = clone((program)"/precompiled/crypto/des");
+  object input = clone((program)"/precompiled/file", "stdin");
+  object output = clone((program)"/precompiled/file", "stdout");
+  string data = "";
+  string outstr = "";
+
+  for (i=1; i < argc; i++) {
+    switch(argv[i]) {
+    case "-e":
+      sunos = 1;
+      /* FALLTHROUGH */
+    case "-E":
+      encrypt = 1;
+      break;
+    case "-d":
+      sunos=1;
+      /* FALLTHROUGH */
+    case "-D":
+      encrypt=0;
+      break;
+    case "-k":
+      if (hexkey) {
+	des_object->set_key(hex_to_string(argv[i+1]));
+      } else if (sunos) {
+	des_object->set_key(des_object->make_sun_key(argv[i+1]));
+      } else {
+	string tmp = des_object->make_key(argv[i+1]);
+	werror(sprintf("rawkey:%s\nkey:%s\n", argv[i+1],
+		       string_to_hex(tmp)));
+	des_object->set_key(tmp);
+	werror(sprintf("schedule:%s\n",
+		       string_to_hex(des_object->get_schedule())));
+      }
+      i++;
+      break;
+    case "-h":
+      hexkey = 1;
+      break;
+    default:
+      if (argv[i][0] == "-"[0]) {
+	werror("Unknown argument \""+argv[i]+"\"\n");
+	exit(1);
+      }
+      input->open(argv[i], "r");
+    }
+  }
+  
+  while (1) {
+    string newdata = input->read(1000000);
+
+    werror("State:"+string_to_hex(des_object->dump())+"\n");
+
+    if (stringp(newdata) && sizeof(newdata)) {
+      int len;
+
+      data += newdata;
+
+      /* Make blocks */
+      len = sizeof(data) & ~0x07;
+
+      if (len) {
+	if (encrypt) {
+perror("foo\n");
+	  output->write(des_object->encrypt(data[0..len-1]));
+perror("foo\n");
+	} else {
+	  output->write(outstr);
+	  outstr = des_object->decrypt(data[0..len-1]);
+	}
+	data = data[len..];
+      }
+    } else {
+      if (encrypt) {
+	int len = sizeof(data);
+	
+	data += sprintf("%@c",
+			({ random(256), random(256), random(256), random(256),
+			   random(256), random(256), random(256), len })[len..]);
+	output->write(des_object->encrypt(data));
+      } else {
+	if ((sizeof(data))||(outstr[-1] & ~0x07)) {
+	  werror("Data didn't decrypt correctly\n");
+	  destruct(des_object);
+	  exit(1);
+	} else {
+	  int len = ((sizeof(outstr) & ~0x07) | outstr[-1]) - 8;
+
+	  if ((len > sizeof(outstr)) || (len < 1)) {
+	    werror("Data didn't decrypt correctly\n");
+	    werror(sprintf("len:%d, %d\n", sizeof(outstr), len));
+	    destruct(des_object);
+	    exit(1);
+	  } else {
+	    output->write(outstr[0..len-1]);
+	  }
+	}
+      }
+      break;
+    }
+  }
+
+  destruct(des_object);
+  input->close();
+
+  return(0);
+}
diff --git a/src/modules/_Crypto/idea.c b/src/modules/_Crypto/idea.c
new file mode 100644
index 0000000000..3c808d4d74
--- /dev/null
+++ b/src/modules/_Crypto/idea.c
@@ -0,0 +1,252 @@
+/*
+ * $Id: idea.c,v 1.1.1.1 1996/11/05 15:10:09 grubba Exp $
+ *
+ * IDEA crypto module for Pike
+ *
+ * /precompiled/crypto/idea
+ *
+ * Henrik Grubbström 1996-11-03
+ */
+
+/*
+ * Includes
+ */
+
+/* From the Pike distribution */
+#include "global.h"
+#include "stralloc.h"
+#include "interpret.h"
+#include "svalue.h"
+#include "constants.h"
+#include "macros.h"
+#include "threads.h"
+#include "object.h"
+#include "stralloc.h"
+#include "builtin_functions.h"
+
+/* System includes */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* SSL includes */
+#include <idea.h>
+
+/* Module specific includes */
+#include "precompiled_crypto.h"
+
+/*
+ * Globals
+ */
+
+struct program *pike_idea_program;
+
+/*
+ * Functions
+ */
+
+void init_pike_idea(struct object *o)
+{
+  MEMSET(PIKE_IDEA, 0, sizeof(struct pike_idea));
+}
+
+void exit_pike_idea(struct object *o)
+{
+  MEMSET(PIKE_IDEA, 0, sizeof(struct pike_idea));
+}
+
+/*
+ * efuns and the like
+ */
+
+/* void set_key(string) */
+static void f_set_key(INT32 args)
+{
+  if (args != 1) {
+    error("Wrong number of args to idea->set_key()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to idea->set_key()\n");
+  }
+  if (sp[-1].u.string->len < 16) {
+    error("idea->set_key(): Too short key\n");
+  }
+  idea_set_encrypt_key((unsigned char *)sp[-1].u.string->str,
+		       &(PIKE_IDEA->e_key));
+  idea_set_decrypt_key(&(PIKE_IDEA->e_key), &(PIKE_IDEA->d_key));
+
+  MEMCPY(&(PIKE_IDEA->key), sp[-1].u.string->str, 8);
+
+  pop_n_elems(args);
+}
+
+/* string encrypt(string) */
+static void f_encrypt(INT32 args)
+{
+  unsigned char buffer[8];
+
+  if (args != 1) {
+    error("Wrong number of arguemnts to idea->encrypt()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to idea->encrypt()\n");
+  }
+  if (sp[-1].u.string->len != 8) {
+    error("Bad length of argument 1 to idea->encrypt()\n");
+  }
+
+  idea_ecb_encrypt((unsigned char *)sp[-1].u.string->str, buffer,
+		   &(PIKE_IDEA->e_key));
+
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string((const char *)buffer, 8));
+
+  MEMSET(buffer, 0, 8);
+}
+
+/* string decrypt(string) */
+static void f_decrypt(INT32 args)
+{
+  unsigned char buffer[8];
+
+  if (args != 1) {
+    error("Wrong number of arguemnts to idea->decrypt()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to idea->decrypt()\n");
+  }
+  if (sp[-1].u.string->len != 8) {
+    error("Bad length of argument 1 to idea->decrypt()\n");
+  }
+
+  idea_ecb_encrypt((unsigned char *)sp[-1].u.string->str, buffer,
+		   &(PIKE_IDEA->e_key));
+
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string((const char *)buffer, 8));
+
+  MEMSET(buffer, 0, 8);
+}
+
+/* string cbc_encrypt(string) */
+static void f_cbc_encrypt(INT32 args)
+{
+  unsigned char *buffer;
+  unsigned char iv[8];
+  int len;
+
+  if (args != 1) {
+    error("Wrong number of arguments to idea->cbc_encrypt()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to idea->cbc_encrypt()\n");
+  }
+  
+  len = (sp[-1].u.string->len + 7) & ~7;
+
+  if (!(buffer = alloca(len))) {
+    error("Out of memory\n");
+  }
+
+  MEMCPY(iv, &(PIKE_IDEA->key), 8);
+
+  idea_cbc_encrypt((unsigned char *)sp[-1].u.string->str, buffer,
+		   sp[-1].u.string->len,
+		   &(PIKE_IDEA->e_key), iv, IDEA_ENCRYPT);
+
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string((const char *)buffer, len));
+
+  MEMSET(buffer, 0, len);
+}
+
+/* string cbc_decrypt(string) */
+static void f_cbc_decrypt(INT32 args)
+{
+  unsigned char *buffer;
+  unsigned char iv[8];
+  int len;
+
+  if (args != 1) {
+    error("Wrong number of arguments to idea->cbc_decrypt()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to idea->cbc_decrypt()\n");
+  }
+  
+  len = (sp[-1].u.string->len + 7) & ~7;
+
+  if (!(buffer = alloca(len))) {
+    error("Out of memory\n");
+  }
+
+  MEMCPY(iv, &(PIKE_IDEA->key), 8);
+
+  idea_cbc_encrypt((unsigned char *)sp[-1].u.string->str, buffer,
+		   sp[-1].u.string->len,
+		   &(PIKE_IDEA->d_key), iv, IDEA_DECRYPT);
+
+  pop_n_elems(args);
+
+  push_string(make_shared_binary_string((const char *)buffer, len));
+
+  MEMSET(buffer, 0, len);
+}
+
+/*
+ * Module linkage
+ */
+
+void init_idea_efuns(void)
+{
+  /* add_efun()s */
+}
+
+void init_idea_programs(void)
+{
+  /*
+   * start_new_program();
+   *
+   * add_storage();
+   *
+   * add_function();
+   * add_function();
+   * ...
+   *
+   * set_init_callback();
+   * set_exit_callback();
+   *
+   * program = end_c_program();
+   * program->refs++;
+   *
+   */
+
+  /* /precompiled/crypto/idea */
+  start_new_program();
+  add_storage(sizeof(struct pike_idea));
+
+  add_function("set_key", f_set_key, "function(string:void)", OPT_SIDE_EFFECT);
+  add_function("encrypt", f_encrypt, "function(string:string)", OPT_SIDE_EFFECT);
+  add_function("decrypt", f_decrypt, "function(string:string)", OPT_SIDE_EFFECT);
+  add_function("cbc_encrypt", f_cbc_encrypt, "function(string:string)", OPT_SIDE_EFFECT);
+  add_function("cbc_decrypt", f_cbc_decrypt, "function(string:string)", OPT_SIDE_EFFECT);
+
+  set_init_callback(init_pike_idea);
+  set_exit_callback(exit_pike_idea);
+
+  pike_idea_program = end_c_program("/precompiled/crypto/idea");
+  pike_idea_program->refs++;
+}
+
+void exit_idea(void)
+{
+  /* free_program()s */
+  free_program(pike_idea_program);
+}
diff --git a/src/modules/_Crypto/md2.c b/src/modules/_Crypto/md2.c
new file mode 100644
index 0000000000..bc017e8e06
--- /dev/null
+++ b/src/modules/_Crypto/md2.c
@@ -0,0 +1,176 @@
+/*
+ * $Id: md2.c,v 1.1.1.1 1996/11/05 15:10:09 grubba Exp $
+ *
+ * A pike module for getting access to some common cryptos.
+ *
+ * /precompiled/crypto/md2
+ *
+ * Henrik Grubbström 1996-10-24
+ */
+
+/*
+ * Includes
+ */
+
+/* From the Pike distribution */
+#include "global.h"
+#include "stralloc.h"
+#include "interpret.h"
+#include "svalue.h"
+#include "constants.h"
+#include "macros.h"
+#include "threads.h"
+#include "object.h"
+#include "stralloc.h"
+#include "builtin_functions.h"
+
+/* System includes */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* SSL includes */
+#include <md2.h>
+
+/* Module specific includes */
+#include "precompiled_crypto.h"
+
+/*
+ * Globals
+ */
+
+struct program *pike_md2_program;
+
+/*
+ * Functions
+ */
+
+static void init_pike_md2(struct object *o)
+{
+  MD2_Init(&(PIKE_MD2->ctx));
+  PIKE_MD2->string = NULL;
+}
+
+static void exit_pike_md2(struct object *o)
+{
+  if (!PIKE_MD2->string) {
+    MD2_Final(PIKE_MD2->checksum, &(PIKE_MD2->ctx));
+  } else {
+    free_string(PIKE_MD2->string);
+    PIKE_MD2->string = NULL;
+  }
+}
+
+/*
+ * efuns and the like
+ */
+
+/* void push(string) */
+static void f_push(INT32 args)
+{
+  if (args != 1) {
+    error("Wrong number of arguments to push()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to push()\n");
+  }
+  if (!PIKE_MD2->string) {
+    MD2_CTX *c = &(PIKE_MD2->ctx);
+
+    MD2_Update(c,
+	       (unsigned char *)sp[-1].u.string->str,
+	       (unsigned long)sp[-1].u.string->len);
+  } else {
+    error("md2->push(): Object not active\n");
+  }
+
+  pop_n_elems(args);
+}
+
+/* string cast_to_string(void) */
+static void f_cast_to_string(INT32 args)
+{
+  if (args) {
+    error("Too many arguments to md2->cast_to_string()\n");
+  }
+  if (!PIKE_MD2->string) {
+    MD2_Final(PIKE_MD2->checksum, &(PIKE_MD2->ctx));
+
+    PIKE_MD2->string = make_shared_binary_string((char *)PIKE_MD2->checksum,
+						 MD2_DIGEST_LENGTH);
+    PIKE_MD2->string->refs++;
+  }
+
+  push_string(PIKE_MD2->string);
+  PIKE_MD2->string->refs++;
+}
+
+/* mixed cast(string) */
+static void f_cast(INT32 args)
+{
+  if (args != 1) {
+    error("Wrong number of arguments to md2->cast()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad arguemnt 1 to md2->cast()\n");
+  }
+  if (strcmp(sp[-1].u.string->str, "string")) {
+    error("md2->cast(): Only casts to string supported.\n");
+  }
+  pop_n_elems(args);
+
+  f_cast_to_string(0);
+}
+
+/*
+ * Module linkage
+ */
+
+void init_md2_efuns(void)
+{
+  /* add_efun()s */
+}
+
+void init_md2_programs(void)
+{
+  /*
+   * start_new_program();
+   *
+   * add_storage();
+   *
+   * add_function();
+   * add_function();
+   * ...
+   *
+   * set_init_callback();
+   * set_exit_callback();
+   *
+   * program = end_c_program();
+   * program->refs++;
+   *
+   */
+
+  /* /precompiled/crypto/md2 */
+  start_new_program();
+  add_storage(sizeof(struct pike_md2));
+
+  add_function("push", f_push, "function(string:void)", OPT_SIDE_EFFECT);
+  add_function("cast", f_cast, "function(string:mixed)", OPT_EXTERNAL_DEPEND);
+  add_function("cast_to_string", f_cast_to_string, "function(void:string)", OPT_EXTERNAL_DEPEND);
+
+  set_init_callback(init_pike_md2);
+  set_exit_callback(exit_pike_md2);
+
+  pike_md2_program = end_c_program("/precompiled/crypto/md2");
+  pike_md2_program->refs++;
+}
+
+void exit_md2(void)
+{
+  /* free_program()s */
+  free_program(pike_md2_program);
+}
diff --git a/src/modules/_Crypto/md5.c b/src/modules/_Crypto/md5.c
new file mode 100644
index 0000000000..89ba7ab4bb
--- /dev/null
+++ b/src/modules/_Crypto/md5.c
@@ -0,0 +1,176 @@
+/*
+ * $Id: md5.c,v 1.1.1.1 1996/11/05 15:10:09 grubba Exp $
+ *
+ * A pike module for getting access to some common cryptos.
+ *
+ * /precompiled/crypto/md5
+ *
+ * Henrik Grubbström 1996-10-24
+ */
+
+/*
+ * Includes
+ */
+
+/* From the Pike distribution */
+#include "global.h"
+#include "stralloc.h"
+#include "interpret.h"
+#include "svalue.h"
+#include "constants.h"
+#include "macros.h"
+#include "threads.h"
+#include "object.h"
+#include "stralloc.h"
+#include "builtin_functions.h"
+
+/* System includes */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* SSL includes */
+#include <md5.h>
+
+/* Module specific includes */
+#include "precompiled_crypto.h"
+
+/*
+ * Globals
+ */
+
+struct program *pike_md5_program;
+
+/*
+ * Functions
+ */
+
+static void init_pike_md5(struct object *o)
+{
+  MD5_Init(&(PIKE_MD5->ctx));
+  PIKE_MD5->string = NULL;
+}
+
+static void exit_pike_md5(struct object *o)
+{
+  if (!PIKE_MD5->string) {
+    MD5_Final(PIKE_MD5->checksum, &(PIKE_MD5->ctx));
+  } else {
+    free_string(PIKE_MD5->string);
+    PIKE_MD5->string = NULL;
+  }
+}
+
+/*
+ * efuns and the like
+ */
+
+/* void push(string) */
+static void f_push(INT32 args)
+{
+  if (args != 1) {
+    error("Wrong number of arguments to push()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad argument 1 to push()\n");
+  }
+  if (!PIKE_MD5->string) {
+    MD5_CTX *c = &(PIKE_MD5->ctx);
+
+    MD5_Update(c,
+	       (unsigned char *)sp[-1].u.string->str,
+	       (unsigned long)sp[-1].u.string->len);
+  } else {
+    error("md5->push(): Object not active\n");
+  }
+
+  pop_n_elems(args);
+}
+
+/* string cast_to_string(void) */
+static void f_cast_to_string(INT32 args)
+{
+  if (args) {
+    error("Too many arguments to md5->cast_to_string()\n");
+  }
+  if (!PIKE_MD5->string) {
+    MD5_Final(PIKE_MD5->checksum, &(PIKE_MD5->ctx));
+
+    PIKE_MD5->string = make_shared_binary_string((char *)PIKE_MD5->checksum,
+						 MD5_DIGEST_LENGTH);
+    PIKE_MD5->string->refs++;
+  }
+
+  push_string(PIKE_MD5->string);
+  PIKE_MD5->string->refs++;
+}
+
+/* mixed cast(string) */
+static void f_cast(INT32 args)
+{
+  if (args != 1) {
+    error("Wrong number of arguments to md5->cast()\n");
+  }
+  if (sp[-1].type != T_STRING) {
+    error("Bad arguemnt 1 to md5->cast()\n");
+  }
+  if (strcmp(sp[-1].u.string->str, "string")) {
+    error("md5->cast(): Only casts to string supported.\n");
+  }
+  pop_n_elems(args);
+
+  f_cast_to_string(0);
+}
+
+/*
+ * Module linkage
+ */
+
+void init_md5_efuns(void)
+{
+  /* add_efun()s */
+}
+
+void init_md5_programs(void)
+{
+  /*
+   * start_new_program();
+   *
+   * add_storage();
+   *
+   * add_function();
+   * add_function();
+   * ...
+   *
+   * set_init_callback();
+   * set_exit_callback();
+   *
+   * program = end_c_program();
+   * program->refs++;
+   *
+   */
+
+  /* /precompiled/crypto/md5 */
+  start_new_program();
+  add_storage(sizeof(struct pike_md5));
+
+  add_function("push", f_push, "function(string:void)", OPT_SIDE_EFFECT);
+  add_function("cast", f_cast, "function(string:mixed)", OPT_EXTERNAL_DEPEND);
+  add_function("cast_to_string", f_cast_to_string, "function(void:string)", OPT_EXTERNAL_DEPEND);
+
+  set_init_callback(init_pike_md5);
+  set_exit_callback(exit_pike_md5);
+
+  pike_md5_program = end_c_program("/precompiled/crypto/md5");
+  pike_md5_program->refs++;
+}
+
+void exit_md5(void)
+{
+  /* free_program()s */
+  free_program(pike_md5_program);
+}
diff --git a/src/modules/_Crypto/md5.pike b/src/modules/_Crypto/md5.pike
new file mode 100755
index 0000000000..5ea8cdbc47
--- /dev/null
+++ b/src/modules/_Crypto/md5.pike
@@ -0,0 +1,69 @@
+#!/home/grubba/src/pike/build/sol2.5/pike
+/*
+ * $Id: md5.pike,v 1.1.1.1 1996/11/05 15:10:10 grubba Exp $
+ *
+ * An md5 checksummer written in Pike
+ *
+ * Henrik Grubbström 1996-10-24
+ */
+
+/*
+ * Includes
+ */
+
+#include "crypto.h"
+
+/*
+ * Functions
+ */
+
+int main(int argc, string *argv)
+{
+  object input;
+
+  input = clone((program)"/precompiled/file");
+
+  if (argc == 1) {
+  } else {
+    string filename;
+
+    foreach (argv[1..], filename) {
+      string data;
+      string foo, bar;
+      object checksum;
+      object checksum2;
+
+      checksum = clone((program)"/precompiled/crypto/md5");
+      checksum2 = clone((program)"/precompiled/crypto/md2");
+
+      input->open(filename, "rb");
+
+      while (1) {
+	data = input->read(1000000000);
+
+	if (stringp(data) && sizeof(data)) {
+	  checksum->push(data);
+	  checksum2->push(data);
+	} else {
+	  break;
+	}
+      }
+
+      input->close();
+
+      werror("MD5("+filename+")= "+string_to_hex((string)checksum)+"\n");
+      werror("MD2("+filename+")= "+string_to_hex((string)checksum2)+"\n");
+
+      foo = ((string)checksum)+((string)checksum2);
+      bar = hex_to_string(string_to_hex((string)checksum) +
+			  string_to_hex((string)checksum2));
+
+      if (foo != bar) { 
+	werror("Mismatch!\nfoo: " + string_to_hex(foo) +"\nbar: "+string_to_hex(bar)+"\n");
+      }
+
+      destruct(checksum);
+      destruct(checksum2);
+    }
+  }
+}
diff --git a/src/modules/_Crypto/precompiled_crypto.h b/src/modules/_Crypto/precompiled_crypto.h
new file mode 100644
index 0000000000..efddaa738c
--- /dev/null
+++ b/src/modules/_Crypto/precompiled_crypto.h
@@ -0,0 +1,100 @@
+/*
+ * precompiled_X.h
+ *
+ * A pike module for getting access to X11
+ *
+ * Henrik Grubbström 1996-10-15
+ */
+
+#ifndef PRECOMPILED_X_H
+#define PRECOMPILED_X_H
+
+/*
+ * Includes
+ */
+
+#include <md2.h>
+#include <md5.h>
+
+#include <idea.h>
+#include <des.h>
+
+/*
+ * Black magic
+ */
+
+#undef _
+
+/*
+ * Structures
+ */
+
+struct pike_md2 {
+  MD2_CTX ctx;
+  unsigned char checksum[MD2_DIGEST_LENGTH];
+  struct pike_string *string;
+};
+
+struct pike_md5 {
+  MD5_CTX ctx;
+  unsigned char checksum[MD5_DIGEST_LENGTH];
+  struct pike_string *string;
+};
+
+struct pike_idea {
+  unsigned char key[8];
+  IDEA_KEY_SCHEDULE e_key, d_key;
+};
+
+struct pike_des {
+  des_key_schedule key_schedules[2];
+  des_cblock ivs[2];
+  int flags3;
+  des_cblock checksum;
+  unsigned char overflow[8];
+  unsigned overflow_len;
+};
+
+/*
+ * Defines
+ */
+
+#define PIKE_MD2	((struct pike_md2 *)(fp->current_storage))
+#define PIKE_MD5	((struct pike_md5 *)(fp->current_storage))
+
+#define PIKE_IDEA	((struct pike_idea *)(fp->current_storage))
+#define PIKE_DES	((struct pike_des *)(fp->current_storage))
+
+/*
+ * Globals
+ */
+
+/*
+ * Prototypes
+ */
+
+/*
+ * Module linkage
+ */
+
+/* /precompiled/crypto/md2 */
+void init_md2_efuns(void);
+void init_md2_programs(void);
+void exit_md2(void);
+
+/* /precompiled/crypto/md5 */
+void init_md5_efuns(void);
+void init_md5_programs(void);
+void exit_md5(void);
+
+/* /precompiled/crypto/md5 */
+void init_idea_efuns(void);
+void init_idea_programs(void);
+void exit_idea(void);
+
+/* /precompiled/crypto/des */
+void init_des_efuns(void);
+void init_des_programs(void);
+void exit_des(void);
+
+#endif /* PRECOMPILED_X_H */
-- 
GitLab