[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Fri, 20 Jun 2008 12:59:34 +0200
From: "Samuel Moñux" <smonux@...il.com>
To: john-users@...ts.openwall.com
Subject: NetscreenOS passwords
Hello everyone,
I have made a little patch for auditing Netscreen OS passwords. It's not
very efficient and probably doesn't meet the code quality standards of John
the ripper's, but it may be of help to someone, or the seed for a better
implementation. I haven't tested it on big endian machines so probably it's
not endian-safe.
I became intrigued about the format of Netscreen passwords, since it was
undocumented, and had clear signs of obfuscation. I did my research
decompiling a Java application called NSM (Netscreen Security Manager).
Since the bytecode files were not obfuscated, it was very easy to find how
the password was generated. After doing this, I found that someone had
already done it the hard way[1], but without publishing his "John the
ripper" patch, which seemed an interesting exercise.
NetscreenOS passwords are basically raw MD5, where the username and a
constant string(":Administration Tools:") are used as the salt. The 128 bits
MD5 hash is mapped to characters in the range [A-Za-z0-9+/] in a weird
manner: every 16 bits word is splitted in 3 parts of 4bits, 6bits and 6bits.
These parts are used as indexes in an array which contains every character
in that range.
After that, a further obfuscation is performed. The characters of the string
"nrcstn"(netscreen without the vowels and reversed) are interpolated in
certain positions. The final password looks like this:
nMjFM0rdC9iOc+xIFsGEm3LtAeGZhn
As I said, I hope it may be of help to someone. It was fun to do the
research and the coding.
Best regards,
Samuel
[1]
http://esec.fr.sogeti.com/blog/dotclear/?2008/01/03/23-chiffrement-des-mots-de-passe-
netscreen
-3-3-analyse-de-la-fonction-de-chiffrement-et-cassage-des-mots-de-passe
[ CONTENT OF TYPE text/html SKIPPED ]
diff -urpN john-1.7.2-orig/src/john.c john-1.7.2/src/john.c
--- john-1.7.2-orig/src/john.c 2006-05-08 14:48:48.000000000 +0000
+++ john-1.7.2/src/john.c 2008-06-19 12:01:26.000000000 +0000
@@ -36,7 +36,7 @@
extern int CPU_detect(void);
#endif
-extern struct fmt_main fmt_DES, fmt_BSDI, fmt_MD5, fmt_BF;
+extern struct fmt_main fmt_DES, fmt_BSDI, fmt_MD5, fmt_BF, fmt_NS;
extern struct fmt_main fmt_AFS, fmt_LM;
extern int unshadow(int argc, char **argv);
@@ -64,6 +64,7 @@ static void john_register_all(void)
john_register_one(&fmt_BF);
john_register_one(&fmt_AFS);
john_register_one(&fmt_LM);
+ john_register_one(&fmt_NS);
if (!fmt_list) {
fprintf(stderr, "Unknown ciphertext format name requested\n");
diff -urpN john-1.7.2-orig/src/Makefile john-1.7.2/src/Makefile
--- john-1.7.2-orig/src/Makefile 2006-05-15 16:38:00.000000000 +0000
+++ john-1.7.2/src/Makefile 2008-06-20 10:31:12.000000000 +0000
@@ -17,7 +17,7 @@ NULL = /dev/null
CPPFLAGS = -E
CFLAGS = -c -Wall -O2 -fomit-frame-pointer
ASFLAGS = -c
-LDFLAGS = -s
+LDFLAGS = -s
OPT_NORMAL = -funroll-loops
OPT_INLINE = -finline-functions
@@ -34,7 +34,9 @@ JOHN_OBJS_MINIMAL = \
recovery.o rpp.o rules.o signals.o single.o status.o tty.o wordlist.o \
unshadow.o \
unafs.o \
- unique.o
+ unique.o \
+ md5.o \
+ NS_fmt.o
JOHN_OBJS_ORIG = \
$(JOHN_OBJS_MINIMAL) \
@@ -60,7 +62,7 @@ BENCH_BF_OBJS_DEPEND = \
BENCH_OBJS = \
$(BENCH_DES_OBJS_DEPEND) \
- DES_bs.o $(BENCH_DES_BS_OBJS_DEPEND) \
+ DES_bs.o $(BENCH_DES_BS_OBJS_DEPEND) NS_fmt.o \
$(BENCH_MD5_OBJS_DEPEND) \
BF_fmt.o $(BENCH_BF_OBJS_DEPEND) \
bench.o best.o common.o config.o formats.o math.o memory.o miscnl.o \
diff -urpN john-1.7.2-orig/src/md5.c john-1.7.2/src/md5.c
--- john-1.7.2-orig/src/md5.c 1970-01-01 00:00:00.000000000 +0000
+++ john-1.7.2/src/md5.c 2008-06-19 11:59:52.000000000 +0000
@@ -0,0 +1,274 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
+ * Inc. MD5 Message-Digest Algorithm.
+ *
+ * Written by Solar Designer <solar@...nwall.com> in 2001, and placed in
+ * the public domain. There's absolutely no warranty.
+ *
+ * This differs from Colin Plumb's older public domain implementation in
+ * that no 32-bit integer data type is required, there's no compile-time
+ * endianness configuration, and the function prototypes match OpenSSL's.
+ * The primary goals are portability and ease of use.
+ *
+ * This implementation is meant to be fast, but not as fast as possible.
+ * Some known optimizations are not included to reduce source code size
+ * and avoid compile-time configuration.
+ */
+
+#ifndef HAVE_OPENSSL
+
+#include <string.h>
+#include "common.h"
+#include "md5.h"
+
+/*
+ * The basic MD5 functions.
+ *
+ * F is optimized compared to its RFC 1321 definition just like in Colin
+ * Plumb's implementation.
+ */
+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
+
+/*
+ * The MD5 transformation for all four rounds.
+ */
+#define STEP(f, a, b, c, d, x, t, s) \
+ (a) += f((b), (c), (d)) + (x) + (t); \
+ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
+ (a) += (b);
+
+/*
+ * SET reads 4 input bytes in little-endian byte order and stores them
+ * in a properly aligned word in host byte order.
+ *
+ * The check for little-endian architectures which tolerate unaligned
+ * memory accesses is just an optimization. Nothing will break if it
+ * doesn't work.
+ */
+#if defined(__i386__) || defined(__vax__)
+#define SET(n) \
+ (*(MD5_u32plus *)&ptr[(n) * 4])
+#define GET(n) \
+ SET(n)
+#else
+#define SET(n) \
+ (ctx->block[(n)] = \
+ (MD5_u32plus)ptr[(n) * 4] | \
+ ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
+ ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
+#define GET(n) \
+ (ctx->block[(n)])
+#endif
+
+/*
+ * This processes one or more 64-byte data blocks, but does NOT update
+ * the bit counters. There're no alignment requirements.
+ */
+static void *body(MD5_CTX *ctx, void *data, unsigned long size)
+{
+ unsigned char *ptr;
+ MD5_u32plus a, b, c, d;
+ MD5_u32plus saved_a, saved_b, saved_c, saved_d;
+
+ ptr = data;
+
+ a = ctx->a;
+ b = ctx->b;
+ c = ctx->c;
+ d = ctx->d;
+
+ do {
+ saved_a = a;
+ saved_b = b;
+ saved_c = c;
+ saved_d = d;
+
+/* Round 1 */
+ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
+ STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
+ STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
+ STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
+ STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
+ STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
+ STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
+ STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
+ STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
+ STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
+ STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
+ STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
+ STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
+ STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
+ STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
+ STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
+
+/* Round 2 */
+ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
+ STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
+ STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
+ STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
+ STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
+ STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
+ STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
+ STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
+ STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
+ STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
+ STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
+ STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
+ STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
+ STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
+ STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
+ STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
+
+/* Round 3 */
+ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
+ STEP(H, d, a, b, c, GET(8), 0x8771f681, 11)
+ STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
+ STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23)
+ STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
+ STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11)
+ STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
+ STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23)
+ STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
+ STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11)
+ STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
+ STEP(H, b, c, d, a, GET(6), 0x04881d05, 23)
+ STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
+ STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11)
+ STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
+ STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23)
+
+/* Round 4 */
+ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
+ STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
+ STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
+ STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
+ STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
+ STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
+ STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
+ STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
+ STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
+ STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
+ STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
+ STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
+ STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
+ STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
+ STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
+ STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
+
+ a += saved_a;
+ b += saved_b;
+ c += saved_c;
+ d += saved_d;
+
+ ptr += 64;
+ } while (size -= 64);
+
+ ctx->a = a;
+ ctx->b = b;
+ ctx->c = c;
+ ctx->d = d;
+
+ return ptr;
+}
+
+void MD5_Init(MD5_CTX *ctx)
+{
+ ctx->a = 0x67452301;
+ ctx->b = 0xefcdab89;
+ ctx->c = 0x98badcfe;
+ ctx->d = 0x10325476;
+
+ ctx->lo = 0;
+ ctx->hi = 0;
+}
+
+void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size)
+{
+ MD5_u32plus saved_lo;
+ unsigned long used, free;
+
+ saved_lo = ctx->lo;
+ if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
+ ctx->hi++;
+ ctx->hi += size >> 29;
+
+ used = saved_lo & 0x3f;
+
+ if (used) {
+ free = 64 - used;
+
+ if (size < free) {
+ memcpy(&ctx->buffer[used], data, size);
+ return;
+ }
+
+ memcpy(&ctx->buffer[used], data, free);
+ data = (unsigned char *)data + free;
+ size -= free;
+ body(ctx, ctx->buffer, 64);
+ }
+
+ if (size >= 64) {
+ data = body(ctx, data, size & ~(unsigned long)0x3f);
+ size &= 0x3f;
+ }
+
+ memcpy(ctx->buffer, data, size);
+}
+
+void MD5_Final(unsigned char *result, MD5_CTX *ctx)
+{
+ unsigned long used, free;
+
+ used = ctx->lo & 0x3f;
+
+ ctx->buffer[used++] = 0x80;
+
+ free = 64 - used;
+
+ if (free < 8) {
+ memset(&ctx->buffer[used], 0, free);
+ body(ctx, ctx->buffer, 64);
+ used = 0;
+ free = 64;
+ }
+
+ memset(&ctx->buffer[used], 0, free - 8);
+
+ ctx->lo <<= 3;
+ ctx->buffer[56] = ctx->lo;
+ ctx->buffer[57] = ctx->lo >> 8;
+ ctx->buffer[58] = ctx->lo >> 16;
+ ctx->buffer[59] = ctx->lo >> 24;
+ ctx->buffer[60] = ctx->hi;
+ ctx->buffer[61] = ctx->hi >> 8;
+ ctx->buffer[62] = ctx->hi >> 16;
+ ctx->buffer[63] = ctx->hi >> 24;
+
+ body(ctx, ctx->buffer, 64);
+
+ result[0] = ctx->a;
+ result[1] = ctx->a >> 8;
+ result[2] = ctx->a >> 16;
+ result[3] = ctx->a >> 24;
+ result[4] = ctx->b;
+ result[5] = ctx->b >> 8;
+ result[6] = ctx->b >> 16;
+ result[7] = ctx->b >> 24;
+ result[8] = ctx->c;
+ result[9] = ctx->c >> 8;
+ result[10] = ctx->c >> 16;
+ result[11] = ctx->c >> 24;
+ result[12] = ctx->d;
+ result[13] = ctx->d >> 8;
+ result[14] = ctx->d >> 16;
+ result[15] = ctx->d >> 24;
+
+ memset(ctx, 0, sizeof(*ctx));
+}
+
+#endif
diff -urpN john-1.7.2-orig/src/md5.h john-1.7.2/src/md5.h
--- john-1.7.2-orig/src/md5.h 1970-01-01 00:00:00.000000000 +0000
+++ john-1.7.2/src/md5.h 2008-06-19 11:59:52.000000000 +0000
@@ -0,0 +1,35 @@
+/*
+ * This is an OpenSSL-compatible implementation of the RSA Data Security,
+ * Inc. MD5 Message-Digest Algorithm.
+ *
+ * Written by Solar Designer <solar@...nwall.com> in 2001, and placed in
+ * the public domain. See md5.c for more information.
+ */
+
+#ifdef HAVE_OPENSSL
+#include <openssl/md5.h>
+#elif !defined(_MD5_H)
+#define _MD5_H
+
+/* Any 32-bit or wider unsigned integer data type will do */
+typedef unsigned long MD5_u32plus;
+
+typedef struct {
+ MD5_u32plus lo, hi;
+ MD5_u32plus a, b, c, d;
+ unsigned char buffer[64];
+ MD5_u32plus block[16];
+} MD5_CTX;
+
+extern void MD5_Init(MD5_CTX *ctx);
+extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size);
+extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
+
+#ifdef MMX_COEF
+extern int mdfivemmx(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3)));
+extern int mdfivemmx_nosizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3)));
+extern int mdfivemmx_noinit_sizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3)));
+extern int mdfivemmx_noinit_uniformsizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3)));
+#endif
+
+#endif
diff -urpN john-1.7.2-orig/src/NS_fmt.c john-1.7.2/src/NS_fmt.c
--- john-1.7.2-orig/src/NS_fmt.c 1970-01-01 00:00:00.000000000 +0000
+++ john-1.7.2/src/NS_fmt.c 2008-06-20 10:17:02.000000000 +0000
@@ -0,0 +1,229 @@
+/*
+ */
+
+#include <string.h>
+
+#include "arch.h"
+#include "misc.h"
+#include "md5.h"
+#include "common.h"
+#include "formats.h"
+
+#define FORMAT_LABEL "md5ns"
+#define FORMAT_NAME "Netscreen MD5"
+#define NS_ALGORITHM_NAME "NS MD5"
+
+#define BENCHMARK_COMMENT ""
+#define BENCHMARK_LENGTH -1
+
+#define PLAINTEXT_LENGTH 15
+#define CIPHERTEXT_LENGTH 50
+
+#define BINARY_SIZE 16
+#define SALT_SIZE 32
+
+#define MIN_KEYS_PER_CRYPT 1
+#define MAX_KEYS_PER_CRYPT 1
+
+
+static struct fmt_tests tests[] = {
+ {"admin$nMjFM0rdC9iOc+xIFsGEm3LtAeGZhn", "password"},
+ {"a$nMf9FkrCIgHGccRAxsBAwxBtDtPHfn", "netscreen"},
+ {NULL}
+};
+
+static unsigned short e64toshort[256];
+
+#define ADM_LEN 22
+static int salt_len, key_len;
+static char cipher_salt[ SALT_SIZE ];
+static char cipher_key[ PLAINTEXT_LENGTH + 1 ];
+static char *adm = ":Administration Tools:";
+static char tocipher[ SALT_SIZE + ADM_LEN + PLAINTEXT_LENGTH ];
+static MD5_u32plus crypted[4];
+
+
+static void NS_init()
+{
+ int i;
+ static char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ char *pos;
+ for (pos = b64, i = 0 ; *pos != 0 ; pos++, i++)
+ e64toshort[(int)*pos] = i;
+}
+
+static int NS_valid(char *ciphertext)
+{
+ char *password;
+ static char *netscreen = "nrcstn" ;
+ static int p[] = { 0, 6, 12, 17, 23, 29 };
+ int i;
+
+ password = ciphertext;
+
+ while ((*password != '$') && (*password != '\0' ))
+ password++;
+ if (*password == '\0') return 0;
+ password++;
+
+ if (strlen(password) != 30) return 0;
+ for (i = 0; i < 6 ; i++)
+ if (netscreen[i] != password[p[i]]) return 0;
+
+ for (i = 0; i < 30 ; i++) {
+ char c = password[i];
+ if (((c >= 'A') && ( c <= 'Z')) ||
+ ((c >= 'a') && ( c <= 'z')) ||
+ ((c >= '0') && ( c <= '9')) ||
+ (c == '+') || ( c == '/'))
+ continue;
+ return 0;
+ }
+ return 1;
+}
+
+static MD5_u32plus *NS_std_get_binary(char *ciphertext)
+{
+ static union {
+ MD5_u32plus w[4];
+ char b[16];
+ } out;
+ char unscrambled[24];
+ int i;
+ MD5_u32plus a, b, c;
+ MD5_u32plus d, e, f;
+ char *pos;
+#if ARCH_LITTLE_ENDIAN
+ MD5_u32plus temp;
+#endif
+
+ pos = ciphertext;
+ while (*pos++ != '$');
+
+ memcpy(unscrambled, pos + 1, 6 );
+ memcpy(unscrambled + 5, pos + 7, 6 );
+ memcpy(unscrambled + 10, pos + 13, 5 );
+ memcpy(unscrambled + 14, pos + 18, 6 );
+ memcpy(unscrambled + 19, pos + 24, 5 );
+
+ for ( i = 0 ; i < 4 ; i++ ) {
+ a = e64toshort[ARCH_INDEX(unscrambled[6*i])];
+ b = e64toshort[ARCH_INDEX(unscrambled[6*i + 1 ])];
+ c = e64toshort[ARCH_INDEX(unscrambled[6*i + 2 ])];
+ d = e64toshort[ARCH_INDEX(unscrambled[6*i + 3 ])];
+ e = e64toshort[ARCH_INDEX(unscrambled[6*i + 4 ])];
+ f = e64toshort[ARCH_INDEX(unscrambled[6*i + 5 ])];
+#if ARCH_LITTLE_ENDIAN
+ temp = (((a << 12) | (b << 6) | (c)) << 16) |
+ ((d << 12) | (e << 6) | (f));
+ out.w[i] = ((temp << 24) & 0xff000000 ) |
+ ((temp << 8) & 0x00ff0000 ) |
+ ((temp >> 8) & 0x0000ff00 ) |
+ ((temp >> 24) & 0x000000ff );
+#else
+ out.w[i] = (((a << 12) | (b << 6) | (c)) << 16) |
+ ((d << 12) | (e << 6) | (f));
+#endif
+ }
+
+ return out.w;
+}
+
+char *NS_std_get_salt(char *ciphertext)
+{
+ static char out[SALT_SIZE + 1];
+ char *ipos, *opos;
+
+ ipos = ciphertext;
+ opos = out;
+ while (*ipos != '$') *opos++ = *ipos++;
+ *opos = '\0';
+
+ return out;
+}
+
+void NS_std_set_salt (void *salt)
+{
+ salt_len = strlen((char *) salt);
+ memcpy(cipher_salt, salt , salt_len);
+}
+
+static void NS_set_key(char *key, int index)
+{
+ key_len = strlen((char *) key);
+ memcpy(cipher_key, key, strlen(key) + 1 );
+}
+
+static char *NS_get_key()
+{
+ return cipher_key;
+}
+
+static void NS_std_crypt()
+{
+ MD5_CTX ctx;
+ MD5_Init(&ctx);
+ memcpy(tocipher, cipher_salt, salt_len);
+ memcpy(tocipher + salt_len, adm, ADM_LEN);
+ memcpy(tocipher + salt_len + ADM_LEN, cipher_key, key_len);
+ MD5_Update(&ctx , tocipher, salt_len + ADM_LEN + key_len);
+ MD5_Final((void*)crypted, &ctx);
+}
+
+static int NS_cmp_all(void *binary, int index)
+{
+ int i;
+ for ( i = 0 ; i < 4 ; i++ ) {
+ if(((MD5_u32plus *)binary)[i]!=((MD5_u32plus*)crypted)[i]) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int NS_cmp_exact(char *source, int index)
+{
+ return 1;
+}
+
+struct fmt_main fmt_NS = {
+ {
+ FORMAT_LABEL,
+ FORMAT_NAME,
+ NS_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
+ }, {
+ NS_init,
+ NS_valid,
+ fmt_default_split,
+ (void *(*)(char *))NS_std_get_binary,
+ (void *(*)(char *))NS_std_get_salt,
+ {
+ fmt_default_binary_hash,
+ fmt_default_binary_hash,
+ fmt_default_binary_hash
+ },
+ fmt_default_salt_hash,
+ NS_std_set_salt,
+ NS_set_key,
+ NS_get_key,
+ fmt_default_clear_keys,
+ NS_std_crypt,
+ {
+ fmt_default_get_hash,
+ fmt_default_get_hash,
+ fmt_default_get_hash
+ },
+ NS_cmp_all,
+ NS_cmp_all,
+ NS_cmp_exact
+ }
+};
--
To unsubscribe, e-mail john-users-unsubscribe@...ts.openwall.com and reply
to the automated confirmation request that will be sent to you.
Powered by blists - more mailing lists
Powered by Openwall GNU/*/Linux -
Powered by OpenVZ