From f2257563e9599c8d48277390d92240b0b05e74dc Mon Sep 17 00:00:00 2001
From: magnum <magnum>
Date: Tue, 15 Nov 2011 15:44:05 +0100
Subject: [PATCH] j8: New NSLDAP format. Based on raw-sha1 and old NSLDAP
 formats. NSLDAPS and OPENLDAPS moved to unused/ since they
 are superseded by salted-sha1

---
 src/NSLDAPS_fmt_plug.c          |  332 -------------------------------------
 src/NSLDAP_fmt_plug.c           |  285 -------------------------------
 src/OPENLDAPS_fmt_plug.c        |  330 ------------------------------------
 src/nsldap_fmt_plug.c           |  350 +++++++++++++++++++++++++++++++++++++++
 src/salted_sha1_fmt_plug.c      |   14 ++-
 src/unused/NSLDAPS_fmt_plug.c   |  332 +++++++++++++++++++++++++++++++++++++
 src/unused/NSLDAP_fmt_plug.c    |  285 +++++++++++++++++++++++++++++++
 src/unused/OPENLDAPS_fmt_plug.c |  330 ++++++++++++++++++++++++++++++++++++
 8 files changed, 1309 insertions(+), 949 deletions(-)
 delete mode 100644 src/NSLDAPS_fmt_plug.c
 delete mode 100644 src/NSLDAP_fmt_plug.c
 delete mode 100644 src/OPENLDAPS_fmt_plug.c
 create mode 100644 src/nsldap_fmt_plug.c
 create mode 100644 src/unused/NSLDAPS_fmt_plug.c
 create mode 100644 src/unused/NSLDAP_fmt_plug.c
 create mode 100644 src/unused/OPENLDAPS_fmt_plug.c

diff --git a/src/NSLDAPS_fmt_plug.c b/src/NSLDAPS_fmt_plug.c
deleted file mode 100644
index 9c545c9..0000000
--- a/src/NSLDAPS_fmt_plug.c
+++ /dev/null
@@ -1,332 +0,0 @@
-// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26.
-/*
- * Minor performance enhancement by bartavelle at bandecon.com
- */
-
-#include <string.h>
-
-#include "misc.h"
-#include "params.h"
-#include "formats.h"
-#include "common.h"
-
-#include "sha.h"
-#include "base64.h"
-
-#define FORMAT_LABEL			"ssha"
-#define FORMAT_NAME			"Netscape LDAP SSHA"
-
-#if defined(MMX_COEF) && MMX_COEF == 4
-#define ALGORITHM_NAME			"SSE2 4x"
-#elif defined(MMX_COEF) && MMX_COEF == 2
-#define ALGORITHM_NAME			"MMX 2x"
-#elif defined(MMX_COEF)
-#define ALGORITHM_NAME			"?"
-#else
-#define ALGORITHM_NAME			"32/" ARCH_BITS_STR
-#endif
-
-#define BENCHMARK_COMMENT		""
-#define BENCHMARK_LENGTH		0
-
-#define PLAINTEXT_LENGTH		32
-#define CIPHERTEXT_LENGTH		40
-
-#define BINARY_SIZE			20
-#define SALT_SIZE			8
-
-#ifdef MMX_COEF
-#define MIN_KEYS_PER_CRYPT		MMX_COEF
-#define MAX_KEYS_PER_CRYPT		MMX_COEF
-#define GETPOS(i, index)		( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) )
-#else
-#define MIN_KEYS_PER_CRYPT		1
-#define MAX_KEYS_PER_CRYPT		1
-#endif
-
-#define NSLDAP_MAGIC "{ssha}"
-#define NSLDAP_MAGIC_LENGTH 6
-
-static struct fmt_tests tests[] = {
-  {"{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==", "Password9"},
-  {"{SSHA}ypkVeJKLzbXakEpuPYbn+YBnQvFmNmB+kQhmWQ==", "qVv3uQ45"},
-  {"{SSHA}cKFVqtf358j0FGpPsEIK1xh3T0mtDNV1kAaBNg==", "salles"},
-  {"{SSHA}W3ipFGmzS3+j6/FhT7ZC39MIfqFcct9Ep0KEGA==", "asddsa123"},
-  {"{SSHA}YbB2R1D2AlzYc9wk/YPtslG7NoiOWaoMOztLHA==", "ripthispassword"},
-#if 0
-/*
- * These two were found in john-1.6-nsldaps4.diff.gz and apparently they were
- * supported by that version of they code, but they are not anymore.
- */
-  {"{SSHA}/EExmSfmhQSPHDJaTxwQSdb/uPpzYWx0ZXI=", "secret"},
-  {"{SSHA}gVK8WC9YyFT1gMsQHTGCgT3sSv5zYWx0", "secret"},
-#endif
-  {NULL}
-};
-
-#ifdef MMX_COEF
-/* Cygwin would not guarantee the alignment if these were declared static */
-#define buffer NSLDAPS_buffer
-#define crypt_key NSLDAPS_crypt_key
-#ifdef _MSC_VER
-__declspec(align(16)) unsigned char buffer[80*4*MMX_COEF];
-__declspec(align(16)) char crypt_key[BINARY_SIZE*MMX_COEF];
-#else
-unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16)));
-char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16)));
-#endif
-static char saved_key[(PLAINTEXT_LENGTH+SALT_SIZE+4+1)*MMX_COEF];
-static unsigned long total_len;
-static unsigned char out[PLAINTEXT_LENGTH + 1];
-#else
-static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4];
-static char saved_key[PLAINTEXT_LENGTH + 1];
-#endif
-
-#ifdef MMX_COEF
-static unsigned long length[MAX_KEYS_PER_CRYPT];
-#endif
-static char saved_salt[SALT_SIZE];
-
-static void * binary(char *ciphertext) {
-  static char *realcipher;
-  // align realcipher (it is the binary returned, and must be aligned for how we 'use' it later)
-  if (!realcipher) realcipher = mem_alloc_tiny(BINARY_SIZE + SALT_SIZE + 9, MEM_ALIGN_WORD);
-
-  /* stupid overflows */
-  memset(realcipher, 0, sizeof(realcipher));
-  base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
-  return (void *)realcipher;
-}
-
-static void * get_salt(char * ciphertext)
-{
-	static char realcipher[BINARY_SIZE + SALT_SIZE + 9];
-	memset(realcipher, 0, sizeof(realcipher));
-	base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
-	return (void*)&realcipher[BINARY_SIZE];
-}
-
-static int valid(char *ciphertext, struct fmt_main *pFmt)
-{
-	if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH + NSLDAP_MAGIC_LENGTH)
-		return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH);
-	return 0;
-}
-
-static int binary_hash_0(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xF;
-}
-
-static int binary_hash_1(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFF;
-}
-
-static int binary_hash_2(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFF;
-}
-
-static int binary_hash_3(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFF;
-}
-
-static int binary_hash_4(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFFF;
-}
-
-static int get_hash_0(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF;
-}
-
-static int get_hash_1(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF;
-}
-
-static int get_hash_2(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF;
-}
-
-static int get_hash_3(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFF;
-}
-
-static int get_hash_4(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFFF;
-}
-
-static int salt_hash(void *salt)
-{
-	return *((ARCH_WORD_32 *)salt) & (SALT_HASH_SIZE - 1);
-}
-
-static void set_key(char *key, int index)
-{
-#ifdef MMX_COEF
-	int len;
-	int i;
-
-	if(index==0)
-	{
-		total_len = 0;
-		memset(saved_key, 0, sizeof(saved_key));
-		memset(length, 0, sizeof(length));
-	}
-	len = strlen(key);
-	if(len>PLAINTEXT_LENGTH)
-		len = PLAINTEXT_LENGTH;
-
-	length[index] = len;
-
-	total_len += (len + SALT_SIZE) << ( ( (32/MMX_COEF) * index ) );
-	for(i=0;i<len;i++)
-		saved_key[GETPOS(i, index)] = key[i];
-
-	saved_key[GETPOS( (i+SALT_SIZE) , index)] = 0x80;
-#else
-	strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1);
-#endif
-}
-
-static void set_salt(void *salt)
-{
-	memcpy(saved_salt, salt, SALT_SIZE);
-
-}
-
-static char *get_key(int index)
-{
-#ifdef MMX_COEF
-	unsigned int i,s;
-
-	s = length[index];
-	for(i=0;i<s;i++)
-		out[i] = saved_key[ GETPOS(i, index) ];
-	out[i] = 0;
-	return (char *) out;
-#else
-  return saved_key;
-#endif
-}
-
-static int
-cmp_all(void *binary, int index)
-{
-#ifdef MMX_COEF
-	int i = 0;
-	while(i< (BINARY_SIZE/4) )
-	{
-		if (
-			( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF])
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+1])
-#if (MMX_COEF > 3)
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2])
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3])
-#endif
-		)
-			return 0;
-		i++;
-	}
-	return 1;
-#else
-	return !memcmp(binary, crypt_key, BINARY_SIZE);
-#endif
-}
-
-static int
-cmp_exact(char *source, int index)
-{
-  return 1;
-}
-
-static int cmp_one(void * binary, int index)
-{
-#ifdef MMX_COEF
-	int i = 0;
-	for(i=0;i<(BINARY_SIZE/4);i++)
-		if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] )
-			return 0;
-	return 1;
-#else
-	return cmp_all(binary, index);
-#endif
-}
-
-
-static void crypt_all(int count)
-{
-#ifdef MMX_COEF
-	int i,idx;
-
-	for(idx=0;idx<MAX_KEYS_PER_CRYPT;idx++)
-		for(i=0;i<SALT_SIZE;i++)
-		{
-			saved_key[GETPOS(i+length[idx],idx)] = ((unsigned char *)saved_salt)[i];
-		}
-
-	memcpy(buffer, saved_key, (PLAINTEXT_LENGTH+SALT_SIZE+4)*MMX_COEF);
-	shammx((unsigned char *) crypt_key, buffer, total_len);
-#else
-	static SHA_CTX ctx;
-	SHA1_Init(&ctx);
-	SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key));
-	SHA1_Update(&ctx, (unsigned char *) saved_salt, SALT_SIZE);
-	SHA1_Final((unsigned char *) crypt_key, &ctx);
-#endif
-}
-
-struct fmt_main fmt_NSLDAPS = {
-	{
-		FORMAT_LABEL,
-		FORMAT_NAME,
-		ALGORITHM_NAME,
-		BENCHMARK_COMMENT,
-		BENCHMARK_LENGTH,
-		PLAINTEXT_LENGTH,
-		BINARY_SIZE,
-		SALT_SIZE,
-		MIN_KEYS_PER_CRYPT,
-		MAX_KEYS_PER_CRYPT,
-		FMT_CASE | FMT_8_BIT,
-		tests
-	}, {
-		fmt_default_init,
-		fmt_default_prepare,
-		valid,
-		fmt_default_split,
-		binary,
-		get_salt,
-		{
-			binary_hash_0,
-			binary_hash_1,
-			binary_hash_2,
-			binary_hash_3,
-			binary_hash_4
-		},
-		salt_hash,
-		set_salt,
-		set_key,
-		get_key,
-		fmt_default_clear_keys,
-		crypt_all,
-		{
-			get_hash_0,
-			get_hash_1,
-			get_hash_2,
-			get_hash_3,
-			get_hash_4
-		},
-		cmp_all,
-		cmp_one,
-		cmp_exact
-	}
-};
diff --git a/src/NSLDAP_fmt_plug.c b/src/NSLDAP_fmt_plug.c
deleted file mode 100644
index 8579005..0000000
--- a/src/NSLDAP_fmt_plug.c
+++ /dev/null
@@ -1,285 +0,0 @@
-// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26.
-/*
- * Minor performance enhancement by bartavelle at bandecon.com
- */
-
-#include <string.h>
-
-#include "misc.h"
-#include "formats.h"
-#include "common.h"
-
-#include "sha.h"
-#include "base64.h"
-
-#define FORMAT_LABEL			"nsldap"
-#define FORMAT_NAME			"Netscape LDAP SHA"
-
-#if defined(MMX_COEF) && MMX_COEF == 4
-#define ALGORITHM_NAME			"SSE2 4x"
-#elif defined(MMX_COEF) && MMX_COEF == 2
-#define ALGORITHM_NAME			"MMX 2x"
-#elif defined(MMX_COEF)
-#define ALGORITHM_NAME			"?"
-#else
-#define ALGORITHM_NAME			"32/" ARCH_BITS_STR
-#endif
-
-#define BENCHMARK_COMMENT		""
-#define BENCHMARK_LENGTH		-1
-
-#define PLAINTEXT_LENGTH		32
-#define CIPHERTEXT_LENGTH		33
-
-#define BINARY_SIZE			20
-#define SALT_SIZE			0
-
-#ifdef MMX_COEF
-#define MIN_KEYS_PER_CRYPT		MMX_COEF
-#define MAX_KEYS_PER_CRYPT		MMX_COEF
-#define GETPOS(i, index)		( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) )
-#else
-#define MIN_KEYS_PER_CRYPT		1
-#define MAX_KEYS_PER_CRYPT		1
-#endif
-
-#define NSLDAP_MAGIC "{sha}"
-#define NSLDAP_MAGIC_LENGTH 5
-
-static struct fmt_tests tests[] = {
-  {"{SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=", "aaaa"},
-  {"{SHA}iu0TIuVFC62weOH7YKgXod8loso=", "bbbb"},
-  {"{SHA}0ijZPTcJXMa+t2XnEbEwSOkvQu0=", "ccccccccc"},
-  {"{SHA}vNR9eUfJfcKmdkLDqNoKagho+qU=", "dddddddddd"},
-  {NULL}
-};
-
-#ifdef MMX_COEF
-/* Cygwin would not guarantee the alignment if these were declared static */
-#define buffer NSLDAP_buffer
-#define crypt_key NSLDAP_crypt_key
-#ifdef _MSC_VER
-__declspec(align(16)) unsigned char buffer[80*4*MMX_COEF];
-__declspec(align(16)) char crypt_key[BINARY_SIZE*MMX_COEF];
-#else
-unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16)));
-char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16)));
-#endif
-static char saved_key[(PLAINTEXT_LENGTH+4+1)*MMX_COEF]; // we add an extra DWORD to hold the 0x80 if the password is exactly PLAINTEXT_LENGTH bytes long)
-static unsigned long total_len;
-static unsigned char out[PLAINTEXT_LENGTH + 1];
-#else
-static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4];
-static char saved_key[PLAINTEXT_LENGTH + 1];
-#endif
-
-static void *
-binary(char *ciphertext) {
-  static char realcipher[BINARY_SIZE + 9];
-
-  /* stupid overflows */
-  memset(realcipher, 0, sizeof(realcipher));
-  base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
-  return (void *)realcipher;
-}
-
-static int
-valid(char *ciphertext, struct fmt_main *pFmt)
-{
-  if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH)
-    return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH);
-  return 0;
-}
-
-static int binary_hash_0(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xF;
-}
-
-static int binary_hash_1(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFF;
-}
-
-static int binary_hash_2(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFF;
-}
-
-static int binary_hash_3(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFF;
-}
-
-static int binary_hash_4(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFFF;
-}
-
-static int get_hash_0(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF;
-}
-
-static int get_hash_1(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF;
-}
-
-static int get_hash_2(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF;
-}
-
-static int get_hash_3(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFF;
-}
-
-static int get_hash_4(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFFF;
-}
-
-static void set_key(char *key, int index)
-{
-#ifdef MMX_COEF
-	int len;
-	int i;
-
-	if(index==0)
-	{
-		total_len = 0;
-		memset(saved_key, 0, sizeof(saved_key));
-	}
-	len = strlen(key);
-	if(len>PLAINTEXT_LENGTH)
-		len = PLAINTEXT_LENGTH;
-
-	total_len += len << ( ( (32/MMX_COEF) * index ) );
-	for(i=0;i<len;i++)
-		saved_key[GETPOS(i, index)] = key[i];
-
-	saved_key[GETPOS(i, index)] = 0x80;
-#else
-  strnzcpy(saved_key, key, sizeof(saved_key));
-#endif
-}
-
-static char *get_key(int index)
-{
-#ifdef MMX_COEF
-	unsigned int i,s;
-
-	s = (total_len >> (((32/MMX_COEF)*(index)))) & 0xff;
-	for(i=0;i<s;i++)
-		out[i] = saved_key[ GETPOS(i, index) ];
-	out[i] = 0;
-	return (char *) out;
-#else
-  return saved_key;
-#endif
-}
-
-static int
-cmp_all(void *binary, int count)
-{
-#ifdef MMX_COEF
-	int i = 0;
-	while(i< (BINARY_SIZE/4) )
-	{
-		if (
-			( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF])
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+1])
-#if (MMX_COEF > 3)
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2])
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3])
-#endif
-		)
-			return 0;
-		i++;
-	}
-	return 1;
-#else
-	return !memcmp(binary, crypt_key, BINARY_SIZE);
-#endif
-}
-
-static int
-cmp_exact(char *source, int index)
-{
-  return 1;
-}
-
-static int cmp_one(void * binary, int index)
-{
-#ifdef MMX_COEF
-	int i = 0;
-	for(i=0;i<(BINARY_SIZE/4);i++)
-		if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] )
-			return 0;
-	return 1;
-#else
-	return cmp_all(binary, index);
-#endif
-}
-
-static void
-crypt_all(int count) {
-#ifdef MMX_COEF
-	memcpy(buffer, saved_key, (PLAINTEXT_LENGTH+4)*MMX_COEF);
-	shammx((unsigned char *) crypt_key, buffer, total_len);
-#else
-  static SHA_CTX ctx;
-  SHA1_Init(&ctx);
-  SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key));
-  SHA1_Final((unsigned char *) crypt_key, &ctx);
-#endif
-}
-
-struct fmt_main fmt_NSLDAP = {
-	{
-		FORMAT_LABEL,
-		FORMAT_NAME,
-		ALGORITHM_NAME,
-		BENCHMARK_COMMENT,
-		BENCHMARK_LENGTH,
-		PLAINTEXT_LENGTH,
-		BINARY_SIZE,
-		SALT_SIZE,
-		MIN_KEYS_PER_CRYPT,
-		MAX_KEYS_PER_CRYPT,
-		FMT_CASE | FMT_8_BIT,
-		tests
-	}, {
-		fmt_default_init,
-		fmt_default_prepare,
-		valid,
-		fmt_default_split,
-		binary,
-		fmt_default_salt,
-		{
-			binary_hash_0,
-			binary_hash_1,
-			binary_hash_2,
-			binary_hash_3,
-			binary_hash_4
-		},
-		fmt_default_salt_hash,
-		fmt_default_set_salt,
-		set_key,
-		get_key,
-		fmt_default_clear_keys,
-		crypt_all,
-		{
-			get_hash_0,
-			get_hash_1,
-			get_hash_2,
-			get_hash_3,
-			get_hash_4
-		},
-		cmp_all,
-		cmp_one,
-		cmp_exact
-	}
-};
diff --git a/src/OPENLDAPS_fmt_plug.c b/src/OPENLDAPS_fmt_plug.c
deleted file mode 100644
index 41940b4..0000000
--- a/src/OPENLDAPS_fmt_plug.c
+++ /dev/null
@@ -1,330 +0,0 @@
-// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26.
-/*
- * Minor performance enhancement by bartavelle at bandecon.com
- */
-
-#include <string.h>
-
-#include "arch.h"
-#include "misc.h"
-#include "params.h"
-#include "formats.h"
-#include "common.h"
-
-#include "sha.h"
-#include "base64.h"
-
-// This format has some MMX/SSE sha things in there but it's not completed.
-// We should re-work it to use sse-intrinsics
-#undef MMX_COEF
-#undef MMX_TYPE
-
-#define FORMAT_LABEL			"openssha"
-#define FORMAT_NAME			"OpenLDAP SSHA"
-
-#if defined(MMX_COEF) && MMX_COEF == 4
-#define ALGORITHM_NAME			"SSE2 4x"
-#elif defined(MMX_COEF) && MMX_COEF == 2
-#define ALGORITHM_NAME			"MMX 2x"
-#elif defined(MMX_COEF)
-#define ALGORITHM_NAME			"?"
-#else
-#define ALGORITHM_NAME			"32/" ARCH_BITS_STR
-#endif
-
-#define BENCHMARK_COMMENT		""
-#define BENCHMARK_LENGTH		0
-
-#define PLAINTEXT_LENGTH		32
-#define CIPHERTEXT_LENGTH		32
-
-#define BINARY_SIZE			20
-#define SALT_SIZE			4
-
-#ifdef MMX_COEF
-#define MIN_KEYS_PER_CRYPT		MMX_COEF
-#define MAX_KEYS_PER_CRYPT		MMX_COEF
-#define GETPOS(i, index)		( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) )
-#else
-#define MIN_KEYS_PER_CRYPT		1
-#define MAX_KEYS_PER_CRYPT		1
-#endif
-
-#define NSLDAP_MAGIC "{ssha}"
-#define NSLDAP_MAGIC_LENGTH 6
-
-static struct fmt_tests tests[] = {
-	{"{SSHA}bPXG4M1KkwZh2Hbgnuoszvpat0T/OS86", "thales"},
-	{"{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X", "test1"},
-	{"{SSHA}pXp4yIiRmppvKYn7cKCT+lngG4qELq4h", "test2"},
-	{"{SSHA}Bv8tu3wB8WTMJj3tcOsl1usm5HzGwEmv", "test3"},
-	{"{SSHA}kXyh8wLCKbN+QRbL2F2aUbkP62BJ/bRg", "lapin"},
-	{"{SSHA}rnMVxsf1YJPg0L5CBhbVLIsJF+o/vkoE", "canard"},
-	{"{SSHA}Uf2x9YxSWZZNAi2t1QXbG2PmT07AtURl", "chien"},
-	{"{SSHA}XXGLZ7iKpYSBpF6EwoeTl27U0L/kYYsY", "hibou"},
-	{"{SSHA}HYRPmcQIIzIIg/c1L8cZKlYdNpyeZeml", "genou"},
-	{"{SSHA}Zm/0Wll7rLNpBU4HFUKhbASpXr94eSTc", "caillou"},
-	{"{SSHA}Qc9OB+aEFA/mJ5MNy0AB4hRIkNiAbqDb", "doudou"},
-	{NULL}
-};
-
-#ifdef MMX_COEF
-static char crypt_key[BINARY_SIZE*MMX_COEF];
-/* Cygwin would not guarantee the alignment for this static declaration, but
- * this source file is not MMX-ready anyway (MMX_COEF is #undef'ed above). */
-static char saved_key[80*MMX_COEF*4] __attribute__ ((aligned(8*MMX_COEF)));
-static unsigned char out[PLAINTEXT_LENGTH + 1];
-#else
-static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4];
-static char saved_key[PLAINTEXT_LENGTH + 1];
-#endif
-
-#ifdef MMX_COEF
-static unsigned long length[MAX_KEYS_PER_CRYPT];
-#endif
-
-static char saved_salt[SALT_SIZE];
-
-static void * binary(char *ciphertext) {
-  static char *realcipher;
-
-  if (!realcipher) realcipher = mem_alloc_tiny(BINARY_SIZE + SALT_SIZE + 9, MEM_ALIGN_WORD);
-
-  /* stupid overflows */
-  memset(realcipher, 0, BINARY_SIZE + SALT_SIZE + 9);
-  base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
-#ifdef MMX_COEF
-  alter_endianity((unsigned char*)realcipher, BINARY_SIZE);
-#endif
-  return (void *)realcipher;
-}
-
-static void * get_salt(char * ciphertext)
-{
-	static char *realcipher;
-
-	if (!realcipher) realcipher = mem_alloc_tiny(BINARY_SIZE + SALT_SIZE + 9, MEM_ALIGN_WORD);
-
-	memset(realcipher, 0, BINARY_SIZE + SALT_SIZE + 9);
-	base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
-	return (void*)&realcipher[BINARY_SIZE];
-}
-
-static int valid(char *ciphertext, struct fmt_main *pFmt)
-{
-	if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH + NSLDAP_MAGIC_LENGTH)
-		return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH);
-	return 0;
-}
-
-static int binary_hash_0(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xF;
-}
-
-static int binary_hash_1(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFF;
-}
-
-static int binary_hash_2(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFF;
-}
-
-static int binary_hash_3(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFF;
-}
-
-static int binary_hash_4(void *binary)
-{
-	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFFF;
-}
-
-static int get_hash_0(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF;
-}
-
-static int get_hash_1(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF;
-}
-
-static int get_hash_2(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF;
-}
-
-static int get_hash_3(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFF;
-}
-
-static int get_hash_4(int index)
-{
-	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFFF;
-}
-
-static int salt_hash(void *salt)
-{
-	return *((ARCH_WORD_32 *)salt) & (SALT_HASH_SIZE - 1);
-}
-
-static void set_key(char *key, int index)
-{
-#ifdef MMX_COEF
-	int len;
-	int i;
-
-	if(index==0)
-	{
-		memset(saved_key, 0, sizeof(saved_key));
-	}
-	len = strlen(key);
-	if(len>PLAINTEXT_LENGTH)
-		len = PLAINTEXT_LENGTH;
-
-	length[index] = len;
-
-	for(i=0;i<len;i++)
-		saved_key[GETPOS(i, index)] = key[i];
-
-	saved_key[GETPOS( (i+SALT_SIZE) , index)] = 0x80;
-	((unsigned int *)saved_key)[15*MMX_COEF+index] = (len+SALT_SIZE)<<3;
-#else
-	strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1);
-#endif
-}
-
-static void set_salt(void *salt)
-{
-	memcpy(saved_salt, salt, SALT_SIZE);
-}
-
-static char *get_key(int index)
-{
-#ifdef MMX_COEF
-	unsigned int i,s;
-
-	s = length[index];
-	for(i=0;i<s;i++)
-		out[i] = saved_key[ GETPOS(i, index) ];
-	out[i] = 0;
-	return (char*)out;
-#else
-  return saved_key;
-#endif
-}
-
-static int
-cmp_all(void *binary, int index)
-{
-#ifdef MMX_COEF
-	int i = 0;
-	while(i< (BINARY_SIZE/4) )
-	{
-		if (
-			( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF])
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+1])
-#if (MMX_COEF > 3)
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2])
-			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3])
-#endif
-		)
-			return 0;
-		i++;
-	}
-	return 1;
-#else
-	return !memcmp(binary, crypt_key, BINARY_SIZE);
-#endif
-}
-
-static int
-cmp_exact(char *source, int index)
-{
-  return 1;
-}
-
-static int cmp_one(void * binary, int index)
-{
-#ifdef MMX_COEF
-	int i = 0;
-	for(i=0;i<(BINARY_SIZE/4);i++)
-		if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] )
-			return 0;
-	return 1;
-#else
-	return cmp_all(binary, index);
-#endif
-}
-
-
-static void crypt_all(int count)
-{
-#ifdef MMX_COEF
-	int i,idx;
-
-	for(idx=0;idx<MAX_KEYS_PER_CRYPT;idx++)
-	{
-		for(i=0;i<SALT_SIZE;i++)
-			saved_key[GETPOS((i+length[idx]),idx)] = ((unsigned char *)saved_salt)[i];
-	}
-	shammx((unsigned char*)crypt_key, (unsigned char*)saved_key);
-#else
-	static SHA_CTX ctx;
-	SHA1_Init(&ctx);
-	SHA1_Update(&ctx, (unsigned char*)saved_key, strlen(saved_key));
-	SHA1_Update(&ctx, (unsigned char*)saved_salt, SALT_SIZE);
-	SHA1_Final((unsigned char*)crypt_key, &ctx);
-#endif
-}
-
-struct fmt_main fmt_OPENLDAPS = {
-	{
-		FORMAT_LABEL,
-		FORMAT_NAME,
-		ALGORITHM_NAME,
-		BENCHMARK_COMMENT,
-		BENCHMARK_LENGTH,
-		PLAINTEXT_LENGTH,
-		BINARY_SIZE,
-		SALT_SIZE,
-		MIN_KEYS_PER_CRYPT,
-		MAX_KEYS_PER_CRYPT,
-		FMT_CASE | FMT_8_BIT,
-		tests
-	}, {
-		fmt_default_init,
-		fmt_default_prepare,
-		valid,
-		fmt_default_split,
-		binary,
-		get_salt,
-		{
-			binary_hash_0,
-			binary_hash_1,
-			binary_hash_2,
-			binary_hash_3,
-			binary_hash_4
-		},
-		salt_hash,
-		set_salt,
-		set_key,
-		get_key,
-		fmt_default_clear_keys,
-		crypt_all,
-		{
-			get_hash_0,
-			get_hash_1,
-			get_hash_2,
-			get_hash_3,
-			get_hash_4
-		},
-		cmp_all,
-		cmp_one,
-		cmp_exact
-	}
-};
diff --git a/src/nsldap_fmt_plug.c b/src/nsldap_fmt_plug.c
new file mode 100644
index 0000000..5247c42
--- /dev/null
+++ b/src/nsldap_fmt_plug.c
@@ -0,0 +1,350 @@
+/*
+ * New NSLDAP format based on NSLDAP_fmt.c (by Sun-Zero, 2004)
+ * and rawSHA1_fmt.c (Copyright (c) 2004 bartavelle,
+ * bartavelle at bandecon.com)
+ *
+ * Whipped together by magnum, 2011. No rights reserved.
+ */
+
+#include <string.h>
+
+#include "arch.h"
+
+#ifdef SHA1_SSE_PARA
+#define MMX_COEF			4
+#include "sse-intrinsics.h"
+#define NBKEYS				(MMX_COEF * SHA1_SSE_PARA)
+#elif MMX_COEF
+#define NBKEYS				MMX_COEF
+#endif
+
+#include "misc.h"
+#include "common.h"
+#include "formats.h"
+#include "sha.h"
+#include "base64.h"
+
+#define FORMAT_LABEL			"nsldap"
+#define FORMAT_NAME			"Netscape LDAP SHA"
+
+#ifdef SHA1_N_STR
+#define ALGORITHM_NAME			"SSE2i " SHA1_N_STR
+#elif defined(MMX_COEF) && MMX_COEF == 4
+#define ALGORITHM_NAME			"SSE2 4x"
+#elif defined(MMX_COEF) && MMX_COEF == 2
+#define ALGORITHM_NAME			"MMX 2x"
+#elif defined(MMX_COEF)
+#define ALGORITHM_NAME			"?"
+#else
+#define ALGORITHM_NAME			"32/" ARCH_BITS_STR
+#endif
+
+#define BENCHMARK_COMMENT		""
+#define BENCHMARK_LENGTH		-1
+
+#define PLAINTEXT_LENGTH		55
+#define CIPHERTEXT_LENGTH		33
+
+#define BINARY_SIZE			20
+#define SALT_SIZE			0
+
+#ifdef MMX_COEF
+#define MIN_KEYS_PER_CRYPT		NBKEYS
+#define MAX_KEYS_PER_CRYPT		NBKEYS
+#define GETPOS(i, index)		( (index&(MMX_COEF-1))*4 + ((i)&(0xffffffff-3))*MMX_COEF + (3-((i)&3)) + (index>>(MMX_COEF>>1))*80*MMX_COEF*4 ) //for endianity conversion
+#else
+#define MIN_KEYS_PER_CRYPT		1
+#define MAX_KEYS_PER_CRYPT		1
+#endif
+
+#define NSLDAP_MAGIC "{SHA}"
+#define NSLDAP_MAGIC_LENGTH 5
+
+static struct fmt_tests tests[] = {
+	{"{SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=", "aaaa"},
+	{"{SHA}iu0TIuVFC62weOH7YKgXod8loso=", "bbbb"},
+	{"{SHA}0ijZPTcJXMa+t2XnEbEwSOkvQu0=", "ccccccccc"},
+	{"{SHA}vNR9eUfJfcKmdkLDqNoKagho+qU=", "dddddddddd"},
+	{NULL}
+};
+
+#ifdef MMX_COEF
+#if defined (_MSC_VER)
+/* Cygwin would not guarantee the alignment if these were declared static */
+#define saved_key nsldap_saved_key
+#define crypt_key nsldap_crypt_key
+__declspec(align(16)) unsigned char saved_key[80*4*NBKEYS];
+__declspec(align(16)) unsigned char crypt_key[BINARY_SIZE*NBKEYS];
+#else
+static unsigned char saved_key[80*4*NBKEYS] __attribute__ ((aligned(16)));
+static unsigned char crypt_key[BINARY_SIZE*NBKEYS] __attribute__ ((aligned(16)));
+#endif
+#ifndef SHA1_SSE_PARA
+static unsigned long total_len;
+#endif
+static unsigned char out[PLAINTEXT_LENGTH + 1];
+#else
+static char saved_key[PLAINTEXT_LENGTH + 1];
+static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4];
+#endif
+
+static int valid(char *ciphertext, struct fmt_main *pFmt)
+{
+	if (ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH)
+		return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH);
+	return 0;
+}
+
+static void init(struct fmt_main *pFmt)
+{
+#ifdef MMX_COEF
+	memset(saved_key, 0, sizeof(saved_key));
+#endif
+}
+
+static void set_key(char *key, int index) {
+#ifdef MMX_COEF
+	int i;
+
+	if (index==0)
+		{
+			i = 0;
+#ifndef SHA1_SSE_PARA
+			total_len = 0;
+#else
+			for (; i < SHA1_SSE_PARA; ++i)
+#endif
+				memset(&saved_key[i*4*80*MMX_COEF], 0, 56*MMX_COEF);
+		}
+
+	i = -1;
+	while (key[++i])
+		saved_key[GETPOS(i, index)] = key[i];
+	saved_key[GETPOS(i, index)] = 0x80;
+
+#ifdef SHA1_SSE_PARA
+	saved_key[GETPOS(63, index)] = i << 3;
+#else
+	total_len += i << ( ( (32/MMX_COEF) * index ) );
+#endif
+
+#else
+	strnzcpy(saved_key, key, PLAINTEXT_LENGTH + 1);
+#endif
+}
+
+static char *get_key(int index) {
+#ifdef MMX_COEF
+	unsigned int i, s;
+
+#ifdef SHA1_SSE_PARA
+	s = saved_key[GETPOS(63, index)] >> 3;
+#else
+	s = (total_len >> (((32/MMX_COEF)*(index)))) & 0xff;
+#endif
+	for(i=0;i<s;i++)
+		out[i] = saved_key[ GETPOS(i, index) ];
+	out[i] = 0;
+	return (char*) out;
+#else
+	return saved_key;
+#endif
+}
+
+static int cmp_all(void *binary, int count) {
+#ifdef MMX_COEF
+# ifdef SHA1_SSE_PARA
+	unsigned int x,y=0;
+
+#ifdef SHA1_SSE_PARA
+	for(;y<SHA1_SSE_PARA;y++)
+#endif
+		for(x=0;x<MMX_COEF;x++)
+			{
+				if( ((unsigned int*)binary)[0] == ((unsigned int*)crypt_key)[x+y*MMX_COEF*5] )
+					return 1;
+			}
+	return 0;
+# else
+	int i=0;
+	while(i< (BINARY_SIZE/4) )
+		{
+			if (
+			    ( ((unsigned long*)binary)[i] != ((unsigned long*)crypt_key)[i*MMX_COEF])
+			    && ( ((unsigned long*)binary)[i] != ((unsigned long*)crypt_key)[i*MMX_COEF+1])
+#   if (MMX_COEF > 3)
+			    && ( ((unsigned long*)binary)[i] != ((unsigned long*)crypt_key)[i*MMX_COEF+2])
+			    && ( ((unsigned long*)binary)[i] != ((unsigned long*)crypt_key)[i*MMX_COEF+3])
+#   endif
+			    )
+				return 0;
+			i++;
+		}
+	return 1;
+# endif
+#else
+	return !memcmp(binary, crypt_key, BINARY_SIZE);
+#endif
+}
+
+static int cmp_exact(char *source, int count){
+	return (1);
+}
+
+static int cmp_one(void * binary, int index)
+{
+#ifdef MMX_COEF
+# if SHA1_SSE_PARA
+	unsigned int x,y;
+	x = index&3;
+	y = index/4;
+
+	if( ((unsigned int*)binary)[0] != ((unsigned int*)crypt_key)[x+y*MMX_COEF*5] )
+		return 0;
+	if( ((unsigned int*)binary)[1] != ((unsigned int*)crypt_key)[x+y*MMX_COEF*5+4] )
+		return 0;
+	if( ((unsigned int*)binary)[2] != ((unsigned int*)crypt_key)[x+y*MMX_COEF*5+8] )
+		return 0;
+	if( ((unsigned int*)binary)[3] != ((unsigned int*)crypt_key)[x+y*MMX_COEF*5+12] )
+		return 0;
+	if( ((unsigned int*)binary)[4] != ((unsigned int*)crypt_key)[x+y*MMX_COEF*5+16] )
+		return 0;
+	return 1;
+# else
+	int i = 0;
+	for(i=0;i<(BINARY_SIZE/4);i++)
+		if ( ((unsigned long*)binary)[i] != ((unsigned long*)crypt_key)[i*MMX_COEF+index] )
+			return 0;
+	return 1;
+# endif
+#else
+	return cmp_all(binary, index);
+#endif
+}
+
+static void crypt_all(int count) {
+#ifdef MMX_COEF
+
+# if SHA1_SSE_PARA
+	SSESHA1body(saved_key, (unsigned int*)crypt_key, NULL, 0);
+# else
+	shammx_nofinalbyteswap((unsigned char*) crypt_key, (unsigned char*) saved_key, total_len);
+# endif
+
+#else
+	SHA_CTX ctx;
+	SHA1_Init( &ctx );
+	SHA1_Update( &ctx, (unsigned char*) saved_key, strlen( saved_key ) );
+	SHA1_Final( (unsigned char*) crypt_key, &ctx);
+#endif
+}
+
+static void * binary(char *ciphertext)
+{
+	static char realcipher[BINARY_SIZE + 9];
+
+	memset(realcipher, 0, sizeof(realcipher));
+	base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
+
+#ifdef MMX_COEF
+	alter_endianity((unsigned char*)realcipher, BINARY_SIZE);
+#endif
+	return (void*)realcipher;
+}
+
+static int binary_hash_0(void * binary) { return ((ARCH_WORD_32*)binary)[0] & 0xf; }
+static int binary_hash_1(void * binary) { return ((ARCH_WORD_32*)binary)[0] & 0xff; }
+static int binary_hash_2(void * binary) { return ((ARCH_WORD_32*)binary)[0] & 0xfff; }
+static int binary_hash_3(void * binary) { return ((ARCH_WORD_32*)binary)[0] & 0xffff; }
+static int binary_hash_4(void * binary) { return ((ARCH_WORD_32*)binary)[0] & 0xfffff; }
+
+#ifdef MMX_COEF
+static int get_hash_0(int index)
+{
+	unsigned int x,y;
+	x = index&3;
+	y = index/4;
+	return ((unsigned int*)crypt_key)[x+y*MMX_COEF*5] & 0xf;
+}
+static int get_hash_1(int index)
+{
+	unsigned int x,y;
+	x = index&3;
+	y = index/4;
+	return ((unsigned int*)crypt_key)[x+y*MMX_COEF*5] & 0xff;
+}
+static int get_hash_2(int index)
+{
+	unsigned int x,y;
+	x = index&3;
+	y = index/4;
+	return ((unsigned int*)crypt_key)[x+y*MMX_COEF*5] & 0xfff;
+}
+static int get_hash_3(int index)
+{
+	unsigned int x,y;
+	x = index&3;
+	y = index/4;
+	return ((unsigned int*)crypt_key)[x+y*MMX_COEF*5] & 0xffff;
+}
+static int get_hash_4(int index)
+{
+	unsigned int x,y;
+	x = index&3;
+	y = index/4;
+	return ((unsigned int*)crypt_key)[x+y*MMX_COEF*5] & 0xfffff;
+}
+#else
+static int get_hash_0(int index) { return ((unsigned int*)crypt_key)[0] & 0xf; }
+static int get_hash_1(int index) { return ((unsigned int*)crypt_key)[0] & 0xff; }
+static int get_hash_2(int index) { return ((unsigned int*)crypt_key)[0] & 0xfff; }
+static int get_hash_3(int index) { return ((unsigned int*)crypt_key)[0] & 0xffff; }
+static int get_hash_4(int index) { return ((unsigned int*)crypt_key)[0] & 0xfffff; }
+#endif
+
+struct fmt_main fmt_nsldap = {
+	{
+		FORMAT_LABEL,
+		FORMAT_NAME,
+		ALGORITHM_NAME,
+		BENCHMARK_COMMENT,
+		BENCHMARK_LENGTH,
+		PLAINTEXT_LENGTH,
+		BINARY_SIZE,
+		SALT_SIZE,
+		MIN_KEYS_PER_CRYPT,
+		MAX_KEYS_PER_CRYPT,
+		FMT_CASE | FMT_8_BIT,
+		tests
+	}, {
+		init,
+		fmt_default_prepare,
+		valid,
+		fmt_default_split,
+		binary,
+		fmt_default_salt,
+		{
+			binary_hash_0,
+			binary_hash_1,
+			binary_hash_2,
+			binary_hash_3,
+			binary_hash_4
+		},
+		fmt_default_salt_hash,
+		fmt_default_set_salt,
+		set_key,
+		get_key,
+		fmt_default_clear_keys,
+		crypt_all,
+		{
+			get_hash_0,
+			get_hash_1,
+			get_hash_2,
+			get_hash_3,
+			get_hash_4
+		},
+		cmp_all,
+		cmp_one,
+		cmp_exact
+	}
+};
diff --git a/src/salted_sha1_fmt_plug.c b/src/salted_sha1_fmt_plug.c
index a252f9e..50e0851 100644
--- a/src/salted_sha1_fmt_plug.c
+++ b/src/salted_sha1_fmt_plug.c
@@ -81,6 +81,7 @@ struct s_salt
 static struct s_salt saved_salt;
 
 static struct fmt_tests tests[] = {
+// Test hashes originally(?) in OPENLDAPS_fmt (openssha) (salt length 4)
 	{"{SSHA}bPXG4M1KkwZh2Hbgnuoszvpat0T/OS86", "thales"},
 	{"{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X", "test1"},
 	{"{SSHA}pXp4yIiRmppvKYn7cKCT+lngG4qELq4h", "test2"},
@@ -92,13 +93,22 @@ static struct fmt_tests tests[] = {
 	{"{SSHA}HYRPmcQIIzIIg/c1L8cZKlYdNpyeZeml", "genou"},
 	{"{SSHA}Zm/0Wll7rLNpBU4HFUKhbASpXr94eSTc", "caillou"},
 	{"{SSHA}Qc9OB+aEFA/mJ5MNy0AB4hRIkNiAbqDb", "doudou"},
-/*
+
+// Test vectors originally in NSLDAPS_fmt (ssha) (salt length 8)
 	{"{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==", "Password9"},
 	{"{SSHA}ypkVeJKLzbXakEpuPYbn+YBnQvFmNmB+kQhmWQ==", "qVv3uQ45"},
 	{"{SSHA}cKFVqtf358j0FGpPsEIK1xh3T0mtDNV1kAaBNg==", "salles"},
 	{"{SSHA}W3ipFGmzS3+j6/FhT7ZC39MIfqFcct9Ep0KEGA==", "asddsa123"},
 	{"{SSHA}YbB2R1D2AlzYc9wk/YPtslG7NoiOWaoMOztLHA==", "ripthispassword"},
-*/
+#if 0
+/*
+ * These two were found in john-1.6-nsldaps4.diff.gz and apparently they were
+ * supported by that version of they code, but they are not anymore.
+ */
+  {"{SSHA}/EExmSfmhQSPHDJaTxwQSdb/uPpzYWx0ZXI=", "secret"},
+  {"{SSHA}gVK8WC9YyFT1gMsQHTGCgT3sSv5zYWx0", "secret"},
+#endif
+
 	{NULL}
 };
 
diff --git a/src/unused/NSLDAPS_fmt_plug.c b/src/unused/NSLDAPS_fmt_plug.c
new file mode 100644
index 0000000..9c545c9
--- /dev/null
+++ b/src/unused/NSLDAPS_fmt_plug.c
@@ -0,0 +1,332 @@
+// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26.
+/*
+ * Minor performance enhancement by bartavelle at bandecon.com
+ */
+
+#include <string.h>
+
+#include "misc.h"
+#include "params.h"
+#include "formats.h"
+#include "common.h"
+
+#include "sha.h"
+#include "base64.h"
+
+#define FORMAT_LABEL			"ssha"
+#define FORMAT_NAME			"Netscape LDAP SSHA"
+
+#if defined(MMX_COEF) && MMX_COEF == 4
+#define ALGORITHM_NAME			"SSE2 4x"
+#elif defined(MMX_COEF) && MMX_COEF == 2
+#define ALGORITHM_NAME			"MMX 2x"
+#elif defined(MMX_COEF)
+#define ALGORITHM_NAME			"?"
+#else
+#define ALGORITHM_NAME			"32/" ARCH_BITS_STR
+#endif
+
+#define BENCHMARK_COMMENT		""
+#define BENCHMARK_LENGTH		0
+
+#define PLAINTEXT_LENGTH		32
+#define CIPHERTEXT_LENGTH		40
+
+#define BINARY_SIZE			20
+#define SALT_SIZE			8
+
+#ifdef MMX_COEF
+#define MIN_KEYS_PER_CRYPT		MMX_COEF
+#define MAX_KEYS_PER_CRYPT		MMX_COEF
+#define GETPOS(i, index)		( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) )
+#else
+#define MIN_KEYS_PER_CRYPT		1
+#define MAX_KEYS_PER_CRYPT		1
+#endif
+
+#define NSLDAP_MAGIC "{ssha}"
+#define NSLDAP_MAGIC_LENGTH 6
+
+static struct fmt_tests tests[] = {
+  {"{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==", "Password9"},
+  {"{SSHA}ypkVeJKLzbXakEpuPYbn+YBnQvFmNmB+kQhmWQ==", "qVv3uQ45"},
+  {"{SSHA}cKFVqtf358j0FGpPsEIK1xh3T0mtDNV1kAaBNg==", "salles"},
+  {"{SSHA}W3ipFGmzS3+j6/FhT7ZC39MIfqFcct9Ep0KEGA==", "asddsa123"},
+  {"{SSHA}YbB2R1D2AlzYc9wk/YPtslG7NoiOWaoMOztLHA==", "ripthispassword"},
+#if 0
+/*
+ * These two were found in john-1.6-nsldaps4.diff.gz and apparently they were
+ * supported by that version of they code, but they are not anymore.
+ */
+  {"{SSHA}/EExmSfmhQSPHDJaTxwQSdb/uPpzYWx0ZXI=", "secret"},
+  {"{SSHA}gVK8WC9YyFT1gMsQHTGCgT3sSv5zYWx0", "secret"},
+#endif
+  {NULL}
+};
+
+#ifdef MMX_COEF
+/* Cygwin would not guarantee the alignment if these were declared static */
+#define buffer NSLDAPS_buffer
+#define crypt_key NSLDAPS_crypt_key
+#ifdef _MSC_VER
+__declspec(align(16)) unsigned char buffer[80*4*MMX_COEF];
+__declspec(align(16)) char crypt_key[BINARY_SIZE*MMX_COEF];
+#else
+unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16)));
+char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16)));
+#endif
+static char saved_key[(PLAINTEXT_LENGTH+SALT_SIZE+4+1)*MMX_COEF];
+static unsigned long total_len;
+static unsigned char out[PLAINTEXT_LENGTH + 1];
+#else
+static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4];
+static char saved_key[PLAINTEXT_LENGTH + 1];
+#endif
+
+#ifdef MMX_COEF
+static unsigned long length[MAX_KEYS_PER_CRYPT];
+#endif
+static char saved_salt[SALT_SIZE];
+
+static void * binary(char *ciphertext) {
+  static char *realcipher;
+  // align realcipher (it is the binary returned, and must be aligned for how we 'use' it later)
+  if (!realcipher) realcipher = mem_alloc_tiny(BINARY_SIZE + SALT_SIZE + 9, MEM_ALIGN_WORD);
+
+  /* stupid overflows */
+  memset(realcipher, 0, sizeof(realcipher));
+  base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
+  return (void *)realcipher;
+}
+
+static void * get_salt(char * ciphertext)
+{
+	static char realcipher[BINARY_SIZE + SALT_SIZE + 9];
+	memset(realcipher, 0, sizeof(realcipher));
+	base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
+	return (void*)&realcipher[BINARY_SIZE];
+}
+
+static int valid(char *ciphertext, struct fmt_main *pFmt)
+{
+	if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH + NSLDAP_MAGIC_LENGTH)
+		return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH);
+	return 0;
+}
+
+static int binary_hash_0(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xF;
+}
+
+static int binary_hash_1(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFF;
+}
+
+static int binary_hash_2(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFF;
+}
+
+static int binary_hash_3(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFF;
+}
+
+static int binary_hash_4(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFFF;
+}
+
+static int get_hash_0(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF;
+}
+
+static int get_hash_1(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF;
+}
+
+static int get_hash_2(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF;
+}
+
+static int get_hash_3(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFF;
+}
+
+static int get_hash_4(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFFF;
+}
+
+static int salt_hash(void *salt)
+{
+	return *((ARCH_WORD_32 *)salt) & (SALT_HASH_SIZE - 1);
+}
+
+static void set_key(char *key, int index)
+{
+#ifdef MMX_COEF
+	int len;
+	int i;
+
+	if(index==0)
+	{
+		total_len = 0;
+		memset(saved_key, 0, sizeof(saved_key));
+		memset(length, 0, sizeof(length));
+	}
+	len = strlen(key);
+	if(len>PLAINTEXT_LENGTH)
+		len = PLAINTEXT_LENGTH;
+
+	length[index] = len;
+
+	total_len += (len + SALT_SIZE) << ( ( (32/MMX_COEF) * index ) );
+	for(i=0;i<len;i++)
+		saved_key[GETPOS(i, index)] = key[i];
+
+	saved_key[GETPOS( (i+SALT_SIZE) , index)] = 0x80;
+#else
+	strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1);
+#endif
+}
+
+static void set_salt(void *salt)
+{
+	memcpy(saved_salt, salt, SALT_SIZE);
+
+}
+
+static char *get_key(int index)
+{
+#ifdef MMX_COEF
+	unsigned int i,s;
+
+	s = length[index];
+	for(i=0;i<s;i++)
+		out[i] = saved_key[ GETPOS(i, index) ];
+	out[i] = 0;
+	return (char *) out;
+#else
+  return saved_key;
+#endif
+}
+
+static int
+cmp_all(void *binary, int index)
+{
+#ifdef MMX_COEF
+	int i = 0;
+	while(i< (BINARY_SIZE/4) )
+	{
+		if (
+			( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF])
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+1])
+#if (MMX_COEF > 3)
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2])
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3])
+#endif
+		)
+			return 0;
+		i++;
+	}
+	return 1;
+#else
+	return !memcmp(binary, crypt_key, BINARY_SIZE);
+#endif
+}
+
+static int
+cmp_exact(char *source, int index)
+{
+  return 1;
+}
+
+static int cmp_one(void * binary, int index)
+{
+#ifdef MMX_COEF
+	int i = 0;
+	for(i=0;i<(BINARY_SIZE/4);i++)
+		if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] )
+			return 0;
+	return 1;
+#else
+	return cmp_all(binary, index);
+#endif
+}
+
+
+static void crypt_all(int count)
+{
+#ifdef MMX_COEF
+	int i,idx;
+
+	for(idx=0;idx<MAX_KEYS_PER_CRYPT;idx++)
+		for(i=0;i<SALT_SIZE;i++)
+		{
+			saved_key[GETPOS(i+length[idx],idx)] = ((unsigned char *)saved_salt)[i];
+		}
+
+	memcpy(buffer, saved_key, (PLAINTEXT_LENGTH+SALT_SIZE+4)*MMX_COEF);
+	shammx((unsigned char *) crypt_key, buffer, total_len);
+#else
+	static SHA_CTX ctx;
+	SHA1_Init(&ctx);
+	SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key));
+	SHA1_Update(&ctx, (unsigned char *) saved_salt, SALT_SIZE);
+	SHA1_Final((unsigned char *) crypt_key, &ctx);
+#endif
+}
+
+struct fmt_main fmt_NSLDAPS = {
+	{
+		FORMAT_LABEL,
+		FORMAT_NAME,
+		ALGORITHM_NAME,
+		BENCHMARK_COMMENT,
+		BENCHMARK_LENGTH,
+		PLAINTEXT_LENGTH,
+		BINARY_SIZE,
+		SALT_SIZE,
+		MIN_KEYS_PER_CRYPT,
+		MAX_KEYS_PER_CRYPT,
+		FMT_CASE | FMT_8_BIT,
+		tests
+	}, {
+		fmt_default_init,
+		fmt_default_prepare,
+		valid,
+		fmt_default_split,
+		binary,
+		get_salt,
+		{
+			binary_hash_0,
+			binary_hash_1,
+			binary_hash_2,
+			binary_hash_3,
+			binary_hash_4
+		},
+		salt_hash,
+		set_salt,
+		set_key,
+		get_key,
+		fmt_default_clear_keys,
+		crypt_all,
+		{
+			get_hash_0,
+			get_hash_1,
+			get_hash_2,
+			get_hash_3,
+			get_hash_4
+		},
+		cmp_all,
+		cmp_one,
+		cmp_exact
+	}
+};
diff --git a/src/unused/NSLDAP_fmt_plug.c b/src/unused/NSLDAP_fmt_plug.c
new file mode 100644
index 0000000..8579005
--- /dev/null
+++ b/src/unused/NSLDAP_fmt_plug.c
@@ -0,0 +1,285 @@
+// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26.
+/*
+ * Minor performance enhancement by bartavelle at bandecon.com
+ */
+
+#include <string.h>
+
+#include "misc.h"
+#include "formats.h"
+#include "common.h"
+
+#include "sha.h"
+#include "base64.h"
+
+#define FORMAT_LABEL			"nsldap"
+#define FORMAT_NAME			"Netscape LDAP SHA"
+
+#if defined(MMX_COEF) && MMX_COEF == 4
+#define ALGORITHM_NAME			"SSE2 4x"
+#elif defined(MMX_COEF) && MMX_COEF == 2
+#define ALGORITHM_NAME			"MMX 2x"
+#elif defined(MMX_COEF)
+#define ALGORITHM_NAME			"?"
+#else
+#define ALGORITHM_NAME			"32/" ARCH_BITS_STR
+#endif
+
+#define BENCHMARK_COMMENT		""
+#define BENCHMARK_LENGTH		-1
+
+#define PLAINTEXT_LENGTH		32
+#define CIPHERTEXT_LENGTH		33
+
+#define BINARY_SIZE			20
+#define SALT_SIZE			0
+
+#ifdef MMX_COEF
+#define MIN_KEYS_PER_CRYPT		MMX_COEF
+#define MAX_KEYS_PER_CRYPT		MMX_COEF
+#define GETPOS(i, index)		( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) )
+#else
+#define MIN_KEYS_PER_CRYPT		1
+#define MAX_KEYS_PER_CRYPT		1
+#endif
+
+#define NSLDAP_MAGIC "{sha}"
+#define NSLDAP_MAGIC_LENGTH 5
+
+static struct fmt_tests tests[] = {
+  {"{SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=", "aaaa"},
+  {"{SHA}iu0TIuVFC62weOH7YKgXod8loso=", "bbbb"},
+  {"{SHA}0ijZPTcJXMa+t2XnEbEwSOkvQu0=", "ccccccccc"},
+  {"{SHA}vNR9eUfJfcKmdkLDqNoKagho+qU=", "dddddddddd"},
+  {NULL}
+};
+
+#ifdef MMX_COEF
+/* Cygwin would not guarantee the alignment if these were declared static */
+#define buffer NSLDAP_buffer
+#define crypt_key NSLDAP_crypt_key
+#ifdef _MSC_VER
+__declspec(align(16)) unsigned char buffer[80*4*MMX_COEF];
+__declspec(align(16)) char crypt_key[BINARY_SIZE*MMX_COEF];
+#else
+unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16)));
+char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16)));
+#endif
+static char saved_key[(PLAINTEXT_LENGTH+4+1)*MMX_COEF]; // we add an extra DWORD to hold the 0x80 if the password is exactly PLAINTEXT_LENGTH bytes long)
+static unsigned long total_len;
+static unsigned char out[PLAINTEXT_LENGTH + 1];
+#else
+static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4];
+static char saved_key[PLAINTEXT_LENGTH + 1];
+#endif
+
+static void *
+binary(char *ciphertext) {
+  static char realcipher[BINARY_SIZE + 9];
+
+  /* stupid overflows */
+  memset(realcipher, 0, sizeof(realcipher));
+  base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
+  return (void *)realcipher;
+}
+
+static int
+valid(char *ciphertext, struct fmt_main *pFmt)
+{
+  if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH)
+    return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH);
+  return 0;
+}
+
+static int binary_hash_0(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xF;
+}
+
+static int binary_hash_1(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFF;
+}
+
+static int binary_hash_2(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFF;
+}
+
+static int binary_hash_3(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFF;
+}
+
+static int binary_hash_4(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFFF;
+}
+
+static int get_hash_0(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF;
+}
+
+static int get_hash_1(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF;
+}
+
+static int get_hash_2(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF;
+}
+
+static int get_hash_3(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFF;
+}
+
+static int get_hash_4(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFFF;
+}
+
+static void set_key(char *key, int index)
+{
+#ifdef MMX_COEF
+	int len;
+	int i;
+
+	if(index==0)
+	{
+		total_len = 0;
+		memset(saved_key, 0, sizeof(saved_key));
+	}
+	len = strlen(key);
+	if(len>PLAINTEXT_LENGTH)
+		len = PLAINTEXT_LENGTH;
+
+	total_len += len << ( ( (32/MMX_COEF) * index ) );
+	for(i=0;i<len;i++)
+		saved_key[GETPOS(i, index)] = key[i];
+
+	saved_key[GETPOS(i, index)] = 0x80;
+#else
+  strnzcpy(saved_key, key, sizeof(saved_key));
+#endif
+}
+
+static char *get_key(int index)
+{
+#ifdef MMX_COEF
+	unsigned int i,s;
+
+	s = (total_len >> (((32/MMX_COEF)*(index)))) & 0xff;
+	for(i=0;i<s;i++)
+		out[i] = saved_key[ GETPOS(i, index) ];
+	out[i] = 0;
+	return (char *) out;
+#else
+  return saved_key;
+#endif
+}
+
+static int
+cmp_all(void *binary, int count)
+{
+#ifdef MMX_COEF
+	int i = 0;
+	while(i< (BINARY_SIZE/4) )
+	{
+		if (
+			( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF])
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+1])
+#if (MMX_COEF > 3)
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2])
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3])
+#endif
+		)
+			return 0;
+		i++;
+	}
+	return 1;
+#else
+	return !memcmp(binary, crypt_key, BINARY_SIZE);
+#endif
+}
+
+static int
+cmp_exact(char *source, int index)
+{
+  return 1;
+}
+
+static int cmp_one(void * binary, int index)
+{
+#ifdef MMX_COEF
+	int i = 0;
+	for(i=0;i<(BINARY_SIZE/4);i++)
+		if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] )
+			return 0;
+	return 1;
+#else
+	return cmp_all(binary, index);
+#endif
+}
+
+static void
+crypt_all(int count) {
+#ifdef MMX_COEF
+	memcpy(buffer, saved_key, (PLAINTEXT_LENGTH+4)*MMX_COEF);
+	shammx((unsigned char *) crypt_key, buffer, total_len);
+#else
+  static SHA_CTX ctx;
+  SHA1_Init(&ctx);
+  SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key));
+  SHA1_Final((unsigned char *) crypt_key, &ctx);
+#endif
+}
+
+struct fmt_main fmt_NSLDAP = {
+	{
+		FORMAT_LABEL,
+		FORMAT_NAME,
+		ALGORITHM_NAME,
+		BENCHMARK_COMMENT,
+		BENCHMARK_LENGTH,
+		PLAINTEXT_LENGTH,
+		BINARY_SIZE,
+		SALT_SIZE,
+		MIN_KEYS_PER_CRYPT,
+		MAX_KEYS_PER_CRYPT,
+		FMT_CASE | FMT_8_BIT,
+		tests
+	}, {
+		fmt_default_init,
+		fmt_default_prepare,
+		valid,
+		fmt_default_split,
+		binary,
+		fmt_default_salt,
+		{
+			binary_hash_0,
+			binary_hash_1,
+			binary_hash_2,
+			binary_hash_3,
+			binary_hash_4
+		},
+		fmt_default_salt_hash,
+		fmt_default_set_salt,
+		set_key,
+		get_key,
+		fmt_default_clear_keys,
+		crypt_all,
+		{
+			get_hash_0,
+			get_hash_1,
+			get_hash_2,
+			get_hash_3,
+			get_hash_4
+		},
+		cmp_all,
+		cmp_one,
+		cmp_exact
+	}
+};
diff --git a/src/unused/OPENLDAPS_fmt_plug.c b/src/unused/OPENLDAPS_fmt_plug.c
new file mode 100644
index 0000000..41940b4
--- /dev/null
+++ b/src/unused/OPENLDAPS_fmt_plug.c
@@ -0,0 +1,330 @@
+// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26.
+/*
+ * Minor performance enhancement by bartavelle at bandecon.com
+ */
+
+#include <string.h>
+
+#include "arch.h"
+#include "misc.h"
+#include "params.h"
+#include "formats.h"
+#include "common.h"
+
+#include "sha.h"
+#include "base64.h"
+
+// This format has some MMX/SSE sha things in there but it's not completed.
+// We should re-work it to use sse-intrinsics
+#undef MMX_COEF
+#undef MMX_TYPE
+
+#define FORMAT_LABEL			"openssha"
+#define FORMAT_NAME			"OpenLDAP SSHA"
+
+#if defined(MMX_COEF) && MMX_COEF == 4
+#define ALGORITHM_NAME			"SSE2 4x"
+#elif defined(MMX_COEF) && MMX_COEF == 2
+#define ALGORITHM_NAME			"MMX 2x"
+#elif defined(MMX_COEF)
+#define ALGORITHM_NAME			"?"
+#else
+#define ALGORITHM_NAME			"32/" ARCH_BITS_STR
+#endif
+
+#define BENCHMARK_COMMENT		""
+#define BENCHMARK_LENGTH		0
+
+#define PLAINTEXT_LENGTH		32
+#define CIPHERTEXT_LENGTH		32
+
+#define BINARY_SIZE			20
+#define SALT_SIZE			4
+
+#ifdef MMX_COEF
+#define MIN_KEYS_PER_CRYPT		MMX_COEF
+#define MAX_KEYS_PER_CRYPT		MMX_COEF
+#define GETPOS(i, index)		( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) )
+#else
+#define MIN_KEYS_PER_CRYPT		1
+#define MAX_KEYS_PER_CRYPT		1
+#endif
+
+#define NSLDAP_MAGIC "{ssha}"
+#define NSLDAP_MAGIC_LENGTH 6
+
+static struct fmt_tests tests[] = {
+	{"{SSHA}bPXG4M1KkwZh2Hbgnuoszvpat0T/OS86", "thales"},
+	{"{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X", "test1"},
+	{"{SSHA}pXp4yIiRmppvKYn7cKCT+lngG4qELq4h", "test2"},
+	{"{SSHA}Bv8tu3wB8WTMJj3tcOsl1usm5HzGwEmv", "test3"},
+	{"{SSHA}kXyh8wLCKbN+QRbL2F2aUbkP62BJ/bRg", "lapin"},
+	{"{SSHA}rnMVxsf1YJPg0L5CBhbVLIsJF+o/vkoE", "canard"},
+	{"{SSHA}Uf2x9YxSWZZNAi2t1QXbG2PmT07AtURl", "chien"},
+	{"{SSHA}XXGLZ7iKpYSBpF6EwoeTl27U0L/kYYsY", "hibou"},
+	{"{SSHA}HYRPmcQIIzIIg/c1L8cZKlYdNpyeZeml", "genou"},
+	{"{SSHA}Zm/0Wll7rLNpBU4HFUKhbASpXr94eSTc", "caillou"},
+	{"{SSHA}Qc9OB+aEFA/mJ5MNy0AB4hRIkNiAbqDb", "doudou"},
+	{NULL}
+};
+
+#ifdef MMX_COEF
+static char crypt_key[BINARY_SIZE*MMX_COEF];
+/* Cygwin would not guarantee the alignment for this static declaration, but
+ * this source file is not MMX-ready anyway (MMX_COEF is #undef'ed above). */
+static char saved_key[80*MMX_COEF*4] __attribute__ ((aligned(8*MMX_COEF)));
+static unsigned char out[PLAINTEXT_LENGTH + 1];
+#else
+static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4];
+static char saved_key[PLAINTEXT_LENGTH + 1];
+#endif
+
+#ifdef MMX_COEF
+static unsigned long length[MAX_KEYS_PER_CRYPT];
+#endif
+
+static char saved_salt[SALT_SIZE];
+
+static void * binary(char *ciphertext) {
+  static char *realcipher;
+
+  if (!realcipher) realcipher = mem_alloc_tiny(BINARY_SIZE + SALT_SIZE + 9, MEM_ALIGN_WORD);
+
+  /* stupid overflows */
+  memset(realcipher, 0, BINARY_SIZE + SALT_SIZE + 9);
+  base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
+#ifdef MMX_COEF
+  alter_endianity((unsigned char*)realcipher, BINARY_SIZE);
+#endif
+  return (void *)realcipher;
+}
+
+static void * get_salt(char * ciphertext)
+{
+	static char *realcipher;
+
+	if (!realcipher) realcipher = mem_alloc_tiny(BINARY_SIZE + SALT_SIZE + 9, MEM_ALIGN_WORD);
+
+	memset(realcipher, 0, BINARY_SIZE + SALT_SIZE + 9);
+	base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher);
+	return (void*)&realcipher[BINARY_SIZE];
+}
+
+static int valid(char *ciphertext, struct fmt_main *pFmt)
+{
+	if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH + NSLDAP_MAGIC_LENGTH)
+		return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH);
+	return 0;
+}
+
+static int binary_hash_0(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xF;
+}
+
+static int binary_hash_1(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFF;
+}
+
+static int binary_hash_2(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFF;
+}
+
+static int binary_hash_3(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFF;
+}
+
+static int binary_hash_4(void *binary)
+{
+	return ((ARCH_WORD_32 *)binary)[0] & 0xFFFFF;
+}
+
+static int get_hash_0(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF;
+}
+
+static int get_hash_1(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF;
+}
+
+static int get_hash_2(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF;
+}
+
+static int get_hash_3(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFF;
+}
+
+static int get_hash_4(int index)
+{
+	return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFFFF;
+}
+
+static int salt_hash(void *salt)
+{
+	return *((ARCH_WORD_32 *)salt) & (SALT_HASH_SIZE - 1);
+}
+
+static void set_key(char *key, int index)
+{
+#ifdef MMX_COEF
+	int len;
+	int i;
+
+	if(index==0)
+	{
+		memset(saved_key, 0, sizeof(saved_key));
+	}
+	len = strlen(key);
+	if(len>PLAINTEXT_LENGTH)
+		len = PLAINTEXT_LENGTH;
+
+	length[index] = len;
+
+	for(i=0;i<len;i++)
+		saved_key[GETPOS(i, index)] = key[i];
+
+	saved_key[GETPOS( (i+SALT_SIZE) , index)] = 0x80;
+	((unsigned int *)saved_key)[15*MMX_COEF+index] = (len+SALT_SIZE)<<3;
+#else
+	strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1);
+#endif
+}
+
+static void set_salt(void *salt)
+{
+	memcpy(saved_salt, salt, SALT_SIZE);
+}
+
+static char *get_key(int index)
+{
+#ifdef MMX_COEF
+	unsigned int i,s;
+
+	s = length[index];
+	for(i=0;i<s;i++)
+		out[i] = saved_key[ GETPOS(i, index) ];
+	out[i] = 0;
+	return (char*)out;
+#else
+  return saved_key;
+#endif
+}
+
+static int
+cmp_all(void *binary, int index)
+{
+#ifdef MMX_COEF
+	int i = 0;
+	while(i< (BINARY_SIZE/4) )
+	{
+		if (
+			( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF])
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+1])
+#if (MMX_COEF > 3)
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2])
+			&& ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3])
+#endif
+		)
+			return 0;
+		i++;
+	}
+	return 1;
+#else
+	return !memcmp(binary, crypt_key, BINARY_SIZE);
+#endif
+}
+
+static int
+cmp_exact(char *source, int index)
+{
+  return 1;
+}
+
+static int cmp_one(void * binary, int index)
+{
+#ifdef MMX_COEF
+	int i = 0;
+	for(i=0;i<(BINARY_SIZE/4);i++)
+		if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] )
+			return 0;
+	return 1;
+#else
+	return cmp_all(binary, index);
+#endif
+}
+
+
+static void crypt_all(int count)
+{
+#ifdef MMX_COEF
+	int i,idx;
+
+	for(idx=0;idx<MAX_KEYS_PER_CRYPT;idx++)
+	{
+		for(i=0;i<SALT_SIZE;i++)
+			saved_key[GETPOS((i+length[idx]),idx)] = ((unsigned char *)saved_salt)[i];
+	}
+	shammx((unsigned char*)crypt_key, (unsigned char*)saved_key);
+#else
+	static SHA_CTX ctx;
+	SHA1_Init(&ctx);
+	SHA1_Update(&ctx, (unsigned char*)saved_key, strlen(saved_key));
+	SHA1_Update(&ctx, (unsigned char*)saved_salt, SALT_SIZE);
+	SHA1_Final((unsigned char*)crypt_key, &ctx);
+#endif
+}
+
+struct fmt_main fmt_OPENLDAPS = {
+	{
+		FORMAT_LABEL,
+		FORMAT_NAME,
+		ALGORITHM_NAME,
+		BENCHMARK_COMMENT,
+		BENCHMARK_LENGTH,
+		PLAINTEXT_LENGTH,
+		BINARY_SIZE,
+		SALT_SIZE,
+		MIN_KEYS_PER_CRYPT,
+		MAX_KEYS_PER_CRYPT,
+		FMT_CASE | FMT_8_BIT,
+		tests
+	}, {
+		fmt_default_init,
+		fmt_default_prepare,
+		valid,
+		fmt_default_split,
+		binary,
+		get_salt,
+		{
+			binary_hash_0,
+			binary_hash_1,
+			binary_hash_2,
+			binary_hash_3,
+			binary_hash_4
+		},
+		salt_hash,
+		set_salt,
+		set_key,
+		get_key,
+		fmt_default_clear_keys,
+		crypt_all,
+		{
+			get_hash_0,
+			get_hash_1,
+			get_hash_2,
+			get_hash_3,
+			get_hash_4
+		},
+		cmp_all,
+		cmp_one,
+		cmp_exact
+	}
+};
-- 
1.7.5.4

