blob: 1edf4b6f08ad4621b392ec3692a4b59af71197a4 [file] [log] [blame]
Eric Andersen27f64e12002-06-23 04:24:25 +00001/* vi: set sw=4 ts=4: */
2/*
Denis Vlasenkod1a84a22008-12-07 01:16:34 +00003 * Utility routines.
Eric Andersen27f64e12002-06-23 04:24:25 +00004 *
Eric Andersenc7bda1c2004-03-15 08:29:22 +00005 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Eric Andersen27f64e12002-06-23 04:24:25 +00006 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02007 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Eric Andersen27f64e12002-06-23 04:24:25 +00008 */
Rob Landleyea224be2006-06-18 20:20:07 +00009#include "libbb.h"
Eric Andersen27f64e12002-06-23 04:24:25 +000010
Denys Vlasenko3e134eb2016-04-22 18:09:21 +020011/* static const uint8_t ascii64[] ALIGN1 =
Denis Vlasenkod1a84a22008-12-07 01:16:34 +000012 * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
13 */
14
15static int i64c(int i)
16{
17 i &= 0x3f;
18 if (i == 0)
19 return '.';
20 if (i == 1)
21 return '/';
22 if (i < 12)
23 return ('0' - 2 + i);
24 if (i < 38)
25 return ('A' - 12 + i);
26 return ('a' - 38 + i);
27}
28
Denys Vlasenko12a43272011-05-13 03:19:01 +020029int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */)
Denis Vlasenkod1a84a22008-12-07 01:16:34 +000030{
Denys Vlasenko12a43272011-05-13 03:19:01 +020031 /* was: x += ... */
Rostislav Skudnov87625122017-02-01 18:35:13 +000032 unsigned x = getpid() + monotonic_us();
Denis Vlasenkod1a84a22008-12-07 01:16:34 +000033 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
Denys Vlasenko12a43272011-05-13 03:19:01 +020050char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo)
51{
52 int len = 2/2;
53 char *salt_ptr = salt;
Pascal Bach2c0d3f52015-12-18 19:01:14 +010054
55 /* Standard chpasswd uses uppercase algos ("MD5", not "md5").
56 * Need to be case-insensitive in the code below.
57 */
58 if ((algo[0]|0x20) != 'd') { /* not des */
Denys Vlasenko12a43272011-05-13 03:19:01 +020059 len = 8/2; /* so far assuming md5 */
60 *salt_ptr++ = '$';
61 *salt_ptr++ = '1';
62 *salt_ptr++ = '$';
63#if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA
Pascal Bach2c0d3f52015-12-18 19:01:14 +010064 if ((algo[0]|0x20) == 's') { /* sha */
65 salt[1] = '5' + (strcasecmp(algo, "sha512") == 0);
Denys Vlasenko12a43272011-05-13 03:19:01 +020066 len = 16/2;
67 }
68#endif
69 }
70 crypt_make_salt(salt_ptr, len);
71 return salt_ptr;
72}
73
Denis Vlasenkob4c5bf62008-06-15 18:35:34 +000074#if ENABLE_USE_BB_CRYPT
75
Denis Vlasenkod1a84a22008-12-07 01:16:34 +000076static char*
77to64(char *s, unsigned v, int n)
78{
79 while (--n >= 0) {
80 /* *s++ = ascii64[v & 0x3f]; */
81 *s++ = i64c(v);
82 v >>= 6;
83 }
84 return s;
85}
86
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000087/*
88 * DES and MD5 crypt implementations are taken from uclibc.
89 * They were modified to not use static buffers.
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000090 */
Denis Vlasenko2211d522008-11-10 18:52:35 +000091
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000092#include "pw_encrypt_des.c"
93#include "pw_encrypt_md5.c"
Denis Vlasenko2211d522008-11-10 18:52:35 +000094#if ENABLE_USE_BB_CRYPT_SHA
95#include "pw_encrypt_sha.c"
96#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +000097
Denis Vlasenko2211d522008-11-10 18:52:35 +000098/* Other advanced crypt ids (TODO?): */
Denis Vlasenko30e1ab62008-11-07 13:36:46 +000099/* $2$ or $2a$: Blowfish */
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000100
101static struct const_des_ctx *des_cctx;
102static struct des_ctx *des_ctx;
103
104/* my_crypt returns malloc'ed data */
105static char *my_crypt(const char *key, const char *salt)
Eric Andersen27f64e12002-06-23 04:24:25 +0000106{
Denis Vlasenko2211d522008-11-10 18:52:35 +0000107 /* MD5 or SHA? */
108 if (salt[0] == '$' && salt[1] && salt[2] == '$') {
109 if (salt[1] == '1')
110 return md5_crypt(xzalloc(MD5_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
111#if ENABLE_USE_BB_CRYPT_SHA
112 if (salt[1] == '5' || salt[1] == '6')
113 return sha_crypt((char*)key, (char*)salt);
114#endif
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000115 }
116
Denis Vlasenko2211d522008-11-10 18:52:35 +0000117 if (!des_cctx)
118 des_cctx = const_des_init();
119 des_ctx = des_init(des_ctx, des_cctx);
120 return des_crypt(des_ctx, xzalloc(DES_OUT_BUFSIZE), (unsigned char*)key, (unsigned char*)salt);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000121}
122
123/* So far nobody wants to have it public */
124static void my_crypt_cleanup(void)
125{
126 free(des_cctx);
127 free(des_ctx);
128 des_cctx = NULL;
129 des_ctx = NULL;
130}
131
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000132char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000133{
Denis Vlasenkofdddab02008-06-12 16:56:52 +0000134 char *encrypted;
Eric Andersen27f64e12002-06-23 04:24:25 +0000135
Denis Vlasenkofdddab02008-06-12 16:56:52 +0000136 encrypted = my_crypt(clear, salt);
Denis Vlasenko4ea83bf2008-06-12 16:55:59 +0000137
138 if (cleanup)
139 my_crypt_cleanup();
140
Denis Vlasenkofdddab02008-06-12 16:56:52 +0000141 return encrypted;
Eric Andersen27f64e12002-06-23 04:24:25 +0000142}
Denis Vlasenkob4c5bf62008-06-15 18:35:34 +0000143
144#else /* if !ENABLE_USE_BB_CRYPT */
145
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000146char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup)
Denis Vlasenkob4c5bf62008-06-15 18:35:34 +0000147{
Denys Vlasenko8ed96722014-02-09 14:38:03 +0100148 char *s;
149
150 s = crypt(clear, salt);
151 /*
152 * glibc used to return "" on malformed salts (for example, ""),
153 * but since 2.17 it returns NULL.
154 */
155 return xstrdup(s ? s : "");
Denis Vlasenkob4c5bf62008-06-15 18:35:34 +0000156}
157
158#endif