1/* vi: set sw=4 ts=4: */ 2/* 3 * Utility routines. 4 * 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 */ 9 10#include "libbb.h" 11 12/* static const uint8_t ascii64[] = 13 * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 14 */ 15 16static int i64c(int i) 17{ 18 i &= 0x3f; 19 if (i == 0) 20 return '.'; 21 if (i == 1) 22 return '/'; 23 if (i < 12) 24 return ('0' - 2 + i); 25 if (i < 38) 26 return ('A' - 12 + i); 27 return ('a' - 38 + i); 28} 29 30int FAST_FUNC crypt_make_salt(char *p, int cnt, int x) 31{ 32 x += getpid() + time(NULL); 33 do { 34 /* x = (x*1664525 + 1013904223) % 2^32 generator is lame 35 * (low-order bit is not "random", etc...), 36 * but for our purposes it is good enough */ 37 x = x*1664525 + 1013904223; 38 /* BTW, Park and Miller's "minimal standard generator" is 39 * x = x*16807 % ((2^31)-1) 40 * It has no problem with visibly alternating lowest bit 41 * but is also weak in cryptographic sense + needs div, 42 * which needs more code (and slower) on many CPUs */ 43 *p++ = i64c(x >> 16); 44 *p++ = i64c(x >> 22); 45 } while (--cnt); 46 *p = '\0'; 47 return x; 48} 49 50#if ENABLE_USE_BB_CRYPT 51 52static char* 53to64(char *s, unsigned v, int n) 54{ 55 while (--n >= 0) { 56 /* *s++ = ascii64[v & 0x3f]; */ 57 *s++ = i64c(v); 58 v >>= 6; 59 } 60 return s; 61} 62 63/* 64 * DES and MD5 crypt implementations are taken from uclibc. 65 * They were modified to not use static buffers. 66 */ 67 68#include "pw_encrypt_des.c" 69#include "pw_encrypt_md5.c" 70#if ENABLE_USE_BB_CRYPT_SHA 71#include "pw_encrypt_sha.c" 72#endif 73 74/* Other advanced crypt ids (TODO?): */ 75/* $2$ or $2a$: Blowfish */ 76 77static struct const_des_ctx *des_cctx; 78static struct des_ctx *des_ctx; 79 80/* my_crypt returns malloc'ed data */ 81static char *my_crypt(const char *key, const char *salt) 82{ 83 /* MD5 or SHA? */ 84 if (salt[0] == '$' && salt[1] && salt[2] == '$') { 85 if (salt[1] == '1') 86 return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); 87#if ENABLE_USE_BB_CRYPT_SHA 88 if (salt[1] == '5' || salt[1] == '6') 89 return sha_crypt((char*)key, (char*)salt); 90#endif 91 } 92 93 if (!des_cctx) 94 des_cctx = const_des_init(); 95 des_ctx = des_init(des_ctx, des_cctx); 96 return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt); 97} 98 99/* So far nobody wants to have it public */ 100static void my_crypt_cleanup(void) 101{ 102 free(des_cctx); 103 free(des_ctx); 104 des_cctx = NULL; 105 des_ctx = NULL; 106} 107 108char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) 109{ 110 char *encrypted; 111 112 encrypted = my_crypt(clear, salt); 113 114 if (cleanup) 115 my_crypt_cleanup(); 116 117 return encrypted; 118} 119 120#else /* if !ENABLE_USE_BB_CRYPT */ 121 122char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) 123{ 124 return xstrdup(crypt(clear, salt)); 125} 126 127#endif 128