busybox/libbb/pw_encrypt.c
<<
>>
Prefs
   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