From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- release/src/router/busybox/libbb/pw_encrypt_md5.c | 161 ++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 release/src/router/busybox/libbb/pw_encrypt_md5.c (limited to 'release/src/router/busybox/libbb/pw_encrypt_md5.c') diff --git a/release/src/router/busybox/libbb/pw_encrypt_md5.c b/release/src/router/busybox/libbb/pw_encrypt_md5.c new file mode 100644 index 00000000..58964b56 --- /dev/null +++ b/release/src/router/busybox/libbb/pw_encrypt_md5.c @@ -0,0 +1,161 @@ +/* + * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + * + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + * + * $FreeBSD: src/lib/libmd/md5c.c,v 1.9.2.1 1999/08/29 14:57:12 peter Exp $ + * + * This code is the same as the code published by RSA Inc. It has been + * edited for clarity and style only. + * + * ---------------------------------------------------------------------------- + * The md5_crypt() function was taken from freeBSD's libcrypt and contains + * this license: + * "THE BEER-WARE LICENSE" (Revision 42): + * wrote this file. As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp + * + * $FreeBSD: src/lib/libcrypt/crypt.c,v 1.7.2.1 1999/08/29 14:56:33 peter Exp $ + * + * ---------------------------------------------------------------------------- + * On April 19th, 2001 md5_crypt() was modified to make it reentrant + * by Erik Andersen + * + * + * June 28, 2001 Manuel Novoa III + * + * "Un-inlined" code using loops and static const tables in order to + * reduce generated code size (on i386 from approx 4k to approx 2.5k). + * + * June 29, 2001 Manuel Novoa III + * + * Completely removed static PADDING array. + * + * Reintroduced the loop unrolling in MD5_Transform and added the + * MD5_SIZE_OVER_SPEED option for configurability. Define below as: + * 0 fully unrolled loops + * 1 partially unrolled (4 ops per loop) + * 2 no unrolling -- introduces the need to swap 4 variables (slow) + * 3 no unrolling and all 4 loops merged into one with switch + * in each loop (glacial) + * On i386, sizes are roughly (-Os -fno-builtin): + * 0: 3k 1: 2.5k 2: 2.2k 3: 2k + * + * Since SuSv3 does not require crypt_r, modified again August 7, 2002 + * by Erik Andersen to remove reentrance stuff... + */ + +/* + * UNIX password + * + * Use MD5 for what it is best at... + */ +#define MD5_OUT_BUFSIZE 36 +static char * +NOINLINE +md5_crypt(char result[MD5_OUT_BUFSIZE], const unsigned char *pw, const unsigned char *salt) +{ + char *p; + unsigned char final[17]; /* final[16] exists only to aid in looping */ + int sl, pl, i, pw_len; + md5_ctx_t ctx, ctx1; + + /* NB: in busybox, "$1$" in salt is always present */ + + /* Refine the Salt first */ + + /* Get the length of the salt including "$1$" */ + sl = 3; + while (salt[sl] && salt[sl] != '$' && sl < (3 + 8)) + sl++; + + /* Hash. the password first, since that is what is most unknown */ + md5_begin(&ctx); + pw_len = strlen((char*)pw); + md5_hash(pw, pw_len, &ctx); + + /* Then the salt including "$1$" */ + md5_hash(salt, sl, &ctx); + + /* Copy salt to result; skip "$1$" */ + memcpy(result, salt, sl); + result[sl] = '$'; + salt += 3; + sl -= 3; + + /* Then just as many characters of the MD5(pw, salt, pw) */ + md5_begin(&ctx1); + md5_hash(pw, pw_len, &ctx1); + md5_hash(salt, sl, &ctx1); + md5_hash(pw, pw_len, &ctx1); + md5_end(final, &ctx1); + for (pl = pw_len; pl > 0; pl -= 16) + md5_hash(final, pl > 16 ? 16 : pl, &ctx); + + /* Then something really weird... */ + memset(final, 0, sizeof(final)); + for (i = pw_len; i; i >>= 1) { + md5_hash(((i & 1) ? final : (const unsigned char *) pw), 1, &ctx); + } + md5_end(final, &ctx); + + /* And now, just to make sure things don't run too fast. + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for (i = 0; i < 1000; i++) { + md5_begin(&ctx1); + if (i & 1) + md5_hash(pw, pw_len, &ctx1); + else + md5_hash(final, 16, &ctx1); + + if (i % 3) + md5_hash(salt, sl, &ctx1); + + if (i % 7) + md5_hash(pw, pw_len, &ctx1); + + if (i & 1) + md5_hash(final, 16, &ctx1); + else + md5_hash(pw, pw_len, &ctx1); + md5_end(final, &ctx1); + } + + p = result + sl + 4; /* 12 bytes max (sl is up to 8 bytes) */ + + /* Add 5*4+2 = 22 bytes of hash, + NUL byte. */ + final[16] = final[5]; + for (i = 0; i < 5; i++) { + unsigned l = (final[i] << 16) | (final[i+6] << 8) | final[i+12]; + p = to64(p, l, 4); + } + p = to64(p, final[11], 2); + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final, 0, sizeof(final)); + + return result; +} -- cgit v1.2.3-54-g00ecf