X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Fpw_encrypt.c;h=bfc7030a8387f81daa44ce8f1ccc6f50e3380233;hb=b432923e29dcd8c6f3a528bb9d61952de68e790c;hp=762cbab27ab001ea498b8d5792242beebe31ecac;hpb=fdddab0c61c55c25d4218d4370e2b16a7936a794;p=oweals%2Fbusybox.git diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 762cbab27..bfc7030a8 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -1,27 +1,99 @@ /* vi: set sw=4 ts=4: */ /* - * Utility routine. + * Utility routines. * * Copyright (C) 1999-2004 by Erik Andersen * - * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #include "libbb.h" +/* static const uint8_t ascii64[] = + * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + */ + +static int i64c(int i) +{ + i &= 0x3f; + if (i == 0) + return '.'; + if (i == 1) + return '/'; + if (i < 12) + return ('0' - 2 + i); + if (i < 38) + return ('A' - 12 + i); + return ('a' - 38 + i); +} + +int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) +{ + /* was: x += ... */ + int x = getpid() + monotonic_us(); + do { + /* x = (x*1664525 + 1013904223) % 2^32 generator is lame + * (low-order bit is not "random", etc...), + * but for our purposes it is good enough */ + x = x*1664525 + 1013904223; + /* BTW, Park and Miller's "minimal standard generator" is + * x = x*16807 % ((2^31)-1) + * It has no problem with visibly alternating lowest bit + * but is also weak in cryptographic sense + needs div, + * which needs more code (and slower) on many CPUs */ + *p++ = i64c(x >> 16); + *p++ = i64c(x >> 22); + } while (--cnt); + *p = '\0'; + return x; +} + +char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) +{ + int len = 2/2; + char *salt_ptr = salt; + if (algo[0] != 'd') { /* not des */ + len = 8/2; /* so far assuming md5 */ + *salt_ptr++ = '$'; + *salt_ptr++ = '1'; + *salt_ptr++ = '$'; +#if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA + if (algo[0] == 's') { /* sha */ + salt[1] = '5' + (strcmp(algo, "sha512") == 0); + len = 16/2; + } +#endif + } + crypt_make_salt(salt_ptr, len); + return salt_ptr; +} + +#if ENABLE_USE_BB_CRYPT + +static char* +to64(char *s, unsigned v, int n) +{ + while (--n >= 0) { + /* *s++ = ascii64[v & 0x3f]; */ + *s++ = i64c(v); + v >>= 6; + } + return s; +} + /* * DES and MD5 crypt implementations are taken from uclibc. * They were modified to not use static buffers. - * Comparison with uclibc (before uclibc had 70k staic buffers reinstated): - * text data bss dec hex filename - * 759909 604 6684 767197 bb4dd busybox_old - * 759579 604 6684 766867 bb393 busybox_unstripped */ -/* Common for them */ -static const uint8_t ascii64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + #include "pw_encrypt_des.c" #include "pw_encrypt_md5.c" +#if ENABLE_USE_BB_CRYPT_SHA +#include "pw_encrypt_sha.c" +#endif +/* Other advanced crypt ids (TODO?): */ +/* $2$ or $2a$: Blowfish */ static struct const_des_ctx *des_cctx; static struct des_ctx *des_ctx; @@ -29,18 +101,20 @@ static struct des_ctx *des_ctx; /* my_crypt returns malloc'ed data */ static char *my_crypt(const char *key, const char *salt) { - /* First, check if we are supposed to be using the MD5 replacement - * instead of DES... */ - if (salt[0] == '$' && salt[1] == '1' && salt[2] == '$') { - return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); + /* MD5 or SHA? */ + if (salt[0] == '$' && salt[1] && salt[2] == '$') { + if (salt[1] == '1') + return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); +#if ENABLE_USE_BB_CRYPT_SHA + if (salt[1] == '5' || salt[1] == '6') + return sha_crypt((char*)key, (char*)salt); +#endif } - { - if (!des_cctx) - des_cctx = const_des_init(); - des_ctx = des_init(des_ctx, des_cctx); - return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); - } + if (!des_cctx) + des_cctx = const_des_init(); + des_ctx = des_init(des_ctx, des_cctx); + return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); } /* So far nobody wants to have it public */ @@ -52,16 +126,10 @@ static void my_crypt_cleanup(void) des_ctx = NULL; } -char *pw_encrypt(const char *clear, const char *salt, int cleanup) +char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) { char *encrypted; -#if 0 /* was CONFIG_FEATURE_SHA1_PASSWORDS, but there is no such thing??? */ - if (strncmp(salt, "$2$", 3) == 0) { - return sha1_crypt(clear); - } -#endif - encrypted = my_crypt(clear, salt); if (cleanup) @@ -69,3 +137,19 @@ char *pw_encrypt(const char *clear, const char *salt, int cleanup) return encrypted; } + +#else /* if !ENABLE_USE_BB_CRYPT */ + +char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) +{ + char *s; + + s = crypt(clear, salt); + /* + * glibc used to return "" on malformed salts (for example, ""), + * but since 2.17 it returns NULL. + */ + return xstrdup(s ? s : ""); +} + +#endif